summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2016-04-10 09:28:39 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2016-04-10 09:28:39 +0000
commit32761a6cee1d0dee366b885b7b9c777e67885688 (patch)
treed6bec92bebfb216f4126356e55518842c2f476a1 /Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
parenta4e969f4965059196ca948db781e52f7cfebf19e (diff)
downloadWebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp')
-rw-r--r--Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp609
1 files changed, 192 insertions, 417 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
index 9283ae302..d859849a3 100644
--- a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,10 +30,21 @@
#include "DFGGraph.h"
#include "DFGPhase.h"
-#include "JSCInlines.h"
+#include "Operations.h"
namespace JSC { namespace DFG {
+SpeculatedType resultOfToPrimitive(SpeculatedType type)
+{
+ if (type & SpecObject) {
+ // Objects get turned into strings. So if the input has hints of objectness,
+ // the output will have hinsts of stringiness.
+ return mergeSpeculations(type & ~SpecObject, SpecString);
+ }
+
+ return type;
+}
+
class PredictionPropagationPhase : public Phase {
public:
PredictionPropagationPhase(Graph& graph)
@@ -45,31 +56,9 @@ public:
{
ASSERT(m_graph.m_form == ThreadedCPS);
ASSERT(m_graph.m_unificationState == GloballyUnified);
-
- propagateThroughArgumentPositions();
-
- m_pass = PrimaryPass;
- propagateToFixpoint();
- m_pass = RareCasePass;
- propagateToFixpoint();
-
- m_pass = DoubleVotingPass;
- do {
- m_changed = false;
- doRoundOfDoubleVoting();
- if (!m_changed)
- break;
- m_changed = false;
- propagateForward();
- } while (m_changed);
-
- return true;
- }
-
-private:
- void propagateToFixpoint()
- {
+ // 1) propagate predictions
+
do {
m_changed = false;
@@ -86,8 +75,22 @@ private:
m_changed = false;
propagateBackward();
} while (m_changed);
+
+ // 2) repropagate predictions while doing double voting.
+
+ do {
+ m_changed = false;
+ doRoundOfDoubleVoting();
+ if (!m_changed)
+ break;
+ m_changed = false;
+ propagateForward();
+ } while (m_changed);
+
+ return true;
}
+private:
bool setPrediction(SpeculatedType prediction)
{
ASSERT(m_currentNode->hasResult());
@@ -110,14 +113,11 @@ private:
SpeculatedType speculatedDoubleTypeForPrediction(SpeculatedType value)
{
- SpeculatedType result = SpecDoubleReal;
- if (value & SpecDoubleImpureNaN)
- result |= SpecDoubleImpureNaN;
- if (value & SpecDoublePureNaN)
- result |= SpecDoublePureNaN;
- if (!isFullNumberOrBooleanSpeculation(value))
- result |= SpecDoublePureNaN;
- return result;
+ if (!isFullNumberSpeculation(value))
+ return SpecDouble;
+ if (value & SpecDoubleNaN)
+ return SpecDouble;
+ return SpecDoubleReal;
}
SpeculatedType speculatedDoubleTypeForPredictions(SpeculatedType left, SpeculatedType right)
@@ -132,23 +132,19 @@ private:
bool changed = false;
switch (op) {
- case JSConstant: {
- SpeculatedType type = speculationFromValue(node->asJSValue());
- if (type == SpecInt52AsDouble && enableInt52())
+ case JSConstant:
+ case WeakJSConstant: {
+ SpeculatedType type = speculationFromValue(m_graph.valueOfJSConstant(node));
+ if (type == SpecInt52AsDouble)
type = SpecInt52;
changed |= setPrediction(type);
break;
}
- case DoubleConstant: {
- SpeculatedType type = speculationFromValue(node->asJSValue());
- changed |= setPrediction(type);
- break;
- }
case GetLocal: {
VariableAccessData* variable = node->variableAccessData();
SpeculatedType prediction = variable->prediction();
- if (!variable->couldRepresentInt52() && (prediction & SpecInt52))
+ if (variable->shouldNeverUnbox() && (prediction & SpecInt52))
prediction = (prediction | SpecInt52AsDouble) & ~SpecInt52;
if (prediction)
changed |= mergePrediction(prediction);
@@ -167,8 +163,7 @@ private:
case BitRShift:
case BitLShift:
case BitURShift:
- case ArithIMul:
- case ArithClz32: {
+ case ArithIMul: {
changed |= setPrediction(SpecInt32);
break;
}
@@ -177,60 +172,17 @@ private:
case ArrayPush:
case RegExpExec:
case RegExpTest:
- case StringReplace:
case GetById:
case GetByIdFlush:
+ case GetMyArgumentByValSafe:
case GetByOffset:
- case MultiGetByOffset:
- case GetDirectPname:
case Call:
- case TailCallInlinedCaller:
case Construct:
- case CallVarargs:
- case TailCallVarargsInlinedCaller:
- case ConstructVarargs:
- case CallForwardVarargs:
- case ConstructForwardVarargs:
- case TailCallForwardVarargsInlinedCaller:
case GetGlobalVar:
- case GetGlobalLexicalVariable:
- case GetClosureVar:
- case GetFromArguments: {
+ case GetClosureVar: {
changed |= setPrediction(node->getHeapPrediction());
break;
}
-
- case GetGetterSetterByOffset:
- case GetExecutable: {
- changed |= setPrediction(SpecCellOther);
- break;
- }
-
- case GetGetter:
- case GetSetter:
- case GetCallee:
- case NewArrowFunction:
- case NewFunction:
- case NewGeneratorFunction: {
- changed |= setPrediction(SpecFunction);
- break;
- }
-
- case GetArgumentCount: {
- changed |= setPrediction(SpecInt32);
- break;
- }
-
- case GetRestLength: {
- changed |= setPrediction(SpecInt32);
- break;
- }
-
- case GetTypedArrayByteOffset:
- case GetArrayLength: {
- changed |= setPrediction(SpecInt32);
- break;
- }
case StringCharCodeAt: {
changed |= setPrediction(SpecInt32);
@@ -240,7 +192,7 @@ private:
case UInt32ToNumber: {
// FIXME: Support Int52.
// https://bugs.webkit.org/show_bug.cgi?id=125704
- if (node->canSpeculateInt32(m_pass))
+ if (nodeCanSpeculateInt32(node->arithNodeFlags()))
changed |= mergePrediction(SpecInt32);
else
changed |= mergePrediction(SpecBytecodeNumber);
@@ -252,31 +204,28 @@ private:
SpeculatedType right = node->child2()->prediction();
if (left && right) {
- if (isFullNumberOrBooleanSpeculationExpectingDefined(left)
- && isFullNumberOrBooleanSpeculationExpectingDefined(right)) {
- if (m_graph.addSpeculationMode(node, m_pass) != DontSpeculateInt32)
+ if (isFullNumberSpeculationExpectingDefined(left) && isFullNumberSpeculationExpectingDefined(right)) {
+ if (m_graph.addSpeculationMode(node) != DontSpeculateInt32)
changed |= mergePrediction(SpecInt32);
else if (m_graph.addShouldSpeculateMachineInt(node))
changed |= mergePrediction(SpecInt52);
else
changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
- } else if (
- !(left & (SpecFullNumber | SpecBoolean))
- || !(right & (SpecFullNumber | SpecBoolean))) {
+ } else if (!(left & SpecFullNumber) || !(right & SpecFullNumber)) {
// left or right is definitely something other than a number.
changed |= mergePrediction(SpecString);
} else
- changed |= mergePrediction(SpecString | SpecInt32 | SpecBytecodeDouble);
+ changed |= mergePrediction(SpecString | SpecInt32 | SpecDouble);
}
break;
}
-
+
case ArithAdd: {
SpeculatedType left = node->child1()->prediction();
SpeculatedType right = node->child2()->prediction();
if (left && right) {
- if (m_graph.addSpeculationMode(node, m_pass) != DontSpeculateInt32)
+ if (m_graph.addSpeculationMode(node) != DontSpeculateInt32)
changed |= mergePrediction(SpecInt32);
else if (m_graph.addShouldSpeculateMachineInt(node))
changed |= mergePrediction(SpecInt52);
@@ -289,27 +238,23 @@ private:
case ArithSub: {
SpeculatedType left = node->child1()->prediction();
SpeculatedType right = node->child2()->prediction();
-
+
if (left && right) {
- if (isFullNumberOrBooleanSpeculationExpectingDefined(left)
- && isFullNumberOrBooleanSpeculationExpectingDefined(right)) {
- if (m_graph.addSpeculationMode(node, m_pass) != DontSpeculateInt32)
- changed |= mergePrediction(SpecInt32);
- else if (m_graph.addShouldSpeculateMachineInt(node))
- changed |= mergePrediction(SpecInt52);
- else
- changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
- } else
- changed |= mergePrediction(SpecInt32 | SpecBytecodeDouble);
+ if (m_graph.addSpeculationMode(node) != DontSpeculateInt32)
+ changed |= mergePrediction(SpecInt32);
+ else if (m_graph.addShouldSpeculateMachineInt(node))
+ changed |= mergePrediction(SpecInt52);
+ else
+ changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
}
break;
}
-
+
case ArithNegate:
if (node->child1()->prediction()) {
- if (m_graph.unaryArithShouldSpeculateInt32(node, m_pass))
+ if (m_graph.negateShouldSpeculateInt32(node))
changed |= mergePrediction(SpecInt32);
- else if (m_graph.unaryArithShouldSpeculateMachineInt(node, m_pass))
+ else if (m_graph.negateShouldSpeculateMachineInt(node))
changed |= mergePrediction(SpecInt52);
else
changed |= mergePrediction(speculatedDoubleTypeForPrediction(node->child1()->prediction()));
@@ -322,8 +267,8 @@ private:
SpeculatedType right = node->child2()->prediction();
if (left && right) {
- if (Node::shouldSpeculateInt32OrBooleanForArithmetic(node->child1().node(), node->child2().node())
- && node->canSpeculateInt32(m_pass))
+ if (Node::shouldSpeculateInt32ForArithmetic(node->child1().node(), node->child2().node())
+ && nodeCanSpeculateInt32(node->arithNodeFlags()))
changed |= mergePrediction(SpecInt32);
else
changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
@@ -336,71 +281,55 @@ private:
SpeculatedType right = node->child2()->prediction();
if (left && right) {
- if (isFullNumberOrBooleanSpeculationExpectingDefined(left)
- && isFullNumberOrBooleanSpeculationExpectingDefined(right)) {
- if (m_graph.binaryArithShouldSpeculateInt32(node, m_pass))
- changed |= mergePrediction(SpecInt32);
- else if (m_graph.binaryArithShouldSpeculateMachineInt(node, m_pass))
- changed |= mergePrediction(SpecInt52);
- else
- changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
- } else {
- if (node->mayHaveNonIntResult())
- changed |= mergePrediction(SpecInt32 | SpecBytecodeDouble);
- else
- changed |= mergePrediction(SpecInt32);
- }
+ if (m_graph.mulShouldSpeculateInt32(node))
+ changed |= mergePrediction(SpecInt32);
+ else if (m_graph.mulShouldSpeculateMachineInt(node))
+ changed |= mergePrediction(SpecInt52);
+ else
+ changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
}
break;
}
-
- case ArithDiv:
+
+ case ArithDiv: {
+ SpeculatedType left = node->child1()->prediction();
+ SpeculatedType right = node->child2()->prediction();
+
+ if (left && right) {
+ if (Node::shouldSpeculateInt32ForArithmetic(node->child1().node(), node->child2().node())
+ && nodeCanSpeculateInt32(node->arithNodeFlags()))
+ changed |= mergePrediction(SpecInt32);
+ else
+ changed |= mergePrediction(SpecDouble);
+ }
+ break;
+ }
+
case ArithMod: {
SpeculatedType left = node->child1()->prediction();
SpeculatedType right = node->child2()->prediction();
if (left && right) {
- if (isFullNumberOrBooleanSpeculationExpectingDefined(left)
- && isFullNumberOrBooleanSpeculationExpectingDefined(right)) {
- if (m_graph.binaryArithShouldSpeculateInt32(node, m_pass))
- changed |= mergePrediction(SpecInt32);
- else
- changed |= mergePrediction(SpecBytecodeDouble);
- } else
- changed |= mergePrediction(SpecInt32 | SpecBytecodeDouble);
+ if (Node::shouldSpeculateInt32ForArithmetic(node->child1().node(), node->child2().node())
+ && nodeCanSpeculateInt32(node->arithNodeFlags()))
+ changed |= mergePrediction(SpecInt32);
+ else
+ changed |= mergePrediction(SpecDouble);
}
break;
}
-
- case ArithPow:
+
case ArithSqrt:
- case ArithFRound:
case ArithSin:
- case ArithCos:
- case ArithLog: {
- changed |= setPrediction(SpecBytecodeDouble);
- break;
- }
-
- case ArithRandom: {
- changed |= setPrediction(SpecDoubleReal);
- break;
- }
-
- case ArithRound:
- case ArithFloor:
- case ArithCeil: {
- if (isInt32OrBooleanSpeculation(node->getHeapPrediction()) && m_graph.roundShouldSpeculateInt32(node, m_pass))
- changed |= setPrediction(SpecInt32);
- else
- changed |= setPrediction(SpecBytecodeDouble);
+ case ArithCos: {
+ changed |= setPrediction(SpecDouble);
break;
}
-
+
case ArithAbs: {
SpeculatedType child = node->child1()->prediction();
- if (isInt32OrBooleanSpeculationForArithmetic(child)
- && node->canSpeculateInt32(m_pass))
+ if (isInt32SpeculationForArithmetic(child)
+ && nodeCanSpeculateInt32(node->arithNodeFlags()))
changed |= mergePrediction(SpecInt32);
else
changed |= mergePrediction(speculatedDoubleTypeForPrediction(child));
@@ -413,77 +342,51 @@ private:
case CompareGreater:
case CompareGreaterEq:
case CompareEq:
+ case CompareEqConstant:
case CompareStrictEq:
- case OverridesHasInstance:
+ case CompareStrictEqConstant:
case InstanceOf:
- case InstanceOfCustom:
case IsUndefined:
case IsBoolean:
case IsNumber:
case IsString:
case IsObject:
- case IsObjectOrNull:
case IsFunction: {
changed |= setPrediction(SpecBoolean);
break;
}
case TypeOf: {
- changed |= setPrediction(SpecStringIdent);
+ changed |= setPrediction(SpecString);
break;
}
case GetByVal: {
if (!node->child1()->prediction())
break;
-
- ArrayMode arrayMode = node->arrayMode().refine(
- m_graph, node,
- node->child1()->prediction(),
- node->child2()->prediction(),
- SpecNone);
-
- switch (arrayMode.type()) {
- case Array::Int32:
- if (arrayMode.isOutOfBounds())
- changed |= mergePrediction(node->getHeapPrediction() | SpecInt32);
- else
- changed |= mergePrediction(SpecInt32);
- break;
- case Array::Double:
- if (arrayMode.isOutOfBounds())
- changed |= mergePrediction(node->getHeapPrediction() | SpecDoubleReal);
- else
- changed |= mergePrediction(SpecDoubleReal);
+ if (!node->getHeapPrediction())
break;
- case Array::Float32Array:
- case Array::Float64Array:
- changed |= mergePrediction(SpecFullDouble);
- break;
- case Array::Uint32Array:
- if (isInt32SpeculationForArithmetic(node->getHeapPrediction()))
+
+ if (node->child1()->shouldSpeculateFloat32Array()
+ || node->child1()->shouldSpeculateFloat64Array())
+ changed |= mergePrediction(SpecDouble);
+ else if (node->child1()->shouldSpeculateUint32Array()) {
+ if (isInt32Speculation(node->getHeapPrediction()))
changed |= mergePrediction(SpecInt32);
- else if (enableInt52())
- changed |= mergePrediction(SpecMachineInt);
else
- changed |= mergePrediction(SpecInt32 | SpecInt52AsDouble);
- break;
- case Array::Int8Array:
- case Array::Uint8Array:
- case Array::Int16Array:
- case Array::Uint16Array:
- case Array::Int32Array:
- changed |= mergePrediction(SpecInt32);
- break;
- default:
+ changed |= mergePrediction(SpecInt52);
+ } else
changed |= mergePrediction(node->getHeapPrediction());
- break;
- }
break;
}
- case GetButterfly:
- case GetButterflyReadOnly:
+ case GetMyArgumentsLengthSafe: {
+ changed |= setPrediction(SpecInt32);
+ break;
+ }
+
+ case GetClosureRegisters:
+ case GetButterfly:
case GetIndexedPropertyStorage:
case AllocatePropertyStorage:
case ReallocatePropertyStorage: {
@@ -492,69 +395,29 @@ private:
}
case ToThis: {
- // ToThis in methods for primitive types should speculate primitive types in strict mode.
- ECMAMode ecmaMode = m_graph.executableFor(node->origin.semantic)->isStrictMode() ? StrictMode : NotStrictMode;
- if (ecmaMode == StrictMode) {
- if (node->child1()->shouldSpeculateBoolean()) {
- changed |= mergePrediction(SpecBoolean);
- break;
- }
-
- if (node->child1()->shouldSpeculateInt32()) {
- changed |= mergePrediction(SpecInt32);
- break;
- }
-
- if (enableInt52() && node->child1()->shouldSpeculateMachineInt()) {
- changed |= mergePrediction(SpecMachineInt);
- break;
- }
-
- if (node->child1()->shouldSpeculateNumber()) {
- changed |= mergePrediction(SpecMachineInt);
- break;
- }
-
- if (node->child1()->shouldSpeculateSymbol()) {
- changed |= mergePrediction(SpecSymbol);
- break;
- }
-
- if (node->child1()->shouldSpeculateStringIdent()) {
- changed |= mergePrediction(SpecStringIdent);
- break;
- }
-
- if (node->child1()->shouldSpeculateString()) {
- changed |= mergePrediction(SpecString);
- break;
- }
- } else {
- if (node->child1()->shouldSpeculateString()) {
- changed |= mergePrediction(SpecStringObject);
- break;
- }
- }
-
SpeculatedType prediction = node->child1()->prediction();
if (prediction) {
if (prediction & ~SpecObject) {
- // Wrapper objects are created only in sloppy mode.
- if (ecmaMode != StrictMode) {
- prediction &= SpecObject;
- prediction = mergeSpeculations(prediction, SpecObjectOther);
- }
+ prediction &= SpecObject;
+ prediction = mergeSpeculations(prediction, SpecObjectOther);
}
changed |= mergePrediction(prediction);
}
break;
}
+ case GetMyScope:
+ case SkipTopScope:
case SkipScope: {
changed |= setPrediction(SpecObjectOther);
break;
}
+ case GetCallee: {
+ changed |= setPrediction(SpecFunction);
+ break;
+ }
+
case CreateThis:
case NewObject: {
changed |= setPrediction(SpecFinalObject);
@@ -573,11 +436,7 @@ private:
break;
}
- case NewRegexp: {
- changed |= setPrediction(SpecRegExpObject);
- break;
- }
-
+ case NewRegexp:
case CreateActivation: {
changed |= setPrediction(SpecObjectOther);
break;
@@ -589,10 +448,8 @@ private:
break;
}
case StringCharAt:
- case CallStringConstructor:
case ToString:
- case MakeRope:
- case StrCat: {
+ case MakeRope: {
changed |= setPrediction(SpecString);
break;
}
@@ -609,66 +466,50 @@ private:
break;
}
- case CreateDirectArguments: {
- changed |= setPrediction(SpecDirectArguments);
+ case CreateArguments: {
+ changed |= setPrediction(SpecArguments);
break;
}
- case CreateScopedArguments: {
- changed |= setPrediction(SpecScopedArguments);
+ case NewFunction: {
+ SpeculatedType child = node->child1()->prediction();
+ if (child & SpecEmpty)
+ changed |= mergePrediction((child & ~SpecEmpty) | SpecFunction);
+ else
+ changed |= mergePrediction(child);
break;
}
- case CreateClonedArguments: {
- changed |= setPrediction(SpecObjectOther);
+ case NewFunctionNoCheck:
+ case NewFunctionExpression: {
+ changed |= setPrediction(SpecFunction);
break;
}
- case FiatInt52: {
- RELEASE_ASSERT(enableInt52());
- changed |= setPrediction(SpecMachineInt);
- break;
- }
-
case PutByValAlias:
+ case GetArrayLength:
+ case GetTypedArrayByteOffset:
+ case Int32ToDouble:
case DoubleAsInt32:
case GetLocalUnlinked:
+ case GetMyArgumentsLength:
+ case GetMyArgumentByVal:
+ case PhantomPutStructure:
+ case PhantomArguments:
case CheckArray:
- case CheckTypeInfoFlags:
case Arrayify:
case ArrayifyToStructure:
case CheckTierUpInLoop:
case CheckTierUpAtReturn:
case CheckTierUpAndOSREnter:
- case CheckTierUpWithNestedTriggerAndOSREnter:
case InvalidationPoint:
+ case Int52ToValue:
+ case Int52ToDouble:
case CheckInBounds:
- case ValueToInt32:
- case DoubleRep:
- case ValueRep:
- case Int52Rep:
- case Int52Constant:
- case Identity:
- case BooleanToNumber:
- case PhantomNewObject:
- case PhantomNewFunction:
- case PhantomNewGeneratorFunction:
- case PhantomCreateActivation:
- case PhantomDirectArguments:
- case PhantomClonedArguments:
- case GetMyArgumentByVal:
- case ForwardVarargs:
- case PutHint:
- case CheckStructureImmediate:
- case MaterializeNewObject:
- case MaterializeCreateActivation:
- case PutStack:
- case KillStack:
- case StoreBarrier:
- case GetStack: {
+ case ValueToInt32: {
// This node should never be visible at this stage of compilation. It is
// inserted by fixup(), which follows this phase.
- DFG_CRASH(m_graph, node, "Unexpected node during prediction propagation");
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
@@ -679,101 +520,69 @@ private:
break;
case Upsilon:
+ case GetArgument:
// These don't get inserted until we go into SSA.
RELEASE_ASSERT_NOT_REACHED();
break;
-
+
case GetScope:
changed |= setPrediction(SpecObjectOther);
break;
-
+
case In:
changed |= setPrediction(SpecBoolean);
break;
- case GetEnumerableLength: {
- changed |= setPrediction(SpecInt32);
- break;
- }
- case HasGenericProperty:
- case HasStructureProperty:
- case HasIndexedProperty: {
- changed |= setPrediction(SpecBoolean);
- break;
- }
- case GetPropertyEnumerator: {
- changed |= setPrediction(SpecCell);
- break;
- }
- case GetEnumeratorStructurePname: {
- changed |= setPrediction(SpecCell | SpecOther);
- break;
- }
- case GetEnumeratorGenericPname: {
- changed |= setPrediction(SpecCell | SpecOther);
- break;
- }
- case ToIndexString: {
- changed |= setPrediction(SpecString);
+ case Identity:
+ changed |= mergePrediction(node->child1()->prediction());
break;
- }
#ifndef NDEBUG
// These get ignored because they don't return anything.
+ case StoreBarrier:
+ case ConditionalStoreBarrier:
+ case StoreBarrierWithNullCheck:
case PutByValDirect:
case PutByVal:
case PutClosureVar:
- case PutToArguments:
case Return:
- case TailCall:
- case TailCallVarargs:
- case TailCallForwardVarargs:
case Throw:
case PutById:
- case PutByIdFlush:
case PutByIdDirect:
case PutByOffset:
- case MultiPutByOffset:
- case PutGetterById:
- case PutSetterById:
- case PutGetterSetterById:
- case PutGetterByVal:
- case PutSetterByVal:
case DFG::Jump:
case Branch:
case Switch:
case Breakpoint:
case ProfileWillCall:
case ProfileDidCall:
- case ProfileType:
- case ProfileControlFlow:
+ case CheckHasInstance:
case ThrowReferenceError:
case ForceOSRExit:
case SetArgument:
case CheckStructure:
- case CheckCell:
- case CheckNotEmpty:
- case CheckIdent:
- case CheckBadCell:
+ case CheckExecutable:
+ case StructureTransitionWatchpoint:
+ case CheckFunction:
case PutStructure:
+ case TearOffActivation:
+ case TearOffArguments:
+ case CheckArgumentsNotCreated:
+ case VariableWatchpoint:
case VarInjectionWatchpoint:
+ case AllocationProfileWatchpoint:
case Phantom:
case Check:
- case PutGlobalVariable:
+ case PutGlobalVar:
case CheckWatchdogTimer:
case Unreachable:
case LoopHint:
case NotifyWrite:
+ case FunctionReentryWatchpoint:
+ case TypedArrayWatchpoint:
case ConstantStoragePointer:
case MovHint:
case ZombieHint:
- case ExitOK:
- case LoadVarargs:
- case CopyRest:
- break;
-
- // This gets ignored because it only pretends to produce a value.
- case BottomValue:
break;
// This gets ignored because it already has a prediction.
@@ -826,14 +635,8 @@ private:
}
}
- void doDoubleVoting(Node* node, float weight)
+ void doDoubleVoting(Node* node)
{
- // Loop pre-headers created by OSR entrypoint creation may have NaN weight to indicate
- // that we actually don't know they weight. Assume that they execute once. This turns
- // out to be an OK assumption since the pre-header doesn't have any meaningful code.
- if (weight != weight)
- weight = 1;
-
switch (node->op()) {
case ValueAdd:
case ArithAdd:
@@ -843,16 +646,15 @@ private:
DoubleBallot ballot;
- if (isFullNumberSpeculation(left)
- && isFullNumberSpeculation(right)
- && !m_graph.addShouldSpeculateInt32(node, m_pass)
+ if (isFullNumberSpeculationExpectingDefined(left) && isFullNumberSpeculationExpectingDefined(right)
+ && !m_graph.addShouldSpeculateInt32(node)
&& !m_graph.addShouldSpeculateMachineInt(node))
ballot = VoteDouble;
else
ballot = VoteValue;
- m_graph.voteNode(node->child1(), ballot, weight);
- m_graph.voteNode(node->child2(), ballot, weight);
+ m_graph.voteNode(node->child1(), ballot);
+ m_graph.voteNode(node->child2(), ballot);
break;
}
@@ -862,16 +664,15 @@ private:
DoubleBallot ballot;
- if (isFullNumberSpeculation(left)
- && isFullNumberSpeculation(right)
- && !m_graph.binaryArithShouldSpeculateInt32(node, m_pass)
- && !m_graph.binaryArithShouldSpeculateMachineInt(node, m_pass))
+ if (isFullNumberSpeculation(left) && isFullNumberSpeculation(right)
+ && !m_graph.mulShouldSpeculateInt32(node)
+ && !m_graph.mulShouldSpeculateMachineInt(node))
ballot = VoteDouble;
else
ballot = VoteValue;
- m_graph.voteNode(node->child1(), ballot, weight);
- m_graph.voteNode(node->child2(), ballot, weight);
+ m_graph.voteNode(node->child1(), ballot);
+ m_graph.voteNode(node->child2(), ballot);
break;
}
@@ -884,47 +685,41 @@ private:
DoubleBallot ballot;
- if (isFullNumberSpeculation(left)
- && isFullNumberSpeculation(right)
- && !m_graph.binaryArithShouldSpeculateInt32(node, m_pass))
+ if (isFullNumberSpeculation(left) && isFullNumberSpeculation(right)
+ && !(Node::shouldSpeculateInt32ForArithmetic(node->child1().node(), node->child2().node()) && node->canSpeculateInt32()))
ballot = VoteDouble;
else
ballot = VoteValue;
- m_graph.voteNode(node->child1(), ballot, weight);
- m_graph.voteNode(node->child2(), ballot, weight);
+ m_graph.voteNode(node->child1(), ballot);
+ m_graph.voteNode(node->child2(), ballot);
break;
}
case ArithAbs:
DoubleBallot ballot;
- if (node->child1()->shouldSpeculateNumber()
- && !m_graph.unaryArithShouldSpeculateInt32(node, m_pass))
+ if (!(node->child1()->shouldSpeculateInt32ForArithmetic() && node->canSpeculateInt32()))
ballot = VoteDouble;
else
ballot = VoteValue;
- m_graph.voteNode(node->child1(), ballot, weight);
+ m_graph.voteNode(node->child1(), ballot);
break;
case ArithSqrt:
case ArithCos:
case ArithSin:
- case ArithLog:
- if (node->child1()->shouldSpeculateNumber())
- m_graph.voteNode(node->child1(), VoteDouble, weight);
- else
- m_graph.voteNode(node->child1(), VoteValue, weight);
+ m_graph.voteNode(node->child1(), VoteDouble);
break;
case SetLocal: {
SpeculatedType prediction = node->child1()->prediction();
if (isDoubleSpeculation(prediction))
- node->variableAccessData()->vote(VoteDouble, weight);
+ node->variableAccessData()->vote(VoteDouble);
else if (
!isFullNumberSpeculation(prediction)
|| isInt32Speculation(prediction) || isMachineIntSpeculation(prediction))
- node->variableAccessData()->vote(VoteValue, weight);
+ node->variableAccessData()->vote(VoteValue);
break;
}
@@ -934,14 +729,14 @@ private:
Edge child1 = m_graph.varArgChild(node, 0);
Edge child2 = m_graph.varArgChild(node, 1);
Edge child3 = m_graph.varArgChild(node, 2);
- m_graph.voteNode(child1, VoteValue, weight);
- m_graph.voteNode(child2, VoteValue, weight);
+ m_graph.voteNode(child1, VoteValue);
+ m_graph.voteNode(child2, VoteValue);
switch (node->arrayMode().type()) {
case Array::Double:
- m_graph.voteNode(child3, VoteDouble, weight);
+ m_graph.voteNode(child3, VoteDouble);
break;
default:
- m_graph.voteNode(child3, VoteValue, weight);
+ m_graph.voteNode(child3, VoteValue);
break;
}
break;
@@ -952,7 +747,7 @@ private:
break;
default:
- m_graph.voteChildren(node, VoteValue, weight);
+ m_graph.voteChildren(node, VoteValue);
break;
}
}
@@ -968,7 +763,7 @@ private:
ASSERT(block->isReachable);
for (unsigned i = 0; i < block->size(); ++i) {
m_currentNode = block->at(i);
- doDoubleVoting(m_currentNode, block->executionCount);
+ doDoubleVoting(m_currentNode);
}
}
for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
@@ -977,7 +772,8 @@ private:
continue;
m_changed |= variableAccessData->tallyVotesForShouldUseDoubleFormat();
}
- propagateThroughArgumentPositions();
+ for (unsigned i = 0; i < m_graph.m_argumentPositions.size(); ++i)
+ m_changed |= m_graph.m_argumentPositions[i].mergeArgumentPredictionAwareness();
for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i];
if (!variableAccessData->isRoot())
@@ -986,29 +782,8 @@ private:
}
}
- void propagateThroughArgumentPositions()
- {
- for (unsigned i = 0; i < m_graph.m_argumentPositions.size(); ++i)
- m_changed |= m_graph.m_argumentPositions[i].mergeArgumentPredictionAwareness();
- }
-
- SpeculatedType resultOfToPrimitive(SpeculatedType type)
- {
- if (type & SpecObject) {
- // We try to be optimistic here about StringObjects since it's unlikely that
- // someone overrides the valueOf or toString methods.
- if (type & SpecStringObject && m_graph.canOptimizeStringObjectAccess(m_currentNode->origin.semantic))
- return mergeSpeculations(type & ~SpecObject, SpecString);
-
- return mergeSpeculations(type & ~SpecObject, SpecPrimitive);
- }
-
- return type;
- }
-
Node* m_currentNode;
bool m_changed;
- PredictionPass m_pass; // We use different logic for considering predictions depending on how far along we are in propagation.
};
bool performPredictionPropagation(Graph& graph)