diff options
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGFixupPhase.cpp')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGFixupPhase.cpp | 107 |
1 files changed, 64 insertions, 43 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp index 5dcfe08a5..5a76aa8df 100644 --- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp +++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp @@ -86,14 +86,14 @@ private: ArrayProfile* arrayProfile = m_graph.baselineCodeBlockFor(nodePtr->codeOrigin)->getArrayProfile( nodePtr->codeOrigin.bytecodeIndex); - Array::Mode arrayMode = Array::SelectUsingPredictions; + ArrayMode arrayMode = ArrayMode(Array::SelectUsingPredictions); if (arrayProfile) { - arrayProfile->computeUpdatedPrediction(); - arrayMode = refineArrayMode( - fromObserved(arrayProfile, Array::Read, false), + arrayProfile->computeUpdatedPrediction(m_graph.baselineCodeBlockFor(node.codeOrigin)); + arrayMode = ArrayMode::fromObserved(arrayProfile, Array::Read, false); + arrayMode = arrayMode.refine( m_graph[node.child1()].prediction(), m_graph[m_compileIndex].prediction()); - if (modeSupportsLength(arrayMode) && arrayProfile->hasDefiniteStructure()) { + if (arrayMode.supportsLength() && arrayProfile->hasDefiniteStructure()) { m_graph.ref(nodePtr->child1()); Node checkStructure(CheckStructure, nodePtr->codeOrigin, OpInfo(m_graph.addStructureSet(arrayProfile->expectedStructure())), nodePtr->child1().index()); checkStructure.ref(); @@ -103,12 +103,11 @@ private: nodePtr = &m_graph[m_compileIndex]; } } else { - arrayMode = refineArrayMode( - arrayMode, + arrayMode = arrayMode.refine( m_graph[node.child1()].prediction(), m_graph[m_compileIndex].prediction()); } - if (!modeSupportsLength(arrayMode)) + if (!arrayMode.supportsLength()) break; nodePtr->setOp(GetArrayLength); ASSERT(nodePtr->flags() & NodeMustGenerate); @@ -125,21 +124,25 @@ private: break; } case GetIndexedPropertyStorage: { - ASSERT(canCSEStorage(node.arrayMode())); + ASSERT(node.arrayMode().canCSEStorage()); break; } - case GetByVal: - case StringCharAt: - case StringCharCodeAt: { + case GetByVal: { node.setArrayMode( - refineArrayMode( - node.arrayMode(), + node.arrayMode().refine( m_graph[node.child1()].prediction(), m_graph[node.child2()].prediction())); blessArrayOperation(node.child1(), node.child2(), 2); break; } + case StringCharAt: + case StringCharCodeAt: { + // Currently we have no good way of refining these. + ASSERT(node.arrayMode() == ArrayMode(Array::String)); + blessArrayOperation(node.child1(), node.child2(), 2); + break; + } case ArrayPush: { blessArrayOperation(node.child1(), node.child2(), 2); @@ -323,8 +326,7 @@ private: Edge child3 = m_graph.varArgChild(node, 2); node.setArrayMode( - refineArrayMode( - node.arrayMode(), + node.arrayMode().refine( m_graph[child1].prediction(), m_graph[child2].prediction())); @@ -332,7 +334,7 @@ private: Node* nodePtr = &m_graph[m_compileIndex]; - switch (modeForPut(nodePtr->arrayMode())) { + switch (nodePtr->arrayMode().modeForPut().type()) { case Array::Int8Array: case Array::Int16Array: case Array::Int32Array: @@ -376,47 +378,66 @@ private: return nodeIndex; } - NodeIndex checkArray(Array::Mode arrayMode, CodeOrigin codeOrigin, NodeIndex array, NodeIndex index, bool (*storageCheck)(Array::Mode) = canCSEStorage, bool shouldGenerate = true) + NodeIndex checkArray(ArrayMode arrayMode, CodeOrigin codeOrigin, NodeIndex array, NodeIndex index, bool (*storageCheck)(const ArrayMode&) = canCSEStorage, bool shouldGenerate = true) { - ASSERT(modeIsSpecific(arrayMode)); + ASSERT(arrayMode.isSpecific()); m_graph.ref(array); - if (isEffectful(arrayMode)) { + if (arrayMode.doesConversion()) { 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. - NodeIndex arrayifyIndex = m_graph.size(); - m_graph.append(arrayify); - m_insertionSet.append(m_indexInBlock, arrayifyIndex); - - ASSERT(shouldGenerate); - ASSERT(canCSEStorage(arrayMode)); - ASSERT(modeUsesButterfly(arrayMode)); - - if (!storageCheck(arrayMode)) - return NoNode; - return arrayifyIndex; + + Structure* structure = 0; + if (arrayMode.isJSArrayWithOriginalStructure()) { + JSGlobalObject* globalObject = m_graph.baselineCodeBlockFor(codeOrigin)->globalObject(); + switch (arrayMode.type()) { + case Array::Contiguous: + structure = globalObject->arrayStructure(); + if (structure->indexingType() != ArrayWithContiguous) + structure = 0; + break; + case Array::ArrayStorage: + structure = globalObject->arrayStructureWithArrayStorage(); + if (structure->indexingType() != ArrayWithArrayStorage) + structure = 0; + break; + default: + break; + } + } + + if (structure) { + Node arrayify(ArrayifyToStructure, codeOrigin, OpInfo(structure), OpInfo(arrayMode.asWord()), array, index); + arrayify.ref(); + NodeIndex arrayifyIndex = m_graph.size(); + m_graph.append(arrayify); + m_insertionSet.append(m_indexInBlock, arrayifyIndex); + } else { + Node arrayify(Arrayify, codeOrigin, OpInfo(arrayMode.asWord()), array, index); + arrayify.ref(); + NodeIndex arrayifyIndex = m_graph.size(); + m_graph.append(arrayify); + m_insertionSet.append(m_indexInBlock, arrayifyIndex); + } + } else { + Node checkArray(CheckArray, codeOrigin, OpInfo(arrayMode.asWord()), array); + checkArray.ref(); + NodeIndex checkArrayIndex = m_graph.size(); + m_graph.append(checkArray); + m_insertionSet.append(m_indexInBlock, checkArrayIndex); } - 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); - if (modeUsesButterfly(arrayMode)) + if (arrayMode.usesButterfly()) return addNode(Node(GetButterfly, codeOrigin, array), shouldGenerate); - return addNode(Node(GetIndexedPropertyStorage, codeOrigin, OpInfo(arrayMode), array), shouldGenerate); + return addNode(Node(GetIndexedPropertyStorage, codeOrigin, OpInfo(arrayMode.asWord()), array), shouldGenerate); } void blessArrayOperation(Edge base, Edge index, unsigned storageChildIdx) @@ -426,7 +447,7 @@ private: Node* nodePtr = &m_graph[m_compileIndex]; - switch (nodePtr->arrayMode()) { + switch (nodePtr->arrayMode().type()) { case Array::ForceExit: { Node forceExit(ForceOSRExit, nodePtr->codeOrigin); forceExit.ref(); |