Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (132427 => 132428)
--- trunk/Source/_javascript_Core/ChangeLog 2012-10-25 00:19:35 UTC (rev 132427)
+++ trunk/Source/_javascript_Core/ChangeLog 2012-10-25 00:24:11 UTC (rev 132428)
@@ -1,3 +1,22 @@
+2012-10-24 Filip Pizlo <[email protected]>
+
+ DFG compileBlahBlahByVal methods for Contiguous and ArrayStorage have only one caller and should be removed
+ https://bugs.webkit.org/show_bug.cgi?id=100311
+
+ Reviewed by Mark Hahnenberg.
+
+ Just trying to simplify things before I make them more complicated again.
+
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+ (JSC::DFG::SpeculativeJIT::temporaryRegisterForPutByVal):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (DFG):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (DFG):
+ (JSC::DFG::SpeculativeJIT::compile):
+
2012-10-23 Andreas Kling <[email protected]>
CodeBlock: Give m_putToBaseOperations an inline capacity.
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (132427 => 132428)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2012-10-25 00:19:35 UTC (rev 132427)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2012-10-25 00:24:11 UTC (rev 132428)
@@ -2270,14 +2270,6 @@
void compileAllocatePropertyStorage(Node&);
void compileReallocatePropertyStorage(Node&);
-#if USE(JSVALUE64)
- MacroAssembler::JumpList compileContiguousGetByVal(Node&, GPRReg baseReg, GPRReg propertyReg, GPRReg storageReg, GPRReg resultReg);
- MacroAssembler::JumpList compileArrayStorageGetByVal(Node&, GPRReg baseReg, GPRReg propertyReg, GPRReg storageReg, GPRReg resultReg);
-#else
- MacroAssembler::JumpList compileContiguousGetByVal(Node&, GPRReg baseReg, GPRReg propertyReg, GPRReg storageReg, GPRReg resultTagReg, GPRReg resultPayloadReg);
- MacroAssembler::JumpList compileArrayStorageGetByVal(Node&, GPRReg baseReg, GPRReg propertyReg, GPRReg storageReg, GPRReg resultTagReg, GPRReg resultPayloadReg);
-#endif
-
bool putByValWillNeedExtraRegister(Array::Mode arrayMode)
{
switch (arrayMode) {
@@ -2304,13 +2296,6 @@
{
return temporaryRegisterForPutByVal(temporary, node.arrayMode());
}
-#if USE(JSVALUE64)
- MacroAssembler::JumpList compileContiguousPutByVal(Node&, GPRReg baseReg, GPRReg propertyReg, GPRReg storageReg, GPRReg valueReg, GPRReg tempReg);
- MacroAssembler::JumpList compileArrayStoragePutByVal(Node&, GPRReg baseReg, GPRReg propertyReg, GPRReg storageReg, GPRReg valueReg, GPRReg tempReg);
-#else
- MacroAssembler::JumpList compileContiguousPutByVal(Node&, GPRReg baseReg, GPRReg propertyReg, GPRReg storageReg, GPRReg valueTagReg, GPRReg valuePayloadReg);
- MacroAssembler::JumpList compileArrayStoragePutByVal(Node&, GPRReg baseReg, GPRReg propertyReg, GPRReg storageReg, GPRReg valueTagReg, GPRReg valuePayloadReg);
-#endif
void compileGetCharCodeAt(Node&);
void compileGetByValOnString(Node&);
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (132427 => 132428)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2012-10-25 00:19:35 UTC (rev 132427)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2012-10-25 00:24:11 UTC (rev 132428)
@@ -2046,113 +2046,6 @@
}
}
-MacroAssembler::JumpList SpeculativeJIT::compileContiguousGetByVal(Node&, GPRReg, GPRReg propertyReg, GPRReg storageReg, GPRReg resultTagReg, GPRReg resultPayloadReg)
-{
- MacroAssembler::JumpList slowCases;
- slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
-
- m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTagReg);
- m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayloadReg);
- slowCases.append(m_jit.branch32(MacroAssembler::Equal, resultTagReg, TrustedImm32(JSValue::EmptyValueTag)));
-
- return slowCases;
-}
-
-MacroAssembler::JumpList SpeculativeJIT::compileArrayStorageGetByVal(Node&, GPRReg, GPRReg propertyReg, GPRReg storageReg, GPRReg resultTagReg, GPRReg resultPayloadReg)
-{
- MacroAssembler::Jump outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset()));
-
- m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTagReg);
- m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayloadReg);
- MacroAssembler::Jump hole = m_jit.branch32(MacroAssembler::Equal, resultTagReg, TrustedImm32(JSValue::EmptyValueTag));
-
- MacroAssembler::JumpList slowCases;
- slowCases.append(outOfBounds);
- slowCases.append(hole);
- return slowCases;
-}
-
-MacroAssembler::JumpList SpeculativeJIT::compileContiguousPutByVal(Node& node, GPRReg, GPRReg propertyReg, GPRReg storageReg, GPRReg valueTagReg, GPRReg valuePayloadReg)
-{
- Array::Mode arrayMode = node.arrayMode();
-
- MacroAssembler::JumpList slowCases;
-
- if (!mayStoreToTail(arrayMode)) {
- speculationCheck(
- Uncountable, JSValueRegs(), NoNode,
- m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
- } else {
- MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()));
-
- slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfVectorLength())));
-
- if (isInBoundsAccess(arrayMode))
- speculationCheck(Uncountable, JSValueRegs(), NoNode, slowCases);
-
- m_jit.add32(TrustedImm32(1), propertyReg);
- m_jit.store32(propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()));
- m_jit.sub32(TrustedImm32(1), propertyReg);
-
- inBounds.link(&m_jit);
- }
-
- m_jit.store32(valueTagReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
- m_jit.store32(valuePayloadReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
-
- if (isInBoundsAccess(arrayMode))
- return MacroAssembler::JumpList();
- return slowCases;
-}
-
-MacroAssembler::JumpList SpeculativeJIT::compileArrayStoragePutByVal(Node& node, GPRReg, GPRReg propertyReg, GPRReg storageReg, GPRReg valueTagReg, GPRReg valuePayloadReg)
-{
- Array::Mode arrayMode = node.arrayMode();
-
- MacroAssembler::JumpList slowCases;
-
- MacroAssembler::Jump beyondArrayBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset()));
- if (isInBoundsAccess(arrayMode))
- speculationCheck(OutOfBounds, JSValueRegs(), NoNode, beyondArrayBounds);
- else
- slowCases.append(beyondArrayBounds);
-
- // Check if we're writing to a hole; if so increment m_numValuesInVector.
- if (!mayStoreToHole(arrayMode)) {
- // This is uncountable because if we take this exit, then the baseline JIT
- // will immediately count the hole store. So there is no need for exit
- // profiling.
- speculationCheck(
- Uncountable, JSValueRegs(), NoNode,
- m_jit.branch32(MacroAssembler::Equal, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag)));
- } else {
- MacroAssembler::Jump notHoleValue = m_jit.branch32(MacroAssembler::NotEqual, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag));
- if (isSlowPutAccess(arrayMode)) {
- // This is sort of strange. If we wanted to optimize this code path, we would invert
- // the above branch. But it's simply not worth it since this only happens if we're
- // already having a bad time.
- slowCases.append(m_jit.jump());
- } else {
- m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageReg, ArrayStorage::numValuesInVectorOffset()));
-
- // If we're writing to a hole we might be growing the array;
- MacroAssembler::Jump lengthDoesNotNeedUpdate = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset()));
- m_jit.add32(TrustedImm32(1), propertyReg);
- m_jit.store32(propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset()));
- m_jit.sub32(TrustedImm32(1), propertyReg);
-
- lengthDoesNotNeedUpdate.link(&m_jit);
- }
- notHoleValue.link(&m_jit);
- }
-
- // Store the value to the array.
- m_jit.store32(valueTagReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
- m_jit.store32(valuePayloadReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
-
- return slowCases;
-}
-
void SpeculativeJIT::compile(Node& node)
{
NodeType op = node.op();
@@ -2712,8 +2605,14 @@
GPRReg resultTagReg = resultTag.gpr();
GPRReg resultPayloadReg = resultPayload.gpr();
- MacroAssembler::JumpList slowCases =
- compileContiguousGetByVal(node, baseReg, propertyReg, storageReg, resultTagReg, resultPayloadReg);
+ MacroAssembler::JumpList slowCases;
+
+ slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
+
+ m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTagReg);
+ m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayloadReg);
+ slowCases.append(m_jit.branch32(MacroAssembler::Equal, resultTagReg, TrustedImm32(JSValue::EmptyValueTag)));
+
addSlowPathGenerator(
slowPathCall(
slowCases, this, operationGetByValArrayInt,
@@ -2900,16 +2799,36 @@
break;
}
- MacroAssembler::JumpList slowCases =
- compileContiguousPutByVal(
- node, baseReg, propertyReg, storageReg, valueTagReg, valuePayloadReg);
+ MacroAssembler::JumpList slowCases;
+ if (!mayStoreToTail(arrayMode)) {
+ speculationCheck(
+ Uncountable, JSValueRegs(), NoNode,
+ m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
+ } else {
+ MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()));
+
+ slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfVectorLength())));
+
+ if (isInBoundsAccess(arrayMode))
+ speculationCheck(Uncountable, JSValueRegs(), NoNode, slowCases);
+
+ m_jit.add32(TrustedImm32(1), propertyReg);
+ m_jit.store32(propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()));
+ m_jit.sub32(TrustedImm32(1), propertyReg);
+
+ inBounds.link(&m_jit);
+ }
+
+ m_jit.store32(valueTagReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
+ m_jit.store32(valuePayloadReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
+
base.use();
property.use();
value.use();
storage.use();
- if (!slowCases.empty()) {
+ if (!isInBoundsAccess(arrayMode)) {
addSlowPathGenerator(
slowPathCall(
slowCases, this,
@@ -2950,10 +2869,47 @@
break;
}
- MacroAssembler::JumpList slowCases =
- compileArrayStoragePutByVal(
- node, baseReg, propertyReg, storageReg, valueTagReg, valuePayloadReg);
+ MacroAssembler::JumpList slowCases;
+ MacroAssembler::Jump beyondArrayBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset()));
+ if (isInBoundsAccess(arrayMode))
+ speculationCheck(OutOfBounds, JSValueRegs(), NoNode, beyondArrayBounds);
+ else
+ slowCases.append(beyondArrayBounds);
+
+ // Check if we're writing to a hole; if so increment m_numValuesInVector.
+ if (!mayStoreToHole(arrayMode)) {
+ // This is uncountable because if we take this exit, then the baseline JIT
+ // will immediately count the hole store. So there is no need for exit
+ // profiling.
+ speculationCheck(
+ Uncountable, JSValueRegs(), NoNode,
+ m_jit.branch32(MacroAssembler::Equal, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag)));
+ } else {
+ MacroAssembler::Jump notHoleValue = m_jit.branch32(MacroAssembler::NotEqual, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag));
+ if (isSlowPutAccess(arrayMode)) {
+ // This is sort of strange. If we wanted to optimize this code path, we would invert
+ // the above branch. But it's simply not worth it since this only happens if we're
+ // already having a bad time.
+ slowCases.append(m_jit.jump());
+ } else {
+ m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageReg, ArrayStorage::numValuesInVectorOffset()));
+
+ // If we're writing to a hole we might be growing the array;
+ MacroAssembler::Jump lengthDoesNotNeedUpdate = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset()));
+ m_jit.add32(TrustedImm32(1), propertyReg);
+ m_jit.store32(propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset()));
+ m_jit.sub32(TrustedImm32(1), propertyReg);
+
+ lengthDoesNotNeedUpdate.link(&m_jit);
+ }
+ notHoleValue.link(&m_jit);
+ }
+
+ // Store the value to the array.
+ m_jit.store32(valueTagReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
+ m_jit.store32(valuePayloadReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
+
base.use();
property.use();
value.use();
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (132427 => 132428)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2012-10-25 00:19:35 UTC (rev 132427)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2012-10-25 00:24:11 UTC (rev 132428)
@@ -2111,107 +2111,6 @@
}
}
-MacroAssembler::JumpList SpeculativeJIT::compileContiguousGetByVal(Node&, GPRReg, GPRReg propertyReg, GPRReg storageReg, GPRReg resultReg)
-{
- MacroAssembler::JumpList slowCases;
- slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
-
- m_jit.load64(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), resultReg);
- slowCases.append(m_jit.branchTest64(MacroAssembler::Zero, resultReg));
-
- return slowCases;
-}
-
-MacroAssembler::JumpList SpeculativeJIT::compileArrayStorageGetByVal(Node&, GPRReg, GPRReg propertyReg, GPRReg storageReg, GPRReg resultReg)
-{
- MacroAssembler::Jump outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset()));
-
- m_jit.load64(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), resultReg);
- MacroAssembler::Jump hole = m_jit.branchTest64(MacroAssembler::Zero, resultReg);
-
- MacroAssembler::JumpList slowCases;
- slowCases.append(outOfBounds);
- slowCases.append(hole);
- return slowCases;
-}
-
-MacroAssembler::JumpList SpeculativeJIT::compileContiguousPutByVal(Node& node, GPRReg, GPRReg propertyReg, GPRReg storageReg, GPRReg valueReg, GPRReg tempReg)
-{
- Array::Mode arrayMode = node.arrayMode();
-
- MacroAssembler::JumpList slowCases;
-
- if (!mayStoreToTail(arrayMode)) {
- speculationCheck(
- Uncountable, JSValueRegs(), NoNode,
- m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
- } else {
- MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()));
-
- slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfVectorLength())));
-
- if (isInBoundsAccess(arrayMode))
- speculationCheck(Uncountable, JSValueRegs(), NoNode, slowCases);
-
- m_jit.add32(TrustedImm32(1), propertyReg, tempReg);
- m_jit.store32(tempReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()));
-
- inBounds.link(&m_jit);
- }
-
- m_jit.store64(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight));
-
- if (isInBoundsAccess(arrayMode))
- return MacroAssembler::JumpList();
- return slowCases;
-}
-
-MacroAssembler::JumpList SpeculativeJIT::compileArrayStoragePutByVal(Node& node, GPRReg, GPRReg propertyReg, GPRReg storageReg, GPRReg valueReg, GPRReg tempReg)
-{
- Array::Mode arrayMode = node.arrayMode();
-
- MacroAssembler::JumpList slowCases;
-
- MacroAssembler::Jump beyondArrayBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset()));
- if (isInBoundsAccess(arrayMode))
- speculationCheck(OutOfBounds, JSValueRegs(), NoNode, beyondArrayBounds);
- else
- slowCases.append(beyondArrayBounds);
-
- // Check if we're writing to a hole; if so increment m_numValuesInVector.
- if (!mayStoreToHole(arrayMode)) {
- // This is uncountable because if we take this exit, then the baseline JIT
- // will immediately count the hole store. So there is no need for exit
- // profiling.
- speculationCheck(
- Uncountable, JSValueRegs(), NoNode,
- m_jit.branchTest64(MacroAssembler::Zero, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))));
- } else {
- MacroAssembler::Jump notHoleValue = m_jit.branchTest64(MacroAssembler::NonZero, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
- if (isSlowPutAccess(arrayMode)) {
- // This is sort of strange. If we wanted to optimize this code path, we would invert
- // the above branch. But it's simply not worth it since this only happens if we're
- // already having a bad time.
- slowCases.append(m_jit.jump());
- } else {
- m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageReg, ArrayStorage::numValuesInVectorOffset()));
-
- // If we're writing to a hole we might be growing the array;
- MacroAssembler::Jump lengthDoesNotNeedUpdate = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset()));
- m_jit.add32(TrustedImm32(1), propertyReg, tempReg);
- m_jit.store32(tempReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset()));
-
- lengthDoesNotNeedUpdate.link(&m_jit);
- }
- notHoleValue.link(&m_jit);
- }
-
- // Store the value to the array.
- m_jit.store64(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
-
- return slowCases;
-}
-
void SpeculativeJIT::compile(Node& node)
{
NodeType op = node.op();
@@ -2733,8 +2632,13 @@
GPRTemporary result(this);
GPRReg resultReg = result.gpr();
- MacroAssembler::JumpList slowCases =
- compileContiguousGetByVal(node, baseReg, propertyReg, storageReg, resultReg);
+ MacroAssembler::JumpList slowCases;
+
+ slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
+
+ m_jit.load64(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), resultReg);
+ slowCases.append(m_jit.branchTest64(MacroAssembler::Zero, resultReg));
+
addSlowPathGenerator(
slowPathCall(
slowCases, this, operationGetByValArrayInt,
@@ -2779,8 +2683,13 @@
GPRTemporary result(this);
GPRReg resultReg = result.gpr();
- MacroAssembler::JumpList slowCases =
- compileArrayStorageGetByVal(node, baseReg, propertyReg, storageReg, resultReg);
+ MacroAssembler::JumpList slowCases;
+
+ slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset())));
+
+ m_jit.load64(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), resultReg);
+ slowCases.append(m_jit.branchTest64(MacroAssembler::Zero, resultReg));
+
addSlowPathGenerator(
slowPathCall(
slowCases, this, operationGetByValArrayInt,
@@ -2910,16 +2819,34 @@
GPRTemporary temporary;
GPRReg temporaryReg = temporaryRegisterForPutByVal(temporary, node);
- MacroAssembler::JumpList slowCases =
- compileContiguousPutByVal(
- node, baseReg, propertyReg, storageReg, valueReg, temporaryReg);
+ MacroAssembler::JumpList slowCases;
+
+ if (!mayStoreToTail(arrayMode)) {
+ speculationCheck(
+ Uncountable, JSValueRegs(), NoNode,
+ m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
+ } else {
+ MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()));
+
+ slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfVectorLength())));
+
+ if (isInBoundsAccess(arrayMode))
+ speculationCheck(Uncountable, JSValueRegs(), NoNode, slowCases);
+
+ m_jit.add32(TrustedImm32(1), propertyReg, temporaryReg);
+ m_jit.store32(temporaryReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()));
+
+ inBounds.link(&m_jit);
+ }
+
+ m_jit.store64(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight));
base.use();
property.use();
value.use();
storage.use();
- if (!slowCases.empty()) {
+ if (!isInBoundsAccess(arrayMode)) {
addSlowPathGenerator(
slowPathCall(
slowCases, this,
@@ -2961,10 +2888,45 @@
GPRTemporary temporary;
GPRReg temporaryReg = temporaryRegisterForPutByVal(temporary, node);
- MacroAssembler::JumpList slowCases =
- compileArrayStoragePutByVal(
- node, baseReg, propertyReg, storageReg, valueReg, temporaryReg);
+ MacroAssembler::JumpList slowCases;
+ MacroAssembler::Jump beyondArrayBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset()));
+ if (isInBoundsAccess(arrayMode))
+ speculationCheck(OutOfBounds, JSValueRegs(), NoNode, beyondArrayBounds);
+ else
+ slowCases.append(beyondArrayBounds);
+
+ // Check if we're writing to a hole; if so increment m_numValuesInVector.
+ if (!mayStoreToHole(arrayMode)) {
+ // This is uncountable because if we take this exit, then the baseline JIT
+ // will immediately count the hole store. So there is no need for exit
+ // profiling.
+ speculationCheck(
+ Uncountable, JSValueRegs(), NoNode,
+ m_jit.branchTest64(MacroAssembler::Zero, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))));
+ } else {
+ MacroAssembler::Jump notHoleValue = m_jit.branchTest64(MacroAssembler::NonZero, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
+ if (isSlowPutAccess(arrayMode)) {
+ // This is sort of strange. If we wanted to optimize this code path, we would invert
+ // the above branch. But it's simply not worth it since this only happens if we're
+ // already having a bad time.
+ slowCases.append(m_jit.jump());
+ } else {
+ m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageReg, ArrayStorage::numValuesInVectorOffset()));
+
+ // If we're writing to a hole we might be growing the array;
+ MacroAssembler::Jump lengthDoesNotNeedUpdate = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset()));
+ m_jit.add32(TrustedImm32(1), propertyReg, temporaryReg);
+ m_jit.store32(temporaryReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset()));
+
+ lengthDoesNotNeedUpdate.link(&m_jit);
+ }
+ notHoleValue.link(&m_jit);
+ }
+
+ // Store the value to the array.
+ m_jit.store64(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
+
base.use();
property.use();
value.use();