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.cpp107
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();