summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/jit
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-09-14 16:29:47 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-09-14 16:29:47 +0200
commitd0424a769059c84ae20beb3c217812792ea6726b (patch)
tree6f94a5c3db8c52c6694ee56498542a6c35417350 /Source/JavaScriptCore/jit
parent88a04ac016f57c2d78e714682445dff2e7db4ade (diff)
downloadqtwebkit-d0424a769059c84ae20beb3c217812792ea6726b.tar.gz
Imported WebKit commit 37c5e5041d39a14ea0d429a77ebd352e4bd26516 (http://svn.webkit.org/repository/webkit/trunk@128608)
New snapshot that enables WebKit2 build on Windows (still some bugs) and allows for WebKit to be built with qmake && make
Diffstat (limited to 'Source/JavaScriptCore/jit')
-rw-r--r--Source/JavaScriptCore/jit/JIT.cpp6
-rw-r--r--Source/JavaScriptCore/jit/JIT.h2
-rw-r--r--Source/JavaScriptCore/jit/JITInlineMethods.h35
-rw-r--r--Source/JavaScriptCore/jit/JITOpcodes.cpp4
-rw-r--r--Source/JavaScriptCore/jit/JITPropertyAccess.cpp47
-rw-r--r--Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp45
-rw-r--r--Source/JavaScriptCore/jit/JITStubs.cpp18
7 files changed, 76 insertions, 81 deletions
diff --git a/Source/JavaScriptCore/jit/JIT.cpp b/Source/JavaScriptCore/jit/JIT.cpp
index 6083a66e4..bf5ac88dd 100644
--- a/Source/JavaScriptCore/jit/JIT.cpp
+++ b/Source/JavaScriptCore/jit/JIT.cpp
@@ -256,6 +256,7 @@ void JIT::privateCompileMainPass()
DEFINE_OP(op_eq)
DEFINE_OP(op_eq_null)
case op_get_by_id_out_of_line:
+ case op_get_array_length:
DEFINE_OP(op_get_by_id)
DEFINE_OP(op_get_arguments_length)
DEFINE_OP(op_get_by_val)
@@ -329,7 +330,9 @@ void JIT::privateCompileMainPass()
DEFINE_OP(op_put_by_index)
DEFINE_OP(op_put_by_val)
DEFINE_OP(op_put_getter_setter)
+ case op_init_global_const:
DEFINE_OP(op_put_global_var)
+ case op_init_global_const_check:
DEFINE_OP(op_put_global_var_check)
DEFINE_OP(op_put_scoped_var)
DEFINE_OP(op_resolve)
@@ -358,7 +361,6 @@ void JIT::privateCompileMainPass()
DEFINE_OP(op_to_jsnumber)
DEFINE_OP(op_to_primitive)
- case op_get_array_length:
case op_get_by_id_chain:
case op_get_by_id_generic:
case op_get_by_id_proto:
@@ -446,6 +448,7 @@ void JIT::privateCompileSlowCases()
DEFINE_SLOWCASE_OP(op_div)
DEFINE_SLOWCASE_OP(op_eq)
case op_get_by_id_out_of_line:
+ case op_get_array_length:
DEFINE_SLOWCASE_OP(op_get_by_id)
DEFINE_SLOWCASE_OP(op_get_arguments_length)
DEFINE_SLOWCASE_OP(op_get_by_val)
@@ -490,6 +493,7 @@ void JIT::privateCompileSlowCases()
case op_put_by_id_transition_normal_out_of_line:
DEFINE_SLOWCASE_OP(op_put_by_id)
DEFINE_SLOWCASE_OP(op_put_by_val)
+ case op_init_global_const_check:
DEFINE_SLOWCASE_OP(op_put_global_var_check);
DEFINE_SLOWCASE_OP(op_resolve_global)
DEFINE_SLOWCASE_OP(op_resolve_global_dynamic)
diff --git a/Source/JavaScriptCore/jit/JIT.h b/Source/JavaScriptCore/jit/JIT.h
index beb4cc060..ce70b40a7 100644
--- a/Source/JavaScriptCore/jit/JIT.h
+++ b/Source/JavaScriptCore/jit/JIT.h
@@ -435,7 +435,7 @@ namespace JSC {
void emitWriteBarrier(JSCell* owner, RegisterID value, RegisterID scratch, WriteBarrierMode, WriteBarrierUseKind);
template<typename ClassType, bool destructor, typename StructureType> void emitAllocateBasicJSObject(StructureType, RegisterID result, RegisterID storagePtr);
- void emitAllocateBasicStorage(size_t, RegisterID result);
+ void emitAllocateBasicStorage(size_t, ptrdiff_t offsetFromBase, RegisterID result);
template<typename T> void emitAllocateJSFinalObject(T structure, RegisterID result, RegisterID storagePtr);
void emitAllocateJSArray(unsigned valuesRegister, unsigned length, RegisterID cellResult, RegisterID storageResult, RegisterID storagePtr);
diff --git a/Source/JavaScriptCore/jit/JITInlineMethods.h b/Source/JavaScriptCore/jit/JITInlineMethods.h
index 3f32597fa..35ac44b23 100644
--- a/Source/JavaScriptCore/jit/JITInlineMethods.h
+++ b/Source/JavaScriptCore/jit/JITInlineMethods.h
@@ -423,7 +423,7 @@ template <typename ClassType, bool destructor, typename StructureType> inline vo
storePtr(structure, Address(result, JSCell::structureOffset()));
// initialize the object's property storage pointer
- storePtr(TrustedImmPtr(0), Address(result, ClassType::offsetOfOutOfLineStorage()));
+ storePtr(TrustedImmPtr(0), Address(result, JSObject::butterflyOffset()));
}
template <typename T> inline void JIT::emitAllocateJSFinalObject(T structure, RegisterID result, RegisterID scratch)
@@ -431,7 +431,7 @@ template <typename T> inline void JIT::emitAllocateJSFinalObject(T structure, Re
emitAllocateBasicJSObject<JSFinalObject, false, T>(structure, result, scratch);
}
-inline void JIT::emitAllocateBasicStorage(size_t size, RegisterID result)
+inline void JIT::emitAllocateBasicStorage(size_t size, ptrdiff_t offsetFromBase, RegisterID result)
{
CopiedAllocator* allocator = &m_globalData->heap.storageAllocator();
@@ -440,37 +440,32 @@ inline void JIT::emitAllocateBasicStorage(size_t size, RegisterID result)
storePtr(result, &allocator->m_currentRemaining);
negPtr(result);
addPtr(AbsoluteAddress(&allocator->m_currentPayloadEnd), result);
- subPtr(TrustedImm32(size), result);
+ subPtr(TrustedImm32(size - offsetFromBase), result);
}
inline void JIT::emitAllocateJSArray(unsigned valuesRegister, unsigned length, RegisterID cellResult, RegisterID storageResult, RegisterID storagePtr)
{
unsigned initialLength = std::max(length, 4U);
- size_t initialStorage = JSArray::storageSize(initialLength);
+ size_t initialStorage = Butterfly::totalSize(0, 0, true, ArrayStorage::sizeFor(initialLength));
// We allocate the backing store first to ensure that garbage collection
// doesn't happen during JSArray initialization.
- emitAllocateBasicStorage(initialStorage, storageResult);
+ emitAllocateBasicStorage(initialStorage, sizeof(IndexingHeader), storageResult);
// Allocate the cell for the array.
emitAllocateBasicJSObject<JSArray, false>(TrustedImmPtr(m_codeBlock->globalObject()->arrayStructure()), cellResult, storagePtr);
// Store all the necessary info in the ArrayStorage.
- storePtr(storageResult, Address(storageResult, ArrayStorage::allocBaseOffset()));
store32(Imm32(length), Address(storageResult, ArrayStorage::lengthOffset()));
store32(Imm32(length), Address(storageResult, ArrayStorage::numValuesInVectorOffset()));
+ store32(Imm32(initialLength), Address(storageResult, ArrayStorage::vectorLengthOffset()));
+ store32(TrustedImm32(0), Address(storageResult, ArrayStorage::indexBiasOffset()));
+ storePtr(TrustedImmPtr(0), Address(storageResult, ArrayStorage::sparseMapOffset()));
// Store the newly allocated ArrayStorage.
- storePtr(storageResult, Address(cellResult, JSArray::storageOffset()));
+ storePtr(storageResult, Address(cellResult, JSObject::butterflyOffset()));
- // Store the vector length and index bias.
- store32(Imm32(initialLength), Address(cellResult, JSArray::vectorLengthOffset()));
- store32(TrustedImm32(0), Address(cellResult, JSArray::indexBiasOffset()));
-
- // Initialize the sparse value map.
- storePtr(TrustedImmPtr(0), Address(cellResult, JSArray::sparseValueMapOffset()));
-
- // Store the values we have.
+ // Store the values we have.
for (unsigned i = 0; i < length; i++) {
#if USE(JSVALUE64)
loadPtr(Address(callFrameRegister, (valuesRegister + i) * sizeof(Register)), storagePtr);
@@ -482,16 +477,6 @@ inline void JIT::emitAllocateJSArray(unsigned valuesRegister, unsigned length, R
store32(storagePtr, Address(storageResult, ArrayStorage::vectorOffset() + sizeof(WriteBarrier<Unknown>) * i + sizeof(uint32_t)));
#endif
}
-
- // Zero out the remaining slots.
- for (unsigned i = length; i < initialLength; i++) {
-#if USE(JSVALUE64)
- storePtr(TrustedImmPtr(0), Address(storageResult, ArrayStorage::vectorOffset() + sizeof(WriteBarrier<Unknown>) * i));
-#else
- store32(TrustedImm32(static_cast<int>(JSValue::EmptyValueTag)), Address(storageResult, ArrayStorage::vectorOffset() + sizeof(WriteBarrier<Unknown>) * i + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
- store32(TrustedImm32(0), Address(storageResult, ArrayStorage::vectorOffset() + sizeof(WriteBarrier<Unknown>) * i + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
-#endif
- }
}
#if ENABLE(VALUE_PROFILER)
diff --git a/Source/JavaScriptCore/jit/JITOpcodes.cpp b/Source/JavaScriptCore/jit/JITOpcodes.cpp
index f859f8b93..486be6bf9 100644
--- a/Source/JavaScriptCore/jit/JITOpcodes.cpp
+++ b/Source/JavaScriptCore/jit/JITOpcodes.cpp
@@ -1666,7 +1666,7 @@ void JIT::emit_op_new_func_exp(Instruction* currentInstruction)
void JIT::emit_op_new_array(Instruction* currentInstruction)
{
int length = currentInstruction[3].u.operand;
- if (CopiedSpace::isOversize(JSArray::storageSize(length))) {
+ if (CopiedSpace::isOversize(Butterfly::totalSize(0, 0, true, ArrayStorage::sizeFor(length)))) {
JITStubCall stubCall(this, cti_op_new_array);
stubCall.addArgument(TrustedImm32(currentInstruction[2].u.operand));
stubCall.addArgument(TrustedImm32(currentInstruction[3].u.operand));
@@ -1685,7 +1685,7 @@ void JIT::emitSlow_op_new_array(Instruction* currentInstruction, Vector<SlowCase
// If the allocation would be oversize, we will already make the proper stub call above in
// emit_op_new_array.
int length = currentInstruction[3].u.operand;
- if (CopiedSpace::isOversize(JSArray::storageSize(length)))
+ if (CopiedSpace::isOversize(Butterfly::totalSize(0, 0, true, ArrayStorage::sizeFor(length))))
return;
linkSlowCase(iter); // Not enough space in CopiedSpace for storage.
linkSlowCase(iter); // Not enough space in MarkedSpace for cell.
diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
index ada862a53..bca68f0b4 100644
--- a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
+++ b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
@@ -114,10 +114,10 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction)
#if ENABLE(VALUE_PROFILER)
storePtr(regT2, currentInstruction[4].u.arrayProfile->addressOfLastSeenStructure());
#endif
- addSlowCase(branchPtr(NotEqual, Address(regT2, Structure::classInfoOffset()), TrustedImmPtr(&JSArray::s_info)));
+ addSlowCase(branchTest8(Zero, Address(regT2, Structure::indexingTypeOffset()), TrustedImm32(HasArrayStorage)));
- loadPtr(Address(regT0, JSArray::storageOffset()), regT2);
- addSlowCase(branch32(AboveOrEqual, regT1, Address(regT0, JSArray::vectorLengthOffset())));
+ loadPtr(Address(regT0, JSObject::butterflyOffset()), regT2);
+ addSlowCase(branch32(AboveOrEqual, regT1, Address(regT2, ArrayStorage::vectorLengthOffset())));
loadPtr(BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT0);
addSlowCase(branchTestPtr(Zero, regT0));
@@ -162,7 +162,7 @@ void JIT::compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID
if (finalObjectMode == MayBeFinal) {
Jump isInline = branch32(LessThan, offset, TrustedImm32(inlineStorageCapacity));
- loadPtr(Address(base, JSObject::offsetOfOutOfLineStorage()), scratch);
+ loadPtr(Address(base, JSObject::butterflyOffset()), scratch);
neg32(offset);
Jump done = jump();
isInline.link(this);
@@ -174,7 +174,7 @@ void JIT::compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID
breakpoint();
isOutOfLine.link(this);
#endif
- loadPtr(Address(base, JSObject::offsetOfOutOfLineStorage()), scratch);
+ loadPtr(Address(base, JSObject::butterflyOffset()), scratch);
neg32(offset);
}
signExtend32ToPtr(offset, offset);
@@ -239,10 +239,10 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction)
#if ENABLE(VALUE_PROFILER)
storePtr(regT2, currentInstruction[4].u.arrayProfile->addressOfLastSeenStructure());
#endif
- addSlowCase(branchPtr(NotEqual, Address(regT2, Structure::classInfoOffset()), TrustedImmPtr(&JSArray::s_info)));
- addSlowCase(branch32(AboveOrEqual, regT1, Address(regT0, JSArray::vectorLengthOffset())));
+ addSlowCase(branchTest8(Zero, Address(regT2, Structure::indexingTypeOffset()), TrustedImm32(HasArrayStorage)));
+ loadPtr(Address(regT0, JSObject::butterflyOffset()), regT2);
+ addSlowCase(branch32(AboveOrEqual, regT1, Address(regT2, ArrayStorage::vectorLengthOffset())));
- loadPtr(Address(regT0, JSArray::storageOffset()), regT2);
Jump empty = branchTestPtr(Zero, BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
Label storeResult(this);
@@ -252,10 +252,10 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction)
empty.link(this);
add32(TrustedImm32(1), Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
- branch32(Below, regT1, Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length))).linkTo(storeResult, this);
+ branch32(Below, regT1, Address(regT2, ArrayStorage::lengthOffset())).linkTo(storeResult, this);
add32(TrustedImm32(1), regT1);
- store32(regT1, Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length)));
+ store32(regT1, Address(regT2, ArrayStorage::lengthOffset()));
sub32(TrustedImm32(1), regT1);
jump().linkTo(storeResult, this);
@@ -403,7 +403,7 @@ void JIT::compileGetByIdHotPath(int baseVReg, Identifier*)
PatchableJump structureCheck = patchableBranchPtrWithPatch(NotEqual, Address(regT0, JSCell::structureOffset()), structureToCompare, TrustedImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)));
addSlowCase(structureCheck);
- ConvertibleLoadLabel propertyStorageLoad = convertibleLoadPtr(Address(regT0, JSObject::offsetOfOutOfLineStorage()), regT0);
+ ConvertibleLoadLabel propertyStorageLoad = convertibleLoadPtr(Address(regT0, JSObject::butterflyOffset()), regT0);
DataLabelCompact displacementLabel = loadPtrWithCompactAddressOffsetPatch(Address(regT0, patchGetByIdDefaultOffset), regT0);
Label putResult(this);
@@ -470,7 +470,7 @@ void JIT::emit_op_put_by_id(Instruction* currentInstruction)
DataLabelPtr structureToCompare;
addSlowCase(branchPtrWithPatch(NotEqual, Address(regT0, JSCell::structureOffset()), structureToCompare, TrustedImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure))));
- ConvertibleLoadLabel propertyStorageLoad = convertibleLoadPtr(Address(regT0, JSObject::offsetOfOutOfLineStorage()), regT2);
+ ConvertibleLoadLabel propertyStorageLoad = convertibleLoadPtr(Address(regT0, JSObject::butterflyOffset()), regT2);
DataLabel32 displacementLabel = storePtrWithAddressOffsetPatch(regT1, Address(regT2, patchPutByIdDefaultOffset));
END_UNINTERRUPTED_SEQUENCE(sequencePutById);
@@ -509,8 +509,8 @@ void JIT::compilePutDirectOffset(RegisterID base, RegisterID value, PropertyOffs
return;
}
- loadPtr(Address(base, JSObject::offsetOfOutOfLineStorage()), base);
- storePtr(value, Address(base, sizeof(JSValue) * offsetInOutOfLineStorage(cachedOffset)));
+ loadPtr(Address(base, JSObject::butterflyOffset()), base);
+ storePtr(value, Address(base, sizeof(JSValue) * offsetInButterfly(cachedOffset)));
}
// Compile a load from an object's property storage. May overwrite base.
@@ -521,8 +521,8 @@ void JIT::compileGetDirectOffset(RegisterID base, RegisterID result, PropertyOff
return;
}
- loadPtr(Address(base, JSObject::offsetOfOutOfLineStorage()), result);
- loadPtr(Address(result, sizeof(JSValue) * offsetInOutOfLineStorage(cachedOffset)), result);
+ loadPtr(Address(base, JSObject::butterflyOffset()), result);
+ loadPtr(Address(result, sizeof(JSValue) * offsetInButterfly(cachedOffset)), result);
}
void JIT::compileGetDirectOffset(JSObject* base, RegisterID result, PropertyOffset cachedOffset)
@@ -532,8 +532,8 @@ void JIT::compileGetDirectOffset(JSObject* base, RegisterID result, PropertyOffs
return;
}
- loadPtr(base->addressOfOutOfLineStorage(), result);
- loadPtr(Address(result, offsetInOutOfLineStorage(cachedOffset) * sizeof(WriteBarrier<Unknown>)), result);
+ loadPtr(base->butterflyAddress(), result);
+ loadPtr(Address(result, offsetInButterfly(cachedOffset) * sizeof(WriteBarrier<Unknown>)), result);
}
void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, PropertyOffset cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress, bool direct)
@@ -660,12 +660,14 @@ void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress)
#if ENABLE(VALUE_PROFILER)
storePtr(regT3, m_codeBlock->getOrAddArrayProfile(stubInfo->bytecodeIndex)->addressOfLastSeenStructure());
#endif
- Jump failureCases1 = branchPtr(NotEqual, Address(regT3, Structure::classInfoOffset()), TrustedImmPtr(&JSArray::s_info));
+ load8(Address(regT3, Structure::indexingTypeOffset()), regT3);
+ Jump failureCases1 = branchTest32(Zero, regT3, TrustedImm32(IsArray));
+ Jump failureCases2 = branchTest32(Zero, regT3, TrustedImm32(HasArrayStorage));
// Checks out okay! - get the length from the storage
- loadPtr(Address(regT0, JSArray::storageOffset()), regT3);
- load32(Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_length)), regT2);
- Jump failureCases2 = branch32(LessThan, regT2, TrustedImm32(0));
+ loadPtr(Address(regT0, JSObject::butterflyOffset()), regT3);
+ load32(Address(regT3, ArrayStorage::lengthOffset()), regT2);
+ Jump failureCases3 = branch32(LessThan, regT2, TrustedImm32(0));
emitFastArithIntToImmNoCheck(regT2, regT0);
Jump success = jump();
@@ -676,6 +678,7 @@ void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress)
CodeLocationLabel slowCaseBegin = stubInfo->callReturnLocation.labelAtOffset(-stubInfo->patch.baseline.u.get.coldPathBegin);
patchBuffer.link(failureCases1, slowCaseBegin);
patchBuffer.link(failureCases2, slowCaseBegin);
+ patchBuffer.link(failureCases3, slowCaseBegin);
// On success return back to the hot patch code, at a point it will perform the store to dest for us.
patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult));
diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
index f3c79a985..04d7c3815 100644
--- a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
@@ -213,10 +213,10 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction)
#if ENABLE(VALUE_PROFILER)
storePtr(regT1, currentInstruction[4].u.arrayProfile->addressOfLastSeenStructure());
#endif
- addSlowCase(branchPtr(NotEqual, Address(regT1, Structure::classInfoOffset()), TrustedImmPtr(&JSArray::s_info)));
+ addSlowCase(branchTest8(Zero, Address(regT1, Structure::indexingTypeOffset()), TrustedImm32(HasArrayStorage)));
- loadPtr(Address(regT0, JSArray::storageOffset()), regT3);
- addSlowCase(branch32(AboveOrEqual, regT2, Address(regT0, JSArray::vectorLengthOffset())));
+ loadPtr(Address(regT0, JSObject::butterflyOffset()), regT3);
+ addSlowCase(branch32(AboveOrEqual, regT2, Address(regT3, ArrayStorage::vectorLengthOffset())));
load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1); // tag
load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0); // payload
@@ -272,11 +272,11 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction)
#if ENABLE(VALUE_PROFILER)
storePtr(regT1, currentInstruction[4].u.arrayProfile->addressOfLastSeenStructure());
#endif
- addSlowCase(branchPtr(NotEqual, Address(regT1, Structure::classInfoOffset()), TrustedImmPtr(&JSArray::s_info)));
- addSlowCase(branch32(AboveOrEqual, regT2, Address(regT0, JSArray::vectorLengthOffset())));
+ addSlowCase(branchTest8(Zero, Address(regT1, Structure::indexingTypeOffset()), TrustedImm32(HasArrayStorage)));
+ loadPtr(Address(regT0, JSObject::butterflyOffset()), regT3);
+ addSlowCase(branch32(AboveOrEqual, regT2, Address(regT3, ArrayStorage::vectorLengthOffset())));
emitWriteBarrier(regT0, regT1, regT1, regT3, UnconditionalWriteBarrier, WriteBarrierForPropertyAccess);
- loadPtr(Address(regT0, JSArray::storageOffset()), regT3);
Jump empty = branch32(Equal, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag));
@@ -288,10 +288,10 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction)
empty.link(this);
add32(TrustedImm32(1), Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
- branch32(Below, regT2, Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_length))).linkTo(storeResult, this);
+ branch32(Below, regT2, Address(regT3, ArrayStorage::lengthOffset())).linkTo(storeResult, this);
add32(TrustedImm32(1), regT2, regT0);
- store32(regT0, Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_length)));
+ store32(regT0, Address(regT3, ArrayStorage::lengthOffset()));
jump().linkTo(storeResult, this);
end.link(this);
@@ -343,7 +343,7 @@ void JIT::compileGetByIdHotPath()
PatchableJump structureCheck = patchableBranchPtrWithPatch(NotEqual, Address(regT0, JSCell::structureOffset()), structureToCompare, TrustedImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)));
addSlowCase(structureCheck);
- ConvertibleLoadLabel propertyStorageLoad = convertibleLoadPtr(Address(regT0, JSObject::offsetOfOutOfLineStorage()), regT2);
+ ConvertibleLoadLabel propertyStorageLoad = convertibleLoadPtr(Address(regT0, JSObject::butterflyOffset()), regT2);
DataLabelCompact displacementLabel1 = loadPtrWithCompactAddressOffsetPatch(Address(regT2, patchGetByIdDefaultOffset), regT0); // payload
DataLabelCompact displacementLabel2 = loadPtrWithCompactAddressOffsetPatch(Address(regT2, patchGetByIdDefaultOffset), regT1); // tag
@@ -409,7 +409,7 @@ void JIT::emit_op_put_by_id(Instruction* currentInstruction)
DataLabelPtr structureToCompare;
addSlowCase(branchPtrWithPatch(NotEqual, Address(regT0, JSCell::structureOffset()), structureToCompare, TrustedImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure))));
- ConvertibleLoadLabel propertyStorageLoad = convertibleLoadPtr(Address(regT0, JSObject::offsetOfOutOfLineStorage()), regT1);
+ ConvertibleLoadLabel propertyStorageLoad = convertibleLoadPtr(Address(regT0, JSObject::butterflyOffset()), regT1);
DataLabel32 displacementLabel1 = storePtrWithAddressOffsetPatch(regT2, Address(regT1, patchPutByIdDefaultOffset)); // payload
DataLabel32 displacementLabel2 = storePtrWithAddressOffsetPatch(regT3, Address(regT1, patchPutByIdDefaultOffset)); // tag
@@ -443,7 +443,7 @@ void JIT::emitSlow_op_put_by_id(Instruction* currentInstruction, Vector<SlowCase
void JIT::compilePutDirectOffset(RegisterID base, RegisterID valueTag, RegisterID valuePayload, PropertyOffset cachedOffset)
{
if (isOutOfLineOffset(cachedOffset))
- loadPtr(Address(base, JSObject::offsetOfOutOfLineStorage()), base);
+ loadPtr(Address(base, JSObject::butterflyOffset()), base);
emitStore(indexRelativeToBase(cachedOffset), valueTag, valuePayload, base);
}
@@ -456,7 +456,7 @@ void JIT::compileGetDirectOffset(RegisterID base, RegisterID resultTag, Register
}
RegisterID temp = resultPayload;
- loadPtr(Address(base, JSObject::offsetOfOutOfLineStorage()), temp);
+ loadPtr(Address(base, JSObject::butterflyOffset()), temp);
emitLoad(indexRelativeToBase(cachedOffset), resultTag, resultPayload, temp);
}
@@ -469,9 +469,9 @@ void JIT::compileGetDirectOffset(JSObject* base, RegisterID resultTag, RegisterI
return;
}
- loadPtr(base->addressOfOutOfLineStorage(), resultTag);
- load32(Address(resultTag, offsetInOutOfLineStorage(cachedOffset) * sizeof(WriteBarrier<Unknown>) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload);
- load32(Address(resultTag, offsetInOutOfLineStorage(cachedOffset) * sizeof(WriteBarrier<Unknown>) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag);
+ loadPtr(base->butterflyAddress(), resultTag);
+ load32(Address(resultTag, offsetInButterfly(cachedOffset) * sizeof(WriteBarrier<Unknown>) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload);
+ load32(Address(resultTag, offsetInButterfly(cachedOffset) * sizeof(WriteBarrier<Unknown>) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag);
}
void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, PropertyOffset cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress, bool direct)
@@ -620,13 +620,15 @@ void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress)
#if ENABLE(VALUE_PROFILER)
storePtr(regT2, m_codeBlock->getOrAddArrayProfile(stubInfo->bytecodeIndex)->addressOfLastSeenStructure());
#endif
- Jump failureCases1 = branchPtr(NotEqual, Address(regT2, Structure::classInfoOffset()), TrustedImmPtr(&JSArray::s_info));
+ load8(Address(regT2, Structure::indexingTypeOffset()), regT3);
+ Jump failureCases1 = branchTest32(Zero, regT2, TrustedImm32(IsArray));
+ Jump failureCases2 = branchTest32(Zero, regT2, TrustedImm32(HasArrayStorage));
// Checks out okay! - get the length from the storage
- loadPtr(Address(regT0, JSArray::storageOffset()), regT2);
- load32(Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length)), regT2);
+ loadPtr(Address(regT0, JSArray::butterflyOffset()), regT2);
+ load32(Address(regT2, ArrayStorage::lengthOffset()), regT2);
- Jump failureCases2 = branch32(Above, regT2, TrustedImm32(INT_MAX));
+ Jump failureCases3 = branch32(Above, regT2, TrustedImm32(INT_MAX));
move(regT2, regT0);
move(TrustedImm32(JSValue::Int32Tag), regT1);
Jump success = jump();
@@ -637,6 +639,7 @@ void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress)
CodeLocationLabel slowCaseBegin = stubInfo->callReturnLocation.labelAtOffset(-stubInfo->patch.baseline.u.get.coldPathBegin);
patchBuffer.link(failureCases1, slowCaseBegin);
patchBuffer.link(failureCases2, slowCaseBegin);
+ patchBuffer.link(failureCases3, slowCaseBegin);
// On success return back to the hot patch code, at a point it will perform the store to dest for us.
patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult));
@@ -1029,7 +1032,7 @@ void JIT::compileGetDirectOffset(RegisterID base, RegisterID resultTag, Register
if (finalObjectMode == MayBeFinal) {
Jump isInline = branch32(LessThan, offset, TrustedImm32(inlineStorageCapacity));
- loadPtr(Address(base, JSObject::offsetOfOutOfLineStorage()), base);
+ loadPtr(Address(base, JSObject::butterflyOffset()), base);
neg32(offset);
Jump done = jump();
isInline.link(this);
@@ -1041,7 +1044,7 @@ void JIT::compileGetDirectOffset(RegisterID base, RegisterID resultTag, Register
breakpoint();
isOutOfLine.link(this);
#endif
- loadPtr(Address(base, JSObject::offsetOfOutOfLineStorage()), base);
+ loadPtr(Address(base, JSObject::butterflyOffset()), base);
neg32(offset);
}
load32(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload) + (inlineStorageCapacity - 2) * sizeof(EncodedJSValue)), resultPayload);
diff --git a/Source/JavaScriptCore/jit/JITStubs.cpp b/Source/JavaScriptCore/jit/JITStubs.cpp
index 5fad9c8d7..40d653b5d 100644
--- a/Source/JavaScriptCore/jit/JITStubs.cpp
+++ b/Source/JavaScriptCore/jit/JITStubs.cpp
@@ -1504,8 +1504,8 @@ DEFINE_STUB_FUNCTION(JSObject*, op_put_by_id_transition_realloc)
ASSERT(baseValue.isObject());
JSObject* base = asObject(baseValue);
JSGlobalData& globalData = *stackFrame.globalData;
- PropertyStorage newStorage = base->growOutOfLineStorage(globalData, oldSize, newSize);
- base->setOutOfLineStorage(globalData, newStorage, newStructure);
+ Butterfly* butterfly = base->growOutOfLineStorage(globalData, oldSize, newSize);
+ base->setButterfly(globalData, butterfly, newStructure);
return base;
}
@@ -2415,7 +2415,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val)
JSValue baseValue = stackFrame.args[0].jsValue();
JSValue subscript = stackFrame.args[1].jsValue();
-
+
if (LIKELY(baseValue.isCell() && subscript.isString())) {
if (JSValue result = baseValue.asCell()->fastGetOwnProperty(callFrame, asString(subscript)->value(callFrame))) {
CHECK_FOR_EXCEPTION();
@@ -2508,12 +2508,12 @@ DEFINE_STUB_FUNCTION(void, op_put_by_val)
if (LIKELY(subscript.isUInt32())) {
uint32_t i = subscript.asUInt32();
- if (isJSArray(baseValue)) {
- JSArray* jsArray = asArray(baseValue);
- if (jsArray->canSetIndex(i))
- jsArray->setIndex(*globalData, i, value);
+ if (baseValue.isObject()) {
+ JSObject* object = asObject(baseValue);
+ if (object->canSetIndexQuickly(i))
+ object->setIndexQuickly(*globalData, i, value);
else
- JSArray::putByIndex(jsArray, callFrame, i, value, callFrame->codeBlock()->isStrictMode());
+ object->methodTable()->putByIndex(object, callFrame, i, value, callFrame->codeBlock()->isStrictMode());
} else
baseValue.putByIndex(callFrame, i, value, callFrame->codeBlock()->isStrictMode());
} else if (isName(subscript)) {
@@ -3368,7 +3368,7 @@ DEFINE_STUB_FUNCTION(void, op_put_getter_setter)
accessor->setGetter(callFrame->globalData(), asObject(getter));
if (!setter.isUndefined())
accessor->setSetter(callFrame->globalData(), asObject(setter));
- baseObj->putDirectAccessor(callFrame->globalData(), stackFrame.args[1].identifier(), accessor, Accessor);
+ baseObj->putDirectAccessor(callFrame, stackFrame.args[1].identifier(), accessor, Accessor);
}
DEFINE_STUB_FUNCTION(void, op_throw_reference_error)