2 * Copyright (C) 2008, 2012, 2013, 2014 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.
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.
34 #define JIT_CLASS_ALIGNMENT __attribute__ ((aligned (32)))
36 #define JIT_CLASS_ALIGNMENT
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));
41 #include "CodeBlock.h"
42 #include "CompactJITCodeMap.h"
43 #include "Interpreter.h"
44 #include "JITDisassembler.h"
45 #include "JITInlineCacheGenerator.h"
46 #include "JSInterfaceJIT.h"
47 #include "LegacyProfiler.h"
49 #include "ResultType.h"
50 #include "SamplingTool.h"
51 #include "UnusedPointer.h"
55 class ArrayAllocationProfile
;
57 class FunctionExecutable
;
59 class JSPropertyNameIterator
;
64 class MarkedAllocator
;
71 struct PolymorphicAccessStructureList
;
72 struct SimpleJumpTable
;
73 struct StringJumpTable
;
74 struct StructureStubInfo
;
77 MacroAssembler::Call from
;
78 unsigned bytecodeOffset
;
85 CallRecord(MacroAssembler::Call from
, unsigned bytecodeOffset
, void* to
= 0)
87 , bytecodeOffset(bytecodeOffset
)
94 MacroAssembler::Jump from
;
95 unsigned toBytecodeOffset
;
97 JumpTable(MacroAssembler::Jump f
, unsigned t
)
104 struct SlowCaseEntry
{
105 MacroAssembler::Jump from
;
109 SlowCaseEntry(MacroAssembler::Jump f
, unsigned t
, unsigned h
= 0)
117 struct SwitchRecord
{
127 SimpleJumpTable
* simpleJumpTable
;
128 StringJumpTable
* stringJumpTable
;
131 unsigned bytecodeOffset
;
132 unsigned defaultOffset
;
134 SwitchRecord(SimpleJumpTable
* jumpTable
, unsigned bytecodeOffset
, unsigned defaultOffset
, Type type
)
136 , bytecodeOffset(bytecodeOffset
)
137 , defaultOffset(defaultOffset
)
139 this->jumpTable
.simpleJumpTable
= jumpTable
;
142 SwitchRecord(StringJumpTable
* jumpTable
, unsigned bytecodeOffset
, unsigned defaultOffset
)
144 , bytecodeOffset(bytecodeOffset
)
145 , defaultOffset(defaultOffset
)
147 this->jumpTable
.stringJumpTable
= jumpTable
;
151 struct ByValCompilationInfo
{
152 ByValCompilationInfo() { }
154 ByValCompilationInfo(unsigned bytecodeIndex
, MacroAssembler::PatchableJump badTypeJump
, JITArrayMode arrayMode
, MacroAssembler::Label doneTarget
)
155 : bytecodeIndex(bytecodeIndex
)
156 , badTypeJump(badTypeJump
)
157 , arrayMode(arrayMode
)
158 , doneTarget(doneTarget
)
162 unsigned bytecodeIndex
;
163 MacroAssembler::PatchableJump badTypeJump
;
164 JITArrayMode arrayMode
;
165 MacroAssembler::Label doneTarget
;
166 MacroAssembler::Label slowPathTarget
;
167 MacroAssembler::Call returnAddress
;
170 struct CallCompilationInfo
{
171 MacroAssembler::DataLabelPtr hotPathBegin
;
172 MacroAssembler::Call hotPathOther
;
173 MacroAssembler::Call callReturnLocation
;
174 CallLinkInfo
* callLinkInfo
;
177 // Near calls can only be patched to other JIT code, regular calls can be patched to JIT code or relinked to stub functions.
178 void ctiPatchNearCallByReturnAddress(CodeBlock
* codeblock
, ReturnAddressPtr returnAddress
, MacroAssemblerCodePtr newCalleeFunction
);
179 void ctiPatchCallByReturnAddress(CodeBlock
* codeblock
, ReturnAddressPtr returnAddress
, MacroAssemblerCodePtr newCalleeFunction
);
180 void ctiPatchCallByReturnAddress(CodeBlock
* codeblock
, ReturnAddressPtr returnAddress
, FunctionPtr newCalleeFunction
);
182 class JIT
: private JSInterfaceJIT
{
183 friend class JITSlowPathCall
;
184 friend class JITStubCall
;
186 using MacroAssembler::Jump
;
187 using MacroAssembler::JumpList
;
188 using MacroAssembler::Label
;
190 static const uintptr_t patchGetByIdDefaultStructure
= unusedPointer
;
191 static const int patchGetByIdDefaultOffset
= 0;
192 // Magic number - initial offset cannot be representable as a signed 8bit value, or the X86Assembler
193 // will compress the displacement, and we may not be able to fit a patched offset.
194 static const int patchPutByIdDefaultOffset
= 256;
197 static CompilationResult
compile(VM
* vm
, CodeBlock
* codeBlock
, JITCompilationEffort effort
)
199 return JIT(vm
, codeBlock
).privateCompile(effort
);
202 static void compileClosureCall(VM
* vm
, CallLinkInfo
* callLinkInfo
, CodeBlock
* callerCodeBlock
, CodeBlock
* calleeCodeBlock
, Structure
* expectedStructure
, ExecutableBase
* expectedExecutable
, MacroAssemblerCodePtr codePtr
)
204 JIT
jit(vm
, callerCodeBlock
);
205 jit
.m_bytecodeOffset
= callLinkInfo
->codeOrigin
.bytecodeIndex
;
206 jit
.privateCompileClosureCall(callLinkInfo
, calleeCodeBlock
, expectedStructure
, expectedExecutable
, codePtr
);
209 static void compileGetByVal(VM
* vm
, CodeBlock
* codeBlock
, ByValInfo
* byValInfo
, ReturnAddressPtr returnAddress
, JITArrayMode arrayMode
)
211 JIT
jit(vm
, codeBlock
);
212 jit
.m_bytecodeOffset
= byValInfo
->bytecodeIndex
;
213 jit
.privateCompileGetByVal(byValInfo
, returnAddress
, arrayMode
);
216 static void compilePutByVal(VM
* vm
, CodeBlock
* codeBlock
, ByValInfo
* byValInfo
, ReturnAddressPtr returnAddress
, JITArrayMode arrayMode
)
218 JIT
jit(vm
, codeBlock
);
219 jit
.m_bytecodeOffset
= byValInfo
->bytecodeIndex
;
220 jit
.privateCompilePutByVal(byValInfo
, returnAddress
, arrayMode
);
223 static void compileDirectPutByVal(VM
* vm
, CodeBlock
* codeBlock
, ByValInfo
* byValInfo
, ReturnAddressPtr returnAddress
, JITArrayMode arrayMode
)
225 JIT
jit(vm
, codeBlock
);
226 jit
.m_bytecodeOffset
= byValInfo
->bytecodeIndex
;
227 jit
.privateCompilePutByVal(byValInfo
, returnAddress
, arrayMode
);
230 static CodeRef
compileCTINativeCall(VM
* vm
, NativeFunction func
)
232 if (!vm
->canUseJIT()) {
233 return CodeRef::createLLIntCodeRef(llint_native_call_trampoline
);
236 return jit
.privateCompileCTINativeCall(vm
, func
);
239 static unsigned frameRegisterCountFor(CodeBlock
*);
240 static int stackPointerOffsetFor(CodeBlock
*);
243 JIT(VM
*, CodeBlock
* = 0);
245 void privateCompileMainPass();
246 void privateCompileLinkPass();
247 void privateCompileSlowCases();
248 CompilationResult
privateCompile(JITCompilationEffort
);
250 void privateCompileClosureCall(CallLinkInfo
*, CodeBlock
* calleeCodeBlock
, Structure
*, ExecutableBase
*, MacroAssemblerCodePtr
);
252 void privateCompileGetByVal(ByValInfo
*, ReturnAddressPtr
, JITArrayMode
);
253 void privateCompilePutByVal(ByValInfo
*, ReturnAddressPtr
, JITArrayMode
);
255 Label
privateCompileCTINativeCall(VM
*, bool isConstruct
= false);
256 CodeRef
privateCompileCTINativeCall(VM
*, NativeFunction
);
257 void privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress
);
259 // Add a call out from JIT code, without an exception check.
260 Call
appendCall(const FunctionPtr
& function
)
262 Call functionCall
= call();
263 m_calls
.append(CallRecord(functionCall
, m_bytecodeOffset
, function
.value()));
267 #if OS(WINDOWS) && CPU(X86_64)
268 Call
appendCallWithSlowPathReturnType(const FunctionPtr
& function
)
270 Call functionCall
= callWithSlowPathReturnType();
271 m_calls
.append(CallRecord(functionCall
, m_bytecodeOffset
, function
.value()));
276 void exceptionCheck(Jump jumpToHandler
)
278 m_exceptionChecks
.append(jumpToHandler
);
281 void exceptionCheck()
283 m_exceptionChecks
.append(emitExceptionCheck());
286 void exceptionCheckWithCallFrameRollback()
288 m_exceptionChecksWithCallFrameRollback
.append(emitExceptionCheck());
291 void privateCompileExceptionHandlers();
293 void addSlowCase(Jump
);
294 void addSlowCase(JumpList
);
296 void addJump(Jump
, int);
297 void emitJumpSlowToHot(Jump
, int);
299 void compileOpCall(OpcodeID
, Instruction
*, unsigned callLinkInfoIndex
);
300 void compileOpCallSlowCase(OpcodeID
, Instruction
*, Vector
<SlowCaseEntry
>::iterator
&, unsigned callLinkInfoIndex
);
301 void compileLoadVarargs(Instruction
*);
302 void compileCallEval(Instruction
*);
303 void compileCallEvalSlowCase(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
304 void emitPutCallResult(Instruction
*);
306 enum CompileOpStrictEqType
{ OpStrictEq
, OpNStrictEq
};
307 void compileOpStrictEq(Instruction
* instruction
, CompileOpStrictEqType type
);
308 bool isOperandConstantImmediateDouble(int src
);
310 void emitLoadDouble(int index
, FPRegisterID value
);
311 void emitLoadInt32ToDouble(int index
, FPRegisterID value
);
312 Jump
emitJumpIfCellNotObject(RegisterID cellReg
);
314 enum WriteBarrierMode
{ UnconditionalWriteBarrier
, ShouldFilterBase
, ShouldFilterValue
, ShouldFilterBaseAndValue
};
315 // value register in write barrier is used before any scratch registers
316 // so may safely be the same as either of the scratch registers.
317 void emitWriteBarrier(unsigned owner
, unsigned value
, WriteBarrierMode
);
318 void emitWriteBarrier(JSCell
* owner
, unsigned value
, WriteBarrierMode
);
319 void emitWriteBarrier(JSCell
* owner
);
321 template<typename StructureType
> // StructureType can be RegisterID or ImmPtr.
322 void emitAllocateJSObject(RegisterID allocator
, StructureType
, RegisterID result
, RegisterID scratch
);
324 // This assumes that the value to profile is in regT0 and that regT3 is available for
326 void emitValueProfilingSite(ValueProfile
*);
327 void emitValueProfilingSite(unsigned bytecodeOffset
);
328 void emitValueProfilingSite();
329 void emitArrayProfilingSiteWithCell(RegisterID cell
, RegisterID indexingType
, ArrayProfile
*);
330 void emitArrayProfilingSiteForBytecodeIndexWithCell(RegisterID cell
, RegisterID indexingType
, unsigned bytecodeIndex
);
331 void emitArrayProfileStoreToHoleSpecialCase(ArrayProfile
*);
332 void emitArrayProfileOutOfBoundsSpecialCase(ArrayProfile
*);
334 JITArrayMode
chooseArrayMode(ArrayProfile
*);
336 // Property is in regT1, base is in regT0. regT2 contains indexing type.
337 // Property is int-checked and zero extended. Base is cell checked.
338 // Structure is already profiled. Returns the slow cases. Fall-through
339 // case contains result in regT0, and it is not yet profiled.
340 JumpList
emitInt32GetByVal(Instruction
* instruction
, PatchableJump
& badType
) { return emitContiguousGetByVal(instruction
, badType
, Int32Shape
); }
341 JumpList
emitDoubleGetByVal(Instruction
*, PatchableJump
& badType
);
342 JumpList
emitContiguousGetByVal(Instruction
*, PatchableJump
& badType
, IndexingType expectedShape
= ContiguousShape
);
343 JumpList
emitArrayStorageGetByVal(Instruction
*, PatchableJump
& badType
);
344 JumpList
emitIntTypedArrayGetByVal(Instruction
*, PatchableJump
& badType
, TypedArrayType
);
345 JumpList
emitFloatTypedArrayGetByVal(Instruction
*, PatchableJump
& badType
, TypedArrayType
);
347 // Property is in regT0, base is in regT0. regT2 contains indecing type.
348 // The value to store is not yet loaded. Property is int-checked and
349 // zero-extended. Base is cell checked. Structure is already profiled.
350 // returns the slow cases.
351 JumpList
emitInt32PutByVal(Instruction
* currentInstruction
, PatchableJump
& badType
)
353 return emitGenericContiguousPutByVal(currentInstruction
, badType
, Int32Shape
);
355 JumpList
emitDoublePutByVal(Instruction
* currentInstruction
, PatchableJump
& badType
)
357 return emitGenericContiguousPutByVal(currentInstruction
, badType
, DoubleShape
);
359 JumpList
emitContiguousPutByVal(Instruction
* currentInstruction
, PatchableJump
& badType
)
361 return emitGenericContiguousPutByVal(currentInstruction
, badType
);
363 JumpList
emitGenericContiguousPutByVal(Instruction
*, PatchableJump
& badType
, IndexingType indexingShape
= ContiguousShape
);
364 JumpList
emitArrayStoragePutByVal(Instruction
*, PatchableJump
& badType
);
365 JumpList
emitIntTypedArrayPutByVal(Instruction
*, PatchableJump
& badType
, TypedArrayType
);
366 JumpList
emitFloatTypedArrayPutByVal(Instruction
*, PatchableJump
& badType
, TypedArrayType
);
368 enum FinalObjectMode
{ MayBeFinal
, KnownNotFinal
};
370 template <typename T
> Jump
branchStructure(RelationalCondition
, T leftHandSide
, Structure
*);
372 #if USE(JSVALUE32_64)
373 bool getOperandConstantImmediateInt(int op1
, int op2
, int& op
, int32_t& constant
);
375 void emitLoadTag(int index
, RegisterID tag
);
376 void emitLoadPayload(int index
, RegisterID payload
);
378 void emitLoad(const JSValue
& v
, RegisterID tag
, RegisterID payload
);
379 void emitLoad(int index
, RegisterID tag
, RegisterID payload
, RegisterID base
= callFrameRegister
);
380 void emitLoad2(int index1
, RegisterID tag1
, RegisterID payload1
, int index2
, RegisterID tag2
, RegisterID payload2
);
382 void emitStore(int index
, RegisterID tag
, RegisterID payload
, RegisterID base
= callFrameRegister
);
383 void emitStore(int index
, const JSValue constant
, RegisterID base
= callFrameRegister
);
384 void emitStoreInt32(int index
, RegisterID payload
, bool indexIsInt32
= false);
385 void emitStoreInt32(int index
, TrustedImm32 payload
, bool indexIsInt32
= false);
386 void emitStoreCell(int index
, RegisterID payload
, bool indexIsCell
= false);
387 void emitStoreBool(int index
, RegisterID payload
, bool indexIsBool
= false);
388 void emitStoreDouble(int index
, FPRegisterID value
);
390 void emitJumpSlowCaseIfNotJSCell(int virtualRegisterIndex
);
391 void emitJumpSlowCaseIfNotJSCell(int virtualRegisterIndex
, RegisterID tag
);
393 void compileGetByIdHotPath(const Identifier
*);
394 void compileGetDirectOffset(RegisterID base
, RegisterID resultTag
, RegisterID resultPayload
, PropertyOffset cachedOffset
);
395 void compileGetDirectOffset(JSObject
* base
, RegisterID resultTag
, RegisterID resultPayload
, PropertyOffset cachedOffset
);
396 void compileGetDirectOffset(RegisterID base
, RegisterID resultTag
, RegisterID resultPayload
, RegisterID offset
, FinalObjectMode
= MayBeFinal
);
397 void compilePutDirectOffset(RegisterID base
, RegisterID valueTag
, RegisterID valuePayload
, PropertyOffset cachedOffset
);
399 // Arithmetic opcode helpers
400 void emitAdd32Constant(int dst
, int op
, int32_t constant
, ResultType opType
);
401 void emitSub32Constant(int dst
, int op
, int32_t constant
, ResultType opType
);
402 void emitBinaryDoubleOp(OpcodeID
, int dst
, int op1
, int op2
, OperandTypes
, JumpList
& notInt32Op1
, JumpList
& notInt32Op2
, bool op1IsInRegisters
= true, bool op2IsInRegisters
= true);
404 #else // USE(JSVALUE32_64)
405 void emitGetVirtualRegister(int src
, RegisterID dst
);
406 void emitGetVirtualRegister(VirtualRegister src
, RegisterID dst
);
407 void emitGetVirtualRegisters(int src1
, RegisterID dst1
, int src2
, RegisterID dst2
);
408 void emitGetVirtualRegisters(VirtualRegister src1
, RegisterID dst1
, VirtualRegister src2
, RegisterID dst2
);
409 void emitPutVirtualRegister(int dst
, RegisterID from
= regT0
);
410 void emitPutVirtualRegister(VirtualRegister dst
, RegisterID from
= regT0
);
411 void emitStoreCell(int dst
, RegisterID payload
, bool /* only used in JSValue32_64 */ = false)
413 emitPutVirtualRegister(dst
, payload
);
415 void emitStoreCell(VirtualRegister dst
, RegisterID payload
)
417 emitPutVirtualRegister(dst
, payload
);
420 int32_t getConstantOperandImmediateInt(int src
);
422 Jump
emitJumpIfJSCell(RegisterID
);
423 Jump
emitJumpIfBothJSCells(RegisterID
, RegisterID
, RegisterID
);
424 void emitJumpSlowCaseIfJSCell(RegisterID
);
425 void emitJumpSlowCaseIfNotJSCell(RegisterID
);
426 void emitJumpSlowCaseIfNotJSCell(RegisterID
, int VReg
);
427 Jump
emitJumpIfImmediateInteger(RegisterID
);
428 Jump
emitJumpIfNotImmediateInteger(RegisterID
);
429 Jump
emitJumpIfNotImmediateIntegers(RegisterID
, RegisterID
, RegisterID
);
430 void emitJumpSlowCaseIfNotImmediateInteger(RegisterID
);
431 void emitJumpSlowCaseIfNotImmediateNumber(RegisterID
);
432 void emitJumpSlowCaseIfNotImmediateIntegers(RegisterID
, RegisterID
, RegisterID
);
434 void emitFastArithReTagImmediate(RegisterID src
, RegisterID dest
);
436 void emitTagAsBoolImmediate(RegisterID reg
);
437 void compileBinaryArithOp(OpcodeID
, int dst
, int src1
, int src2
, OperandTypes opi
);
438 void compileBinaryArithOpSlowCase(Instruction
*, OpcodeID
, Vector
<SlowCaseEntry
>::iterator
&, int dst
, int src1
, int src2
, OperandTypes
, bool op1HasImmediateIntFastCase
, bool op2HasImmediateIntFastCase
);
440 void compileGetByIdHotPath(int baseVReg
, const Identifier
*);
441 void compileGetDirectOffset(RegisterID base
, RegisterID result
, PropertyOffset cachedOffset
);
442 void compileGetDirectOffset(JSObject
* base
, RegisterID result
, PropertyOffset cachedOffset
);
443 void compileGetDirectOffset(RegisterID base
, RegisterID result
, RegisterID offset
, RegisterID scratch
, FinalObjectMode
= MayBeFinal
);
444 void compilePutDirectOffset(RegisterID base
, RegisterID value
, PropertyOffset cachedOffset
);
446 #endif // USE(JSVALUE32_64)
448 void emit_compareAndJump(OpcodeID
, int op1
, int op2
, unsigned target
, RelationalCondition
);
449 void emit_compareAndJumpSlow(int op1
, int op2
, unsigned target
, DoubleCondition
, size_t (JIT_OPERATION
*operation
)(ExecState
*, EncodedJSValue
, EncodedJSValue
), bool invert
, Vector
<SlowCaseEntry
>::iterator
&);
451 void emit_op_touch_entry(Instruction
*);
452 void emit_op_add(Instruction
*);
453 void emit_op_bitand(Instruction
*);
454 void emit_op_bitor(Instruction
*);
455 void emit_op_bitxor(Instruction
*);
456 void emit_op_call(Instruction
*);
457 void emit_op_call_eval(Instruction
*);
458 void emit_op_call_varargs(Instruction
*);
459 void emit_op_construct_varargs(Instruction
*);
460 void emit_op_captured_mov(Instruction
*);
461 void emit_op_catch(Instruction
*);
462 void emit_op_construct(Instruction
*);
463 void emit_op_get_callee(Instruction
*);
464 void emit_op_create_this(Instruction
*);
465 void emit_op_to_this(Instruction
*);
466 void emit_op_create_arguments(Instruction
*);
467 void emit_op_debug(Instruction
*);
468 void emit_op_del_by_id(Instruction
*);
469 void emit_op_div(Instruction
*);
470 void emit_op_end(Instruction
*);
471 void emit_op_enter(Instruction
*);
472 void emit_op_create_activation(Instruction
*);
473 void emit_op_eq(Instruction
*);
474 void emit_op_eq_null(Instruction
*);
475 void emit_op_get_by_id(Instruction
*);
476 void emit_op_get_arguments_length(Instruction
*);
477 void emit_op_get_by_val(Instruction
*);
478 void emit_op_get_argument_by_val(Instruction
*);
479 void emit_op_get_by_pname(Instruction
*);
480 void emit_op_init_lazy_reg(Instruction
*);
481 void emit_op_check_has_instance(Instruction
*);
482 void emit_op_instanceof(Instruction
*);
483 void emit_op_is_undefined(Instruction
*);
484 void emit_op_is_boolean(Instruction
*);
485 void emit_op_is_number(Instruction
*);
486 void emit_op_is_string(Instruction
*);
487 void emit_op_jeq_null(Instruction
*);
488 void emit_op_jfalse(Instruction
*);
489 void emit_op_jmp(Instruction
*);
490 void emit_op_jneq_null(Instruction
*);
491 void emit_op_jneq_ptr(Instruction
*);
492 void emit_op_jless(Instruction
*);
493 void emit_op_jlesseq(Instruction
*);
494 void emit_op_jgreater(Instruction
*);
495 void emit_op_jgreatereq(Instruction
*);
496 void emit_op_jnless(Instruction
*);
497 void emit_op_jnlesseq(Instruction
*);
498 void emit_op_jngreater(Instruction
*);
499 void emit_op_jngreatereq(Instruction
*);
500 void emit_op_jtrue(Instruction
*);
501 void emit_op_loop_hint(Instruction
*);
502 void emit_op_lshift(Instruction
*);
503 void emit_op_mod(Instruction
*);
504 void emit_op_mov(Instruction
*);
505 void emit_op_mul(Instruction
*);
506 void emit_op_negate(Instruction
*);
507 void emit_op_neq(Instruction
*);
508 void emit_op_neq_null(Instruction
*);
509 void emit_op_new_array(Instruction
*);
510 void emit_op_new_array_with_size(Instruction
*);
511 void emit_op_new_array_buffer(Instruction
*);
512 void emit_op_new_func(Instruction
*);
513 void emit_op_new_captured_func(Instruction
*);
514 void emit_op_new_func_exp(Instruction
*);
515 void emit_op_new_object(Instruction
*);
516 void emit_op_new_regexp(Instruction
*);
517 void emit_op_get_pnames(Instruction
*);
518 void emit_op_next_pname(Instruction
*);
519 void emit_op_not(Instruction
*);
520 void emit_op_nstricteq(Instruction
*);
521 void emit_op_pop_scope(Instruction
*);
522 void emit_op_dec(Instruction
*);
523 void emit_op_inc(Instruction
*);
524 void emit_op_profile_did_call(Instruction
*);
525 void emit_op_profile_will_call(Instruction
*);
526 void emit_op_push_name_scope(Instruction
*);
527 void emit_op_push_with_scope(Instruction
*);
528 void emit_op_put_by_id(Instruction
*);
529 void emit_op_put_by_index(Instruction
*);
530 void emit_op_put_by_val(Instruction
*);
531 void emit_op_put_getter_setter(Instruction
*);
532 void emit_op_init_global_const(Instruction
*);
533 void emit_op_ret(Instruction
*);
534 void emit_op_ret_object_or_this(Instruction
*);
535 void emit_op_rshift(Instruction
*);
536 void emit_op_strcat(Instruction
*);
537 void emit_op_stricteq(Instruction
*);
538 void emit_op_sub(Instruction
*);
539 void emit_op_switch_char(Instruction
*);
540 void emit_op_switch_imm(Instruction
*);
541 void emit_op_switch_string(Instruction
*);
542 void emit_op_tear_off_activation(Instruction
*);
543 void emit_op_tear_off_arguments(Instruction
*);
544 void emit_op_throw(Instruction
*);
545 void emit_op_throw_static_error(Instruction
*);
546 void emit_op_to_number(Instruction
*);
547 void emit_op_to_primitive(Instruction
*);
548 void emit_op_unexpected_load(Instruction
*);
549 void emit_op_unsigned(Instruction
*);
550 void emit_op_urshift(Instruction
*);
552 void emitSlow_op_add(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
553 void emitSlow_op_bitand(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
554 void emitSlow_op_bitor(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
555 void emitSlow_op_bitxor(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
556 void emitSlow_op_call(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
557 void emitSlow_op_call_eval(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
558 void emitSlow_op_call_varargs(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
559 void emitSlow_op_construct_varargs(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
560 void emitSlow_op_captured_mov(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
561 void emitSlow_op_construct(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
562 void emitSlow_op_to_this(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
563 void emitSlow_op_create_this(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
564 void emitSlow_op_div(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
565 void emitSlow_op_eq(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
566 void emitSlow_op_get_callee(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
567 void emitSlow_op_get_by_id(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
568 void emitSlow_op_get_arguments_length(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
569 void emitSlow_op_get_by_val(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
570 void emitSlow_op_get_argument_by_val(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
571 void emitSlow_op_get_by_pname(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
572 void emitSlow_op_check_has_instance(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
573 void emitSlow_op_instanceof(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
574 void emitSlow_op_jfalse(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
575 void emitSlow_op_jless(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
576 void emitSlow_op_jlesseq(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
577 void emitSlow_op_jgreater(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
578 void emitSlow_op_jgreatereq(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
579 void emitSlow_op_jnless(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
580 void emitSlow_op_jnlesseq(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
581 void emitSlow_op_jngreater(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
582 void emitSlow_op_jngreatereq(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
583 void emitSlow_op_jtrue(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
584 void emitSlow_op_loop_hint(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
585 void emitSlow_op_lshift(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
586 void emitSlow_op_mod(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
587 void emitSlow_op_mul(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
588 void emitSlow_op_negate(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
589 void emitSlow_op_neq(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
590 void emitSlow_op_new_object(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
591 void emitSlow_op_not(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
592 void emitSlow_op_nstricteq(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
593 void emitSlow_op_dec(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
594 void emitSlow_op_inc(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
595 void emitSlow_op_put_by_id(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
596 void emitSlow_op_put_by_val(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
597 void emitSlow_op_rshift(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
598 void emitSlow_op_stricteq(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
599 void emitSlow_op_sub(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
600 void emitSlow_op_to_number(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
601 void emitSlow_op_to_primitive(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
602 void emitSlow_op_unsigned(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
603 void emitSlow_op_urshift(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
605 void emit_op_resolve_scope(Instruction
*);
606 void emit_op_get_from_scope(Instruction
*);
607 void emit_op_put_to_scope(Instruction
*);
608 void emitSlow_op_resolve_scope(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
609 void emitSlow_op_get_from_scope(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
610 void emitSlow_op_put_to_scope(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&);
612 void emitRightShift(Instruction
*, bool isUnsigned
);
613 void emitRightShiftSlowCase(Instruction
*, Vector
<SlowCaseEntry
>::iterator
&, bool isUnsigned
);
615 void emitVarInjectionCheck(bool needsVarInjectionChecks
);
616 void emitResolveClosure(int dst
, bool needsVarInjectionChecks
, unsigned depth
);
617 void emitLoadWithStructureCheck(int scope
, Structure
** structureSlot
);
618 void emitGetGlobalProperty(uintptr_t* operandSlot
);
619 void emitGetGlobalVar(uintptr_t operand
);
620 void emitGetClosureVar(int scope
, uintptr_t operand
);
621 void emitPutGlobalProperty(uintptr_t* operandSlot
, int value
);
623 void emitNotifyWrite(RegisterID value
, RegisterID scratch
, VariableWatchpointSet
*);
625 void emitNotifyWrite(RegisterID tag
, RegisterID payload
, RegisterID scratch
, VariableWatchpointSet
*);
627 void emitPutGlobalVar(uintptr_t operand
, int value
, VariableWatchpointSet
*);
628 void emitPutClosureVar(int scope
, uintptr_t operand
, int value
);
630 void emitInitRegister(int dst
);
632 void emitPutIntToCallFrameHeader(RegisterID from
, JSStack::CallFrameHeaderEntry
);
633 void emitGetFromCallFrameHeaderPtr(JSStack::CallFrameHeaderEntry
, RegisterID to
, RegisterID from
= callFrameRegister
);
634 void emitGetFromCallFrameHeader32(JSStack::CallFrameHeaderEntry
, RegisterID to
, RegisterID from
= callFrameRegister
);
636 void emitGetFromCallFrameHeader64(JSStack::CallFrameHeaderEntry
, RegisterID to
, RegisterID from
= callFrameRegister
);
639 JSValue
getConstantOperand(int src
);
640 bool isOperandConstantImmediateInt(int src
);
641 bool isOperandConstantImmediateChar(int src
);
643 Jump
getSlowCase(Vector
<SlowCaseEntry
>::iterator
& iter
)
647 void linkSlowCase(Vector
<SlowCaseEntry
>::iterator
& iter
)
649 iter
->from
.link(this);
652 void linkDummySlowCase(Vector
<SlowCaseEntry
>::iterator
& iter
)
654 ASSERT(!iter
->from
.isSet());
657 void linkSlowCaseIfNotJSCell(Vector
<SlowCaseEntry
>::iterator
&, int virtualRegisterIndex
);
659 MacroAssembler::Call
appendCallWithExceptionCheck(const FunctionPtr
&);
660 #if OS(WINDOWS) && CPU(X86_64)
661 MacroAssembler::Call
appendCallWithExceptionCheckAndSlowPathReturnType(const FunctionPtr
&);
663 MacroAssembler::Call
appendCallWithCallFrameRollbackOnException(const FunctionPtr
&);
664 MacroAssembler::Call
appendCallWithExceptionCheckSetJSValueResult(const FunctionPtr
&, int);
665 MacroAssembler::Call
appendCallWithExceptionCheckSetJSValueResultWithProfile(const FunctionPtr
&, int);
667 enum WithProfileTag
{ WithProfile
};
669 MacroAssembler::Call
callOperation(C_JITOperation_E
);
670 MacroAssembler::Call
callOperation(C_JITOperation_EO
, GPRReg
);
671 MacroAssembler::Call
callOperation(C_JITOperation_ESt
, Structure
*);
672 MacroAssembler::Call
callOperation(C_JITOperation_EZ
, int32_t);
673 MacroAssembler::Call
callOperation(F_JITOperation_EJZZ
, GPRReg
, int32_t, int32_t);
674 MacroAssembler::Call
callOperation(J_JITOperation_E
, int);
675 MacroAssembler::Call
callOperation(J_JITOperation_EAapJ
, int, ArrayAllocationProfile
*, GPRReg
);
676 MacroAssembler::Call
callOperation(J_JITOperation_EAapJcpZ
, int, ArrayAllocationProfile
*, GPRReg
, int32_t);
677 MacroAssembler::Call
callOperation(J_JITOperation_EAapJcpZ
, int, ArrayAllocationProfile
*, const JSValue
*, int32_t);
678 MacroAssembler::Call
callOperation(J_JITOperation_EC
, int, JSCell
*);
679 MacroAssembler::Call
callOperation(V_JITOperation_EC
, JSCell
*);
680 MacroAssembler::Call
callOperation(J_JITOperation_EJ
, int, GPRReg
);
682 MacroAssembler::Call
callOperation(WithProfileTag
, J_JITOperation_ESsiJI
, int, StructureStubInfo
*, GPRReg
, StringImpl
*);
684 MacroAssembler::Call
callOperation(WithProfileTag
, J_JITOperation_ESsiJI
, int, StructureStubInfo
*, GPRReg
, GPRReg
, StringImpl
*);
686 MacroAssembler::Call
callOperation(J_JITOperation_EJIdc
, int, GPRReg
, const Identifier
*);
687 MacroAssembler::Call
callOperation(J_JITOperation_EJJ
, int, GPRReg
, GPRReg
);
689 MacroAssembler::Call
callOperation(WithProfileTag
, J_JITOperation_EJJ
, int, GPRReg
, GPRReg
);
691 MacroAssembler::Call
callOperation(WithProfileTag
, J_JITOperation_EJJ
, int, GPRReg
, GPRReg
, GPRReg
, GPRReg
);
693 MacroAssembler::Call
callOperation(J_JITOperation_EP
, int, void*);
694 MacroAssembler::Call
callOperation(WithProfileTag
, J_JITOperation_EPc
, int, Instruction
*);
695 MacroAssembler::Call
callOperation(J_JITOperation_EZ
, int, int32_t);
696 MacroAssembler::Call
callOperation(P_JITOperation_EJS
, GPRReg
, size_t);
697 MacroAssembler::Call
callOperation(S_JITOperation_ECC
, RegisterID
, RegisterID
);
698 MacroAssembler::Call
callOperation(S_JITOperation_EJ
, RegisterID
);
699 MacroAssembler::Call
callOperation(S_JITOperation_EJJ
, RegisterID
, RegisterID
);
700 MacroAssembler::Call
callOperation(S_JITOperation_EOJss
, RegisterID
, RegisterID
);
701 MacroAssembler::Call
callOperation(Sprt_JITOperation_EZ
, int32_t);
702 MacroAssembler::Call
callOperation(V_JITOperation_E
);
703 MacroAssembler::Call
callOperation(V_JITOperation_EC
, RegisterID
);
704 MacroAssembler::Call
callOperation(V_JITOperation_ECC
, RegisterID
, RegisterID
);
705 MacroAssembler::Call
callOperation(V_JITOperation_ECICC
, RegisterID
, const Identifier
*, RegisterID
, RegisterID
);
706 MacroAssembler::Call
callOperation(V_JITOperation_EIdJZ
, const Identifier
*, RegisterID
, int32_t);
707 MacroAssembler::Call
callOperation(V_JITOperation_EJ
, RegisterID
);
709 MacroAssembler::Call
callOperationNoExceptionCheck(V_JITOperation_EJ
, RegisterID
);
711 MacroAssembler::Call
callOperationNoExceptionCheck(V_JITOperation_EJ
, RegisterID
, RegisterID
);
713 MacroAssembler::Call
callOperation(V_JITOperation_EJIdJJ
, RegisterID
, const Identifier
*, RegisterID
, RegisterID
);
715 MacroAssembler::Call
callOperation(F_JITOperation_EFJJZ
, RegisterID
, RegisterID
, RegisterID
, int32_t);
716 MacroAssembler::Call
callOperation(V_JITOperation_ESsiJJI
, StructureStubInfo
*, RegisterID
, RegisterID
, StringImpl
*);
718 MacroAssembler::Call
callOperation(V_JITOperation_ESsiJJI
, StructureStubInfo
*, RegisterID
, RegisterID
, RegisterID
, RegisterID
, StringImpl
*);
720 MacroAssembler::Call
callOperation(V_JITOperation_EJJJ
, RegisterID
, RegisterID
, RegisterID
);
721 MacroAssembler::Call
callOperation(V_JITOperation_EJZJ
, RegisterID
, int32_t, RegisterID
);
722 MacroAssembler::Call
callOperation(V_JITOperation_EJZ
, RegisterID
, int32_t);
723 MacroAssembler::Call
callOperation(V_JITOperation_EPc
, Instruction
*);
724 MacroAssembler::Call
callOperation(V_JITOperation_EZ
, int32_t);
725 MacroAssembler::Call
callOperationWithCallFrameRollbackOnException(J_JITOperation_E
);
726 MacroAssembler::Call
callOperationNoExceptionCheck(J_JITOperation_EE
, RegisterID
);
727 MacroAssembler::Call
callOperationWithCallFrameRollbackOnException(V_JITOperation_ECb
, CodeBlock
*);
728 MacroAssembler::Call
callOperationWithCallFrameRollbackOnException(Z_JITOperation_E
);
729 #if USE(JSVALUE32_64)
730 MacroAssembler::Call
callOperation(F_JITOperation_EFJJZ
, RegisterID
, RegisterID
, RegisterID
, RegisterID
, RegisterID
, int32_t);
731 MacroAssembler::Call
callOperation(F_JITOperation_EJZZ
, GPRReg
, GPRReg
, int32_t, int32_t);
732 MacroAssembler::Call
callOperation(J_JITOperation_EAapJ
, int, ArrayAllocationProfile
*, GPRReg
, GPRReg
);
733 MacroAssembler::Call
callOperation(J_JITOperation_EJ
, int, GPRReg
, GPRReg
);
734 MacroAssembler::Call
callOperation(J_JITOperation_EJIdc
, int, GPRReg
, GPRReg
, const Identifier
*);
735 MacroAssembler::Call
callOperation(J_JITOperation_EJJ
, int, GPRReg
, GPRReg
, GPRReg
, GPRReg
);
736 MacroAssembler::Call
callOperation(P_JITOperation_EJS
, GPRReg
, GPRReg
, size_t);
737 MacroAssembler::Call
callOperation(S_JITOperation_EJ
, RegisterID
, RegisterID
);
738 MacroAssembler::Call
callOperation(S_JITOperation_EJJ
, RegisterID
, RegisterID
, RegisterID
, RegisterID
);
739 MacroAssembler::Call
callOperation(V_JITOperation_EIdJZ
, const Identifier
*, RegisterID
, RegisterID
, int32_t);
740 MacroAssembler::Call
callOperation(V_JITOperation_EJ
, RegisterID
, RegisterID
);
741 MacroAssembler::Call
callOperation(V_JITOperation_EJJJ
, RegisterID
, RegisterID
, RegisterID
, RegisterID
, RegisterID
, RegisterID
);
742 MacroAssembler::Call
callOperation(V_JITOperation_EJZ
, RegisterID
, RegisterID
, int32_t);
743 MacroAssembler::Call
callOperation(V_JITOperation_EJZJ
, RegisterID
, RegisterID
, int32_t, RegisterID
, RegisterID
);
746 Jump
checkStructure(RegisterID reg
, Structure
* structure
);
748 void updateTopCallFrame();
750 Call
emitNakedCall(CodePtr function
= CodePtr());
752 // Loads the character value of a single character string into dst.
753 void emitLoadCharacterString(RegisterID src
, RegisterID dst
, JumpList
& failures
);
756 void emitEnterOptimizationCheck();
758 void emitEnterOptimizationCheck() { }
762 void printBytecodeOperandTypes(int src1
, int src2
);
765 #if ENABLE(SAMPLING_FLAGS)
766 void setSamplingFlag(int32_t);
767 void clearSamplingFlag(int32_t);
770 #if ENABLE(SAMPLING_COUNTERS)
771 void emitCount(AbstractSamplingCounter
&, int32_t = 1);
774 #if ENABLE(OPCODE_SAMPLING)
775 void sampleInstruction(Instruction
*, bool = false);
778 #if ENABLE(CODEBLOCK_SAMPLING)
779 void sampleCodeBlock(CodeBlock
*);
781 void sampleCodeBlock(CodeBlock
*) {}
785 bool canBeOptimized() { return m_canBeOptimized
; }
786 bool canBeOptimizedOrInlined() { return m_canBeOptimizedOrInlined
; }
787 bool shouldEmitProfiling() { return m_shouldEmitProfiling
; }
789 bool canBeOptimized() { return false; }
790 bool canBeOptimizedOrInlined() { return false; }
791 // Enables use of value profiler with tiered compilation turned off,
792 // in which case all code gets profiled.
793 bool shouldEmitProfiling() { return false; }
796 Interpreter
* m_interpreter
;
798 Vector
<CallRecord
> m_calls
;
799 Vector
<Label
> m_labels
;
800 Vector
<JITGetByIdGenerator
> m_getByIds
;
801 Vector
<JITPutByIdGenerator
> m_putByIds
;
802 Vector
<ByValCompilationInfo
> m_byValCompilationInfo
;
803 Vector
<CallCompilationInfo
> m_callCompilationInfo
;
804 Vector
<JumpTable
> m_jmpTable
;
806 unsigned m_bytecodeOffset
;
807 Vector
<SlowCaseEntry
> m_slowCases
;
808 Vector
<SwitchRecord
> m_switches
;
810 JumpList m_exceptionChecks
;
811 JumpList m_exceptionChecksWithCallFrameRollback
;
813 unsigned m_getByIdIndex
;
814 unsigned m_putByIdIndex
;
815 unsigned m_byValInstructionIndex
;
816 unsigned m_callLinkInfoIndex
;
818 OwnPtr
<JITDisassembler
> m_disassembler
;
819 RefPtr
<Profiler::Compilation
> m_compilation
;
820 WeakRandom m_randomGenerator
;
821 static CodeRef
stringGetByValStubGenerator(VM
*);
823 bool m_canBeOptimized
;
824 bool m_canBeOptimizedOrInlined
;
825 bool m_shouldEmitProfiling
;
826 } JIT_CLASS_ALIGNMENT
;
830 #endif // ENABLE(JIT)