diff options
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp | 474 |
1 files changed, 286 insertions, 188 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp index 98bdaac06..53174604a 100644 --- a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp +++ b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Apple Inc. All rights reserved. + * Copyright (C) 2011, 2012 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -45,8 +45,8 @@ public: #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) m_count = 0; #endif - // Two stage process: first propagate predictions, then propagate while doing double voting. - + // 1) propagate predictions + do { m_changed = false; @@ -64,6 +64,8 @@ public: propagateBackward(); } while (m_changed); + // 2) repropagate predictions while doing double voting. + do { m_changed = false; doRoundOfDoubleVoting(); @@ -75,8 +77,6 @@ public: doRoundOfDoubleVoting(); propagateBackward(); } while (m_changed); - - fixup(); } private: @@ -100,15 +100,31 @@ private: return m_graph[m_compileIndex].predict(prediction); } + bool isNotNegZero(NodeIndex nodeIndex) + { + if (!m_graph.isNumberConstant(nodeIndex)) + return false; + double value = m_graph.valueOfNumberConstant(nodeIndex); + return !value && 1.0 / value < 0.0; + } + + bool isNotZero(NodeIndex nodeIndex) + { + if (!m_graph.isNumberConstant(nodeIndex)) + return false; + return !!m_graph.valueOfNumberConstant(nodeIndex); + } + void propagate(Node& node) { if (!node.shouldGenerate()) return; - NodeType op = static_cast<NodeType>(node.op); + NodeType op = node.op(); + NodeFlags flags = node.flags() & NodeBackPropMask; #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) - dataLog(" %s @%u: ", Graph::opName(op), m_compileIndex); + dataLog(" %s @%u: %s ", Graph::opName(op), m_compileIndex, nodeFlagsAsString(flags)); #endif bool changed = false; @@ -121,14 +137,26 @@ private: } case GetLocal: { - PredictedType prediction = node.variableAccessData()->prediction(); + VariableAccessData* variableAccessData = node.variableAccessData(); + PredictedType prediction = variableAccessData->prediction(); if (prediction) changed |= mergePrediction(prediction); + + changed |= variableAccessData->mergeFlags(flags); break; } case SetLocal: { - changed |= node.variableAccessData()->predict(m_graph[node.child1()].prediction()); + VariableAccessData* variableAccessData = node.variableAccessData(); + changed |= variableAccessData->predict(m_graph[node.child1()].prediction()); + changed |= m_graph[node.child1()].mergeFlags(variableAccessData->flags()); + break; + } + + case Flush: { + // Make sure that the analysis knows that flushed locals escape. + VariableAccessData* variableAccessData = node.variableAccessData(); + changed |= variableAccessData->mergeFlags(NodeUsedAsValue); break; } @@ -137,21 +165,47 @@ private: case BitXor: case BitRShift: case BitLShift: - case BitURShift: + case BitURShift: { + changed |= setPrediction(PredictInt32); + flags |= NodeUsedAsInt; + flags &= ~(NodeUsedAsNumber | NodeNeedsNegZero); + changed |= m_graph[node.child1()].mergeFlags(flags); + changed |= m_graph[node.child2()].mergeFlags(flags); + break; + } + case ValueToInt32: { changed |= setPrediction(PredictInt32); + flags |= NodeUsedAsInt; + flags &= ~(NodeUsedAsNumber | NodeNeedsNegZero); + changed |= m_graph[node.child1()].mergeFlags(flags); break; } - case ArrayPop: + case ArrayPop: { + changed |= mergePrediction(node.getHeapPrediction()); + changed |= mergeDefaultFlags(node); + break; + } + case ArrayPush: { - if (node.getHeapPrediction()) - changed |= mergePrediction(node.getHeapPrediction()); + changed |= mergePrediction(node.getHeapPrediction()); + changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue); + changed |= m_graph[node.child2()].mergeFlags(NodeUsedAsValue); + break; + } + + case RegExpExec: + case RegExpTest: { + changed |= mergePrediction(node.getHeapPrediction()); + changed |= mergeDefaultFlags(node); break; } case StringCharCodeAt: { changed |= mergePrediction(PredictInt32); + changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue); + changed |= m_graph[node.child2()].mergeFlags(NodeUsedAsNumber | NodeUsedAsInt); break; } @@ -160,19 +214,26 @@ private: PredictedType right = m_graph[node.child2()].prediction(); if (left && right) { - if (isInt32Prediction(mergePredictions(left, right)) && nodeCanSpeculateInteger(node.arithNodeFlags())) + if (isInt32Prediction(mergePredictions(left, right)) + && nodeCanSpeculateInteger(node.arithNodeFlags())) changed |= mergePrediction(PredictInt32); else changed |= mergePrediction(PredictDouble); } + + flags |= NodeUsedAsValue; + changed |= m_graph[node.child1()].mergeFlags(flags); + changed |= m_graph[node.child2()].mergeFlags(flags); break; } case UInt32ToNumber: { if (nodeCanSpeculateInteger(node.arithNodeFlags())) - changed |= setPrediction(PredictInt32); + changed |= mergePrediction(PredictInt32); else - changed |= setPrediction(PredictNumber); + changed |= mergePrediction(PredictNumber); + + changed |= m_graph[node.child1()].mergeFlags(flags); break; } @@ -192,10 +253,34 @@ private: } else changed |= mergePrediction(PredictString | PredictInt32 | PredictDouble); } + + if (isNotNegZero(node.child1().index()) || isNotNegZero(node.child2().index())) + flags &= ~NodeNeedsNegZero; + + changed |= m_graph[node.child1()].mergeFlags(flags); + changed |= m_graph[node.child2()].mergeFlags(flags); + break; + } + + case ArithAdd: { + PredictedType left = m_graph[node.child1()].prediction(); + PredictedType right = m_graph[node.child2()].prediction(); + + if (left && right) { + if (m_graph.addShouldSpeculateInteger(node)) + changed |= mergePrediction(PredictInt32); + else + changed |= mergePrediction(PredictDouble); + } + + if (isNotNegZero(node.child1().index()) || isNotNegZero(node.child2().index())) + flags &= ~NodeNeedsNegZero; + + changed |= m_graph[node.child1()].mergeFlags(flags); + changed |= m_graph[node.child2()].mergeFlags(flags); break; } - case ArithAdd: case ArithSub: { PredictedType left = m_graph[node.child1()].prediction(); PredictedType right = m_graph[node.child2()].prediction(); @@ -206,6 +291,12 @@ private: else changed |= mergePrediction(PredictDouble); } + + if (isNotZero(node.child1().index()) || isNotZero(node.child2().index())) + flags &= ~NodeNeedsNegZero; + + changed |= m_graph[node.child1()].mergeFlags(flags); + changed |= m_graph[node.child2()].mergeFlags(flags); break; } @@ -216,37 +307,68 @@ private: else changed |= mergePrediction(PredictDouble); } + + changed |= m_graph[node.child1()].mergeFlags(flags); break; - case ArithMul: case ArithMin: - case ArithMax: + case ArithMax: { + PredictedType left = m_graph[node.child1()].prediction(); + PredictedType right = m_graph[node.child2()].prediction(); + + if (left && right) { + if (isInt32Prediction(mergePredictions(left, right)) + && nodeCanSpeculateInteger(node.arithNodeFlags())) + changed |= mergePrediction(PredictInt32); + else + changed |= mergePrediction(PredictDouble); + } + + flags |= NodeUsedAsNumber; + changed |= m_graph[node.child1()].mergeFlags(flags); + changed |= m_graph[node.child2()].mergeFlags(flags); + break; + } + + case ArithMul: case ArithDiv: { PredictedType left = m_graph[node.child1()].prediction(); PredictedType right = m_graph[node.child2()].prediction(); if (left && right) { - if (isInt32Prediction(mergePredictions(left, right)) && nodeCanSpeculateInteger(node.arithNodeFlags())) + if (isInt32Prediction(mergePredictions(left, right)) + && nodeCanSpeculateInteger(node.arithNodeFlags())) changed |= mergePrediction(PredictInt32); else changed |= mergePrediction(PredictDouble); } + + // As soon as a multiply happens, we can easily end up in the part + // of the double domain where the point at which you do truncation + // can change the outcome. So, ArithMul always checks for overflow + // no matter what, and always forces its inputs to check as well. + + flags |= NodeUsedAsNumber | NodeNeedsNegZero; + changed |= m_graph[node.child1()].mergeFlags(flags); + changed |= m_graph[node.child2()].mergeFlags(flags); break; } case ArithSqrt: { changed |= setPrediction(PredictDouble); + changed |= m_graph[node.child1()].mergeFlags(flags | NodeUsedAsValue); break; } case ArithAbs: { PredictedType child = m_graph[node.child1()].prediction(); - if (child) { - if (nodeCanSpeculateInteger(node.arithNodeFlags())) - changed |= mergePrediction(child); - else - changed |= setPrediction(PredictDouble); - } + if (nodeCanSpeculateInteger(node.arithNodeFlags())) + changed |= mergePrediction(child); + else + changed |= setPrediction(PredictDouble); + + flags &= ~NodeNeedsNegZero; + changed |= m_graph[node.child1()].mergeFlags(flags); break; } @@ -257,64 +379,63 @@ private: case CompareGreaterEq: case CompareEq: case CompareStrictEq: - case InstanceOf: { + case InstanceOf: + case IsUndefined: + case IsBoolean: + case IsNumber: + case IsString: + case IsObject: + case IsFunction: { changed |= setPrediction(PredictBoolean); + changed |= mergeDefaultFlags(node); break; } case GetById: { - if (node.getHeapPrediction()) - changed |= mergePrediction(node.getHeapPrediction()); - else if (codeBlock()->identifier(node.identifierNumber()) == globalData().propertyNames->length) { - // If there is no prediction from value profiles, check if we might be - // able to infer the type ourselves. - bool isArray = isArrayPrediction(m_graph[node.child1()].prediction()); - bool isString = isStringPrediction(m_graph[node.child1()].prediction()); - bool isByteArray = m_graph[node.child1()].shouldSpeculateByteArray(); - 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 || isString || isByteArray || isInt8Array || isInt16Array || isInt32Array || isUint8Array || isUint8ClampedArray || isUint16Array || isUint32Array || isFloat32Array || isFloat64Array) - changed |= mergePrediction(PredictInt32); - } + changed |= mergePrediction(node.getHeapPrediction()); + changed |= mergeDefaultFlags(node); break; } case GetByIdFlush: - if (node.getHeapPrediction()) - changed |= mergePrediction(node.getHeapPrediction()); + changed |= mergePrediction(node.getHeapPrediction()); + changed |= mergeDefaultFlags(node); break; case GetByVal: { - if (m_graph[node.child1()].shouldSpeculateUint32Array() || m_graph[node.child1()].shouldSpeculateFloat32Array() || m_graph[node.child1()].shouldSpeculateFloat64Array()) + if (m_graph[node.child1()].shouldSpeculateFloat32Array() + || m_graph[node.child1()].shouldSpeculateFloat64Array()) changed |= mergePrediction(PredictDouble); - else if (node.getHeapPrediction()) + else changed |= mergePrediction(node.getHeapPrediction()); + + changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue); + changed |= m_graph[node.child2()].mergeFlags(NodeUsedAsNumber | NodeUsedAsInt); break; } case GetPropertyStorage: case GetIndexedPropertyStorage: { changed |= setPrediction(PredictOther); + changed |= mergeDefaultFlags(node); break; } case GetByOffset: { - if (node.getHeapPrediction()) - changed |= mergePrediction(node.getHeapPrediction()); + changed |= mergePrediction(node.getHeapPrediction()); + changed |= mergeDefaultFlags(node); break; } case Call: case Construct: { - if (node.getHeapPrediction()) - changed |= mergePrediction(node.getHeapPrediction()); + changed |= mergePrediction(node.getHeapPrediction()); + for (unsigned childIdx = node.firstChild(); + childIdx < node.firstChild() + node.numChildren(); + ++childIdx) { + Edge edge = m_graph.m_varArgChildren[childIdx]; + changed |= m_graph[edge].mergeFlags(NodeUsedAsValue); + } break; } @@ -327,18 +448,17 @@ private: } changed |= mergePrediction(prediction); } + changed |= mergeDefaultFlags(node); break; } case GetGlobalVar: { - PredictedType prediction = m_graph.getGlobalVarPrediction(node.varNumber()); - if (prediction) - changed |= mergePrediction(prediction); + changed |= mergePrediction(node.getHeapPrediction()); break; } case PutGlobalVar: { - changed |= m_graph.predictGlobalVar(node.varNumber(), m_graph[node.child1()].prediction()); + changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue); break; } @@ -348,8 +468,7 @@ private: case ResolveBaseStrictPut: case ResolveGlobal: { PredictedType prediction = node.getHeapPrediction(); - if (prediction) - changed |= mergePrediction(prediction); + changed |= mergePrediction(prediction); break; } @@ -366,10 +485,21 @@ private: case CreateThis: case NewObject: { changed |= setPrediction(PredictFinalObject); + changed |= mergeDefaultFlags(node); + break; + } + + case NewArray: { + changed |= setPrediction(PredictArray); + for (unsigned childIdx = node.firstChild(); + childIdx < node.firstChild() + node.numChildren(); + ++childIdx) { + Edge edge = m_graph.m_varArgChildren[childIdx]; + changed |= m_graph[edge].mergeFlags(NodeUsedAsValue); + } break; } - case NewArray: case NewArrayBuffer: { changed |= setPrediction(PredictArray); break; @@ -380,9 +510,19 @@ private: break; } - case StringCharAt: + case StringCharAt: { + changed |= setPrediction(PredictString); + changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue); + changed |= m_graph[node.child2()].mergeFlags(NodeUsedAsNumber | NodeUsedAsInt); + break; + } + case StrCat: { changed |= setPrediction(PredictString); + for (unsigned childIdx = node.firstChild(); + childIdx < node.firstChild() + node.numChildren(); + ++childIdx) + changed |= m_graph[m_graph.m_varArgChildren[childIdx]].mergeFlags(NodeUsedAsNumber); break; } @@ -399,10 +539,12 @@ private: } else if (child & PredictObjectMask) { // Objects get turned into strings. So if the input has hints of objectness, // the output will have hinsts of stringiness. - changed |= mergePrediction(mergePredictions(child & ~PredictObjectMask, PredictString)); + changed |= mergePrediction( + mergePredictions(child & ~PredictObjectMask, PredictString)); } else changed |= mergePrediction(child); } + changed |= m_graph[node.child1()].mergeFlags(flags); break; } @@ -418,8 +560,8 @@ private: break; } + case PutByValAlias: case GetArrayLength: - case GetByteArrayLength: case GetInt8ArrayLength: case GetInt16ArrayLength: case GetInt32ArrayLength: @@ -429,38 +571,56 @@ private: case GetUint32ArrayLength: case GetFloat32ArrayLength: case GetFloat64ArrayLength: - case GetStringLength: { + case GetStringLength: + case Int32ToDouble: + case DoubleAsInt32: { // This node should never be visible at this stage of compilation. It is // inserted by fixup(), which follows this phase. ASSERT_NOT_REACHED(); break; } - case Flush: + case PutByVal: + changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue); + changed |= m_graph[node.child2()].mergeFlags(NodeUsedAsNumber | NodeUsedAsInt); + changed |= m_graph[node.child3()].mergeFlags(NodeUsedAsValue); + break; + + case PutScopedVar: + case Return: + case Throw: + changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue); + break; + + case PutById: + case PutByIdDirect: + changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue); + changed |= m_graph[node.child2()].mergeFlags(NodeUsedAsValue); + break; + + case PutByOffset: + changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue); + changed |= m_graph[node.child3()].mergeFlags(NodeUsedAsValue); + break; + + case Phi: break; #ifndef NDEBUG // These get ignored because they don't return anything. - case PutScopedVar: case DFG::Jump: case Branch: case Breakpoint: - case Return: case CheckHasInstance: - case Phi: - case Throw: case ThrowReferenceError: case ForceOSRExit: case SetArgument: - case PutByVal: - case PutByValAlias: - case PutById: - case PutByIdDirect: case CheckStructure: case CheckFunction: case PutStructure: - case PutByOffset: case TearOffActivation: + case CheckNumber: + changed |= mergeDefaultFlags(node); break; // These gets ignored because it doesn't do anything. @@ -474,6 +634,7 @@ private: break; #else default: + changed |= mergeDefaultFlags(node); break; #endif } @@ -484,6 +645,28 @@ private: m_changed |= changed; } + + bool mergeDefaultFlags(Node& node) + { + bool changed = false; + if (node.flags() & NodeHasVarArgs) { + for (unsigned childIdx = node.firstChild(); + childIdx < node.firstChild() + node.numChildren(); + childIdx++) + changed |= m_graph[m_graph.m_varArgChildren[childIdx]].mergeFlags(NodeUsedAsValue); + } else { + if (!node.child1()) + return changed; + changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue); + if (!node.child2()) + return changed; + changed |= m_graph[node.child2()].mergeFlags(NodeUsedAsValue); + if (!node.child3()) + return changed; + changed |= m_graph[node.child3()].mergeFlags(NodeUsedAsValue); + } + return changed; + } void propagateForward() { @@ -502,10 +685,10 @@ private: for (m_compileIndex = m_graph.size(); m_compileIndex-- > 0;) propagate(m_graph[m_compileIndex]); } - - void vote(NodeUse nodeUse, VariableAccessData::Ballot ballot) + + void vote(Edge nodeUse, VariableAccessData::Ballot ballot) { - switch (m_graph[nodeUse].op) { + switch (m_graph[nodeUse].op()) { case ValueToInt32: case UInt32ToNumber: nodeUse = m_graph[nodeUse].child1(); @@ -514,14 +697,16 @@ private: break; } - if (m_graph[nodeUse].op == GetLocal) + if (m_graph[nodeUse].op() == GetLocal) m_graph[nodeUse].variableAccessData()->vote(ballot); } void vote(Node& node, VariableAccessData::Ballot ballot) { - if (node.flags & NodeHasVarArgs) { - for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++) + if (node.flags() & NodeHasVarArgs) { + for (unsigned childIdx = node.firstChild(); + childIdx < node.firstChild() + node.numChildren(); + childIdx++) vote(m_graph.m_varArgChildren[childIdx], ballot); return; } @@ -546,7 +731,7 @@ private: m_graph.m_variableAccessData[i].find()->clearVotes(); for (m_compileIndex = 0; m_compileIndex < m_graph.size(); ++m_compileIndex) { Node& node = m_graph[m_compileIndex]; - switch (node.op) { + switch (node.op()) { case ValueAdd: case ArithAdd: case ArithSub: { @@ -576,7 +761,9 @@ private: VariableAccessData::Ballot ballot; - if (isNumberPrediction(left) && isNumberPrediction(right) && !(Node::shouldSpeculateInteger(m_graph[node.child1()], m_graph[node.child1()]) && node.canSpeculateInteger())) + if (isNumberPrediction(left) && isNumberPrediction(right) + && !(Node::shouldSpeculateInteger(m_graph[node.child1()], m_graph[node.child1()]) + && node.canSpeculateInteger())) ballot = VariableAccessData::VoteDouble; else ballot = VariableAccessData::VoteValue; @@ -588,7 +775,8 @@ private: case ArithAbs: VariableAccessData::Ballot ballot; - if (!(m_graph[node.child1()].shouldSpeculateInteger() && node.canSpeculateInteger())) + if (!(m_graph[node.child1()].shouldSpeculateInteger() + && node.canSpeculateInteger())) ballot = VariableAccessData::VoteDouble; else ballot = VariableAccessData::VoteValue; @@ -615,115 +803,25 @@ private: } } for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) { - VariableAccessData* variableAccessData = m_graph.m_variableAccessData[i].find(); + VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i]; + if (!variableAccessData->isRoot()) + continue; if (operandIsArgument(variableAccessData->local()) || m_graph.isCaptured(variableAccessData->local())) continue; m_changed |= variableAccessData->tallyVotesForShouldUseDoubleFormat(); } - } - - void fixupNode(Node& node) - { - if (!node.shouldGenerate()) - return; - - NodeType op = static_cast<NodeType>(node.op); - -#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) - dataLog(" %s @%u: ", Graph::opName(op), m_compileIndex); -#endif - - switch (op) { - case GetById: { - if (!isInt32Prediction(m_graph[m_compileIndex].prediction())) - break; - if (codeBlock()->identifier(node.identifierNumber()) != globalData().propertyNames->length) - break; - bool isArray = isArrayPrediction(m_graph[node.child1()].prediction()); - bool isString = isStringPrediction(m_graph[node.child1()].prediction()); - bool isByteArray = m_graph[node.child1()].shouldSpeculateByteArray(); - 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 && !isString && !isByteArray && !isInt8Array && !isInt16Array && !isInt32Array && !isUint8Array && !isUint8ClampedArray && !isUint16Array && !isUint32Array && !isFloat32Array && !isFloat64Array) - break; - -#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) - dataLog(" @%u -> %s", m_compileIndex, isArray ? "GetArrayLength" : "GetStringLength"); -#endif - if (isArray) - node.op = GetArrayLength; - else if (isString) - node.op = GetStringLength; - else if (isByteArray) - node.op = GetByteArrayLength; - else if (isInt8Array) - node.op = GetInt8ArrayLength; - else if (isInt16Array) - node.op = GetInt16ArrayLength; - else if (isInt32Array) - node.op = GetInt32ArrayLength; - else if (isUint8Array) - node.op = GetUint8ArrayLength; - else if (isUint8ClampedArray) - node.op = GetUint8ClampedArrayLength; - else if (isUint16Array) - node.op = GetUint16ArrayLength; - else if (isUint32Array) - node.op = GetUint32ArrayLength; - else if (isFloat32Array) - node.op = GetFloat32ArrayLength; - else if (isFloat64Array) - node.op = GetFloat64ArrayLength; - else - ASSERT_NOT_REACHED(); - // No longer MustGenerate - ASSERT(node.flags & NodeMustGenerate); - node.flags &= ~NodeMustGenerate; - m_graph.deref(m_compileIndex); - break; - } - case GetIndexedPropertyStorage: { - PredictedType basePrediction = m_graph[node.child2()].prediction(); - if (!(basePrediction & PredictInt32) && basePrediction) { - node.setOpAndDefaultFlags(Nop); - m_graph.clearAndDerefChild1(node); - m_graph.clearAndDerefChild2(node); - m_graph.clearAndDerefChild3(node); - node.setRefCount(0); - } - break; - } - case GetByVal: - case StringCharAt: - case StringCharCodeAt: { - if (!!node.child3() && m_graph[node.child3()].op == Nop) - node.children.child3() = NodeUse(); - break; - } - default: - break; + for (unsigned i = 0; i < m_graph.m_argumentPositions.size(); ++i) + m_changed |= m_graph.m_argumentPositions[i].mergeArgumentAwareness(); + for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) { + VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i]; + if (!variableAccessData->isRoot()) + continue; + if (operandIsArgument(variableAccessData->local()) + || m_graph.isCaptured(variableAccessData->local())) + continue; + m_changed |= variableAccessData->makePredictionForDoubleFormat(); } - -#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) - dataLog("\n"); -#endif - } - - void fixup() - { -#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) - dataLog("Performing Fixup\n"); -#endif - for (m_compileIndex = 0; m_compileIndex < m_graph.size(); ++m_compileIndex) - fixupNode(m_graph[m_compileIndex]); } NodeIndex m_compileIndex; |