]>
Commit | Line | Data |
---|---|---|
9dae56ea | 1 | /* |
ed1e77d3 | 2 | * Copyright (C) 2008, 2012-2015 Apple Inc. All rights reserved. |
9dae56ea 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 JIT_h | |
27 | #define JIT_h | |
28 | ||
9dae56ea A |
29 | #if ENABLE(JIT) |
30 | ||
ba379fdc A |
31 | // We've run into some problems where changing the size of the class JIT leads to |
32 | // performance fluctuations. Try forcing alignment in an attempt to stabalize this. | |
33 | #if COMPILER(GCC) | |
34 | #define JIT_CLASS_ALIGNMENT __attribute__ ((aligned (32))) | |
35 | #else | |
36 | #define JIT_CLASS_ALIGNMENT | |
37 | #endif | |
9dae56ea | 38 | |
14957cd0 | 39 | #define ASSERT_JIT_OFFSET(actual, expected) ASSERT_WITH_MESSAGE(actual == expected, "JIT Offset \"%s\" should be %d, not %d.\n", #expected, static_cast<int>(expected), static_cast<int>(actual)); |
f9bf01c6 | 40 | |
ba379fdc | 41 | #include "CodeBlock.h" |
6fe7ccc8 | 42 | #include "CompactJITCodeMap.h" |
9dae56ea | 43 | #include "Interpreter.h" |
93a37866 | 44 | #include "JITDisassembler.h" |
81345200 | 45 | #include "JITInlineCacheGenerator.h" |
4e4e5a6f | 46 | #include "JSInterfaceJIT.h" |
9dae56ea | 47 | #include "Opcode.h" |
93a37866 | 48 | #include "ResultType.h" |
81345200 | 49 | #include "SamplingTool.h" |
93a37866 | 50 | #include "UnusedPointer.h" |
9dae56ea | 51 | |
9dae56ea A |
52 | namespace JSC { |
53 | ||
81345200 | 54 | class ArrayAllocationProfile; |
ed1e77d3 | 55 | class CallLinkInfo; |
9dae56ea | 56 | class CodeBlock; |
6fe7ccc8 | 57 | class FunctionExecutable; |
ba379fdc | 58 | class JIT; |
81345200 | 59 | class Identifier; |
9dae56ea | 60 | class Interpreter; |
93a37866 A |
61 | class JSScope; |
62 | class JSStack; | |
63 | class MarkedAllocator; | |
9dae56ea | 64 | class Register; |
9dae56ea A |
65 | class StructureChain; |
66 | ||
9dae56ea A |
67 | struct Instruction; |
68 | struct OperandTypes; | |
69 | struct PolymorphicAccessStructureList; | |
f9bf01c6 A |
70 | struct SimpleJumpTable; |
71 | struct StringJumpTable; | |
9dae56ea A |
72 | struct StructureStubInfo; |
73 | ||
9dae56ea | 74 | struct CallRecord { |
ba379fdc | 75 | MacroAssembler::Call from; |
14957cd0 | 76 | unsigned bytecodeOffset; |
9dae56ea A |
77 | void* to; |
78 | ||
79 | CallRecord() | |
80 | { | |
81 | } | |
82 | ||
14957cd0 | 83 | CallRecord(MacroAssembler::Call from, unsigned bytecodeOffset, void* to = 0) |
9dae56ea | 84 | : from(from) |
14957cd0 | 85 | , bytecodeOffset(bytecodeOffset) |
9dae56ea A |
86 | , to(to) |
87 | { | |
88 | } | |
89 | }; | |
90 | ||
91 | struct JumpTable { | |
92 | MacroAssembler::Jump from; | |
14957cd0 | 93 | unsigned toBytecodeOffset; |
9dae56ea A |
94 | |
95 | JumpTable(MacroAssembler::Jump f, unsigned t) | |
96 | : from(f) | |
14957cd0 | 97 | , toBytecodeOffset(t) |
9dae56ea A |
98 | { |
99 | } | |
100 | }; | |
101 | ||
102 | struct SlowCaseEntry { | |
103 | MacroAssembler::Jump from; | |
104 | unsigned to; | |
105 | unsigned hint; | |
106 | ||
107 | SlowCaseEntry(MacroAssembler::Jump f, unsigned t, unsigned h = 0) | |
108 | : from(f) | |
109 | , to(t) | |
110 | , hint(h) | |
111 | { | |
112 | } | |
113 | }; | |
114 | ||
115 | struct SwitchRecord { | |
116 | enum Type { | |
117 | Immediate, | |
118 | Character, | |
119 | String | |
120 | }; | |
121 | ||
122 | Type type; | |
123 | ||
124 | union { | |
125 | SimpleJumpTable* simpleJumpTable; | |
126 | StringJumpTable* stringJumpTable; | |
127 | } jumpTable; | |
128 | ||
14957cd0 | 129 | unsigned bytecodeOffset; |
9dae56ea A |
130 | unsigned defaultOffset; |
131 | ||
14957cd0 | 132 | SwitchRecord(SimpleJumpTable* jumpTable, unsigned bytecodeOffset, unsigned defaultOffset, Type type) |
9dae56ea | 133 | : type(type) |
14957cd0 | 134 | , bytecodeOffset(bytecodeOffset) |
9dae56ea A |
135 | , defaultOffset(defaultOffset) |
136 | { | |
137 | this->jumpTable.simpleJumpTable = jumpTable; | |
138 | } | |
139 | ||
14957cd0 | 140 | SwitchRecord(StringJumpTable* jumpTable, unsigned bytecodeOffset, unsigned defaultOffset) |
9dae56ea | 141 | : type(String) |
14957cd0 | 142 | , bytecodeOffset(bytecodeOffset) |
9dae56ea A |
143 | , defaultOffset(defaultOffset) |
144 | { | |
145 | this->jumpTable.stringJumpTable = jumpTable; | |
146 | } | |
147 | }; | |
148 | ||
93a37866 A |
149 | struct ByValCompilationInfo { |
150 | ByValCompilationInfo() { } | |
151 | ||
152 | ByValCompilationInfo(unsigned bytecodeIndex, MacroAssembler::PatchableJump badTypeJump, JITArrayMode arrayMode, MacroAssembler::Label doneTarget) | |
153 | : bytecodeIndex(bytecodeIndex) | |
154 | , badTypeJump(badTypeJump) | |
155 | , arrayMode(arrayMode) | |
156 | , doneTarget(doneTarget) | |
6fe7ccc8 | 157 | { |
6fe7ccc8 | 158 | } |
93a37866 A |
159 | |
160 | unsigned bytecodeIndex; | |
161 | MacroAssembler::PatchableJump badTypeJump; | |
162 | JITArrayMode arrayMode; | |
163 | MacroAssembler::Label doneTarget; | |
164 | MacroAssembler::Label slowPathTarget; | |
165 | MacroAssembler::Call returnAddress; | |
9dae56ea A |
166 | }; |
167 | ||
81345200 | 168 | struct CallCompilationInfo { |
9dae56ea | 169 | MacroAssembler::DataLabelPtr hotPathBegin; |
ba379fdc A |
170 | MacroAssembler::Call hotPathOther; |
171 | MacroAssembler::Call callReturnLocation; | |
81345200 | 172 | CallLinkInfo* callLinkInfo; |
9dae56ea A |
173 | }; |
174 | ||
ba379fdc A |
175 | // Near calls can only be patched to other JIT code, regular calls can be patched to JIT code or relinked to stub functions. |
176 | void ctiPatchNearCallByReturnAddress(CodeBlock* codeblock, ReturnAddressPtr returnAddress, MacroAssemblerCodePtr newCalleeFunction); | |
177 | void ctiPatchCallByReturnAddress(CodeBlock* codeblock, ReturnAddressPtr returnAddress, MacroAssemblerCodePtr newCalleeFunction); | |
178 | void ctiPatchCallByReturnAddress(CodeBlock* codeblock, ReturnAddressPtr returnAddress, FunctionPtr newCalleeFunction); | |
9dae56ea | 179 | |
4e4e5a6f | 180 | class JIT : private JSInterfaceJIT { |
81345200 | 181 | friend class JITSlowPathCall; |
ba379fdc A |
182 | friend class JITStubCall; |
183 | ||
9dae56ea A |
184 | using MacroAssembler::Jump; |
185 | using MacroAssembler::JumpList; | |
186 | using MacroAssembler::Label; | |
187 | ||
93a37866 | 188 | static const uintptr_t patchGetByIdDefaultStructure = unusedPointer; |
14957cd0 | 189 | static const int patchGetByIdDefaultOffset = 0; |
9dae56ea A |
190 | // Magic number - initial offset cannot be representable as a signed 8bit value, or the X86Assembler |
191 | // will compress the displacement, and we may not be able to fit a patched offset. | |
14957cd0 | 192 | static const int patchPutByIdDefaultOffset = 256; |
9dae56ea | 193 | |
9dae56ea | 194 | public: |
81345200 | 195 | static CompilationResult compile(VM* vm, CodeBlock* codeBlock, JITCompilationEffort effort) |
93a37866 | 196 | { |
81345200 | 197 | return JIT(vm, codeBlock).privateCompile(effort); |
93a37866 A |
198 | } |
199 | ||
93a37866 A |
200 | static void compileGetByVal(VM* vm, CodeBlock* codeBlock, ByValInfo* byValInfo, ReturnAddressPtr returnAddress, JITArrayMode arrayMode) |
201 | { | |
202 | JIT jit(vm, codeBlock); | |
203 | jit.m_bytecodeOffset = byValInfo->bytecodeIndex; | |
204 | jit.privateCompileGetByVal(byValInfo, returnAddress, arrayMode); | |
205 | } | |
9dae56ea | 206 | |
93a37866 | 207 | static void compilePutByVal(VM* vm, CodeBlock* codeBlock, ByValInfo* byValInfo, ReturnAddressPtr returnAddress, JITArrayMode arrayMode) |
9dae56ea | 208 | { |
93a37866 A |
209 | JIT jit(vm, codeBlock); |
210 | jit.m_bytecodeOffset = byValInfo->bytecodeIndex; | |
211 | jit.privateCompilePutByVal(byValInfo, returnAddress, arrayMode); | |
9dae56ea | 212 | } |
81345200 A |
213 | |
214 | static void compileDirectPutByVal(VM* vm, CodeBlock* codeBlock, ByValInfo* byValInfo, ReturnAddressPtr returnAddress, JITArrayMode arrayMode) | |
215 | { | |
216 | JIT jit(vm, codeBlock); | |
217 | jit.m_bytecodeOffset = byValInfo->bytecodeIndex; | |
218 | jit.privateCompilePutByVal(byValInfo, returnAddress, arrayMode); | |
219 | } | |
9dae56ea | 220 | |
ed1e77d3 A |
221 | static void compileHasIndexedProperty(VM* vm, CodeBlock* codeBlock, ByValInfo* byValInfo, ReturnAddressPtr returnAddress, JITArrayMode arrayMode) |
222 | { | |
223 | JIT jit(vm, codeBlock); | |
224 | jit.m_bytecodeOffset = byValInfo->bytecodeIndex; | |
225 | jit.privateCompileHasIndexedProperty(byValInfo, returnAddress, arrayMode); | |
226 | } | |
227 | ||
93a37866 | 228 | static CodeRef compileCTINativeCall(VM* vm, NativeFunction func) |
14957cd0 | 229 | { |
93a37866 | 230 | if (!vm->canUseJIT()) { |
6fe7ccc8 | 231 | return CodeRef::createLLIntCodeRef(llint_native_call_trampoline); |
6fe7ccc8 | 232 | } |
93a37866 A |
233 | JIT jit(vm, 0); |
234 | return jit.privateCompileCTINativeCall(vm, func); | |
14957cd0 A |
235 | } |
236 | ||
81345200 A |
237 | static unsigned frameRegisterCountFor(CodeBlock*); |
238 | static int stackPointerOffsetFor(CodeBlock*); | |
9dae56ea | 239 | |
9dae56ea | 240 | private: |
93a37866 | 241 | JIT(VM*, CodeBlock* = 0); |
9dae56ea A |
242 | |
243 | void privateCompileMainPass(); | |
244 | void privateCompileLinkPass(); | |
245 | void privateCompileSlowCases(); | |
81345200 | 246 | CompilationResult privateCompile(JITCompilationEffort); |
93a37866 | 247 | |
93a37866 A |
248 | void privateCompileGetByVal(ByValInfo*, ReturnAddressPtr, JITArrayMode); |
249 | void privateCompilePutByVal(ByValInfo*, ReturnAddressPtr, JITArrayMode); | |
250 | ||
ed1e77d3 A |
251 | void privateCompileHasIndexedProperty(ByValInfo*, ReturnAddressPtr, JITArrayMode); |
252 | ||
93a37866 A |
253 | Label privateCompileCTINativeCall(VM*, bool isConstruct = false); |
254 | CodeRef privateCompileCTINativeCall(VM*, NativeFunction); | |
ba379fdc | 255 | void privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress); |
9dae56ea | 256 | |
81345200 A |
257 | // Add a call out from JIT code, without an exception check. |
258 | Call appendCall(const FunctionPtr& function) | |
259 | { | |
260 | Call functionCall = call(); | |
261 | m_calls.append(CallRecord(functionCall, m_bytecodeOffset, function.value())); | |
262 | return functionCall; | |
263 | } | |
264 | ||
265 | #if OS(WINDOWS) && CPU(X86_64) | |
266 | Call appendCallWithSlowPathReturnType(const FunctionPtr& function) | |
267 | { | |
268 | Call functionCall = callWithSlowPathReturnType(); | |
269 | m_calls.append(CallRecord(functionCall, m_bytecodeOffset, function.value())); | |
270 | return functionCall; | |
271 | } | |
272 | #endif | |
273 | ||
274 | void exceptionCheck(Jump jumpToHandler) | |
275 | { | |
276 | m_exceptionChecks.append(jumpToHandler); | |
277 | } | |
278 | ||
279 | void exceptionCheck() | |
280 | { | |
281 | m_exceptionChecks.append(emitExceptionCheck()); | |
282 | } | |
283 | ||
284 | void exceptionCheckWithCallFrameRollback() | |
285 | { | |
286 | m_exceptionChecksWithCallFrameRollback.append(emitExceptionCheck()); | |
287 | } | |
288 | ||
289 | void privateCompileExceptionHandlers(); | |
6fe7ccc8 | 290 | |
9dae56ea | 291 | void addSlowCase(Jump); |
ba379fdc | 292 | void addSlowCase(JumpList); |
6fe7ccc8 | 293 | void addSlowCase(); |
9dae56ea A |
294 | void addJump(Jump, int); |
295 | void emitJumpSlowToHot(Jump, int); | |
296 | ||
6fe7ccc8 A |
297 | void compileOpCall(OpcodeID, Instruction*, unsigned callLinkInfoIndex); |
298 | void compileOpCallSlowCase(OpcodeID, Instruction*, Vector<SlowCaseEntry>::iterator&, unsigned callLinkInfoIndex); | |
ed1e77d3 | 299 | void compileSetupVarargsFrame(Instruction*, CallLinkInfo*); |
81345200 A |
300 | void compileCallEval(Instruction*); |
301 | void compileCallEvalSlowCase(Instruction*, Vector<SlowCaseEntry>::iterator&); | |
302 | void emitPutCallResult(Instruction*); | |
ba379fdc | 303 | |
9dae56ea A |
304 | enum CompileOpStrictEqType { OpStrictEq, OpNStrictEq }; |
305 | void compileOpStrictEq(Instruction* instruction, CompileOpStrictEqType type); | |
81345200 | 306 | bool isOperandConstantImmediateDouble(int src); |
f9bf01c6 | 307 | |
6fe7ccc8 A |
308 | void emitLoadDouble(int index, FPRegisterID value); |
309 | void emitLoadInt32ToDouble(int index, FPRegisterID value); | |
ed1e77d3 | 310 | Jump emitJumpIfCellObject(RegisterID cellReg); |
81345200 | 311 | Jump emitJumpIfCellNotObject(RegisterID cellReg); |
9dae56ea | 312 | |
81345200 | 313 | enum WriteBarrierMode { UnconditionalWriteBarrier, ShouldFilterBase, ShouldFilterValue, ShouldFilterBaseAndValue }; |
6fe7ccc8 A |
314 | // value register in write barrier is used before any scratch registers |
315 | // so may safely be the same as either of the scratch registers. | |
81345200 A |
316 | void emitWriteBarrier(unsigned owner, unsigned value, WriteBarrierMode); |
317 | void emitWriteBarrier(JSCell* owner, unsigned value, WriteBarrierMode); | |
318 | void emitWriteBarrier(JSCell* owner); | |
6fe7ccc8 | 319 | |
93a37866 A |
320 | template<typename StructureType> // StructureType can be RegisterID or ImmPtr. |
321 | void emitAllocateJSObject(RegisterID allocator, StructureType, RegisterID result, RegisterID scratch); | |
6fe7ccc8 | 322 | |
6fe7ccc8 A |
323 | // This assumes that the value to profile is in regT0 and that regT3 is available for |
324 | // scratch. | |
325 | void emitValueProfilingSite(ValueProfile*); | |
326 | void emitValueProfilingSite(unsigned bytecodeOffset); | |
327 | void emitValueProfilingSite(); | |
81345200 A |
328 | void emitArrayProfilingSiteWithCell(RegisterID cell, RegisterID indexingType, ArrayProfile*); |
329 | void emitArrayProfilingSiteForBytecodeIndexWithCell(RegisterID cell, RegisterID indexingType, unsigned bytecodeIndex); | |
93a37866 A |
330 | void emitArrayProfileStoreToHoleSpecialCase(ArrayProfile*); |
331 | void emitArrayProfileOutOfBoundsSpecialCase(ArrayProfile*); | |
332 | ||
333 | JITArrayMode chooseArrayMode(ArrayProfile*); | |
334 | ||
335 | // Property is in regT1, base is in regT0. regT2 contains indexing type. | |
336 | // Property is int-checked and zero extended. Base is cell checked. | |
337 | // Structure is already profiled. Returns the slow cases. Fall-through | |
338 | // case contains result in regT0, and it is not yet profiled. | |
ed1e77d3 A |
339 | JumpList emitInt32Load(Instruction* instruction, PatchableJump& badType) { return emitContiguousLoad(instruction, badType, Int32Shape); } |
340 | JumpList emitDoubleLoad(Instruction*, PatchableJump& badType); | |
341 | JumpList emitContiguousLoad(Instruction*, PatchableJump& badType, IndexingType expectedShape = ContiguousShape); | |
342 | JumpList emitArrayStorageLoad(Instruction*, PatchableJump& badType); | |
343 | JumpList emitLoadForArrayMode(Instruction*, JITArrayMode, PatchableJump& badType); | |
344 | ||
93a37866 A |
345 | JumpList emitInt32GetByVal(Instruction* instruction, PatchableJump& badType) { return emitContiguousGetByVal(instruction, badType, Int32Shape); } |
346 | JumpList emitDoubleGetByVal(Instruction*, PatchableJump& badType); | |
347 | JumpList emitContiguousGetByVal(Instruction*, PatchableJump& badType, IndexingType expectedShape = ContiguousShape); | |
348 | JumpList emitArrayStorageGetByVal(Instruction*, PatchableJump& badType); | |
ed1e77d3 A |
349 | JumpList emitDirectArgumentsGetByVal(Instruction*, PatchableJump& badType); |
350 | JumpList emitScopedArgumentsGetByVal(Instruction*, PatchableJump& badType); | |
81345200 A |
351 | JumpList emitIntTypedArrayGetByVal(Instruction*, PatchableJump& badType, TypedArrayType); |
352 | JumpList emitFloatTypedArrayGetByVal(Instruction*, PatchableJump& badType, TypedArrayType); | |
93a37866 A |
353 | |
354 | // Property is in regT0, base is in regT0. regT2 contains indecing type. | |
355 | // The value to store is not yet loaded. Property is int-checked and | |
356 | // zero-extended. Base is cell checked. Structure is already profiled. | |
357 | // returns the slow cases. | |
358 | JumpList emitInt32PutByVal(Instruction* currentInstruction, PatchableJump& badType) | |
359 | { | |
360 | return emitGenericContiguousPutByVal(currentInstruction, badType, Int32Shape); | |
361 | } | |
362 | JumpList emitDoublePutByVal(Instruction* currentInstruction, PatchableJump& badType) | |
363 | { | |
364 | return emitGenericContiguousPutByVal(currentInstruction, badType, DoubleShape); | |
365 | } | |
366 | JumpList emitContiguousPutByVal(Instruction* currentInstruction, PatchableJump& badType) | |
367 | { | |
368 | return emitGenericContiguousPutByVal(currentInstruction, badType); | |
369 | } | |
370 | JumpList emitGenericContiguousPutByVal(Instruction*, PatchableJump& badType, IndexingType indexingShape = ContiguousShape); | |
371 | JumpList emitArrayStoragePutByVal(Instruction*, PatchableJump& badType); | |
81345200 A |
372 | JumpList emitIntTypedArrayPutByVal(Instruction*, PatchableJump& badType, TypedArrayType); |
373 | JumpList emitFloatTypedArrayPutByVal(Instruction*, PatchableJump& badType, TypedArrayType); | |
93a37866 A |
374 | |
375 | enum FinalObjectMode { MayBeFinal, KnownNotFinal }; | |
6fe7ccc8 | 376 | |
81345200 A |
377 | template <typename T> Jump branchStructure(RelationalCondition, T leftHandSide, Structure*); |
378 | ||
ba379fdc | 379 | #if USE(JSVALUE32_64) |
81345200 | 380 | bool getOperandConstantImmediateInt(int op1, int op2, int& op, int32_t& constant); |
ba379fdc | 381 | |
6fe7ccc8 A |
382 | void emitLoadTag(int index, RegisterID tag); |
383 | void emitLoadPayload(int index, RegisterID payload); | |
ba379fdc A |
384 | |
385 | void emitLoad(const JSValue& v, RegisterID tag, RegisterID payload); | |
6fe7ccc8 A |
386 | void emitLoad(int index, RegisterID tag, RegisterID payload, RegisterID base = callFrameRegister); |
387 | void emitLoad2(int index1, RegisterID tag1, RegisterID payload1, int index2, RegisterID tag2, RegisterID payload2); | |
388 | ||
389 | void emitStore(int index, RegisterID tag, RegisterID payload, RegisterID base = callFrameRegister); | |
390 | void emitStore(int index, const JSValue constant, RegisterID base = callFrameRegister); | |
391 | void emitStoreInt32(int index, RegisterID payload, bool indexIsInt32 = false); | |
392 | void emitStoreInt32(int index, TrustedImm32 payload, bool indexIsInt32 = false); | |
6fe7ccc8 A |
393 | void emitStoreCell(int index, RegisterID payload, bool indexIsCell = false); |
394 | void emitStoreBool(int index, RegisterID payload, bool indexIsBool = false); | |
395 | void emitStoreDouble(int index, FPRegisterID value); | |
ba379fdc | 396 | |
6fe7ccc8 A |
397 | void emitJumpSlowCaseIfNotJSCell(int virtualRegisterIndex); |
398 | void emitJumpSlowCaseIfNotJSCell(int virtualRegisterIndex, RegisterID tag); | |
ba379fdc | 399 | |
81345200 | 400 | void compileGetByIdHotPath(const Identifier*); |
93a37866 A |
401 | void compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, PropertyOffset cachedOffset); |
402 | void compileGetDirectOffset(JSObject* base, RegisterID resultTag, RegisterID resultPayload, PropertyOffset cachedOffset); | |
403 | void compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, RegisterID offset, FinalObjectMode = MayBeFinal); | |
404 | void compilePutDirectOffset(RegisterID base, RegisterID valueTag, RegisterID valuePayload, PropertyOffset cachedOffset); | |
9dae56ea | 405 | |
ba379fdc | 406 | // Arithmetic opcode helpers |
81345200 A |
407 | void emitAdd32Constant(int dst, int op, int32_t constant, ResultType opType); |
408 | void emitSub32Constant(int dst, int op, int32_t constant, ResultType opType); | |
409 | void emitBinaryDoubleOp(OpcodeID, int dst, int op1, int op2, OperandTypes, JumpList& notInt32Op1, JumpList& notInt32Op2, bool op1IsInRegisters = true, bool op2IsInRegisters = true); | |
9dae56ea | 410 | |
ba379fdc A |
411 | #else // USE(JSVALUE32_64) |
412 | void emitGetVirtualRegister(int src, RegisterID dst); | |
81345200 | 413 | void emitGetVirtualRegister(VirtualRegister src, RegisterID dst); |
ba379fdc | 414 | void emitGetVirtualRegisters(int src1, RegisterID dst1, int src2, RegisterID dst2); |
81345200 A |
415 | void emitGetVirtualRegisters(VirtualRegister src1, RegisterID dst1, VirtualRegister src2, RegisterID dst2); |
416 | void emitPutVirtualRegister(int dst, RegisterID from = regT0); | |
417 | void emitPutVirtualRegister(VirtualRegister dst, RegisterID from = regT0); | |
418 | void emitStoreCell(int dst, RegisterID payload, bool /* only used in JSValue32_64 */ = false) | |
419 | { | |
420 | emitPutVirtualRegister(dst, payload); | |
421 | } | |
422 | void emitStoreCell(VirtualRegister dst, RegisterID payload) | |
6fe7ccc8 A |
423 | { |
424 | emitPutVirtualRegister(dst, payload); | |
425 | } | |
9dae56ea | 426 | |
81345200 | 427 | int32_t getConstantOperandImmediateInt(int src); |
9dae56ea A |
428 | |
429 | Jump emitJumpIfJSCell(RegisterID); | |
430 | Jump emitJumpIfBothJSCells(RegisterID, RegisterID, RegisterID); | |
431 | void emitJumpSlowCaseIfJSCell(RegisterID); | |
9dae56ea A |
432 | void emitJumpSlowCaseIfNotJSCell(RegisterID); |
433 | void emitJumpSlowCaseIfNotJSCell(RegisterID, int VReg); | |
6fe7ccc8 A |
434 | Jump emitJumpIfImmediateInteger(RegisterID); |
435 | Jump emitJumpIfNotImmediateInteger(RegisterID); | |
436 | Jump emitJumpIfNotImmediateIntegers(RegisterID, RegisterID, RegisterID); | |
9dae56ea | 437 | void emitJumpSlowCaseIfNotImmediateInteger(RegisterID); |
f9bf01c6 | 438 | void emitJumpSlowCaseIfNotImmediateNumber(RegisterID); |
9dae56ea A |
439 | void emitJumpSlowCaseIfNotImmediateIntegers(RegisterID, RegisterID, RegisterID); |
440 | ||
9dae56ea | 441 | void emitFastArithReTagImmediate(RegisterID src, RegisterID dest); |
9dae56ea A |
442 | |
443 | void emitTagAsBoolImmediate(RegisterID reg); | |
81345200 A |
444 | void compileBinaryArithOp(OpcodeID, int dst, int src1, int src2, OperandTypes opi); |
445 | void compileBinaryArithOpSlowCase(Instruction*, OpcodeID, Vector<SlowCaseEntry>::iterator&, int dst, int src1, int src2, OperandTypes, bool op1HasImmediateIntFastCase, bool op2HasImmediateIntFastCase); | |
ba379fdc | 446 | |
81345200 | 447 | void compileGetByIdHotPath(int baseVReg, const Identifier*); |
93a37866 A |
448 | void compileGetDirectOffset(RegisterID base, RegisterID result, PropertyOffset cachedOffset); |
449 | void compileGetDirectOffset(JSObject* base, RegisterID result, PropertyOffset cachedOffset); | |
450 | void compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID offset, RegisterID scratch, FinalObjectMode = MayBeFinal); | |
451 | void compilePutDirectOffset(RegisterID base, RegisterID value, PropertyOffset cachedOffset); | |
f9bf01c6 | 452 | |
ba379fdc A |
453 | #endif // USE(JSVALUE32_64) |
454 | ||
81345200 A |
455 | void emit_compareAndJump(OpcodeID, int op1, int op2, unsigned target, RelationalCondition); |
456 | void emit_compareAndJumpSlow(int op1, int op2, unsigned target, DoubleCondition, size_t (JIT_OPERATION *operation)(ExecState*, EncodedJSValue, EncodedJSValue), bool invert, Vector<SlowCaseEntry>::iterator&); | |
ed1e77d3 A |
457 | |
458 | void assertStackPointerOffset(); | |
6fe7ccc8 | 459 | |
ba379fdc A |
460 | void emit_op_add(Instruction*); |
461 | void emit_op_bitand(Instruction*); | |
ba379fdc A |
462 | void emit_op_bitor(Instruction*); |
463 | void emit_op_bitxor(Instruction*); | |
464 | void emit_op_call(Instruction*); | |
465 | void emit_op_call_eval(Instruction*); | |
466 | void emit_op_call_varargs(Instruction*); | |
81345200 | 467 | void emit_op_construct_varargs(Instruction*); |
ba379fdc A |
468 | void emit_op_catch(Instruction*); |
469 | void emit_op_construct(Instruction*); | |
14957cd0 | 470 | void emit_op_create_this(Instruction*); |
81345200 | 471 | void emit_op_to_this(Instruction*); |
ed1e77d3 A |
472 | void emit_op_create_direct_arguments(Instruction*); |
473 | void emit_op_create_scoped_arguments(Instruction*); | |
474 | void emit_op_create_out_of_band_arguments(Instruction*); | |
475 | void emit_op_check_tdz(Instruction*); | |
ba379fdc A |
476 | void emit_op_debug(Instruction*); |
477 | void emit_op_del_by_id(Instruction*); | |
478 | void emit_op_div(Instruction*); | |
479 | void emit_op_end(Instruction*); | |
480 | void emit_op_enter(Instruction*); | |
ed1e77d3 A |
481 | void emit_op_create_lexical_environment(Instruction*); |
482 | void emit_op_get_scope(Instruction*); | |
ba379fdc A |
483 | void emit_op_eq(Instruction*); |
484 | void emit_op_eq_null(Instruction*); | |
485 | void emit_op_get_by_id(Instruction*); | |
14957cd0 | 486 | void emit_op_get_arguments_length(Instruction*); |
ba379fdc | 487 | void emit_op_get_by_val(Instruction*); |
14957cd0 | 488 | void emit_op_get_argument_by_val(Instruction*); |
14957cd0 A |
489 | void emit_op_init_lazy_reg(Instruction*); |
490 | void emit_op_check_has_instance(Instruction*); | |
ba379fdc | 491 | void emit_op_instanceof(Instruction*); |
6fe7ccc8 A |
492 | void emit_op_is_undefined(Instruction*); |
493 | void emit_op_is_boolean(Instruction*); | |
494 | void emit_op_is_number(Instruction*); | |
495 | void emit_op_is_string(Instruction*); | |
ed1e77d3 | 496 | void emit_op_is_object(Instruction*); |
ba379fdc A |
497 | void emit_op_jeq_null(Instruction*); |
498 | void emit_op_jfalse(Instruction*); | |
499 | void emit_op_jmp(Instruction*); | |
ba379fdc A |
500 | void emit_op_jneq_null(Instruction*); |
501 | void emit_op_jneq_ptr(Instruction*); | |
f9bf01c6 | 502 | void emit_op_jless(Instruction*); |
6fe7ccc8 A |
503 | void emit_op_jlesseq(Instruction*); |
504 | void emit_op_jgreater(Instruction*); | |
505 | void emit_op_jgreatereq(Instruction*); | |
506 | void emit_op_jnless(Instruction*); | |
ba379fdc | 507 | void emit_op_jnlesseq(Instruction*); |
6fe7ccc8 A |
508 | void emit_op_jngreater(Instruction*); |
509 | void emit_op_jngreatereq(Instruction*); | |
ba379fdc | 510 | void emit_op_jtrue(Instruction*); |
6fe7ccc8 | 511 | void emit_op_loop_hint(Instruction*); |
ba379fdc | 512 | void emit_op_lshift(Instruction*); |
ba379fdc A |
513 | void emit_op_mod(Instruction*); |
514 | void emit_op_mov(Instruction*); | |
515 | void emit_op_mul(Instruction*); | |
516 | void emit_op_negate(Instruction*); | |
517 | void emit_op_neq(Instruction*); | |
518 | void emit_op_neq_null(Instruction*); | |
519 | void emit_op_new_array(Instruction*); | |
93a37866 | 520 | void emit_op_new_array_with_size(Instruction*); |
14957cd0 | 521 | void emit_op_new_array_buffer(Instruction*); |
ba379fdc A |
522 | void emit_op_new_func(Instruction*); |
523 | void emit_op_new_func_exp(Instruction*); | |
524 | void emit_op_new_object(Instruction*); | |
525 | void emit_op_new_regexp(Instruction*); | |
ba379fdc A |
526 | void emit_op_not(Instruction*); |
527 | void emit_op_nstricteq(Instruction*); | |
528 | void emit_op_pop_scope(Instruction*); | |
93a37866 A |
529 | void emit_op_dec(Instruction*); |
530 | void emit_op_inc(Instruction*); | |
ba379fdc A |
531 | void emit_op_profile_did_call(Instruction*); |
532 | void emit_op_profile_will_call(Instruction*); | |
ed1e77d3 A |
533 | void emit_op_profile_type(Instruction*); |
534 | void emit_op_profile_control_flow(Instruction*); | |
93a37866 A |
535 | void emit_op_push_name_scope(Instruction*); |
536 | void emit_op_push_with_scope(Instruction*); | |
ba379fdc A |
537 | void emit_op_put_by_id(Instruction*); |
538 | void emit_op_put_by_index(Instruction*); | |
539 | void emit_op_put_by_val(Instruction*); | |
ed1e77d3 A |
540 | void emit_op_put_getter_by_id(Instruction*); |
541 | void emit_op_put_setter_by_id(Instruction*); | |
6fe7ccc8 | 542 | void emit_op_put_getter_setter(Instruction*); |
93a37866 | 543 | void emit_op_init_global_const(Instruction*); |
ba379fdc A |
544 | void emit_op_ret(Instruction*); |
545 | void emit_op_rshift(Instruction*); | |
ba379fdc A |
546 | void emit_op_strcat(Instruction*); |
547 | void emit_op_stricteq(Instruction*); | |
548 | void emit_op_sub(Instruction*); | |
549 | void emit_op_switch_char(Instruction*); | |
550 | void emit_op_switch_imm(Instruction*); | |
551 | void emit_op_switch_string(Instruction*); | |
ba379fdc A |
552 | void emit_op_tear_off_arguments(Instruction*); |
553 | void emit_op_throw(Instruction*); | |
93a37866 A |
554 | void emit_op_throw_static_error(Instruction*); |
555 | void emit_op_to_number(Instruction*); | |
ed1e77d3 | 556 | void emit_op_to_string(Instruction*); |
ba379fdc A |
557 | void emit_op_to_primitive(Instruction*); |
558 | void emit_op_unexpected_load(Instruction*); | |
81345200 | 559 | void emit_op_unsigned(Instruction*); |
4e4e5a6f | 560 | void emit_op_urshift(Instruction*); |
ed1e77d3 A |
561 | void emit_op_get_enumerable_length(Instruction*); |
562 | void emit_op_has_generic_property(Instruction*); | |
563 | void emit_op_has_structure_property(Instruction*); | |
564 | void emit_op_has_indexed_property(Instruction*); | |
565 | void emit_op_get_direct_pname(Instruction*); | |
566 | void emit_op_get_property_enumerator(Instruction*); | |
567 | void emit_op_enumerator_structure_pname(Instruction*); | |
568 | void emit_op_enumerator_generic_pname(Instruction*); | |
569 | void emit_op_to_index_string(Instruction*); | |
ba379fdc A |
570 | |
571 | void emitSlow_op_add(Instruction*, Vector<SlowCaseEntry>::iterator&); | |
572 | void emitSlow_op_bitand(Instruction*, Vector<SlowCaseEntry>::iterator&); | |
ba379fdc A |
573 | void emitSlow_op_bitor(Instruction*, Vector<SlowCaseEntry>::iterator&); |
574 | void emitSlow_op_bitxor(Instruction*, Vector<SlowCaseEntry>::iterator&); | |
575 | void emitSlow_op_call(Instruction*, Vector<SlowCaseEntry>::iterator&); | |
576 | void emitSlow_op_call_eval(Instruction*, Vector<SlowCaseEntry>::iterator&); | |
577 | void emitSlow_op_call_varargs(Instruction*, Vector<SlowCaseEntry>::iterator&); | |
81345200 | 578 | void emitSlow_op_construct_varargs(Instruction*, Vector<SlowCaseEntry>::iterator&); |
ba379fdc | 579 | void emitSlow_op_construct(Instruction*, Vector<SlowCaseEntry>::iterator&); |
81345200 | 580 | void emitSlow_op_to_this(Instruction*, Vector<SlowCaseEntry>::iterator&); |
6fe7ccc8 | 581 | void emitSlow_op_create_this(Instruction*, Vector<SlowCaseEntry>::iterator&); |
ed1e77d3 | 582 | void emitSlow_op_check_tdz(Instruction*, Vector<SlowCaseEntry>::iterator&); |
ba379fdc A |
583 | void emitSlow_op_div(Instruction*, Vector<SlowCaseEntry>::iterator&); |
584 | void emitSlow_op_eq(Instruction*, Vector<SlowCaseEntry>::iterator&); | |
81345200 | 585 | void emitSlow_op_get_callee(Instruction*, Vector<SlowCaseEntry>::iterator&); |
ba379fdc | 586 | void emitSlow_op_get_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&); |
14957cd0 | 587 | void emitSlow_op_get_arguments_length(Instruction*, Vector<SlowCaseEntry>::iterator&); |
ba379fdc | 588 | void emitSlow_op_get_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&); |
14957cd0 | 589 | void emitSlow_op_get_argument_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&); |
14957cd0 | 590 | void emitSlow_op_check_has_instance(Instruction*, Vector<SlowCaseEntry>::iterator&); |
ba379fdc A |
591 | void emitSlow_op_instanceof(Instruction*, Vector<SlowCaseEntry>::iterator&); |
592 | void emitSlow_op_jfalse(Instruction*, Vector<SlowCaseEntry>::iterator&); | |
f9bf01c6 | 593 | void emitSlow_op_jless(Instruction*, Vector<SlowCaseEntry>::iterator&); |
6fe7ccc8 A |
594 | void emitSlow_op_jlesseq(Instruction*, Vector<SlowCaseEntry>::iterator&); |
595 | void emitSlow_op_jgreater(Instruction*, Vector<SlowCaseEntry>::iterator&); | |
596 | void emitSlow_op_jgreatereq(Instruction*, Vector<SlowCaseEntry>::iterator&); | |
597 | void emitSlow_op_jnless(Instruction*, Vector<SlowCaseEntry>::iterator&); | |
ba379fdc | 598 | void emitSlow_op_jnlesseq(Instruction*, Vector<SlowCaseEntry>::iterator&); |
6fe7ccc8 A |
599 | void emitSlow_op_jngreater(Instruction*, Vector<SlowCaseEntry>::iterator&); |
600 | void emitSlow_op_jngreatereq(Instruction*, Vector<SlowCaseEntry>::iterator&); | |
ba379fdc | 601 | void emitSlow_op_jtrue(Instruction*, Vector<SlowCaseEntry>::iterator&); |
93a37866 | 602 | void emitSlow_op_loop_hint(Instruction*, Vector<SlowCaseEntry>::iterator&); |
ba379fdc | 603 | void emitSlow_op_lshift(Instruction*, Vector<SlowCaseEntry>::iterator&); |
ba379fdc A |
604 | void emitSlow_op_mod(Instruction*, Vector<SlowCaseEntry>::iterator&); |
605 | void emitSlow_op_mul(Instruction*, Vector<SlowCaseEntry>::iterator&); | |
606 | void emitSlow_op_negate(Instruction*, Vector<SlowCaseEntry>::iterator&); | |
607 | void emitSlow_op_neq(Instruction*, Vector<SlowCaseEntry>::iterator&); | |
6fe7ccc8 | 608 | void emitSlow_op_new_object(Instruction*, Vector<SlowCaseEntry>::iterator&); |
ba379fdc A |
609 | void emitSlow_op_not(Instruction*, Vector<SlowCaseEntry>::iterator&); |
610 | void emitSlow_op_nstricteq(Instruction*, Vector<SlowCaseEntry>::iterator&); | |
93a37866 A |
611 | void emitSlow_op_dec(Instruction*, Vector<SlowCaseEntry>::iterator&); |
612 | void emitSlow_op_inc(Instruction*, Vector<SlowCaseEntry>::iterator&); | |
ba379fdc A |
613 | void emitSlow_op_put_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&); |
614 | void emitSlow_op_put_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&); | |
ba379fdc A |
615 | void emitSlow_op_rshift(Instruction*, Vector<SlowCaseEntry>::iterator&); |
616 | void emitSlow_op_stricteq(Instruction*, Vector<SlowCaseEntry>::iterator&); | |
617 | void emitSlow_op_sub(Instruction*, Vector<SlowCaseEntry>::iterator&); | |
93a37866 | 618 | void emitSlow_op_to_number(Instruction*, Vector<SlowCaseEntry>::iterator&); |
ed1e77d3 | 619 | void emitSlow_op_to_string(Instruction*, Vector<SlowCaseEntry>::iterator&); |
ba379fdc | 620 | void emitSlow_op_to_primitive(Instruction*, Vector<SlowCaseEntry>::iterator&); |
81345200 | 621 | void emitSlow_op_unsigned(Instruction*, Vector<SlowCaseEntry>::iterator&); |
4e4e5a6f | 622 | void emitSlow_op_urshift(Instruction*, Vector<SlowCaseEntry>::iterator&); |
ed1e77d3 A |
623 | void emitSlow_op_has_indexed_property(Instruction*, Vector<SlowCaseEntry>::iterator&); |
624 | void emitSlow_op_has_structure_property(Instruction*, Vector<SlowCaseEntry>::iterator&); | |
625 | void emitSlow_op_get_direct_pname(Instruction*, Vector<SlowCaseEntry>::iterator&); | |
93a37866 | 626 | |
81345200 A |
627 | void emit_op_resolve_scope(Instruction*); |
628 | void emit_op_get_from_scope(Instruction*); | |
629 | void emit_op_put_to_scope(Instruction*); | |
ed1e77d3 A |
630 | void emit_op_get_from_arguments(Instruction*); |
631 | void emit_op_put_to_arguments(Instruction*); | |
81345200 A |
632 | void emitSlow_op_resolve_scope(Instruction*, Vector<SlowCaseEntry>::iterator&); |
633 | void emitSlow_op_get_from_scope(Instruction*, Vector<SlowCaseEntry>::iterator&); | |
634 | void emitSlow_op_put_to_scope(Instruction*, Vector<SlowCaseEntry>::iterator&); | |
93a37866 | 635 | |
4e4e5a6f A |
636 | void emitRightShift(Instruction*, bool isUnsigned); |
637 | void emitRightShiftSlowCase(Instruction*, Vector<SlowCaseEntry>::iterator&, bool isUnsigned); | |
ba379fdc | 638 | |
81345200 | 639 | void emitVarInjectionCheck(bool needsVarInjectionChecks); |
ed1e77d3 | 640 | void emitResolveClosure(int dst, int scope, bool needsVarInjectionChecks, unsigned depth); |
81345200 A |
641 | void emitLoadWithStructureCheck(int scope, Structure** structureSlot); |
642 | void emitGetGlobalProperty(uintptr_t* operandSlot); | |
643 | void emitGetGlobalVar(uintptr_t operand); | |
644 | void emitGetClosureVar(int scope, uintptr_t operand); | |
645 | void emitPutGlobalProperty(uintptr_t* operandSlot, int value); | |
ed1e77d3 A |
646 | void emitNotifyWrite(WatchpointSet*); |
647 | void emitPutGlobalVar(uintptr_t operand, int value, WatchpointSet*); | |
648 | void emitPutClosureVar(int scope, uintptr_t operand, int value, WatchpointSet*); | |
81345200 A |
649 | |
650 | void emitInitRegister(int dst); | |
ba379fdc | 651 | |
93a37866 | 652 | void emitPutIntToCallFrameHeader(RegisterID from, JSStack::CallFrameHeaderEntry); |
ba379fdc | 653 | |
81345200 A |
654 | JSValue getConstantOperand(int src); |
655 | bool isOperandConstantImmediateInt(int src); | |
656 | bool isOperandConstantImmediateChar(int src); | |
14957cd0 | 657 | |
ba379fdc A |
658 | Jump getSlowCase(Vector<SlowCaseEntry>::iterator& iter) |
659 | { | |
660 | return iter++->from; | |
661 | } | |
662 | void linkSlowCase(Vector<SlowCaseEntry>::iterator& iter) | |
663 | { | |
664 | iter->from.link(this); | |
665 | ++iter; | |
666 | } | |
6fe7ccc8 A |
667 | void linkDummySlowCase(Vector<SlowCaseEntry>::iterator& iter) |
668 | { | |
669 | ASSERT(!iter->from.isSet()); | |
670 | ++iter; | |
671 | } | |
672 | void linkSlowCaseIfNotJSCell(Vector<SlowCaseEntry>::iterator&, int virtualRegisterIndex); | |
ba379fdc | 673 | |
81345200 A |
674 | MacroAssembler::Call appendCallWithExceptionCheck(const FunctionPtr&); |
675 | #if OS(WINDOWS) && CPU(X86_64) | |
676 | MacroAssembler::Call appendCallWithExceptionCheckAndSlowPathReturnType(const FunctionPtr&); | |
677 | #endif | |
678 | MacroAssembler::Call appendCallWithCallFrameRollbackOnException(const FunctionPtr&); | |
679 | MacroAssembler::Call appendCallWithExceptionCheckSetJSValueResult(const FunctionPtr&, int); | |
680 | MacroAssembler::Call appendCallWithExceptionCheckSetJSValueResultWithProfile(const FunctionPtr&, int); | |
681 | ||
682 | enum WithProfileTag { WithProfile }; | |
683 | ||
684 | MacroAssembler::Call callOperation(C_JITOperation_E); | |
685 | MacroAssembler::Call callOperation(C_JITOperation_EO, GPRReg); | |
ed1e77d3 A |
686 | MacroAssembler::Call callOperation(C_JITOperation_EL, GPRReg); |
687 | MacroAssembler::Call callOperation(C_JITOperation_EL, TrustedImmPtr); | |
81345200 A |
688 | MacroAssembler::Call callOperation(C_JITOperation_ESt, Structure*); |
689 | MacroAssembler::Call callOperation(C_JITOperation_EZ, int32_t); | |
ed1e77d3 | 690 | MacroAssembler::Call callOperation(Z_JITOperation_EJZZ, GPRReg, int32_t, int32_t); |
81345200 A |
691 | MacroAssembler::Call callOperation(J_JITOperation_E, int); |
692 | MacroAssembler::Call callOperation(J_JITOperation_EAapJ, int, ArrayAllocationProfile*, GPRReg); | |
693 | MacroAssembler::Call callOperation(J_JITOperation_EAapJcpZ, int, ArrayAllocationProfile*, GPRReg, int32_t); | |
694 | MacroAssembler::Call callOperation(J_JITOperation_EAapJcpZ, int, ArrayAllocationProfile*, const JSValue*, int32_t); | |
695 | MacroAssembler::Call callOperation(J_JITOperation_EC, int, JSCell*); | |
696 | MacroAssembler::Call callOperation(V_JITOperation_EC, JSCell*); | |
697 | MacroAssembler::Call callOperation(J_JITOperation_EJ, int, GPRReg); | |
698 | #if USE(JSVALUE64) | |
ed1e77d3 | 699 | MacroAssembler::Call callOperation(WithProfileTag, J_JITOperation_ESsiJI, int, StructureStubInfo*, GPRReg, UniquedStringImpl*); |
81345200 | 700 | #else |
ed1e77d3 | 701 | MacroAssembler::Call callOperation(WithProfileTag, J_JITOperation_ESsiJI, int, StructureStubInfo*, GPRReg, GPRReg, UniquedStringImpl*); |
81345200 A |
702 | #endif |
703 | MacroAssembler::Call callOperation(J_JITOperation_EJIdc, int, GPRReg, const Identifier*); | |
704 | MacroAssembler::Call callOperation(J_JITOperation_EJJ, int, GPRReg, GPRReg); | |
ed1e77d3 A |
705 | MacroAssembler::Call callOperation(J_JITOperation_EJJAp, int, GPRReg, GPRReg, ArrayProfile*); |
706 | MacroAssembler::Call callOperation(C_JITOperation_EJsc, GPRReg); | |
707 | MacroAssembler::Call callOperation(J_JITOperation_EJscC, int, GPRReg, JSCell*); | |
708 | MacroAssembler::Call callOperation(C_JITOperation_EJscZ, GPRReg, int32_t); | |
709 | MacroAssembler::Call callOperation(C_JITOperation_EJscZ, int, GPRReg, int32_t); | |
81345200 A |
710 | #if USE(JSVALUE64) |
711 | MacroAssembler::Call callOperation(WithProfileTag, J_JITOperation_EJJ, int, GPRReg, GPRReg); | |
712 | #else | |
713 | MacroAssembler::Call callOperation(WithProfileTag, J_JITOperation_EJJ, int, GPRReg, GPRReg, GPRReg, GPRReg); | |
714 | #endif | |
715 | MacroAssembler::Call callOperation(J_JITOperation_EP, int, void*); | |
716 | MacroAssembler::Call callOperation(WithProfileTag, J_JITOperation_EPc, int, Instruction*); | |
717 | MacroAssembler::Call callOperation(J_JITOperation_EZ, int, int32_t); | |
ed1e77d3 | 718 | MacroAssembler::Call callOperation(J_JITOperation_EZZ, int, int32_t, int32_t); |
81345200 A |
719 | MacroAssembler::Call callOperation(P_JITOperation_EJS, GPRReg, size_t); |
720 | MacroAssembler::Call callOperation(S_JITOperation_ECC, RegisterID, RegisterID); | |
721 | MacroAssembler::Call callOperation(S_JITOperation_EJ, RegisterID); | |
722 | MacroAssembler::Call callOperation(S_JITOperation_EJJ, RegisterID, RegisterID); | |
723 | MacroAssembler::Call callOperation(S_JITOperation_EOJss, RegisterID, RegisterID); | |
724 | MacroAssembler::Call callOperation(Sprt_JITOperation_EZ, int32_t); | |
725 | MacroAssembler::Call callOperation(V_JITOperation_E); | |
726 | MacroAssembler::Call callOperation(V_JITOperation_EC, RegisterID); | |
727 | MacroAssembler::Call callOperation(V_JITOperation_ECC, RegisterID, RegisterID); | |
ed1e77d3 | 728 | MacroAssembler::Call callOperation(V_JITOperation_ECIC, RegisterID, const Identifier*, RegisterID); |
81345200 | 729 | MacroAssembler::Call callOperation(V_JITOperation_ECICC, RegisterID, const Identifier*, RegisterID, RegisterID); |
ed1e77d3 A |
730 | MacroAssembler::Call callOperation(J_JITOperation_EE, RegisterID); |
731 | MacroAssembler::Call callOperation(V_JITOperation_EZSymtabJ, int, SymbolTable*, RegisterID); | |
81345200 A |
732 | MacroAssembler::Call callOperation(V_JITOperation_EJ, RegisterID); |
733 | #if USE(JSVALUE64) | |
734 | MacroAssembler::Call callOperationNoExceptionCheck(V_JITOperation_EJ, RegisterID); | |
735 | #else | |
736 | MacroAssembler::Call callOperationNoExceptionCheck(V_JITOperation_EJ, RegisterID, RegisterID); | |
737 | #endif | |
ed1e77d3 | 738 | MacroAssembler::Call callOperation(V_JITOperation_EJIdJ, RegisterID, const Identifier*, RegisterID); |
81345200 A |
739 | MacroAssembler::Call callOperation(V_JITOperation_EJIdJJ, RegisterID, const Identifier*, RegisterID, RegisterID); |
740 | #if USE(JSVALUE64) | |
ed1e77d3 A |
741 | MacroAssembler::Call callOperation(F_JITOperation_EFJZZ, RegisterID, RegisterID, int32_t, RegisterID); |
742 | MacroAssembler::Call callOperation(V_JITOperation_ESsiJJI, StructureStubInfo*, RegisterID, RegisterID, UniquedStringImpl*); | |
81345200 | 743 | #else |
ed1e77d3 | 744 | MacroAssembler::Call callOperation(V_JITOperation_ESsiJJI, StructureStubInfo*, RegisterID, RegisterID, RegisterID, RegisterID, UniquedStringImpl*); |
81345200 A |
745 | #endif |
746 | MacroAssembler::Call callOperation(V_JITOperation_EJJJ, RegisterID, RegisterID, RegisterID); | |
ed1e77d3 | 747 | MacroAssembler::Call callOperation(V_JITOperation_EJJJAp, RegisterID, RegisterID, RegisterID, ArrayProfile*); |
81345200 A |
748 | MacroAssembler::Call callOperation(V_JITOperation_EJZJ, RegisterID, int32_t, RegisterID); |
749 | MacroAssembler::Call callOperation(V_JITOperation_EJZ, RegisterID, int32_t); | |
750 | MacroAssembler::Call callOperation(V_JITOperation_EPc, Instruction*); | |
751 | MacroAssembler::Call callOperation(V_JITOperation_EZ, int32_t); | |
ed1e77d3 | 752 | MacroAssembler::Call callOperation(V_JITOperation_EZJ, int, GPRReg); |
81345200 | 753 | MacroAssembler::Call callOperationWithCallFrameRollbackOnException(J_JITOperation_E); |
81345200 A |
754 | MacroAssembler::Call callOperationWithCallFrameRollbackOnException(V_JITOperation_ECb, CodeBlock*); |
755 | MacroAssembler::Call callOperationWithCallFrameRollbackOnException(Z_JITOperation_E); | |
756 | #if USE(JSVALUE32_64) | |
ed1e77d3 A |
757 | MacroAssembler::Call callOperation(F_JITOperation_EFJZZ, RegisterID, RegisterID, RegisterID, int32_t, RegisterID); |
758 | MacroAssembler::Call callOperation(Z_JITOperation_EJZZ, GPRReg, GPRReg, int32_t, int32_t); | |
81345200 A |
759 | MacroAssembler::Call callOperation(J_JITOperation_EAapJ, int, ArrayAllocationProfile*, GPRReg, GPRReg); |
760 | MacroAssembler::Call callOperation(J_JITOperation_EJ, int, GPRReg, GPRReg); | |
761 | MacroAssembler::Call callOperation(J_JITOperation_EJIdc, int, GPRReg, GPRReg, const Identifier*); | |
762 | MacroAssembler::Call callOperation(J_JITOperation_EJJ, int, GPRReg, GPRReg, GPRReg, GPRReg); | |
ed1e77d3 | 763 | MacroAssembler::Call callOperation(J_JITOperation_EJJAp, int, GPRReg, GPRReg, GPRReg, GPRReg, ArrayProfile*); |
81345200 A |
764 | MacroAssembler::Call callOperation(P_JITOperation_EJS, GPRReg, GPRReg, size_t); |
765 | MacroAssembler::Call callOperation(S_JITOperation_EJ, RegisterID, RegisterID); | |
766 | MacroAssembler::Call callOperation(S_JITOperation_EJJ, RegisterID, RegisterID, RegisterID, RegisterID); | |
ed1e77d3 | 767 | MacroAssembler::Call callOperation(V_JITOperation_EZSymtabJ, int, SymbolTable*, RegisterID, RegisterID); |
81345200 A |
768 | MacroAssembler::Call callOperation(V_JITOperation_EJ, RegisterID, RegisterID); |
769 | MacroAssembler::Call callOperation(V_JITOperation_EJJJ, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID); | |
ed1e77d3 | 770 | MacroAssembler::Call callOperation(V_JITOperation_EJJJAp, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID, ArrayProfile*); |
81345200 A |
771 | MacroAssembler::Call callOperation(V_JITOperation_EJZ, RegisterID, RegisterID, int32_t); |
772 | MacroAssembler::Call callOperation(V_JITOperation_EJZJ, RegisterID, RegisterID, int32_t, RegisterID, RegisterID); | |
ed1e77d3 | 773 | MacroAssembler::Call callOperation(V_JITOperation_EZJ, int32_t, RegisterID, RegisterID); |
81345200 A |
774 | #endif |
775 | ||
ba379fdc | 776 | Jump checkStructure(RegisterID reg, Structure* structure); |
9dae56ea | 777 | |
6fe7ccc8 | 778 | void updateTopCallFrame(); |
9dae56ea | 779 | |
ba379fdc | 780 | Call emitNakedCall(CodePtr function = CodePtr()); |
9dae56ea | 781 | |
4e4e5a6f A |
782 | // Loads the character value of a single character string into dst. |
783 | void emitLoadCharacterString(RegisterID src, RegisterID dst, JumpList& failures); | |
784 | ||
6fe7ccc8 | 785 | #if ENABLE(DFG_JIT) |
93a37866 | 786 | void emitEnterOptimizationCheck(); |
6fe7ccc8 | 787 | #else |
93a37866 | 788 | void emitEnterOptimizationCheck() { } |
6fe7ccc8 | 789 | #endif |
93a37866 | 790 | |
9dae56ea | 791 | #ifndef NDEBUG |
81345200 | 792 | void printBytecodeOperandTypes(int src1, int src2); |
9dae56ea A |
793 | #endif |
794 | ||
ba379fdc A |
795 | #if ENABLE(SAMPLING_FLAGS) |
796 | void setSamplingFlag(int32_t); | |
797 | void clearSamplingFlag(int32_t); | |
9dae56ea | 798 | #endif |
ba379fdc A |
799 | |
800 | #if ENABLE(SAMPLING_COUNTERS) | |
6fe7ccc8 | 801 | void emitCount(AbstractSamplingCounter&, int32_t = 1); |
9dae56ea A |
802 | #endif |
803 | ||
804 | #if ENABLE(OPCODE_SAMPLING) | |
ba379fdc | 805 | void sampleInstruction(Instruction*, bool = false); |
9dae56ea | 806 | #endif |
ba379fdc A |
807 | |
808 | #if ENABLE(CODEBLOCK_SAMPLING) | |
809 | void sampleCodeBlock(CodeBlock*); | |
9dae56ea | 810 | #else |
ba379fdc | 811 | void sampleCodeBlock(CodeBlock*) {} |
9dae56ea A |
812 | #endif |
813 | ||
6fe7ccc8 A |
814 | #if ENABLE(DFG_JIT) |
815 | bool canBeOptimized() { return m_canBeOptimized; } | |
93a37866 A |
816 | bool canBeOptimizedOrInlined() { return m_canBeOptimizedOrInlined; } |
817 | bool shouldEmitProfiling() { return m_shouldEmitProfiling; } | |
6fe7ccc8 A |
818 | #else |
819 | bool canBeOptimized() { return false; } | |
93a37866 | 820 | bool canBeOptimizedOrInlined() { return false; } |
6fe7ccc8 A |
821 | // Enables use of value profiler with tiered compilation turned off, |
822 | // in which case all code gets profiled. | |
93a37866 | 823 | bool shouldEmitProfiling() { return false; } |
6fe7ccc8 A |
824 | #endif |
825 | ||
9dae56ea | 826 | Interpreter* m_interpreter; |
9dae56ea A |
827 | |
828 | Vector<CallRecord> m_calls; | |
829 | Vector<Label> m_labels; | |
81345200 A |
830 | Vector<JITGetByIdGenerator> m_getByIds; |
831 | Vector<JITPutByIdGenerator> m_putByIds; | |
93a37866 | 832 | Vector<ByValCompilationInfo> m_byValCompilationInfo; |
81345200 | 833 | Vector<CallCompilationInfo> m_callCompilationInfo; |
9dae56ea A |
834 | Vector<JumpTable> m_jmpTable; |
835 | ||
14957cd0 | 836 | unsigned m_bytecodeOffset; |
9dae56ea A |
837 | Vector<SlowCaseEntry> m_slowCases; |
838 | Vector<SwitchRecord> m_switches; | |
839 | ||
81345200 A |
840 | JumpList m_exceptionChecks; |
841 | JumpList m_exceptionChecksWithCallFrameRollback; | |
842 | ||
843 | unsigned m_getByIdIndex; | |
844 | unsigned m_putByIdIndex; | |
93a37866 | 845 | unsigned m_byValInstructionIndex; |
ba379fdc A |
846 | unsigned m_callLinkInfoIndex; |
847 | ||
ed1e77d3 | 848 | std::unique_ptr<JITDisassembler> m_disassembler; |
93a37866 | 849 | RefPtr<Profiler::Compilation> m_compilation; |
14957cd0 | 850 | WeakRandom m_randomGenerator; |
93a37866 | 851 | static CodeRef stringGetByValStubGenerator(VM*); |
6fe7ccc8 | 852 | |
6fe7ccc8 | 853 | bool m_canBeOptimized; |
93a37866 A |
854 | bool m_canBeOptimizedOrInlined; |
855 | bool m_shouldEmitProfiling; | |
ba379fdc | 856 | } JIT_CLASS_ALIGNMENT; |
f9bf01c6 | 857 | |
ba379fdc | 858 | } // namespace JSC |
9dae56ea A |
859 | |
860 | #endif // ENABLE(JIT) | |
861 | ||
862 | #endif // JIT_h |