summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGFixupPhase.cpp')
-rw-r--r--Source/JavaScriptCore/dfg/DFGFixupPhase.cpp176
1 files changed, 87 insertions, 89 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
index f7b10fc43..fe7cae8a9 100644
--- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
@@ -74,97 +74,89 @@ private:
switch (op) {
case GetById: {
+ Node* nodePtr = &node;
+
if (!isInt32Speculation(m_graph[m_compileIndex].prediction()))
break;
- if (codeBlock()->identifier(node.identifierNumber()) != globalData().propertyNames->length)
- break;
- bool isArray = isArraySpeculation(m_graph[node.child1()].prediction());
- bool isArguments = isArgumentsSpeculation(m_graph[node.child1()].prediction());
- bool isString = isStringSpeculation(m_graph[node.child1()].prediction());
- bool isInt8Array = m_graph[node.child1()].shouldSpeculateInt8Array();
- bool isInt16Array = m_graph[node.child1()].shouldSpeculateInt16Array();
- bool isInt32Array = m_graph[node.child1()].shouldSpeculateInt32Array();
- bool isUint8Array = m_graph[node.child1()].shouldSpeculateUint8Array();
- bool isUint8ClampedArray = m_graph[node.child1()].shouldSpeculateUint8ClampedArray();
- bool isUint16Array = m_graph[node.child1()].shouldSpeculateUint16Array();
- bool isUint32Array = m_graph[node.child1()].shouldSpeculateUint32Array();
- bool isFloat32Array = m_graph[node.child1()].shouldSpeculateFloat32Array();
- bool isFloat64Array = m_graph[node.child1()].shouldSpeculateFloat64Array();
- if (!isArray && !isArguments && !isString && !isInt8Array && !isInt16Array && !isInt32Array && !isUint8Array && !isUint8ClampedArray && !isUint16Array && !isUint32Array && !isFloat32Array && !isFloat64Array)
+ if (codeBlock()->identifier(nodePtr->identifierNumber()) != globalData().propertyNames->length)
break;
-
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLog(" @%u -> %s", m_compileIndex, isArray ? "GetArrayLength" : "GetStringLength");
-#endif
- if (isArray) {
- node.setOp(GetArrayLength);
- ASSERT(node.flags() & NodeMustGenerate);
- node.clearFlags(NodeMustGenerate);
- m_graph.deref(m_compileIndex);
-
- ArrayProfile* arrayProfile =
- m_graph.baselineCodeBlockFor(node.codeOrigin)->getArrayProfile(
- node.codeOrigin.bytecodeIndex);
- if (!arrayProfile)
- break;
+ ArrayProfile* arrayProfile =
+ m_graph.baselineCodeBlockFor(nodePtr->codeOrigin)->getArrayProfile(
+ nodePtr->codeOrigin.bytecodeIndex);
+ Array::Mode arrayMode = Array::Undecided;
+ if (arrayProfile) {
arrayProfile->computeUpdatedPrediction();
- if (!arrayProfile->hasDefiniteStructure())
- break;
- m_graph.ref(node.child1());
- Node checkStructure(CheckStructure, node.codeOrigin, OpInfo(m_graph.addStructureSet(arrayProfile->expectedStructure())), node.child1().index());
- checkStructure.ref();
- NodeIndex checkStructureIndex = m_graph.size();
- m_graph.append(checkStructure);
- m_insertionSet.append(m_indexInBlock, checkStructureIndex);
- break;
+ arrayMode = refineArrayMode(
+ fromObserved(arrayProfile->observedArrayModes(), false),
+ m_graph[node.child1()].prediction(),
+ m_graph[m_compileIndex].prediction());
+ if (modeSupportsLength(arrayMode)
+ && arrayProfile->hasDefiniteStructure()) {
+ m_graph.ref(nodePtr->child1());
+ Node checkStructure(CheckStructure, nodePtr->codeOrigin, OpInfo(m_graph.addStructureSet(arrayProfile->expectedStructure())), nodePtr->child1().index());
+ checkStructure.ref();
+ NodeIndex checkStructureIndex = m_graph.size();
+ m_graph.append(checkStructure);
+ m_insertionSet.append(m_indexInBlock, checkStructureIndex);
+ nodePtr = &m_graph[m_compileIndex];
+ }
+ } else {
+ arrayMode = refineArrayMode(
+ arrayMode,
+ m_graph[node.child1()].prediction(),
+ m_graph[m_compileIndex].prediction());
}
- if (isArguments)
- node.setOp(GetArgumentsLength);
- else if (isString)
- node.setOp(GetStringLength);
- else if (isInt8Array)
- node.setOp(GetInt8ArrayLength);
- else if (isInt16Array)
- node.setOp(GetInt16ArrayLength);
- else if (isInt32Array)
- node.setOp(GetInt32ArrayLength);
- else if (isUint8Array)
- node.setOp(GetUint8ArrayLength);
- else if (isUint8ClampedArray)
- node.setOp(GetUint8ClampedArrayLength);
- else if (isUint16Array)
- node.setOp(GetUint16ArrayLength);
- else if (isUint32Array)
- node.setOp(GetUint32ArrayLength);
- else if (isFloat32Array)
- node.setOp(GetFloat32ArrayLength);
- else if (isFloat64Array)
- node.setOp(GetFloat64ArrayLength);
- else
- ASSERT_NOT_REACHED();
- // No longer MustGenerate
- ASSERT(node.flags() & NodeMustGenerate);
- node.clearFlags(NodeMustGenerate);
+ if (!modeSupportsLength(arrayMode))
+ break;
+ nodePtr->setOp(GetArrayLength);
+ ASSERT(nodePtr->flags() & NodeMustGenerate);
+ nodePtr->clearFlags(NodeMustGenerate);
m_graph.deref(m_compileIndex);
+ nodePtr->setArrayMode(arrayMode);
break;
}
case GetIndexedPropertyStorage: {
- if (!m_graph[node.child1()].prediction()
- || !m_graph[node.child2()].shouldSpeculateInteger()
- || m_graph[node.child1()].shouldSpeculateArguments()) {
- node.setOpAndDefaultFlags(Nop);
- m_graph.clearAndDerefChild1(node);
- m_graph.clearAndDerefChild2(node);
- m_graph.clearAndDerefChild3(node);
- node.setRefCount(0);
- }
+ node.setArrayMode(
+ refineArrayMode(
+ node.arrayMode(),
+ m_graph[node.child1()].prediction(),
+ m_graph[node.child2()].prediction()));
+ // Predictions should only become more, rather than less, refined. Hence
+ // if we were ever able to CSE the storage pointer for this operation,
+ // then we should always continue to be able to do so.
+ ASSERT(canCSEStorage(node.arrayMode()));
break;
}
case GetByVal:
case StringCharAt:
case StringCharCodeAt: {
- if (!!node.child3() && m_graph[node.child3()].op() == Nop)
- node.children.child3() = Edge();
+ node.setArrayMode(
+ refineArrayMode(
+ node.arrayMode(),
+ m_graph[node.child1()].prediction(),
+ m_graph[node.child2()].prediction()));
+
+ if (canCSEStorage(node.arrayMode())) {
+ if (node.child3()) {
+ ASSERT(m_graph[node.child3()].op() == GetIndexedPropertyStorage);
+ ASSERT(modesCompatibleForStorageLoad(m_graph[node.child3()].arrayMode(), node.arrayMode()));
+ } else {
+ // Make sure we don't use the node reference after we do the append.
+ Node getIndexedPropertyStorage(
+ GetIndexedPropertyStorage, node.codeOrigin, OpInfo(node.arrayMode()),
+ node.child1().index(), node.child2().index());
+ NodeIndex getIndexedPropertyStorageIndex = m_graph.size();
+ node.children.child3() = Edge(getIndexedPropertyStorageIndex);
+ m_graph.append(getIndexedPropertyStorage);
+ m_graph.ref(getIndexedPropertyStorageIndex); // Once because it's MustGenerate.
+ m_graph.ref(getIndexedPropertyStorageIndex); // And again because it's referenced from the GetByVal.
+ m_insertionSet.append(m_indexInBlock, getIndexedPropertyStorageIndex);
+ }
+ } else {
+ // See above. Continued fixup of the graph should not regress our ability
+ // to speculate.
+ ASSERT(!node.child3());
+ }
break;
}
@@ -334,24 +326,30 @@ private:
}
case PutByVal:
- case PutByValSafe: {
+ case PutByValAlias: {
Edge child1 = m_graph.varArgChild(node, 0);
Edge child2 = m_graph.varArgChild(node, 1);
Edge child3 = m_graph.varArgChild(node, 2);
- if (!m_graph[child1].prediction() || !m_graph[child2].prediction())
- break;
- if (!m_graph[child2].shouldSpeculateInteger())
+ node.setArrayMode(
+ refineArrayMode(
+ node.arrayMode(), m_graph[child1].prediction(), m_graph[child2].prediction()));
+
+ switch (modeForPut(node.arrayMode())) {
+ case Array::Int8Array:
+ case Array::Int16Array:
+ case Array::Int32Array:
+ case Array::Uint8Array:
+ case Array::Uint8ClampedArray:
+ case Array::Uint16Array:
+ case Array::Uint32Array:
+ if (!m_graph[child3].shouldSpeculateInteger())
+ fixDoubleEdge(2);
break;
- if (isActionableIntMutableArraySpeculation(m_graph[child1].prediction())) {
- if (m_graph[child3].isConstant())
- break;
- if (m_graph[child3].shouldSpeculateInteger())
- break;
+ case Array::Float32Array:
+ case Array::Float64Array:
fixDoubleEdge(2);
break;
- }
- if (isActionableFloatMutableArraySpeculation(m_graph[child1].prediction())) {
- fixDoubleEdge(2);
+ default:
break;
}
break;