summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/llint
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2012-11-22 09:09:45 +0100
committerSimon Hausmann <simon.hausmann@digia.com>2012-11-22 09:10:13 +0100
commit470286ecfe79d59df14944e5b5d34630fc739391 (patch)
tree43983212872e06cebefd2ae474418fa2908ca54c /Source/JavaScriptCore/llint
parent23037105e948c2065da5a937d3a2396b0ff45c1e (diff)
downloadqtwebkit-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.cpp16
-rw-r--r--Source/JavaScriptCore/llint/LLIntExceptions.cpp6
-rw-r--r--Source/JavaScriptCore/llint/LLIntSlowPaths.cpp64
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter.asm17
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm101
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter64.asm96
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