Add Options::alwaysCheckTraps() and Options::usePollingTraps() options.
authormark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 2 Mar 2017 22:06:04 +0000 (22:06 +0000)
committermark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 2 Mar 2017 22:06:04 +0000 (22:06 +0000)
https://bugs.webkit.org/show_bug.cgi?id=169088

Reviewed by Keith Miller.

Options::alwaysCheckTraps() forces the op_check_traps bytecode to always be
generated.  This is useful for testing purposes until we have signal based
traps, at which point, we will always emit the op_check_traps bytecode and remove
this option.

Options::usePollingTraps() enables the use of polling VM traps all the time.
This will be useful for benchmark comparisons, (between polling and non-polling
traps), as well as for forcing polling traps later for ports that don't support
signal based traps.

Note: signal based traps are not fully implemented yet.  As a result, if the VM
watchdog is in use, we will force Options::usePollingTraps() to be true.

* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitCheckTraps):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileCheckTraps):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileCheckTraps):
* runtime/Options.cpp:
(JSC::recomputeDependentOptions):
* runtime/Options.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@213302 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
Source/JavaScriptCore/dfg/DFGClobberize.h
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
Source/JavaScriptCore/runtime/Options.h
Source/JavaScriptCore/runtime/VM.cpp
Source/JavaScriptCore/runtime/VM.h

index ba541cb..bde17d9 100644 (file)
@@ -1,3 +1,40 @@
+2017-03-02  Mark Lam  <mark.lam@apple.com>
+
+        Add Options::alwaysCheckTraps() and Options::usePollingTraps() options.
+        https://bugs.webkit.org/show_bug.cgi?id=169088
+
+        Reviewed by Keith Miller.
+
+        Options::alwaysCheckTraps() forces the op_check_traps bytecode to always be
+        generated.  This is useful for testing purposes until we have signal based
+        traps, at which point, we will always emit the op_check_traps bytecode and remove
+        this option.
+
+        Options::usePollingTraps() enables the use of polling VM traps all the time.
+        This will be useful for benchmark comparisons, (between polling and non-polling
+        traps), as well as for forcing polling traps later for ports that don't support
+        signal based traps.
+
+        Note: signal based traps are not fully implemented yet.  As a result, if the VM
+        watchdog is in use, we will force Options::usePollingTraps() to be true.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitCheckTraps):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileCheckTraps):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
+        (JSC::FTL::DFG::LowerDFGToB3::compileCheckTraps):
+        * runtime/Options.cpp:
+        (JSC::recomputeDependentOptions):
+        * runtime/Options.h:
+
 2017-03-02  Keith Miller  <keith_miller@apple.com>
 
         Fix addressing mode for B3WasmAddress
index 1a6df1b..8d89f84 100644 (file)
@@ -1274,7 +1274,7 @@ void BytecodeGenerator::emitLoopHint()
 
 void BytecodeGenerator::emitCheckTraps()
 {
-    if (vm()->watchdog() || vm()->needAsynchronousTerminationSupport())
+    if (Options::alwaysCheckTraps() || vm()->watchdog() || vm()->needAsynchronousTerminationSupport())
         emitOpcode(op_check_traps);
 }
 
index c9c1940..4a665a3 100644 (file)
@@ -434,6 +434,14 @@ void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu
         write(JSCell_cellState);
         return;
 
+    case CheckTraps:
+        if (Options::usePollingTraps()) {
+            read(InternalState);
+            write(InternalState);
+        } else
+            write(Watchpoint_fire);
+        return;
+
     case InvalidationPoint:
         write(SideState);
         def(HeapLocation(InvalidationPointLoc, Watchpoint_fire), LazyNode(node));
@@ -1411,7 +1419,6 @@ void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu
         return;
         
     case CountExecution:
-    case CheckTraps:
         read(InternalState);
         write(InternalState);
         return;
index 03ddbd1..b0104bc 100644 (file)
@@ -1898,6 +1898,7 @@ void SpeculativeJIT::linkOSREntries(LinkBuffer& linkBuffer)
     
 void SpeculativeJIT::compileCheckTraps(Node*)
 {
+    ASSERT(Options::usePollingTraps());
     GPRTemporary unused(this);
     GPRReg unusedGPR = unused.gpr();
 
index f0cf92c..651ec5d 100644 (file)
@@ -5544,7 +5544,10 @@ void SpeculativeJIT::compile(Node* node)
         break;
 
     case CheckTraps:
-        compileCheckTraps(node);
+        if (Options::usePollingTraps())
+            compileCheckTraps(node);
+        else
+            noResult(node); // This is a no-op.
         break;
 
     case CountExecution:
index 5f61475..8e78a0f 100644 (file)
@@ -5328,7 +5328,10 @@ void SpeculativeJIT::compile(Node* node)
         break;
 
     case CheckTraps:
-        compileCheckTraps(node);
+        if (Options::usePollingTraps())
+            compileCheckTraps(node);
+        else
+            noResult(node); // This is a no-op.
         break;
 
     case Phantom:
index 986192b..3d76b40 100644 (file)
@@ -1023,7 +1023,8 @@ private:
             compileMaterializeCreateActivation();
             break;
         case CheckTraps:
-            compileCheckTraps();
+            if (Options::usePollingTraps())
+                compileCheckTraps();
             break;
         case CreateRest:
             compileCreateRest();
@@ -8986,6 +8987,7 @@ private:
 
     void compileCheckTraps()
     {
+        ASSERT(Options::usePollingTraps());
         LBasicBlock needTrapHandling = m_out.newBlock();
         LBasicBlock continuation = m_out.newBlock();
         
index b3370a3..65b9829 100644 (file)
@@ -406,6 +406,8 @@ typedef const char* optionString;
     v(bool, useSigillCrashAnalyzer, false, Configurable, "logs data about SIGILL crashes") \
     \
     v(unsigned, watchdog, 0, Normal, "watchdog timeout (0 = Disabled, N = a timeout period of N milliseconds)") \
+    v(bool, alwaysCheckTraps, false, Normal, "always emit op_check_traps bytecode") \
+    v(bool, usePollingTraps, false, Normal, "use polling (instead of signalling) VM traps") \
     \
     v(bool, useICStats, false, Normal, nullptr) \
     \
index 68ed1dd..96aed50 100644 (file)
@@ -462,6 +462,8 @@ VM*& VM::sharedInstanceInternal()
 Watchdog& VM::ensureWatchdog()
 {
     if (!m_watchdog) {
+        Options::usePollingTraps() = true; // Force polling traps on until we have support for signal based traps.
+
         m_watchdog = adoptRef(new Watchdog(this));
         
         // The LLINT peeks into the Watchdog object directly. In order to do that,
@@ -973,4 +975,10 @@ void VM::handleTraps(ExecState* exec, VMTraps::Mask mask)
     }
 }
 
+void VM::setNeedAsynchronousTerminationSupport()
+{
+    Options::usePollingTraps() = true; // Force polling traps on until we have support for signal based traps.
+    m_needAsynchronousTerminationSupport = true;
+}
+
 } // namespace JSC
index cb5757f..466f854 100644 (file)
@@ -680,7 +680,7 @@ public:
     void notifyNeedWatchdogCheck() { m_traps.fireTrap(VMTraps::NeedWatchdogCheck); }
 
     bool needAsynchronousTerminationSupport() const { return m_needAsynchronousTerminationSupport; }
-    void setNeedAsynchronousTerminationSupport() { m_needAsynchronousTerminationSupport = true; }
+    JS_EXPORT_PRIVATE void setNeedAsynchronousTerminationSupport();
 
 private:
     friend class LLIntOffsetsExtractor;