diff options
Diffstat (limited to 'JavaScriptCore/jit/JIT.h')
| -rw-r--r-- | JavaScriptCore/jit/JIT.h | 420 |
1 files changed, 231 insertions, 189 deletions
diff --git a/JavaScriptCore/jit/JIT.h b/JavaScriptCore/jit/JIT.h index bfbb1ee..907a774 100644 --- a/JavaScriptCore/jit/JIT.h +++ b/JavaScriptCore/jit/JIT.h @@ -26,8 +26,6 @@ #ifndef JIT_h #define JIT_h -#include <wtf/Platform.h> - #if ENABLE(JIT) // We've run into some problems where changing the size of the class JIT leads to @@ -42,15 +40,10 @@ #include "CodeBlock.h" #include "Interpreter.h" -#include "JITCode.h" -#include "JITStubs.h" +#include "JSInterfaceJIT.h" #include "Opcode.h" -#include "RegisterFile.h" -#include "MacroAssembler.h" #include "Profiler.h" #include <bytecode/SamplingTool.h> -#include <wtf/AlwaysInline.h> -#include <wtf/Vector.h> namespace JSC { @@ -73,16 +66,16 @@ namespace JSC { struct CallRecord { MacroAssembler::Call from; - unsigned bytecodeIndex; + unsigned bytecodeOffset; void* to; CallRecord() { } - CallRecord(MacroAssembler::Call from, unsigned bytecodeIndex, void* to = 0) + CallRecord(MacroAssembler::Call from, unsigned bytecodeOffset, void* to = 0) : from(from) - , bytecodeIndex(bytecodeIndex) + , bytecodeOffset(bytecodeOffset) , to(to) { } @@ -90,11 +83,11 @@ namespace JSC { struct JumpTable { MacroAssembler::Jump from; - unsigned toBytecodeIndex; + unsigned toBytecodeOffset; JumpTable(MacroAssembler::Jump f, unsigned t) : from(f) - , toBytecodeIndex(t) + , toBytecodeOffset(t) { } }; @@ -126,20 +119,20 @@ namespace JSC { StringJumpTable* stringJumpTable; } jumpTable; - unsigned bytecodeIndex; + unsigned bytecodeOffset; unsigned defaultOffset; - SwitchRecord(SimpleJumpTable* jumpTable, unsigned bytecodeIndex, unsigned defaultOffset, Type type) + SwitchRecord(SimpleJumpTable* jumpTable, unsigned bytecodeOffset, unsigned defaultOffset, Type type) : type(type) - , bytecodeIndex(bytecodeIndex) + , bytecodeOffset(bytecodeOffset) , defaultOffset(defaultOffset) { this->jumpTable.simpleJumpTable = jumpTable; } - SwitchRecord(StringJumpTable* jumpTable, unsigned bytecodeIndex, unsigned defaultOffset) + SwitchRecord(StringJumpTable* jumpTable, unsigned bytecodeOffset, unsigned defaultOffset) : type(String) - , bytecodeIndex(bytecodeIndex) + , bytecodeOffset(bytecodeOffset) , defaultOffset(defaultOffset) { this->jumpTable.stringJumpTable = jumpTable; @@ -172,159 +165,76 @@ namespace JSC { void ctiPatchCallByReturnAddress(CodeBlock* codeblock, ReturnAddressPtr returnAddress, MacroAssemblerCodePtr newCalleeFunction); void ctiPatchCallByReturnAddress(CodeBlock* codeblock, ReturnAddressPtr returnAddress, FunctionPtr newCalleeFunction); - class JIT : private MacroAssembler { + class JIT : private JSInterfaceJIT { friend class JITStubCall; using MacroAssembler::Jump; using MacroAssembler::JumpList; using MacroAssembler::Label; - // NOTES: - // - // regT0 has two special meanings. The return value from a stub - // call will always be in regT0, and by default (unless - // a register is specified) emitPutVirtualRegister() will store - // the value from regT0. - // - // regT3 is required to be callee-preserved. - // - // tempRegister2 is has no such dependencies. It is important that - // on x86/x86-64 it is ecx for performance reasons, since the - // MacroAssembler will need to plant register swaps if it is not - - // however the code will still function correctly. -#if CPU(X86_64) - static const RegisterID returnValueRegister = X86Registers::eax; - static const RegisterID cachedResultRegister = X86Registers::eax; - static const RegisterID firstArgumentRegister = X86Registers::edi; - - static const RegisterID timeoutCheckRegister = X86Registers::r12; - static const RegisterID callFrameRegister = X86Registers::r13; - static const RegisterID tagTypeNumberRegister = X86Registers::r14; - static const RegisterID tagMaskRegister = X86Registers::r15; - - static const RegisterID regT0 = X86Registers::eax; - static const RegisterID regT1 = X86Registers::edx; - static const RegisterID regT2 = X86Registers::ecx; - static const RegisterID regT3 = X86Registers::ebx; - - static const FPRegisterID fpRegT0 = X86Registers::xmm0; - static const FPRegisterID fpRegT1 = X86Registers::xmm1; - static const FPRegisterID fpRegT2 = X86Registers::xmm2; -#elif CPU(X86) - static const RegisterID returnValueRegister = X86Registers::eax; - static const RegisterID cachedResultRegister = X86Registers::eax; - // On x86 we always use fastcall conventions = but on - // OS X if might make more sense to just use regparm. - static const RegisterID firstArgumentRegister = X86Registers::ecx; - - static const RegisterID timeoutCheckRegister = X86Registers::esi; - static const RegisterID callFrameRegister = X86Registers::edi; - - static const RegisterID regT0 = X86Registers::eax; - static const RegisterID regT1 = X86Registers::edx; - static const RegisterID regT2 = X86Registers::ecx; - static const RegisterID regT3 = X86Registers::ebx; - - static const FPRegisterID fpRegT0 = X86Registers::xmm0; - static const FPRegisterID fpRegT1 = X86Registers::xmm1; - static const FPRegisterID fpRegT2 = X86Registers::xmm2; -#elif CPU(ARM_THUMB2) - static const RegisterID returnValueRegister = ARMRegisters::r0; - static const RegisterID cachedResultRegister = ARMRegisters::r0; - static const RegisterID firstArgumentRegister = ARMRegisters::r0; - - static const RegisterID regT0 = ARMRegisters::r0; - static const RegisterID regT1 = ARMRegisters::r1; - static const RegisterID regT2 = ARMRegisters::r2; - static const RegisterID regT3 = ARMRegisters::r4; - - static const RegisterID callFrameRegister = ARMRegisters::r5; - static const RegisterID timeoutCheckRegister = ARMRegisters::r6; - - static const FPRegisterID fpRegT0 = ARMRegisters::d0; - static const FPRegisterID fpRegT1 = ARMRegisters::d1; - static const FPRegisterID fpRegT2 = ARMRegisters::d2; -#elif CPU(ARM_TRADITIONAL) - static const RegisterID returnValueRegister = ARMRegisters::r0; - static const RegisterID cachedResultRegister = ARMRegisters::r0; - static const RegisterID firstArgumentRegister = ARMRegisters::r0; - - static const RegisterID timeoutCheckRegister = ARMRegisters::r5; - static const RegisterID callFrameRegister = ARMRegisters::r4; - - static const RegisterID regT0 = ARMRegisters::r0; - static const RegisterID regT1 = ARMRegisters::r1; - static const RegisterID regT2 = ARMRegisters::r2; - // Callee preserved - static const RegisterID regT3 = ARMRegisters::r7; - - static const RegisterID regS0 = ARMRegisters::S0; - // Callee preserved - static const RegisterID regS1 = ARMRegisters::S1; - - static const RegisterID regStackPtr = ARMRegisters::sp; - static const RegisterID regLink = ARMRegisters::lr; - - static const FPRegisterID fpRegT0 = ARMRegisters::d0; - static const FPRegisterID fpRegT1 = ARMRegisters::d1; - static const FPRegisterID fpRegT2 = ARMRegisters::d2; -#else - #error "JIT not supported on this platform." -#endif - static const int patchGetByIdDefaultStructure = -1; // Magic number - initial offset cannot be representable as a signed 8bit value, or the X86Assembler // will compress the displacement, and we may not be able to fit a patched offset. static const int patchGetByIdDefaultOffset = 256; public: - static JITCode compile(JSGlobalData* globalData, CodeBlock* codeBlock) + static JITCode compile(JSGlobalData* globalData, CodeBlock* codeBlock, CodePtr* functionEntryArityCheck = 0, void* offsetBase = 0) { - return JIT(globalData, codeBlock).privateCompile(); + return JIT(globalData, codeBlock, offsetBase).privateCompile(functionEntryArityCheck); } - static void compileGetByIdProto(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, size_t cachedOffset, ReturnAddressPtr returnAddress) + static void compileGetByIdProto(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, ReturnAddressPtr returnAddress) { JIT jit(globalData, codeBlock); - jit.privateCompileGetByIdProto(stubInfo, structure, prototypeStructure, cachedOffset, returnAddress, callFrame); + jit.privateCompileGetByIdProto(stubInfo, structure, prototypeStructure, ident, slot, cachedOffset, returnAddress, callFrame); } - static void compileGetByIdSelfList(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* polymorphicStructures, int currentIndex, Structure* structure, size_t cachedOffset) + static void compileGetByIdSelfList(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* polymorphicStructures, int currentIndex, Structure* structure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset) { JIT jit(globalData, codeBlock); - jit.privateCompileGetByIdSelfList(stubInfo, polymorphicStructures, currentIndex, structure, cachedOffset); + jit.privateCompileGetByIdSelfList(stubInfo, polymorphicStructures, currentIndex, structure, ident, slot, cachedOffset); } - static void compileGetByIdProtoList(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructureList, int currentIndex, Structure* structure, Structure* prototypeStructure, size_t cachedOffset) + static void compileGetByIdProtoList(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructureList, int currentIndex, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset) { JIT jit(globalData, codeBlock); - jit.privateCompileGetByIdProtoList(stubInfo, prototypeStructureList, currentIndex, structure, prototypeStructure, cachedOffset, callFrame); + jit.privateCompileGetByIdProtoList(stubInfo, prototypeStructureList, currentIndex, structure, prototypeStructure, ident, slot, cachedOffset, callFrame); } - static void compileGetByIdChainList(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructureList, int currentIndex, Structure* structure, StructureChain* chain, size_t count, size_t cachedOffset) + static void compileGetByIdChainList(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructureList, int currentIndex, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset) { JIT jit(globalData, codeBlock); - jit.privateCompileGetByIdChainList(stubInfo, prototypeStructureList, currentIndex, structure, chain, count, cachedOffset, callFrame); + jit.privateCompileGetByIdChainList(stubInfo, prototypeStructureList, currentIndex, structure, chain, count, ident, slot, cachedOffset, callFrame); } - static void compileGetByIdChain(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, size_t cachedOffset, ReturnAddressPtr returnAddress) + static void compileGetByIdChain(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, ReturnAddressPtr returnAddress) { JIT jit(globalData, codeBlock); - jit.privateCompileGetByIdChain(stubInfo, structure, chain, count, cachedOffset, returnAddress, callFrame); + jit.privateCompileGetByIdChain(stubInfo, structure, chain, count, ident, slot, cachedOffset, returnAddress, callFrame); } - static void compilePutByIdTransition(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress) + static void compilePutByIdTransition(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress, bool direct) { JIT jit(globalData, codeBlock); - jit.privateCompilePutByIdTransition(stubInfo, oldStructure, newStructure, cachedOffset, chain, returnAddress); + jit.privateCompilePutByIdTransition(stubInfo, oldStructure, newStructure, cachedOffset, chain, returnAddress, direct); } static void compileCTIMachineTrampolines(JSGlobalData* globalData, RefPtr<ExecutablePool>* executablePool, TrampolineStructure *trampolines) { - JIT jit(globalData); + if (!globalData->canUseJIT()) + return; + JIT jit(globalData, 0, 0); jit.privateCompileCTIMachineTrampolines(executablePool, globalData, trampolines); } + static CodePtr compileCTINativeCall(JSGlobalData* globalData, PassRefPtr<ExecutablePool> executablePool, NativeFunction func) + { + if (!globalData->canUseJIT()) + return CodePtr(); + JIT jit(globalData, 0, 0); + return jit.privateCompileCTINativeCall(executablePool, globalData, func); + } + static void patchGetByIdSelf(CodeBlock* codeblock, StructureStubInfo*, Structure*, size_t cachedOffset, ReturnAddressPtr returnAddress); - static void patchPutByIdReplace(CodeBlock* codeblock, StructureStubInfo*, Structure*, size_t cachedOffset, ReturnAddressPtr returnAddress); + static void patchPutByIdReplace(CodeBlock* codeblock, StructureStubInfo*, Structure*, size_t cachedOffset, ReturnAddressPtr returnAddress, bool direct); static void patchMethodCallProto(CodeBlock* codeblock, MethodCallLinkInfo&, JSFunction*, Structure*, JSObject*, ReturnAddressPtr); static void compilePatchGetArrayLength(JSGlobalData* globalData, CodeBlock* codeBlock, ReturnAddressPtr returnAddress) @@ -333,8 +243,9 @@ namespace JSC { return jit.privateCompilePatchGetArrayLength(returnAddress); } - static void linkCall(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, JITCode&, CallLinkInfo*, int callerArgCount, JSGlobalData*); - static void unlinkCall(CallLinkInfo*); + static void linkCall(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, CodePtr, CallLinkInfo*, int callerArgCount, JSGlobalData*); + static void linkConstruct(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, CodePtr, CallLinkInfo*, int callerArgCount, JSGlobalData*); + static void unlinkCallOrConstruct(CallLinkInfo*); private: struct JSRInfo { @@ -348,20 +259,22 @@ namespace JSC { } }; - JIT(JSGlobalData*, CodeBlock* = 0); + JIT(JSGlobalData*, CodeBlock* = 0, void* = 0); void privateCompileMainPass(); void privateCompileLinkPass(); void privateCompileSlowCases(); - JITCode privateCompile(); - void privateCompileGetByIdProto(StructureStubInfo*, Structure*, Structure* prototypeStructure, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame); - void privateCompileGetByIdSelfList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, size_t cachedOffset); - void privateCompileGetByIdProtoList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, Structure* prototypeStructure, size_t cachedOffset, CallFrame* callFrame); - void privateCompileGetByIdChainList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, StructureChain* chain, size_t count, size_t cachedOffset, CallFrame* callFrame); - void privateCompileGetByIdChain(StructureStubInfo*, Structure*, StructureChain*, size_t count, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame); - void privateCompilePutByIdTransition(StructureStubInfo*, Structure*, Structure*, size_t cachedOffset, StructureChain*, ReturnAddressPtr returnAddress); + JITCode privateCompile(CodePtr* functionEntryArityCheck); + void privateCompileGetByIdProto(StructureStubInfo*, Structure*, Structure* prototypeStructure, const Identifier&, const PropertySlot&, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame); + void privateCompileGetByIdSelfList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, const Identifier&, const PropertySlot&, size_t cachedOffset); + void privateCompileGetByIdProtoList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, Structure* prototypeStructure, const Identifier&, const PropertySlot&, size_t cachedOffset, CallFrame* callFrame); + void privateCompileGetByIdChainList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, StructureChain* chain, size_t count, const Identifier&, const PropertySlot&, size_t cachedOffset, CallFrame* callFrame); + void privateCompileGetByIdChain(StructureStubInfo*, Structure*, StructureChain*, size_t count, const Identifier&, const PropertySlot&, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame); + void privateCompilePutByIdTransition(StructureStubInfo*, Structure*, Structure*, size_t cachedOffset, StructureChain*, ReturnAddressPtr returnAddress, bool direct); void privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* data, TrampolineStructure *trampolines); + Label privateCompileCTINativeCall(JSGlobalData*, bool isConstruct = false); + CodePtr privateCompileCTINativeCall(PassRefPtr<ExecutablePool> executablePool, JSGlobalData* data, NativeFunction func); void privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress); void addSlowCase(Jump); @@ -372,11 +285,8 @@ namespace JSC { void compileOpCall(OpcodeID, Instruction* instruction, unsigned callLinkInfoIndex); void compileOpCallVarargs(Instruction* instruction); void compileOpCallInitializeCallFrame(); - void compileOpCallSetupArgs(Instruction*); - void compileOpCallVarargsSetupArgs(Instruction*); void compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>::iterator& iter, unsigned callLinkInfoIndex, OpcodeID opcodeID); void compileOpCallVarargsSlowCase(Instruction* instruction, Vector<SlowCaseEntry>::iterator& iter); - void compileOpConstructSetupArgs(Instruction*); enum CompileOpStrictEqType { OpStrictEq, OpNStrictEq }; void compileOpStrictEq(Instruction* instruction, CompileOpStrictEqType type); @@ -385,14 +295,9 @@ namespace JSC { void emitLoadDouble(unsigned index, FPRegisterID value); void emitLoadInt32ToDouble(unsigned index, FPRegisterID value); - Address addressFor(unsigned index, RegisterID base = callFrameRegister); - - void testPrototype(Structure*, JumpList& failureCases); + void testPrototype(JSValue, JumpList& failureCases); #if USE(JSVALUE32_64) - Address tagFor(unsigned index, RegisterID base = callFrameRegister); - Address payloadFor(unsigned index, RegisterID base = callFrameRegister); - bool getOperandConstantImmediateInt(unsigned op1, unsigned op2, unsigned& op, int32_t& constant); void emitLoadTag(unsigned index, RegisterID tag); @@ -410,8 +315,8 @@ namespace JSC { void emitStoreBool(unsigned index, RegisterID tag, bool indexIsBool = false); void emitStoreDouble(unsigned index, FPRegisterID value); - bool isLabeled(unsigned bytecodeIndex); - void map(unsigned bytecodeIndex, unsigned virtualRegisterIndex, RegisterID tag, RegisterID payload); + bool isLabeled(unsigned bytecodeOffset); + void map(unsigned bytecodeOffset, unsigned virtualRegisterIndex, RegisterID tag, RegisterID payload); void unmap(RegisterID); void unmap(); bool isMapped(unsigned virtualRegisterIndex); @@ -451,12 +356,8 @@ namespace JSC { static const int patchOffsetGetByIdPropertyMapOffset1 = 22; static const int patchOffsetGetByIdPropertyMapOffset2 = 28; static const int patchOffsetGetByIdPutResult = 28; -#if ENABLE(OPCODE_SAMPLING) && USE(JIT_STUB_ARGUMENT_VA_LIST) - static const int patchOffsetGetByIdSlowCaseCall = 35; -#elif ENABLE(OPCODE_SAMPLING) +#if ENABLE(OPCODE_SAMPLING) static const int patchOffsetGetByIdSlowCaseCall = 37; -#elif USE(JIT_STUB_ARGUMENT_VA_LIST) - static const int patchOffsetGetByIdSlowCaseCall = 25; #else static const int patchOffsetGetByIdSlowCaseCall = 27; #endif @@ -501,11 +402,98 @@ namespace JSC { static const int sequenceGetByIdHotPathInstructionSpace = 36; static const int sequenceGetByIdHotPathConstantSpace = 4; // sequenceGetByIdSlowCase + static const int sequenceGetByIdSlowCaseInstructionSpace = 56; + static const int sequenceGetByIdSlowCaseConstantSpace = 2; + // sequencePutById + static const int sequencePutByIdInstructionSpace = 36; + static const int sequencePutByIdConstantSpace = 4; +#elif CPU(ARM_THUMB2) + // These architecture specific value are used to enable patching - see comment on op_put_by_id. + static const int patchOffsetPutByIdStructure = 10; + static const int patchOffsetPutByIdExternalLoad = 26; + static const int patchLengthPutByIdExternalLoad = 12; + static const int patchOffsetPutByIdPropertyMapOffset1 = 46; + static const int patchOffsetPutByIdPropertyMapOffset2 = 58; + // These architecture specific value are used to enable patching - see comment on op_get_by_id. + static const int patchOffsetGetByIdStructure = 10; + static const int patchOffsetGetByIdBranchToSlowCase = 26; + static const int patchOffsetGetByIdExternalLoad = 26; + static const int patchLengthGetByIdExternalLoad = 12; + static const int patchOffsetGetByIdPropertyMapOffset1 = 46; + static const int patchOffsetGetByIdPropertyMapOffset2 = 58; + static const int patchOffsetGetByIdPutResult = 62; +#if ENABLE(OPCODE_SAMPLING) + #error "OPCODE_SAMPLING is not yet supported" +#else + static const int patchOffsetGetByIdSlowCaseCall = 30; +#endif + static const int patchOffsetOpCallCompareToJump = 16; + + static const int patchOffsetMethodCheckProtoObj = 24; + static const int patchOffsetMethodCheckProtoStruct = 34; + static const int patchOffsetMethodCheckPutFunction = 58; + + // sequenceOpCall + static const int sequenceOpCallInstructionSpace = 12; + static const int sequenceOpCallConstantSpace = 2; + // sequenceMethodCheck + static const int sequenceMethodCheckInstructionSpace = 40; + static const int sequenceMethodCheckConstantSpace = 6; + // sequenceGetByIdHotPath + static const int sequenceGetByIdHotPathInstructionSpace = 36; + static const int sequenceGetByIdHotPathConstantSpace = 4; + // sequenceGetByIdSlowCase static const int sequenceGetByIdSlowCaseInstructionSpace = 40; static const int sequenceGetByIdSlowCaseConstantSpace = 2; // sequencePutById static const int sequencePutByIdInstructionSpace = 36; static const int sequencePutByIdConstantSpace = 4; +#elif CPU(MIPS) +#if WTF_MIPS_ISA(1) + static const int patchOffsetPutByIdStructure = 16; + static const int patchOffsetPutByIdExternalLoad = 48; + static const int patchLengthPutByIdExternalLoad = 20; + static const int patchOffsetPutByIdPropertyMapOffset1 = 68; + static const int patchOffsetPutByIdPropertyMapOffset2 = 84; + static const int patchOffsetGetByIdStructure = 16; + static const int patchOffsetGetByIdBranchToSlowCase = 48; + static const int patchOffsetGetByIdExternalLoad = 48; + static const int patchLengthGetByIdExternalLoad = 20; + static const int patchOffsetGetByIdPropertyMapOffset1 = 68; + static const int patchOffsetGetByIdPropertyMapOffset2 = 88; + static const int patchOffsetGetByIdPutResult = 108; +#if ENABLE(OPCODE_SAMPLING) + #error "OPCODE_SAMPLING is not yet supported" +#else + static const int patchOffsetGetByIdSlowCaseCall = 44; +#endif + static const int patchOffsetOpCallCompareToJump = 32; + static const int patchOffsetMethodCheckProtoObj = 32; + static const int patchOffsetMethodCheckProtoStruct = 56; + static const int patchOffsetMethodCheckPutFunction = 88; +#else // WTF_MIPS_ISA(1) + static const int patchOffsetPutByIdStructure = 12; + static const int patchOffsetPutByIdExternalLoad = 44; + static const int patchLengthPutByIdExternalLoad = 16; + static const int patchOffsetPutByIdPropertyMapOffset1 = 60; + static const int patchOffsetPutByIdPropertyMapOffset2 = 76; + static const int patchOffsetGetByIdStructure = 12; + static const int patchOffsetGetByIdBranchToSlowCase = 44; + static const int patchOffsetGetByIdExternalLoad = 44; + static const int patchLengthGetByIdExternalLoad = 16; + static const int patchOffsetGetByIdPropertyMapOffset1 = 60; + static const int patchOffsetGetByIdPropertyMapOffset2 = 76; + static const int patchOffsetGetByIdPutResult = 92; +#if ENABLE(OPCODE_SAMPLING) + #error "OPCODE_SAMPLING is not yet supported" +#else + static const int patchOffsetGetByIdSlowCaseCall = 44; +#endif + static const int patchOffsetOpCallCompareToJump = 32; + static const int patchOffsetMethodCheckProtoObj = 32; + static const int patchOffsetMethodCheckProtoStruct = 52; + static const int patchOffsetMethodCheckPutFunction = 84; +#endif #else #error "JSVALUE32_64 not supported on this platform." #endif @@ -528,10 +516,7 @@ namespace JSC { Jump emitJumpIfNotJSCell(RegisterID); void emitJumpSlowCaseIfNotJSCell(RegisterID); void emitJumpSlowCaseIfNotJSCell(RegisterID, int VReg); -#if USE(JSVALUE64) - JIT::Jump emitJumpIfImmediateNumber(RegisterID); - JIT::Jump emitJumpIfNotImmediateNumber(RegisterID); -#else +#if USE(JSVALUE32_64) JIT::Jump emitJumpIfImmediateNumber(RegisterID reg) { return emitJumpIfImmediateInteger(reg); @@ -549,12 +534,11 @@ namespace JSC { void emitJumpSlowCaseIfNotImmediateNumber(RegisterID); void emitJumpSlowCaseIfNotImmediateIntegers(RegisterID, RegisterID, RegisterID); -#if !USE(JSVALUE64) +#if USE(JSVALUE32_64) void emitFastArithDeTagImmediate(RegisterID); Jump emitFastArithDeTagImmediateJumpIfZero(RegisterID); #endif void emitFastArithReTagImmediate(RegisterID src, RegisterID dest); - void emitFastArithImmToInt(RegisterID); void emitFastArithIntToImmNoCheck(RegisterID src, RegisterID dest); void emitTagAsBoolImmediate(RegisterID reg); @@ -610,12 +594,8 @@ namespace JSC { static const int patchLengthGetByIdExternalLoad = 3; static const int patchOffsetGetByIdPropertyMapOffset = 22; static const int patchOffsetGetByIdPutResult = 22; -#if ENABLE(OPCODE_SAMPLING) && USE(JIT_STUB_ARGUMENT_VA_LIST) - static const int patchOffsetGetByIdSlowCaseCall = 31; -#elif ENABLE(OPCODE_SAMPLING) +#if ENABLE(OPCODE_SAMPLING) static const int patchOffsetGetByIdSlowCaseCall = 33; -#elif USE(JIT_STUB_ARGUMENT_VA_LIST) - static const int patchOffsetGetByIdSlowCaseCall = 21; #else static const int patchOffsetGetByIdSlowCaseCall = 23; #endif @@ -686,19 +666,61 @@ namespace JSC { // sequencePutById static const int sequencePutByIdInstructionSpace = 28; static const int sequencePutByIdConstantSpace = 3; +#elif CPU(MIPS) +#if WTF_MIPS_ISA(1) + static const int patchOffsetPutByIdStructure = 16; + static const int patchOffsetPutByIdExternalLoad = 48; + static const int patchLengthPutByIdExternalLoad = 20; + static const int patchOffsetPutByIdPropertyMapOffset = 68; + static const int patchOffsetGetByIdStructure = 16; + static const int patchOffsetGetByIdBranchToSlowCase = 48; + static const int patchOffsetGetByIdExternalLoad = 48; + static const int patchLengthGetByIdExternalLoad = 20; + static const int patchOffsetGetByIdPropertyMapOffset = 68; + static const int patchOffsetGetByIdPutResult = 88; +#if ENABLE(OPCODE_SAMPLING) + #error "OPCODE_SAMPLING is not yet supported" +#else + static const int patchOffsetGetByIdSlowCaseCall = 40; +#endif + static const int patchOffsetOpCallCompareToJump = 32; + static const int patchOffsetMethodCheckProtoObj = 32; + static const int patchOffsetMethodCheckProtoStruct = 56; + static const int patchOffsetMethodCheckPutFunction = 88; +#else // WTF_MIPS_ISA(1) + static const int patchOffsetPutByIdStructure = 12; + static const int patchOffsetPutByIdExternalLoad = 44; + static const int patchLengthPutByIdExternalLoad = 16; + static const int patchOffsetPutByIdPropertyMapOffset = 60; + static const int patchOffsetGetByIdStructure = 12; + static const int patchOffsetGetByIdBranchToSlowCase = 44; + static const int patchOffsetGetByIdExternalLoad = 44; + static const int patchLengthGetByIdExternalLoad = 16; + static const int patchOffsetGetByIdPropertyMapOffset = 60; + static const int patchOffsetGetByIdPutResult = 76; +#if ENABLE(OPCODE_SAMPLING) + #error "OPCODE_SAMPLING is not yet supported" +#else + static const int patchOffsetGetByIdSlowCaseCall = 40; +#endif + static const int patchOffsetOpCallCompareToJump = 32; + static const int patchOffsetMethodCheckProtoObj = 32; + static const int patchOffsetMethodCheckProtoStruct = 52; + static const int patchOffsetMethodCheckPutFunction = 84; +#endif #endif #endif // USE(JSVALUE32_64) -#if defined(ASSEMBLER_HAS_CONSTANT_POOL) && ASSEMBLER_HAS_CONSTANT_POOL -#define BEGIN_UNINTERRUPTED_SEQUENCE(name) beginUninterruptedSequence(name ## InstructionSpace, name ## ConstantSpace) -#define END_UNINTERRUPTED_SEQUENCE(name) endUninterruptedSequence(name ## InstructionSpace, name ## ConstantSpace) +#if (defined(ASSEMBLER_HAS_CONSTANT_POOL) && ASSEMBLER_HAS_CONSTANT_POOL) +#define BEGIN_UNINTERRUPTED_SEQUENCE(name) do { beginUninterruptedSequence(name ## InstructionSpace, name ## ConstantSpace); } while (false) +#define END_UNINTERRUPTED_SEQUENCE(name) do { endUninterruptedSequence(name ## InstructionSpace, name ## ConstantSpace); } while (false) void beginUninterruptedSequence(int, int); void endUninterruptedSequence(int, int); #else -#define BEGIN_UNINTERRUPTED_SEQUENCE(name) -#define END_UNINTERRUPTED_SEQUENCE(name) +#define BEGIN_UNINTERRUPTED_SEQUENCE(name) do { beginUninterruptedSequence(); } while (false) +#define END_UNINTERRUPTED_SEQUENCE(name) do { endUninterruptedSequence(); } while (false) #endif void emit_op_add(Instruction*); @@ -709,25 +731,31 @@ namespace JSC { void emit_op_call(Instruction*); void emit_op_call_eval(Instruction*); void emit_op_call_varargs(Instruction*); + void emit_op_call_put_result(Instruction*); void emit_op_catch(Instruction*); void emit_op_construct(Instruction*); - void emit_op_construct_verify(Instruction*); + void emit_op_get_callee(Instruction*); + void emit_op_create_this(Instruction*); void emit_op_convert_this(Instruction*); + void emit_op_convert_this_strict(Instruction*); void emit_op_create_arguments(Instruction*); void emit_op_debug(Instruction*); void emit_op_del_by_id(Instruction*); void emit_op_div(Instruction*); void emit_op_end(Instruction*); void emit_op_enter(Instruction*); - void emit_op_enter_with_activation(Instruction*); + void emit_op_create_activation(Instruction*); void emit_op_eq(Instruction*); void emit_op_eq_null(Instruction*); void emit_op_get_by_id(Instruction*); + void emit_op_get_arguments_length(Instruction*); void emit_op_get_by_val(Instruction*); + void emit_op_get_argument_by_val(Instruction*); void emit_op_get_by_pname(Instruction*); void emit_op_get_global_var(Instruction*); void emit_op_get_scoped_var(Instruction*); - void emit_op_init_arguments(Instruction*); + void emit_op_init_lazy_reg(Instruction*); + void emit_op_check_has_instance(Instruction*); void emit_op_instanceof(Instruction*); void emit_op_jeq_null(Instruction*); void emit_op_jfalse(Instruction*); @@ -737,6 +765,7 @@ namespace JSC { void emit_op_jneq_ptr(Instruction*); void emit_op_jnless(Instruction*); void emit_op_jless(Instruction*); + void emit_op_jlesseq(Instruction*, bool invert = false); void emit_op_jnlesseq(Instruction*); void emit_op_jsr(Instruction*); void emit_op_jtrue(Instruction*); @@ -755,7 +784,6 @@ namespace JSC { void emit_op_neq(Instruction*); void emit_op_neq_null(Instruction*); void emit_op_new_array(Instruction*); - void emit_op_new_error(Instruction*); void emit_op_new_func(Instruction*); void emit_op_new_func_exp(Instruction*); void emit_op_new_object(Instruction*); @@ -782,10 +810,13 @@ namespace JSC { void emit_op_put_setter(Instruction*); void emit_op_resolve(Instruction*); void emit_op_resolve_base(Instruction*); - void emit_op_resolve_global(Instruction*); + void emit_op_ensure_property_exists(Instruction*); + void emit_op_resolve_global(Instruction*, bool dynamic = false); + void emit_op_resolve_global_dynamic(Instruction*); void emit_op_resolve_skip(Instruction*); void emit_op_resolve_with_base(Instruction*); void emit_op_ret(Instruction*); + void emit_op_ret_object_or_this(Instruction*); void emit_op_rshift(Instruction*); void emit_op_sret(Instruction*); void emit_op_strcat(Instruction*); @@ -797,10 +828,13 @@ namespace JSC { void emit_op_tear_off_activation(Instruction*); void emit_op_tear_off_arguments(Instruction*); void emit_op_throw(Instruction*); + void emit_op_throw_reference_error(Instruction*); + void emit_op_throw_syntax_error(Instruction*); void emit_op_to_jsnumber(Instruction*); void emit_op_to_primitive(Instruction*); void emit_op_unexpected_load(Instruction*); -#if ENABLE(JIT_OPTIMIZE_MOD) + void emit_op_urshift(Instruction*); +#if ENABLE(JIT_USE_SOFT_MODULO) void softModulo(); #endif @@ -813,19 +847,24 @@ namespace JSC { void emitSlow_op_call_eval(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_call_varargs(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_construct(Instruction*, Vector<SlowCaseEntry>::iterator&); - void emitSlow_op_construct_verify(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_convert_this(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_convert_this_strict(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_div(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_eq(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_get_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_get_arguments_length(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_get_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_get_argument_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_get_by_pname(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_check_has_instance(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_instanceof(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_jfalse(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_jnless(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_jless(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_jlesseq(Instruction*, Vector<SlowCaseEntry>::iterator&, bool invert = false); void emitSlow_op_jnlesseq(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_jtrue(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_load_varargs(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_loop_if_less(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_loop_if_lesseq(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_loop_if_true(Instruction*, Vector<SlowCaseEntry>::iterator&); @@ -845,22 +884,19 @@ namespace JSC { void emitSlow_op_put_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_put_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_resolve_global(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_resolve_global_dynamic(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_rshift(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_stricteq(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_sub(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_to_jsnumber(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_to_primitive(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_urshift(Instruction*, Vector<SlowCaseEntry>::iterator&); - /* These functions are deprecated: Please use JITStubCall instead. */ - void emitPutJITStubArg(RegisterID src, unsigned argumentNumber); -#if USE(JSVALUE32_64) - void emitPutJITStubArg(RegisterID tag, RegisterID payload, unsigned argumentNumber); - void emitPutJITStubArgFromVirtualRegister(unsigned src, unsigned argumentNumber, RegisterID scratch1, RegisterID scratch2); -#else - void emitPutJITStubArgFromVirtualRegister(unsigned src, unsigned argumentNumber, RegisterID scratch); -#endif - void emitPutJITStubArgConstant(unsigned value, unsigned argumentNumber); - void emitPutJITStubArgConstant(void* value, unsigned argumentNumber); + + void emitRightShift(Instruction*, bool isUnsigned); + void emitRightShiftSlowCase(Instruction*, Vector<SlowCaseEntry>::iterator&, bool isUnsigned); + + /* This function is deprecated. */ void emitGetJITStubArg(unsigned argumentNumber, RegisterID dst); void emitInitRegister(unsigned dst); @@ -872,6 +908,7 @@ namespace JSC { JSValue getConstantOperand(unsigned src); bool isOperandConstantImmediateInt(unsigned src); + bool isOperandConstantImmediateChar(unsigned src); Jump getSlowCase(Vector<SlowCaseEntry>::iterator& iter) { @@ -895,6 +932,9 @@ namespace JSC { void restoreReturnAddressBeforeReturn(RegisterID); void restoreReturnAddressBeforeReturn(Address); + // Loads the character value of a single character string into dst. + void emitLoadCharacterString(RegisterID src, RegisterID dst, JumpList& failures); + void emitTimeoutCheck(); #ifndef NDEBUG void printBytecodeOperandTypes(unsigned src1, unsigned src2); @@ -930,7 +970,7 @@ namespace JSC { Vector<MethodCallCompilationInfo> m_methodCallCompilationInfo; Vector<JumpTable> m_jmpTable; - unsigned m_bytecodeIndex; + unsigned m_bytecodeOffset; Vector<JSRInfo> m_jsrSites; Vector<SlowCaseEntry> m_slowCases; Vector<SwitchRecord> m_switches; @@ -941,7 +981,7 @@ namespace JSC { #if USE(JSVALUE32_64) unsigned m_jumpTargetIndex; - unsigned m_mappedBytecodeIndex; + unsigned m_mappedBytecodeOffset; unsigned m_mappedVirtualRegisterIndex; RegisterID m_mappedTag; RegisterID m_mappedPayload; @@ -956,6 +996,8 @@ namespace JSC { int m_uninterruptedConstantSequenceBegin; #endif #endif + void* m_linkerOffset; + static CodePtr stringGetByValStubGenerator(JSGlobalData* globalData, ExecutablePool* pool); } JIT_CLASS_ALIGNMENT; inline void JIT::emit_op_loop(Instruction* currentInstruction) |
