diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2012-11-22 09:09:45 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2012-11-22 09:10:13 +0100 |
commit | 470286ecfe79d59df14944e5b5d34630fc739391 (patch) | |
tree | 43983212872e06cebefd2ae474418fa2908ca54c /Source/JavaScriptCore/llint | |
parent | 23037105e948c2065da5a937d3a2396b0ff45c1e (diff) | |
download | qtwebkit-470286ecfe79d59df14944e5b5d34630fc739391.tar.gz |
Imported WebKit commit e89504fa9195b2063b2530961d4b73dd08de3242 (http://svn.webkit.org/repository/webkit/trunk@135485)
Change-Id: I03774e5ac79721c13ffa30d152537a74d0b12e66
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'Source/JavaScriptCore/llint')
-rw-r--r-- | Source/JavaScriptCore/llint/LLIntData.cpp | 16 | ||||
-rw-r--r-- | Source/JavaScriptCore/llint/LLIntExceptions.cpp | 6 | ||||
-rw-r--r-- | Source/JavaScriptCore/llint/LLIntSlowPaths.cpp | 64 | ||||
-rw-r--r-- | Source/JavaScriptCore/llint/LowLevelInterpreter.asm | 17 | ||||
-rw-r--r-- | Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm | 101 | ||||
-rw-r--r-- | Source/JavaScriptCore/llint/LowLevelInterpreter64.asm | 96 |
6 files changed, 208 insertions, 92 deletions
diff --git a/Source/JavaScriptCore/llint/LLIntData.cpp b/Source/JavaScriptCore/llint/LLIntData.cpp index eec376b37..90faff2ee 100644 --- a/Source/JavaScriptCore/llint/LLIntData.cpp +++ b/Source/JavaScriptCore/llint/LLIntData.cpp @@ -84,14 +84,14 @@ void Data::performAssertions(JSGlobalData& globalData) ASSERT(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload) == 0); #endif #if USE(JSVALUE32_64) - ASSERT(JSValue::Int32Tag == -1); - ASSERT(JSValue::BooleanTag == -2); - ASSERT(JSValue::NullTag == -3); - ASSERT(JSValue::UndefinedTag == -4); - ASSERT(JSValue::CellTag == -5); - ASSERT(JSValue::EmptyValueTag == -6); - ASSERT(JSValue::DeletedValueTag == -7); - ASSERT(JSValue::LowestTag == -7); + ASSERT(JSValue::Int32Tag == static_cast<unsigned>(-1)); + ASSERT(JSValue::BooleanTag == static_cast<unsigned>(-2)); + ASSERT(JSValue::NullTag == static_cast<unsigned>(-3)); + ASSERT(JSValue::UndefinedTag == static_cast<unsigned>(-4)); + ASSERT(JSValue::CellTag == static_cast<unsigned>(-5)); + ASSERT(JSValue::EmptyValueTag == static_cast<unsigned>(-6)); + ASSERT(JSValue::DeletedValueTag == static_cast<unsigned>(-7)); + ASSERT(JSValue::LowestTag == static_cast<unsigned>(-7)); #else ASSERT(TagBitTypeOther == 0x2); ASSERT(TagBitBool == 0x4); diff --git a/Source/JavaScriptCore/llint/LLIntExceptions.cpp b/Source/JavaScriptCore/llint/LLIntExceptions.cpp index 80ca732ad..5e6bba365 100644 --- a/Source/JavaScriptCore/llint/LLIntExceptions.cpp +++ b/Source/JavaScriptCore/llint/LLIntExceptions.cpp @@ -50,7 +50,7 @@ void interpreterThrowInCaller(ExecState* exec, ReturnAddressPtr pc) JSGlobalData* globalData = &exec->globalData(); NativeCallFrameTracer tracer(globalData, exec); #if LLINT_SLOW_PATH_TRACING - dataLog("Throwing exception %s.\n", globalData->exception.description()); + dataLogF("Throwing exception %s.\n", globalData->exception.description()); #endif fixupPCforExceptionIfNeeded(exec); genericThrow( @@ -69,7 +69,7 @@ Instruction* returnToThrow(ExecState* exec, Instruction* pc) JSGlobalData* globalData = &exec->globalData(); NativeCallFrameTracer tracer(globalData, exec); #if LLINT_SLOW_PATH_TRACING - dataLog("Throwing exception %s (returnToThrow).\n", globalData->exception.description()); + dataLogF("Throwing exception %s (returnToThrow).\n", globalData->exception.description()); #endif fixupPCforExceptionIfNeeded(exec); genericThrow(globalData, exec, globalData->exception, pc - exec->codeBlock()->instructions().begin()); @@ -82,7 +82,7 @@ void* callToThrow(ExecState* exec, Instruction* pc) JSGlobalData* globalData = &exec->globalData(); NativeCallFrameTracer tracer(globalData, exec); #if LLINT_SLOW_PATH_TRACING - dataLog("Throwing exception %s (callToThrow).\n", globalData->exception.description()); + dataLogF("Throwing exception %s (callToThrow).\n", globalData->exception.description()); #endif fixupPCforExceptionIfNeeded(exec); genericThrow(globalData, exec, globalData->exception, pc - exec->codeBlock()->instructions().begin()); diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp index ba44bf404..584100e50 100644 --- a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp +++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp @@ -162,7 +162,7 @@ namespace JSC { namespace LLInt { extern "C" SlowPathReturnType llint_trace_operand(ExecState* exec, Instruction* pc, int fromWhere, int operand) { LLINT_BEGIN(); - dataLog("%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d\n", + dataLogF("%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d\n", exec->codeBlock(), exec, static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()), @@ -184,7 +184,7 @@ extern "C" SlowPathReturnType llint_trace_value(ExecState* exec, Instruction* pc EncodedJSValue asValue; } u; u.asValue = JSValue::encode(value); - dataLog("%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d: %08x:%08x: %s\n", + dataLogF("%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d: %08x:%08x: %s\n", exec->codeBlock(), exec, static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()), @@ -200,7 +200,7 @@ extern "C" SlowPathReturnType llint_trace_value(ExecState* exec, Instruction* pc LLINT_SLOW_PATH_DECL(trace_prologue) { - dataLog("%p / %p: in prologue.\n", exec->codeBlock(), exec); + dataLogF("%p / %p: in prologue.\n", exec->codeBlock(), exec); LLINT_END_IMPL(); } @@ -209,7 +209,7 @@ static void traceFunctionPrologue(ExecState* exec, const char* comment, CodeSpec JSFunction* callee = jsCast<JSFunction*>(exec->callee()); FunctionExecutable* executable = callee->jsExecutable(); CodeBlock* codeBlock = &executable->generatedBytecodeFor(kind); - dataLog("%p / %p: in %s of function %p, executable %p; numVars = %u, numParameters = %u, numCalleeRegisters = %u, caller = %p.\n", + dataLogF("%p / %p: in %s of function %p, executable %p; numVars = %u, numParameters = %u, numCalleeRegisters = %u, caller = %p.\n", codeBlock, exec, comment, callee, executable, codeBlock->m_numVars, codeBlock->numParameters(), codeBlock->m_numCalleeRegisters, exec->callerFrame()); @@ -241,22 +241,22 @@ LLINT_SLOW_PATH_DECL(trace_arityCheck_for_construct) LLINT_SLOW_PATH_DECL(trace) { - dataLog("%p / %p: executing bc#%zu, %s, scope %p\n", + dataLogF("%p / %p: executing bc#%zu, %s, scope %p\n", exec->codeBlock(), exec, static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()), opcodeNames[exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode)], exec->scope()); if (exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode) == op_ret) { - dataLog("Will be returning to %p\n", exec->returnPC().value()); - dataLog("The new cfr will be %p\n", exec->callerFrame()); + dataLogF("Will be returning to %p\n", exec->returnPC().value()); + dataLogF("The new cfr will be %p\n", exec->callerFrame()); } LLINT_END_IMPL(); } LLINT_SLOW_PATH_DECL(special_trace) { - dataLog("%p / %p: executing special case bc#%zu, op#%u, return PC is %p\n", + dataLogF("%p / %p: executing special case bc#%zu, op#%u, return PC is %p\n", exec->codeBlock(), exec, static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()), @@ -275,11 +275,11 @@ inline bool shouldJIT(ExecState* exec) // Returns true if we should try to OSR. inline bool jitCompileAndSetHeuristics(CodeBlock* codeBlock, ExecState* exec) { - codeBlock->updateAllPredictions(); + codeBlock->updateAllValueProfilePredictions(); if (!codeBlock->checkIfJITThresholdReached()) { #if ENABLE(JIT_VERBOSE_OSR) - dataLog(" JIT threshold should be lifted.\n"); + dataLogF(" JIT threshold should be lifted.\n"); #endif return false; } @@ -288,19 +288,19 @@ inline bool jitCompileAndSetHeuristics(CodeBlock* codeBlock, ExecState* exec) switch (result) { case CodeBlock::AlreadyCompiled: #if ENABLE(JIT_VERBOSE_OSR) - dataLog(" Code was already compiled.\n"); + dataLogF(" Code was already compiled.\n"); #endif codeBlock->jitSoon(); return true; case CodeBlock::CouldNotCompile: #if ENABLE(JIT_VERBOSE_OSR) - dataLog(" JIT compilation failed.\n"); + dataLogF(" JIT compilation failed.\n"); #endif codeBlock->dontJITAnytimeSoon(); return false; case CodeBlock::CompiledSuccessfully: #if ENABLE(JIT_VERBOSE_OSR) - dataLog(" JIT compilation successful.\n"); + dataLogF(" JIT compilation successful.\n"); #endif codeBlock->jitSoon(); return true; @@ -313,7 +313,7 @@ enum EntryKind { Prologue, ArityCheck }; static SlowPathReturnType entryOSR(ExecState* exec, Instruction*, CodeBlock* codeBlock, const char *name, EntryKind kind) { #if ENABLE(JIT_VERBOSE_OSR) - dataLog("%p: Entered %s with executeCounter = %s\n", codeBlock, name, + dataLogF("%p: Entered %s with executeCounter = %s\n", codeBlock, name, codeBlock->llintExecuteCounter().status()); #else UNUSED_PARAM(name); @@ -362,7 +362,7 @@ LLINT_SLOW_PATH_DECL(loop_osr) CodeBlock* codeBlock = exec->codeBlock(); #if ENABLE(JIT_VERBOSE_OSR) - dataLog("%p: Entered loop_osr with executeCounter = %s\n", codeBlock, + dataLogF("%p: Entered loop_osr with executeCounter = %s\n", codeBlock, codeBlock->llintExecuteCounter().status()); #endif @@ -393,7 +393,7 @@ LLINT_SLOW_PATH_DECL(replace) CodeBlock* codeBlock = exec->codeBlock(); #if ENABLE(JIT_VERBOSE_OSR) - dataLog("%p: Entered replace with executeCounter = %s\n", codeBlock, + dataLogF("%p: Entered replace with executeCounter = %s\n", codeBlock, codeBlock->llintExecuteCounter().status()); #endif @@ -409,11 +409,11 @@ LLINT_SLOW_PATH_DECL(stack_check) { LLINT_BEGIN(); #if LLINT_SLOW_PATH_TRACING - dataLog("Checking stack height with exec = %p.\n", exec); - dataLog("CodeBlock = %p.\n", exec->codeBlock()); - dataLog("Num callee registers = %u.\n", exec->codeBlock()->m_numCalleeRegisters); - dataLog("Num vars = %u.\n", exec->codeBlock()->m_numVars); - dataLog("Current end is at %p.\n", exec->globalData().interpreter->stack().end()); + dataLogF("Checking stack height with exec = %p.\n", exec); + dataLogF("CodeBlock = %p.\n", exec->codeBlock()); + dataLogF("Num callee registers = %u.\n", exec->codeBlock()->m_numCalleeRegisters); + dataLogF("Num vars = %u.\n", exec->codeBlock()->m_numVars); + dataLogF("Current end is at %p.\n", exec->globalData().interpreter->stack().end()); #endif ASSERT(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters] > exec->globalData().interpreter->stack().end()); if (UNLIKELY(!globalData.interpreter->stack().grow(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters]))) { @@ -458,7 +458,7 @@ LLINT_SLOW_PATH_DECL(slow_path_create_activation) { LLINT_BEGIN(); #if LLINT_SLOW_PATH_TRACING - dataLog("Creating an activation, exec = %p!\n", exec); + dataLogF("Creating an activation, exec = %p!\n", exec); #endif JSActivation* activation = JSActivation::create(globalData, exec, exec->codeBlock()); exec->setScope(activation); @@ -478,7 +478,7 @@ LLINT_SLOW_PATH_DECL(slow_path_create_arguments) LLINT_SLOW_PATH_DECL(slow_path_create_this) { LLINT_BEGIN(); - JSFunction* constructor = jsCast<JSFunction*>(exec->callee()); + JSFunction* constructor = jsCast<JSFunction*>(LLINT_OP(2).jsValue().asCell()); #if !ASSERT_DISABLED ConstructData constructData; @@ -510,19 +510,19 @@ LLINT_SLOW_PATH_DECL(slow_path_new_object) LLINT_SLOW_PATH_DECL(slow_path_new_array) { LLINT_BEGIN(); - LLINT_RETURN(constructArray(exec, bitwise_cast<JSValue*>(&LLINT_OP(2)), pc[3].u.operand)); + LLINT_RETURN(constructArray(exec, pc[4].u.arrayAllocationProfile, bitwise_cast<JSValue*>(&LLINT_OP(2)), pc[3].u.operand)); } LLINT_SLOW_PATH_DECL(slow_path_new_array_with_size) { LLINT_BEGIN(); - LLINT_RETURN(constructArrayWithSizeQuirk(exec, exec->lexicalGlobalObject(), LLINT_OP_C(2).jsValue())); + LLINT_RETURN(constructArrayWithSizeQuirk(exec, pc[3].u.arrayAllocationProfile, exec->lexicalGlobalObject(), LLINT_OP_C(2).jsValue())); } LLINT_SLOW_PATH_DECL(slow_path_new_array_buffer) { LLINT_BEGIN(); - LLINT_RETURN(constructArray(exec, exec->codeBlock()->constantBuffer(pc[2].u.operand), pc[3].u.operand)); + LLINT_RETURN(constructArray(exec, pc[4].u.arrayAllocationProfile, exec->codeBlock()->constantBuffer(pc[2].u.operand), pc[3].u.operand)); } LLINT_SLOW_PATH_DECL(slow_path_new_regexp) @@ -635,8 +635,8 @@ LLINT_SLOW_PATH_DECL(slow_path_add) JSValue v2 = LLINT_OP_C(3).jsValue(); #if LLINT_SLOW_PATH_TRACING - dataLog("Trying to add %s", v1.description()); - dataLog(" to %s.\n", v2.description()); + dataLogF("Trying to add %s", v1.description()); + dataLogF(" to %s.\n", v2.description()); #endif if (v1.isString() && !v2.isObject()) @@ -1328,7 +1328,7 @@ LLINT_SLOW_PATH_DECL(slow_path_new_func) || !codeBlock->needsFullScopeChain() || exec->uncheckedR(codeBlock->activationRegister()).jsValue()); #if LLINT_SLOW_PATH_TRACING - dataLog("Creating function!\n"); + dataLogF("Creating function!\n"); #endif LLINT_RETURN(JSFunction::create(exec, codeBlock->functionDecl(pc[2].u.operand), exec->scope())); } @@ -1367,7 +1367,7 @@ static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc, } #if LLINT_SLOW_PATH_TRACING - dataLog("Call callee is not a function: %s\n", callee.description()); + dataLogF("Call callee is not a function: %s\n", callee.description()); #endif ASSERT(callType == CallTypeNone); @@ -1390,7 +1390,7 @@ static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc, } #if LLINT_SLOW_PATH_TRACING - dataLog("Constructor callee is not a function: %s\n", callee.description()); + dataLogF("Constructor callee is not a function: %s\n", callee.description()); #endif ASSERT(constructType == ConstructTypeNone); @@ -1400,7 +1400,7 @@ static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc, inline SlowPathReturnType setUpCall(ExecState* execCallee, Instruction* pc, CodeSpecializationKind kind, JSValue calleeAsValue, LLIntCallLinkInfo* callLinkInfo = 0) { #if LLINT_SLOW_PATH_TRACING - dataLog("Performing call with recorded PC = %p\n", execCallee->callerFrame()->currentVPC()); + dataLogF("Performing call with recorded PC = %p\n", execCallee->callerFrame()->currentVPC()); #endif JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue); diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm index ba5b67df4..00d5c4f6f 100644 --- a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm +++ b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm @@ -88,10 +88,13 @@ else end # Constant for reasoning about butterflies. -const IsArray = 1 -const IndexingShapeMask = 30 -const ContiguousShape = 26 -const ArrayStorageShape = 28 +const IsArray = 1 +const IndexingShapeMask = 30 +const NoIndexingShape = 0 +const Int32Shape = 20 +const DoubleShape = 22 +const ContiguousShape = 26 +const ArrayStorageShape = 28 const SlowPutArrayStorageShape = 30 # Type constants. @@ -462,19 +465,19 @@ end _llint_op_new_array: traceExecution() callSlowPath(_llint_slow_path_new_array) - dispatch(4) + dispatch(5) _llint_op_new_array_with_size: traceExecution() callSlowPath(_llint_slow_path_new_array_with_size) - dispatch(3) + dispatch(4) _llint_op_new_array_buffer: traceExecution() callSlowPath(_llint_slow_path_new_array_buffer) - dispatch(4) + dispatch(5) _llint_op_new_regexp: diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm index ffb146247..8d5cdf108 100644 --- a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm +++ b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm @@ -349,18 +349,30 @@ _llint_op_create_arguments: _llint_op_create_this: traceExecution() - loadp Callee[cfr], t0 + loadi 8[PC], t0 + loadp PayloadOffset[cfr, t0, 8], t0 loadp JSFunction::m_cachedInheritorID[t0], t2 btpz t2, .opCreateThisSlow allocateBasicJSObject(JSFinalObjectSizeClassIndex, t2, t0, t1, t3, .opCreateThisSlow) loadi 4[PC], t1 storei CellTag, TagOffset[cfr, t1, 8] storei t0, PayloadOffset[cfr, t1, 8] - dispatch(2) + dispatch(3) .opCreateThisSlow: callSlowPath(_llint_slow_path_create_this) - dispatch(2) + dispatch(3) + + +_llint_op_get_callee: + traceExecution() + loadi 4[PC], t0 + loadp PayloadOffset + Callee[cfr], t1 + loadp 8[PC], t2 + valueProfile(CellTag, t1, t2) + storei CellTag, TagOffset[cfr, t0, 8] + storei t1, PayloadOffset[cfr, t0, 8] + dispatch(3) _llint_op_convert_this: @@ -1185,7 +1197,9 @@ _llint_op_get_by_val: loadConstantOrVariablePayload(t3, Int32Tag, t1, .opGetByValSlow) loadp JSObject::m_butterfly[t0], t3 andi IndexingShapeMask, t2 + bieq t2, Int32Shape, .opGetByValIsContiguous bineq t2, ContiguousShape, .opGetByValNotContiguous +.opGetByValIsContiguous: biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t3], .opGetByValSlow loadi TagOffset[t3, t1, 8], t2 @@ -1193,6 +1207,16 @@ _llint_op_get_by_val: jmp .opGetByValDone .opGetByValNotContiguous: + bineq t2, DoubleShape, .opGetByValNotDouble + biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t3], .opGetByValSlow + loadd [t3, t1, 8], ft0 + bdnequn ft0, ft0, .opGetByValSlow + # FIXME: This could be massively optimized. + fd2ii ft0, t1, t2 + loadi 4[PC], t0 + jmp .opGetByValNotEmpty + +.opGetByValNotDouble: subi ArrayStorageShape, t2 bia t2, SlowPutArrayStorageShape - ArrayStorageShape, .opGetByValSlow biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t3], .opGetByValSlow @@ -1202,6 +1226,7 @@ _llint_op_get_by_val: .opGetByValDone: loadi 4[PC], t0 bieq t2, EmptyValueTag, .opGetByValSlow +.opGetByValNotEmpty: storei t2, TagOffset[cfr, t0, 8] storei t1, PayloadOffset[cfr, t0, 8] loadi 20[PC], t0 @@ -1270,6 +1295,24 @@ _llint_op_get_by_pname: dispatch(7) +macro contiguousPutByVal(storeCallback) + biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .outOfBounds +.storeResult: + loadi 12[PC], t2 + storeCallback(t2, t1, t0, t3) + dispatch(5) + +.outOfBounds: + biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow + if VALUE_PROFILER + loadp 16[PC], t2 + storeb 1, ArrayProfile::m_mayStoreToHole[t2] + end + addi 1, t3, t2 + storei t2, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0] + jmp .storeResult +end + _llint_op_put_by_val: traceExecution() loadi 4[PC], t0 @@ -1281,26 +1324,42 @@ _llint_op_put_by_val: loadConstantOrVariablePayload(t0, Int32Tag, t3, .opPutByValSlow) loadp JSObject::m_butterfly[t1], t0 andi IndexingShapeMask, t2 - bineq t2, ContiguousShape, .opPutByValNotContiguous + bineq t2, Int32Shape, .opPutByValNotInt32 + contiguousPutByVal( + macro (operand, scratch, base, index) + loadConstantOrVariablePayload(operand, Int32Tag, scratch, .opPutByValSlow) + storei Int32Tag, TagOffset[base, index, 8] + storei scratch, PayloadOffset[base, index, 8] + end) - biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .opPutByValContiguousOutOfBounds -.opPutByValContiguousStoreResult: - loadi 12[PC], t2 - loadConstantOrVariable2Reg(t2, t1, t2) - writeBarrier(t1, t2) - storei t1, TagOffset[t0, t3, 8] - storei t2, PayloadOffset[t0, t3, 8] - dispatch(5) +.opPutByValNotInt32: + bineq t2, DoubleShape, .opPutByValNotDouble + contiguousPutByVal( + macro (operand, scratch, base, index) + const tag = scratch + const payload = operand + loadConstantOrVariable2Reg(operand, tag, payload) + bineq tag, Int32Tag, .notInt + ci2d payload, ft0 + jmp .ready + .notInt: + fii2d payload, tag, ft0 + bdnequn ft0, ft0, .opPutByValSlow + .ready: + stored ft0, [base, index, 8] + end) -.opPutByValContiguousOutOfBounds: - biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow - if VALUE_PROFILER - loadp 16[PC], t1 - storeb 1, ArrayProfile::m_mayStoreToHole[t1] - end - addi 1, t3, t2 - storei t2, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0] - jmp .opPutByValContiguousStoreResult +.opPutByValNotDouble: + bineq t2, ContiguousShape, .opPutByValNotContiguous + contiguousPutByVal( + macro (operand, scratch, base, index) + const tag = scratch + const payload = operand + loadConstantOrVariable2Reg(operand, tag, payload) + writeBarrier(tag, payload) + storei tag, TagOffset[base, index, 8] + storei payload, PayloadOffset[base, index, 8] + end) .opPutByValNotContiguous: bineq t2, ArrayStorageShape, .opPutByValSlow diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm index c9900b343..ed6799ef3 100644 --- a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm +++ b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm @@ -241,17 +241,28 @@ _llint_op_create_arguments: _llint_op_create_this: traceExecution() - loadp Callee[cfr], t0 + loadisFromInstruction(2, t0) + loadp [cfr, t0, 8], t0 loadp JSFunction::m_cachedInheritorID[t0], t2 btpz t2, .opCreateThisSlow allocateBasicJSObject(JSFinalObjectSizeClassIndex, t2, t0, t1, t3, .opCreateThisSlow) loadisFromInstruction(1, t1) storeq t0, [cfr, t1, 8] - dispatch(2) + dispatch(3) .opCreateThisSlow: callSlowPath(_llint_slow_path_create_this) - dispatch(2) + dispatch(3) + + +_llint_op_get_callee: + traceExecution() + loadisFromInstruction(1, t0) + loadpFromInstruction(2, t2) + loadp Callee[cfr], t1 + valueProfile(t1, t2) + storep t1, [cfr, t0, 8] + dispatch(3) _llint_op_convert_this: @@ -1025,7 +1036,9 @@ _llint_op_get_by_val: sxi2q t1, t1 loadp JSObject::m_butterfly[t0], t3 andi IndexingShapeMask, t2 + bieq t2, Int32Shape, .opGetByValIsContiguous bineq t2, ContiguousShape, .opGetByValNotContiguous +.opGetByValIsContiguous: biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t3], .opGetByValSlow loadisFromInstruction(1, t0) @@ -1034,6 +1047,16 @@ _llint_op_get_by_val: jmp .opGetByValDone .opGetByValNotContiguous: + bineq t2, DoubleShape, .opGetByValNotDouble + biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t3], .opGetByValSlow + loadis 8[PB, PC, 8], t0 + loadd [t3, t1, 8], ft0 + bdnequn ft0, ft0, .opGetByValSlow + fd2q ft0, t2 + subq tagTypeNumber, t2 + jmp .opGetByValDone + +.opGetByValNotDouble: subi ArrayStorageShape, t2 bia t2, SlowPutArrayStorageShape - ArrayStorageShape, .opGetByValSlow biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t3], .opGetByValSlow @@ -1109,6 +1132,24 @@ _llint_op_get_by_pname: dispatch(7) +macro contiguousPutByVal(storeCallback) + biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .outOfBounds +.storeResult: + loadisFromInstruction(3, t2) + storeCallback(t2, t1, [t0, t3, 8]) + dispatch(5) + +.outOfBounds: + biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow + if VALUE_PROFILER + loadp 32[PB, PC, 8], t2 + storeb 1, ArrayProfile::m_mayStoreToHole[t2] + end + addi 1, t3, t2 + storei t2, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0] + jmp .storeResult +end + _llint_op_put_by_val: traceExecution() loadisFromInstruction(1, t0) @@ -1121,25 +1162,38 @@ _llint_op_put_by_val: sxi2q t3, t3 loadp JSObject::m_butterfly[t1], t0 andi IndexingShapeMask, t2 - bineq t2, ContiguousShape, .opPutByValNotContiguous - - biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .opPutByValContiguousOutOfBounds -.opPutByValContiguousStoreResult: - loadisFromInstruction(3, t2) - loadConstantOrVariable(t2, t1) - writeBarrier(t1) - storeq t1, [t0, t3, 8] - dispatch(5) + bineq t2, Int32Shape, .opPutByValNotInt32 + contiguousPutByVal( + macro (operand, scratch, address) + loadConstantOrVariable(operand, scratch) + bpb scratch, tagTypeNumber, .opPutByValSlow + storep scratch, address + end) -.opPutByValContiguousOutOfBounds: - biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow - if VALUE_PROFILER - loadpFromInstruction(4, t2) - storeb 1, ArrayProfile::m_mayStoreToHole[t2] - end - addi 1, t3, t2 - storei t2, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0] - jmp .opPutByValContiguousStoreResult +.opPutByValNotInt32: + bineq t2, DoubleShape, .opPutByValNotDouble + contiguousPutByVal( + macro (operand, scratch, address) + loadConstantOrVariable(operand, scratch) + bqb scratch, tagTypeNumber, .notInt + ci2d scratch, ft0 + jmp .ready + .notInt: + addp tagTypeNumber, scratch + fq2d scratch, ft0 + bdnequn ft0, ft0, .opPutByValSlow + .ready: + stored ft0, address + end) + +.opPutByValNotDouble: + bineq t2, ContiguousShape, .opPutByValNotContiguous + contiguousPutByVal( + macro (operand, scratch, address) + loadConstantOrVariable(operand, scratch) + writeBarrier(scratch) + storep scratch, address + end) .opPutByValNotContiguous: bineq t2, ArrayStorageShape, .opPutByValSlow |