diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-09-10 19:10:20 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-09-10 19:10:20 +0200 |
commit | 284837daa07b29d6a63a748544a90b1f5842ac5c (patch) | |
tree | ecd258180bde91fe741e0cfd2638beb3c6da7e8e /Source/JavaScriptCore/dfg/DFGFixupPhase.cpp | |
parent | 2e2ba8ff45915f40ed3e014101269c175f2a89a0 (diff) | |
download | qtwebkit-284837daa07b29d6a63a748544a90b1f5842ac5c.tar.gz |
Imported WebKit commit 68645295d2e3e09af2c942f092556f06aa5f8b0d (http://svn.webkit.org/repository/webkit/trunk@128073)
New snapshot
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGFixupPhase.cpp')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGFixupPhase.cpp | 116 |
1 files changed, 83 insertions, 33 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp index fe7cae8a9..7700b4b86 100644 --- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp +++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp @@ -74,6 +74,9 @@ private: switch (op) { case GetById: { + if (m_graph.m_fixpointState > BeforeFixpoint) + break; + Node* nodePtr = &node; if (!isInt32Speculation(m_graph[m_compileIndex].prediction())) @@ -90,8 +93,7 @@ private: fromObserved(arrayProfile->observedArrayModes(), false), m_graph[node.child1()].prediction(), m_graph[m_compileIndex].prediction()); - if (modeSupportsLength(arrayMode) - && arrayProfile->hasDefiniteStructure()) { + 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(); @@ -113,17 +115,16 @@ private: nodePtr->clearFlags(NodeMustGenerate); m_graph.deref(m_compileIndex); nodePtr->setArrayMode(arrayMode); + + NodeIndex storage = checkArray(arrayMode, nodePtr->codeOrigin, nodePtr->child1().index(), lengthNeedsStorage, nodePtr->shouldGenerate()); + if (storage == NoNode) + break; + + nodePtr = &m_graph[m_compileIndex]; + nodePtr->children.child2() = Edge(storage); break; } case GetIndexedPropertyStorage: { - 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; } @@ -136,30 +137,19 @@ private: 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()); - } + blessArrayOperation(node.child1(), 2); + break; + } + + case ArrayPush: { + blessArrayOperation(node.child1(), 2); break; } + case ArrayPop: { + blessArrayOperation(node.child1(), 1); + } + case ValueToInt32: { if (m_graph[node.child1()].shouldSpeculateNumber() && node.mustGenerate()) { @@ -330,11 +320,18 @@ private: Edge child1 = m_graph.varArgChild(node, 0); Edge child2 = m_graph.varArgChild(node, 1); Edge child3 = m_graph.varArgChild(node, 2); + node.setArrayMode( refineArrayMode( - node.arrayMode(), m_graph[child1].prediction(), m_graph[child2].prediction())); + node.arrayMode(), + m_graph[child1].prediction(), + m_graph[child2].prediction())); + + blessArrayOperation(child1, 3); - switch (modeForPut(node.arrayMode())) { + Node* nodePtr = &m_graph[m_compileIndex]; + + switch (modeForPut(nodePtr->arrayMode())) { case Array::Int8Array: case Array::Int16Array: case Array::Int32Array: @@ -368,6 +365,59 @@ private: #endif } + NodeIndex checkArray(Array::Mode arrayMode, CodeOrigin codeOrigin, NodeIndex array, bool (*storageCheck)(Array::Mode) = canCSEStorage, bool shouldGenerate = true) + { + ASSERT(modeIsSpecific(arrayMode)); + + m_graph.ref(array); + Node checkArray(CheckArray, codeOrigin, OpInfo(arrayMode), array); + checkArray.ref(); + NodeIndex checkArrayIndex = m_graph.size(); + m_graph.append(checkArray); + m_insertionSet.append(m_indexInBlock, checkArrayIndex); + + if (!storageCheck(arrayMode)) + return NoNode; + + if (shouldGenerate) + m_graph.ref(array); + Node getIndexedPropertyStorage( + GetIndexedPropertyStorage, codeOrigin, OpInfo(arrayMode), array); + if (shouldGenerate) + getIndexedPropertyStorage.ref(); + NodeIndex getIndexedPropertyStorageIndex = m_graph.size(); + m_graph.append(getIndexedPropertyStorage); + m_insertionSet.append(m_indexInBlock, getIndexedPropertyStorageIndex); + + return getIndexedPropertyStorageIndex; + } + + void blessArrayOperation(Edge base, unsigned storageChildIdx) + { + if (m_graph.m_fixpointState > BeforeFixpoint) + return; + + Node* nodePtr = &m_graph[m_compileIndex]; + + if (nodePtr->arrayMode() == Array::ForceExit) { + Node forceExit(ForceOSRExit, nodePtr->codeOrigin); + forceExit.ref(); + NodeIndex forceExitIndex = m_graph.size(); + m_graph.append(forceExit); + m_insertionSet.append(m_indexInBlock, forceExitIndex); + return; + } + + if (!modeIsSpecific(nodePtr->arrayMode())) + return; + + NodeIndex storage = checkArray(nodePtr->arrayMode(), nodePtr->codeOrigin, base.index()); + if (storage == NoNode) + return; + + m_graph.child(m_graph[m_compileIndex], storageChildIdx) = Edge(storage); + } + void fixIntEdge(Edge& edge) { Node& node = m_graph[edge]; |