Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (167611 => 167612)
--- trunk/Source/_javascript_Core/ChangeLog 2014-04-21 19:51:01 UTC (rev 167611)
+++ trunk/Source/_javascript_Core/ChangeLog 2014-04-21 19:51:54 UTC (rev 167612)
@@ -1,5 +1,38 @@
2014-04-21 Filip Pizlo <[email protected]>
+ OSR exit should know about Int52 and Double constants
+ https://bugs.webkit.org/show_bug.cgi?id=131945
+
+ Reviewed by Oliver Hunt.
+
+ The DFG OSR exit machinery's ignorance would lead to some constants becoming
+ jsUndefined() after OSR exit.
+
+ The FTL OSR exit machinery's ignorance just meant that we would sometimes use a
+ stackmap constant rather than baking the constant into the OSRExit data structure.
+ So, not a big deal, but worth fixing.
+
+ Also added some helpful hacks to jsc.cpp for testing such OSR exit pathologies.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::handleIntrinsic):
+ * dfg/DFGMinifiedNode.h:
+ (JSC::DFG::belongsInMinifiedGraph):
+ (JSC::DFG::MinifiedNode::hasConstantNumber):
+ * ftl/FTLLowerDFGToLLVM.cpp:
+ (JSC::FTL::LowerDFGToLLVM::tryToSetConstantExitArgument):
+ * jsc.cpp:
+ (GlobalObject::finishCreation):
+ (functionOtherFalse):
+ (functionUndefined):
+ * runtime/Intrinsic.h:
+ * tests/stress/fold-to-double-constant-then-exit.js: Added.
+ (foo):
+ * tests/stress/fold-to-int52-constant-then-exit.js: Added.
+ (foo):
+
+2014-04-21 Filip Pizlo <[email protected]>
+
Provide feedback when we encounter an unrecognied node in the FTL backend.
Rubber stamped by Alexey Proskuryakov.
Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (167611 => 167612)
--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2014-04-21 19:51:01 UTC (rev 167611)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2014-04-21 19:51:54 UTC (rev 167612)
@@ -1714,11 +1714,23 @@
return true;
}
- case DFGTrue: {
+ case DFGTrueIntrinsic: {
set(VirtualRegister(resultOperand), getJSConstantForValue(jsBoolean(true)));
return true;
}
+ case OSRExitIntrinsic: {
+ addToGraph(ForceOSRExit);
+ set(VirtualRegister(resultOperand), constantUndefined());
+ return true;
+ }
+
+ case IsFinalTierIntrinsic: {
+ set(VirtualRegister(resultOperand),
+ getJSConstantForValue(jsBoolean(Options::useFTLJIT() ? isFTL(m_graph.m_plan.mode) : true)));
+ return true;
+ }
+
default:
return false;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGMinifiedNode.h (167611 => 167612)
--- trunk/Source/_javascript_Core/dfg/DFGMinifiedNode.h 2014-04-21 19:51:01 UTC (rev 167611)
+++ trunk/Source/_javascript_Core/dfg/DFGMinifiedNode.h 2014-04-21 19:51:54 UTC (rev 167612)
@@ -40,6 +40,8 @@
{
switch (type) {
case JSConstant:
+ case Int52Constant:
+ case DoubleConstant:
case WeakJSConstant:
case PhantomArguments:
return true;
@@ -84,7 +86,7 @@
private:
static bool hasConstantNumber(NodeType type)
{
- return type == JSConstant;
+ return type == JSConstant || type == Int52Constant || type == DoubleConstant;
}
static bool hasWeakConstant(NodeType type)
{
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp (167611 => 167612)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp 2014-04-21 19:51:01 UTC (rev 167611)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp 2014-04-21 19:51:54 UTC (rev 167612)
@@ -5891,6 +5891,8 @@
switch (node->op()) {
case JSConstant:
+ case Int52Constant:
+ case DoubleConstant:
case WeakJSConstant:
exit.m_values[index] = ExitValue::constant(m_graph.valueOfJSConstant(node));
return true;
Modified: trunk/Source/_javascript_Core/jsc.cpp (167611 => 167612)
--- trunk/Source/_javascript_Core/jsc.cpp 2014-04-21 19:51:01 UTC (rev 167611)
+++ trunk/Source/_javascript_Core/jsc.cpp 2014-04-21 19:51:54 UTC (rev 167612)
@@ -270,6 +270,8 @@
static EncodedJSValue JSC_HOST_CALL functionTransferArrayBuffer(ExecState*);
static NO_RETURN_WITH_VALUE EncodedJSValue JSC_HOST_CALL functionQuit(ExecState*);
static EncodedJSValue JSC_HOST_CALL functionFalse(ExecState*);
+static EncodedJSValue JSC_HOST_CALL functionOtherFalse(ExecState*); // Need a separate function to break hash-consing of native executables.
+static EncodedJSValue JSC_HOST_CALL functionUndefined(ExecState*);
static EncodedJSValue JSC_HOST_CALL functionEffectful42(ExecState*);
static EncodedJSValue JSC_HOST_CALL functionMakeMasquerader(ExecState*);
@@ -405,7 +407,9 @@
addFunction(vm, "getElement", functionGetElement, 1);
addFunction(vm, "setElementRoot", functionSetElementRoot, 2);
- putDirectNativeFunction(vm, this, Identifier(&vm, "DFGTrue"), 0, functionFalse, DFGTrue, DontEnum | JSC::Function);
+ putDirectNativeFunction(vm, this, Identifier(&vm, "DFGTrue"), 0, functionFalse, DFGTrueIntrinsic, DontEnum | JSC::Function);
+ putDirectNativeFunction(vm, this, Identifier(&vm, "OSRExit"), 0, functionUndefined, OSRExitIntrinsic, DontEnum | JSC::Function);
+ putDirectNativeFunction(vm, this, Identifier(&vm, "isFinalTier"), 0, functionOtherFalse, IsFinalTierIntrinsic, DontEnum | JSC::Function);
addFunction(vm, "effectful42", functionEffectful42, 0);
addFunction(vm, "makeMasquerader", functionMakeMasquerader, 0);
@@ -773,6 +777,16 @@
return JSValue::encode(jsBoolean(false));
}
+EncodedJSValue JSC_HOST_CALL functionOtherFalse(ExecState*)
+{
+ return JSValue::encode(jsBoolean(false));
+}
+
+EncodedJSValue JSC_HOST_CALL functionUndefined(ExecState*)
+{
+ return JSValue::encode(jsUndefined());
+}
+
EncodedJSValue JSC_HOST_CALL functionEffectful42(ExecState*)
{
return JSValue::encode(jsNumber(42));
Modified: trunk/Source/_javascript_Core/runtime/Intrinsic.h (167611 => 167612)
--- trunk/Source/_javascript_Core/runtime/Intrinsic.h 2014-04-21 19:51:01 UTC (rev 167611)
+++ trunk/Source/_javascript_Core/runtime/Intrinsic.h 2014-04-21 19:51:54 UTC (rev 167612)
@@ -57,7 +57,9 @@
ArrayIteratorNextGenericIntrinsic,
// Debugging intrinsics
- DFGTrue
+ DFGTrueIntrinsic,
+ OSRExitIntrinsic,
+ IsFinalTierIntrinsic
};
} // namespace JSC
Added: trunk/Source/_javascript_Core/tests/stress/fold-to-double-constant-then-exit.js (0 => 167612)
--- trunk/Source/_javascript_Core/tests/stress/fold-to-double-constant-then-exit.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/fold-to-double-constant-then-exit.js 2014-04-21 19:51:54 UTC (rev 167612)
@@ -0,0 +1,17 @@
+function foo(a, b) {
+ if (DFGTrue())
+ a = b = 5.4;
+ var c = a + b;
+ if (isFinalTier())
+ OSRExit();
+ return c + 0.5;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 100000; ++i) {
+ var result = foo(1.4, 1.3);
+ if (result != 1.4 + 1.3 + 0.5 && result != 5.4 + 5.4 + 0.5)
+ throw "Error: bad result: " + result;
+}
+
Added: trunk/Source/_javascript_Core/tests/stress/fold-to-int52-constant-then-exit.js (0 => 167612)
--- trunk/Source/_javascript_Core/tests/stress/fold-to-int52-constant-then-exit.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/fold-to-int52-constant-then-exit.js 2014-04-21 19:51:54 UTC (rev 167612)
@@ -0,0 +1,17 @@
+function foo(a, b) {
+ if (DFGTrue())
+ a = b = 2000000000;
+ var c = a + b;
+ if (isFinalTier())
+ OSRExit();
+ return c + 42;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 100000; ++i) {
+ var result = foo(2000000001, 2000000001);
+ if (result != 2000000001 + 2000000001 + 42 && result != 2000000000 + 2000000000 + 42)
+ throw "Error: bad result: " + result;
+}
+