summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-09-10 19:10:20 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-09-10 19:10:20 +0200
commit284837daa07b29d6a63a748544a90b1f5842ac5c (patch)
treeecd258180bde91fe741e0cfd2638beb3c6da7e8e /Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
parent2e2ba8ff45915f40ed3e014101269c175f2a89a0 (diff)
downloadqtwebkit-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.cpp116
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];