]>
Commit | Line | Data |
---|---|---|
14957cd0 | 1 | /* |
93a37866 | 2 | * Copyright (C) 2011, 2013 Apple Inc. All rights reserved. |
14957cd0 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 DFGJITCompiler_h | |
27 | #define DFGJITCompiler_h | |
28 | ||
29 | #if ENABLE(DFG_JIT) | |
30 | ||
93a37866 A |
31 | #include "CodeBlock.h" |
32 | #include "DFGCCallHelpers.h" | |
33 | #include "DFGDisassembler.h" | |
34 | #include "DFGFPRInfo.h" | |
35 | #include "DFGGPRInfo.h" | |
36 | #include "DFGGraph.h" | |
37 | #include "DFGOSRExitCompilationInfo.h" | |
38 | #include "DFGRegisterBank.h" | |
39 | #include "DFGRegisterSet.h" | |
40 | #include "JITCode.h" | |
41 | #include "LinkBuffer.h" | |
42 | #include "MacroAssembler.h" | |
14957cd0 | 43 | |
14957cd0 A |
44 | namespace JSC { |
45 | ||
46 | class AbstractSamplingCounter; | |
47 | class CodeBlock; | |
93a37866 | 48 | class VM; |
14957cd0 A |
49 | |
50 | namespace DFG { | |
51 | ||
52 | class JITCodeGenerator; | |
6fe7ccc8 | 53 | class NodeToRegisterMap; |
93a37866 A |
54 | class OSRExitJumpPlaceholder; |
55 | class SlowPathGenerator; | |
14957cd0 A |
56 | class SpeculativeJIT; |
57 | class SpeculationRecovery; | |
58 | ||
59 | struct EntryLocation; | |
6fe7ccc8 | 60 | struct OSRExit; |
14957cd0 | 61 | |
6fe7ccc8 | 62 | // === CallLinkRecord === |
14957cd0 | 63 | // |
6fe7ccc8 A |
64 | // A record of a call out from JIT code that needs linking to a helper function. |
65 | // Every CallLinkRecord contains a reference to the call instruction & the function | |
66 | // that it needs to be linked to. | |
67 | struct CallLinkRecord { | |
68 | CallLinkRecord(MacroAssembler::Call call, FunctionPtr function) | |
14957cd0 A |
69 | : m_call(call) |
70 | , m_function(function) | |
71 | { | |
72 | } | |
73 | ||
6fe7ccc8 A |
74 | MacroAssembler::Call m_call; |
75 | FunctionPtr m_function; | |
76 | }; | |
77 | ||
78 | class CallBeginToken { | |
79 | public: | |
80 | CallBeginToken() | |
81 | #if !ASSERT_DISABLED | |
93a37866 A |
82 | : m_registered(false) |
83 | , m_exceptionCheckIndex(std::numeric_limits<unsigned>::max()) | |
6fe7ccc8 A |
84 | #endif |
85 | { | |
86 | } | |
87 | ||
93a37866 A |
88 | ~CallBeginToken() |
89 | { | |
90 | ASSERT(m_registered || !m_codeOrigin.isSet()); | |
91 | ASSERT(m_codeOrigin.isSet() == (m_exceptionCheckIndex != std::numeric_limits<unsigned>::max())); | |
92 | } | |
93 | ||
94 | void set(CodeOrigin codeOrigin, unsigned index) | |
95 | { | |
6fe7ccc8 | 96 | #if !ASSERT_DISABLED |
93a37866 A |
97 | ASSERT(m_registered || !m_codeOrigin.isSet()); |
98 | ASSERT(m_codeOrigin.isSet() == (m_exceptionCheckIndex != std::numeric_limits<unsigned>::max())); | |
99 | m_codeOrigin = codeOrigin; | |
100 | m_registered = false; | |
101 | m_exceptionCheckIndex = index; | |
102 | #else | |
103 | UNUSED_PARAM(codeOrigin); | |
104 | UNUSED_PARAM(index); | |
6fe7ccc8 | 105 | #endif |
6fe7ccc8 A |
106 | } |
107 | ||
93a37866 | 108 | void registerWithExceptionCheck(CodeOrigin codeOrigin, unsigned index) |
6fe7ccc8 | 109 | { |
93a37866 A |
110 | #if !ASSERT_DISABLED |
111 | ASSERT(m_codeOrigin == codeOrigin); | |
112 | if (m_registered) | |
113 | return; | |
114 | ASSERT(m_exceptionCheckIndex == index); | |
115 | m_registered = true; | |
116 | #else | |
117 | UNUSED_PARAM(codeOrigin); | |
118 | UNUSED_PARAM(index); | |
119 | #endif | |
6fe7ccc8 A |
120 | } |
121 | ||
93a37866 A |
122 | #if !ASSERT_DISABLED |
123 | const CodeOrigin& codeOrigin() const | |
124 | { | |
125 | return m_codeOrigin; | |
126 | } | |
127 | #endif | |
128 | ||
6fe7ccc8 A |
129 | private: |
130 | #if !ASSERT_DISABLED | |
93a37866 A |
131 | CodeOrigin m_codeOrigin; |
132 | bool m_registered; | |
133 | unsigned m_exceptionCheckIndex; | |
6fe7ccc8 A |
134 | #endif |
135 | }; | |
136 | ||
137 | // === CallExceptionRecord === | |
138 | // | |
139 | // A record of a call out from JIT code that might throw an exception. | |
140 | // Calls that might throw an exception also record the Jump taken on exception | |
141 | // (unset if not present) and code origin used to recover handler/source info. | |
142 | struct CallExceptionRecord { | |
93a37866 | 143 | CallExceptionRecord(MacroAssembler::Call call, CodeOrigin codeOrigin) |
6fe7ccc8 A |
144 | : m_call(call) |
145 | , m_codeOrigin(codeOrigin) | |
6fe7ccc8 A |
146 | { |
147 | } | |
148 | ||
93a37866 | 149 | CallExceptionRecord(MacroAssembler::Call call, MacroAssembler::Jump exceptionCheck, CodeOrigin codeOrigin) |
14957cd0 | 150 | : m_call(call) |
14957cd0 | 151 | , m_exceptionCheck(exceptionCheck) |
6fe7ccc8 | 152 | , m_codeOrigin(codeOrigin) |
14957cd0 A |
153 | { |
154 | } | |
155 | ||
156 | MacroAssembler::Call m_call; | |
14957cd0 | 157 | MacroAssembler::Jump m_exceptionCheck; |
6fe7ccc8 | 158 | CodeOrigin m_codeOrigin; |
6fe7ccc8 A |
159 | }; |
160 | ||
161 | struct PropertyAccessRecord { | |
162 | enum RegisterMode { RegistersFlushed, RegistersInUse }; | |
163 | ||
164 | #if USE(JSVALUE64) | |
93a37866 A |
165 | PropertyAccessRecord( |
166 | CodeOrigin codeOrigin, | |
167 | MacroAssembler::DataLabelPtr structureImm, | |
168 | MacroAssembler::PatchableJump structureCheck, | |
169 | MacroAssembler::ConvertibleLoadLabel propertyStorageLoad, | |
170 | MacroAssembler::DataLabelCompact loadOrStore, | |
171 | SlowPathGenerator* slowPathGenerator, | |
172 | MacroAssembler::Label done, | |
173 | int8_t baseGPR, | |
174 | int8_t valueGPR, | |
175 | const RegisterSet& usedRegisters, | |
176 | RegisterMode registerMode = RegistersInUse) | |
6fe7ccc8 | 177 | #elif USE(JSVALUE32_64) |
93a37866 A |
178 | PropertyAccessRecord( |
179 | CodeOrigin codeOrigin, | |
180 | MacroAssembler::DataLabelPtr structureImm, | |
181 | MacroAssembler::PatchableJump structureCheck, | |
182 | MacroAssembler::ConvertibleLoadLabel propertyStorageLoad, | |
183 | MacroAssembler::DataLabelCompact tagLoadOrStore, | |
184 | MacroAssembler::DataLabelCompact payloadLoadOrStore, | |
185 | SlowPathGenerator* slowPathGenerator, | |
186 | MacroAssembler::Label done, | |
187 | int8_t baseGPR, | |
188 | int8_t valueTagGPR, | |
189 | int8_t valueGPR, | |
190 | const RegisterSet& usedRegisters, | |
191 | RegisterMode registerMode = RegistersInUse) | |
6fe7ccc8 A |
192 | #endif |
193 | : m_codeOrigin(codeOrigin) | |
93a37866 A |
194 | , m_structureImm(structureImm) |
195 | , m_structureCheck(structureCheck) | |
196 | , m_propertyStorageLoad(propertyStorageLoad) | |
6fe7ccc8 | 197 | #if USE(JSVALUE64) |
93a37866 | 198 | , m_loadOrStore(loadOrStore) |
6fe7ccc8 | 199 | #elif USE(JSVALUE32_64) |
93a37866 A |
200 | , m_tagLoadOrStore(tagLoadOrStore) |
201 | , m_payloadLoadOrStore(payloadLoadOrStore) | |
6fe7ccc8 | 202 | #endif |
93a37866 A |
203 | , m_slowPathGenerator(slowPathGenerator) |
204 | , m_done(done) | |
6fe7ccc8 A |
205 | , m_baseGPR(baseGPR) |
206 | #if USE(JSVALUE32_64) | |
207 | , m_valueTagGPR(valueTagGPR) | |
208 | #endif | |
209 | , m_valueGPR(valueGPR) | |
93a37866 | 210 | , m_usedRegisters(usedRegisters) |
6fe7ccc8 A |
211 | , m_registerMode(registerMode) |
212 | { | |
213 | } | |
214 | ||
215 | CodeOrigin m_codeOrigin; | |
93a37866 A |
216 | MacroAssembler::DataLabelPtr m_structureImm; |
217 | MacroAssembler::PatchableJump m_structureCheck; | |
218 | MacroAssembler::ConvertibleLoadLabel m_propertyStorageLoad; | |
6fe7ccc8 | 219 | #if USE(JSVALUE64) |
93a37866 | 220 | MacroAssembler::DataLabelCompact m_loadOrStore; |
6fe7ccc8 | 221 | #elif USE(JSVALUE32_64) |
93a37866 A |
222 | MacroAssembler::DataLabelCompact m_tagLoadOrStore; |
223 | MacroAssembler::DataLabelCompact m_payloadLoadOrStore; | |
6fe7ccc8 | 224 | #endif |
93a37866 A |
225 | SlowPathGenerator* m_slowPathGenerator; |
226 | MacroAssembler::Label m_done; | |
6fe7ccc8 A |
227 | int8_t m_baseGPR; |
228 | #if USE(JSVALUE32_64) | |
229 | int8_t m_valueTagGPR; | |
230 | #endif | |
231 | int8_t m_valueGPR; | |
93a37866 | 232 | RegisterSet m_usedRegisters; |
6fe7ccc8 | 233 | RegisterMode m_registerMode; |
14957cd0 A |
234 | }; |
235 | ||
236 | // === JITCompiler === | |
237 | // | |
238 | // DFG::JITCompiler is responsible for generating JIT code from the dataflow graph. | |
239 | // It does so by delegating to the speculative & non-speculative JITs, which | |
240 | // generate to a MacroAssembler (which the JITCompiler owns through an inheritance | |
241 | // relationship). The JITCompiler holds references to information required during | |
242 | // compilation, and also records information used in linking (e.g. a list of all | |
243 | // call to be linked). | |
6fe7ccc8 | 244 | class JITCompiler : public CCallHelpers { |
14957cd0 | 245 | public: |
93a37866 A |
246 | JITCompiler(Graph& dfg); |
247 | ||
6fe7ccc8 A |
248 | bool compile(JITCode& entry); |
249 | bool compileFunction(JITCode& entry, MacroAssemblerCodePtr& entryWithArityCheck); | |
14957cd0 A |
250 | |
251 | // Accessors for properties. | |
252 | Graph& graph() { return m_graph; } | |
6fe7ccc8 | 253 | |
93a37866 A |
254 | // Methods to set labels for the disassembler. |
255 | void setStartOfCode() | |
256 | { | |
257 | if (LIKELY(!m_disassembler)) | |
258 | return; | |
259 | m_disassembler->setStartOfCode(labelIgnoringWatchpoints()); | |
260 | } | |
261 | ||
262 | void setForBlock(BlockIndex blockIndex) | |
263 | { | |
264 | if (LIKELY(!m_disassembler)) | |
265 | return; | |
266 | m_disassembler->setForBlock(blockIndex, labelIgnoringWatchpoints()); | |
267 | } | |
268 | ||
269 | void setForNode(Node* node) | |
270 | { | |
271 | if (LIKELY(!m_disassembler)) | |
272 | return; | |
273 | m_disassembler->setForNode(node, labelIgnoringWatchpoints()); | |
274 | } | |
275 | ||
276 | void setEndOfMainPath() | |
277 | { | |
278 | if (LIKELY(!m_disassembler)) | |
279 | return; | |
280 | m_disassembler->setEndOfMainPath(labelIgnoringWatchpoints()); | |
281 | } | |
282 | ||
283 | void setEndOfCode() | |
284 | { | |
285 | if (LIKELY(!m_disassembler)) | |
286 | return; | |
287 | m_disassembler->setEndOfCode(labelIgnoringWatchpoints()); | |
288 | } | |
289 | ||
290 | unsigned currentCodeOriginIndex() const | |
291 | { | |
292 | return m_currentCodeOriginIndex; | |
293 | } | |
294 | ||
6fe7ccc8 | 295 | // Get a token for beginning a call, and set the current code origin index in |
93a37866 A |
296 | // the call frame. For each beginCall() there must be at least one exception |
297 | // check, and all of the exception checks must have the same CodeOrigin as the | |
298 | // beginCall(). | |
299 | void beginCall(CodeOrigin codeOrigin, CallBeginToken& token) | |
14957cd0 | 300 | { |
93a37866 A |
301 | unsigned index = m_exceptionChecks.size(); |
302 | store32(TrustedImm32(index), tagFor(static_cast<VirtualRegister>(JSStack::ArgumentCount))); | |
303 | token.set(codeOrigin, index); | |
14957cd0 A |
304 | } |
305 | ||
6fe7ccc8 | 306 | // Notify the JIT of a call that does not require linking. |
93a37866 | 307 | void notifyCall(Call functionCall, CodeOrigin codeOrigin, CallBeginToken& token) |
14957cd0 | 308 | { |
93a37866 A |
309 | token.registerWithExceptionCheck(codeOrigin, m_exceptionChecks.size()); |
310 | m_exceptionChecks.append(CallExceptionRecord(functionCall, codeOrigin)); | |
14957cd0 A |
311 | } |
312 | ||
6fe7ccc8 A |
313 | // Add a call out from JIT code, without an exception check. |
314 | Call appendCall(const FunctionPtr& function) | |
14957cd0 | 315 | { |
6fe7ccc8 A |
316 | Call functionCall = call(); |
317 | m_calls.append(CallLinkRecord(functionCall, function)); | |
318 | return functionCall; | |
14957cd0 | 319 | } |
93a37866 A |
320 | |
321 | void prepareForExceptionCheck() | |
322 | { | |
323 | move(TrustedImm32(m_exceptionChecks.size()), GPRInfo::nonPreservedNonReturnGPR); | |
324 | } | |
14957cd0 | 325 | |
6fe7ccc8 | 326 | // Add a call out from JIT code, with an exception check. |
93a37866 | 327 | void addExceptionCheck(Call functionCall, CodeOrigin codeOrigin, CallBeginToken& token) |
14957cd0 | 328 | { |
93a37866 A |
329 | prepareForExceptionCheck(); |
330 | token.registerWithExceptionCheck(codeOrigin, m_exceptionChecks.size()); | |
331 | m_exceptionChecks.append(CallExceptionRecord(functionCall, emitExceptionCheck(), codeOrigin)); | |
14957cd0 | 332 | } |
6fe7ccc8 A |
333 | |
334 | // Add a call out from JIT code, with a fast exception check that tests if the return value is zero. | |
93a37866 | 335 | void addFastExceptionCheck(Call functionCall, CodeOrigin codeOrigin, CallBeginToken& token) |
14957cd0 | 336 | { |
93a37866 | 337 | prepareForExceptionCheck(); |
6fe7ccc8 | 338 | Jump exceptionCheck = branchTestPtr(Zero, GPRInfo::returnValueGPR); |
93a37866 A |
339 | token.registerWithExceptionCheck(codeOrigin, m_exceptionChecks.size()); |
340 | m_exceptionChecks.append(CallExceptionRecord(functionCall, exceptionCheck, codeOrigin)); | |
14957cd0 | 341 | } |
6fe7ccc8 | 342 | |
93a37866 A |
343 | void appendExitInfo(MacroAssembler::JumpList jumpsToFail = MacroAssembler::JumpList()) |
344 | { | |
345 | OSRExitCompilationInfo info; | |
346 | info.m_failureJumps = jumpsToFail; | |
347 | m_exitCompilationInfo.append(info); | |
348 | } | |
6fe7ccc8 A |
349 | |
350 | #if USE(JSVALUE32_64) | |
93a37866 | 351 | void* addressOfDoubleConstant(Node* node) |
14957cd0 | 352 | { |
93a37866 A |
353 | ASSERT(m_graph.isNumberConstant(node)); |
354 | unsigned constantIndex = node->constantNumber(); | |
6fe7ccc8 | 355 | return &(codeBlock()->constantRegister(FirstConstantRegisterIndex + constantIndex)); |
14957cd0 A |
356 | } |
357 | #endif | |
358 | ||
6fe7ccc8 | 359 | void addPropertyAccess(const PropertyAccessRecord& record) |
14957cd0 | 360 | { |
6fe7ccc8 | 361 | m_propertyAccesses.append(record); |
14957cd0 A |
362 | } |
363 | ||
93a37866 | 364 | void addJSCall(Call fastCall, Call slowCall, DataLabelPtr targetToCheck, CallLinkInfo::CallType callType, GPRReg callee, CodeOrigin codeOrigin) |
14957cd0 | 365 | { |
93a37866 | 366 | m_jsCalls.append(JSCallRecord(fastCall, slowCall, targetToCheck, callType, callee, codeOrigin)); |
14957cd0 | 367 | } |
6fe7ccc8 A |
368 | |
369 | void addWeakReference(JSCell* target) | |
14957cd0 | 370 | { |
6fe7ccc8 | 371 | m_codeBlock->appendWeakReference(target); |
14957cd0 | 372 | } |
6fe7ccc8 | 373 | |
93a37866 A |
374 | void addWeakReferences(const StructureSet& structureSet) |
375 | { | |
376 | for (unsigned i = structureSet.size(); i--;) | |
377 | addWeakReference(structureSet[i]); | |
378 | } | |
379 | ||
6fe7ccc8 | 380 | void addWeakReferenceTransition(JSCell* codeOrigin, JSCell* from, JSCell* to) |
14957cd0 | 381 | { |
6fe7ccc8 | 382 | m_codeBlock->appendWeakReferenceTransition(codeOrigin, from, to); |
14957cd0 | 383 | } |
6fe7ccc8 A |
384 | |
385 | template<typename T> | |
386 | Jump branchWeakPtr(RelationalCondition cond, T left, JSCell* weakPtr) | |
14957cd0 | 387 | { |
6fe7ccc8 A |
388 | Jump result = branchPtr(cond, left, TrustedImmPtr(weakPtr)); |
389 | addWeakReference(weakPtr); | |
390 | return result; | |
14957cd0 | 391 | } |
6fe7ccc8 A |
392 | |
393 | void noticeOSREntry(BasicBlock& basicBlock, JITCompiler::Label blockHead, LinkBuffer& linkBuffer) | |
14957cd0 | 394 | { |
6fe7ccc8 | 395 | #if DFG_ENABLE(OSR_ENTRY) |
93a37866 A |
396 | // OSR entry is not allowed into blocks deemed unreachable by control flow analysis. |
397 | if (!basicBlock.cfaHasVisited) | |
398 | return; | |
399 | ||
6fe7ccc8 A |
400 | OSREntryData* entry = codeBlock()->appendDFGOSREntryData(basicBlock.bytecodeBegin, linkBuffer.offsetOf(blockHead)); |
401 | ||
402 | entry->m_expectedValues = basicBlock.valuesAtHead; | |
403 | ||
404 | // Fix the expected values: in our protocol, a dead variable will have an expected | |
405 | // value of (None, []). But the old JIT may stash some values there. So we really | |
406 | // need (Top, TOP). | |
407 | for (size_t argument = 0; argument < basicBlock.variablesAtHead.numberOfArguments(); ++argument) { | |
93a37866 A |
408 | Node* node = basicBlock.variablesAtHead.argument(argument); |
409 | if (!node || !node->shouldGenerate()) | |
6fe7ccc8 A |
410 | entry->m_expectedValues.argument(argument).makeTop(); |
411 | } | |
412 | for (size_t local = 0; local < basicBlock.variablesAtHead.numberOfLocals(); ++local) { | |
93a37866 A |
413 | Node* node = basicBlock.variablesAtHead.local(local); |
414 | if (!node || !node->shouldGenerate()) | |
6fe7ccc8 | 415 | entry->m_expectedValues.local(local).makeTop(); |
93a37866 | 416 | else if (node->variableAccessData()->shouldUseDoubleFormat()) |
6fe7ccc8 A |
417 | entry->m_localsForcedDouble.set(local); |
418 | } | |
14957cd0 | 419 | #else |
6fe7ccc8 A |
420 | UNUSED_PARAM(basicBlock); |
421 | UNUSED_PARAM(blockHead); | |
422 | UNUSED_PARAM(linkBuffer); | |
14957cd0 | 423 | #endif |
6fe7ccc8 | 424 | } |
14957cd0 A |
425 | |
426 | private: | |
93a37866 A |
427 | friend class OSRExitJumpPlaceholder; |
428 | ||
6fe7ccc8 A |
429 | // Internal implementation to compile. |
430 | void compileEntry(); | |
431 | void compileBody(SpeculativeJIT&); | |
432 | void link(LinkBuffer&); | |
433 | ||
434 | void exitSpeculativeWithOSR(const OSRExit&, SpeculationRecovery*); | |
93a37866 | 435 | void compileExceptionHandlers(); |
6fe7ccc8 A |
436 | void linkOSRExits(); |
437 | ||
14957cd0 A |
438 | // The dataflow graph currently being generated. |
439 | Graph& m_graph; | |
440 | ||
93a37866 A |
441 | OwnPtr<Disassembler> m_disassembler; |
442 | ||
14957cd0 | 443 | // Vector of calls out from JIT code, including exception handler information. |
6fe7ccc8 A |
444 | // Count of the number of CallRecords with exception handlers. |
445 | Vector<CallLinkRecord> m_calls; | |
446 | Vector<CallExceptionRecord> m_exceptionChecks; | |
447 | ||
448 | struct JSCallRecord { | |
93a37866 | 449 | JSCallRecord(Call fastCall, Call slowCall, DataLabelPtr targetToCheck, CallLinkInfo::CallType callType, GPRReg callee, CodeOrigin codeOrigin) |
6fe7ccc8 A |
450 | : m_fastCall(fastCall) |
451 | , m_slowCall(slowCall) | |
452 | , m_targetToCheck(targetToCheck) | |
453 | , m_callType(callType) | |
93a37866 | 454 | , m_callee(callee) |
6fe7ccc8 A |
455 | , m_codeOrigin(codeOrigin) |
456 | { | |
457 | } | |
458 | ||
459 | Call m_fastCall; | |
460 | Call m_slowCall; | |
461 | DataLabelPtr m_targetToCheck; | |
462 | CallLinkInfo::CallType m_callType; | |
93a37866 | 463 | GPRReg m_callee; |
6fe7ccc8 A |
464 | CodeOrigin m_codeOrigin; |
465 | }; | |
466 | ||
467 | Vector<PropertyAccessRecord, 4> m_propertyAccesses; | |
468 | Vector<JSCallRecord, 4> m_jsCalls; | |
93a37866 A |
469 | Vector<OSRExitCompilationInfo> m_exitCompilationInfo; |
470 | Vector<Vector<Label> > m_exitSiteLabels; | |
6fe7ccc8 | 471 | unsigned m_currentCodeOriginIndex; |
14957cd0 A |
472 | }; |
473 | ||
474 | } } // namespace JSC::DFG | |
475 | ||
476 | #endif | |
477 | #endif | |
478 |