blob: bc0f841df751459345927df3da6aabd091675b53 [file] [log] [blame]
fpizlo@apple.com8a5fd182015-02-02 18:38:08 +00001/*
fpizlo@apple.comf7240e02016-12-16 02:16:19 +00002 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
fpizlo@apple.com8a5fd182015-02-02 18:38:08 +00003 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "PolymorphicCallStubRoutine.h"
28
29#if ENABLE(JIT)
30
31#include "CallLinkInfo.h"
32#include "CodeBlock.h"
jfbastien@apple.comc6594e52017-02-22 01:16:42 +000033#include "FullCodeOrigin.h"
fpizlo@apple.com8a5fd182015-02-02 18:38:08 +000034#include "JSCInlines.h"
35#include "LinkBuffer.h"
36
37namespace JSC {
38
39PolymorphicCallNode::~PolymorphicCallNode()
40{
41 if (isOnList())
42 remove();
43}
44
fpizlo@apple.com7a797262015-09-03 21:11:59 +000045void PolymorphicCallNode::unlink(VM& vm)
fpizlo@apple.com8a5fd182015-02-02 18:38:08 +000046{
msaboff@apple.com6c3c71c2015-06-01 23:35:02 +000047 if (m_callLinkInfo) {
mark.lam@apple.comee3c4102015-10-14 18:57:07 +000048 if (Options::dumpDisassembly())
msaboff@apple.com203a56e2015-06-24 22:37:30 +000049 dataLog("Unlinking polymorphic call at ", m_callLinkInfo->callReturnLocation(), ", ", m_callLinkInfo->codeOrigin(), "\n");
msaboff@apple.com6c3c71c2015-06-01 23:35:02 +000050
fpizlo@apple.com7a797262015-09-03 21:11:59 +000051 m_callLinkInfo->unlink(vm);
msaboff@apple.com6c3c71c2015-06-01 23:35:02 +000052 }
53
fpizlo@apple.com8a5fd182015-02-02 18:38:08 +000054 if (isOnList())
55 remove();
56}
57
msaboff@apple.com6c3c71c2015-06-01 23:35:02 +000058void PolymorphicCallNode::clearCallLinkInfo()
59{
mark.lam@apple.comee3c4102015-10-14 18:57:07 +000060 if (Options::dumpDisassembly())
msaboff@apple.com203a56e2015-06-24 22:37:30 +000061 dataLog("Clearing call link info for polymorphic call at ", m_callLinkInfo->callReturnLocation(), ", ", m_callLinkInfo->codeOrigin(), "\n");
msaboff@apple.com6c3c71c2015-06-01 23:35:02 +000062
63 m_callLinkInfo = nullptr;
64}
65
fpizlo@apple.com8a5fd182015-02-02 18:38:08 +000066void PolymorphicCallCase::dump(PrintStream& out) const
67{
68 out.print("<variant = ", m_variant, ", codeBlock = ", pointerDump(m_codeBlock), ">");
69}
70
71PolymorphicCallStubRoutine::PolymorphicCallStubRoutine(
72 const MacroAssemblerCodeRef& codeRef, VM& vm, const JSCell* owner, ExecState* callerFrame,
73 CallLinkInfo& info, const Vector<PolymorphicCallCase>& cases,
utatane.tea@gmail.com1d211e12018-03-06 07:25:14 +000074 UniqueArray<uint32_t>&& fastCounts)
fpizlo@apple.com8a5fd182015-02-02 18:38:08 +000075 : GCAwareJITStubRoutine(codeRef, vm)
aestes@apple.com13aae082016-01-02 08:03:08 +000076 , m_fastCounts(WTFMove(fastCounts))
fpizlo@apple.com8a5fd182015-02-02 18:38:08 +000077{
78 for (PolymorphicCallCase callCase : cases) {
79 m_variants.append(WriteBarrier<JSCell>(vm, owner, callCase.variant().rawCalleeCell()));
mark.lam@apple.comee3c4102015-10-14 18:57:07 +000080 if (shouldDumpDisassemblyFor(callerFrame->codeBlock()))
jfbastien@apple.comc6594e52017-02-22 01:16:42 +000081 dataLog("Linking polymorphic call in ", FullCodeOrigin(callerFrame->codeBlock(), callerFrame->codeOrigin()), " to ", callCase.variant(), ", codeBlock = ", pointerDump(callCase.codeBlock()), "\n");
fpizlo@apple.com8a5fd182015-02-02 18:38:08 +000082 if (CodeBlock* codeBlock = callCase.codeBlock())
83 codeBlock->linkIncomingPolymorphicCall(callerFrame, m_callNodes.add(&info));
84 }
85 m_variants.shrinkToFit();
86 WTF::storeStoreFence();
87}
88
89PolymorphicCallStubRoutine::~PolymorphicCallStubRoutine() { }
90
91CallVariantList PolymorphicCallStubRoutine::variants() const
92{
93 CallVariantList result;
94 for (size_t i = 0; i < m_variants.size(); ++i)
95 result.append(CallVariant(m_variants[i].get()));
96 return result;
97}
98
99CallEdgeList PolymorphicCallStubRoutine::edges() const
100{
101 // We wouldn't have these if this was an FTL stub routine. We shouldn't be asking for profiling
102 // from the FTL.
103 RELEASE_ASSERT(m_fastCounts);
104
105 CallEdgeList result;
106 for (size_t i = 0; i < m_variants.size(); ++i)
107 result.append(CallEdge(CallVariant(m_variants[i].get()), m_fastCounts[i]));
108 return result;
109}
110
msaboff@apple.com6c3c71c2015-06-01 23:35:02 +0000111void PolymorphicCallStubRoutine::clearCallNodesFor(CallLinkInfo* info)
112{
113 for (Bag<PolymorphicCallNode>::iterator iter = m_callNodes.begin(); !!iter; ++iter) {
114 PolymorphicCallNode& node = **iter;
115 // All nodes should point to info, but okay to be a little paranoid.
116 if (node.hasCallLinkInfo(info))
117 node.clearCallLinkInfo();
118 }
119}
120
fpizlo@apple.com7a797262015-09-03 21:11:59 +0000121bool PolymorphicCallStubRoutine::visitWeak(VM&)
fpizlo@apple.com8a5fd182015-02-02 18:38:08 +0000122{
123 for (auto& variant : m_variants) {
124 if (!Heap::isMarked(variant.get()))
125 return false;
126 }
127 return true;
128}
129
130void PolymorphicCallStubRoutine::markRequiredObjectsInternal(SlotVisitor& visitor)
131{
132 for (auto& variant : m_variants)
fpizlo@apple.comf7240e02016-12-16 02:16:19 +0000133 visitor.append(variant);
fpizlo@apple.com8a5fd182015-02-02 18:38:08 +0000134}
135
136} // namespace JSC
137
138#endif // ENABLE(JIT)