diff options
Diffstat (limited to 'Source/JavaScriptCore/jit')
-rw-r--r-- | Source/JavaScriptCore/jit/HostCallReturnValue.h | 4 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JIT.cpp | 14 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JIT.h | 5 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JITCode.h | 13 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JITOpcodes.cpp | 11 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JITOpcodes32_64.cpp | 14 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JITPropertyAccess.cpp | 80 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp | 101 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JITStubs.cpp | 62 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JITStubs.h | 257 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/SpecializedThunkJIT.h | 4 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/ThunkGenerators.cpp | 66 |
12 files changed, 387 insertions, 244 deletions
diff --git a/Source/JavaScriptCore/jit/HostCallReturnValue.h b/Source/JavaScriptCore/jit/HostCallReturnValue.h index fc9127faf..b134c73da 100644 --- a/Source/JavaScriptCore/jit/HostCallReturnValue.h +++ b/Source/JavaScriptCore/jit/HostCallReturnValue.h @@ -43,10 +43,10 @@ namespace JSC { -extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValue() REFERENCED_FROM_ASM; +extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValue() REFERENCED_FROM_ASM WTF_INTERNAL; // This is a public declaration only to convince CLANG not to elide it. -extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValueWithExecState(ExecState*) REFERENCED_FROM_ASM; +extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValueWithExecState(ExecState*) REFERENCED_FROM_ASM WTF_INTERNAL; inline void initializeHostCallReturnValue() { diff --git a/Source/JavaScriptCore/jit/JIT.cpp b/Source/JavaScriptCore/jit/JIT.cpp index ff5615f44..2aca35146 100644 --- a/Source/JavaScriptCore/jit/JIT.cpp +++ b/Source/JavaScriptCore/jit/JIT.cpp @@ -259,6 +259,7 @@ void JIT::privateCompileMainPass() DEFINE_OP(op_get_by_val) DEFINE_OP(op_get_argument_by_val) DEFINE_OP(op_get_by_pname) + DEFINE_OP(op_get_global_var_watchable) DEFINE_OP(op_get_global_var) DEFINE_OP(op_get_pnames) DEFINE_OP(op_get_scoped_var) @@ -324,6 +325,7 @@ void JIT::privateCompileMainPass() DEFINE_OP(op_put_by_val) DEFINE_OP(op_put_getter_setter) DEFINE_OP(op_put_global_var) + DEFINE_OP(op_put_global_var_check) DEFINE_OP(op_put_scoped_var) DEFINE_OP(op_resolve) DEFINE_OP(op_resolve_base) @@ -481,6 +483,7 @@ void JIT::privateCompileSlowCases() case op_put_by_id_transition_normal: DEFINE_SLOWCASE_OP(op_put_by_id) DEFINE_SLOWCASE_OP(op_put_by_val) + DEFINE_SLOWCASE_OP(op_put_global_var_check); DEFINE_SLOWCASE_OP(op_resolve_global) DEFINE_SLOWCASE_OP(op_resolve_global_dynamic) DEFINE_SLOWCASE_OP(op_rshift) @@ -715,11 +718,9 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck, JITCompilationEffo patchBuffer.link(iter->from, FunctionPtr(iter->to)); } - if (m_codeBlock->needsCallReturnIndices()) { - m_codeBlock->callReturnIndexVector().reserveCapacity(m_calls.size()); - for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) - m_codeBlock->callReturnIndexVector().append(CallReturnOffsetToBytecodeOffset(patchBuffer.returnAddressOffset(iter->from), iter->bytecodeOffset)); - } + m_codeBlock->callReturnIndexVector().reserveCapacity(m_calls.size()); + for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) + m_codeBlock->callReturnIndexVector().append(CallReturnOffsetToBytecodeOffset(patchBuffer.returnAddressOffset(iter->from), iter->bytecodeOffset)); m_codeBlock->setNumberOfStructureStubInfos(m_propertyAccessCompilationInfo.size()); for (unsigned i = 0; i < m_propertyAccessCompilationInfo.size(); ++i) @@ -760,7 +761,8 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck, JITCompilationEffo if (m_codeBlock->codeType() == FunctionCode && functionEntryArityCheck) *functionEntryArityCheck = patchBuffer.locationOf(arityCheck); - CodeRef result = patchBuffer.finalizeCode(); + CodeRef result = FINALIZE_CODE( + patchBuffer, ("Baseline JIT code for CodeBlock %p", m_codeBlock)); m_globalData->machineCodeBytesPerBytecodeWordForBaselineJIT.add( static_cast<double>(result.size()) / diff --git a/Source/JavaScriptCore/jit/JIT.h b/Source/JavaScriptCore/jit/JIT.h index d1143105a..6491edbed 100644 --- a/Source/JavaScriptCore/jit/JIT.h +++ b/Source/JavaScriptCore/jit/JIT.h @@ -463,7 +463,7 @@ namespace JSC { bool isMapped(int virtualRegisterIndex); bool getMappedPayload(int virtualRegisterIndex, RegisterID& payload); bool getMappedTag(int virtualRegisterIndex, RegisterID& tag); - + void emitJumpSlowCaseIfNotJSCell(int virtualRegisterIndex); void emitJumpSlowCaseIfNotJSCell(int virtualRegisterIndex, RegisterID tag); @@ -599,6 +599,7 @@ namespace JSC { 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_global_var_watchable(Instruction* instruction) { emit_op_get_global_var(instruction); } void emit_op_get_scoped_var(Instruction*); void emit_op_init_lazy_reg(Instruction*); void emit_op_check_has_instance(Instruction*); @@ -662,6 +663,7 @@ namespace JSC { void emit_op_put_by_val(Instruction*); void emit_op_put_getter_setter(Instruction*); void emit_op_put_global_var(Instruction*); + void emit_op_put_global_var_check(Instruction*); void emit_op_put_scoped_var(Instruction*); void emit_op_resolve(Instruction*); void emit_op_resolve_base(Instruction*); @@ -739,6 +741,7 @@ namespace JSC { void emitSlow_op_pre_inc(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_put_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&); void emitSlow_op_put_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&); + void emitSlow_op_put_global_var_check(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&); diff --git a/Source/JavaScriptCore/jit/JITCode.h b/Source/JavaScriptCore/jit/JITCode.h index c85e02e80..478fcc7bf 100644 --- a/Source/JavaScriptCore/jit/JITCode.h +++ b/Source/JavaScriptCore/jit/JITCode.h @@ -29,6 +29,7 @@ #if ENABLE(JIT) #include "CallFrame.h" #include "JSValue.h" +#include "Disassembler.h" #include "MacroAssemblerCodeRef.h" #include "Profiler.h" #endif @@ -105,6 +106,11 @@ namespace JSC { return reinterpret_cast<char*>(m_ref.code().executableAddress()) + offset; } + void* executableAddress() const + { + return executableAddressAtOffset(0); + } + void* dataAddressAtOffset(size_t offset) const { ASSERT(offset <= size()); // use <= instead of < because it is valid to ask for an address at the exclusive end of the code. @@ -124,7 +130,7 @@ namespace JSC { // Execute the code! inline JSValue execute(RegisterFile* registerFile, CallFrame* callFrame, JSGlobalData* globalData) { - JSValue result = JSValue::decode(ctiTrampoline(m_ref.code().executableAddress(), registerFile, callFrame, 0, Profiler::enabledProfilerReference(), globalData)); + JSValue result = JSValue::decode(ctiTrampoline(m_ref.code().executableAddress(), registerFile, callFrame, 0, 0, globalData)); return globalData->exception ? jsNull() : result; } @@ -138,6 +144,11 @@ namespace JSC { ASSERT(m_ref.code().executableAddress()); return m_ref.size(); } + + bool tryToDisassemble(const char* prefix) const + { + return m_ref.tryToDisassemble(prefix); + } ExecutableMemoryHandle* getExecutableMemory() { diff --git a/Source/JavaScriptCore/jit/JITOpcodes.cpp b/Source/JavaScriptCore/jit/JITOpcodes.cpp index aa2938cc2..ad7a56e12 100644 --- a/Source/JavaScriptCore/jit/JITOpcodes.cpp +++ b/Source/JavaScriptCore/jit/JITOpcodes.cpp @@ -211,7 +211,7 @@ PassRefPtr<ExecutableMemoryHandle> JIT::privateCompileCTIMachineTrampolines(JSGl patchBuffer.link(callCallNotJSFunction, FunctionPtr(cti_op_call_NotJSFunction)); patchBuffer.link(callConstructNotJSFunction, FunctionPtr(cti_op_construct_NotJSConstruct)); - CodeRef finalCode = patchBuffer.finalizeCode(); + CodeRef finalCode = FINALIZE_CODE(patchBuffer, ("JIT CTI machine trampolines")); RefPtr<ExecutableMemoryHandle> executableMemory = finalCode.executableMemory(); trampolines->ctiVirtualCallLink = patchBuffer.trampolineAt(virtualCallLinkBegin); @@ -1290,25 +1290,16 @@ void JIT::emitSlow_op_create_this(Instruction* currentInstruction, Vector<SlowCa void JIT::emit_op_profile_will_call(Instruction* currentInstruction) { - peek(regT1, OBJECT_OFFSETOF(JITStackFrame, enabledProfilerReference) / sizeof(void*)); - Jump noProfiler = branchTestPtr(Zero, Address(regT1)); - JITStubCall stubCall(this, cti_op_profile_will_call); stubCall.addArgument(currentInstruction[1].u.operand, regT1); stubCall.call(); - noProfiler.link(this); - } void JIT::emit_op_profile_did_call(Instruction* currentInstruction) { - peek(regT1, OBJECT_OFFSETOF(JITStackFrame, enabledProfilerReference) / sizeof(void*)); - Jump noProfiler = branchTestPtr(Zero, Address(regT1)); - JITStubCall stubCall(this, cti_op_profile_did_call); stubCall.addArgument(currentInstruction[1].u.operand, regT1); stubCall.call(); - noProfiler.link(this); } diff --git a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp index 12e47b2ee..57ef7ef2f 100644 --- a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp +++ b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp @@ -207,7 +207,7 @@ PassRefPtr<ExecutableMemoryHandle> JIT::privateCompileCTIMachineTrampolines(JSGl patchBuffer.link(callCallNotJSFunction, FunctionPtr(cti_op_call_NotJSFunction)); patchBuffer.link(callConstructNotJSFunction, FunctionPtr(cti_op_construct_NotJSConstruct)); - CodeRef finalCode = patchBuffer.finalizeCode(); + CodeRef finalCode = FINALIZE_CODE(patchBuffer, ("JIT CTI machine trampolines")); RefPtr<ExecutableMemoryHandle> executableMemory = finalCode.executableMemory(); trampolines->ctiVirtualCallLink = patchBuffer.trampolineAt(virtualCallLinkBegin); @@ -497,7 +497,7 @@ JIT::CodeRef JIT::privateCompileCTINativeCall(JSGlobalData* globalData, NativeFu LinkBuffer patchBuffer(*m_globalData, this, GLOBAL_THUNK_ID); patchBuffer.link(nativeCall, FunctionPtr(func)); - return patchBuffer.finalizeCode(); + return FINALIZE_CODE(patchBuffer, ("JIT CTI native call")); } void JIT::emit_op_mov(Instruction* currentInstruction) @@ -1590,24 +1590,16 @@ void JIT::emitSlow_op_convert_this(Instruction* currentInstruction, Vector<SlowC void JIT::emit_op_profile_will_call(Instruction* currentInstruction) { - peek(regT2, OBJECT_OFFSETOF(JITStackFrame, enabledProfilerReference) / sizeof(void*)); - Jump noProfiler = branchTestPtr(Zero, Address(regT2)); - JITStubCall stubCall(this, cti_op_profile_will_call); stubCall.addArgument(currentInstruction[1].u.operand); stubCall.call(); - noProfiler.link(this); } void JIT::emit_op_profile_did_call(Instruction* currentInstruction) { - peek(regT2, OBJECT_OFFSETOF(JITStackFrame, enabledProfilerReference) / sizeof(void*)); - Jump noProfiler = branchTestPtr(Zero, Address(regT2)); - JITStubCall stubCall(this, cti_op_profile_did_call); stubCall.addArgument(currentInstruction[1].u.operand); stubCall.call(); - noProfiler.link(this); } void JIT::emit_op_get_arguments_length(Instruction* currentInstruction) @@ -1672,7 +1664,7 @@ void JIT::emitSlow_op_get_argument_by_val(Instruction* currentInstruction, Vecto JITStubCall stubCall(this, cti_op_get_by_val); stubCall.addArgument(arguments); stubCall.addArgument(property); - stubCall.call(dst); + stubCall.callWithValueProfiling(dst); } } // namespace JSC diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp index 5d39735af..7478f9184 100644 --- a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp +++ b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp @@ -30,12 +30,13 @@ #include "CodeBlock.h" #include "GetterSetter.h" +#include "Interpreter.h" #include "JITInlineMethods.h" #include "JITStubCall.h" #include "JSArray.h" #include "JSFunction.h" #include "JSPropertyNameIterator.h" -#include "Interpreter.h" +#include "JSVariableObject.h" #include "LinkBuffer.h" #include "RepatchBuffer.h" #include "ResultType.h" @@ -87,7 +88,7 @@ JIT::CodeRef JIT::stringGetByValStubGenerator(JSGlobalData* globalData) jit.ret(); LinkBuffer patchBuffer(*globalData, &jit, GLOBAL_THUNK_ID); - return patchBuffer.finalizeCode(); + return FINALIZE_CODE(patchBuffer, ("String get_by_val stub")); } void JIT::emit_op_get_by_val(Instruction* currentInstruction) @@ -563,7 +564,10 @@ void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure patchBuffer.link(m_calls[0].from, FunctionPtr(cti_op_put_by_id_transition_realloc)); } - stubInfo->stubRoutine = patchBuffer.finalizeCode(); + stubInfo->stubRoutine = FINALIZE_CODE( + patchBuffer, + ("Baseline put_by_id transition for CodeBlock %p, return point %p", + m_codeBlock, returnAddress.value())); RepatchBuffer repatchBuffer(m_codeBlock); repatchBuffer.relinkCallerToTrampoline(returnAddress, CodeLocationLabel(stubInfo->stubRoutine.code())); } @@ -624,7 +628,11 @@ void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress) patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult)); // Track the stub we have created so that it will be deleted later. - stubInfo->stubRoutine = patchBuffer.finalizeCode(); + stubInfo->stubRoutine = FINALIZE_CODE( + patchBuffer, + ("Basline JIT get_by_id array length stub for CodeBlock %p, return point %p", + m_codeBlock, stubInfo->hotPathBegin.labelAtOffset( + stubInfo->patch.baseline.u.get.putResult).executableAddress())); // Finally patch the jump to slow case back in the hot path to jump here instead. CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(stubInfo->patch.baseline.u.get.structureCheck); @@ -687,7 +695,11 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str } } // Track the stub we have created so that it will be deleted later. - stubInfo->stubRoutine = patchBuffer.finalizeCode(); + stubInfo->stubRoutine = FINALIZE_CODE( + patchBuffer, + ("Baseline JIT get_by_id proto stub for CodeBlock %p, return point %p", + m_codeBlock, stubInfo->hotPathBegin.labelAtOffset( + stubInfo->patch.baseline.u.get.putResult).executableAddress())); // Finally patch the jump to slow case back in the hot path to jump here instead. CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(stubInfo->patch.baseline.u.get.structureCheck); @@ -744,7 +756,11 @@ void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, Polymorphic // On success return back to the hot patch code, at a point it will perform the store to dest for us. patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult)); - MacroAssemblerCodeRef stubCode = patchBuffer.finalizeCode(); + MacroAssemblerCodeRef stubCode = FINALIZE_CODE( + patchBuffer, + ("Baseline JIT get_by_id list stub for CodeBlock %p, return point %p", + m_codeBlock, stubInfo->hotPathBegin.labelAtOffset( + stubInfo->patch.baseline.u.get.putResult).executableAddress())); polymorphicStructures->list[currentIndex].set(*m_globalData, m_codeBlock->ownerExecutable(), stubCode, structure, isDirect); @@ -810,7 +826,11 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi // On success return back to the hot patch code, at a point it will perform the store to dest for us. patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult)); - MacroAssemblerCodeRef stubCode = patchBuffer.finalizeCode(); + MacroAssemblerCodeRef stubCode = FINALIZE_CODE( + patchBuffer, + ("Baseline JIT get_by_id proto list stub for CodeBlock %p, return point %p", + m_codeBlock, stubInfo->hotPathBegin.labelAtOffset( + stubInfo->patch.baseline.u.get.putResult).executableAddress())); prototypeStructures->list[currentIndex].set(*m_globalData, m_codeBlock->ownerExecutable(), stubCode, structure, prototypeStructure, isDirect); // Finally patch the jump to slow case back in the hot path to jump here instead. @@ -879,7 +899,11 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi // On success return back to the hot patch code, at a point it will perform the store to dest for us. patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult)); - CodeRef stubRoutine = patchBuffer.finalizeCode(); + CodeRef stubRoutine = FINALIZE_CODE( + patchBuffer, + ("Baseline JIT get_by_id chain list stub for CodeBlock %p, return point %p", + m_codeBlock, stubInfo->hotPathBegin.labelAtOffset( + stubInfo->patch.baseline.u.get.putResult).executableAddress())); // Track the stub we have created so that it will be deleted later. prototypeStructures->list[currentIndex].set(callFrame->globalData(), m_codeBlock->ownerExecutable(), stubRoutine, structure, chain, isDirect); @@ -946,7 +970,11 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult)); // Track the stub we have created so that it will be deleted later. - CodeRef stubRoutine = patchBuffer.finalizeCode(); + CodeRef stubRoutine = FINALIZE_CODE( + patchBuffer, + ("Baseline JIT get_by_id chain stub for CodeBlock %p, return point %p", + m_codeBlock, stubInfo->hotPathBegin.labelAtOffset( + stubInfo->patch.baseline.u.get.putResult).executableAddress())); stubInfo->stubRoutine = stubRoutine; // Finally patch the jump to slow case back in the hot path to jump here instead. @@ -1010,9 +1038,7 @@ void JIT::emit_op_put_scoped_var(Instruction* currentInstruction) void JIT::emit_op_get_global_var(Instruction* currentInstruction) { - JSVariableObject* globalObject = m_codeBlock->globalObject(); - loadPtr(&globalObject->m_registers, regT0); - loadPtr(Address(regT0, currentInstruction[2].u.operand * sizeof(Register)), regT0); + loadPtr(currentInstruction[2].u.registerPointer, regT0); emitValueProfilingSite(); emitPutVirtualRegister(currentInstruction[1].u.operand); } @@ -1022,11 +1048,33 @@ void JIT::emit_op_put_global_var(Instruction* currentInstruction) JSGlobalObject* globalObject = m_codeBlock->globalObject(); emitGetVirtualRegister(currentInstruction[2].u.operand, regT0); + + storePtr(regT0, currentInstruction[1].u.registerPointer); + if (Heap::isWriteBarrierEnabled()) + emitWriteBarrier(globalObject, regT0, regT2, ShouldFilterImmediates, WriteBarrierForVariableAccess); +} - move(TrustedImmPtr(globalObject), regT1); - loadPtr(Address(regT1, JSVariableObject::offsetOfRegisters()), regT1); - storePtr(regT0, Address(regT1, currentInstruction[1].u.operand * sizeof(Register))); - emitWriteBarrier(globalObject, regT0, regT2, ShouldFilterImmediates, WriteBarrierForVariableAccess); +void JIT::emit_op_put_global_var_check(Instruction* currentInstruction) +{ + emitGetVirtualRegister(currentInstruction[2].u.operand, regT0); + + addSlowCase(branchTest8(NonZero, AbsoluteAddress(currentInstruction[3].u.predicatePointer))); + + JSGlobalObject* globalObject = m_codeBlock->globalObject(); + + storePtr(regT0, currentInstruction[1].u.registerPointer); + if (Heap::isWriteBarrierEnabled()) + emitWriteBarrier(globalObject, regT0, regT2, ShouldFilterImmediates, WriteBarrierForVariableAccess); +} + +void JIT::emitSlow_op_put_global_var_check(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + linkSlowCase(iter); + + JITStubCall stubCall(this, cti_op_put_global_var_check); + stubCall.addArgument(regT0); + stubCall.addArgument(TrustedImm32(currentInstruction[4].u.operand)); + stubCall.call(); } void JIT::resetPatchGetById(RepatchBuffer& repatchBuffer, StructureStubInfo* stubInfo) diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp index bd57484c4..a44c576c5 100644 --- a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp +++ b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp @@ -30,12 +30,13 @@ #include "JIT.h" #include "CodeBlock.h" +#include "Interpreter.h" #include "JITInlineMethods.h" #include "JITStubCall.h" #include "JSArray.h" #include "JSFunction.h" #include "JSPropertyNameIterator.h" -#include "Interpreter.h" +#include "JSVariableObject.h" #include "LinkBuffer.h" #include "RepatchBuffer.h" #include "ResultType.h" @@ -193,7 +194,7 @@ JIT::CodeRef JIT::stringGetByValStubGenerator(JSGlobalData* globalData) jit.ret(); LinkBuffer patchBuffer(*globalData, &jit, GLOBAL_THUNK_ID); - return patchBuffer.finalizeCode(); + return FINALIZE_CODE(patchBuffer, ("String get_by_val stub")); } void JIT::emit_op_get_by_val(Instruction* currentInstruction) @@ -544,7 +545,10 @@ void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure patchBuffer.link(m_calls[0].from, FunctionPtr(cti_op_put_by_id_transition_realloc)); } - stubInfo->stubRoutine = patchBuffer.finalizeCode(); + stubInfo->stubRoutine = FINALIZE_CODE( + patchBuffer, + ("Baseline put_by_id transition stub for CodeBlock %p, return point %p", + m_codeBlock, returnAddress.value())); RepatchBuffer repatchBuffer(m_codeBlock); repatchBuffer.relinkCallerToTrampoline(returnAddress, CodeLocationLabel(stubInfo->stubRoutine.code())); } @@ -610,7 +614,11 @@ void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress) patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult)); // Track the stub we have created so that it will be deleted later. - stubInfo->stubRoutine = patchBuffer.finalizeCode(); + stubInfo->stubRoutine = FINALIZE_CODE( + patchBuffer, + ("Baseline get_by_id array length stub for CodeBlock %p, return point %p", + m_codeBlock, stubInfo->hotPathBegin.labelAtOffset( + stubInfo->patch.baseline.u.get.putResult).executableAddress())); // Finally patch the jump to slow case back in the hot path to jump here instead. CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(stubInfo->patch.baseline.u.get.structureCheck); @@ -676,7 +684,11 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str } // Track the stub we have created so that it will be deleted later. - stubInfo->stubRoutine = patchBuffer.finalizeCode(); + stubInfo->stubRoutine = FINALIZE_CODE( + patchBuffer, + ("Baseline get_by_id proto stub for CodeBlock %p, return point %p", + m_codeBlock, stubInfo->hotPathBegin.labelAtOffset( + stubInfo->patch.baseline.u.get.putResult).executableAddress())); // Finally patch the jump to slow case back in the hot path to jump here instead. CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(stubInfo->patch.baseline.u.get.structureCheck); @@ -734,7 +746,11 @@ void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, Polymorphic // On success return back to the hot patch code, at a point it will perform the store to dest for us. patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult)); - CodeRef stubRoutine = patchBuffer.finalizeCode(); + MacroAssemblerCodeRef stubRoutine = FINALIZE_CODE( + patchBuffer, + ("Baseline get_by_id self list stub for CodeBlock %p, return point %p", + m_codeBlock, stubInfo->hotPathBegin.labelAtOffset( + stubInfo->patch.baseline.u.get.putResult).executableAddress())); polymorphicStructures->list[currentIndex].set(*m_globalData, m_codeBlock->ownerExecutable(), stubRoutine, structure, isDirect); @@ -799,7 +815,11 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi // On success return back to the hot patch code, at a point it will perform the store to dest for us. patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult)); - CodeRef stubRoutine = patchBuffer.finalizeCode(); + MacroAssemblerCodeRef stubRoutine = FINALIZE_CODE( + patchBuffer, + ("Baseline get_by_id proto list stub for CodeBlock %p, return point %p", + m_codeBlock, stubInfo->hotPathBegin.labelAtOffset( + stubInfo->patch.baseline.u.get.putResult).executableAddress())); prototypeStructures->list[currentIndex].set(callFrame->globalData(), m_codeBlock->ownerExecutable(), stubRoutine, structure, prototypeStructure, isDirect); @@ -869,7 +889,11 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi // On success return back to the hot patch code, at a point it will perform the store to dest for us. patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult)); - CodeRef stubRoutine = patchBuffer.finalizeCode(); + MacroAssemblerCodeRef stubRoutine = FINALIZE_CODE( + patchBuffer, + ("Baseline get_by_id chain list stub for CodeBlock %p, return point %p", + m_codeBlock, stubInfo->hotPathBegin.labelAtOffset( + stubInfo->patch.baseline.u.get.putResult).executableAddress())); // Track the stub we have created so that it will be deleted later. prototypeStructures->list[currentIndex].set(callFrame->globalData(), m_codeBlock->ownerExecutable(), stubRoutine, structure, chain, isDirect); @@ -935,7 +959,11 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult)); // Track the stub we have created so that it will be deleted later. - CodeRef stubRoutine = patchBuffer.finalizeCode(); + MacroAssemblerCodeRef stubRoutine = FINALIZE_CODE( + patchBuffer, + ("Baseline get_by_id chain stub for CodeBlock %p, return point %p", + m_codeBlock, stubInfo->hotPathBegin.labelAtOffset( + stubInfo->patch.baseline.u.get.putResult).executableAddress())); stubInfo->stubRoutine = stubRoutine; // Finally patch the jump to slow case back in the hot path to jump here instead. @@ -1060,13 +1088,10 @@ void JIT::emit_op_put_scoped_var(Instruction* currentInstruction) void JIT::emit_op_get_global_var(Instruction* currentInstruction) { int dst = currentInstruction[1].u.operand; - JSGlobalObject* globalObject = m_codeBlock->globalObject(); - ASSERT(globalObject->isGlobalObject()); - int index = currentInstruction[2].u.operand; + WriteBarrier<Unknown>* registerPointer = currentInstruction[2].u.registerPointer; - loadPtr(&globalObject->m_registers, regT2); - - emitLoad(index, regT1, regT0, regT2); + load32(registerPointer->tagPointer(), regT1); + load32(registerPointer->payloadPointer(), regT0); emitValueProfilingSite(); emitStore(dst, regT1, regT0); map(m_bytecodeOffset + OPCODE_LENGTH(op_get_global_var), dst, regT1, regT0); @@ -1074,21 +1099,55 @@ void JIT::emit_op_get_global_var(Instruction* currentInstruction) void JIT::emit_op_put_global_var(Instruction* currentInstruction) { - int index = currentInstruction[1].u.operand; + WriteBarrier<Unknown>* registerPointer = currentInstruction[1].u.registerPointer; int value = currentInstruction[2].u.operand; JSGlobalObject* globalObject = m_codeBlock->globalObject(); emitLoad(value, regT1, regT0); - move(TrustedImmPtr(globalObject), regT2); - - emitWriteBarrier(globalObject, regT1, regT3, ShouldFilterImmediates, WriteBarrierForVariableAccess); + + if (Heap::isWriteBarrierEnabled()) { + move(TrustedImmPtr(globalObject), regT2); + + emitWriteBarrier(globalObject, regT1, regT3, ShouldFilterImmediates, WriteBarrierForVariableAccess); + } - loadPtr(Address(regT2, JSVariableObject::offsetOfRegisters()), regT2); - emitStore(index, regT1, regT0, regT2); + store32(regT1, registerPointer->tagPointer()); + store32(regT0, registerPointer->payloadPointer()); map(m_bytecodeOffset + OPCODE_LENGTH(op_put_global_var), value, regT1, regT0); } +void JIT::emit_op_put_global_var_check(Instruction* currentInstruction) +{ + WriteBarrier<Unknown>* registerPointer = currentInstruction[1].u.registerPointer; + int value = currentInstruction[2].u.operand; + + JSGlobalObject* globalObject = m_codeBlock->globalObject(); + + emitLoad(value, regT1, regT0); + + addSlowCase(branchTest8(NonZero, AbsoluteAddress(currentInstruction[3].u.predicatePointer))); + + if (Heap::isWriteBarrierEnabled()) { + move(TrustedImmPtr(globalObject), regT2); + emitWriteBarrier(globalObject, regT1, regT3, ShouldFilterImmediates, WriteBarrierForVariableAccess); + } + + store32(regT1, registerPointer->tagPointer()); + store32(regT0, registerPointer->payloadPointer()); + unmap(); +} + +void JIT::emitSlow_op_put_global_var_check(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) +{ + linkSlowCase(iter); + + JITStubCall stubCall(this, cti_op_put_global_var_check); + stubCall.addArgument(regT1, regT0); + stubCall.addArgument(TrustedImm32(currentInstruction[4].u.operand)); + stubCall.call(); +} + void JIT::resetPatchGetById(RepatchBuffer& repatchBuffer, StructureStubInfo* stubInfo) { repatchBuffer.relink(stubInfo->callReturnLocation, cti_op_get_by_id); diff --git a/Source/JavaScriptCore/jit/JITStubs.cpp b/Source/JavaScriptCore/jit/JITStubs.cpp index e75f2825c..12f3ec344 100644 --- a/Source/JavaScriptCore/jit/JITStubs.cpp +++ b/Source/JavaScriptCore/jit/JITStubs.cpp @@ -112,7 +112,7 @@ asm ( HIDE_SYMBOL(ctiVMThrowTrampoline) "\n" SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" "movl %esp, %ecx" "\n" - "call " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n" + "call " LOCAL_REFERENCE(cti_vm_throw) "\n" "int3" "\n" ); @@ -172,7 +172,7 @@ asm ( HIDE_SYMBOL(ctiVMThrowTrampoline) "\n" SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" "movq %rsp, %rdi" "\n" - "call " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n" + "call " LOCAL_REFERENCE(cti_vm_throw) "\n" "int3" "\n" ); @@ -205,7 +205,7 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" #define REGISTER_FILE_OFFSET 0x60 #define CALLFRAME_OFFSET 0x64 #define EXCEPTION_OFFSET 0x64 -#define ENABLE_PROFILER_REFERENCE_OFFSET 0x68 +#define FIRST_STACK_ARGUMENT 0x68 #elif (COMPILER(GCC) || COMPILER(MSVC) || COMPILER(RVCT)) && CPU(ARM_TRADITIONAL) @@ -225,7 +225,7 @@ COMPILE_ASSERT(offsetof(struct JITStackFrame, code) == 0x50, JITStackFrame_code_ extern "C" { - __declspec(naked) EncodedJSValue ctiTrampoline(void* code, RegisterFile*, CallFrame*, void* /*unused1*/, Profiler**, JSGlobalData*) + __declspec(naked) EncodedJSValue ctiTrampoline(void* code, RegisterFile*, CallFrame*, void* /*unused1*/, void* /*unused2*/, JSGlobalData*) { __asm { push ebp; @@ -284,12 +284,11 @@ extern "C" { #define REGISTER_FILE_OFFSET 84 #define CALLFRAME_OFFSET 88 #define EXCEPTION_OFFSET 92 -#define ENABLE_PROFILER_REFERENCE_OFFSET 96 #define GLOBAL_DATA_OFFSET 100 #define STACK_LENGTH 104 #elif CPU(SH4) #define SYMBOL_STRING(name) #name -/* code (r4), RegisterFile* (r5), CallFrame* (r6), JSValue* exception (r7), Profiler**(sp), JSGlobalData (sp)*/ +/* code (r4), RegisterFile* (r5), CallFrame* (r6), void* unused1 (r7), void* unused2(sp), JSGlobalData (sp)*/ asm volatile ( ".text\n" @@ -417,7 +416,7 @@ asm ( HIDE_SYMBOL(ctiVMThrowTrampoline) "\n" SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" "movq %rsp, %rdi" "\n" - "call " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n" + "call " LOCAL_REFERENCE(cti_vm_throw) "\n" "int3" "\n" ); @@ -465,9 +464,7 @@ SYMBOL_STRING(ctiTrampoline) ":" "\n" "sw $5," STRINGIZE_VALUE_OF(REGISTER_FILE_OFFSET) "($29) # store registerFile to current stack" "\n" "sw $6," STRINGIZE_VALUE_OF(CALLFRAME_OFFSET) "($29) # store callFrame to curent stack" "\n" "sw $7," STRINGIZE_VALUE_OF(EXCEPTION_OFFSET) "($29) # store exception to current stack" "\n" - "lw $8," STRINGIZE_VALUE_OF(STACK_LENGTH + 16) "($29) # load enableProfilerReference from previous stack" "\n" "lw $9," STRINGIZE_VALUE_OF(STACK_LENGTH + 20) "($29) # load globalData from previous stack" "\n" - "sw $8," STRINGIZE_VALUE_OF(ENABLE_PROFILER_REFERENCE_OFFSET) "($29) # store enableProfilerReference to current stack" "\n" "jalr $25" "\n" "sw $9," STRINGIZE_VALUE_OF(GLOBAL_DATA_OFFSET) "($29) # store globalData to current stack" "\n" "lw $16," STRINGIZE_VALUE_OF(PRESERVED_S0_OFFSET) "($29)" "\n" @@ -543,7 +540,7 @@ HIDE_SYMBOL(ctiTrampoline) "\n" ".thumb" "\n" ".thumb_func " THUMB_FUNC_PARAM(ctiTrampoline) "\n" SYMBOL_STRING(ctiTrampoline) ":" "\n" - "sub sp, sp, #" STRINGIZE_VALUE_OF(ENABLE_PROFILER_REFERENCE_OFFSET) "\n" + "sub sp, sp, #" STRINGIZE_VALUE_OF(FIRST_STACK_ARGUMENT) "\n" "str lr, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_RETURN_ADDRESS_OFFSET) "]" "\n" "str r4, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R4_OFFSET) "]" "\n" "str r5, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R5_OFFSET) "]" "\n" @@ -568,7 +565,7 @@ SYMBOL_STRING(ctiTrampoline) ":" "\n" "ldr r5, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R5_OFFSET) "]" "\n" "ldr r4, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R4_OFFSET) "]" "\n" "ldr lr, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_RETURN_ADDRESS_OFFSET) "]" "\n" - "add sp, sp, #" STRINGIZE_VALUE_OF(ENABLE_PROFILER_REFERENCE_OFFSET) "\n" + "add sp, sp, #" STRINGIZE_VALUE_OF(FIRST_STACK_ARGUMENT) "\n" "bx lr" "\n" ".align 2" "\n" ".globl " SYMBOL_STRING(ctiTrampolineEnd) "\n" @@ -587,7 +584,7 @@ HIDE_SYMBOL(ctiVMThrowTrampoline) "\n" ".thumb_func " THUMB_FUNC_PARAM(ctiVMThrowTrampoline) "\n" SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" "mov r0, sp" "\n" - "bl " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n" + "bl " LOCAL_REFERENCE(cti_vm_throw) "\n" "ldr r11, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R11_OFFSET) "]" "\n" "ldr r10, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R10_OFFSET) "]" "\n" "ldr r9, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R9_OFFSET) "]" "\n" @@ -597,7 +594,7 @@ SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" "ldr r5, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R5_OFFSET) "]" "\n" "ldr r4, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R4_OFFSET) "]" "\n" "ldr lr, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_RETURN_ADDRESS_OFFSET) "]" "\n" - "add sp, sp, #" STRINGIZE_VALUE_OF(ENABLE_PROFILER_REFERENCE_OFFSET) "\n" + "add sp, sp, #" STRINGIZE_VALUE_OF(FIRST_STACK_ARGUMENT) "\n" "bx lr" "\n" ); @@ -618,7 +615,7 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" "ldr r5, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R5_OFFSET) "]" "\n" "ldr r4, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R4_OFFSET) "]" "\n" "ldr lr, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_RETURN_ADDRESS_OFFSET) "]" "\n" - "add sp, sp, #" STRINGIZE_VALUE_OF(ENABLE_PROFILER_REFERENCE_OFFSET) "\n" + "add sp, sp, #" STRINGIZE_VALUE_OF(FIRST_STACK_ARGUMENT) "\n" "bx lr" "\n" ); @@ -661,10 +658,10 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" #elif COMPILER(RVCT) && CPU(ARM_THUMB2) -__asm EncodedJSValue ctiTrampoline(void*, RegisterFile*, CallFrame*, JSValue*, Profiler**, JSGlobalData*) +__asm EncodedJSValue ctiTrampoline(void*, RegisterFile*, CallFrame*, void* /*unused1*/, void* /*unused2*/, JSGlobalData*) { PRESERVE8 - sub sp, sp, # ENABLE_PROFILER_REFERENCE_OFFSET + sub sp, sp, # FIRST_STACK_ARGUMENT str lr, [sp, # PRESERVED_RETURN_ADDRESS_OFFSET ] str r4, [sp, # PRESERVED_R4_OFFSET ] str r5, [sp, # PRESERVED_R5_OFFSET ] @@ -689,7 +686,7 @@ __asm EncodedJSValue ctiTrampoline(void*, RegisterFile*, CallFrame*, JSValue*, P ldr r5, [sp, # PRESERVED_R5_OFFSET ] ldr r4, [sp, # PRESERVED_R4_OFFSET ] ldr lr, [sp, # PRESERVED_RETURN_ADDRESS_OFFSET ] - add sp, sp, # ENABLE_PROFILER_REFERENCE_OFFSET + add sp, sp, # FIRST_STACK_ARGUMENT bx lr } @@ -708,7 +705,7 @@ __asm void ctiVMThrowTrampoline() ldr r5, [sp, # PRESERVED_R5_OFFSET ] ldr r4, [sp, # PRESERVED_R4_OFFSET ] ldr lr, [sp, # PRESERVED_RETURN_ADDRESS_OFFSET ] - add sp, sp, # ENABLE_PROFILER_REFERENCE_OFFSET + add sp, sp, # FIRST_STACK_ARGUMENT bx lr } @@ -725,13 +722,13 @@ __asm void ctiOpThrowNotCaught() ldr r5, [sp, # PRESERVED_R5_OFFSET ] ldr r4, [sp, # PRESERVED_R4_OFFSET ] ldr lr, [sp, # PRESERVED_RETURN_ADDRESS_OFFSET ] - add sp, sp, # ENABLE_PROFILER_REFERENCE_OFFSET + add sp, sp, # FIRST_STACK_ARGUMENT bx lr } #elif COMPILER(RVCT) && CPU(ARM_TRADITIONAL) -__asm EncodedJSValue ctiTrampoline(void*, RegisterFile*, CallFrame*, void* /*unused1*/, Profiler**, JSGlobalData*) +__asm EncodedJSValue ctiTrampoline(void*, RegisterFile*, CallFrame*, void* /*unused1*/, void* /*unused2*/, JSGlobalData*) { ARM stmdb sp!, {r1-r3} @@ -800,7 +797,7 @@ JITThunks::JITThunks(JSGlobalData* globalData) ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, registerFile) == REGISTER_FILE_OFFSET); ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, callFrame) == CALLFRAME_OFFSET); // The fifth argument is the first item already on the stack. - ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, enabledProfilerReference) == ENABLE_PROFILER_REFERENCE_OFFSET); + ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, unused1) == FIRST_STACK_ARGUMENT); ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, thunkReturnAddress) == THUNK_RETURN_ADDRESS_OFFSET); @@ -820,7 +817,6 @@ JITThunks::JITThunks(JSGlobalData* globalData) ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, registerFile) == REGISTER_FILE_OFFSET); ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, callFrame) == CALLFRAME_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); #endif @@ -870,6 +866,7 @@ NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* co normalizePrototypeChain(callFrame, baseCell); StructureChain* prototypeChain = structure->prototypeChain(callFrame); + ASSERT(structure->previousID()->transitionWatchpointSetHasBeenInvalidated()); stubInfo->initPutByIdTransition(callFrame->globalData(), codeBlock->ownerExecutable(), structure->previousID(), structure, prototypeChain, direct); JIT::compilePutByIdTransition(callFrame->scopeChain()->globalData, codeBlock, stubInfo, structure->previousID(), structure, slot.cachedOffset(), prototypeChain, returnAddress, direct); return; @@ -949,7 +946,7 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co offset = slotBaseObject->structure()->get(callFrame->globalData(), propertyName); } - stubInfo->initGetByIdProto(callFrame->globalData(), codeBlock->ownerExecutable(), structure, slotBaseObject->structure()); + stubInfo->initGetByIdProto(callFrame->globalData(), codeBlock->ownerExecutable(), structure, slotBaseObject->structure(), slot.cachedPropertyType() == PropertySlot::Value); ASSERT(!structure->isDictionary()); ASSERT(!slotBaseObject->structure()->isDictionary()); @@ -965,7 +962,7 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co } StructureChain* prototypeChain = structure->prototypeChain(callFrame); - stubInfo->initGetByIdChain(callFrame->globalData(), codeBlock->ownerExecutable(), structure, prototypeChain); + stubInfo->initGetByIdChain(callFrame->globalData(), codeBlock->ownerExecutable(), structure, prototypeChain, count, slot.cachedPropertyType() == PropertySlot::Value); JIT::compileGetByIdChain(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, prototypeChain, count, propertyName, slot, offset, returnAddress); } @@ -2355,16 +2352,16 @@ DEFINE_STUB_FUNCTION(void, op_profile_will_call) { STUB_INIT_STACK_FRAME(stackFrame); - ASSERT(*stackFrame.enabledProfilerReference); - (*stackFrame.enabledProfilerReference)->willExecute(stackFrame.callFrame, stackFrame.args[0].jsValue()); + if (Profiler* profiler = stackFrame.globalData->enabledProfiler()) + profiler->willExecute(stackFrame.callFrame, stackFrame.args[0].jsValue()); } DEFINE_STUB_FUNCTION(void, op_profile_did_call) { STUB_INIT_STACK_FRAME(stackFrame); - ASSERT(*stackFrame.enabledProfilerReference); - (*stackFrame.enabledProfilerReference)->didExecute(stackFrame.callFrame, stackFrame.args[0].jsValue()); + if (Profiler* profiler = stackFrame.globalData->enabledProfiler()) + profiler->didExecute(stackFrame.callFrame, stackFrame.args[0].jsValue()); } DEFINE_STUB_FUNCTION(JSObject*, op_new_array) @@ -2381,6 +2378,15 @@ DEFINE_STUB_FUNCTION(JSObject*, op_new_array_buffer) return constructArray(stackFrame.callFrame, stackFrame.callFrame->codeBlock()->constantBuffer(stackFrame.args[0].int32()), stackFrame.args[1].int32()); } +DEFINE_STUB_FUNCTION(void, op_put_global_var_check) +{ + STUB_INIT_STACK_FRAME(stackFrame); + + CallFrame* callFrame = stackFrame.callFrame; + CodeBlock* codeBlock = callFrame->codeBlock(); + symbolTablePut(codeBlock->globalObject(), callFrame, codeBlock->identifier(stackFrame.args[1].int32()), stackFrame.args[0].jsValue(), true); +} + DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve) { STUB_INIT_STACK_FRAME(stackFrame); diff --git a/Source/JavaScriptCore/jit/JITStubs.h b/Source/JavaScriptCore/jit/JITStubs.h index 664338fd3..251776075 100644 --- a/Source/JavaScriptCore/jit/JITStubs.h +++ b/Source/JavaScriptCore/jit/JITStubs.h @@ -104,7 +104,7 @@ namespace JSC { RegisterFile* registerFile; CallFrame* callFrame; void* unused1; - Profiler** enabledProfilerReference; + void* unused2; JSGlobalData* globalData; void* savedRBX; @@ -140,7 +140,7 @@ namespace JSC { RegisterFile* registerFile; CallFrame* callFrame; void* unused1; - Profiler** enabledProfilerReference; + void* unused2; JSGlobalData* globalData; // When JIT code makes a call, it pushes its return address just below the rest of the stack. @@ -171,7 +171,7 @@ namespace JSC { CallFrame* callFrame; // These arguments passed on the stack. - Profiler** enabledProfilerReference; + void* unused1; JSGlobalData* globalData; ReturnAddressPtr* returnAddressSlot() { return &thunkReturnAddress; } @@ -199,7 +199,7 @@ namespace JSC { void* unused1; // These arguments passed on the stack. - Profiler** enabledProfilerReference; + void* unused2; JSGlobalData* globalData; // When JIT code makes a call, it pushes its return address just below the rest of the stack. @@ -231,7 +231,7 @@ namespace JSC { void* unused1; // These arguments passed on the stack. - Profiler** enabledProfilerReference; + void* unused2; JSGlobalData* globalData; ReturnAddressPtr* returnAddressSlot() { return &thunkReturnAddress; } @@ -252,7 +252,7 @@ namespace JSC { RegisterFile* registerFile; CallFrame* callFrame; JSValue* exception; - Profiler** enabledProfilerReference; + void* unused1; JSGlobalData* globalData; ReturnAddressPtr* returnAddressSlot() { return &thunkReturnAddress; } @@ -282,7 +282,7 @@ namespace JSC { extern "C" void ctiVMThrowTrampoline(); extern "C" void ctiOpThrowNotCaught(); - extern "C" EncodedJSValue ctiTrampoline(void* code, RegisterFile*, CallFrame*, void* /*unused1*/, Profiler**, JSGlobalData*); + extern "C" EncodedJSValue ctiTrampoline(void* code, RegisterFile*, CallFrame*, void* /*unused1*/, void* /*unused2*/, JSGlobalData*); #if ENABLE(DFG_JIT) extern "C" void ctiTrampolineEnd(); @@ -341,129 +341,130 @@ namespace JSC { }; extern "C" { - EncodedJSValue JIT_STUB cti_op_add(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_bitand(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_bitor(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_bitxor(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_call_NotJSFunction(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_call_eval(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_construct_NotJSConstruct(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_create_this(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_convert_this(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_create_arguments(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_del_by_id(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_del_by_val(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_div(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_get_by_id(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_get_by_id_array_fail(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_get_by_id_custom_stub(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_get_by_id_generic(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_get_by_id_getter_stub(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_get_by_id_method_check(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_get_by_id_method_check_update(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_get_by_id_proto_fail(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_get_by_id_proto_list(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_get_by_id_proto_list_full(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_get_by_id_self_fail(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_get_by_id_string_fail(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_get_by_val(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_get_by_val_string(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_in(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_instanceof(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_is_boolean(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_is_function(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_is_number(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_is_object(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_is_string(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_is_undefined(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_less(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_lesseq(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_greater(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_greatereq(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_lshift(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_mod(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_mul(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_negate(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_not(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_nstricteq(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_post_dec(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_post_inc(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_pre_dec(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_pre_inc(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_resolve(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_resolve_base(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_resolve_base_strict_put(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_ensure_property_exists(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_resolve_global(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_resolve_global_dynamic(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_resolve_skip(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_resolve_with_base(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_resolve_with_this(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_rshift(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_strcat(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_stricteq(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_sub(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_to_jsnumber(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_to_primitive(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_typeof(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_urshift(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_to_object(STUB_ARGS_DECLARATION); - JSObject* JIT_STUB cti_op_new_array(STUB_ARGS_DECLARATION); - JSObject* JIT_STUB cti_op_new_array_buffer(STUB_ARGS_DECLARATION); - JSObject* JIT_STUB cti_op_new_func(STUB_ARGS_DECLARATION); - JSObject* JIT_STUB cti_op_new_func_exp(STUB_ARGS_DECLARATION); - JSObject* JIT_STUB cti_op_new_object(STUB_ARGS_DECLARATION); - JSObject* JIT_STUB cti_op_new_regexp(STUB_ARGS_DECLARATION); - JSObject* JIT_STUB cti_op_push_activation(STUB_ARGS_DECLARATION); - JSObject* JIT_STUB cti_op_push_new_scope(STUB_ARGS_DECLARATION); - JSObject* JIT_STUB cti_op_push_scope(STUB_ARGS_DECLARATION); - JSObject* JIT_STUB cti_op_put_by_id_transition_realloc(STUB_ARGS_DECLARATION); - JSPropertyNameIterator* JIT_STUB cti_op_get_pnames(STUB_ARGS_DECLARATION); - int JIT_STUB cti_op_eq(STUB_ARGS_DECLARATION); - int JIT_STUB cti_op_eq_strings(STUB_ARGS_DECLARATION); - int JIT_STUB cti_op_jless(STUB_ARGS_DECLARATION); - int JIT_STUB cti_op_jlesseq(STUB_ARGS_DECLARATION); - int JIT_STUB cti_op_jgreater(STUB_ARGS_DECLARATION); - int JIT_STUB cti_op_jgreatereq(STUB_ARGS_DECLARATION); - int JIT_STUB cti_op_jtrue(STUB_ARGS_DECLARATION); - void* JIT_STUB cti_op_load_varargs(STUB_ARGS_DECLARATION); - int JIT_STUB cti_timeout_check(STUB_ARGS_DECLARATION); - int JIT_STUB cti_has_property(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_check_has_instance(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_debug(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_end(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_jmp_scopes(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_pop_scope(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_profile_did_call(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_profile_will_call(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_put_by_id(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_put_by_id_fail(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_put_by_id_generic(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_put_by_id_direct(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_put_by_id_direct_fail(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_put_by_id_direct_generic(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_put_by_index(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_put_by_val(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_put_getter_setter(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); + EncodedJSValue JIT_STUB cti_op_add(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_bitand(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_bitor(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_bitxor(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_call_NotJSFunction(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_call_eval(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_construct_NotJSConstruct(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_create_this(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_convert_this(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_create_arguments(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_del_by_id(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_del_by_val(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_div(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_get_by_id(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_get_by_id_array_fail(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_get_by_id_custom_stub(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_get_by_id_generic(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_get_by_id_getter_stub(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_get_by_id_method_check(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_get_by_id_method_check_update(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_get_by_id_proto_fail(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_get_by_id_proto_list(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_get_by_id_proto_list_full(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_get_by_id_self_fail(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_get_by_id_string_fail(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_get_by_val(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_get_by_val_string(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_in(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_instanceof(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_is_boolean(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_is_function(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_is_number(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_is_object(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_is_string(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_is_undefined(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_less(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_lesseq(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_greater(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_greatereq(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_lshift(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_mod(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_mul(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_negate(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_not(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_nstricteq(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_post_dec(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_post_inc(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_pre_dec(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_pre_inc(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_resolve(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_resolve_base(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_resolve_base_strict_put(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_ensure_property_exists(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_resolve_global(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_resolve_global_dynamic(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_resolve_skip(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_resolve_with_base(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_resolve_with_this(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_rshift(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_strcat(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_stricteq(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_sub(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_to_jsnumber(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_to_primitive(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_typeof(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_urshift(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_to_object(STUB_ARGS_DECLARATION) WTF_INTERNAL; + JSObject* JIT_STUB cti_op_new_array(STUB_ARGS_DECLARATION) WTF_INTERNAL; + JSObject* JIT_STUB cti_op_new_array_buffer(STUB_ARGS_DECLARATION) WTF_INTERNAL; + JSObject* JIT_STUB cti_op_new_func(STUB_ARGS_DECLARATION) WTF_INTERNAL; + JSObject* JIT_STUB cti_op_new_func_exp(STUB_ARGS_DECLARATION) WTF_INTERNAL; + JSObject* JIT_STUB cti_op_new_object(STUB_ARGS_DECLARATION) WTF_INTERNAL; + JSObject* JIT_STUB cti_op_new_regexp(STUB_ARGS_DECLARATION) WTF_INTERNAL; + JSObject* JIT_STUB cti_op_push_activation(STUB_ARGS_DECLARATION) WTF_INTERNAL; + JSObject* JIT_STUB cti_op_push_new_scope(STUB_ARGS_DECLARATION) WTF_INTERNAL; + JSObject* JIT_STUB cti_op_push_scope(STUB_ARGS_DECLARATION) WTF_INTERNAL; + JSObject* JIT_STUB cti_op_put_by_id_transition_realloc(STUB_ARGS_DECLARATION) WTF_INTERNAL; + JSPropertyNameIterator* JIT_STUB cti_op_get_pnames(STUB_ARGS_DECLARATION) WTF_INTERNAL; + int JIT_STUB cti_op_eq(STUB_ARGS_DECLARATION) WTF_INTERNAL; + int JIT_STUB cti_op_eq_strings(STUB_ARGS_DECLARATION) WTF_INTERNAL; + int JIT_STUB cti_op_jless(STUB_ARGS_DECLARATION) WTF_INTERNAL; + int JIT_STUB cti_op_jlesseq(STUB_ARGS_DECLARATION) WTF_INTERNAL; + int JIT_STUB cti_op_jgreater(STUB_ARGS_DECLARATION) WTF_INTERNAL; + int JIT_STUB cti_op_jgreatereq(STUB_ARGS_DECLARATION) WTF_INTERNAL; + int JIT_STUB cti_op_jtrue(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void* JIT_STUB cti_op_load_varargs(STUB_ARGS_DECLARATION) WTF_INTERNAL; + int JIT_STUB cti_timeout_check(STUB_ARGS_DECLARATION) WTF_INTERNAL; + int JIT_STUB cti_has_property(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void JIT_STUB cti_op_check_has_instance(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void JIT_STUB cti_op_debug(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void JIT_STUB cti_op_end(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void JIT_STUB cti_op_jmp_scopes(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void JIT_STUB cti_op_pop_scope(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void JIT_STUB cti_op_profile_did_call(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void JIT_STUB cti_op_profile_will_call(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void JIT_STUB cti_op_put_by_id(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void JIT_STUB cti_op_put_by_id_fail(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void JIT_STUB cti_op_put_by_id_generic(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void JIT_STUB cti_op_put_by_id_direct(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void JIT_STUB cti_op_put_by_id_direct_fail(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void JIT_STUB cti_op_put_by_id_direct_generic(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void JIT_STUB cti_op_put_by_index(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void JIT_STUB cti_op_put_by_val(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void JIT_STUB cti_op_put_getter_setter(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void JIT_STUB cti_op_put_global_var_check(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void JIT_STUB cti_op_tear_off_activation(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void JIT_STUB cti_op_tear_off_arguments(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void JIT_STUB cti_op_throw_reference_error(STUB_ARGS_DECLARATION) WTF_INTERNAL; #if ENABLE(DFG_JIT) - void JIT_STUB cti_optimize_from_loop(STUB_ARGS_DECLARATION); - void JIT_STUB cti_optimize_from_ret(STUB_ARGS_DECLARATION); + void JIT_STUB cti_optimize_from_loop(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void JIT_STUB cti_optimize_from_ret(STUB_ARGS_DECLARATION) WTF_INTERNAL; #endif - void* JIT_STUB cti_op_call_arityCheck(STUB_ARGS_DECLARATION); - void* JIT_STUB cti_op_construct_arityCheck(STUB_ARGS_DECLARATION); - void* JIT_STUB cti_op_call_jitCompile(STUB_ARGS_DECLARATION); - void* JIT_STUB cti_op_construct_jitCompile(STUB_ARGS_DECLARATION); - void* JIT_STUB cti_op_switch_char(STUB_ARGS_DECLARATION); - void* JIT_STUB cti_op_switch_imm(STUB_ARGS_DECLARATION); - void* JIT_STUB cti_op_switch_string(STUB_ARGS_DECLARATION); - void* JIT_STUB cti_op_throw(STUB_ARGS_DECLARATION); - void* JIT_STUB cti_register_file_check(STUB_ARGS_DECLARATION); - void* JIT_STUB cti_vm_lazyLinkCall(STUB_ARGS_DECLARATION); - void* JIT_STUB cti_vm_lazyLinkConstruct(STUB_ARGS_DECLARATION); - void* JIT_STUB cti_vm_throw(STUB_ARGS_DECLARATION) REFERENCED_FROM_ASM; + void* JIT_STUB cti_op_call_arityCheck(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void* JIT_STUB cti_op_construct_arityCheck(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void* JIT_STUB cti_op_call_jitCompile(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void* JIT_STUB cti_op_construct_jitCompile(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void* JIT_STUB cti_op_switch_char(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void* JIT_STUB cti_op_switch_imm(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void* JIT_STUB cti_op_switch_string(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void* JIT_STUB cti_op_throw(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void* JIT_STUB cti_register_file_check(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void* JIT_STUB cti_vm_lazyLinkCall(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void* JIT_STUB cti_vm_lazyLinkConstruct(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void* JIT_STUB cti_vm_throw(STUB_ARGS_DECLARATION) REFERENCED_FROM_ASM WTF_INTERNAL; } // extern "C" #endif // ENABLE(JIT) diff --git a/Source/JavaScriptCore/jit/SpecializedThunkJIT.h b/Source/JavaScriptCore/jit/SpecializedThunkJIT.h index 74e94ea3c..c98e57d12 100644 --- a/Source/JavaScriptCore/jit/SpecializedThunkJIT.h +++ b/Source/JavaScriptCore/jit/SpecializedThunkJIT.h @@ -132,13 +132,13 @@ namespace JSC { ret(); } - MacroAssemblerCodeRef finalize(JSGlobalData& globalData, MacroAssemblerCodePtr fallback) + MacroAssemblerCodeRef finalize(JSGlobalData& globalData, MacroAssemblerCodePtr fallback, const char* thunkKind) { LinkBuffer patchBuffer(globalData, this, GLOBAL_THUNK_ID); patchBuffer.link(m_failures, CodeLocationLabel(fallback)); for (unsigned i = 0; i < m_calls.size(); i++) patchBuffer.link(m_calls[i].first, m_calls[i].second); - return patchBuffer.finalizeCode(); + return FINALIZE_CODE(patchBuffer, ("Specialized thunk for %s", thunkKind)); } // Assumes that the target function uses fpRegister0 as the first argument diff --git a/Source/JavaScriptCore/jit/ThunkGenerators.cpp b/Source/JavaScriptCore/jit/ThunkGenerators.cpp index e46ba809c..c440b5157 100644 --- a/Source/JavaScriptCore/jit/ThunkGenerators.cpp +++ b/Source/JavaScriptCore/jit/ThunkGenerators.cpp @@ -78,7 +78,7 @@ MacroAssemblerCodeRef charCodeAtThunkGenerator(JSGlobalData* globalData) SpecializedThunkJIT jit(1, globalData); stringCharLoad(jit); jit.returnInt32(SpecializedThunkJIT::regT0); - return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall()); + return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "charCodeAt"); } MacroAssemblerCodeRef charAtThunkGenerator(JSGlobalData* globalData) @@ -87,7 +87,7 @@ MacroAssemblerCodeRef charAtThunkGenerator(JSGlobalData* globalData) stringCharLoad(jit); charToString(jit, globalData, SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT1); jit.returnJSCell(SpecializedThunkJIT::regT0); - return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall()); + return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "charAt"); } MacroAssemblerCodeRef fromCharCodeThunkGenerator(JSGlobalData* globalData) @@ -97,7 +97,7 @@ MacroAssemblerCodeRef fromCharCodeThunkGenerator(JSGlobalData* globalData) jit.loadInt32Argument(0, SpecializedThunkJIT::regT0); charToString(jit, globalData, SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT1); jit.returnJSCell(SpecializedThunkJIT::regT0); - return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall()); + return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "fromCharCode"); } MacroAssemblerCodeRef sqrtThunkGenerator(JSGlobalData* globalData) @@ -109,7 +109,7 @@ MacroAssemblerCodeRef sqrtThunkGenerator(JSGlobalData* globalData) jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0); jit.sqrtDouble(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::fpRegT0); jit.returnDouble(SpecializedThunkJIT::fpRegT0); - return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall()); + return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "sqrt"); } @@ -135,7 +135,7 @@ double jsRound(double d) ".globl " SYMBOL_STRING(function##Thunk) "\n" \ HIDE_SYMBOL(function##Thunk) "\n" \ SYMBOL_STRING(function##Thunk) ":" "\n" \ - "call " SYMBOL_STRING_RELOCATION(function) "\n" \ + "call " GLOBAL_REFERENCE(function) "\n" \ "ret\n" \ );\ extern "C" { \ @@ -152,7 +152,7 @@ double jsRound(double d) SYMBOL_STRING(function##Thunk) ":" "\n" \ "subl $8, %esp\n" \ "movsd %xmm0, (%esp) \n" \ - "call " SYMBOL_STRING_RELOCATION(function) "\n" \ + "call " GLOBAL_REFERENCE(function) "\n" \ "fstpl (%esp) \n" \ "movsd (%esp), %xmm0 \n" \ "addl $8, %esp\n" \ @@ -175,6 +175,11 @@ defineUnaryDoubleOpWrapper(log); defineUnaryDoubleOpWrapper(floor); defineUnaryDoubleOpWrapper(ceil); +static const double oneConstant = 1.0; +static const double negativeHalfConstant = -0.5; +static const double zeroConstant = 0.0; +static const double halfConstant = 0.5; + MacroAssemblerCodeRef floorThunkGenerator(JSGlobalData* globalData) { SpecializedThunkJIT jit(1, globalData); @@ -185,13 +190,26 @@ MacroAssemblerCodeRef floorThunkGenerator(JSGlobalData* globalData) jit.returnInt32(SpecializedThunkJIT::regT0); nonIntJump.link(&jit); jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0); - jit.callDoubleToDouble(UnaryDoubleOpWrapper(floor)); + SpecializedThunkJIT::Jump intResult; SpecializedThunkJIT::JumpList doubleResult; + if (jit.supportsFloatingPointTruncate()) { + jit.loadDouble(&zeroConstant, SpecializedThunkJIT::fpRegT1); + doubleResult.append(jit.branchDouble(MacroAssembler::DoubleEqual, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::fpRegT1)); + SpecializedThunkJIT::JumpList slowPath; + // Handle the negative doubles in the slow path for now. + slowPath.append(jit.branchDouble(MacroAssembler::DoubleLessThanOrUnordered, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::fpRegT1)); + slowPath.append(jit.branchTruncateDoubleToInt32(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0)); + intResult = jit.jump(); + slowPath.link(&jit); + } + jit.callDoubleToDouble(UnaryDoubleOpWrapper(floor)); jit.branchConvertDoubleToInt32(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0, doubleResult, SpecializedThunkJIT::fpRegT1); + if (jit.supportsFloatingPointTruncate()) + intResult.link(&jit); jit.returnInt32(SpecializedThunkJIT::regT0); doubleResult.link(&jit); jit.returnDouble(SpecializedThunkJIT::fpRegT0); - return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall()); + return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "floor"); } MacroAssemblerCodeRef ceilThunkGenerator(JSGlobalData* globalData) @@ -210,12 +228,9 @@ MacroAssemblerCodeRef ceilThunkGenerator(JSGlobalData* globalData) jit.returnInt32(SpecializedThunkJIT::regT0); doubleResult.link(&jit); jit.returnDouble(SpecializedThunkJIT::fpRegT0); - return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall()); + return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "ceil"); } -static const double oneConstant = 1.0; -static const double negativeHalfConstant = -0.5; - MacroAssemblerCodeRef roundThunkGenerator(JSGlobalData* globalData) { SpecializedThunkJIT jit(1, globalData); @@ -226,13 +241,28 @@ MacroAssemblerCodeRef roundThunkGenerator(JSGlobalData* globalData) jit.returnInt32(SpecializedThunkJIT::regT0); nonIntJump.link(&jit); jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0); - jit.callDoubleToDouble(UnaryDoubleOpWrapper(jsRound)); + SpecializedThunkJIT::Jump intResult; SpecializedThunkJIT::JumpList doubleResult; + if (jit.supportsFloatingPointTruncate()) { + jit.loadDouble(&zeroConstant, SpecializedThunkJIT::fpRegT1); + doubleResult.append(jit.branchDouble(MacroAssembler::DoubleEqual, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::fpRegT1)); + SpecializedThunkJIT::JumpList slowPath; + // Handle the negative doubles in the slow path for now. + slowPath.append(jit.branchDouble(MacroAssembler::DoubleLessThanOrUnordered, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::fpRegT1)); + jit.loadDouble(&halfConstant, SpecializedThunkJIT::fpRegT1); + jit.addDouble(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::fpRegT1); + slowPath.append(jit.branchTruncateDoubleToInt32(SpecializedThunkJIT::fpRegT1, SpecializedThunkJIT::regT0)); + intResult = jit.jump(); + slowPath.link(&jit); + } + jit.callDoubleToDouble(UnaryDoubleOpWrapper(jsRound)); jit.branchConvertDoubleToInt32(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0, doubleResult, SpecializedThunkJIT::fpRegT1); + if (jit.supportsFloatingPointTruncate()) + intResult.link(&jit); jit.returnInt32(SpecializedThunkJIT::regT0); doubleResult.link(&jit); jit.returnDouble(SpecializedThunkJIT::fpRegT0); - return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall()); + return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "round"); } MacroAssemblerCodeRef expThunkGenerator(JSGlobalData* globalData) @@ -245,7 +275,7 @@ MacroAssemblerCodeRef expThunkGenerator(JSGlobalData* globalData) jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0); jit.callDoubleToDouble(UnaryDoubleOpWrapper(exp)); jit.returnDouble(SpecializedThunkJIT::fpRegT0); - return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall()); + return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "exp"); } MacroAssemblerCodeRef logThunkGenerator(JSGlobalData* globalData) @@ -258,7 +288,7 @@ MacroAssemblerCodeRef logThunkGenerator(JSGlobalData* globalData) jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0); jit.callDoubleToDouble(UnaryDoubleOpWrapper(log)); jit.returnDouble(SpecializedThunkJIT::fpRegT0); - return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall()); + return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "log"); } MacroAssemblerCodeRef absThunkGenerator(JSGlobalData* globalData) @@ -278,7 +308,7 @@ MacroAssemblerCodeRef absThunkGenerator(JSGlobalData* globalData) jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0); jit.absDouble(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::fpRegT1); jit.returnDouble(SpecializedThunkJIT::fpRegT1); - return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall()); + return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "abs"); } MacroAssemblerCodeRef powThunkGenerator(JSGlobalData* globalData) @@ -330,7 +360,7 @@ MacroAssemblerCodeRef powThunkGenerator(JSGlobalData* globalData) } else jit.appendFailure(nonIntExponent); - return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall()); + return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "pow"); } } |