2 * Copyright (C) 2012, 2014, 2015 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
26 #ifndef CallLinkInfo_h
27 #define CallLinkInfo_h
29 #include "CodeLocation.h"
30 #include "CodeSpecializationKind.h"
31 #include "JITWriteBarrier.h"
32 #include "JSFunction.h"
34 #include "PolymorphicCallStubRoutine.h"
35 #include "WriteBarrier.h"
36 #include <wtf/SentinelLinkedList.h>
44 class CallLinkInfo
: public BasicRawSentinelNode
<CallLinkInfo
> {
46 enum CallType
{ None
, Call
, CallVarargs
, Construct
, ConstructVarargs
};
47 static CallType
callTypeFor(OpcodeID opcodeID
)
49 if (opcodeID
== op_call
|| opcodeID
== op_call_eval
)
51 if (opcodeID
== op_construct
)
53 if (opcodeID
== op_construct_varargs
)
54 return ConstructVarargs
;
55 ASSERT(opcodeID
== op_call_varargs
);
61 , m_hasSeenShouldRepatch(false)
62 , m_hasSeenClosure(false)
63 , m_clearedByGC(false)
65 , m_maxNumArguments(0)
78 static CodeSpecializationKind
specializationKindFor(CallType callType
)
80 return specializationFromIsConstruct(callType
== Construct
|| callType
== ConstructVarargs
);
82 CodeSpecializationKind
specializationKind() const
84 return specializationKindFor(static_cast<CallType
>(m_callType
));
87 bool isLinked() { return m_stub
|| m_callee
; }
88 void unlink(RepatchBuffer
&);
90 void setUpCall(CallType callType
, CodeOrigin codeOrigin
, unsigned calleeGPR
)
92 m_callType
= callType
;
93 m_codeOrigin
= codeOrigin
;
94 m_calleeGPR
= calleeGPR
;
97 void setCallLocations(CodeLocationNearCall callReturnLocation
, CodeLocationDataLabelPtr hotPathBegin
,
98 CodeLocationNearCall hotPathOther
)
100 m_callReturnLocation
= callReturnLocation
;
101 m_hotPathBegin
= hotPathBegin
;
102 m_hotPathOther
= hotPathOther
;
105 void setUpCallFromFTL(CallType callType
, CodeOrigin codeOrigin
,
106 CodeLocationNearCall callReturnLocation
, CodeLocationDataLabelPtr hotPathBegin
,
107 CodeLocationNearCall hotPathOther
, unsigned calleeGPR
)
110 m_callType
= callType
;
111 m_codeOrigin
= codeOrigin
;
112 m_callReturnLocation
= callReturnLocation
;
113 m_hotPathBegin
= hotPathBegin
;
114 m_hotPathOther
= hotPathOther
;
115 m_calleeGPR
= calleeGPR
;
118 CodeLocationNearCall
callReturnLocation()
120 return m_callReturnLocation
;
123 CodeLocationDataLabelPtr
hotPathBegin()
125 return m_hotPathBegin
;
128 CodeLocationNearCall
hotPathOther()
130 return m_hotPathOther
;
133 void setCallee(VM
& vm
, CodeLocationDataLabelPtr location
, JSCell
* owner
, JSFunction
* callee
)
135 m_callee
.set(vm
, location
, owner
, callee
);
145 return m_callee
.get();
148 void setLastSeenCallee(VM
& vm
, const JSCell
* owner
, JSFunction
* callee
)
150 m_lastSeenCallee
.set(vm
, owner
, callee
);
153 void clearLastSeenCallee()
155 m_lastSeenCallee
.clear();
158 JSFunction
* lastSeenCallee()
160 return m_lastSeenCallee
.get();
163 bool haveLastSeenCallee()
165 return !!m_lastSeenCallee
;
168 void setStub(PassRefPtr
<PolymorphicCallStubRoutine
> newStub
)
176 PolymorphicCallStubRoutine
* stub()
183 return m_hasSeenShouldRepatch
;
188 m_hasSeenShouldRepatch
= false;
193 m_hasSeenShouldRepatch
= true;
196 bool hasSeenClosure()
198 return m_hasSeenClosure
;
201 void setHasSeenClosure()
203 m_hasSeenClosure
= true;
208 return m_clearedByGC
;
211 void setCallType(CallType callType
)
213 m_callType
= callType
;
218 return static_cast<CallType
>(m_callType
);
221 uint8_t* addressOfMaxNumArguments()
223 return &m_maxNumArguments
;
226 uint8_t maxNumArguments()
228 return m_maxNumArguments
;
231 static ptrdiff_t offsetOfSlowPathCount()
233 return OBJECT_OFFSETOF(CallLinkInfo
, m_slowPathCount
);
236 void setCalleeGPR(unsigned calleeGPR
)
238 m_calleeGPR
= calleeGPR
;
246 uint32_t slowPathCount()
248 return m_slowPathCount
;
251 void setCodeOrigin(CodeOrigin codeOrigin
)
253 m_codeOrigin
= codeOrigin
;
256 CodeOrigin
codeOrigin()
261 void visitWeak(RepatchBuffer
&);
263 static CallLinkInfo
& dummy();
266 CodeLocationNearCall m_callReturnLocation
;
267 CodeLocationDataLabelPtr m_hotPathBegin
;
268 CodeLocationNearCall m_hotPathOther
;
269 JITWriteBarrier
<JSFunction
> m_callee
;
270 WriteBarrier
<JSFunction
> m_lastSeenCallee
;
271 RefPtr
<PolymorphicCallStubRoutine
> m_stub
;
273 bool m_hasSeenShouldRepatch
: 1;
274 bool m_hasSeenClosure
: 1;
275 bool m_clearedByGC
: 1;
276 unsigned m_callType
: 4; // CallType
277 unsigned m_calleeGPR
: 8;
278 uint8_t m_maxNumArguments
; // Only used for varargs calls.
279 uint32_t m_slowPathCount
;
280 CodeOrigin m_codeOrigin
;
283 inline CodeOrigin
getCallLinkInfoCodeOrigin(CallLinkInfo
& callLinkInfo
)
285 return callLinkInfo
.codeOrigin();
288 typedef HashMap
<CodeOrigin
, CallLinkInfo
*, CodeOriginApproximateHash
> CallLinkInfoMap
;
292 typedef HashMap
<int, void*> CallLinkInfoMap
;
294 #endif // ENABLE(JIT)
298 #endif // CallLinkInfo_h