36 #define JIT_CLASS_ALIGNMENT __attribute__ ((aligned (32))) |
36 #define JIT_CLASS_ALIGNMENT __attribute__ ((aligned (32))) |
37 #else |
37 #else |
38 #define JIT_CLASS_ALIGNMENT |
38 #define JIT_CLASS_ALIGNMENT |
39 #endif |
39 #endif |
40 |
40 |
|
41 #define ASSERT_JIT_OFFSET(actual, expected) ASSERT_WITH_MESSAGE(actual == expected, "JIT Offset \"%s\" should be %d, not %d.\n", #expected, static_cast<int>(actual), static_cast<int>(expected)); |
|
42 |
41 #include "CodeBlock.h" |
43 #include "CodeBlock.h" |
42 #include "Interpreter.h" |
44 #include "Interpreter.h" |
43 #include "JITCode.h" |
45 #include "JITCode.h" |
44 #include "JITStubs.h" |
46 #include "JITStubs.h" |
45 #include "Opcode.h" |
47 #include "Opcode.h" |
247 static const RegisterID cachedResultRegister = ARMRegisters::r0; |
249 static const RegisterID cachedResultRegister = ARMRegisters::r0; |
248 static const RegisterID firstArgumentRegister = ARMRegisters::r0; |
250 static const RegisterID firstArgumentRegister = ARMRegisters::r0; |
249 |
251 |
250 static const RegisterID timeoutCheckRegister = ARMRegisters::r5; |
252 static const RegisterID timeoutCheckRegister = ARMRegisters::r5; |
251 static const RegisterID callFrameRegister = ARMRegisters::r4; |
253 static const RegisterID callFrameRegister = ARMRegisters::r4; |
252 static const RegisterID ctiReturnRegister = ARMRegisters::r6; |
|
253 |
254 |
254 static const RegisterID regT0 = ARMRegisters::r0; |
255 static const RegisterID regT0 = ARMRegisters::r0; |
255 static const RegisterID regT1 = ARMRegisters::r1; |
256 static const RegisterID regT1 = ARMRegisters::r1; |
256 static const RegisterID regT2 = ARMRegisters::r2; |
257 static const RegisterID regT2 = ARMRegisters::r2; |
257 // Callee preserved |
258 // Callee preserved |
425 void compileGetByIdHotPath(); |
426 void compileGetByIdHotPath(); |
426 void compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident, Vector<SlowCaseEntry>::iterator& iter, bool isMethodCheck = false); |
427 void compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident, Vector<SlowCaseEntry>::iterator& iter, bool isMethodCheck = false); |
427 #endif |
428 #endif |
428 void compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, Structure* structure, size_t cachedOffset); |
429 void compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, Structure* structure, size_t cachedOffset); |
429 void compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID resultTag, RegisterID resultPayload, size_t cachedOffset); |
430 void compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID resultTag, RegisterID resultPayload, size_t cachedOffset); |
|
431 void compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, RegisterID structure, RegisterID offset); |
430 void compilePutDirectOffset(RegisterID base, RegisterID valueTag, RegisterID valuePayload, Structure* structure, size_t cachedOffset); |
432 void compilePutDirectOffset(RegisterID base, RegisterID valueTag, RegisterID valuePayload, Structure* structure, size_t cachedOffset); |
431 |
433 |
432 // Arithmetic opcode helpers |
434 // Arithmetic opcode helpers |
433 void emitAdd32Constant(unsigned dst, unsigned op, int32_t constant, ResultType opType); |
435 void emitAdd32Constant(unsigned dst, unsigned op, int32_t constant, ResultType opType); |
434 void emitSub32Constant(unsigned dst, unsigned op, int32_t constant, ResultType opType); |
436 void emitSub32Constant(unsigned dst, unsigned op, int32_t constant, ResultType opType); |
526 void compileGetByIdHotPath(int resultVReg, int baseVReg, Identifier* ident, unsigned propertyAccessInstructionIndex); |
528 void compileGetByIdHotPath(int resultVReg, int baseVReg, Identifier* ident, unsigned propertyAccessInstructionIndex); |
527 void compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident, Vector<SlowCaseEntry>::iterator& iter, bool isMethodCheck = false); |
529 void compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident, Vector<SlowCaseEntry>::iterator& iter, bool isMethodCheck = false); |
528 #endif |
530 #endif |
529 void compileGetDirectOffset(RegisterID base, RegisterID result, Structure* structure, size_t cachedOffset); |
531 void compileGetDirectOffset(RegisterID base, RegisterID result, Structure* structure, size_t cachedOffset); |
530 void compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID result, size_t cachedOffset); |
532 void compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID result, size_t cachedOffset); |
|
533 void compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID structure, RegisterID offset, RegisterID scratch); |
531 void compilePutDirectOffset(RegisterID base, RegisterID value, Structure* structure, size_t cachedOffset); |
534 void compilePutDirectOffset(RegisterID base, RegisterID value, Structure* structure, size_t cachedOffset); |
532 |
535 |
533 #if PLATFORM(X86_64) |
536 #if PLATFORM(X86_64) |
534 // These architecture specific value are used to enable patching - see comment on op_put_by_id. |
537 // These architecture specific value are used to enable patching - see comment on op_put_by_id. |
535 static const int patchOffsetPutByIdStructure = 10; |
538 static const int patchOffsetPutByIdStructure = 10; |
581 static const int patchOffsetMethodCheckProtoStruct = 18; |
584 static const int patchOffsetMethodCheckProtoStruct = 18; |
582 static const int patchOffsetMethodCheckPutFunction = 29; |
585 static const int patchOffsetMethodCheckPutFunction = 29; |
583 #elif PLATFORM(ARM_THUMB2) |
586 #elif PLATFORM(ARM_THUMB2) |
584 // These architecture specific value are used to enable patching - see comment on op_put_by_id. |
587 // These architecture specific value are used to enable patching - see comment on op_put_by_id. |
585 static const int patchOffsetPutByIdStructure = 10; |
588 static const int patchOffsetPutByIdStructure = 10; |
586 static const int patchOffsetPutByIdExternalLoad = 20; |
589 static const int patchOffsetPutByIdExternalLoad = 26; |
587 static const int patchLengthPutByIdExternalLoad = 12; |
590 static const int patchLengthPutByIdExternalLoad = 12; |
588 static const int patchOffsetPutByIdPropertyMapOffset = 40; |
591 static const int patchOffsetPutByIdPropertyMapOffset = 46; |
589 // These architecture specific value are used to enable patching - see comment on op_get_by_id. |
592 // These architecture specific value are used to enable patching - see comment on op_get_by_id. |
590 static const int patchOffsetGetByIdStructure = 10; |
593 static const int patchOffsetGetByIdStructure = 10; |
591 static const int patchOffsetGetByIdBranchToSlowCase = 20; |
594 static const int patchOffsetGetByIdBranchToSlowCase = 26; |
592 static const int patchOffsetGetByIdExternalLoad = 20; |
595 static const int patchOffsetGetByIdExternalLoad = 26; |
593 static const int patchLengthGetByIdExternalLoad = 12; |
596 static const int patchLengthGetByIdExternalLoad = 12; |
594 static const int patchOffsetGetByIdPropertyMapOffset = 40; |
597 static const int patchOffsetGetByIdPropertyMapOffset = 46; |
595 static const int patchOffsetGetByIdPutResult = 44; |
598 static const int patchOffsetGetByIdPutResult = 50; |
596 #if ENABLE(OPCODE_SAMPLING) |
599 #if ENABLE(OPCODE_SAMPLING) |
597 static const int patchOffsetGetByIdSlowCaseCall = 0; // FIMXE |
600 static const int patchOffsetGetByIdSlowCaseCall = 0; // FIMXE |
598 #else |
601 #else |
599 static const int patchOffsetGetByIdSlowCaseCall = 28; |
602 static const int patchOffsetGetByIdSlowCaseCall = 28; |
600 #endif |
603 #endif |
601 static const int patchOffsetOpCallCompareToJump = 10; |
604 static const int patchOffsetOpCallCompareToJump = 16; |
602 |
605 |
603 static const int patchOffsetMethodCheckProtoObj = 18; |
606 static const int patchOffsetMethodCheckProtoObj = 24; |
604 static const int patchOffsetMethodCheckProtoStruct = 28; |
607 static const int patchOffsetMethodCheckProtoStruct = 34; |
605 static const int patchOffsetMethodCheckPutFunction = 46; |
608 static const int patchOffsetMethodCheckPutFunction = 58; |
606 #elif PLATFORM(ARM_TRADITIONAL) |
609 #elif PLATFORM(ARM_TRADITIONAL) |
607 // These architecture specific value are used to enable patching - see comment on op_put_by_id. |
610 // These architecture specific value are used to enable patching - see comment on op_put_by_id. |
608 static const int patchOffsetPutByIdStructure = 4; |
611 static const int patchOffsetPutByIdStructure = 4; |
609 static const int patchOffsetPutByIdExternalLoad = 16; |
612 static const int patchOffsetPutByIdExternalLoad = 16; |
610 static const int patchLengthPutByIdExternalLoad = 4; |
613 static const int patchLengthPutByIdExternalLoad = 4; |
617 static const int patchOffsetGetByIdPropertyMapOffset = 20; |
620 static const int patchOffsetGetByIdPropertyMapOffset = 20; |
618 static const int patchOffsetGetByIdPutResult = 28; |
621 static const int patchOffsetGetByIdPutResult = 28; |
619 #if ENABLE(OPCODE_SAMPLING) |
622 #if ENABLE(OPCODE_SAMPLING) |
620 #error "OPCODE_SAMPLING is not yet supported" |
623 #error "OPCODE_SAMPLING is not yet supported" |
621 #else |
624 #else |
622 static const int patchOffsetGetByIdSlowCaseCall = 36; |
625 static const int patchOffsetGetByIdSlowCaseCall = 28; |
623 #endif |
626 #endif |
624 static const int patchOffsetOpCallCompareToJump = 12; |
627 static const int patchOffsetOpCallCompareToJump = 12; |
625 |
628 |
626 static const int patchOffsetMethodCheckProtoObj = 12; |
629 static const int patchOffsetMethodCheckProtoObj = 12; |
627 static const int patchOffsetMethodCheckProtoStruct = 20; |
630 static const int patchOffsetMethodCheckProtoStruct = 20; |
638 static const int sequenceMethodCheckConstantSpace = 6; |
641 static const int sequenceMethodCheckConstantSpace = 6; |
639 // sequenceGetByIdHotPath |
642 // sequenceGetByIdHotPath |
640 static const int sequenceGetByIdHotPathInstructionSpace = 28; |
643 static const int sequenceGetByIdHotPathInstructionSpace = 28; |
641 static const int sequenceGetByIdHotPathConstantSpace = 3; |
644 static const int sequenceGetByIdHotPathConstantSpace = 3; |
642 // sequenceGetByIdSlowCase |
645 // sequenceGetByIdSlowCase |
643 static const int sequenceGetByIdSlowCaseInstructionSpace = 40; |
646 static const int sequenceGetByIdSlowCaseInstructionSpace = 32; |
644 static const int sequenceGetByIdSlowCaseConstantSpace = 2; |
647 static const int sequenceGetByIdSlowCaseConstantSpace = 2; |
645 // sequencePutById |
648 // sequencePutById |
646 static const int sequencePutByIdInstructionSpace = 28; |
649 static const int sequencePutByIdInstructionSpace = 28; |
647 static const int sequencePutByIdConstantSpace = 3; |
650 static const int sequencePutByIdConstantSpace = 3; |
648 #endif |
651 #endif |
680 void emit_op_enter_with_activation(Instruction*); |
683 void emit_op_enter_with_activation(Instruction*); |
681 void emit_op_eq(Instruction*); |
684 void emit_op_eq(Instruction*); |
682 void emit_op_eq_null(Instruction*); |
685 void emit_op_eq_null(Instruction*); |
683 void emit_op_get_by_id(Instruction*); |
686 void emit_op_get_by_id(Instruction*); |
684 void emit_op_get_by_val(Instruction*); |
687 void emit_op_get_by_val(Instruction*); |
|
688 void emit_op_get_by_pname(Instruction*); |
685 void emit_op_get_global_var(Instruction*); |
689 void emit_op_get_global_var(Instruction*); |
686 void emit_op_get_scoped_var(Instruction*); |
690 void emit_op_get_scoped_var(Instruction*); |
687 void emit_op_init_arguments(Instruction*); |
691 void emit_op_init_arguments(Instruction*); |
688 void emit_op_instanceof(Instruction*); |
692 void emit_op_instanceof(Instruction*); |
689 void emit_op_jeq_null(Instruction*); |
693 void emit_op_jeq_null(Instruction*); |
769 void emitSlow_op_convert_this(Instruction*, Vector<SlowCaseEntry>::iterator&); |
773 void emitSlow_op_convert_this(Instruction*, Vector<SlowCaseEntry>::iterator&); |
770 void emitSlow_op_div(Instruction*, Vector<SlowCaseEntry>::iterator&); |
774 void emitSlow_op_div(Instruction*, Vector<SlowCaseEntry>::iterator&); |
771 void emitSlow_op_eq(Instruction*, Vector<SlowCaseEntry>::iterator&); |
775 void emitSlow_op_eq(Instruction*, Vector<SlowCaseEntry>::iterator&); |
772 void emitSlow_op_get_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&); |
776 void emitSlow_op_get_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&); |
773 void emitSlow_op_get_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&); |
777 void emitSlow_op_get_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&); |
|
778 void emitSlow_op_get_by_pname(Instruction*, Vector<SlowCaseEntry>::iterator&); |
774 void emitSlow_op_instanceof(Instruction*, Vector<SlowCaseEntry>::iterator&); |
779 void emitSlow_op_instanceof(Instruction*, Vector<SlowCaseEntry>::iterator&); |
775 void emitSlow_op_jfalse(Instruction*, Vector<SlowCaseEntry>::iterator&); |
780 void emitSlow_op_jfalse(Instruction*, Vector<SlowCaseEntry>::iterator&); |
776 void emitSlow_op_jnless(Instruction*, Vector<SlowCaseEntry>::iterator&); |
781 void emitSlow_op_jnless(Instruction*, Vector<SlowCaseEntry>::iterator&); |
777 void emitSlow_op_jnlesseq(Instruction*, Vector<SlowCaseEntry>::iterator&); |
782 void emitSlow_op_jnlesseq(Instruction*, Vector<SlowCaseEntry>::iterator&); |
778 void emitSlow_op_jtrue(Instruction*, Vector<SlowCaseEntry>::iterator&); |
783 void emitSlow_op_jtrue(Instruction*, Vector<SlowCaseEntry>::iterator&); |