diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-07-11 13:45:28 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-07-11 13:45:28 +0200 |
commit | d6a599dbc9d824a462b2b206316e102bf8136446 (patch) | |
tree | ecb257a5e55b2239d74b90fdad62fccd661cf286 /Source/JavaScriptCore/jit/JITStubs.cpp | |
parent | 3ccc3a85f09a83557b391aae380d3bf5f81a2911 (diff) | |
download | qtwebkit-d6a599dbc9d824a462b2b206316e102bf8136446.tar.gz |
Imported WebKit commit 8ff1f22783a32de82fee915abd55bd1b298f2644 (http://svn.webkit.org/repository/webkit/trunk@122325)
New snapshot that should work with the latest Qt build system changes
Diffstat (limited to 'Source/JavaScriptCore/jit/JITStubs.cpp')
-rw-r--r-- | Source/JavaScriptCore/jit/JITStubs.cpp | 75 |
1 files changed, 52 insertions, 23 deletions
diff --git a/Source/JavaScriptCore/jit/JITStubs.cpp b/Source/JavaScriptCore/jit/JITStubs.cpp index 6b8082886..2273f0f38 100644 --- a/Source/JavaScriptCore/jit/JITStubs.cpp +++ b/Source/JavaScriptCore/jit/JITStubs.cpp @@ -622,38 +622,46 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" #elif COMPILER(GCC) && CPU(ARM_TRADITIONAL) asm ( +".text" "\n" ".globl " SYMBOL_STRING(ctiTrampoline) "\n" HIDE_SYMBOL(ctiTrampoline) "\n" +INLINE_ARM_FUNCTION(ctiTrampoline) SYMBOL_STRING(ctiTrampoline) ":" "\n" "stmdb sp!, {r1-r3}" "\n" - "stmdb sp!, {r4-r8, lr}" "\n" + "stmdb sp!, {r4-r6, r8-r11, lr}" "\n" "sub sp, sp, #" STRINGIZE_VALUE_OF(PRESERVEDR4_OFFSET) "\n" - "mov r4, r2" "\n" - "mov r5, #512" "\n" + "mov r5, r2" "\n" + "mov r6, #512" "\n" // r0 contains the code - "mov lr, pc" "\n" - "mov pc, r0" "\n" + "blx r0" "\n" "add sp, sp, #" STRINGIZE_VALUE_OF(PRESERVEDR4_OFFSET) "\n" - "ldmia sp!, {r4-r8, lr}" "\n" + "ldmia sp!, {r4-r6, r8-r11, lr}" "\n" "add sp, sp, #12" "\n" - "mov pc, lr" "\n" + "bx lr" "\n" +".globl " SYMBOL_STRING(ctiTrampolineEnd) "\n" +HIDE_SYMBOL(ctiTrampolineEnd) "\n" +SYMBOL_STRING(ctiTrampolineEnd) ":" "\n" ); asm ( +".text" "\n" ".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n" HIDE_SYMBOL(ctiVMThrowTrampoline) "\n" +INLINE_ARM_FUNCTION(ctiVMThrowTrampoline) SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" "mov r0, sp" "\n" "bl " SYMBOL_STRING(cti_vm_throw) "\n" // Both has the same return sequence +".text" "\n" ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n" HIDE_SYMBOL(ctiOpThrowNotCaught) "\n" +INLINE_ARM_FUNCTION(ctiOpThrowNotCaught) SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" "add sp, sp, #" STRINGIZE_VALUE_OF(PRESERVEDR4_OFFSET) "\n" - "ldmia sp!, {r4-r8, lr}" "\n" + "ldmia sp!, {r4-r6, r8-r11, lr}" "\n" "add sp, sp, #12" "\n" - "mov pc, lr" "\n" + "bx lr" "\n" ); #elif COMPILER(RVCT) && CPU(ARM_THUMB2) @@ -954,7 +962,7 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co return; } - size_t offset = slot.cachedOffset(); + PropertyOffset offset = slot.cachedOffset(); size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset); if (!count) { stubInfo->accessType = access_get_by_id_generic; @@ -1156,11 +1164,12 @@ template<typename T> static T throwExceptionFromOpCall(JITStackFrame& jitStackFr }; \ asm ( \ ".globl " SYMBOL_STRING(cti_##op) "\n" \ + INLINE_ARM_FUNCTION(cti_##op) \ SYMBOL_STRING(cti_##op) ":" "\n" \ "str lr, [sp, #" STRINGIZE_VALUE_OF(THUNK_RETURN_ADDRESS_OFFSET) "]" "\n" \ "bl " SYMBOL_STRING(JITStubThunked_##op) "\n" \ "ldr lr, [sp, #" STRINGIZE_VALUE_OF(THUNK_RETURN_ADDRESS_OFFSET) "]" "\n" \ - "mov pc, lr" "\n" \ + "bx lr" "\n" \ ); \ rtype JITStubThunked_##op(STUB_ARGS_DECLARATION) @@ -1486,13 +1495,16 @@ DEFINE_STUB_FUNCTION(JSObject*, op_put_by_id_transition_realloc) JSValue baseValue = stackFrame.args[0].jsValue(); int32_t oldSize = stackFrame.args[3].int32(); Structure* newStructure = stackFrame.args[4].structure(); - int32_t newSize = newStructure->propertyStorageCapacity(); + int32_t newSize = newStructure->outOfLineCapacity(); + + ASSERT(oldSize >= 0); + ASSERT(newSize > oldSize); ASSERT(baseValue.isObject()); JSObject* base = asObject(baseValue); JSGlobalData& globalData = *stackFrame.globalData; - PropertyStorage newStorage = base->growPropertyStorage(globalData, oldSize, newSize); - base->setPropertyStorage(globalData, newStorage, newStructure); + PropertyStorage newStorage = base->growOutOfLineStorage(globalData, oldSize, newSize); + base->setOutOfLineStorage(globalData, newStorage, newStructure); return base; } @@ -1710,7 +1722,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_self_fail) if (stubInfo->accessType == access_get_by_id_self) { ASSERT(!stubInfo->stubRoutine); - polymorphicStructureList = new PolymorphicAccessStructureList(callFrame->globalData(), codeBlock->ownerExecutable(), MacroAssemblerCodeRef(), stubInfo->u.getByIdSelf.baseObjectStructure.get(), true); + polymorphicStructureList = new PolymorphicAccessStructureList(callFrame->globalData(), codeBlock->ownerExecutable(), 0, stubInfo->u.getByIdSelf.baseObjectStructure.get(), true); stubInfo->initGetByIdSelfList(polymorphicStructureList, 1); } else { polymorphicStructureList = stubInfo->u.getByIdSelfList.structureList; @@ -1736,12 +1748,12 @@ static PolymorphicAccessStructureList* getPolymorphicAccessStructureListSlot(JSG switch (stubInfo->accessType) { case access_get_by_id_proto: prototypeStructureList = new PolymorphicAccessStructureList(globalData, owner, stubInfo->stubRoutine, stubInfo->u.getByIdProto.baseObjectStructure.get(), stubInfo->u.getByIdProto.prototypeStructure.get(), true); - stubInfo->stubRoutine = MacroAssemblerCodeRef(); + stubInfo->stubRoutine.clear(); stubInfo->initGetByIdProtoList(prototypeStructureList, 2); break; case access_get_by_id_chain: prototypeStructureList = new PolymorphicAccessStructureList(globalData, owner, stubInfo->stubRoutine, stubInfo->u.getByIdChain.baseObjectStructure.get(), stubInfo->u.getByIdChain.chain.get(), true); - stubInfo->stubRoutine = MacroAssemblerCodeRef(); + stubInfo->stubRoutine.clear(); stubInfo->initGetByIdProtoList(prototypeStructureList, 2); break; case access_get_by_id_proto_list: @@ -1814,7 +1826,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list) ASSERT(slot.slotBase().isObject()); JSObject* slotBaseObject = asObject(slot.slotBase()); - size_t offset = slot.cachedOffset(); + PropertyOffset offset = slot.cachedOffset(); if (slot.slotBase() == baseValue) ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail)); @@ -1928,7 +1940,12 @@ DEFINE_STUB_FUNCTION(void, optimize) unsigned bytecodeIndex = stackFrame.args[0].int32(); #if ENABLE(JIT_VERBOSE_OSR) - dataLog("%p: Entered optimize with bytecodeIndex = %u, executeCounter = %s, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u\n", codeBlock, bytecodeIndex, codeBlock->jitExecuteCounter().status(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter()); + dataLog("%p: Entered optimize with bytecodeIndex = %u, executeCounter = %s, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u, exitCounter = ", codeBlock, bytecodeIndex, codeBlock->jitExecuteCounter().status(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter()); + if (codeBlock->hasOptimizedReplacement()) + dataLog("%u", codeBlock->replacement()->osrExitCounter()); + else + dataLog("N/A"); + dataLog("\n"); #endif if (!codeBlock->checkIfOptimizationThresholdReached()) { @@ -1938,8 +1955,21 @@ DEFINE_STUB_FUNCTION(void, optimize) if (codeBlock->hasOptimizedReplacement()) { #if ENABLE(JIT_VERBOSE_OSR) - dataLog("Considering OSR into %p(%p) with success/fail %u/%u.\n", codeBlock, codeBlock->replacement(), codeBlock->replacement()->speculativeSuccessCounter(), codeBlock->replacement()->speculativeFailCounter()); + dataLog("Considering OSR into %p(%p).\n", codeBlock, codeBlock->replacement()); #endif + // If we have an optimized replacement, then it must be the case that we entered + // cti_optimize from a loop. That's because is there's an optimized replacement, + // then all calls to this function will be relinked to the replacement and so + // the prologue OSR will never fire. + + // This is an interesting threshold check. Consider that a function OSR exits + // in the middle of a loop, while having a relatively low exit count. The exit + // will reset the execution counter to some target threshold, meaning that this + // code won't be reached until that loop heats up for >=1000 executions. But then + // we do a second check here, to see if we should either reoptimize, or just + // attempt OSR entry. Hence it might even be correct for + // shouldReoptimizeFromLoopNow() to always return true. But we make it do some + // additional checking anyway, to reduce the amount of recompilation thrashing. if (codeBlock->replacement()->shouldReoptimizeFromLoopNow()) { #if ENABLE(JIT_VERBOSE_OSR) dataLog("Triggering reoptimization of %p(%p) (in loop).\n", codeBlock, codeBlock->replacement()); @@ -1985,7 +2015,6 @@ DEFINE_STUB_FUNCTION(void, optimize) #endif codeBlock->optimizeSoon(); - optimizedCodeBlock->countSpeculationSuccess(); STUB_SET_RETURN_ADDRESS(address); return; } @@ -1996,10 +2025,10 @@ DEFINE_STUB_FUNCTION(void, optimize) // Count the OSR failure as a speculation failure. If this happens a lot, then // reoptimize. - optimizedCodeBlock->countSpeculationFailure(); + optimizedCodeBlock->countOSRExit(); #if ENABLE(JIT_VERBOSE_OSR) - dataLog("Encountered OSR failure into %p(%p) with success/fail %u/%u.\n", codeBlock, codeBlock->replacement(), codeBlock->replacement()->speculativeSuccessCounter(), codeBlock->replacement()->speculativeFailCounter()); + dataLog("Encountered OSR failure into %p(%p).\n", codeBlock, codeBlock->replacement()); #endif // We are a lot more conservative about triggering reoptimization after OSR failure than |