diff options
Diffstat (limited to 'Source/JavaScriptCore/jit')
-rw-r--r-- | Source/JavaScriptCore/jit/ExecutableAllocator.cpp | 6 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/ExecutableAllocator.h | 3 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp | 9 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JIT.cpp | 7 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JIT.h | 10 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JITCall.cpp | 4 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JITCall32_64.cpp | 2 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JITDriver.h | 101 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JITInlineMethods.h | 18 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JITOpcodes.cpp | 18 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JITOpcodes32_64.cpp | 18 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JITPropertyAccess.cpp | 48 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp | 57 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JITStubCall.h | 8 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JITStubs.cpp | 86 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JITStubs.h | 14 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/SpecializedThunkJIT.h | 2 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/ThunkGenerators.cpp | 20 |
18 files changed, 266 insertions, 165 deletions
diff --git a/Source/JavaScriptCore/jit/ExecutableAllocator.cpp b/Source/JavaScriptCore/jit/ExecutableAllocator.cpp index 82c149d0e..75137279e 100644 --- a/Source/JavaScriptCore/jit/ExecutableAllocator.cpp +++ b/Source/JavaScriptCore/jit/ExecutableAllocator.cpp @@ -28,6 +28,7 @@ #include "ExecutableAllocator.h" #if ENABLE(EXECUTABLE_ALLOCATOR_DEMAND) +#include "CodeProfiling.h" #include <wtf/MetaAllocator.h> #include <wtf/PageReservation.h> #include <wtf/VMTags.h> @@ -93,6 +94,7 @@ void ExecutableAllocator::initializeAllocator() { ASSERT(!allocator); allocator = new DemandExecutableAllocator(); + CodeProfiling::notifyAllocator(allocator); } ExecutableAllocator::ExecutableAllocator(JSGlobalData&) @@ -110,9 +112,9 @@ bool ExecutableAllocator::underMemoryPressure() return false; } -PassRefPtr<ExecutableMemoryHandle> ExecutableAllocator::allocate(JSGlobalData&, size_t sizeInBytes) +PassRefPtr<ExecutableMemoryHandle> ExecutableAllocator::allocate(JSGlobalData&, size_t sizeInBytes, void* ownerUID) { - RefPtr<ExecutableMemoryHandle> result = allocator->allocate(sizeInBytes); + RefPtr<ExecutableMemoryHandle> result = allocator->allocate(sizeInBytes, ownerUID); if (!result) CRASH(); return result.release(); diff --git a/Source/JavaScriptCore/jit/ExecutableAllocator.h b/Source/JavaScriptCore/jit/ExecutableAllocator.h index 876bda62e..bc8b816c8 100644 --- a/Source/JavaScriptCore/jit/ExecutableAllocator.h +++ b/Source/JavaScriptCore/jit/ExecutableAllocator.h @@ -113,7 +113,7 @@ public: static void dumpProfile() { } #endif - PassRefPtr<ExecutableMemoryHandle> allocate(JSGlobalData&, size_t sizeInBytes); + PassRefPtr<ExecutableMemoryHandle> allocate(JSGlobalData&, size_t sizeInBytes, void* ownerUID); #if ENABLE(ASSEMBLER_WX_EXCLUSIVE) static void makeWritable(void* start, size_t size) @@ -130,7 +130,6 @@ public: static void makeExecutable(void*, size_t) {} #endif - #if CPU(X86) || CPU(X86_64) static void cacheFlush(void*, size_t) { diff --git a/Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp b/Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp index 3771c74a9..3fe631e3b 100644 --- a/Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp +++ b/Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp @@ -29,8 +29,8 @@ #if ENABLE(EXECUTABLE_ALLOCATOR_FIXED) +#include "CodeProfiling.h" #include <errno.h> - #include <sys/mman.h> #include <unistd.h> #include <wtf/MetaAllocator.h> @@ -96,6 +96,7 @@ void ExecutableAllocator::initializeAllocator() { ASSERT(!allocator); allocator = new FixedVMPoolExecutableAllocator(); + CodeProfiling::notifyAllocator(allocator); } ExecutableAllocator::ExecutableAllocator(JSGlobalData&) @@ -114,12 +115,12 @@ bool ExecutableAllocator::underMemoryPressure() return statistics.bytesAllocated > statistics.bytesReserved / 2; } -PassRefPtr<ExecutableMemoryHandle> ExecutableAllocator::allocate(JSGlobalData& globalData, size_t sizeInBytes) +PassRefPtr<ExecutableMemoryHandle> ExecutableAllocator::allocate(JSGlobalData& globalData, size_t sizeInBytes, void* ownerUID) { - RefPtr<ExecutableMemoryHandle> result = allocator->allocate(sizeInBytes); + RefPtr<ExecutableMemoryHandle> result = allocator->allocate(sizeInBytes, ownerUID); if (!result) { releaseExecutableMemory(globalData); - result = allocator->allocate(sizeInBytes); + result = allocator->allocate(sizeInBytes, ownerUID); if (!result) CRASH(); } diff --git a/Source/JavaScriptCore/jit/JIT.cpp b/Source/JavaScriptCore/jit/JIT.cpp index 025b5b706..247495aaf 100644 --- a/Source/JavaScriptCore/jit/JIT.cpp +++ b/Source/JavaScriptCore/jit/JIT.cpp @@ -99,7 +99,7 @@ void JIT::emitOptimizationCheck(OptimizationCheckKind kind) if (!shouldEmitProfiling()) return; - Jump skipOptimize = branchAdd32(Signed, TrustedImm32(kind == LoopOptimizationCheck ? Options::executionCounterIncrementForLoop : Options::executionCounterIncrementForReturn), AbsoluteAddress(m_codeBlock->addressOfExecuteCounter())); + Jump skipOptimize = branchAdd32(Signed, TrustedImm32(kind == LoopOptimizationCheck ? Options::executionCounterIncrementForLoop : Options::executionCounterIncrementForReturn), AbsoluteAddress(m_codeBlock->addressOfJITExecuteCounter())); JITStubCall stubCall(this, kind == LoopOptimizationCheck ? cti_optimize_from_loop : cti_optimize_from_ret); if (kind == LoopOptimizationCheck) stubCall.addArgument(Imm32(m_bytecodeOffset)); @@ -328,10 +328,9 @@ void JIT::privateCompileMainPass() DEFINE_OP(op_put_by_id) DEFINE_OP(op_put_by_index) DEFINE_OP(op_put_by_val) - DEFINE_OP(op_put_getter) + DEFINE_OP(op_put_getter_setter) DEFINE_OP(op_put_global_var) DEFINE_OP(op_put_scoped_var) - DEFINE_OP(op_put_setter) DEFINE_OP(op_resolve) DEFINE_OP(op_resolve_base) DEFINE_OP(op_ensure_property_exists) @@ -614,7 +613,7 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck) ASSERT(m_jmpTable.isEmpty()); - LinkBuffer patchBuffer(*m_globalData, this); + LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock); // Translate vPC offsets into addresses in JIT generated code, for switch tables. for (unsigned i = 0; i < m_switches.size(); ++i) { diff --git a/Source/JavaScriptCore/jit/JIT.h b/Source/JavaScriptCore/jit/JIT.h index 750b9d818..c357e8c39 100644 --- a/Source/JavaScriptCore/jit/JIT.h +++ b/Source/JavaScriptCore/jit/JIT.h @@ -333,14 +333,15 @@ namespace JSC { template<typename T> void emitAllocateJSFinalObject(T structure, RegisterID result, RegisterID storagePtr); void emitAllocateJSFunction(FunctionExecutable*, RegisterID scopeChain, RegisterID result, RegisterID storagePtr); - enum ValueProfilingSiteKind { FirstProfilingSite, SubsequentProfilingSite }; #if ENABLE(VALUE_PROFILER) // This assumes that the value to profile is in regT0 and that regT3 is available for // scratch. void emitValueProfilingSite(ValueProfile*); - void emitValueProfilingSite(ValueProfilingSiteKind); + void emitValueProfilingSite(unsigned bytecodeOffset); + void emitValueProfilingSite(); #else - void emitValueProfilingSite(ValueProfilingSiteKind) { } + void emitValueProfilingSite(unsigned) { } + void emitValueProfilingSite() { } #endif #if USE(JSVALUE32_64) @@ -856,10 +857,9 @@ namespace JSC { void emit_op_put_by_id(Instruction*); void emit_op_put_by_index(Instruction*); void emit_op_put_by_val(Instruction*); - void emit_op_put_getter(Instruction*); + void emit_op_put_getter_setter(Instruction*); void emit_op_put_global_var(Instruction*); void emit_op_put_scoped_var(Instruction*); - void emit_op_put_setter(Instruction*); void emit_op_resolve(Instruction*); void emit_op_resolve_base(Instruction*); void emit_op_ensure_property_exists(Instruction*); diff --git a/Source/JavaScriptCore/jit/JITCall.cpp b/Source/JavaScriptCore/jit/JITCall.cpp index 465f1add8..69dc9540e 100644 --- a/Source/JavaScriptCore/jit/JITCall.cpp +++ b/Source/JavaScriptCore/jit/JITCall.cpp @@ -50,8 +50,10 @@ namespace JSC { void JIT::emit_op_call_put_result(Instruction* instruction) { int dst = instruction[1].u.operand; - emitValueProfilingSite(FirstProfilingSite); + emitValueProfilingSite(); emitPutVirtualRegister(dst); + if (canBeOptimized()) + killLastResultRegister(); // Make lastResultRegister tracking simpler in the DFG. } void JIT::compileLoadVarargs(Instruction* instruction) diff --git a/Source/JavaScriptCore/jit/JITCall32_64.cpp b/Source/JavaScriptCore/jit/JITCall32_64.cpp index 01c9db094..b84ad1a49 100644 --- a/Source/JavaScriptCore/jit/JITCall32_64.cpp +++ b/Source/JavaScriptCore/jit/JITCall32_64.cpp @@ -50,7 +50,7 @@ namespace JSC { void JIT::emit_op_call_put_result(Instruction* instruction) { int dst = instruction[1].u.operand; - emitValueProfilingSite(FirstProfilingSite); + emitValueProfilingSite(); emitStore(dst, regT1, regT0); } diff --git a/Source/JavaScriptCore/jit/JITDriver.h b/Source/JavaScriptCore/jit/JITDriver.h new file mode 100644 index 000000000..7e010cdfe --- /dev/null +++ b/Source/JavaScriptCore/jit/JITDriver.h @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JITDriver_h +#define JITDriver_h + +#include <wtf/Platform.h> + +#if ENABLE(JIT) + +#include "BytecodeGenerator.h" +#include "DFGDriver.h" +#include "JIT.h" + +namespace JSC { + +template<typename CodeBlockType> +inline bool jitCompileIfAppropriate(JSGlobalData& globalData, OwnPtr<CodeBlockType>& codeBlock, JITCode& jitCode, JITCode::JITType jitType) +{ + if (!globalData.canUseJIT()) + return true; + + bool dfgCompiled = false; + if (jitType == JITCode::DFGJIT) + dfgCompiled = DFG::tryCompile(globalData, codeBlock.get(), jitCode); + if (dfgCompiled) { + if (codeBlock->alternative()) + codeBlock->alternative()->unlinkIncomingCalls(); + } else { + if (codeBlock->alternative()) { + codeBlock = static_pointer_cast<CodeBlockType>(codeBlock->releaseAlternative()); + return false; + } + jitCode = JIT::compile(&globalData, codeBlock.get()); + } +#if !ENABLE(OPCODE_SAMPLING) + if (!BytecodeGenerator::dumpsGeneratedCode()) + codeBlock->handleBytecodeDiscardingOpportunity(); +#endif + codeBlock->setJITCode(jitCode, MacroAssemblerCodePtr()); + + return true; +} + +inline bool jitCompileFunctionIfAppropriate(JSGlobalData& globalData, OwnPtr<FunctionCodeBlock>& codeBlock, JITCode& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck, SharedSymbolTable*& symbolTable, JITCode::JITType jitType) +{ + if (!globalData.canUseJIT()) + return true; + + bool dfgCompiled = false; + if (jitType == JITCode::DFGJIT) + dfgCompiled = DFG::tryCompileFunction(globalData, codeBlock.get(), jitCode, jitCodeWithArityCheck); + if (dfgCompiled) { + if (codeBlock->alternative()) + codeBlock->alternative()->unlinkIncomingCalls(); + } else { + if (codeBlock->alternative()) { + codeBlock = static_pointer_cast<FunctionCodeBlock>(codeBlock->releaseAlternative()); + symbolTable = codeBlock->sharedSymbolTable(); + return false; + } + jitCode = JIT::compile(&globalData, codeBlock.get(), &jitCodeWithArityCheck); + } +#if !ENABLE(OPCODE_SAMPLING) + if (!BytecodeGenerator::dumpsGeneratedCode()) + codeBlock->handleBytecodeDiscardingOpportunity(); +#endif + + codeBlock->setJITCode(jitCode, jitCodeWithArityCheck); + + return true; +} + +} // namespace JSC + +#endif // ENABLE(JIT) + +#endif // JITDriver_h + diff --git a/Source/JavaScriptCore/jit/JITInlineMethods.h b/Source/JavaScriptCore/jit/JITInlineMethods.h index 5540ffab3..e617961b5 100644 --- a/Source/JavaScriptCore/jit/JITInlineMethods.h +++ b/Source/JavaScriptCore/jit/JITInlineMethods.h @@ -486,20 +486,16 @@ inline void JIT::emitValueProfilingSite(ValueProfile* valueProfile) #endif } -inline void JIT::emitValueProfilingSite(ValueProfilingSiteKind siteKind) +inline void JIT::emitValueProfilingSite(unsigned bytecodeOffset) { if (!shouldEmitProfiling()) return; - - ValueProfile* valueProfile; - if (siteKind == FirstProfilingSite) - valueProfile = m_codeBlock->addValueProfile(m_bytecodeOffset); - else { - ASSERT(siteKind == SubsequentProfilingSite); - valueProfile = m_codeBlock->valueProfileForBytecodeOffset(m_bytecodeOffset); - } - - emitValueProfilingSite(valueProfile); + emitValueProfilingSite(m_codeBlock->valueProfileForBytecodeOffset(bytecodeOffset)); +} + +inline void JIT::emitValueProfilingSite() +{ + emitValueProfilingSite(m_bytecodeOffset); } #endif diff --git a/Source/JavaScriptCore/jit/JITOpcodes.cpp b/Source/JavaScriptCore/jit/JITOpcodes.cpp index f5be279a6..8a2077e47 100644 --- a/Source/JavaScriptCore/jit/JITOpcodes.cpp +++ b/Source/JavaScriptCore/jit/JITOpcodes.cpp @@ -194,7 +194,7 @@ PassRefPtr<ExecutableMemoryHandle> JIT::privateCompileCTIMachineTrampolines(JSGl Call string_failureCases3Call = makeTailRecursiveCall(string_failureCases3); // All trampolines constructed! copy the code, link up calls, and set the pointers on the Machine object. - LinkBuffer patchBuffer(*m_globalData, this); + LinkBuffer patchBuffer(*m_globalData, this, GLOBAL_THUNK_ID); patchBuffer.link(string_failureCases1Call, FunctionPtr(cti_op_get_by_id_string_fail)); patchBuffer.link(string_failureCases2Call, FunctionPtr(cti_op_get_by_id_string_fail)); @@ -568,7 +568,7 @@ void JIT::emit_op_resolve(Instruction* currentInstruction) { JITStubCall stubCall(this, cti_op_resolve); stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand))); - stubCall.callWithValueProfiling(currentInstruction[1].u.operand, FirstProfilingSite); + stubCall.callWithValueProfiling(currentInstruction[1].u.operand); } void JIT::emit_op_to_primitive(Instruction* currentInstruction) @@ -599,7 +599,7 @@ void JIT::emit_op_resolve_base(Instruction* currentInstruction) { JITStubCall stubCall(this, currentInstruction[3].u.operand ? cti_op_resolve_base_strict_put : cti_op_resolve_base); stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand))); - stubCall.callWithValueProfiling(currentInstruction[1].u.operand, FirstProfilingSite); + stubCall.callWithValueProfiling(currentInstruction[1].u.operand); } void JIT::emit_op_ensure_property_exists(Instruction* currentInstruction) @@ -615,7 +615,7 @@ void JIT::emit_op_resolve_skip(Instruction* currentInstruction) JITStubCall stubCall(this, cti_op_resolve_skip); stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand))); stubCall.addArgument(Imm32(currentInstruction[3].u.operand)); - stubCall.callWithValueProfiling(currentInstruction[1].u.operand, FirstProfilingSite); + stubCall.callWithValueProfiling(currentInstruction[1].u.operand); } void JIT::emit_op_resolve_global(Instruction* currentInstruction, bool) @@ -636,7 +636,7 @@ void JIT::emit_op_resolve_global(Instruction* currentInstruction, bool) loadPtr(Address(regT0, OBJECT_OFFSETOF(JSGlobalObject, m_propertyStorage)), regT0); load32(Address(regT2, OBJECT_OFFSETOF(GlobalResolveInfo, offset)), regT1); loadPtr(BaseIndex(regT0, regT1, ScalePtr), regT0); - emitValueProfilingSite(FirstProfilingSite); + emitValueProfilingSite(); emitPutVirtualRegister(currentInstruction[1].u.operand); } @@ -652,7 +652,7 @@ void JIT::emitSlow_op_resolve_global(Instruction* currentInstruction, Vector<Slo stubCall.addArgument(TrustedImmPtr(ident)); stubCall.addArgument(Imm32(currentIndex)); stubCall.addArgument(regT0); - stubCall.callWithValueProfiling(dst, SubsequentProfilingSite); + stubCall.callWithValueProfiling(dst); } void JIT::emit_op_not(Instruction* currentInstruction) @@ -773,7 +773,7 @@ void JIT::emit_op_resolve_with_base(Instruction* currentInstruction) JITStubCall stubCall(this, cti_op_resolve_with_base); stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[3].u.operand))); stubCall.addArgument(Imm32(currentInstruction[1].u.operand)); - stubCall.callWithValueProfiling(currentInstruction[2].u.operand, FirstProfilingSite); + stubCall.callWithValueProfiling(currentInstruction[2].u.operand); } void JIT::emit_op_resolve_with_this(Instruction* currentInstruction) @@ -781,7 +781,7 @@ void JIT::emit_op_resolve_with_this(Instruction* currentInstruction) JITStubCall stubCall(this, cti_op_resolve_with_this); stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[3].u.operand))); stubCall.addArgument(Imm32(currentInstruction[1].u.operand)); - stubCall.callWithValueProfiling(currentInstruction[2].u.operand, FirstProfilingSite); + stubCall.callWithValueProfiling(currentInstruction[2].u.operand); } void JIT::emit_op_jtrue(Instruction* currentInstruction) @@ -1563,7 +1563,7 @@ void JIT::emitSlow_op_resolve_global_dynamic(Instruction* currentInstruction, Ve stubCall.addArgument(TrustedImmPtr(ident)); stubCall.addArgument(Imm32(currentIndex)); stubCall.addArgument(regT0); - stubCall.callWithValueProfiling(dst, SubsequentProfilingSite); // The first profiling site is in emit_op_resolve_global + stubCall.callWithValueProfiling(dst); } void JIT::emit_op_new_regexp(Instruction* currentInstruction) diff --git a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp index 9d1cbce8d..99594c3f1 100644 --- a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp +++ b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp @@ -193,7 +193,7 @@ PassRefPtr<ExecutableMemoryHandle> JIT::privateCompileCTIMachineTrampolines(JSGl Call string_failureCases3Call = makeTailRecursiveCall(string_failureCases3); // All trampolines constructed! copy the code, link up calls, and set the pointers on the Machine object. - LinkBuffer patchBuffer(*m_globalData, this); + LinkBuffer patchBuffer(*m_globalData, this, GLOBAL_THUNK_ID); patchBuffer.link(string_failureCases1Call, FunctionPtr(cti_op_get_by_id_string_fail)); patchBuffer.link(string_failureCases2Call, FunctionPtr(cti_op_get_by_id_string_fail)); @@ -492,7 +492,7 @@ JIT::CodeRef JIT::privateCompileCTINativeCall(JSGlobalData* globalData, NativeFu ret(); // All trampolines constructed! copy the code, link up calls, and set the pointers on the Machine object. - LinkBuffer patchBuffer(*m_globalData, this); + LinkBuffer patchBuffer(*m_globalData, this, GLOBAL_THUNK_ID); patchBuffer.link(nativeCall, FunctionPtr(func)); return patchBuffer.finalizeCode(); @@ -660,7 +660,7 @@ void JIT::emit_op_resolve(Instruction* currentInstruction) { JITStubCall stubCall(this, cti_op_resolve); stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand))); - stubCall.callWithValueProfiling(currentInstruction[1].u.operand, FirstProfilingSite); + stubCall.callWithValueProfiling(currentInstruction[1].u.operand); } void JIT::emit_op_to_primitive(Instruction* currentInstruction) @@ -702,7 +702,7 @@ void JIT::emit_op_resolve_base(Instruction* currentInstruction) { JITStubCall stubCall(this, currentInstruction[3].u.operand ? cti_op_resolve_base_strict_put : cti_op_resolve_base); stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand))); - stubCall.callWithValueProfiling(currentInstruction[1].u.operand, FirstProfilingSite); + stubCall.callWithValueProfiling(currentInstruction[1].u.operand); } void JIT::emit_op_ensure_property_exists(Instruction* currentInstruction) @@ -718,7 +718,7 @@ void JIT::emit_op_resolve_skip(Instruction* currentInstruction) JITStubCall stubCall(this, cti_op_resolve_skip); stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand))); stubCall.addArgument(Imm32(currentInstruction[3].u.operand)); - stubCall.callWithValueProfiling(currentInstruction[1].u.operand, FirstProfilingSite); + stubCall.callWithValueProfiling(currentInstruction[1].u.operand); } void JIT::emit_op_resolve_global(Instruction* currentInstruction, bool dynamic) @@ -743,7 +743,7 @@ void JIT::emit_op_resolve_global(Instruction* currentInstruction, bool dynamic) load32(Address(regT3, OBJECT_OFFSETOF(GlobalResolveInfo, offset)), regT3); load32(BaseIndex(regT2, regT3, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0); // payload load32(BaseIndex(regT2, regT3, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1); // tag - emitValueProfilingSite(FirstProfilingSite); + emitValueProfilingSite(); emitStore(dst, regT1, regT0); map(m_bytecodeOffset + (dynamic ? OPCODE_LENGTH(op_resolve_global_dynamic) : OPCODE_LENGTH(op_resolve_global)), dst, regT1, regT0); } @@ -759,7 +759,7 @@ void JIT::emitSlow_op_resolve_global(Instruction* currentInstruction, Vector<Slo JITStubCall stubCall(this, cti_op_resolve_global); stubCall.addArgument(TrustedImmPtr(ident)); stubCall.addArgument(Imm32(currentIndex)); - stubCall.callWithValueProfiling(dst, SubsequentProfilingSite); + stubCall.callWithValueProfiling(dst); } void JIT::emit_op_not(Instruction* currentInstruction) @@ -1157,7 +1157,7 @@ void JIT::emit_op_resolve_with_base(Instruction* currentInstruction) JITStubCall stubCall(this, cti_op_resolve_with_base); stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[3].u.operand))); stubCall.addArgument(Imm32(currentInstruction[1].u.operand)); - stubCall.callWithValueProfiling(currentInstruction[2].u.operand, FirstProfilingSite); + stubCall.callWithValueProfiling(currentInstruction[2].u.operand); } void JIT::emit_op_resolve_with_this(Instruction* currentInstruction) @@ -1165,7 +1165,7 @@ void JIT::emit_op_resolve_with_this(Instruction* currentInstruction) JITStubCall stubCall(this, cti_op_resolve_with_this); stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[3].u.operand))); stubCall.addArgument(Imm32(currentInstruction[1].u.operand)); - stubCall.callWithValueProfiling(currentInstruction[2].u.operand, FirstProfilingSite); + stubCall.callWithValueProfiling(currentInstruction[2].u.operand); } void JIT::emit_op_throw(Instruction* currentInstruction) diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp index 48951e879..9fa29e2d9 100644 --- a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp +++ b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp @@ -86,7 +86,7 @@ JIT::CodeRef JIT::stringGetByValStubGenerator(JSGlobalData* globalData) jit.move(TrustedImm32(0), regT0); jit.ret(); - LinkBuffer patchBuffer(*globalData, &jit); + LinkBuffer patchBuffer(*globalData, &jit, GLOBAL_THUNK_ID); return patchBuffer.finalizeCode(); } @@ -116,7 +116,7 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction) loadPtr(BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT0); addSlowCase(branchTestPtr(Zero, regT0)); - emitValueProfilingSite(FirstProfilingSite); + emitValueProfilingSite(); emitPutVirtualRegister(dst); } @@ -147,7 +147,7 @@ void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCas stubCall.addArgument(property, regT2); stubCall.call(dst); - emitValueProfilingSite(SubsequentProfilingSite); + emitValueProfilingSite(); } void JIT::compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID offset, RegisterID scratch) @@ -261,21 +261,13 @@ void JIT::emit_op_put_by_index(Instruction* currentInstruction) stubCall.call(); } -void JIT::emit_op_put_getter(Instruction* currentInstruction) +void JIT::emit_op_put_getter_setter(Instruction* currentInstruction) { - JITStubCall stubCall(this, cti_op_put_getter); - stubCall.addArgument(currentInstruction[1].u.operand, regT2); - stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand))); - stubCall.addArgument(currentInstruction[3].u.operand, regT2); - stubCall.call(); -} - -void JIT::emit_op_put_setter(Instruction* currentInstruction) -{ - JITStubCall stubCall(this, cti_op_put_setter); + JITStubCall stubCall(this, cti_op_put_getter_setter); stubCall.addArgument(currentInstruction[1].u.operand, regT2); stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand))); stubCall.addArgument(currentInstruction[3].u.operand, regT2); + stubCall.addArgument(currentInstruction[4].u.operand, regT2); stubCall.call(); } @@ -332,7 +324,7 @@ void JIT::emit_op_method_check(Instruction* currentInstruction) compileGetByIdHotPath(baseVReg, ident); match.link(this); - emitValueProfilingSite(FirstProfilingSite); + emitValueProfilingSite(m_bytecodeOffset + OPCODE_LENGTH(op_method_check)); emitPutVirtualRegister(resultVReg); // We've already generated the following get_by_id, so make sure it's skipped over. @@ -347,7 +339,7 @@ void JIT::emitSlow_op_method_check(Instruction* currentInstruction, Vector<SlowC Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand)); compileGetByIdSlowCase(resultVReg, baseVReg, ident, iter, true); - emitValueProfilingSite(SubsequentProfilingSite); + emitValueProfilingSite(m_bytecodeOffset + OPCODE_LENGTH(op_method_check)); // We've already generated the following get_by_id, so make sure it's skipped over. m_bytecodeOffset += OPCODE_LENGTH(op_get_by_id); @@ -361,7 +353,7 @@ void JIT::emit_op_get_by_id(Instruction* currentInstruction) emitGetVirtualRegister(baseVReg, regT0); compileGetByIdHotPath(baseVReg, ident); - emitValueProfilingSite(FirstProfilingSite); + emitValueProfilingSite(); emitPutVirtualRegister(resultVReg); } @@ -405,7 +397,7 @@ void JIT::emitSlow_op_get_by_id(Instruction* currentInstruction, Vector<SlowCase Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand)); compileGetByIdSlowCase(resultVReg, baseVReg, ident, iter, false); - emitValueProfilingSite(SubsequentProfilingSite); + emitValueProfilingSite(); } void JIT::compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident, Vector<SlowCaseEntry>::iterator& iter, bool isMethodCheck) @@ -548,7 +540,7 @@ void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure stubCall.skipArgument(); // ident stubCall.skipArgument(); // value stubCall.addArgument(TrustedImm32(oldStructure->propertyStorageCapacity())); - stubCall.addArgument(TrustedImm32(newStructure->propertyStorageCapacity())); + stubCall.addArgument(TrustedImmPtr(newStructure)); stubCall.call(regT0); emitGetJITStubArg(2, regT1); @@ -570,7 +562,7 @@ void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure restoreArgumentReferenceForTrampoline(); Call failureCall = tailRecursiveCall(); - LinkBuffer patchBuffer(*m_globalData, this); + LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock); patchBuffer.link(failureCall, FunctionPtr(direct ? cti_op_put_by_id_direct_fail : cti_op_put_by_id_fail)); @@ -629,7 +621,7 @@ void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress) emitFastArithIntToImmNoCheck(regT2, regT0); Jump success = jump(); - LinkBuffer patchBuffer(*m_globalData, this); + LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock); // Use the patch information to link the failure cases back to the original slow case routine. CodeLocationLabel slowCaseBegin = stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall); @@ -686,7 +678,7 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str } else compileGetDirectOffset(protoObject, regT0, cachedOffset); Jump success = jump(); - LinkBuffer patchBuffer(*m_globalData, this); + LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock); // Use the patch information to link the failure cases back to the original slow case routine. CodeLocationLabel slowCaseBegin = stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall); @@ -741,7 +733,7 @@ void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, Polymorphic } Jump success = jump(); - LinkBuffer patchBuffer(*m_globalData, this); + LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock); if (needsStubLink) { for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) { @@ -809,7 +801,7 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi Jump success = jump(); - LinkBuffer patchBuffer(*m_globalData, this); + LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock); if (needsStubLink) { for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) { @@ -878,7 +870,7 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi } Jump success = jump(); - LinkBuffer patchBuffer(*m_globalData, this); + LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock); if (needsStubLink) { for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) { @@ -946,7 +938,7 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str compileGetDirectOffset(protoObject, regT0, cachedOffset); Jump success = jump(); - LinkBuffer patchBuffer(*m_globalData, this); + LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock); if (needsStubLink) { for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) { @@ -994,7 +986,7 @@ void JIT::emit_op_get_scoped_var(Instruction* currentInstruction) loadPtr(Address(regT0, OBJECT_OFFSETOF(ScopeChainNode, object)), regT0); loadPtr(Address(regT0, JSVariableObject::offsetOfRegisters()), regT0); loadPtr(Address(regT0, currentInstruction[2].u.operand * sizeof(Register)), regT0); - emitValueProfilingSite(FirstProfilingSite); + emitValueProfilingSite(); emitPutVirtualRegister(currentInstruction[1].u.operand); } @@ -1029,7 +1021,7 @@ 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); - emitValueProfilingSite(FirstProfilingSite); + emitValueProfilingSite(); emitPutVirtualRegister(currentInstruction[1].u.operand); } diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp index b73d7ab75..2c81a5ff6 100644 --- a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp +++ b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp @@ -62,29 +62,18 @@ void JIT::emit_op_put_by_index(Instruction* currentInstruction) stubCall.call(); } -void JIT::emit_op_put_getter(Instruction* currentInstruction) +void JIT::emit_op_put_getter_setter(Instruction* currentInstruction) { unsigned base = currentInstruction[1].u.operand; unsigned property = currentInstruction[2].u.operand; - unsigned function = currentInstruction[3].u.operand; + unsigned getter = currentInstruction[3].u.operand; + unsigned setter = currentInstruction[4].u.operand; - JITStubCall stubCall(this, cti_op_put_getter); + JITStubCall stubCall(this, cti_op_put_getter_setter); stubCall.addArgument(base); stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(property))); - stubCall.addArgument(function); - stubCall.call(); -} - -void JIT::emit_op_put_setter(Instruction* currentInstruction) -{ - unsigned base = currentInstruction[1].u.operand; - unsigned property = currentInstruction[2].u.operand; - unsigned function = currentInstruction[3].u.operand; - - JITStubCall stubCall(this, cti_op_put_setter); - stubCall.addArgument(base); - stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(property))); - stubCall.addArgument(function); + stubCall.addArgument(getter); + stubCall.addArgument(setter); stubCall.call(); } @@ -144,7 +133,7 @@ void JIT::emit_op_method_check(Instruction* currentInstruction) compileGetByIdHotPath(); match.link(this); - emitValueProfilingSite(FirstProfilingSite); + emitValueProfilingSite(m_bytecodeOffset + OPCODE_LENGTH(op_method_check)); emitStore(dst, regT1, regT0); map(m_bytecodeOffset + OPCODE_LENGTH(op_method_check) + OPCODE_LENGTH(op_get_by_id), dst, regT1, regT0); @@ -161,7 +150,7 @@ void JIT::emitSlow_op_method_check(Instruction* currentInstruction, Vector<SlowC int ident = currentInstruction[3].u.operand; compileGetByIdSlowCase(dst, base, &(m_codeBlock->identifier(ident)), iter, true); - emitValueProfilingSite(SubsequentProfilingSite); + emitValueProfilingSite(m_bytecodeOffset + OPCODE_LENGTH(op_method_check)); // We've already generated the following get_by_id, so make sure it's skipped over. m_bytecodeOffset += OPCODE_LENGTH(op_get_by_id); @@ -205,7 +194,7 @@ JIT::CodeRef JIT::stringGetByValStubGenerator(JSGlobalData* globalData) jit.move(TrustedImm32(0), regT0); jit.ret(); - LinkBuffer patchBuffer(*globalData, &jit); + LinkBuffer patchBuffer(*globalData, &jit, GLOBAL_THUNK_ID); return patchBuffer.finalizeCode(); } @@ -228,7 +217,7 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction) load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0); // payload addSlowCase(branch32(Equal, regT1, TrustedImm32(JSValue::EmptyValueTag))); - emitValueProfilingSite(FirstProfilingSite); + emitValueProfilingSite(); emitStore(dst, regT1, regT0); map(m_bytecodeOffset + OPCODE_LENGTH(op_get_by_val), dst, regT1, regT0); } @@ -261,7 +250,7 @@ void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCas stubCall.addArgument(property); stubCall.call(dst); - emitValueProfilingSite(SubsequentProfilingSite); + emitValueProfilingSite(); } void JIT::emit_op_put_by_val(Instruction* currentInstruction) @@ -325,7 +314,7 @@ void JIT::emit_op_get_by_id(Instruction* currentInstruction) emitLoad(base, regT1, regT0); emitJumpSlowCaseIfNotJSCell(base, regT1); compileGetByIdHotPath(); - emitValueProfilingSite(FirstProfilingSite); + emitValueProfilingSite(); emitStore(dst, regT1, regT0); map(m_bytecodeOffset + OPCODE_LENGTH(op_get_by_id), dst, regT1, regT0); } @@ -369,7 +358,7 @@ void JIT::emitSlow_op_get_by_id(Instruction* currentInstruction, Vector<SlowCase int ident = currentInstruction[3].u.operand; compileGetByIdSlowCase(dst, base, &(m_codeBlock->identifier(ident)), iter); - emitValueProfilingSite(SubsequentProfilingSite); + emitValueProfilingSite(); } void JIT::compileGetByIdSlowCase(int dst, int base, Identifier* ident, Vector<SlowCaseEntry>::iterator& iter, bool isMethodCheck) @@ -517,7 +506,7 @@ void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure stubCall.skipArgument(); // ident stubCall.skipArgument(); // value stubCall.addArgument(TrustedImm32(oldStructure->propertyStorageCapacity())); - stubCall.addArgument(TrustedImm32(newStructure->propertyStorageCapacity())); + stubCall.addArgument(TrustedImmPtr(newStructure)); stubCall.call(regT0); restoreReturnAddressBeforeReturn(regT3); @@ -553,7 +542,7 @@ void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure restoreArgumentReferenceForTrampoline(); Call failureCall = tailRecursiveCall(); - LinkBuffer patchBuffer(*m_globalData, this); + LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock); patchBuffer.link(failureCall, FunctionPtr(direct ? cti_op_put_by_id_direct_fail : cti_op_put_by_id_fail)); @@ -617,7 +606,7 @@ void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress) move(TrustedImm32(JSValue::Int32Tag), regT1); Jump success = jump(); - LinkBuffer patchBuffer(*m_globalData, this); + LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock); // Use the patch information to link the failure cases back to the original slow case routine. CodeLocationLabel slowCaseBegin = stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall); @@ -676,7 +665,7 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str Jump success = jump(); - LinkBuffer patchBuffer(*m_globalData, this); + LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock); // Use the patch information to link the failure cases back to the original slow case routine. CodeLocationLabel slowCaseBegin = stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall); @@ -735,7 +724,7 @@ void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, Polymorphic Jump success = jump(); - LinkBuffer patchBuffer(*m_globalData, this); + LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock); if (needsStubLink) { for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) { if (iter->to) @@ -802,7 +791,7 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi Jump success = jump(); - LinkBuffer patchBuffer(*m_globalData, this); + LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock); if (needsStubLink) { for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) { if (iter->to) @@ -872,7 +861,7 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi Jump success = jump(); - LinkBuffer patchBuffer(*m_globalData, this); + LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock); if (needsStubLink) { for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) { if (iter->to) @@ -939,7 +928,7 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset); Jump success = jump(); - LinkBuffer patchBuffer(*m_globalData, this); + LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock); if (needsStubLink) { for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) { if (iter->to) @@ -1043,7 +1032,7 @@ void JIT::emit_op_get_scoped_var(Instruction* currentInstruction) loadPtr(Address(regT2, JSVariableObject::offsetOfRegisters()), regT2); emitLoad(index, regT1, regT0, regT2); - emitValueProfilingSite(FirstProfilingSite); + emitValueProfilingSite(); emitStore(dst, regT1, regT0); map(m_bytecodeOffset + OPCODE_LENGTH(op_get_scoped_var), dst, regT1, regT0); } @@ -1085,7 +1074,7 @@ void JIT::emit_op_get_global_var(Instruction* currentInstruction) loadPtr(&globalObject->m_registers, regT2); emitLoad(index, regT1, regT0, regT2); - emitValueProfilingSite(FirstProfilingSite); + emitValueProfilingSite(); emitStore(dst, regT1, regT0); map(m_bytecodeOffset + OPCODE_LENGTH(op_get_global_var), dst, regT1, regT0); } diff --git a/Source/JavaScriptCore/jit/JITStubCall.h b/Source/JavaScriptCore/jit/JITStubCall.h index 18441c363..51401a77f 100644 --- a/Source/JavaScriptCore/jit/JITStubCall.h +++ b/Source/JavaScriptCore/jit/JITStubCall.h @@ -201,14 +201,14 @@ namespace JSC { return call; } - JIT::Call callWithValueProfiling(unsigned dst, JIT::ValueProfilingSiteKind kind) + JIT::Call callWithValueProfiling(unsigned dst) { ASSERT(m_returnType == Value || m_returnType == Cell); JIT::Call call = this->call(); ASSERT(JIT::returnValueRegister == JIT::regT0); if (m_returnType == Cell) m_jit->move(JIT::TrustedImm32(JSValue::CellTag), JIT::regT1); - m_jit->emitValueProfilingSite(kind); + m_jit->emitValueProfilingSite(); if (m_returnType == Value) m_jit->emitStore(dst, JIT::regT1, JIT::regT0); else @@ -224,12 +224,12 @@ namespace JSC { return call; } - JIT::Call callWithValueProfiling(unsigned dst, JIT::ValueProfilingSiteKind kind) + JIT::Call callWithValueProfiling(unsigned dst) { ASSERT(m_returnType == VoidPtr || m_returnType == Cell); JIT::Call call = this->call(); ASSERT(JIT::returnValueRegister == JIT::regT0); - m_jit->emitValueProfilingSite(kind); + m_jit->emitValueProfilingSite(); m_jit->emitPutVirtualRegister(dst); return call; } diff --git a/Source/JavaScriptCore/jit/JITStubs.cpp b/Source/JavaScriptCore/jit/JITStubs.cpp index 3c16efe01..386d0dfa1 100644 --- a/Source/JavaScriptCore/jit/JITStubs.cpp +++ b/Source/JavaScriptCore/jit/JITStubs.cpp @@ -37,6 +37,7 @@ #include "Arguments.h" #include "CallFrame.h" #include "CodeBlock.h" +#include "CodeProfiling.h" #include "DFGOSREntry.h" #include "Debugger.h" #include "ExceptionHelpers.h" @@ -101,6 +102,9 @@ SYMBOL_STRING(ctiTrampoline) ":" "\n" "popl %esi" "\n" "popl %ebp" "\n" "ret" "\n" +".globl " SYMBOL_STRING(ctiTrampolineEnd) "\n" +HIDE_SYMBOL(ctiTrampolineEnd) "\n" +SYMBOL_STRING(ctiTrampolineEnd) ":" "\n" ); asm ( @@ -158,6 +162,9 @@ SYMBOL_STRING(ctiTrampoline) ":" "\n" "popq %r12" "\n" "popq %rbp" "\n" "ret" "\n" +".globl " SYMBOL_STRING(ctiTrampolineEnd) "\n" +HIDE_SYMBOL(ctiTrampolineEnd) "\n" +SYMBOL_STRING(ctiTrampolineEnd) ":" "\n" ); asm ( @@ -400,6 +407,9 @@ SYMBOL_STRING(ctiTrampoline) ":" "\n" "popq %r12" "\n" "popq %rbp" "\n" "ret" "\n" +".globl " SYMBOL_STRING(ctiTrampolineEnd) "\n" +HIDE_SYMBOL(ctiTrampolineEnd) "\n" +SYMBOL_STRING(ctiTrampolineEnd) ":" "\n" ); asm ( @@ -560,6 +570,12 @@ SYMBOL_STRING(ctiTrampoline) ":" "\n" "ldr lr, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_RETURN_ADDRESS_OFFSET) "]" "\n" "add sp, sp, #" STRINGIZE_VALUE_OF(ENABLE_PROFILER_REFERENCE_OFFSET) "\n" "bx lr" "\n" +".align 2" "\n" +".globl " SYMBOL_STRING(ctiTrampolineEnd) "\n" +HIDE_SYMBOL(ctiTrampolineEnd) "\n" +".thumb" "\n" +".thumb_func " THUMB_FUNC_PARAM(ctiTrampolineEnd) "\n" +SYMBOL_STRING(ctiTrampolineEnd) ":" "\n" ); asm ( @@ -953,7 +969,7 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co JIT::compileGetByIdChain(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, prototypeChain, count, propertyName, slot, offset, returnAddress); } -#ifndef NDEBUG +#if !defined(NDEBUG) extern "C" { @@ -971,7 +987,8 @@ struct StackHack { : stackFrame(stackFrame) , savedReturnAddress(*stackFrame.returnAddressSlot()) { - *stackFrame.returnAddressSlot() = ReturnAddressPtr(FunctionPtr(jscGeneratedNativeCode)); + if (!CodeProfiling::enabled()) + *stackFrame.returnAddressSlot() = ReturnAddressPtr(FunctionPtr(jscGeneratedNativeCode)); } ALWAYS_INLINE ~StackHack() @@ -1303,10 +1320,8 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_add) JSValue v2 = stackFrame.args[1].jsValue(); CallFrame* callFrame = stackFrame.callFrame; - if (v1.isString()) { - JSValue result = v2.isString() - ? jsString(callFrame, asString(v1), asString(v2)) - : jsString(callFrame, asString(v1), v2.toPrimitiveString(callFrame)); + if (v1.isString() && !v2.isObject()) { + JSValue result = jsString(callFrame, asString(v1), v2.toString(callFrame)); CHECK_FOR_EXCEPTION_AT_END(); return JSValue::encode(result); } @@ -1382,7 +1397,9 @@ DEFINE_STUB_FUNCTION(void, op_put_by_id_direct_generic) STUB_INIT_STACK_FRAME(stackFrame); PutPropertySlot slot(stackFrame.callFrame->codeBlock()->isStrictMode()); - stackFrame.args[0].jsValue().putDirect(stackFrame.callFrame, stackFrame.args[1].identifier(), stackFrame.args[2].jsValue(), slot); + JSValue baseValue = stackFrame.args[0].jsValue(); + ASSERT(baseValue.isObject()); + asObject(baseValue)->putDirect(stackFrame.callFrame->globalData(), stackFrame.args[1].identifier(), stackFrame.args[2].jsValue(), slot); CHECK_FOR_EXCEPTION_AT_END(); } @@ -1427,7 +1444,9 @@ DEFINE_STUB_FUNCTION(void, op_put_by_id_direct) Identifier& ident = stackFrame.args[1].identifier(); PutPropertySlot slot(callFrame->codeBlock()->isStrictMode()); - stackFrame.args[0].jsValue().putDirect(callFrame, ident, stackFrame.args[2].jsValue(), slot); + JSValue baseValue = stackFrame.args[0].jsValue(); + ASSERT(baseValue.isObject()); + asObject(baseValue)->putDirect(callFrame->globalData(), ident, stackFrame.args[2].jsValue(), slot); CodeBlock* codeBlock = stackFrame.callFrame->codeBlock(); StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS); @@ -1460,7 +1479,9 @@ DEFINE_STUB_FUNCTION(void, op_put_by_id_direct_fail) Identifier& ident = stackFrame.args[1].identifier(); PutPropertySlot slot(callFrame->codeBlock()->isStrictMode()); - stackFrame.args[0].jsValue().putDirect(callFrame, ident, stackFrame.args[2].jsValue(), slot); + JSValue baseValue = stackFrame.args[0].jsValue(); + ASSERT(baseValue.isObject()); + asObject(baseValue)->putDirect(callFrame->globalData(), ident, stackFrame.args[2].jsValue(), slot); CHECK_FOR_EXCEPTION_AT_END(); } @@ -1471,7 +1492,8 @@ DEFINE_STUB_FUNCTION(JSObject*, op_put_by_id_transition_realloc) JSValue baseValue = stackFrame.args[0].jsValue(); int32_t oldSize = stackFrame.args[3].int32(); - int32_t newSize = stackFrame.args[4].int32(); + Structure* newStructure = stackFrame.args[4].structure(); + int32_t newSize = newStructure->propertyStorageCapacity(); ASSERT(baseValue.isObject()); JSObject* base = asObject(baseValue); @@ -1909,7 +1931,7 @@ DEFINE_STUB_FUNCTION(void, optimize_from_loop) unsigned bytecodeIndex = stackFrame.args[0].int32(); #if ENABLE(JIT_VERBOSE_OSR) - printf("Entered optimize_from_loop with executeCounter = %d, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u\n", codeBlock->executeCounter(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter()); + printf("Entered optimize_from_loop with executeCounter = %d, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u\n", codeBlock->jitExecuteCounter(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter()); #endif if (codeBlock->hasOptimizedReplacement()) { @@ -2007,7 +2029,7 @@ DEFINE_STUB_FUNCTION(void, optimize_from_ret) CodeBlock* codeBlock = callFrame->codeBlock(); #if ENABLE(JIT_VERBOSE_OSR) - printf("Entered optimize_from_ret with executeCounter = %d, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u\n", codeBlock->executeCounter(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter()); + printf("Entered optimize_from_ret with executeCounter = %d, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u\n", codeBlock->jitExecuteCounter(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter()); #endif if (codeBlock->hasOptimizedReplacement()) { @@ -2455,7 +2477,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val) return JSValue::encode(result); } - Identifier property(callFrame, subscript.toString(callFrame)); + Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame)); JSValue result = baseValue.get(callFrame, property); CHECK_FOR_EXCEPTION_AT_END(); return JSValue::encode(result); @@ -2482,7 +2504,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val_string) ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val)); } } else { - Identifier property(callFrame, subscript.toString(callFrame)); + Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame)); result = baseValue.get(callFrame, property); } @@ -2512,7 +2534,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val_byte_array) if (!isJSByteArray(baseValue)) ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val)); } else { - Identifier property(callFrame, subscript.toString(callFrame)); + Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame)); result = baseValue.get(callFrame, property); } @@ -2573,7 +2595,7 @@ DEFINE_STUB_FUNCTION(void, op_put_by_val) } else baseValue.put(callFrame, i, value); } else { - Identifier property(callFrame, subscript.toString(callFrame)); + Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame)); if (!stackFrame.globalData->exception) { // Don't put to an object if toString threw an exception. PutPropertySlot slot(callFrame->codeBlock()->isStrictMode()); baseValue.put(callFrame, property, value, slot); @@ -2614,7 +2636,7 @@ DEFINE_STUB_FUNCTION(void, op_put_by_val_byte_array) ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_put_by_val)); baseValue.put(callFrame, i, value); } else { - Identifier property(callFrame, subscript.toString(callFrame)); + Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame)); if (!stackFrame.globalData->exception) { // Don't put to an object if toString threw an exception. PutPropertySlot slot(callFrame->codeBlock()->isStrictMode()); baseValue.put(callFrame, property, value, slot); @@ -3380,7 +3402,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_in) if (propName.getUInt32(i)) return JSValue::encode(jsBoolean(baseObj->hasProperty(callFrame, i))); - Identifier property(callFrame, propName.toString(callFrame)); + Identifier property(callFrame, propName.toString(callFrame)->value(callFrame)); CHECK_FOR_EXCEPTION(); return JSValue::encode(jsBoolean(baseObj->hasProperty(callFrame, property))); } @@ -3492,7 +3514,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_del_by_val) result = baseObj->methodTable()->deletePropertyByIndex(baseObj, callFrame, i); else { CHECK_FOR_EXCEPTION(); - Identifier property(callFrame, subscript.toString(callFrame)); + Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame)); CHECK_FOR_EXCEPTION(); result = baseObj->methodTable()->deleteProperty(baseObj, callFrame, property); } @@ -3504,7 +3526,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_del_by_val) return JSValue::encode(jsBoolean(result)); } -DEFINE_STUB_FUNCTION(void, op_put_getter) +DEFINE_STUB_FUNCTION(void, op_put_getter_setter) { STUB_INIT_STACK_FRAME(stackFrame); @@ -3512,20 +3534,20 @@ DEFINE_STUB_FUNCTION(void, op_put_getter) ASSERT(stackFrame.args[0].jsValue().isObject()); JSObject* baseObj = asObject(stackFrame.args[0].jsValue()); - ASSERT(stackFrame.args[2].jsValue().isObject()); - baseObj->methodTable()->defineGetter(baseObj, callFrame, stackFrame.args[1].identifier(), asObject(stackFrame.args[2].jsValue()), 0); -} -DEFINE_STUB_FUNCTION(void, op_put_setter) -{ - STUB_INIT_STACK_FRAME(stackFrame); + GetterSetter* accessor = GetterSetter::create(callFrame); - CallFrame* callFrame = stackFrame.callFrame; + JSValue getter = stackFrame.args[2].jsValue(); + JSValue setter = stackFrame.args[3].jsValue(); + ASSERT(getter.isObject() || getter.isUndefined()); + ASSERT(setter.isObject() || setter.isUndefined()); + ASSERT(getter.isObject() || setter.isObject()); - ASSERT(stackFrame.args[0].jsValue().isObject()); - JSObject* baseObj = asObject(stackFrame.args[0].jsValue()); - ASSERT(stackFrame.args[2].jsValue().isObject()); - baseObj->methodTable()->defineSetter(baseObj, callFrame, stackFrame.args[1].identifier(), asObject(stackFrame.args[2].jsValue()), 0); + if (!getter.isUndefined()) + accessor->setGetter(callFrame->globalData(), asObject(getter)); + if (!setter.isUndefined()) + accessor->setSetter(callFrame->globalData(), asObject(setter)); + baseObj->putDirectAccessor(callFrame->globalData(), stackFrame.args[1].identifier(), accessor, Accessor); } DEFINE_STUB_FUNCTION(void, op_throw_reference_error) @@ -3533,7 +3555,7 @@ DEFINE_STUB_FUNCTION(void, op_throw_reference_error) STUB_INIT_STACK_FRAME(stackFrame); CallFrame* callFrame = stackFrame.callFrame; - UString message = stackFrame.args[0].jsValue().toString(callFrame); + UString message = stackFrame.args[0].jsValue().toString(callFrame)->value(callFrame); stackFrame.globalData->exception = createReferenceError(callFrame, message); VM_THROW_EXCEPTION_AT_END(); } diff --git a/Source/JavaScriptCore/jit/JITStubs.h b/Source/JavaScriptCore/jit/JITStubs.h index 241ace968..fe5f522e9 100644 --- a/Source/JavaScriptCore/jit/JITStubs.h +++ b/Source/JavaScriptCore/jit/JITStubs.h @@ -59,6 +59,7 @@ namespace JSC { class PutPropertySlot; class RegisterFile; class RegExp; + class Structure; template <typename T> class Weak; @@ -78,6 +79,7 @@ namespace JSC { JSPropertyNameIterator* propertyNameIterator() { return static_cast<JSPropertyNameIterator*>(asPointer); } JSGlobalObject* globalObject() { return static_cast<JSGlobalObject*>(asPointer); } JSString* jsString() { return static_cast<JSString*>(asPointer); } + Structure* structure() { return static_cast<Structure*>(asPointer); } ReturnAddressPtr returnAddress() { return ReturnAddressPtr(asPointer); } }; @@ -281,6 +283,15 @@ namespace JSC { extern "C" void ctiVMThrowTrampoline(); extern "C" void ctiOpThrowNotCaught(); extern "C" EncodedJSValue ctiTrampoline(void* code, RegisterFile*, CallFrame*, void* /*unused1*/, Profiler**, JSGlobalData*); +#if ENABLE(DFG_JIT) + extern "C" void ctiTrampolineEnd(); + + inline bool returnAddressIsInCtiTrampoline(ReturnAddressPtr returnAddress) + { + return returnAddress.value() >= bitwise_cast<void*>(&ctiTrampoline) + && returnAddress.value() < bitwise_cast<void*>(&ctiTrampolineEnd); + } +#endif class JITThunks { public: @@ -423,8 +434,7 @@ extern "C" { 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_by_val_byte_array(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_put_getter(STUB_ARGS_DECLARATION); - void JIT_STUB cti_op_put_setter(STUB_ARGS_DECLARATION); + void JIT_STUB cti_op_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); diff --git a/Source/JavaScriptCore/jit/SpecializedThunkJIT.h b/Source/JavaScriptCore/jit/SpecializedThunkJIT.h index 1802216fa..74e94ea3c 100644 --- a/Source/JavaScriptCore/jit/SpecializedThunkJIT.h +++ b/Source/JavaScriptCore/jit/SpecializedThunkJIT.h @@ -134,7 +134,7 @@ namespace JSC { MacroAssemblerCodeRef finalize(JSGlobalData& globalData, MacroAssemblerCodePtr fallback) { - LinkBuffer patchBuffer(globalData, this); + 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); diff --git a/Source/JavaScriptCore/jit/ThunkGenerators.cpp b/Source/JavaScriptCore/jit/ThunkGenerators.cpp index 0e54c8a8f..099796986 100644 --- a/Source/JavaScriptCore/jit/ThunkGenerators.cpp +++ b/Source/JavaScriptCore/jit/ThunkGenerators.cpp @@ -27,8 +27,9 @@ #include "ThunkGenerators.h" #include "CodeBlock.h" -#include <wtf/text/StringImpl.h> +#include "InlineASM.h" #include "SpecializedThunkJIT.h" +#include <wtf/text/StringImpl.h> #if ENABLE(JIT) @@ -111,21 +112,6 @@ MacroAssemblerCodeRef sqrtThunkGenerator(JSGlobalData* globalData) return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall()); } -#if OS(DARWIN) || (OS(WINDOWS) && CPU(X86)) -#define SYMBOL_STRING(name) "_" #name -#else -#define SYMBOL_STRING(name) #name -#endif - -#if (OS(LINUX) || OS(FREEBSD)) && CPU(X86_64) -#define SYMBOL_STRING_RELOCATION(name) #name "@plt" -#elif OS(DARWIN) || (CPU(X86_64) && COMPILER(MINGW) && !GCC_VERSION_AT_LEAST(4, 5, 0)) -#define SYMBOL_STRING_RELOCATION(name) "_" #name -#elif CPU(X86) && COMPILER(MINGW) -#define SYMBOL_STRING_RELOCATION(name) "@" #name "@4" -#else -#define SYMBOL_STRING_RELOCATION(name) #name -#endif #define UnaryDoubleOpWrapper(function) function##Wrapper enum MathThunkCallingConvention { }; @@ -147,6 +133,7 @@ double jsRound(double d) asm( \ ".text\n" \ ".globl " SYMBOL_STRING(function##Thunk) "\n" \ + HIDE_SYMBOL(function##Thunk) "\n" \ SYMBOL_STRING(function##Thunk) ":" "\n" \ "call " SYMBOL_STRING_RELOCATION(function) "\n" \ "ret\n" \ @@ -161,6 +148,7 @@ double jsRound(double d) asm( \ ".text\n" \ ".globl " SYMBOL_STRING(function##Thunk) "\n" \ + HIDE_SYMBOL(function##Thunk) "\n" \ SYMBOL_STRING(function##Thunk) ":" "\n" \ "subl $8, %esp\n" \ "movsd %xmm0, (%esp) \n" \ |