]> git.saurik.com Git - apple/javascriptcore.git/blame - bytecode/CallLinkInfo.h
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / bytecode / CallLinkInfo.h
CommitLineData
6fe7ccc8 1/*
ed1e77d3 2 * Copyright (C) 2012, 2014, 2015 Apple Inc. All rights reserved.
6fe7ccc8
A
3 *
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#ifndef CallLinkInfo_h
27#define CallLinkInfo_h
28
29#include "CodeLocation.h"
93a37866 30#include "CodeSpecializationKind.h"
6fe7ccc8
A
31#include "JITWriteBarrier.h"
32#include "JSFunction.h"
33#include "Opcode.h"
ed1e77d3 34#include "PolymorphicCallStubRoutine.h"
6fe7ccc8 35#include "WriteBarrier.h"
6fe7ccc8
A
36#include <wtf/SentinelLinkedList.h>
37
38namespace JSC {
39
40#if ENABLE(JIT)
41
42class RepatchBuffer;
43
ed1e77d3
A
44class CallLinkInfo : public BasicRawSentinelNode<CallLinkInfo> {
45public:
81345200 46 enum CallType { None, Call, CallVarargs, Construct, ConstructVarargs };
6fe7ccc8
A
47 static CallType callTypeFor(OpcodeID opcodeID)
48 {
49 if (opcodeID == op_call || opcodeID == op_call_eval)
50 return Call;
51 if (opcodeID == op_construct)
52 return Construct;
81345200
A
53 if (opcodeID == op_construct_varargs)
54 return ConstructVarargs;
6fe7ccc8
A
55 ASSERT(opcodeID == op_call_varargs);
56 return CallVarargs;
57 }
ed1e77d3 58
6fe7ccc8 59 CallLinkInfo()
ed1e77d3
A
60 : m_isFTL(false)
61 , m_hasSeenShouldRepatch(false)
62 , m_hasSeenClosure(false)
63 , m_clearedByGC(false)
64 , m_callType(None)
65 , m_maxNumArguments(0)
66 , m_slowPathCount(0)
6fe7ccc8
A
67 {
68 }
69
70 ~CallLinkInfo()
71 {
ed1e77d3
A
72 clearStub();
73
6fe7ccc8
A
74 if (isOnList())
75 remove();
76 }
93a37866 77
ed1e77d3 78 static CodeSpecializationKind specializationKindFor(CallType callType)
93a37866 79 {
81345200 80 return specializationFromIsConstruct(callType == Construct || callType == ConstructVarargs);
93a37866 81 }
ed1e77d3
A
82 CodeSpecializationKind specializationKind() const
83 {
84 return specializationKindFor(static_cast<CallType>(m_callType));
85 }
6fe7ccc8 86
ed1e77d3 87 bool isLinked() { return m_stub || m_callee; }
81345200 88 void unlink(RepatchBuffer&);
6fe7ccc8 89
ed1e77d3
A
90 void setUpCall(CallType callType, CodeOrigin codeOrigin, unsigned calleeGPR)
91 {
92 m_callType = callType;
93 m_codeOrigin = codeOrigin;
94 m_calleeGPR = calleeGPR;
95 }
96
97 void setCallLocations(CodeLocationNearCall callReturnLocation, CodeLocationDataLabelPtr hotPathBegin,
98 CodeLocationNearCall hotPathOther)
99 {
100 m_callReturnLocation = callReturnLocation;
101 m_hotPathBegin = hotPathBegin;
102 m_hotPathOther = hotPathOther;
103 }
104
105 void setUpCallFromFTL(CallType callType, CodeOrigin codeOrigin,
106 CodeLocationNearCall callReturnLocation, CodeLocationDataLabelPtr hotPathBegin,
107 CodeLocationNearCall hotPathOther, unsigned calleeGPR)
108 {
109 m_isFTL = true;
110 m_callType = callType;
111 m_codeOrigin = codeOrigin;
112 m_callReturnLocation = callReturnLocation;
113 m_hotPathBegin = hotPathBegin;
114 m_hotPathOther = hotPathOther;
115 m_calleeGPR = calleeGPR;
116 }
117
118 CodeLocationNearCall callReturnLocation()
119 {
120 return m_callReturnLocation;
121 }
122
123 CodeLocationDataLabelPtr hotPathBegin()
124 {
125 return m_hotPathBegin;
126 }
127
128 CodeLocationNearCall hotPathOther()
129 {
130 return m_hotPathOther;
131 }
132
133 void setCallee(VM& vm, CodeLocationDataLabelPtr location, JSCell* owner, JSFunction* callee)
134 {
135 m_callee.set(vm, location, owner, callee);
136 }
137
138 void clearCallee()
139 {
140 m_callee.clear();
141 }
142
143 JSFunction* callee()
144 {
145 return m_callee.get();
146 }
147
148 void setLastSeenCallee(VM& vm, const JSCell* owner, JSFunction* callee)
149 {
150 m_lastSeenCallee.set(vm, owner, callee);
151 }
152
153 void clearLastSeenCallee()
154 {
155 m_lastSeenCallee.clear();
156 }
157
158 JSFunction* lastSeenCallee()
159 {
160 return m_lastSeenCallee.get();
161 }
162
163 bool haveLastSeenCallee()
164 {
165 return !!m_lastSeenCallee;
166 }
167
168 void setStub(PassRefPtr<PolymorphicCallStubRoutine> newStub)
169 {
170 clearStub();
171 m_stub = newStub;
172 }
173
174 void clearStub();
175
176 PolymorphicCallStubRoutine* stub()
177 {
178 return m_stub.get();
179 }
180
6fe7ccc8
A
181 bool seenOnce()
182 {
ed1e77d3
A
183 return m_hasSeenShouldRepatch;
184 }
185
186 void clearSeen()
187 {
188 m_hasSeenShouldRepatch = false;
6fe7ccc8
A
189 }
190
191 void setSeen()
192 {
ed1e77d3 193 m_hasSeenShouldRepatch = true;
6fe7ccc8 194 }
ed1e77d3
A
195
196 bool hasSeenClosure()
197 {
198 return m_hasSeenClosure;
199 }
200
201 void setHasSeenClosure()
202 {
203 m_hasSeenClosure = true;
204 }
205
206 bool clearedByGC()
207 {
208 return m_clearedByGC;
209 }
210
211 void setCallType(CallType callType)
212 {
213 m_callType = callType;
214 }
215
216 CallType callType()
217 {
218 return static_cast<CallType>(m_callType);
219 }
220
221 uint8_t* addressOfMaxNumArguments()
222 {
223 return &m_maxNumArguments;
224 }
225
226 uint8_t maxNumArguments()
227 {
228 return m_maxNumArguments;
229 }
230
231 static ptrdiff_t offsetOfSlowPathCount()
232 {
233 return OBJECT_OFFSETOF(CallLinkInfo, m_slowPathCount);
234 }
235
236 void setCalleeGPR(unsigned calleeGPR)
237 {
238 m_calleeGPR = calleeGPR;
239 }
240
241 unsigned calleeGPR()
242 {
243 return m_calleeGPR;
244 }
245
246 uint32_t slowPathCount()
247 {
248 return m_slowPathCount;
249 }
250
251 void setCodeOrigin(CodeOrigin codeOrigin)
252 {
253 m_codeOrigin = codeOrigin;
254 }
255
256 CodeOrigin codeOrigin()
257 {
258 return m_codeOrigin;
259 }
260
81345200 261 void visitWeak(RepatchBuffer&);
ed1e77d3 262
81345200 263 static CallLinkInfo& dummy();
ed1e77d3
A
264
265private:
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;
272 bool m_isFTL : 1;
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;
6fe7ccc8
A
281};
282
81345200 283inline CodeOrigin getCallLinkInfoCodeOrigin(CallLinkInfo& callLinkInfo)
6fe7ccc8 284{
ed1e77d3 285 return callLinkInfo.codeOrigin();
6fe7ccc8
A
286}
287
81345200
A
288typedef HashMap<CodeOrigin, CallLinkInfo*, CodeOriginApproximateHash> CallLinkInfoMap;
289
290#else // ENABLE(JIT)
291
292typedef HashMap<int, void*> CallLinkInfoMap;
293
6fe7ccc8
A
294#endif // ENABLE(JIT)
295
296} // namespace JSC
297
298#endif // CallLinkInfo_h