summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/dfg/DFGGraph.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGGraph.h')
-rw-r--r--Source/JavaScriptCore/dfg/DFGGraph.h64
1 files changed, 47 insertions, 17 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.h b/Source/JavaScriptCore/dfg/DFGGraph.h
index fb729063d..d3f16a0f4 100644
--- a/Source/JavaScriptCore/dfg/DFGGraph.h
+++ b/Source/JavaScriptCore/dfg/DFGGraph.h
@@ -137,6 +137,26 @@ public:
return predictionFromValue(node.valueOfJSConstant(codeBlock));
}
+ bool addShouldSpeculateInteger(Node& add, CodeBlock* codeBlock)
+ {
+ ASSERT(add.op == ValueAdd || add.op == ArithAdd || add.op == ArithSub);
+
+ Node& left = at(add.child1());
+ Node& right = at(add.child2());
+
+ if (left.hasConstant())
+ return addImmediateShouldSpeculateInteger(codeBlock, add, right, left);
+ if (right.hasConstant())
+ return addImmediateShouldSpeculateInteger(codeBlock, add, left, right);
+
+ return Node::shouldSpeculateInteger(left, right) && add.canSpeculateInteger();
+ }
+
+ bool addShouldSpeculateInteger(NodeIndex nodeIndex, CodeBlock* codeBlock)
+ {
+ return addShouldSpeculateInteger(at(nodeIndex), codeBlock);
+ }
+
// Helper methods to check nodes for constants.
bool isConstant(NodeIndex nodeIndex)
{
@@ -223,8 +243,7 @@ public:
Node& node = at(nodeIndex);
- switch (node.op) {
- case GetLocal: {
+ if (node.op == GetLocal) {
if (!operandIsArgument(node.local()))
return 0;
int argument = operandToArgument(node.local());
@@ -233,21 +252,10 @@ public:
return profiledBlock->valueProfileForArgument(argument);
}
- // Nodes derives from calls need special handling because the value profile is
- // associated with the op_call_put_result instruction.
- case Call:
- case Construct:
- case ArrayPop:
- case ArrayPush: {
- ASSERT(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_construct));
- return profiledBlock->valueProfileForBytecodeOffset(node.codeOrigin.bytecodeIndex + OPCODE_LENGTH(op_call));
- }
-
- default:
- if (node.hasHeapPrediction())
- return profiledBlock->valueProfileForBytecodeOffset(node.codeOrigin.bytecodeIndex);
- return 0;
- }
+ if (node.hasHeapPrediction())
+ return profiledBlock->valueProfileForBytecodeOffset(node.codeOrigin.bytecodeIndexForValueProfile());
+
+ return 0;
}
Vector< OwnPtr<BasicBlock> , 8> m_blocks;
@@ -263,6 +271,28 @@ public:
unsigned m_parameterSlots;
private:
+ bool addImmediateShouldSpeculateInteger(CodeBlock* codeBlock, Node& add, Node& variable, Node& immediate)
+ {
+ ASSERT(immediate.hasConstant());
+
+ JSValue immediateValue = immediate.valueOfJSConstant(codeBlock);
+ if (!immediateValue.isNumber())
+ return false;
+
+ if (!variable.shouldSpeculateInteger())
+ return false;
+
+ if (immediateValue.isInt32())
+ return add.canSpeculateInteger();
+
+ double doubleImmediate = immediateValue.asDouble();
+ const double twoToThe48 = 281474976710656.0;
+ if (doubleImmediate < -twoToThe48 || doubleImmediate > twoToThe48)
+ return false;
+
+ return nodeCanTruncateInteger(add.arithNodeFlags());
+ }
+
// When a node's refCount goes from 0 to 1, it must (logically) recursively ref all of its children, and vice versa.
void refChildren(NodeIndex);
void derefChildren(NodeIndex);