summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/llint
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2012-10-15 16:08:57 +0200
committerSimon Hausmann <simon.hausmann@digia.com>2012-10-15 16:08:57 +0200
commit5466563f4b5b6b86523e3f89bb7f77e5b5270c78 (patch)
tree8caccf7cd03a15207cde3ba282c88bf132482a91 /Source/JavaScriptCore/llint
parent33b26980cb24288b5a9f2590ccf32a949281bb79 (diff)
downloadqtwebkit-5466563f4b5b6b86523e3f89bb7f77e5b5270c78.tar.gz
Imported WebKit commit 0dc6cd75e1d4836eaffbb520be96fac4847cc9d2 (http://svn.webkit.org/repository/webkit/trunk@131300)
WebKit update which introduces the QtWebKitWidgets module that contains the WK1 widgets based API. (In fact it renames QtWebKit to QtWebKitWidgets while we're working on completing the entire split as part of https://bugs.webkit.org/show_bug.cgi?id=99314
Diffstat (limited to 'Source/JavaScriptCore/llint')
-rw-r--r--Source/JavaScriptCore/llint/LLIntData.cpp20
-rw-r--r--Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h7
-rw-r--r--Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp2
-rw-r--r--Source/JavaScriptCore/llint/LLIntSlowPaths.cpp20
-rw-r--r--Source/JavaScriptCore/llint/LLIntSlowPaths.h2
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter.asm31
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm96
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter64.asm92
8 files changed, 183 insertions, 87 deletions
diff --git a/Source/JavaScriptCore/llint/LLIntData.cpp b/Source/JavaScriptCore/llint/LLIntData.cpp
index c7fd741d6..8e2dacf4d 100644
--- a/Source/JavaScriptCore/llint/LLIntData.cpp
+++ b/Source/JavaScriptCore/llint/LLIntData.cpp
@@ -68,14 +68,14 @@ void Data::performAssertions(JSGlobalData& globalData)
// Assertions to match LowLevelInterpreter.asm. If you change any of this code, be
// prepared to change LowLevelInterpreter.asm as well!!
- ASSERT(RegisterFile::CallFrameHeaderSize * 8 == 48);
- ASSERT(RegisterFile::ArgumentCount * 8 == -48);
- ASSERT(RegisterFile::CallerFrame * 8 == -40);
- ASSERT(RegisterFile::Callee * 8 == -32);
- ASSERT(RegisterFile::ScopeChain * 8 == -24);
- ASSERT(RegisterFile::ReturnPC * 8 == -16);
- ASSERT(RegisterFile::CodeBlock * 8 == -8);
- ASSERT(CallFrame::argumentOffsetIncludingThis(0) == -RegisterFile::CallFrameHeaderSize - 1);
+ ASSERT(JSStack::CallFrameHeaderSize * 8 == 48);
+ ASSERT(JSStack::ArgumentCount * 8 == -48);
+ ASSERT(JSStack::CallerFrame * 8 == -40);
+ ASSERT(JSStack::Callee * 8 == -32);
+ ASSERT(JSStack::ScopeChain * 8 == -24);
+ ASSERT(JSStack::ReturnPC * 8 == -16);
+ ASSERT(JSStack::CodeBlock * 8 == -8);
+ ASSERT(CallFrame::argumentOffsetIncludingThis(0) == -JSStack::CallFrameHeaderSize - 1);
#if CPU(BIG_ENDIAN)
ASSERT(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag) == 0);
ASSERT(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload) == 4);
@@ -108,9 +108,9 @@ void Data::performAssertions(JSGlobalData& globalData)
ASSERT(ImplementsHasInstance == 2);
ASSERT(ImplementsDefaultHasInstance == 8);
#if USE(JSVALUE64)
- ASSERT(&globalData.heap.allocatorForObjectWithoutDestructor(sizeof(JSFinalObject)) - &globalData.heap.firstAllocatorWithoutDestructors() == 1);
+ ASSERT(&globalData.heap.allocatorForObjectWithoutDestructor(JSObject::allocationSize(INLINE_STORAGE_CAPACITY)) - &globalData.heap.firstAllocatorWithoutDestructors() == 1);
#else
- ASSERT(&globalData.heap.allocatorForObjectWithoutDestructor(sizeof(JSFinalObject)) - &globalData.heap.firstAllocatorWithoutDestructors() == 3);
+ ASSERT(&globalData.heap.allocatorForObjectWithoutDestructor(JSObject::allocationSize(INLINE_STORAGE_CAPACITY)) - &globalData.heap.firstAllocatorWithoutDestructors() == 3);
#endif
ASSERT(FirstConstantRegisterIndex == 0x40000000);
ASSERT(GlobalCode == 0);
diff --git a/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h b/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h
index 63488aa0b..da2d510b5 100644
--- a/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h
+++ b/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h
@@ -37,6 +37,7 @@
#define OFFLINE_ASM_X86 0
#define OFFLINE_ASM_ARMv7 0
#define OFFLINE_ASM_X86_64 0
+#define OFFLINE_ASM_ARMv7s 0
#else // !ENABLE(LLINT_C_LOOP)
@@ -48,6 +49,12 @@
#define OFFLINE_ASM_X86 0
#endif
+#ifdef __ARM_ARCH_7S__
+#define OFFLINE_ASM_ARMv7s 1
+#else
+#define OFFLINE_ASM_ARMv7s 0
+#endif
+
#if CPU(ARM_THUMB2)
#define OFFLINE_ASM_ARMv7 1
#else
diff --git a/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp b/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp
index 3ed6d6d2f..cbfff29d6 100644
--- a/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp
+++ b/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp
@@ -38,13 +38,13 @@
#include "JSGlobalObject.h"
#include "JSObject.h"
#include "JSPropertyNameIterator.h"
+#include "JSStack.h"
#include "JSString.h"
#include "JSTypeInfo.h"
#include "JSVariableObject.h"
#include "JumpTable.h"
#include "LLIntOfflineAsmConfig.h"
#include "MarkedSpace.h"
-#include "RegisterFile.h"
#include "Structure.h"
#include "StructureChain.h"
diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
index f9833e4ce..5a9b41da7 100644
--- a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
+++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
@@ -396,7 +396,7 @@ LLINT_SLOW_PATH_DECL(replace)
}
#endif // ENABLE(JIT)
-LLINT_SLOW_PATH_DECL(register_file_check)
+LLINT_SLOW_PATH_DECL(stack_check)
{
LLINT_BEGIN();
#if LLINT_SLOW_PATH_TRACING
@@ -404,10 +404,10 @@ LLINT_SLOW_PATH_DECL(register_file_check)
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->registerFile().end());
+ dataLog("Current end is at %p.\n", exec->globalData().interpreter->stack().end());
#endif
- ASSERT(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters] > exec->globalData().interpreter->registerFile().end());
- if (UNLIKELY(!globalData.interpreter->registerFile().grow(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters]))) {
+ ASSERT(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters] > exec->globalData().interpreter->stack().end());
+ if (UNLIKELY(!globalData.interpreter->stack().grow(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters]))) {
ReturnAddressPtr returnPC = exec->returnPC();
exec = exec->callerFrame();
globalData.exception = createStackOverflowError(exec);
@@ -420,7 +420,7 @@ LLINT_SLOW_PATH_DECL(register_file_check)
LLINT_SLOW_PATH_DECL(slow_path_call_arityCheck)
{
LLINT_BEGIN();
- ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &globalData.interpreter->registerFile(), CodeForCall);
+ ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &globalData.interpreter->stack(), CodeForCall);
if (!newExec) {
ReturnAddressPtr returnPC = exec->returnPC();
exec = exec->callerFrame();
@@ -434,7 +434,7 @@ LLINT_SLOW_PATH_DECL(slow_path_call_arityCheck)
LLINT_SLOW_PATH_DECL(slow_path_construct_arityCheck)
{
LLINT_BEGIN();
- ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &globalData.interpreter->registerFile(), CodeForConstruct);
+ ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &globalData.interpreter->stack(), CodeForConstruct);
if (!newExec) {
ReturnAddressPtr returnPC = exec->returnPC();
exec = exec->callerFrame();
@@ -1408,7 +1408,7 @@ inline SlowPathReturnType genericCall(ExecState* exec, Instruction* pc, CodeSpec
ExecState* execCallee = exec + pc[3].u.operand;
execCallee->setArgumentCountIncludingThis(pc[2].u.operand);
- execCallee->uncheckedR(RegisterFile::Callee) = calleeAsValue;
+ execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
execCallee->setCallerFrame(exec);
ASSERT(pc[4].u.callLinkInfo);
@@ -1438,11 +1438,11 @@ LLINT_SLOW_PATH_DECL(slow_path_call_varargs)
JSValue calleeAsValue = LLINT_OP_C(1).jsValue();
ExecState* execCallee = loadVarargs(
- exec, &globalData.interpreter->registerFile(),
+ exec, &globalData.interpreter->stack(),
LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue(), pc[4].u.operand);
LLINT_CALL_CHECK_EXCEPTION(exec, pc);
- execCallee->uncheckedR(RegisterFile::Callee) = calleeAsValue;
+ execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
execCallee->setCallerFrame(exec);
exec->setCurrentVPC(pc + OPCODE_LENGTH(op_call_varargs));
@@ -1458,7 +1458,7 @@ LLINT_SLOW_PATH_DECL(slow_path_call_eval)
execCallee->setArgumentCountIncludingThis(pc[2].u.operand);
execCallee->setCallerFrame(exec);
- execCallee->uncheckedR(RegisterFile::Callee) = calleeAsValue;
+ execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
execCallee->setScope(exec->scope());
execCallee->setReturnPC(LLInt::getCodePtr(llint_generic_return_point));
execCallee->setCodeBlock(0);
diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.h b/Source/JavaScriptCore/llint/LLIntSlowPaths.h
index fe897d4a4..5bfb0ccdf 100644
--- a/Source/JavaScriptCore/llint/LLIntSlowPaths.h
+++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.h
@@ -112,7 +112,7 @@ LLINT_SLOW_PATH_HIDDEN_DECL(entry_osr_function_for_call_arityCheck);
LLINT_SLOW_PATH_HIDDEN_DECL(entry_osr_function_for_construct_arityCheck);
LLINT_SLOW_PATH_HIDDEN_DECL(loop_osr);
LLINT_SLOW_PATH_HIDDEN_DECL(replace);
-LLINT_SLOW_PATH_HIDDEN_DECL(register_file_check);
+LLINT_SLOW_PATH_HIDDEN_DECL(stack_check);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_call_arityCheck);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_construct_arityCheck);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_create_activation);
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
index e347ccc70..a971abf4f 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
@@ -24,7 +24,13 @@
# First come the common protocols that both interpreters use. Note that each
# of these must have an ASSERT() in LLIntData.cpp
-# These declarations must match interpreter/RegisterFile.h.
+# Work-around for the fact that the toolchain's awareness of armv7s results in
+# a separate slab in the fat binary, yet the offlineasm doesn't know to expect
+# it.
+if ARMv7s
+end
+
+# These declarations must match interpreter/JSStack.h.
const CallFrameHeaderSize = 48
const ArgumentCount = -48
const CallerFrame = -40
@@ -38,7 +44,7 @@ const ThisArgumentOffset = -CallFrameHeaderSize - 8
# Some register conventions.
if JSVALUE64
# - Use a pair of registers to represent the PC: one register for the
- # base of the register file, and one register for the index.
+ # base of the stack, and one register for the index.
# - The PC base (or PB for short) should be stored in the csr. It will
# get clobbered on calls to other JS code, but will get saved on calls
# to C functions.
@@ -63,8 +69,10 @@ end
# Constant for reasoning about butterflies.
const IsArray = 1
-const HasArrayStorage = 8
-const AllArrayTypes = 15
+const IndexingShapeMask = 30
+const ContiguousShape = 26
+const ArrayStorageShape = 28
+const SlowPutArrayStorageShape = 30
# Type constants.
const StringType = 5
@@ -89,12 +97,8 @@ const LLIntReturnPC = ArgumentCount + TagOffset
# String flags.
const HashFlags8BitBuffer = 64
-# Property storage constants
-if JSVALUE64
- const InlineStorageCapacity = 6
-else
- const InlineStorageCapacity = 7
-end
+# Copied from PropertyOffset.h
+const firstOutOfLineOffset = 100
# Allocation constants
if JSVALUE64
@@ -319,13 +323,13 @@ macro functionInitialization(profileArgSkip)
# Check stack height.
loadi CodeBlock::m_numCalleeRegisters[t1], t0
loadp CodeBlock::m_globalData[t1], t2
- loadp JSGlobalData::interpreter[t2], t2 # FIXME: Can get to the RegisterFile from the JITStackFrame
+ loadp JSGlobalData::interpreter[t2], t2 # FIXME: Can get to the JSStack from the JITStackFrame
lshifti 3, t0
addp t0, cfr, t0
- bpaeq Interpreter::m_registerFile + RegisterFile::m_end[t2], t0, .stackHeightOK
+ bpaeq Interpreter::m_stack + JSStack::m_end[t2], t0, .stackHeightOK
# Stack height check failed - need to call a slow_path.
- callSlowPath(_llint_register_file_check)
+ callSlowPath(_llint_stack_check)
.stackHeightOK:
end
@@ -910,3 +914,4 @@ _llint_op_put_by_id_transition:
# Indicate the end of LLInt.
_llint_end:
crash()
+
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
index 83abf380c..f0d45eb0e 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
@@ -937,24 +937,24 @@ _llint_op_is_string:
dispatch(3)
-macro loadPropertyAtVariableOffsetKnownNotFinal(propertyOffset, objectAndStorage, tag, payload)
- assert(macro (ok) bigteq propertyOffset, InlineStorageCapacity, ok end)
+macro loadPropertyAtVariableOffsetKnownNotInline(propertyOffset, objectAndStorage, tag, payload)
+ assert(macro (ok) bigteq propertyOffset, firstOutOfLineOffset, ok end)
negi propertyOffset
loadp JSObject::m_butterfly[objectAndStorage], objectAndStorage
- loadi TagOffset + (InlineStorageCapacity - 1) * 8 - sizeof IndexingHeader[objectAndStorage, propertyOffset, 8], tag
- loadi PayloadOffset + (InlineStorageCapacity - 1) * 8 - sizeof IndexingHeader[objectAndStorage, propertyOffset, 8], payload
+ loadi TagOffset + (firstOutOfLineOffset - 2) * 8[objectAndStorage, propertyOffset, 8], tag
+ loadi PayloadOffset + (firstOutOfLineOffset - 2) * 8[objectAndStorage, propertyOffset, 8], payload
end
macro loadPropertyAtVariableOffset(propertyOffset, objectAndStorage, tag, payload)
- bilt propertyOffset, InlineStorageCapacity, .isInline
+ bilt propertyOffset, firstOutOfLineOffset, .isInline
loadp JSObject::m_butterfly[objectAndStorage], objectAndStorage
negi propertyOffset
jmp .ready
.isInline:
- addp JSFinalObject::m_inlineStorage - (InlineStorageCapacity - 1) * 8 + sizeof IndexingHeader, objectAndStorage
+ addp sizeof JSObject - (firstOutOfLineOffset - 2) * 8, objectAndStorage
.ready:
- loadi TagOffset + (InlineStorageCapacity - 1) * 8 - sizeof IndexingHeader[objectAndStorage, propertyOffset, 8], tag
- loadi PayloadOffset + (InlineStorageCapacity - 1) * 8 - sizeof IndexingHeader[objectAndStorage, propertyOffset, 8], payload
+ loadi TagOffset + (firstOutOfLineOffset - 2) * 8[objectAndStorage, propertyOffset, 8], tag
+ loadi PayloadOffset + (firstOutOfLineOffset - 2) * 8[objectAndStorage, propertyOffset, 8], payload
end
macro resolveGlobal(size, slow)
@@ -968,7 +968,7 @@ macro resolveGlobal(size, slow)
loadp JSCell::m_structure[t0], t1
bpneq t1, 12[PC], slow
loadi 16[PC], t1
- loadPropertyAtVariableOffsetKnownNotFinal(t1, t0, t2, t3)
+ loadPropertyAtVariableOffsetKnownNotInline(t1, t0, t2, t3)
loadi 4[PC], t0
storei t2, TagOffset[cfr, t0, 8]
storei t3, PayloadOffset[cfr, t0, 8]
@@ -1171,7 +1171,7 @@ _llint_op_get_array_length:
loadp JSCell::m_structure[t3], t2
arrayProfile(t2, t1, t0)
btiz t2, IsArray, .opGetArrayLengthSlow
- btiz t2, HasArrayStorage, .opGetArrayLengthSlow
+ btiz t2, IndexingShapeMask, .opGetArrayLengthSlow
loadi 4[PC], t1
loadp 32[PC], t2
loadp JSObject::m_butterfly[t3], t0
@@ -1302,14 +1302,26 @@ _llint_op_get_by_val:
loadp JSCell::m_structure[t0], t2
loadp 16[PC], t3
arrayProfile(t2, t3, t1)
- btiz t2, HasArrayStorage, .opGetByValSlow
loadi 12[PC], t3
loadConstantOrVariablePayload(t3, Int32Tag, t1, .opGetByValSlow)
loadp JSObject::m_butterfly[t0], t3
+ andi IndexingShapeMask, t2
+ bineq t2, ContiguousShape, .opGetByValNotContiguous
+
+ biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t3], .opGetByValSlow
+ loadi TagOffset[t3, t1, 8], t2
+ loadi PayloadOffset[t3, t1, 8], t1
+ jmp .opGetByValDone
+
+.opGetByValNotContiguous:
+ subi ArrayStorageShape, t2
+ bia t2, SlowPutArrayStorageShape - ArrayStorageShape, .opGetByValSlow
biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t3], .opGetByValSlow
- loadi 4[PC], t0
loadi ArrayStorage::m_vector + TagOffset[t3, t1, 8], t2
loadi ArrayStorage::m_vector + PayloadOffset[t3, t1, 8], t1
+
+.opGetByValDone:
+ loadi 4[PC], t0
bieq t2, EmptyValueTag, .opGetByValSlow
storei t2, TagOffset[cfr, t0, 8]
storei t1, PayloadOffset[cfr, t0, 8]
@@ -1364,7 +1376,10 @@ _llint_op_get_by_pname:
loadi [cfr, t0, 8], t0
subi 1, t0
biaeq t0, JSPropertyNameIterator::m_numCacheableSlots[t3], .opGetByPnameSlow
- addi JSPropertyNameIterator::m_offsetBase[t3], t0
+ bilt t0, JSPropertyNameIterator::m_cachedStructureInlineCapacity[t3], .opGetByPnameInlineProperty
+ addi firstOutOfLineOffset, t0
+ subi JSPropertyNameIterator::m_cachedStructureInlineCapacity[t3], t0
+.opGetByPnameInlineProperty:
loadPropertyAtVariableOffset(t0, t2, t1, t3)
loadi 4[PC], t0
storei t1, TagOffset[cfr, t0, 8]
@@ -1383,29 +1398,53 @@ _llint_op_put_by_val:
loadp JSCell::m_structure[t1], t2
loadp 16[PC], t3
arrayProfile(t2, t3, t0)
- btiz t2, HasArrayStorage, .opPutByValSlow
loadi 8[PC], t0
- loadConstantOrVariablePayload(t0, Int32Tag, t2, .opPutByValSlow)
+ loadConstantOrVariablePayload(t0, Int32Tag, t3, .opPutByValSlow)
loadp JSObject::m_butterfly[t1], t0
- biaeq t2, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow
- bieq ArrayStorage::m_vector + TagOffset[t0, t2, 8], EmptyValueTag, .opPutByValEmpty
-.opPutByValStoreResult:
- loadi 12[PC], t3
- loadConstantOrVariable2Reg(t3, t1, t3)
- writeBarrier(t1, t3)
- storei t1, ArrayStorage::m_vector + TagOffset[t0, t2, 8]
- storei t3, ArrayStorage::m_vector + PayloadOffset[t0, t2, 8]
+ andi IndexingShapeMask, t2
+ bineq t2, ContiguousShape, .opPutByValNotContiguous
+
+ 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)
-.opPutByValEmpty:
+.opPutByValContiguousOutOfBounds:
+ biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow
if VALUE_PROFILER
- storeb 1, ArrayProfile::m_mayStoreToHole[t3]
+ 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
+
+.opPutByValNotContiguous:
+ bineq t2, ArrayStorageShape, .opPutByValSlow
+ biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow
+ bieq ArrayStorage::m_vector + TagOffset[t0, t3, 8], EmptyValueTag, .opPutByValArrayStorageEmpty
+.opPutByValArrayStorageStoreResult:
+ loadi 12[PC], t2
+ loadConstantOrVariable2Reg(t2, t1, t2)
+ writeBarrier(t1, t2)
+ storei t1, ArrayStorage::m_vector + TagOffset[t0, t3, 8]
+ storei t2, ArrayStorage::m_vector + PayloadOffset[t0, t3, 8]
+ dispatch(5)
+
+.opPutByValArrayStorageEmpty:
+ if VALUE_PROFILER
+ loadp 16[PC], t1
+ storeb 1, ArrayProfile::m_mayStoreToHole[t1]
end
addi 1, ArrayStorage::m_numValuesInVector[t0]
- bib t2, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .opPutByValStoreResult
+ bib t2, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .opPutByValArrayStorageStoreResult
addi 1, t2, t1
storei t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0]
- jmp .opPutByValStoreResult
+ jmp .opPutByValArrayStorageStoreResult
.opPutByValSlow:
callSlowPath(_llint_slow_path_put_by_val)
@@ -1485,7 +1524,10 @@ _llint_op_jneq_ptr:
traceExecution()
loadi 4[PC], t0
loadi 8[PC], t1
+ loadp CodeBlock[cfr], t2
+ loadp CodeBlock::m_globalObject[t2], t2
bineq TagOffset[cfr, t0, 8], CellTag, .opJneqPtrBranch
+ loadp JSGlobalObject::m_specialPointers[t2, t1, 8], t1
bpeq PayloadOffset[cfr, t0, 8], t1, .opJneqPtrFallThrough
.opJneqPtrBranch:
dispatchBranch(12[PC])
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
index 4d614f51f..8b72674ab 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
@@ -796,23 +796,23 @@ _llint_op_is_string:
dispatch(3)
-macro loadPropertyAtVariableOffsetKnownNotFinal(propertyOffsetAsPointer, objectAndStorage, value)
- assert(macro (ok) bigteq propertyOffsetAsPointer, InlineStorageCapacity, ok end)
+macro loadPropertyAtVariableOffsetKnownNotInline(propertyOffsetAsPointer, objectAndStorage, value)
+ assert(macro (ok) bigteq propertyOffsetAsPointer, firstOutOfLineOffset, ok end)
negp propertyOffsetAsPointer
loadp JSObject::m_butterfly[objectAndStorage], objectAndStorage
- loadp (InlineStorageCapacity - 1) * 8 - sizeof IndexingHeader[objectAndStorage, propertyOffsetAsPointer, 8], value
+ loadp (firstOutOfLineOffset - 2) * 8[objectAndStorage, propertyOffsetAsPointer, 8], value
end
macro loadPropertyAtVariableOffset(propertyOffsetAsInt, objectAndStorage, value)
- bilt propertyOffsetAsInt, InlineStorageCapacity, .isInline
+ bilt propertyOffsetAsInt, firstOutOfLineOffset, .isInline
loadp JSObject::m_butterfly[objectAndStorage], objectAndStorage
negi propertyOffsetAsInt
sxi2p propertyOffsetAsInt, propertyOffsetAsInt
jmp .ready
.isInline:
- addp JSFinalObject::m_inlineStorage - (InlineStorageCapacity - 1) * 8 + sizeof IndexingHeader, objectAndStorage
+ addp sizeof JSObject - (firstOutOfLineOffset - 2) * 8, objectAndStorage
.ready:
- loadp (InlineStorageCapacity - 1) * 8 - sizeof IndexingHeader[objectAndStorage, propertyOffsetAsInt, 8], value
+ loadp (firstOutOfLineOffset - 2) * 8[objectAndStorage, propertyOffsetAsInt, 8], value
end
macro resolveGlobal(size, slow)
@@ -826,7 +826,7 @@ macro resolveGlobal(size, slow)
loadp JSCell::m_structure[t0], t1
bpneq t1, 24[PB, PC, 8], slow
loadis 32[PB, PC, 8], t1
- loadPropertyAtVariableOffset(t1, t0, t2)
+ loadPropertyAtVariableOffsetKnownNotInline(t1, t0, t2)
loadis 8[PB, PC, 8], t0
storep t2, [cfr, t0, 8]
loadp (size - 1) * 8[PB, PC, 8], t0
@@ -1018,7 +1018,7 @@ _llint_op_get_array_length:
loadp JSCell::m_structure[t3], t2
arrayProfile(t2, t1, t0)
btiz t2, IsArray, .opGetArrayLengthSlow
- btiz t2, HasArrayStorage, .opGetArrayLengthSlow
+ btiz t2, IndexingShapeMask, .opGetArrayLengthSlow
loadis 8[PB, PC, 8], t1
loadp 64[PB, PC, 8], t2
loadp JSObject::m_butterfly[t3], t0
@@ -1147,14 +1147,27 @@ _llint_op_get_by_val:
loadp 32[PB, PC, 8], t3
arrayProfile(t2, t3, t1)
loadis 24[PB, PC, 8], t3
- btiz t2, HasArrayStorage, .opGetByValSlow
loadConstantOrVariableInt32(t3, t1, .opGetByValSlow)
sxi2p t1, t1
loadp JSObject::m_butterfly[t0], t3
+ andi IndexingShapeMask, t2
+ bineq t2, ContiguousShape, .opGetByValNotContiguous
+
+ biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t3], .opGetByValSlow
+ loadis 8[PB, PC, 8], t0
+ loadp [t3, t1, 8], t2
+ btpz t2, .opGetByValSlow
+ jmp .opGetByValDone
+
+.opGetByValNotContiguous:
+ subi ArrayStorageShape, t2
+ bia t2, SlowPutArrayStorageShape - ArrayStorageShape, .opGetByValSlow
biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t3], .opGetByValSlow
loadis 8[PB, PC, 8], t0
loadp ArrayStorage::m_vector[t3, t1, 8], t2
btpz t2, .opGetByValSlow
+
+.opGetByValDone:
storep t2, [cfr, t0, 8]
loadp 40[PB, PC, 8], t0
valueProfile(t2, t0)
@@ -1208,7 +1221,10 @@ _llint_op_get_by_pname:
loadi PayloadOffset[cfr, t3, 8], t3
subi 1, t3
biaeq t3, JSPropertyNameIterator::m_numCacheableSlots[t1], .opGetByPnameSlow
- addi JSPropertyNameIterator::m_offsetBase[t1], t3
+ bilt t3, JSPropertyNameIterator::m_cachedStructureInlineCapacity[t1], .opGetByPnameInlineProperty
+ addi firstOutOfLineOffset, t3
+ subi JSPropertyNameIterator::m_cachedStructureInlineCapacity[t1], t3
+.opGetByPnameInlineProperty:
loadPropertyAtVariableOffset(t3, t0, t0)
loadis 8[PB, PC, 8], t1
storep t0, [cfr, t1, 8]
@@ -1226,29 +1242,52 @@ _llint_op_put_by_val:
loadp JSCell::m_structure[t1], t2
loadp 32[PB, PC, 8], t3
arrayProfile(t2, t3, t0)
- btiz t2, HasArrayStorage, .opPutByValSlow
loadis 16[PB, PC, 8], t0
- loadConstantOrVariableInt32(t0, t2, .opPutByValSlow)
- sxi2p t2, t2
+ loadConstantOrVariableInt32(t0, t3, .opPutByValSlow)
+ sxi2p t3, t3
loadp JSObject::m_butterfly[t1], t0
- biaeq t2, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow
- btpz ArrayStorage::m_vector[t0, t2, 8], .opPutByValEmpty
-.opPutByValStoreResult:
- loadis 24[PB, PC, 8], t3
- loadConstantOrVariable(t3, t1)
+ andi IndexingShapeMask, t2
+ bineq t2, ContiguousShape, .opPutByValNotContiguous
+
+ biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .opPutByValContiguousOutOfBounds
+.opPutByValContiguousStoreResult:
+ loadis 24[PB, PC, 8], t2
+ loadConstantOrVariable(t2, t1)
+ writeBarrier(t1)
+ storep t1, [t0, t3, 8]
+ dispatch(5)
+
+.opPutByValContiguousOutOfBounds:
+ 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 .opPutByValContiguousStoreResult
+
+.opPutByValNotContiguous:
+ bineq t2, ArrayStorageShape, .opPutByValSlow
+ biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow
+ btpz ArrayStorage::m_vector[t0, t3, 8], .opPutByValArrayStorageEmpty
+.opPutByValArrayStorageStoreResult:
+ loadis 24[PB, PC, 8], t2
+ loadConstantOrVariable(t2, t1)
writeBarrier(t1)
- storep t1, ArrayStorage::m_vector[t0, t2, 8]
+ storep t1, ArrayStorage::m_vector[t0, t3, 8]
dispatch(5)
-.opPutByValEmpty:
+.opPutByValArrayStorageEmpty:
if VALUE_PROFILER
- storeb 1, ArrayProfile::m_mayStoreToHole[t3]
+ loadp 32[PB, PC, 8], t1
+ storeb 1, ArrayProfile::m_mayStoreToHole[t1]
end
addi 1, ArrayStorage::m_numValuesInVector[t0]
- bib t2, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .opPutByValStoreResult
- addi 1, t2, t1
+ bib t3, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .opPutByValArrayStorageStoreResult
+ addi 1, t3, t1
storei t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0]
- jmp .opPutByValStoreResult
+ jmp .opPutByValArrayStorageStoreResult
.opPutByValSlow:
callSlowPath(_llint_slow_path_put_by_val)
@@ -1328,7 +1367,10 @@ _llint_op_jneq_null:
_llint_op_jneq_ptr:
traceExecution()
loadis 8[PB, PC, 8], t0
- loadp 16[PB, PC, 8], t1
+ loadi 16[PB, PC, 8], t1
+ loadp CodeBlock[cfr], t2
+ loadp CodeBlock::m_globalObject[t2], t2
+ loadp JSGlobalObject::m_specialPointers[t2, t1, 8], t1
bpneq t1, [cfr, t0, 8], .opJneqPtrTarget
dispatch(4)