[JSC] ArithSqrt should work with any argument type
https://bugs.webkit.org/show_bug.cgi?id=160954
Patch by Benjamin Poulain <bpoulain@apple.com> on 2016-08-19
Reviewed by Saam Barati.
JSTests:
* stress/arith-sqrt-on-various-types.js: Added.
(let.validInputTypedTestCases.validInputTestCases.map):
(isIdentical):
(opaqueAllTypesSqrt):
(testAllTypesCall):
(testSingleTypeCall):
(opaqueSqrtForSideEffects):
(testSideEffect.let.testObject.valueOf):
(testSideEffect):
(opaqueSqrtForCSE):
(testCSE.let.testObject.valueOf):
(testCSE):
(testException.opaqueSqrtWithException):
(testException):
Source/JavaScriptCore:
Previsouly, ArithSqrt would always OSR Exit if the argument
is not typed Integer, Double, or Boolean.
Since we can't recover by generalizing to those, we continuously
OSR Exit and recompile the same code over and over again.
This patch introduces a fallback to handle the remaining types.
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGMayExit.cpp:
This is somewhat unrelated. While discussing the design of this
with Filip, we decided not to use ToNumber+ArithSqrt despite
the guarantee that ToNumber does not OSR Exit.
Since it does not OSR Exit, we should say so in mayExitImpl().
* dfg/DFGNodeType.h:
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileArithSqrt):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::callOperation):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileArithSqrt):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@204670 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/runtime/Executable.cpp b/Source/JavaScriptCore/runtime/Executable.cpp
index 4c9449d..589ea59 100644
--- a/Source/JavaScriptCore/runtime/Executable.cpp
+++ b/Source/JavaScriptCore/runtime/Executable.cpp
@@ -146,6 +146,7 @@
, m_neverOptimize(false)
, m_neverFTLOptimize(false)
, m_isArrowFunctionContext(isInArrowFunctionContext)
+ , m_canUseOSRExitFuzzing(true)
, m_derivedContextType(static_cast<unsigned>(derivedContextType))
, m_evalContextType(static_cast<unsigned>(evalContextType))
, m_overrideLineNumber(-1)
diff --git a/Source/JavaScriptCore/runtime/Executable.h b/Source/JavaScriptCore/runtime/Executable.h
index 2d00919..35b2d4c 100644
--- a/Source/JavaScriptCore/runtime/Executable.h
+++ b/Source/JavaScriptCore/runtime/Executable.h
@@ -337,12 +337,14 @@
void setNeverOptimize(bool value) { m_neverOptimize = value; }
void setNeverFTLOptimize(bool value) { m_neverFTLOptimize = value; }
void setDidTryToEnterInLoop(bool value) { m_didTryToEnterInLoop = value; }
+ void setCanUseOSRExitFuzzing(bool value) { m_canUseOSRExitFuzzing = value; }
bool neverInline() const { return m_neverInline; }
bool neverOptimize() const { return m_neverOptimize; }
bool neverFTLOptimize() const { return m_neverFTLOptimize; }
bool didTryToEnterInLoop() const { return m_didTryToEnterInLoop; }
bool isInliningCandidate() const { return !neverInline(); }
bool isOkToOptimize() const { return !neverOptimize(); }
+ bool canUseOSRExitFuzzing() const { return m_canUseOSRExitFuzzing; }
bool* addressOfDidTryToEnterInLoop() { return &m_didTryToEnterInLoop; }
@@ -403,6 +405,7 @@
bool m_neverOptimize : 1;
bool m_neverFTLOptimize : 1;
bool m_isArrowFunctionContext : 1;
+ bool m_canUseOSRExitFuzzing : 1;
unsigned m_derivedContextType : 2; // DerivedContextType
unsigned m_evalContextType : 2; // EvalContextType
diff --git a/Source/JavaScriptCore/runtime/TestRunnerUtils.cpp b/Source/JavaScriptCore/runtime/TestRunnerUtils.cpp
index d13090f..43aa456 100644
--- a/Source/JavaScriptCore/runtime/TestRunnerUtils.cpp
+++ b/Source/JavaScriptCore/runtime/TestRunnerUtils.cpp
@@ -131,6 +131,18 @@
return setNeverOptimize(exec->uncheckedArgument(0));
}
+JSValue setCannotUseOSRExitFuzzing(ExecState* exec)
+{
+ if (exec->argumentCount() < 1)
+ return jsUndefined();
+
+ JSValue theFunctionValue = exec->uncheckedArgument(0);
+ if (FunctionExecutable* executable = getExecutableForFunction(theFunctionValue))
+ executable->setCanUseOSRExitFuzzing(false);
+
+ return jsUndefined();
+}
+
JSValue optimizeNextInvocation(ExecState* exec)
{
if (exec->argumentCount() < 1)
diff --git a/Source/JavaScriptCore/runtime/TestRunnerUtils.h b/Source/JavaScriptCore/runtime/TestRunnerUtils.h
index b8dfaea..14658d6 100644
--- a/Source/JavaScriptCore/runtime/TestRunnerUtils.h
+++ b/Source/JavaScriptCore/runtime/TestRunnerUtils.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2016 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,6 +45,7 @@
JS_EXPORT_PRIVATE JSValue numberOfDFGCompiles(ExecState*);
JS_EXPORT_PRIVATE JSValue setNeverInline(ExecState*);
JS_EXPORT_PRIVATE JSValue setNeverOptimize(ExecState*);
+JS_EXPORT_PRIVATE JSValue setCannotUseOSRExitFuzzing(ExecState*);
JS_EXPORT_PRIVATE JSValue optimizeNextInvocation(ExecState*);
JS_EXPORT_PRIVATE unsigned numberOfExceptionFuzzChecks();