diff options
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGGraph.h')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGGraph.h | 64 |
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); |