Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (131288 => 131289)
--- trunk/Source/_javascript_Core/ChangeLog 2012-10-15 02:40:48 UTC (rev 131288)
+++ trunk/Source/_javascript_Core/ChangeLog 2012-10-15 03:17:17 UTC (rev 131289)
@@ -1,5 +1,49 @@
2012-10-14 Filip Pizlo <[email protected]>
+ DFG should handle polymorphic array modes by eagerly transforming arrays into the most general applicable form
+ https://bugs.webkit.org/show_bug.cgi?id=99269
+
+ Reviewed by Geoffrey Garen.
+
+ This kills off a bunch of code for "polymorphic" array modes in the DFG. It should
+ also be a performance win for code that uses a lot of array storage arrays.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGArrayMode.cpp:
+ (JSC::DFG::fromObserved):
+ (JSC::DFG::modeAlreadyChecked):
+ (JSC::DFG::modeToString):
+ * dfg/DFGArrayMode.h:
+ (DFG):
+ (JSC::DFG::modeUsesButterfly):
+ (JSC::DFG::modeIsJSArray):
+ (JSC::DFG::mayStoreToTail):
+ (JSC::DFG::mayStoreToHole):
+ (JSC::DFG::canCSEStorage):
+ (JSC::DFG::modeSupportsLength):
+ (JSC::DFG::benefitsFromStructureCheck):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::checkArray):
+ (JSC::DFG::FixupPhase::blessArrayOperation):
+ * dfg/DFGGraph.h:
+ (JSC::DFG::Graph::byValIsPure):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::jumpSlowForUnwantedArrayMode):
+ (JSC::DFG::SpeculativeJIT::checkArray):
+ (JSC::DFG::SpeculativeJIT::arrayify):
+ (DFG):
+ (JSC::DFG::SpeculativeJIT::compileGetArrayLength):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::putByValWillNeedExtraRegister):
+ (SpeculativeJIT):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2012-10-14 Filip Pizlo <[email protected]>
+
REGRESSION(126886): Fat binary builds don't know how to handle architecture variants to which the LLInt is agnostic
https://bugs.webkit.org/show_bug.cgi?id=99270
Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractState.cpp (131288 => 131289)
--- trunk/Source/_javascript_Core/dfg/DFGAbstractState.cpp 2012-10-15 02:40:48 UTC (rev 131288)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractState.cpp 2012-10-15 03:17:17 UTC (rev 131289)
@@ -868,7 +868,6 @@
case OUT_OF_BOUNDS_ARRAY_STORAGE_MODES:
case SLOW_PUT_ARRAY_STORAGE_MODES:
case ALL_EFFECTFUL_MODES:
- case POLYMORPHIC_MODES:
forNode(node.child1()).filter(SpecCell);
forNode(node.child2()).filter(SpecInt32);
clobberWorld(node.codeOrigin, indexInBlock);
@@ -943,7 +942,6 @@
case OUT_OF_BOUNDS_ARRAY_STORAGE_MODES:
case SLOW_PUT_ARRAY_STORAGE_MODES:
case ALL_EFFECTFUL_MODES:
- case POLYMORPHIC_MODES:
forNode(child1).filter(SpecCell);
forNode(child2).filter(SpecInt32);
clobberWorld(node.codeOrigin, indexInBlock);
@@ -1384,7 +1382,6 @@
break;
case ALL_CONTIGUOUS_MODES:
case ALL_ARRAY_STORAGE_MODES:
- case POLYMORPHIC_MODES: // These only get a CheckArray for GetArrayLength
// This doesn't filter anything meaningful right now. We may want to add
// CFA tracking of array mode speculations, but we don't have that, yet.
forNode(node.child1()).filter(SpecCell);
@@ -1430,7 +1427,8 @@
case ALL_EFFECTFUL_MODES:
node.setCanExit(true);
forNode(node.child1()).filter(SpecCell);
- forNode(node.child2()).filter(SpecInt32);
+ if (node.child2())
+ forNode(node.child2()).filter(SpecInt32);
forNode(nodeIndex).clear();
clobberStructures(indexInBlock);
break;
Modified: trunk/Source/_javascript_Core/dfg/DFGArrayMode.cpp (131288 => 131289)
--- trunk/Source/_javascript_Core/dfg/DFGArrayMode.cpp 2012-10-15 02:40:48 UTC (rev 131288)
+++ trunk/Source/_javascript_Core/dfg/DFGArrayMode.cpp 2012-10-15 03:17:17 UTC (rev 131289)
@@ -39,7 +39,7 @@
return Array::Unprofiled;
case asArrayModes(NonArray):
if (action == Array::Write && !profile->mayInterceptIndexedAccesses())
- return Array::BlankToContiguousOrArrayStorage; // FIXME: we don't know whether to go to slow put mode or not. We're guessing that we don't need slow put.
+ return Array::ToContiguous; // FIXME: we don't know whether to go to contiguous or array storage. We're making a static guess here. In future we should use exit profiling for this.
return Array::Undecided;
case asArrayModes(NonArrayWithContiguous):
return makeSafe ? Array::ContiguousOutOfBounds : (profile->mayStoreToHole() ? Array::ContiguousToTail : Array::Contiguous);
@@ -63,27 +63,24 @@
case asArrayModes(NonArrayWithArrayStorage) | asArrayModes(ArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage):
return Array::PossiblyArrayWithSlowPutArrayStorage;
case asArrayModes(NonArrayWithContiguous) | asArrayModes(NonArrayWithArrayStorage):
- return Array::ContiguousOrArrayStorage;
+ return Array::ToArrayStorage;
case asArrayModes(ArrayWithContiguous) | asArrayModes(ArrayWithArrayStorage):
- return Array::ArrayWithContiguousOrArrayStorage;
+ return Array::ArrayToArrayStorage;
case asArrayModes(NonArrayWithContiguous) | asArrayModes(NonArrayWithArrayStorage) | asArrayModes(ArrayWithContiguous) | asArrayModes(ArrayWithArrayStorage):
- return Array::PossiblyArrayWithContiguousOrArrayStorage;
+ return Array::PossiblyArrayToArrayStorage;
case asArrayModes(NonArray) | asArrayModes(NonArrayWithContiguous):
if (action == Array::Write && !profile->mayInterceptIndexedAccesses())
- return Array::BlankToContiguous;
+ return Array::ToContiguous;
return Array::Undecided;
case asArrayModes(NonArray) | asArrayModes(NonArrayWithContiguous) | asArrayModes(NonArrayWithArrayStorage):
- if (action == Array::Write && !profile->mayInterceptIndexedAccesses())
- return Array::BlankToContiguousOrArrayStorage;
- return Array::Undecided;
case asArrayModes(NonArray) | asArrayModes(NonArrayWithArrayStorage):
if (action == Array::Write && !profile->mayInterceptIndexedAccesses())
- return Array::BlankToArrayStorage;
+ return Array::ToArrayStorage;
return Array::Undecided;
case asArrayModes(NonArray) | asArrayModes(NonArrayWithSlowPutArrayStorage):
case asArrayModes(NonArray) | asArrayModes(NonArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage):
if (action == Array::Write && !profile->mayInterceptIndexedAccesses())
- return Array::BlankToSlowPutArrayStorage;
+ return Array::ToSlowPutArrayStorage;
return Array::Undecided;
default:
// We know that this is possibly a kind of array for which, though there is no
@@ -207,7 +204,6 @@
&& (value.m_currentKnownStructure.singleton()->indexingType() & IsArray);
case ALL_EFFECTFUL_MODES:
- case POLYMORPHIC_MODES:
return false;
case Array::Arguments:
@@ -304,20 +300,16 @@
return "PossiblyArrayWithSlowPutArrayStorage";
case Array::PossiblyArrayWithArrayStorageOutOfBounds:
return "PossiblyArrayWithArrayStorageOutOfBounds";
- case Array::BlankToContiguous:
- return "BlankToContiguous";
- case Array::BlankToArrayStorage:
- return "BlankToArrayStorage";
- case Array::BlankToSlowPutArrayStorage:
- return "BlankToSlowPutArrayStorage";
- case Array::BlankToContiguousOrArrayStorage:
- return "BlankToContiguousOrArrayStorage";
- case Array::ContiguousOrArrayStorage:
- return "ContiguousOrArrayStorage";
- case Array::ArrayWithContiguousOrArrayStorage:
- return "ArrayWithContiguousOrArrayStorage";
- case Array::PossiblyArrayWithContiguousOrArrayStorage:
- return "PossiblyArrayWithContiguousOrArrayStorage";
+ case Array::ToContiguous:
+ return "ToContiguous";
+ case Array::ToArrayStorage:
+ return "ToArrayStorage";
+ case Array::ToSlowPutArrayStorage:
+ return "ToSlowPutArrayStorage";
+ case Array::ArrayToArrayStorage:
+ return "ArrayToArrayStorage";
+ case Array::PossiblyArrayToArrayStorage:
+ return "PossiblyArrayToArrayStorage";
case Array::Arguments:
return "Arguments";
case Array::Int8Array:
Modified: trunk/Source/_javascript_Core/dfg/DFGArrayMode.h (131288 => 131289)
--- trunk/Source/_javascript_Core/dfg/DFGArrayMode.h 2012-10-15 02:40:48 UTC (rev 131288)
+++ trunk/Source/_javascript_Core/dfg/DFGArrayMode.h 2012-10-15 03:17:17 UTC (rev 131289)
@@ -77,17 +77,12 @@
PossiblyArrayWithArrayStorageOutOfBounds,
// Modes of conventional indexed storage where the check is side-effecting.
- BlankToContiguous,
- BlankToArrayStorage,
- BlankToSlowPutArrayStorage,
- BlankToContiguousOrArrayStorage,
+ ToContiguous,
+ ToArrayStorage,
+ ArrayToArrayStorage,
+ PossiblyArrayToArrayStorage,
+ ToSlowPutArrayStorage,
- // Modes that indicate polymorphic array storage. These don't benefit from
- // any checking or storage CSE.
- ContiguousOrArrayStorage,
- ArrayWithContiguousOrArrayStorage,
- PossiblyArrayWithContiguousOrArrayStorage,
-
Arguments,
Int8Array,
Int16Array,
@@ -167,31 +162,26 @@
case Array::PossiblyArrayWithArrayStorageOutOfBounds
// Next: helpers for side-effecting checks.
+#define NON_ARRAY_EFFECTFUL_MODES \
+ Array::ToContiguous: \
+ case Array::ToArrayStorage: \
+ case Array::ToSlowPutArrayStorage: \
+ case Array::PossiblyArrayToArrayStorage
+#define ARRAY_EFFECTFUL_MODES \
+ Array::ArrayToArrayStorage
#define ALL_EFFECTFUL_CONTIGUOUS_MODES \
- Array::BlankToContiguous
-#define EFFECTFUL_NON_ARRAY_ARRAY_STORAGE_MODES \
- Array::BlankToArrayStorage: \
- case Array::BlankToSlowPutArrayStorage
+ Array::ToContiguous
#define ALL_EFFECTFUL_ARRAY_STORAGE_MODES \
- EFFECTFUL_NON_ARRAY_ARRAY_STORAGE_MODES
+ Array::ToArrayStorage: \
+ case Array::ToSlowPutArrayStorage: \
+ case Array::ArrayToArrayStorage: \
+ case Array::PossiblyArrayToArrayStorage
#define SLOW_PUT_EFFECTFUL_ARRAY_STORAGE_MODES \
- Array::BlankToSlowPutArrayStorage
-#define POLYMORPHIC_EFFECTFUL_MODES \
- Array::BlankToContiguousOrArrayStorage
+ Array::ToSlowPutArrayStorage
#define ALL_EFFECTFUL_MODES \
ALL_EFFECTFUL_CONTIGUOUS_MODES: \
- case ALL_EFFECTFUL_ARRAY_STORAGE_MODES: \
- case POLYMORPHIC_EFFECTFUL_MODES
+ case ALL_EFFECTFUL_ARRAY_STORAGE_MODES
-// Finally: helpers for polymorphic array accesses.
-#define POLYMORPHIC_MODES \
- Array::ContiguousOrArrayStorage: \
- case Array::ArrayWithContiguousOrArrayStorage: \
- case Array::PossiblyArrayWithContiguousOrArrayStorage
-#define ALL_POLYMORPHIC_MODES \
- POLYMORPHIC_EFFECTFUL_MODES: \
- case POLYMORPHIC_MODES
-
Array::Mode fromObserved(ArrayProfile*, Array::Action, bool makeSafe);
Array::Mode refineArrayMode(Array::Mode, SpeculatedType base, SpeculatedType index);
@@ -206,7 +196,6 @@
case ALL_CONTIGUOUS_MODES:
case ALL_ARRAY_STORAGE_MODES:
case ALL_EFFECTFUL_MODES:
- case POLYMORPHIC_MODES:
return true;
default:
return false;
@@ -218,7 +207,7 @@
switch (arrayMode) {
case ARRAY_WITH_CONTIGUOUS_MODES:
case ARRAY_WITH_ARRAY_STORAGE_MODES:
- case Array::ArrayWithContiguousOrArrayStorage:
+ case ARRAY_EFFECTFUL_MODES:
return true;
default:
return false;
@@ -255,7 +244,6 @@
case CONTIGUOUS_TO_TAIL_MODES:
case OUT_OF_BOUNDS_CONTIGUOUS_MODES:
case ALL_EFFECTFUL_CONTIGUOUS_MODES:
- case ALL_POLYMORPHIC_MODES:
return true;
default:
return false;
@@ -269,35 +257,12 @@
case OUT_OF_BOUNDS_ARRAY_STORAGE_MODES:
case SLOW_PUT_ARRAY_STORAGE_MODES:
case ALL_EFFECTFUL_ARRAY_STORAGE_MODES:
- case ALL_POLYMORPHIC_MODES:
return true;
default:
return false;
}
}
-inline bool modeIsPolymorphic(Array::Mode mode)
-{
- switch (mode) {
- case ALL_POLYMORPHIC_MODES:
- return true;
- default:
- return false;
- }
-}
-
-inline bool polymorphicIncludesContiguous(Array::Mode arrayMode)
-{
- ASSERT_UNUSED(arrayMode, modeIsPolymorphic(arrayMode));
- return true;
-}
-
-inline bool polymorphicIncludesArrayStorage(Array::Mode arrayMode)
-{
- ASSERT_UNUSED(arrayMode, modeIsPolymorphic(arrayMode));
- return true;
-}
-
inline bool canCSEStorage(Array::Mode arrayMode)
{
switch (arrayMode) {
@@ -306,7 +271,6 @@
case Array::ForceExit:
case Array::Generic:
case Array::Arguments:
- case ALL_POLYMORPHIC_MODES:
return false;
default:
return true;
@@ -354,9 +318,7 @@
case Array::Generic:
case NON_ARRAY_CONTIGUOUS_MODES:
case NON_ARRAY_ARRAY_STORAGE_MODES:
- case ALL_EFFECTFUL_MODES:
- case Array::ContiguousOrArrayStorage:
- case Array::PossiblyArrayWithContiguousOrArrayStorage:
+ case NON_ARRAY_EFFECTFUL_MODES:
return false;
default:
return true;
@@ -367,7 +329,6 @@
{
switch (mode) {
case ALL_EFFECTFUL_MODES:
- case POLYMORPHIC_MODES:
case Array::Undecided:
case Array::Unprofiled:
case Array::ForceExit:
Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (131288 => 131289)
--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2012-10-15 02:40:48 UTC (rev 131288)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2012-10-15 03:17:17 UTC (rev 131289)
@@ -382,8 +382,8 @@
m_graph.ref(array);
if (isEffectful(arrayMode)) {
- ASSERT(index != NoNode);
- m_graph.ref(index);
+ if (index != NoNode)
+ m_graph.ref(index);
Node arrayify(Arrayify, codeOrigin, OpInfo(arrayMode), array, index);
arrayify.ref(); // Once because it's used as a butterfly.
arrayify.ref(); // And twice because it's must-generate.
@@ -391,11 +391,12 @@
m_graph.append(arrayify);
m_insertionSet.append(m_indexInBlock, arrayifyIndex);
- ASSERT(storageCheck == canCSEStorage);
ASSERT(shouldGenerate);
ASSERT(canCSEStorage(arrayMode));
ASSERT(modeUsesButterfly(arrayMode));
-
+
+ if (!storageCheck(arrayMode))
+ return NoNode;
return arrayifyIndex;
}
@@ -440,7 +441,6 @@
return;
case Array::Generic:
- case ALL_POLYMORPHIC_MODES:
return;
default: {
Modified: trunk/Source/_javascript_Core/dfg/DFGGraph.h (131288 => 131289)
--- trunk/Source/_javascript_Core/dfg/DFGGraph.h 2012-10-15 02:40:48 UTC (rev 131288)
+++ trunk/Source/_javascript_Core/dfg/DFGGraph.h 2012-10-15 03:17:17 UTC (rev 131289)
@@ -484,7 +484,6 @@
case OUT_OF_BOUNDS_ARRAY_STORAGE_MODES:
case SLOW_PUT_ARRAY_STORAGE_MODES:
case ALL_EFFECTFUL_MODES:
- case POLYMORPHIC_MODES:
return false;
case Array::String:
return node.op() == GetByVal;
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (131288 => 131289)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2012-10-15 02:40:48 UTC (rev 131288)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2012-10-15 03:17:17 UTC (rev 131289)
@@ -379,17 +379,6 @@
TrustedImm32(SlowPutArrayStorageShape - ArrayStorageShape)));
break;
}
- case POLYMORPHIC_MODES: {
- if (modeIsJSArray(arrayMode)) {
- result.append(
- m_jit.branchTest32(
- MacroAssembler::Zero, tempGPR, TrustedImm32(IsArray)));
- }
- result.append(
- m_jit.branchTest32(
- MacroAssembler::Zero, tempGPR, TrustedImm32(IndexingShapeMask)));
- break;
- }
default:
CRASH();
break;
@@ -421,8 +410,7 @@
case NON_ARRAY_CONTIGUOUS_MODES:
case ARRAY_WITH_CONTIGUOUS_MODES:
case NON_ARRAY_ARRAY_STORAGE_MODES:
- case ARRAY_WITH_ARRAY_STORAGE_MODES:
- case POLYMORPHIC_MODES: {
+ case ARRAY_WITH_ARRAY_STORAGE_MODES: {
GPRTemporary temp(this);
GPRReg tempGPR = temp.gpr();
m_jit.loadPtr(
@@ -467,31 +455,26 @@
noResult(m_compileIndex);
}
-void SpeculativeJIT::arrayify(Node& node)
+void SpeculativeJIT::arrayify(Node& node, GPRReg baseReg, GPRReg propertyReg)
{
- ASSERT(modeIsSpecific(node.arrayMode()));
- ASSERT(!modeAlreadyChecked(m_state.forNode(node.child1()), node.arrayMode()));
-
- SpeculateCellOperand base(this, node.child1());
- SpeculateIntegerOperand property(this, node.child2());
- GPRReg baseReg = base.gpr();
- GPRReg propertyReg = property.gpr();
-
Array::Mode desiredArrayMode;
switch (node.arrayMode()) {
- case Array::BlankToContiguous:
+ case Array::ToContiguous:
desiredArrayMode = Array::Contiguous;
break;
- case Array::BlankToArrayStorage:
+ case Array::ToArrayStorage:
desiredArrayMode = Array::ArrayStorage;
break;
- case Array::BlankToSlowPutArrayStorage:
+ case Array::ToSlowPutArrayStorage:
desiredArrayMode = Array::SlowPutArrayStorage;
break;
- case Array::BlankToContiguousOrArrayStorage:
- desiredArrayMode = Array::ContiguousOrArrayStorage;
+ case Array::ArrayToArrayStorage:
+ desiredArrayMode = Array::ArrayWithArrayStorage;
break;
+ case Array::PossiblyArrayToArrayStorage:
+ desiredArrayMode = Array::PossiblyArrayWithArrayStorage;
+ break;
default:
CRASH();
desiredArrayMode = Array::Undecided;
@@ -522,7 +505,7 @@
// If we're allegedly creating contiguous storage and the index is bogus, then
// just don't.
- if (node.arrayMode() == Array::BlankToContiguous) {
+ if (node.arrayMode() == Array::ToContiguous && propertyReg != InvalidGPRReg) {
speculationCheck(
Uncountable, JSValueRegs(), NoNode,
m_jit.branch32(
@@ -541,16 +524,12 @@
// Now call out to create the array storage.
silentSpillAllRegisters(tempGPR);
switch (node.arrayMode()) {
- case Array::BlankToContiguous:
+ case ALL_EFFECTFUL_CONTIGUOUS_MODES:
callOperation(operationEnsureContiguous, tempGPR, baseReg);
break;
- case Array::BlankToArrayStorage:
- case Array::BlankToSlowPutArrayStorage:
+ case ALL_EFFECTFUL_ARRAY_STORAGE_MODES:
callOperation(operationEnsureArrayStorage, tempGPR, baseReg);
break;
- case Array::BlankToContiguousOrArrayStorage:
- callOperation(operationEnsureContiguousOrArrayStorage, tempGPR, baseReg, propertyReg);
- break;
default:
CRASH();
break;
@@ -572,11 +551,28 @@
speculationCheck(
Uncountable, JSValueRegs(), NoNode,
jumpSlowForUnwantedArrayMode(structureGPR, desiredArrayMode));
-
+
done.link(&m_jit);
storageResult(tempGPR, m_compileIndex);
}
+void SpeculativeJIT::arrayify(Node& node)
+{
+ ASSERT(modeIsSpecific(node.arrayMode()));
+ ASSERT(!modeAlreadyChecked(m_state.forNode(node.child1()), node.arrayMode()));
+
+ SpeculateCellOperand base(this, node.child1());
+
+ if (!node.child2()) {
+ arrayify(node, base.gpr(), InvalidGPRReg);
+ return;
+ }
+
+ SpeculateIntegerOperand property(this, node.child2());
+
+ arrayify(node, base.gpr(), property.gpr());
+}
+
GPRReg SpeculativeJIT::fillStorage(NodeIndex nodeIndex)
{
Node& node = m_jit.graph()[nodeIndex];
@@ -3336,7 +3332,7 @@
break;
}
case ARRAY_WITH_ARRAY_STORAGE_MODES:
- case Array::ArrayWithContiguousOrArrayStorage: {
+ case ARRAY_EFFECTFUL_MODES: {
StorageOperand storage(this, node.child2());
GPRTemporary result(this, storage);
GPRReg storageReg = storage.gpr();
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (131288 => 131289)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2012-10-15 02:40:48 UTC (rev 131288)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2012-10-15 03:17:17 UTC (rev 131289)
@@ -2215,10 +2215,6 @@
case ALL_EFFECTFUL_CONTIGUOUS_MODES:
return true;
- // All polymorphic modes need an extra reg.
- case ALL_POLYMORPHIC_MODES:
- return true;
-
default:
return false;
}
@@ -2373,6 +2369,7 @@
JITCompiler::JumpList jumpSlowForUnwantedArrayMode(GPRReg tempWithIndexingTypeReg, Array::Mode arrayMode);
void checkArray(Node&);
+ void arrayify(Node&, GPRReg baseReg, GPRReg propertyReg);
void arrayify(Node&);
template<bool strict>
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (131288 => 131289)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2012-10-15 02:40:48 UTC (rev 131288)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2012-10-15 03:17:17 UTC (rev 131289)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
* Copyright (C) 2011 Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -2782,57 +2782,6 @@
jsValueResult(resultTagReg, resultPayloadReg, m_compileIndex);
break;
}
- case ALL_POLYMORPHIC_MODES: {
- SpeculateCellOperand base(this, node.child1());
- SpeculateStrictInt32Operand property(this, node.child2());
-
- GPRReg baseReg = base.gpr();
- GPRReg propertyReg = property.gpr();
-
- if (!m_compileOkay)
- return;
-
- GPRTemporary storage(this);
- GPRTemporary resultTag(this);
- GPRTemporary resultPayload(this);
- GPRReg storageReg = storage.gpr();
- GPRReg resultTagReg = resultTag.gpr();
- GPRReg resultPayloadReg = resultPayload.gpr();
-
- MacroAssembler::JumpList slowCases;
- MacroAssembler::JumpList doneCases;
- MacroAssembler::Jump fallThrough;
- m_jit.loadPtr(MacroAssembler::Address(baseReg, JSCell::structureOffset()), resultTagReg);
- m_jit.loadPtr(MacroAssembler::Address(baseReg, JSObject::butterflyOffset()), storageReg);
- m_jit.load8(MacroAssembler::Address(resultTagReg, Structure::indexingTypeOffset()), resultTagReg);
- m_jit.and32(TrustedImm32(IndexingShapeMask), resultTagReg);
- if (polymorphicIncludesContiguous(node.arrayMode())) {
- if (fallThrough.isSet()) {
- doneCases.append(m_jit.jump());
- fallThrough.link(&m_jit);
- }
- fallThrough = m_jit.branch32(MacroAssembler::NotEqual, resultTagReg, MacroAssembler::TrustedImm32(ContiguousShape));
- slowCases.append(compileContiguousGetByVal(node, baseReg, propertyReg, storageReg, resultTagReg, resultPayloadReg));
- }
- if (polymorphicIncludesArrayStorage(node.arrayMode())) {
- if (fallThrough.isSet()) {
- doneCases.append(m_jit.jump());
- fallThrough.link(&m_jit);
- }
- fallThrough = m_jit.branch32(MacroAssembler::NotEqual, resultTagReg, MacroAssembler::TrustedImm32(ArrayStorageShape));
- slowCases.append(compileArrayStorageGetByVal(node, baseReg, propertyReg, storageReg, resultTagReg, resultPayloadReg));
- }
- ASSERT(fallThrough.isSet());
- doneCases.link(&m_jit);
- slowCases.append(fallThrough);
- addSlowPathGenerator(
- slowPathCall(
- slowCases, this, operationGetByValArrayInt,
- JSValueRegs(resultTagReg, resultPayloadReg), baseReg, propertyReg));
-
- jsValueResult(resultTagReg, resultPayloadReg, m_compileIndex);
- break;
- }
case Array::String:
compileGetByValOnString(node);
break;
@@ -3022,64 +2971,6 @@
break;
}
- case ALL_POLYMORPHIC_MODES: {
- ASSERT(node.op() == PutByVal);
-
- JSValueOperand value(this, child3);
-
- GPRReg valueTagReg = value.tagGPR();
- GPRReg valuePayloadReg = value.payloadGPR();
-
- if (!m_compileOkay)
- return;
-
- GPRTemporary storage(this);
- GPRReg storageReg = storage.gpr();
-
- MacroAssembler::JumpList slowCases;
- MacroAssembler::JumpList doneCases;
- MacroAssembler::Jump fallThrough;
- m_jit.loadPtr(MacroAssembler::Address(baseReg, JSCell::structureOffset()), storageReg);
- m_jit.load8(MacroAssembler::Address(storageReg, Structure::indexingTypeOffset()), storageReg);
- m_jit.and32(TrustedImm32(IndexingShapeMask), storageReg);
- if (polymorphicIncludesContiguous(node.arrayMode())) {
- if (fallThrough.isSet()) {
- doneCases.append(m_jit.jump());
- fallThrough.link(&m_jit);
- }
- fallThrough = m_jit.branch32(MacroAssembler::NotEqual, storageReg, MacroAssembler::TrustedImm32(ContiguousShape));
- m_jit.loadPtr(MacroAssembler::Address(baseReg, JSObject::butterflyOffset()), storageReg);
- slowCases.append(compileContiguousPutByVal(node, baseReg, propertyReg, storageReg, valueTagReg, valuePayloadReg));
- }
- if (polymorphicIncludesArrayStorage(node.arrayMode())) {
- if (fallThrough.isSet()) {
- doneCases.append(m_jit.jump());
- fallThrough.link(&m_jit);
- }
- fallThrough = m_jit.branch32(MacroAssembler::NotEqual, storageReg, MacroAssembler::TrustedImm32(ArrayStorageShape));
- m_jit.loadPtr(MacroAssembler::Address(baseReg, JSObject::butterflyOffset()), storageReg);
- slowCases.append(compileArrayStoragePutByVal(node, baseReg, propertyReg, storageReg, valueTagReg, valuePayloadReg));
- }
- ASSERT(fallThrough.isSet());
- doneCases.link(&m_jit);
- slowCases.append(fallThrough);
-
- base.use();
- property.use();
- value.use();
-
- // FIXME: the decision of whether or not we're in strict mode should be made
- // based on the inline call frame, not the machine code block.
- addSlowPathGenerator(
- slowPathCall(
- slowCases, this,
- m_jit.codeBlock()->isStrictMode() ? operationPutByValBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsNonStrict,
- NoResult, baseReg, propertyReg, valueTagReg, valuePayloadReg));
-
- noResult(m_compileIndex, UseChildrenCalledExplicitly);
- break;
- }
-
case Array::Arguments:
// FIXME: we could at some point make this work. Right now we're assuming that the register
// pressure would be too great.
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (131288 => 131289)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2012-10-15 02:40:48 UTC (rev 131288)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2012-10-15 03:17:17 UTC (rev 131289)
@@ -2788,55 +2788,6 @@
jsValueResult(resultReg, m_compileIndex);
break;
}
- case ALL_POLYMORPHIC_MODES: {
- SpeculateCellOperand base(this, node.child1());
- SpeculateStrictInt32Operand property(this, node.child2());
-
- GPRReg baseReg = base.gpr();
- GPRReg propertyReg = property.gpr();
-
- if (!m_compileOkay)
- return;
-
- GPRTemporary storage(this);
- GPRTemporary result(this);
- GPRReg storageReg = storage.gpr();
- GPRReg resultReg = result.gpr();
-
- MacroAssembler::JumpList slowCases;
- MacroAssembler::JumpList doneCases;
- MacroAssembler::Jump fallThrough;
- m_jit.loadPtr(MacroAssembler::Address(baseReg, JSCell::structureOffset()), resultReg);
- m_jit.loadPtr(MacroAssembler::Address(baseReg, JSObject::butterflyOffset()), storageReg);
- m_jit.load8(MacroAssembler::Address(resultReg, Structure::indexingTypeOffset()), resultReg);
- m_jit.and32(TrustedImm32(IndexingShapeMask), resultReg);
- if (polymorphicIncludesContiguous(node.arrayMode())) {
- if (fallThrough.isSet()) {
- doneCases.append(m_jit.jump());
- fallThrough.link(&m_jit);
- }
- fallThrough = m_jit.branch32(MacroAssembler::NotEqual, resultReg, MacroAssembler::TrustedImm32(ContiguousShape));
- slowCases.append(compileContiguousGetByVal(node, baseReg, propertyReg, storageReg, resultReg));
- }
- if (polymorphicIncludesArrayStorage(node.arrayMode())) {
- if (fallThrough.isSet()) {
- doneCases.append(m_jit.jump());
- fallThrough.link(&m_jit);
- }
- fallThrough = m_jit.branch32(MacroAssembler::NotEqual, resultReg, MacroAssembler::TrustedImm32(ArrayStorageShape));
- slowCases.append(compileArrayStorageGetByVal(node, baseReg, propertyReg, storageReg, resultReg));
- }
- ASSERT(fallThrough.isSet());
- doneCases.link(&m_jit);
- slowCases.append(fallThrough);
- addSlowPathGenerator(
- slowPathCall(
- slowCases, this, operationGetByValArrayInt,
- result.gpr(), baseReg, propertyReg));
-
- jsValueResult(resultReg, m_compileIndex);
- break;
- }
case Array::String:
compileGetByValOnString(node);
break;
@@ -3030,64 +2981,6 @@
break;
}
- case ALL_POLYMORPHIC_MODES: {
- ASSERT(node.op() == PutByVal);
-
- JSValueOperand value(this, child3);
-
- GPRReg valueReg = value.gpr();
-
- if (!m_compileOkay)
- return;
-
- GPRTemporary storage(this);
- GPRTemporary temporary(this);
- GPRReg storageReg = storage.gpr();
- GPRReg temporaryReg = temporary.gpr();
-
- MacroAssembler::JumpList slowCases;
- MacroAssembler::JumpList doneCases;
- MacroAssembler::Jump fallThrough;
- m_jit.loadPtr(MacroAssembler::Address(baseReg, JSCell::structureOffset()), temporaryReg);
- m_jit.loadPtr(MacroAssembler::Address(baseReg, JSObject::butterflyOffset()), storageReg);
- m_jit.load8(MacroAssembler::Address(temporaryReg, Structure::indexingTypeOffset()), temporaryReg);
- m_jit.and32(TrustedImm32(IndexingShapeMask), temporaryReg);
- if (polymorphicIncludesContiguous(node.arrayMode())) {
- if (fallThrough.isSet()) {
- doneCases.append(m_jit.jump());
- fallThrough.link(&m_jit);
- }
- fallThrough = m_jit.branch32(MacroAssembler::NotEqual, temporaryReg, MacroAssembler::TrustedImm32(ContiguousShape));
- slowCases.append(compileContiguousPutByVal(node, baseReg, propertyReg, storageReg, valueReg, temporaryReg));
- }
- if (polymorphicIncludesArrayStorage(node.arrayMode())) {
- if (fallThrough.isSet()) {
- doneCases.append(m_jit.jump());
- fallThrough.link(&m_jit);
- }
- fallThrough = m_jit.branch32(MacroAssembler::NotEqual, temporaryReg, MacroAssembler::TrustedImm32(ArrayStorageShape));
- slowCases.append(compileArrayStoragePutByVal(node, baseReg, propertyReg, storageReg, valueReg, temporaryReg));
- }
- ASSERT(fallThrough.isSet());
- doneCases.link(&m_jit);
- slowCases.append(fallThrough);
-
- base.use();
- property.use();
- value.use();
-
- // FIXME: the decision of whether or not we're in strict mode should be made
- // based on the inline call frame, not the machine code block.
- addSlowPathGenerator(
- slowPathCall(
- slowCases, this,
- m_jit.codeBlock()->isStrictMode() ? operationPutByValBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsNonStrict,
- NoResult, baseReg, propertyReg, valueReg));
-
- noResult(m_compileIndex, UseChildrenCalledExplicitly);
- break;
- }
-
case Array::Arguments: {
JSValueOperand value(this, child3);
GPRTemporary scratch(this);