diff options
Diffstat (limited to 'src/3rdparty/webkit/JavaScriptCore/jit')
9 files changed, 207 insertions, 52 deletions
diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocator.h b/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocator.h index 1d15ef0..5c43eeb 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocator.h +++ b/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocator.h @@ -189,6 +189,22 @@ public: sys_dcache_flush(code, size); sys_icache_invalidate(code, size); } +#elif PLATFORM(ARM_THUMB2) && PLATFORM(LINUX) + static void cacheFlush(void* code, size_t size) + { + asm volatile ( + "push {r7}\n" + "mov r0, %0\n" + "mov r1, %1\n" + "movw r7, #0x2\n" + "movt r7, #0xf\n" + "movs r2, #0x0\n" + "svc 0x0\n" + "pop {r7}\n" + : + : "r" (code), "r" (reinterpret_cast<char*>(code) + size) + : "r0", "r1"); + } #elif PLATFORM(SYMBIAN) static void cacheFlush(void* code, size_t size) { diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JIT.cpp b/src/3rdparty/webkit/JavaScriptCore/jit/JIT.cpp index fa0ac2e..000e4b8 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JIT.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JIT.cpp @@ -239,6 +239,7 @@ void JIT::privateCompileMainPass() DEFINE_OP(op_eq_null) DEFINE_OP(op_get_by_id) DEFINE_OP(op_get_by_val) + DEFINE_OP(op_get_by_pname) DEFINE_OP(op_get_global_var) DEFINE_OP(op_get_pnames) DEFINE_OP(op_get_scoped_var) @@ -385,6 +386,7 @@ void JIT::privateCompileSlowCases() DEFINE_SLOWCASE_OP(op_eq) DEFINE_SLOWCASE_OP(op_get_by_id) DEFINE_SLOWCASE_OP(op_get_by_val) + DEFINE_SLOWCASE_OP(op_get_by_pname) DEFINE_SLOWCASE_OP(op_instanceof) DEFINE_SLOWCASE_OP(op_jfalse) DEFINE_SLOWCASE_OP(op_jnless) diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JIT.h b/src/3rdparty/webkit/JavaScriptCore/jit/JIT.h index 9406d1f..e19ea17 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JIT.h +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JIT.h @@ -38,6 +38,8 @@ #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)); + #include "CodeBlock.h" #include "Interpreter.h" #include "JITCode.h" @@ -249,7 +251,6 @@ namespace JSC { static const RegisterID timeoutCheckRegister = ARMRegisters::r5; static const RegisterID callFrameRegister = ARMRegisters::r4; - static const RegisterID ctiReturnRegister = ARMRegisters::r6; static const RegisterID regT0 = ARMRegisters::r0; static const RegisterID regT1 = ARMRegisters::r1; @@ -427,6 +428,7 @@ namespace JSC { #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 compilePutDirectOffset(RegisterID base, RegisterID valueTag, RegisterID valuePayload, Structure* structure, size_t cachedOffset); // Arithmetic opcode helpers @@ -528,6 +530,7 @@ namespace JSC { #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 compilePutDirectOffset(RegisterID base, RegisterID value, Structure* structure, size_t cachedOffset); #if PLATFORM(X86_64) @@ -583,26 +586,26 @@ namespace JSC { #elif PLATFORM(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 = 20; + static const int patchOffsetPutByIdExternalLoad = 26; static const int patchLengthPutByIdExternalLoad = 12; - static const int patchOffsetPutByIdPropertyMapOffset = 40; + 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 = 20; - static const int patchOffsetGetByIdExternalLoad = 20; + static const int patchOffsetGetByIdBranchToSlowCase = 26; + static const int patchOffsetGetByIdExternalLoad = 26; static const int patchLengthGetByIdExternalLoad = 12; - static const int patchOffsetGetByIdPropertyMapOffset = 40; - static const int patchOffsetGetByIdPutResult = 44; + static const int patchOffsetGetByIdPropertyMapOffset = 46; + static const int patchOffsetGetByIdPutResult = 50; #if ENABLE(OPCODE_SAMPLING) static const int patchOffsetGetByIdSlowCaseCall = 0; // FIMXE #else static const int patchOffsetGetByIdSlowCaseCall = 28; #endif - static const int patchOffsetOpCallCompareToJump = 10; + static const int patchOffsetOpCallCompareToJump = 16; - static const int patchOffsetMethodCheckProtoObj = 18; - static const int patchOffsetMethodCheckProtoStruct = 28; - static const int patchOffsetMethodCheckPutFunction = 46; + static const int patchOffsetMethodCheckProtoObj = 24; + static const int patchOffsetMethodCheckProtoStruct = 34; + static const int patchOffsetMethodCheckPutFunction = 58; #elif PLATFORM(ARM_TRADITIONAL) // These architecture specific value are used to enable patching - see comment on op_put_by_id. static const int patchOffsetPutByIdStructure = 4; @@ -619,7 +622,7 @@ namespace JSC { #if ENABLE(OPCODE_SAMPLING) #error "OPCODE_SAMPLING is not yet supported" #else - static const int patchOffsetGetByIdSlowCaseCall = 36; + static const int patchOffsetGetByIdSlowCaseCall = 28; #endif static const int patchOffsetOpCallCompareToJump = 12; @@ -640,7 +643,7 @@ namespace JSC { static const int sequenceGetByIdHotPathInstructionSpace = 28; static const int sequenceGetByIdHotPathConstantSpace = 3; // sequenceGetByIdSlowCase - static const int sequenceGetByIdSlowCaseInstructionSpace = 40; + static const int sequenceGetByIdSlowCaseInstructionSpace = 32; static const int sequenceGetByIdSlowCaseConstantSpace = 2; // sequencePutById static const int sequencePutByIdInstructionSpace = 28; @@ -682,6 +685,7 @@ namespace JSC { void emit_op_eq_null(Instruction*); void emit_op_get_by_id(Instruction*); void emit_op_get_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*); @@ -771,6 +775,7 @@ namespace JSC { void emitSlow_op_eq(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_get_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_get_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_get_by_pname(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&); diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JITCall.cpp b/src/3rdparty/webkit/JavaScriptCore/jit/JITCall.cpp index cfaa69f..f7fcc0a 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JITCall.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JITCall.cpp @@ -614,7 +614,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; // The following is the fast case, only used whan a callee can be linked. diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JITInlineMethods.h b/src/3rdparty/webkit/JavaScriptCore/jit/JITInlineMethods.h index f26457a..93d6ce7 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JITInlineMethods.h +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JITInlineMethods.h @@ -144,7 +144,7 @@ ALWAYS_INLINE void JIT::endUninterruptedSequence(int insnSpace, int constSpace) #endif -#if PLATFORM(ARM_THUMB2) +#if PLATFORM(ARM) ALWAYS_INLINE void JIT::preserveReturnAddressAfterCall(RegisterID reg) { @@ -161,7 +161,7 @@ ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(Address address) loadPtr(address, linkRegister); } -#else // PLATFORM(X86) || PLATFORM(X86_64) || PLATFORM(ARM_TRADITIONAL) +#else // PLATFORM(X86) || PLATFORM(X86_64) ALWAYS_INLINE void JIT::preserveReturnAddressAfterCall(RegisterID reg) { @@ -191,16 +191,13 @@ ALWAYS_INLINE void JIT::restoreArgumentReference() { move(stackPointerRegister, firstArgumentRegister); poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof (void*)); -#if PLATFORM(ARM_TRADITIONAL) - move(ctiReturnRegister, ARMRegisters::lr); -#endif } ALWAYS_INLINE void JIT::restoreArgumentReferenceForTrampoline() { #if PLATFORM(X86) // Within a trampoline the return address will be on the stack at this point. addPtr(Imm32(sizeof(void*)), stackPointerRegister, firstArgumentRegister); -#elif PLATFORM(ARM_THUMB2) +#elif PLATFORM(ARM) move(stackPointerRegister, firstArgumentRegister); #endif // In the trampoline on x86-64, the first argument register is not overwritten. diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JITOpcodes.cpp b/src/3rdparty/webkit/JavaScriptCore/jit/JITOpcodes.cpp index e10d105..14736cf 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JITOpcodes.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JITOpcodes.cpp @@ -1792,7 +1792,6 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable // Setup arg4: This is a plain hack move(stackPointerRegister, ARMRegisters::S0); - move(ctiReturnRegister, ARMRegisters::lr); call(Address(regT1, OBJECT_OFFSETOF(JSFunction, m_data))); addPtr(Imm32(sizeof(ArgList)), stackPointerRegister); @@ -2500,7 +2499,13 @@ void JIT::emit_op_next_pname(Instruction* currentInstruction) // Grab key @ i loadPtr(addressFor(it), regT1); loadPtr(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStrings)), regT2); + +#if USE(JSVALUE64) loadPtr(BaseIndex(regT2, regT0, TimesEight), regT2); +#else + loadPtr(BaseIndex(regT2, regT0, TimesFour), regT2); +#endif + emitPutVirtualRegister(dst, regT2); // Increment i diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JITPropertyAccess.cpp b/src/3rdparty/webkit/JavaScriptCore/jit/JITPropertyAccess.cpp index 4241111..bf367a6 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JITPropertyAccess.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JITPropertyAccess.cpp @@ -33,6 +33,7 @@ #include "JITStubCall.h" #include "JSArray.h" #include "JSFunction.h" +#include "JSPropertyNameIterator.h" #include "Interpreter.h" #include "LinkBuffer.h" #include "RepatchBuffer.h" @@ -934,6 +935,69 @@ 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) +{ + 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(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) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned base = currentInstruction[2].u.operand; + unsigned property = currentInstruction[3].u.operand; + unsigned expected = currentInstruction[4].u.operand; + unsigned iter = currentInstruction[5].u.operand; + unsigned i = currentInstruction[6].u.operand; + + emitLoad2(property, regT1, regT0, base, regT3, regT2); + emitJumpSlowCaseIfNotJSCell(property, regT1); + addSlowCase(branchPtr(NotEqual, regT0, payloadFor(expected))); + // Property registers are now available as the property is known + emitJumpSlowCaseIfNotJSCell(base, regT3); + emitLoadPayload(iter, regT1); + + // Test base's structure + loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT0); + addSlowCase(branchPtr(NotEqual, regT0, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructure)))); + 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); + + emitStore(dst, regT1, regT0); + map(m_bytecodeIndex + OPCODE_LENGTH(op_get_by_pname), dst, regT1, regT0); +} + +void JIT::emitSlow_op_get_by_pname(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned base = currentInstruction[2].u.operand; + unsigned property = currentInstruction[3].u.operand; + + linkSlowCaseIfNotJSCell(iter, property); + linkSlowCase(iter); + linkSlowCaseIfNotJSCell(iter, base); + linkSlowCase(iter); + linkSlowCase(iter); + + JITStubCall stubCall(this, cti_op_get_by_val); + stubCall.addArgument(base); + stubCall.addArgument(property); + stubCall.call(dst); +} + #else // USE(JSVALUE32_64) void JIT::emit_op_get_by_val(Instruction* currentInstruction) @@ -967,6 +1031,48 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction) emitPutVirtualRegister(dst); } +void JIT::emit_op_get_by_pname(Instruction* currentInstruction) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned base = currentInstruction[2].u.operand; + unsigned property = currentInstruction[3].u.operand; + unsigned expected = currentInstruction[4].u.operand; + unsigned iter = currentInstruction[5].u.operand; + unsigned i = currentInstruction[6].u.operand; + + emitGetVirtualRegister(property, regT0); + addSlowCase(branchPtr(NotEqual, regT0, addressFor(expected))); + emitGetVirtualRegisters(base, regT0, iter, regT1); + emitJumpSlowCaseIfNotJSCell(regT0, base); + + // Test base's structure + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); + addSlowCase(branchPtr(NotEqual, regT2, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructure)))); + 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); + + emitPutVirtualRegister(dst, regT0); +} + +void JIT::emitSlow_op_get_by_pname(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + unsigned dst = currentInstruction[1].u.operand; + unsigned base = currentInstruction[2].u.operand; + unsigned property = currentInstruction[3].u.operand; + + linkSlowCase(iter); + linkSlowCaseIfNotJSCell(iter, base); + linkSlowCase(iter); + linkSlowCase(iter); + + JITStubCall stubCall(this, cti_op_get_by_val); + stubCall.addArgument(base, regT2); + stubCall.addArgument(property, regT2); + stubCall.call(dst); +} + void JIT::emit_op_put_by_val(Instruction* currentInstruction) { unsigned base = currentInstruction[1].u.operand; @@ -1132,9 +1238,9 @@ void JIT::emit_op_method_check(Instruction* currentInstruction) 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. notCell.link(this); @@ -1201,22 +1307,22 @@ void JIT::compileGetByIdHotPath(int, int baseVReg, Identifier*, unsigned propert 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); + 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(differenceBetween(hotPathBegin, externalLoad) == patchOffsetGetByIdExternalLoad); - ASSERT(differenceBetween(externalLoad, externalLoadComplete) == patchLengthGetByIdExternalLoad); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, externalLoad), patchOffsetGetByIdExternalLoad); + ASSERT_JIT_OFFSET(differenceBetween(externalLoad, externalLoadComplete), patchLengthGetByIdExternalLoad); DataLabel32 displacementLabel = loadPtrWithAddressOffsetPatch(Address(regT0, patchGetByIdDefaultOffset), regT0); - ASSERT(differenceBetween(hotPathBegin, displacementLabel) == patchOffsetGetByIdPropertyMapOffset); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, displacementLabel), patchOffsetGetByIdPropertyMapOffset); Label putResult(this); END_UNINTERRUPTED_SEQUENCE(sequenceGetByIdHotPath); - ASSERT(differenceBetween(hotPathBegin, putResult) == patchOffsetGetByIdPutResult); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, putResult), patchOffsetGetByIdPutResult); } void JIT::emitSlow_op_get_by_id(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) @@ -1251,7 +1357,7 @@ void JIT::compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident 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; @@ -1282,19 +1388,19 @@ 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); + 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(differenceBetween(hotPathBegin, externalLoad) == patchOffsetPutByIdExternalLoad); - ASSERT(differenceBetween(externalLoad, externalLoadComplete) == patchLengthPutByIdExternalLoad); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, externalLoad), patchOffsetPutByIdExternalLoad); + ASSERT_JIT_OFFSET(differenceBetween(externalLoad, externalLoadComplete), patchLengthPutByIdExternalLoad); DataLabel32 displacementLabel = storePtrWithAddressOffsetPatch(regT1, Address(regT0, patchGetByIdDefaultOffset)); END_UNINTERRUPTED_SEQUENCE(sequencePutById); - ASSERT(differenceBetween(hotPathBegin, displacementLabel) == patchOffsetPutByIdPropertyMapOffset); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, displacementLabel), patchOffsetPutByIdPropertyMapOffset); } void JIT::emitSlow_op_put_by_id(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) @@ -1351,6 +1457,20 @@ void JIT::compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID res } } +void JIT::compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID structure, 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(BaseIndex(scratch, offset, ScalePtr, 0), result); + finishedLoad.link(this); +} + void JIT::testPrototype(Structure* structure, JumpList& failureCases) { if (structure->m_prototype.isNull()) diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.cpp b/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.cpp index 457518c..470ed0b 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.cpp @@ -570,22 +570,15 @@ HIDE_SYMBOL(ctiTrampoline) "\n" SYMBOL_STRING(ctiTrampoline) ":" "\n" "stmdb sp!, {r1-r3}" "\n" "stmdb sp!, {r4-r8, lr}" "\n" - "mov r6, pc" "\n" - "add r6, r6, #40" "\n" - "sub sp, sp, #32" "\n" - "ldr r4, [sp, #60]" "\n" + "sub sp, sp, #36" "\n" + "mov r4, r2" "\n" "mov r5, #512" "\n" - // r0 contains the code - "add r8, pc, #4" "\n" - "str r8, [sp, #-4]!" "\n" + "mov lr, pc" "\n" "mov pc, r0" "\n" - "add sp, sp, #32" "\n" + "add sp, sp, #36" "\n" "ldmia sp!, {r4-r8, lr}" "\n" "add sp, sp, #12" "\n" "mov pc, lr" "\n" - - // the return instruction - "ldr pc, [sp], #4" "\n" ); asm volatile ( @@ -593,16 +586,13 @@ asm volatile ( HIDE_SYMBOL(ctiVMThrowTrampoline) "\n" SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" "mov r0, sp" "\n" - "mov lr, r6" "\n" - "add r8, pc, #4" "\n" - "str r8, [sp, #-4]!" "\n" - "b " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n" + "bl " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n" // Both has the same return sequence ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n" HIDE_SYMBOL(ctiOpThrowNotCaught) "\n" SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" - "add sp, sp, #32" "\n" + "add sp, sp, #36" "\n" "ldmia sp!, {r4-r8, lr}" "\n" "add sp, sp, #12" "\n" "mov pc, lr" "\n" @@ -946,6 +936,22 @@ static NEVER_INLINE void throwStackOverflowError(CallFrame* callFrame, JSGlobalD ); \ rtype JITStubThunked_##op(STUB_ARGS_DECLARATION) \ +#elif PLATFORM(ARM_TRADITIONAL) && COMPILER(GCC) + +#define DEFINE_STUB_FUNCTION(rtype, op) \ + extern "C" { \ + rtype JITStubThunked_##op(STUB_ARGS_DECLARATION); \ + }; \ + asm volatile ( \ + ".globl " SYMBOL_STRING(cti_##op) "\n" \ + SYMBOL_STRING(cti_##op) ":" "\n" \ + "str lr, [sp, #32]" "\n" \ + "bl " SYMBOL_STRING(JITStubThunked_##op) "\n" \ + "ldr lr, [sp, #32]" "\n" \ + "mov pc, lr" "\n" \ + ); \ + rtype JITStubThunked_##op(STUB_ARGS_DECLARATION) + #else #define DEFINE_STUB_FUNCTION(rtype, op) rtype JIT_STUB cti_##op(STUB_ARGS_DECLARATION) #endif diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.h b/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.h index ccbcd2a..69776cb 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.h +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.h @@ -163,6 +163,8 @@ namespace JSC { JITStubArg padding; // Unused JITStubArg args[7]; + ReturnAddressPtr thunkReturnAddress; + void* preservedR4; void* preservedR5; void* preservedR6; @@ -173,11 +175,13 @@ namespace JSC { RegisterFile* registerFile; CallFrame* callFrame; JSValue* exception; + + // These arguments passed on the stack. Profiler** enabledProfilerReference; JSGlobalData* globalData; // When JIT code makes a call, it pushes its return address just below the rest of the stack. - ReturnAddressPtr* returnAddressSlot() { return reinterpret_cast<ReturnAddressPtr*>(this) - 1; } + ReturnAddressPtr* returnAddressSlot() { return &thunkReturnAddress; } }; #else #error "JITStackFrame not defined for this platform." |