summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/jit/JITStubs.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-07-11 13:45:28 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-07-11 13:45:28 +0200
commitd6a599dbc9d824a462b2b206316e102bf8136446 (patch)
treeecb257a5e55b2239d74b90fdad62fccd661cf286 /Source/JavaScriptCore/jit/JITStubs.cpp
parent3ccc3a85f09a83557b391aae380d3bf5f81a2911 (diff)
downloadqtwebkit-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.cpp75
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