diff options
Diffstat (limited to 'Source/JavaScriptCore/jit')
-rw-r--r-- | Source/JavaScriptCore/jit/ExecutableAllocator.h | 16 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JIT.h | 84 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JITCall.cpp | 4 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JITCall32_64.cpp | 19 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JITOpcodes.cpp | 18 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JITOpcodes32_64.cpp | 4 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JITPropertyAccess.cpp | 85 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp | 120 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JITStubs.cpp | 52 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JITStubs.h | 1 |
10 files changed, 126 insertions, 277 deletions
diff --git a/Source/JavaScriptCore/jit/ExecutableAllocator.h b/Source/JavaScriptCore/jit/ExecutableAllocator.h index 57ee054..77a2567 100644 --- a/Source/JavaScriptCore/jit/ExecutableAllocator.h +++ b/Source/JavaScriptCore/jit/ExecutableAllocator.h @@ -47,6 +47,13 @@ #include <sys/cachectl.h> #endif +#if CPU(SH4) && OS(LINUX) +#include <asm/cachectl.h> +#include <asm/unistd.h> +#include <sys/syscall.h> +#include <unistd.h> +#endif + #if OS(WINCE) // From pkfuncs.h (private header file from the Platform Builder) #define CACHE_SYNC_ALL 0x07F @@ -310,6 +317,15 @@ public: IMemCache1_ClearCache(memCache.get(), reinterpret_cast<uint32>(code), size, MEMSPACE_CACHE_FLUSH, MEMSPACE_DATACACHE); IMemCache1_ClearCache(memCache.get(), reinterpret_cast<uint32>(code), size, MEMSPACE_CACHE_INVALIDATE, MEMSPACE_INSTCACHE); } +#elif CPU(SH4) && OS(LINUX) + static void cacheFlush(void* code, size_t size) + { +#ifdef CACHEFLUSH_D_L2 + syscall(__NR_cacheflush, reinterpret_cast<unsigned>(code), size, CACHEFLUSH_D_WB | CACHEFLUSH_I | CACHEFLUSH_D_L2); +#else + syscall(__NR_cacheflush, reinterpret_cast<unsigned>(code), size, CACHEFLUSH_D_WB | CACHEFLUSH_I); +#endif + } #else #error "The cacheFlush support is missing on this platform." #endif diff --git a/Source/JavaScriptCore/jit/JIT.h b/Source/JavaScriptCore/jit/JIT.h index dc1650d..f98158c 100644 --- a/Source/JavaScriptCore/jit/JIT.h +++ b/Source/JavaScriptCore/jit/JIT.h @@ -36,7 +36,7 @@ #define JIT_CLASS_ALIGNMENT #endif -#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)); +#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)); #include "CodeBlock.h" #include "Interpreter.h" @@ -332,8 +332,8 @@ namespace JSC { void compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident, Vector<SlowCaseEntry>::iterator& iter, bool isMethodCheck = false); #endif void compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, Structure* structure, size_t cachedOffset); - void compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID resultTag, RegisterID resultPayload, size_t cachedOffset); - void compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, RegisterID structure, RegisterID offset); + void compileGetDirectOffset(JSObject* base, RegisterID resultTag, RegisterID resultPayload, size_t cachedOffset); + void compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, RegisterID offset); void compilePutDirectOffset(RegisterID base, RegisterID valueTag, RegisterID valuePayload, Structure* structure, size_t cachedOffset); // Arithmetic opcode helpers @@ -344,15 +344,11 @@ namespace JSC { #if CPU(X86) // These architecture specific value are used to enable patching - see comment on op_put_by_id. static const int patchOffsetPutByIdStructure = 7; - static const int patchOffsetPutByIdExternalLoad = 13; - static const int patchLengthPutByIdExternalLoad = 3; static const int patchOffsetPutByIdPropertyMapOffset1 = 22; static const int patchOffsetPutByIdPropertyMapOffset2 = 28; // These architecture specific value are used to enable patching - see comment on op_get_by_id. static const int patchOffsetGetByIdStructure = 7; static const int patchOffsetGetByIdBranchToSlowCase = 13; - static const int patchOffsetGetByIdExternalLoad = 13; - static const int patchLengthGetByIdExternalLoad = 3; static const int patchOffsetGetByIdPropertyMapOffset1 = 22; static const int patchOffsetGetByIdPropertyMapOffset2 = 28; static const int patchOffsetGetByIdPutResult = 28; @@ -369,15 +365,11 @@ namespace JSC { #elif CPU(ARM_TRADITIONAL) // These architecture specific value are used to enable patching - see comment on op_put_by_id. static const int patchOffsetPutByIdStructure = 4; - static const int patchOffsetPutByIdExternalLoad = 16; - static const int patchLengthPutByIdExternalLoad = 4; static const int patchOffsetPutByIdPropertyMapOffset1 = 20; static const int patchOffsetPutByIdPropertyMapOffset2 = 28; // These architecture specific value are used to enable patching - see comment on op_get_by_id. static const int patchOffsetGetByIdStructure = 4; static const int patchOffsetGetByIdBranchToSlowCase = 16; - static const int patchOffsetGetByIdExternalLoad = 16; - static const int patchLengthGetByIdExternalLoad = 4; static const int patchOffsetGetByIdPropertyMapOffset1 = 20; static const int patchOffsetGetByIdPropertyMapOffset2 = 28; static const int patchOffsetGetByIdPutResult = 36; @@ -410,18 +402,14 @@ namespace JSC { #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; + static const int patchOffsetPutByIdPropertyMapOffset1 = 36; + static const int patchOffsetPutByIdPropertyMapOffset2 = 48; // 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; + static const int patchOffsetGetByIdPropertyMapOffset1 = 36; + static const int patchOffsetGetByIdPropertyMapOffset2 = 48; + static const int patchOffsetGetByIdPutResult = 52; #if ENABLE(OPCODE_SAMPLING) #error "OPCODE_SAMPLING is not yet supported" #else @@ -451,17 +439,13 @@ namespace JSC { #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 patchOffsetPutByIdPropertyMapOffset1 = 56; + static const int patchOffsetPutByIdPropertyMapOffset2 = 72; 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; + static const int patchOffsetGetByIdPropertyMapOffset1 = 56; + static const int patchOffsetGetByIdPropertyMapOffset2 = 76; + static const int patchOffsetGetByIdPutResult = 96; #if ENABLE(OPCODE_SAMPLING) #error "OPCODE_SAMPLING is not yet supported" #else @@ -473,17 +457,13 @@ namespace JSC { 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 patchOffsetPutByIdPropertyMapOffset1 = 48; + static const int patchOffsetPutByIdPropertyMapOffset2 = 64; 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; + static const int patchOffsetGetByIdPropertyMapOffset1 = 48; + static const int patchOffsetGetByIdPropertyMapOffset2 = 64; + static const int patchOffsetGetByIdPutResult = 80; #if ENABLE(OPCODE_SAMPLING) #error "OPCODE_SAMPLING is not yet supported" #else @@ -551,21 +531,17 @@ namespace JSC { void compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident, Vector<SlowCaseEntry>::iterator& iter, bool isMethodCheck = false); #endif void compileGetDirectOffset(RegisterID base, RegisterID result, Structure* structure, size_t cachedOffset); - void compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID result, size_t cachedOffset); - void compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID structure, RegisterID offset, RegisterID scratch); + void compileGetDirectOffset(JSObject* base, RegisterID result, size_t cachedOffset); + void compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID offset, RegisterID scratch); void compilePutDirectOffset(RegisterID base, RegisterID value, Structure* structure, size_t cachedOffset); #if CPU(X86_64) // 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 = 20; - static const int patchLengthPutByIdExternalLoad = 4; static const int patchOffsetPutByIdPropertyMapOffset = 31; // 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 = 20; - static const int patchOffsetGetByIdExternalLoad = 20; - static const int patchLengthGetByIdExternalLoad = 4; static const int patchOffsetGetByIdPropertyMapOffset = 31; static const int patchOffsetGetByIdPutResult = 31; #if ENABLE(OPCODE_SAMPLING) @@ -581,14 +557,10 @@ namespace JSC { #elif CPU(X86) // These architecture specific value are used to enable patching - see comment on op_put_by_id. static const int patchOffsetPutByIdStructure = 7; - static const int patchOffsetPutByIdExternalLoad = 13; - static const int patchLengthPutByIdExternalLoad = 3; static const int patchOffsetPutByIdPropertyMapOffset = 22; // These architecture specific value are used to enable patching - see comment on op_get_by_id. static const int patchOffsetGetByIdStructure = 7; static const int patchOffsetGetByIdBranchToSlowCase = 13; - static const int patchOffsetGetByIdExternalLoad = 13; - static const int patchLengthGetByIdExternalLoad = 3; static const int patchOffsetGetByIdPropertyMapOffset = 22; static const int patchOffsetGetByIdPutResult = 22; #if ENABLE(OPCODE_SAMPLING) @@ -604,14 +576,10 @@ namespace JSC { #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 patchOffsetPutByIdPropertyMapOffset = 46; // 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 patchOffsetGetByIdPropertyMapOffset = 46; static const int patchOffsetGetByIdPutResult = 50; #if ENABLE(OPCODE_SAMPLING) @@ -627,14 +595,10 @@ namespace JSC { #elif CPU(ARM_TRADITIONAL) // These architecture specific value are used to enable patching - see comment on op_put_by_id. static const int patchOffsetPutByIdStructure = 4; - static const int patchOffsetPutByIdExternalLoad = 16; - static const int patchLengthPutByIdExternalLoad = 4; static const int patchOffsetPutByIdPropertyMapOffset = 20; // These architecture specific value are used to enable patching - see comment on op_get_by_id. static const int patchOffsetGetByIdStructure = 4; static const int patchOffsetGetByIdBranchToSlowCase = 16; - static const int patchOffsetGetByIdExternalLoad = 16; - static const int patchLengthGetByIdExternalLoad = 4; static const int patchOffsetGetByIdPropertyMapOffset = 20; static const int patchOffsetGetByIdPutResult = 28; #if ENABLE(OPCODE_SAMPLING) @@ -666,13 +630,9 @@ namespace JSC { #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) @@ -686,13 +646,9 @@ namespace JSC { 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) diff --git a/Source/JavaScriptCore/jit/JITCall.cpp b/Source/JavaScriptCore/jit/JITCall.cpp index fdd0d47..524e576 100644 --- a/Source/JavaScriptCore/jit/JITCall.cpp +++ b/Source/JavaScriptCore/jit/JITCall.cpp @@ -49,7 +49,7 @@ namespace JSC { void JIT::compileOpCallInitializeCallFrame() { store32(regT1, Address(callFrameRegister, RegisterFile::ArgumentCount * static_cast<int>(sizeof(Register)))); - loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scopeChain) + OBJECT_OFFSETOF(ScopeChain, m_node)), regT3); // newScopeChain + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scopeChain)), regT3); // newScopeChain storePtr(regT0, Address(callFrameRegister, RegisterFile::Callee * static_cast<int>(sizeof(Register)))); storePtr(regT3, Address(callFrameRegister, RegisterFile::ScopeChain * static_cast<int>(sizeof(Register)))); } @@ -198,7 +198,7 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca // Fast version of stack frame initialization, directly relative to edi. // Note that this omits to set up RegisterFile::CodeBlock, which is set in the callee - loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scopeChain) + OBJECT_OFFSETOF(ScopeChain, m_node)), regT1); // newScopeChain + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scopeChain)), regT1); // newScopeChain store32(Imm32(argCount), Address(callFrameRegister, (registerOffset + RegisterFile::ArgumentCount) * static_cast<int>(sizeof(Register)))); storePtr(callFrameRegister, Address(callFrameRegister, (registerOffset + RegisterFile::CallerFrame) * static_cast<int>(sizeof(Register)))); diff --git a/Source/JavaScriptCore/jit/JITCall32_64.cpp b/Source/JavaScriptCore/jit/JITCall32_64.cpp index daf5d2d..ac231a9 100644 --- a/Source/JavaScriptCore/jit/JITCall32_64.cpp +++ b/Source/JavaScriptCore/jit/JITCall32_64.cpp @@ -50,7 +50,7 @@ void JIT::compileOpCallInitializeCallFrame() { // regT0 holds callee, regT1 holds argCount store32(regT1, Address(callFrameRegister, RegisterFile::ArgumentCount * static_cast<int>(sizeof(Register)))); - loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scopeChain) + OBJECT_OFFSETOF(ScopeChain, m_node)), regT3); // scopeChain + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scopeChain)), regT3); // scopeChain storePtr(regT0, Address(callFrameRegister, RegisterFile::Callee * static_cast<int>(sizeof(Register)))); // callee storePtr(regT3, Address(callFrameRegister, RegisterFile::ScopeChain * static_cast<int>(sizeof(Register)))); // scopeChain } @@ -107,12 +107,6 @@ void JIT::emit_op_ret(Instruction* currentInstruction) { unsigned dst = currentInstruction[1].u.operand; - // We could JIT generate the deref, only calling out to C when the refcount hits zero. - if (m_codeBlock->needsFullScopeChain()) { - Jump activationNotCreated = branch32(Equal, tagFor(m_codeBlock->activationRegister()), Imm32(JSValue::EmptyValueTag)); - JITStubCall(this, cti_op_ret_scopeChain).call(); - activationNotCreated.link(this); - } emitLoad(dst, regT1, regT0); emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT2); emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister); @@ -126,13 +120,6 @@ void JIT::emit_op_ret_object_or_this(Instruction* currentInstruction) unsigned result = currentInstruction[1].u.operand; unsigned thisReg = currentInstruction[2].u.operand; - // We could JIT generate the deref, only calling out to C when the refcount hits zero. - if (m_codeBlock->needsFullScopeChain()) { - Jump activationNotCreated = branch32(Equal, tagFor(m_codeBlock->activationRegister()), Imm32(JSValue::EmptyValueTag)); - JITStubCall(this, cti_op_ret_scopeChain).call(); - activationNotCreated.link(this); - } - emitLoad(result, regT1, regT0); Jump notJSCell = branch32(NotEqual, regT1, Imm32(JSValue::CellTag)); loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); @@ -282,7 +269,7 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca END_UNINTERRUPTED_SEQUENCE(sequenceOpCall); addSlowCase(jumpToSlow); - ASSERT(differenceBetween(addressOfLinkedFunctionCheck, jumpToSlow) == patchOffsetOpCallCompareToJump); + ASSERT_JIT_OFFSET(differenceBetween(addressOfLinkedFunctionCheck, jumpToSlow), patchOffsetOpCallCompareToJump); m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathBegin = addressOfLinkedFunctionCheck; addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::CellTag))); @@ -291,7 +278,7 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca // Fast version of stack frame initialization, directly relative to edi. // Note that this omits to set up RegisterFile::CodeBlock, which is set in the callee - loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scopeChain) + OBJECT_OFFSETOF(ScopeChain, m_node)), regT2); + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scopeChain)), regT2); store32(Imm32(argCount), Address(callFrameRegister, (registerOffset + RegisterFile::ArgumentCount) * static_cast<int>(sizeof(Register)))); storePtr(callFrameRegister, Address(callFrameRegister, (registerOffset + RegisterFile::CallerFrame) * static_cast<int>(sizeof(Register)))); diff --git a/Source/JavaScriptCore/jit/JITOpcodes.cpp b/Source/JavaScriptCore/jit/JITOpcodes.cpp index f458ea2..fc769db 100644 --- a/Source/JavaScriptCore/jit/JITOpcodes.cpp +++ b/Source/JavaScriptCore/jit/JITOpcodes.cpp @@ -330,9 +330,6 @@ void JIT::emit_op_mov(Instruction* currentInstruction) void JIT::emit_op_end(Instruction* currentInstruction) { - if (m_codeBlock->needsFullScopeChain()) - JITStubCall(this, cti_op_end).call(); - ASSERT(returnValueRegister != callFrameRegister); emitGetVirtualRegister(currentInstruction[1].u.operand, returnValueRegister); restoreReturnAddressBeforeReturn(Address(callFrameRegister, RegisterFile::ReturnPC * static_cast<int>(sizeof(Register)))); @@ -543,12 +540,6 @@ void JIT::emit_op_tear_off_arguments(Instruction* currentInstruction) void JIT::emit_op_ret(Instruction* currentInstruction) { - // We could JIT generate the deref, only calling out to C when the refcount hits zero. - if (m_codeBlock->needsFullScopeChain()) { - Jump activationNotCreated = branchTestPtr(Zero, addressFor(m_codeBlock->activationRegister())); - JITStubCall(this, cti_op_ret_scopeChain).call(); - activationNotCreated.link(this); - } ASSERT(callFrameRegister != regT1); ASSERT(regT1 != returnValueRegister); ASSERT(returnValueRegister != callFrameRegister); @@ -569,13 +560,6 @@ void JIT::emit_op_ret(Instruction* currentInstruction) void JIT::emit_op_ret_object_or_this(Instruction* currentInstruction) { - // We could JIT generate the deref, only calling out to C when the refcount hits zero. - if (m_codeBlock->needsFullScopeChain()) { - Jump activationNotCreated = branchTestPtr(Zero, addressFor(m_codeBlock->activationRegister())); - JITStubCall(this, cti_op_ret_scopeChain).call(); - activationNotCreated.link(this); - } - ASSERT(callFrameRegister != regT1); ASSERT(regT1 != returnValueRegister); ASSERT(returnValueRegister != callFrameRegister); @@ -689,7 +673,7 @@ void JIT::emit_op_resolve_global(Instruction* currentInstruction, bool) // Load cached property // Assume that the global object always uses external storage. - loadPtr(Address(regT0, OBJECT_OFFSETOF(JSGlobalObject, m_externalStorage)), regT0); + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSGlobalObject, m_propertyStorage)), regT0); load32(offsetAddr, regT1); loadPtr(BaseIndex(regT0, regT1, ScalePtr), regT0); emitPutVirtualRegister(currentInstruction[1].u.operand); diff --git a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp index dda74c8..0c8402b 100644 --- a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp +++ b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp @@ -448,8 +448,6 @@ void JIT::emit_op_mov(Instruction* currentInstruction) void JIT::emit_op_end(Instruction* currentInstruction) { - if (m_codeBlock->needsFullScopeChain()) - JITStubCall(this, cti_op_end).call(); ASSERT(returnValueRegister != callFrameRegister); emitLoad(currentInstruction[1].u.operand, regT1, regT0); restoreReturnAddressBeforeReturn(Address(callFrameRegister, RegisterFile::ReturnPC * static_cast<int>(sizeof(Register)))); @@ -804,7 +802,7 @@ void JIT::emit_op_resolve_global(Instruction* currentInstruction, bool dynamic) addSlowCase(branchPtr(NotEqual, regT1, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)))); // Load property. - loadPtr(Address(regT0, OBJECT_OFFSETOF(JSGlobalObject, m_externalStorage)), regT2); + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSGlobalObject, m_propertyStorage)), regT2); load32(offsetAddr, regT3); load32(BaseIndex(regT2, regT3, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0); // payload load32(BaseIndex(regT2, regT3, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1); // tag diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp index 1b95eec..b497319 100644 --- a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp +++ b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp @@ -138,18 +138,10 @@ void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCas stubCall.call(dst); } -void JIT::compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID structure, RegisterID offset, RegisterID scratch) +void JIT::compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID offset, RegisterID scratch) { - ASSERT(sizeof(((Structure*)0)->m_propertyStorageCapacity) == sizeof(int32_t)); - ASSERT(sizeof(JSObject::inlineStorageCapacity) == sizeof(int32_t)); - - Jump notUsingInlineStorage = branch32(NotEqual, Address(structure, OBJECT_OFFSETOF(Structure, m_propertyStorageCapacity)), Imm32(JSObject::inlineStorageCapacity)); - loadPtr(BaseIndex(base, offset, ScalePtr, OBJECT_OFFSETOF(JSObject, m_inlineStorage)), result); - Jump finishedLoad = jump(); - notUsingInlineStorage.link(this); - loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), scratch); + loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_propertyStorage)), scratch); loadPtr(BaseIndex(scratch, offset, ScalePtr, 0), result); - finishedLoad.link(this); } void JIT::emit_op_get_by_pname(Instruction* currentInstruction) @@ -172,7 +164,7 @@ void JIT::emit_op_get_by_pname(Instruction* currentInstruction) load32(addressFor(i), regT3); sub32(Imm32(1), regT3); addSlowCase(branch32(AboveOrEqual, regT3, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_numCacheableSlots)))); - compileGetDirectOffset(regT0, regT0, regT2, regT3, regT1); + compileGetDirectOffset(regT0, regT0, regT3, regT1); emitPutVirtualRegister(dst, regT0); } @@ -427,11 +419,7 @@ void JIT::compileGetByIdHotPath(int, int baseVReg, Identifier*, unsigned propert ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, structureToCompare), patchOffsetGetByIdStructure); ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, structureCheck), patchOffsetGetByIdBranchToSlowCase) - Label externalLoad = loadPtrWithPatchToLEA(Address(regT0, OBJECT_OFFSETOF(JSObject, m_externalStorage)), regT0); - Label externalLoadComplete(this); - ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, externalLoad), patchOffsetGetByIdExternalLoad); - ASSERT_JIT_OFFSET(differenceBetween(externalLoad, externalLoadComplete), patchLengthGetByIdExternalLoad); - + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSObject, m_propertyStorage)), regT0); DataLabel32 displacementLabel = loadPtrWithAddressOffsetPatch(Address(regT0, patchGetByIdDefaultOffset), regT0); ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, displacementLabel), patchOffsetGetByIdPropertyMapOffset); @@ -507,12 +495,7 @@ void JIT::emit_op_put_by_id(Instruction* currentInstruction) addSlowCase(branchPtrWithPatch(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)))); ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, structureToCompare), patchOffsetPutByIdStructure); - // Plant a load from a bogus ofset in the object's property map; we will patch this later, if it is to be used. - Label externalLoad = loadPtrWithPatchToLEA(Address(regT0, OBJECT_OFFSETOF(JSObject, m_externalStorage)), regT0); - Label externalLoadComplete(this); - ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, externalLoad), patchOffsetPutByIdExternalLoad); - ASSERT_JIT_OFFSET(differenceBetween(externalLoad, externalLoadComplete), patchLengthPutByIdExternalLoad); - + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSObject, m_propertyStorage)), regT0); DataLabel32 displacementLabel = storePtrWithAddressOffsetPatch(regT1, Address(regT0, patchGetByIdDefaultOffset)); END_UNINTERRUPTED_SEQUENCE(sequencePutById); @@ -547,9 +530,9 @@ void JIT::compilePutDirectOffset(RegisterID base, RegisterID value, Structure* s { int offset = cachedOffset * sizeof(JSValue); if (structure->isUsingInlineStorage()) - offset += OBJECT_OFFSETOF(JSObject, m_inlineStorage); + offset += JSObject::offsetOfInlineStorage(); else - loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), base); + loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_propertyStorage)), base); storePtr(value, Address(base, offset)); } @@ -557,22 +540,18 @@ void JIT::compilePutDirectOffset(RegisterID base, RegisterID value, Structure* s void JIT::compileGetDirectOffset(RegisterID base, RegisterID result, Structure* structure, size_t cachedOffset) { int offset = cachedOffset * sizeof(JSValue); - if (structure->isUsingInlineStorage()) - offset += OBJECT_OFFSETOF(JSObject, m_inlineStorage); - else - loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), base); - loadPtr(Address(base, offset), result); + if (structure->isUsingInlineStorage()) { + offset += JSObject::offsetOfInlineStorage(); + loadPtr(Address(base, offset), result); + } else { + loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_propertyStorage)), result); + loadPtr(Address(result, offset), result); + } } -void JIT::compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID result, size_t cachedOffset) +void JIT::compileGetDirectOffset(JSObject* base, RegisterID result, size_t cachedOffset) { - if (base->isUsingInlineStorage()) - loadPtr(static_cast<void*>(&base->m_inlineStorage[cachedOffset]), result); - else { - PropertyStorage* protoPropertyStorage = &base->m_externalStorage; - loadPtr(static_cast<void*>(protoPropertyStorage), temp); - loadPtr(Address(temp, cachedOffset * sizeof(JSValue)), result); - } + loadPtr(static_cast<void*>(&base->m_propertyStorage[cachedOffset]), result); } void JIT::testPrototype(JSValue prototype, JumpList& failureCases) @@ -668,11 +647,6 @@ void JIT::patchGetByIdSelf(CodeBlock* codeBlock, StructureStubInfo* stubInfo, St int offset = sizeof(JSValue) * cachedOffset; - // If we're patching to use inline storage, convert the initial load to a lea; this avoids the extra load - // and makes the subsequent load's offset automatically correct - if (structure->isUsingInlineStorage()) - repatchBuffer.repatchLoadPtrToLEA(stubInfo->hotPathBegin.instructionAtOffset(patchOffsetGetByIdExternalLoad)); - // Patch the offset into the propoerty map to load from, then patch the Structure to look for. repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelPtrAtOffset(patchOffsetGetByIdStructure), structure); repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabel32AtOffset(patchOffsetGetByIdPropertyMapOffset), offset); @@ -708,11 +682,6 @@ void JIT::patchPutByIdReplace(CodeBlock* codeBlock, StructureStubInfo* stubInfo, int offset = sizeof(JSValue) * cachedOffset; - // If we're patching to use inline storage, convert the initial load to a lea; this avoids the extra load - // and makes the subsequent load's offset automatically correct - if (structure->isUsingInlineStorage()) - repatchBuffer.repatchLoadPtrToLEA(stubInfo->hotPathBegin.instructionAtOffset(patchOffsetPutByIdExternalLoad)); - // Patch the offset into the propoerty map to load from, then patch the Structure to look for. repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelPtrAtOffset(patchOffsetPutByIdStructure), structure); repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabel32AtOffset(patchOffsetPutByIdPropertyMapOffset), offset); @@ -779,7 +748,7 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str // Checks out okay! if (slot.cachedPropertyType() == PropertySlot::Getter) { needsStubLink = true; - compileGetDirectOffset(protoObject, regT1, regT1, cachedOffset); + compileGetDirectOffset(protoObject, regT1, cachedOffset); JITStubCall stubCall(this, cti_op_get_by_id_getter_stub); stubCall.addArgument(regT1); stubCall.addArgument(regT0); @@ -794,7 +763,7 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress())); stubCall.call(); } else - compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset); + compileGetDirectOffset(protoObject, regT0, cachedOffset); Jump success = jump(); LinkBuffer patchBuffer(this, m_codeBlock->executablePool(), 0); @@ -831,11 +800,7 @@ void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, Polymorphic bool needsStubLink = false; if (slot.cachedPropertyType() == PropertySlot::Getter) { needsStubLink = true; - if (!structure->isUsingInlineStorage()) { - move(regT0, regT1); - compileGetDirectOffset(regT1, regT1, structure, cachedOffset); - } else - compileGetDirectOffset(regT0, regT1, structure, cachedOffset); + compileGetDirectOffset(regT0, regT1, structure, cachedOffset); JITStubCall stubCall(this, cti_op_get_by_id_getter_stub); stubCall.addArgument(regT1); stubCall.addArgument(regT0); @@ -905,7 +870,7 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi bool needsStubLink = false; if (slot.cachedPropertyType() == PropertySlot::Getter) { needsStubLink = true; - compileGetDirectOffset(protoObject, regT1, regT1, cachedOffset); + compileGetDirectOffset(protoObject, regT1, cachedOffset); JITStubCall stubCall(this, cti_op_get_by_id_getter_stub); stubCall.addArgument(regT1); stubCall.addArgument(regT0); @@ -920,7 +885,7 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress())); stubCall.call(); } else - compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset); + compileGetDirectOffset(protoObject, regT0, cachedOffset); Jump success = jump(); @@ -975,7 +940,7 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi bool needsStubLink = false; if (slot.cachedPropertyType() == PropertySlot::Getter) { needsStubLink = true; - compileGetDirectOffset(protoObject, regT1, regT1, cachedOffset); + compileGetDirectOffset(protoObject, regT1, cachedOffset); JITStubCall stubCall(this, cti_op_get_by_id_getter_stub); stubCall.addArgument(regT1); stubCall.addArgument(regT0); @@ -990,7 +955,7 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress())); stubCall.call(); } else - compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset); + compileGetDirectOffset(protoObject, regT0, cachedOffset); Jump success = jump(); LinkBuffer patchBuffer(this, m_codeBlock->executablePool(), 0); @@ -1045,7 +1010,7 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str bool needsStubLink = false; if (slot.cachedPropertyType() == PropertySlot::Getter) { needsStubLink = true; - compileGetDirectOffset(protoObject, regT1, regT1, cachedOffset); + compileGetDirectOffset(protoObject, regT1, cachedOffset); JITStubCall stubCall(this, cti_op_get_by_id_getter_stub); stubCall.addArgument(regT1); stubCall.addArgument(regT0); @@ -1060,7 +1025,7 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress())); stubCall.call(); } else - compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset); + compileGetDirectOffset(protoObject, regT0, cachedOffset); Jump success = jump(); LinkBuffer patchBuffer(this, m_codeBlock->executablePool(), 0); diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp index 710a155..3562200 100644 --- a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp +++ b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp @@ -225,9 +225,9 @@ void JIT::emit_op_method_check(Instruction* currentInstruction) move(Imm32(JSValue::CellTag), regT1); Jump match = jump(); - ASSERT(differenceBetween(info.structureToCompare, protoObj) == patchOffsetMethodCheckProtoObj); - ASSERT(differenceBetween(info.structureToCompare, protoStructureToCompare) == patchOffsetMethodCheckProtoStruct); - ASSERT(differenceBetween(info.structureToCompare, putFunction) == patchOffsetMethodCheckPutFunction); + ASSERT_JIT_OFFSET(differenceBetween(info.structureToCompare, protoObj), patchOffsetMethodCheckProtoObj); + ASSERT_JIT_OFFSET(differenceBetween(info.structureToCompare, protoStructureToCompare), patchOffsetMethodCheckProtoStruct); + ASSERT_JIT_OFFSET(differenceBetween(info.structureToCompare, putFunction), patchOffsetMethodCheckPutFunction); // Link the failure cases here. structureCheck.link(this); @@ -431,21 +431,17 @@ void JIT::compileGetByIdHotPath() DataLabelPtr structureToCompare; Jump structureCheck = branchPtrWithPatch(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure))); addSlowCase(structureCheck); - ASSERT(differenceBetween(hotPathBegin, structureToCompare) == patchOffsetGetByIdStructure); - ASSERT(differenceBetween(hotPathBegin, structureCheck) == patchOffsetGetByIdBranchToSlowCase); - - Label externalLoad = loadPtrWithPatchToLEA(Address(regT0, OBJECT_OFFSETOF(JSObject, m_externalStorage)), regT2); - Label externalLoadComplete(this); - ASSERT(differenceBetween(hotPathBegin, externalLoad) == patchOffsetGetByIdExternalLoad); - ASSERT(differenceBetween(externalLoad, externalLoadComplete) == patchLengthGetByIdExternalLoad); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, structureToCompare), patchOffsetGetByIdStructure); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, structureCheck), patchOffsetGetByIdBranchToSlowCase); + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSObject, m_propertyStorage)), regT2); DataLabel32 displacementLabel1 = loadPtrWithAddressOffsetPatch(Address(regT2, patchGetByIdDefaultOffset), regT0); // payload - ASSERT(differenceBetween(hotPathBegin, displacementLabel1) == patchOffsetGetByIdPropertyMapOffset1); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, displacementLabel1), patchOffsetGetByIdPropertyMapOffset1); DataLabel32 displacementLabel2 = loadPtrWithAddressOffsetPatch(Address(regT2, patchGetByIdDefaultOffset), regT1); // tag - ASSERT(differenceBetween(hotPathBegin, displacementLabel2) == patchOffsetGetByIdPropertyMapOffset2); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, displacementLabel2), patchOffsetGetByIdPropertyMapOffset2); Label putResult(this); - ASSERT(differenceBetween(hotPathBegin, putResult) == patchOffsetGetByIdPutResult); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, putResult), patchOffsetGetByIdPutResult); END_UNINTERRUPTED_SEQUENCE(sequenceGetByIdHotPath); } @@ -481,7 +477,7 @@ void JIT::compileGetByIdSlowCase(int dst, int base, Identifier* ident, Vector<Sl END_UNINTERRUPTED_SEQUENCE(sequenceGetByIdSlowCase); - ASSERT(differenceBetween(coldPathBegin, call) == patchOffsetGetByIdSlowCaseCall); + ASSERT_JIT_OFFSET(differenceBetween(coldPathBegin, call), patchOffsetGetByIdSlowCaseCall); // Track the location of the call; this will be used to recover patch information. m_propertyAccessCompilationInfo[m_propertyAccessInstructionIndex].callReturnLocation = call; @@ -510,21 +506,16 @@ void JIT::emit_op_put_by_id(Instruction* currentInstruction) // It is important that the following instruction plants a 32bit immediate, in order that it can be patched over. DataLabelPtr structureToCompare; addSlowCase(branchPtrWithPatch(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)))); - ASSERT(differenceBetween(hotPathBegin, structureToCompare) == patchOffsetPutByIdStructure); - - // Plant a load from a bogus ofset in the object's property map; we will patch this later, if it is to be used. - Label externalLoad = loadPtrWithPatchToLEA(Address(regT0, OBJECT_OFFSETOF(JSObject, m_externalStorage)), regT0); - Label externalLoadComplete(this); - ASSERT(differenceBetween(hotPathBegin, externalLoad) == patchOffsetPutByIdExternalLoad); - ASSERT(differenceBetween(externalLoad, externalLoadComplete) == patchLengthPutByIdExternalLoad); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, structureToCompare), patchOffsetPutByIdStructure); + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSObject, m_propertyStorage)), regT0); DataLabel32 displacementLabel1 = storePtrWithAddressOffsetPatch(regT2, Address(regT0, patchGetByIdDefaultOffset)); // payload DataLabel32 displacementLabel2 = storePtrWithAddressOffsetPatch(regT3, Address(regT0, patchGetByIdDefaultOffset)); // tag END_UNINTERRUPTED_SEQUENCE(sequencePutById); - ASSERT(differenceBetween(hotPathBegin, displacementLabel1) == patchOffsetPutByIdPropertyMapOffset1); - ASSERT(differenceBetween(hotPathBegin, displacementLabel2) == patchOffsetPutByIdPropertyMapOffset2); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, displacementLabel1), patchOffsetPutByIdPropertyMapOffset1); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, displacementLabel2), patchOffsetPutByIdPropertyMapOffset2); } void JIT::emitSlow_op_put_by_id(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) @@ -552,9 +543,9 @@ void JIT::compilePutDirectOffset(RegisterID base, RegisterID valueTag, RegisterI { int offset = cachedOffset; if (structure->isUsingInlineStorage()) - offset += OBJECT_OFFSETOF(JSObject, m_inlineStorage) / sizeof(Register); + offset += JSObject::offsetOfInlineStorage() / sizeof(Register); else - loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), base); + loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_propertyStorage)), base); emitStore(offset, valueTag, valuePayload, base); } @@ -562,27 +553,20 @@ void JIT::compilePutDirectOffset(RegisterID base, RegisterID valueTag, RegisterI void JIT::compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, Structure* structure, size_t cachedOffset) { int offset = cachedOffset; - if (structure->isUsingInlineStorage()) - offset += OBJECT_OFFSETOF(JSObject, m_inlineStorage) / sizeof(Register); - else - loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), base); - emitLoad(offset, resultTag, resultPayload, base); + if (structure->isUsingInlineStorage()) { + offset += JSObject::offsetOfInlineStorage() / sizeof(Register); + emitLoad(offset, resultTag, resultPayload, base); + } else { + RegisterID temp = resultPayload; + loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_propertyStorage)), temp); + emitLoad(offset, resultTag, resultPayload, temp); + } } -void JIT::compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID resultTag, RegisterID resultPayload, size_t cachedOffset) +void JIT::compileGetDirectOffset(JSObject* base, RegisterID resultTag, RegisterID resultPayload, size_t cachedOffset) { - if (base->isUsingInlineStorage()) { - load32(reinterpret_cast<char*>(&base->m_inlineStorage[cachedOffset]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload), resultPayload); - load32(reinterpret_cast<char*>(&base->m_inlineStorage[cachedOffset]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag), resultTag); - return; - } - - size_t offset = cachedOffset * sizeof(JSValue); - - PropertyStorage* protoPropertyStorage = &base->m_externalStorage; - loadPtr(static_cast<void*>(protoPropertyStorage), temp); - load32(Address(temp, offset + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload); - load32(Address(temp, offset + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag); + load32(reinterpret_cast<char*>(&base->m_propertyStorage[cachedOffset]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload), resultPayload); + load32(reinterpret_cast<char*>(&base->m_propertyStorage[cachedOffset]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag), resultTag); } void JIT::testPrototype(JSValue prototype, JumpList& failureCases) @@ -683,12 +667,7 @@ void JIT::patchGetByIdSelf(CodeBlock* codeBlock, StructureStubInfo* stubInfo, St repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_self_fail)); int offset = sizeof(JSValue) * cachedOffset; - - // If we're patching to use inline storage, convert the initial load to a lea; this avoids the extra load - // and makes the subsequent load's offset automatically correct - if (structure->isUsingInlineStorage()) - repatchBuffer.repatchLoadPtrToLEA(stubInfo->hotPathBegin.instructionAtOffset(patchOffsetGetByIdExternalLoad)); - + // Patch the offset into the propoerty map to load from, then patch the Structure to look for. repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelPtrAtOffset(patchOffsetGetByIdStructure), structure); repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabel32AtOffset(patchOffsetGetByIdPropertyMapOffset1), offset + OBJECT_OFFSETOF(JSValue, u.asBits.payload)); // payload @@ -724,12 +703,7 @@ void JIT::patchPutByIdReplace(CodeBlock* codeBlock, StructureStubInfo* stubInfo, repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(direct ? cti_op_put_by_id_direct_generic : cti_op_put_by_id_generic)); int offset = sizeof(JSValue) * cachedOffset; - - // If we're patching to use inline storage, convert the initial load to a lea; this avoids the extra load - // and makes the subsequent load's offset automatically correct - if (structure->isUsingInlineStorage()) - repatchBuffer.repatchLoadPtrToLEA(stubInfo->hotPathBegin.instructionAtOffset(patchOffsetPutByIdExternalLoad)); - + // Patch the offset into the propoerty map to load from, then patch the Structure to look for. repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelPtrAtOffset(patchOffsetPutByIdStructure), structure); repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabel32AtOffset(patchOffsetPutByIdPropertyMapOffset1), offset + OBJECT_OFFSETOF(JSValue, u.asBits.payload)); // payload @@ -799,7 +773,7 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str // Checks out okay! if (slot.cachedPropertyType() == PropertySlot::Getter) { needsStubLink = true; - compileGetDirectOffset(protoObject, regT2, regT2, regT1, cachedOffset); + compileGetDirectOffset(protoObject, regT2, regT1, cachedOffset); JITStubCall stubCall(this, cti_op_get_by_id_getter_stub); stubCall.addArgument(regT1); stubCall.addArgument(regT0); @@ -814,7 +788,7 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress())); stubCall.call(); } else - compileGetDirectOffset(protoObject, regT2, regT1, regT0, cachedOffset); + compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset); Jump success = jump(); @@ -856,11 +830,7 @@ void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, Polymorphic bool needsStubLink = false; if (slot.cachedPropertyType() == PropertySlot::Getter) { needsStubLink = true; - if (!structure->isUsingInlineStorage()) { - move(regT0, regT1); - compileGetDirectOffset(regT1, regT2, regT1, structure, cachedOffset); - } else - compileGetDirectOffset(regT0, regT2, regT1, structure, cachedOffset); + compileGetDirectOffset(regT0, regT2, regT1, structure, cachedOffset); JITStubCall stubCall(this, cti_op_get_by_id_getter_stub); stubCall.addArgument(regT1); stubCall.addArgument(regT0); @@ -930,7 +900,7 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi bool needsStubLink = false; if (slot.cachedPropertyType() == PropertySlot::Getter) { needsStubLink = true; - compileGetDirectOffset(protoObject, regT2, regT2, regT1, cachedOffset); + compileGetDirectOffset(protoObject, regT2, regT1, cachedOffset); JITStubCall stubCall(this, cti_op_get_by_id_getter_stub); stubCall.addArgument(regT1); stubCall.addArgument(regT0); @@ -945,7 +915,7 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress())); stubCall.call(); } else - compileGetDirectOffset(protoObject, regT2, regT1, regT0, cachedOffset); + compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset); Jump success = jump(); @@ -999,7 +969,7 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi bool needsStubLink = false; if (slot.cachedPropertyType() == PropertySlot::Getter) { needsStubLink = true; - compileGetDirectOffset(protoObject, regT2, regT2, regT1, cachedOffset); + compileGetDirectOffset(protoObject, regT2, regT1, cachedOffset); JITStubCall stubCall(this, cti_op_get_by_id_getter_stub); stubCall.addArgument(regT1); stubCall.addArgument(regT0); @@ -1014,7 +984,7 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress())); stubCall.call(); } else - compileGetDirectOffset(protoObject, regT2, regT1, regT0, cachedOffset); + compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset); Jump success = jump(); @@ -1069,7 +1039,7 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str bool needsStubLink = false; if (slot.cachedPropertyType() == PropertySlot::Getter) { needsStubLink = true; - compileGetDirectOffset(protoObject, regT2, regT2, regT1, cachedOffset); + compileGetDirectOffset(protoObject, regT2, regT1, cachedOffset); JITStubCall stubCall(this, cti_op_get_by_id_getter_stub); stubCall.addArgument(regT1); stubCall.addArgument(regT0); @@ -1084,7 +1054,7 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress())); stubCall.call(); } else - compileGetDirectOffset(protoObject, regT2, regT1, regT0, cachedOffset); + compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset); Jump success = jump(); LinkBuffer patchBuffer(this, m_codeBlock->executablePool(), 0); @@ -1117,21 +1087,13 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str #endif // !ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) -void JIT::compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, RegisterID structure, RegisterID offset) +void JIT::compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, RegisterID offset) { - ASSERT(sizeof(((Structure*)0)->m_propertyStorageCapacity) == sizeof(int32_t)); - ASSERT(sizeof(JSObject::inlineStorageCapacity) == sizeof(int32_t)); ASSERT(sizeof(JSValue) == 8); - Jump notUsingInlineStorage = branch32(NotEqual, Address(structure, OBJECT_OFFSETOF(Structure, m_propertyStorageCapacity)), Imm32(JSObject::inlineStorageCapacity)); - loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSObject, m_inlineStorage) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload); - loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSObject, m_inlineStorage) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag); - Jump finishedLoad = jump(); - notUsingInlineStorage.link(this); - loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), base); + loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_propertyStorage)), base); loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload); loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag); - finishedLoad.link(this); } void JIT::emit_op_get_by_pname(Instruction* currentInstruction) @@ -1156,7 +1118,7 @@ void JIT::emit_op_get_by_pname(Instruction* currentInstruction) load32(addressFor(i), regT3); sub32(Imm32(1), regT3); addSlowCase(branch32(AboveOrEqual, regT3, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_numCacheableSlots)))); - compileGetDirectOffset(regT2, regT1, regT0, regT0, regT3); + compileGetDirectOffset(regT2, regT1, regT0, regT3); emitStore(dst, regT1, regT0); map(m_bytecodeOffset + OPCODE_LENGTH(op_get_by_pname), dst, regT1, regT0); diff --git a/Source/JavaScriptCore/jit/JITStubs.cpp b/Source/JavaScriptCore/jit/JITStubs.cpp index 74f505f..95bf52c 100644 --- a/Source/JavaScriptCore/jit/JITStubs.cpp +++ b/Source/JavaScriptCore/jit/JITStubs.cpp @@ -40,7 +40,6 @@ #include "Debugger.h" #include "ExceptionHelpers.h" #include "GetterSetter.h" -#include "GlobalEvalFunction.h" #include "JIT.h" #include "JSActivation.h" #include "JSArray.h" @@ -717,7 +716,7 @@ JITThunks::JITThunks(JSGlobalData* globalData) ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, thunkReturnAddress) == THUNK_RETURN_ADDRESS_OFFSET); ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, registerFile) == REGISTER_FILE_OFFSET); ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, callFrame) == CALLFRAME_OFFSET); - ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, exception) == EXCEPTION_OFFSET); + ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, unused1) == EXCEPTION_OFFSET); ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, enabledProfilerReference) == ENABLE_PROFILER_REFERENCE_OFFSET); ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, globalData) == GLOBAL_DATA_OFFSET); @@ -1175,8 +1174,8 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_create_this) if (proto.isObject()) structure = asObject(proto)->inheritorID(); else - structure = constructor->scope().node()->globalObject->emptyObjectStructure(); - JSValue result = new (&callFrame->globalData()) JSObject(structure); + structure = constructor->scope()->globalObject->emptyObjectStructure(); + JSValue result = constructEmptyObject(callFrame, structure); return JSValue::encode(result); } @@ -1205,15 +1204,6 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_convert_this_strict) return JSValue::encode(result); } -DEFINE_STUB_FUNCTION(void, op_end) -{ - STUB_INIT_STACK_FRAME(stackFrame); - - ScopeChainNode* scopeChain = stackFrame.callFrame->scopeChain(); - ASSERT(scopeChain->refCount > 1); - scopeChain->deref(); -} - DEFINE_STUB_FUNCTION(EncodedJSValue, op_add) { STUB_INIT_STACK_FRAME(stackFrame); @@ -1848,7 +1838,7 @@ DEFINE_STUB_FUNCTION(void*, op_call_jitCompile) JSFunction* function = asFunction(stackFrame.callFrame->callee()); ASSERT(!function->isHostFunction()); FunctionExecutable* executable = function->jsExecutable(); - ScopeChainNode* callDataScopeChain = function->scope().node(); + ScopeChainNode* callDataScopeChain = function->scope(); JSObject* error = executable->compileForCall(stackFrame.callFrame, callDataScopeChain); if (error) { stackFrame.callFrame->globalData().exception = error; @@ -1869,7 +1859,7 @@ DEFINE_STUB_FUNCTION(void*, op_construct_jitCompile) JSFunction* function = asFunction(stackFrame.callFrame->callee()); ASSERT(!function->isHostFunction()); FunctionExecutable* executable = function->jsExecutable(); - ScopeChainNode* callDataScopeChain = function->scope().node(); + ScopeChainNode* callDataScopeChain = function->scope(); JSObject* error = executable->compileForConstruct(stackFrame.callFrame, callDataScopeChain); if (error) { stackFrame.callFrame->globalData().exception = error; @@ -1930,7 +1920,7 @@ DEFINE_STUB_FUNCTION(void*, op_call_arityCheck) callFrame->setCallerFrame(oldCallFrame); callFrame->setArgumentCountIncludingThis(argCount); callFrame->setCallee(callee); - callFrame->setScopeChain(callee->scope().node()); + callFrame->setScopeChain(callee->scope()); callFrame->setReturnPC(pc.value()); ASSERT((void*)callFrame <= stackFrame.registerFile->end()); @@ -1989,7 +1979,7 @@ DEFINE_STUB_FUNCTION(void*, op_construct_arityCheck) callFrame->setCallerFrame(oldCallFrame); callFrame->setArgumentCountIncludingThis(argCount); callFrame->setCallee(callee); - callFrame->setScopeChain(callee->scope().node()); + callFrame->setScopeChain(callee->scope()); callFrame->setReturnPC(pc.value()); ASSERT((void*)callFrame <= stackFrame.registerFile->end()); @@ -2010,7 +2000,7 @@ DEFINE_STUB_FUNCTION(void*, vm_lazyLinkCall) codePtr = executable->generatedJITCodeForCall().addressForCall(); else { FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); - JSObject* error = functionExecutable->compileForCall(callFrame, callee->scope().node()); + JSObject* error = functionExecutable->compileForCall(callFrame, callee->scope()); if (error) { callFrame->globalData().exception = createStackOverflowError(callFrame); return 0; @@ -2044,7 +2034,7 @@ DEFINE_STUB_FUNCTION(void*, vm_lazyLinkConstruct) codePtr = executable->generatedJITCodeForConstruct().addressForCall(); else { FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); - JSObject* error = functionExecutable->compileForConstruct(callFrame, callee->scope().node()); + JSObject* error = functionExecutable->compileForConstruct(callFrame, callee->scope()); if (error) { throwStackOverflowError(callFrame, stackFrame.globalData, ReturnAddressPtr(callFrame->returnPC()), STUB_RETURN_ADDRESS); return 0; @@ -2071,7 +2061,7 @@ DEFINE_STUB_FUNCTION(JSObject*, op_push_activation) STUB_INIT_STACK_FRAME(stackFrame); JSActivation* activation = new (stackFrame.globalData) JSActivation(stackFrame.callFrame, static_cast<FunctionExecutable*>(stackFrame.callFrame->codeBlock()->ownerExecutable())); - stackFrame.callFrame->setScopeChain(stackFrame.callFrame->scopeChain()->copy()->push(activation)); + stackFrame.callFrame->setScopeChain(stackFrame.callFrame->scopeChain()->push(activation)); return activation; } @@ -2139,12 +2129,12 @@ DEFINE_STUB_FUNCTION(void, op_tear_off_activation) if (!activationValue) { if (JSValue v = stackFrame.args[1].jsValue()) { if (!stackFrame.callFrame->codeBlock()->isStrictMode()) - asArguments(v)->copyRegisters(); + asArguments(v)->copyRegisters(*stackFrame.globalData); } return; } JSActivation* activation = asActivation(stackFrame.args[0].jsValue()); - activation->copyRegisters(); + activation->copyRegisters(*stackFrame.globalData); if (JSValue v = stackFrame.args[1].jsValue()) { if (!stackFrame.callFrame->codeBlock()->isStrictMode()) asArguments(v)->setActivation(*stackFrame.globalData, activation); @@ -2156,7 +2146,7 @@ DEFINE_STUB_FUNCTION(void, op_tear_off_arguments) STUB_INIT_STACK_FRAME(stackFrame); ASSERT(stackFrame.callFrame->codeBlock()->usesArguments() && !stackFrame.callFrame->codeBlock()->needsFullScopeChain()); - asArguments(stackFrame.args[0].jsValue())->copyRegisters(); + asArguments(stackFrame.args[0].jsValue())->copyRegisters(*stackFrame.globalData); } DEFINE_STUB_FUNCTION(void, op_profile_will_call) @@ -2175,14 +2165,6 @@ DEFINE_STUB_FUNCTION(void, op_profile_did_call) (*stackFrame.enabledProfilerReference)->didExecute(stackFrame.callFrame, stackFrame.args[0].jsValue()); } -DEFINE_STUB_FUNCTION(void, op_ret_scopeChain) -{ - STUB_INIT_STACK_FRAME(stackFrame); - - ASSERT(stackFrame.callFrame->codeBlock()->needsFullScopeChain()); - stackFrame.callFrame->scopeChain()->deref(); -} - DEFINE_STUB_FUNCTION(JSObject*, op_new_array) { STUB_INIT_STACK_FRAME(stackFrame); @@ -2525,7 +2507,7 @@ DEFINE_STUB_FUNCTION(int, op_load_varargs) stackFrame.globalData->exception = createInvalidParamError(callFrame, "Function.prototype.apply", arguments); VM_THROW_EXCEPTION(); } - if (asObject(arguments)->classInfo() == &Arguments::info) { + if (asObject(arguments)->classInfo() == &Arguments::s_info) { Arguments* argsObject = asArguments(arguments); argCount = argsObject->numProvidedArguments(callFrame); argCount = min(argCount, static_cast<uint32_t>(Arguments::MaxArguments)); @@ -2547,7 +2529,7 @@ DEFINE_STUB_FUNCTION(int, op_load_varargs) VM_THROW_EXCEPTION(); } array->copyToRegisters(callFrame, callFrame->registers() + argsOffset, argCount); - } else if (asObject(arguments)->inherits(&JSArray::info)) { + } else if (asObject(arguments)->inherits(&JSArray::s_info)) { JSObject* argObject = asObject(arguments); argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame); argCount = min(argCount, static_cast<uint32_t>(Arguments::MaxArguments)); @@ -3009,7 +2991,7 @@ DEFINE_STUB_FUNCTION(JSObject*, op_new_func_exp) */ if (!function->name().isNull()) { JSStaticScopeObject* functionScopeObject = new (callFrame) JSStaticScopeObject(callFrame, function->name(), func, ReadOnly | DontDelete); - func->scope().push(functionScopeObject); + func->setScope(callFrame->globalData(), func->scope()->push(functionScopeObject)); } return func; @@ -3119,7 +3101,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_call_eval) Register* newCallFrame = callFrame->registers() + registerOffset; Register* argv = newCallFrame - RegisterFile::CallFrameHeaderSize - argCount; JSValue baseValue = argv[0].jsValue(); - JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject; + JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject.get(); if (baseValue == globalObject && funcVal == globalObject->evalFunction()) { JSValue result = interpreter->callEval(callFrame, registerFile, argv, argCount, registerOffset); diff --git a/Source/JavaScriptCore/jit/JITStubs.h b/Source/JavaScriptCore/jit/JITStubs.h index 66edf45..65f6a55 100644 --- a/Source/JavaScriptCore/jit/JITStubs.h +++ b/Source/JavaScriptCore/jit/JITStubs.h @@ -390,7 +390,6 @@ extern "C" { void JIT_STUB cti_op_put_by_val_byte_array(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_put_getter(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_put_setter(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_ret_scopeChain(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_tear_off_activation(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_tear_off_arguments(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_throw_reference_error(STUB_ARGS_DECLARATION); |