Title: [188649] trunk/Source/_javascript_Core
Revision
188649
Author
mark....@apple.com
Date
2015-08-19 14:18:15 -0700 (Wed, 19 Aug 2015)

Log Message

Add support for CheckWatchdogTimer as slow path in DFG and FTL.
https://bugs.webkit.org/show_bug.cgi?id=147968

Reviewed by Michael Saboff.

Re-implement the DFG's CheckWatchdogTimer as a slow path instead of a speculation
check.  Since the watchdog timer can fire spuriously, this allows the code to
stay optimized if all we have are spurious fires.

Implement the equivalent slow path for CheckWatchdogTimer in the FTL. 

The watchdog tests in ExecutionTimeLimitTest.cpp has already been updated in
https://bugs.webkit.org/show_bug.cgi?id=148125 to test for the FTL's watchdog
implementation.

* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::DFG::LowerDFGToLLVM::compileNode):
(JSC::FTL::DFG::LowerDFGToLLVM::compileMaterializeCreateActivation):
(JSC::FTL::DFG::LowerDFGToLLVM::compileCheckWatchdogTimer):
(JSC::FTL::DFG::LowerDFGToLLVM::isInlinableSize):

* jit/JIT.h:
* jit/JITInlines.h:
(JSC::JIT::callOperation):
* jit/JITOperations.cpp:
* jit/JITOperations.h:
- Changed operationHandleWatchdogTimer() to return an unused nullptr.  This
  allows me to reuse the existing DFG slow path generator mechanism.  I didn't
  think that operationHandleWatchdogTimer() was worth introducing a whole new set
  of machinery just so we can have a slow path that returns void.

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (188648 => 188649)


--- trunk/Source/_javascript_Core/ChangeLog	2015-08-19 20:41:30 UTC (rev 188648)
+++ trunk/Source/_javascript_Core/ChangeLog	2015-08-19 21:18:15 UTC (rev 188649)
@@ -1,5 +1,44 @@
 2015-08-19  Mark Lam  <mark....@apple.com>
 
+        Add support for CheckWatchdogTimer as slow path in DFG and FTL.
+        https://bugs.webkit.org/show_bug.cgi?id=147968
+
+        Reviewed by Michael Saboff.
+
+        Re-implement the DFG's CheckWatchdogTimer as a slow path instead of a speculation
+        check.  Since the watchdog timer can fire spuriously, this allows the code to
+        stay optimized if all we have are spurious fires.
+
+        Implement the equivalent slow path for CheckWatchdogTimer in the FTL. 
+
+        The watchdog tests in ExecutionTimeLimitTest.cpp has already been updated in
+        https://bugs.webkit.org/show_bug.cgi?id=148125 to test for the FTL's watchdog
+        implementation.
+
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::DFG::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::DFG::LowerDFGToLLVM::compileMaterializeCreateActivation):
+        (JSC::FTL::DFG::LowerDFGToLLVM::compileCheckWatchdogTimer):
+        (JSC::FTL::DFG::LowerDFGToLLVM::isInlinableSize):
+
+        * jit/JIT.h:
+        * jit/JITInlines.h:
+        (JSC::JIT::callOperation):
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        - Changed operationHandleWatchdogTimer() to return an unused nullptr.  This
+          allows me to reuse the existing DFG slow path generator mechanism.  I didn't
+          think that operationHandleWatchdogTimer() was worth introducing a whole new set
+          of machinery just so we can have a slow path that returns void.
+
+2015-08-19  Mark Lam  <mark....@apple.com>
+
         Add ability to save and restore JSC options.
         https://bugs.webkit.org/show_bug.cgi?id=148125
 

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (188648 => 188649)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2015-08-19 20:41:30 UTC (rev 188648)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2015-08-19 21:18:15 UTC (rev 188649)
@@ -4640,14 +4640,17 @@
         emitInvalidationPoint(node);
         break;
 
-    case CheckWatchdogTimer:
+    case CheckWatchdogTimer: {
         ASSERT(m_jit.vm()->watchdog);
-        speculationCheck(
-            WatchdogTimerFired, JSValueRegs(), 0,
-            m_jit.branchTest8(
-                JITCompiler::NonZero,
-                JITCompiler::AbsoluteAddress(m_jit.vm()->watchdog->timerDidFireAddress())));
+        GPRTemporary unused(this);
+        GPRReg unusedGPR = unused.gpr();
+        
+        JITCompiler::Jump timerDidFire = m_jit.branchTest8(JITCompiler::NonZero,
+            JITCompiler::AbsoluteAddress(m_jit.vm()->watchdog->timerDidFireAddress()));
+        
+        addSlowPathGenerator(slowPathCall(timerDidFire, this, operationHandleWatchdogTimer, unusedGPR));
         break;
+    }
 
     case CountExecution:
         m_jit.add64(TrustedImm32(1), MacroAssembler::AbsoluteAddress(node->executionCounter()->address()));

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (188648 => 188649)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2015-08-19 20:41:30 UTC (rev 188648)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2015-08-19 21:18:15 UTC (rev 188649)
@@ -4329,14 +4329,17 @@
         emitInvalidationPoint(node);
         break;
 
-    case CheckWatchdogTimer:
+    case CheckWatchdogTimer: {
         ASSERT(m_jit.vm()->watchdog);
-        speculationCheck(
-            WatchdogTimerFired, JSValueRegs(), 0,
-            m_jit.branchTest8(
-                JITCompiler::NonZero,
-                JITCompiler::AbsoluteAddress(m_jit.vm()->watchdog->timerDidFireAddress())));
+        GPRTemporary unused(this);
+        GPRReg unusedGPR = unused.gpr();
+
+        JITCompiler::Jump timerDidFire = m_jit.branchTest8(JITCompiler::NonZero,
+            JITCompiler::AbsoluteAddress(m_jit.vm()->watchdog->timerDidFireAddress()));
+
+        addSlowPathGenerator(slowPathCall(timerDidFire, this, operationHandleWatchdogTimer, unusedGPR));
         break;
+    }
 
     case Phantom:
     case Check:

Modified: trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp (188648 => 188649)


--- trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp	2015-08-19 20:41:30 UTC (rev 188648)
+++ trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp	2015-08-19 21:18:15 UTC (rev 188649)
@@ -119,6 +119,7 @@
     case CheckBadCell:
     case CheckNotEmpty:
     case CheckIdent:
+    case CheckWatchdogTimer:
     case StringCharCodeAt:
     case AllocatePropertyStorage:
     case ReallocatePropertyStorage:

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp (188648 => 188649)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp	2015-08-19 20:41:30 UTC (rev 188648)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp	2015-08-19 21:18:15 UTC (rev 188649)
@@ -51,6 +51,7 @@
 #include "ScopedArguments.h"
 #include "ScopedArgumentsTable.h"
 #include "VirtualRegister.h"
+#include "Watchdog.h"
 #include <atomic>
 #include <dlfcn.h>
 #include <llvm/InitializeLLVM.h>
@@ -829,6 +830,9 @@
         case MaterializeCreateActivation:
             compileMaterializeCreateActivation();
             break;
+        case CheckWatchdogTimer:
+            compileCheckWatchdogTimer();
+            break;
 
         case PhantomLocal:
         case LoopHint:
@@ -5428,6 +5432,23 @@
         setJSValue(activation);
     }
 
+    void compileCheckWatchdogTimer()
+    {
+        LBasicBlock timerDidFire = FTL_NEW_BLOCK(m_out, ("CheckWatchdogTimer timer did fire"));
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("CheckWatchdogTimer continuation"));
+        
+        LValue state = m_out.load8(m_out.absolute(vm().watchdog->timerDidFireAddress()));
+        m_out.branch(m_out.equal(state, m_out.constInt8(0)),
+            usually(continuation), rarely(timerDidFire));
+
+        LBasicBlock lastNext = m_out.appendTo(timerDidFire, continuation);
+
+        vmCall(m_out.operation(operationHandleWatchdogTimer), m_callFrame);
+        m_out.jump(continuation);
+        
+        m_out.appendTo(continuation, lastNext);
+    }
+
     bool isInlinableSize(LValue function)
     {
         size_t instructionCount = 0;

Modified: trunk/Source/_javascript_Core/jit/JIT.h (188648 => 188649)


--- trunk/Source/_javascript_Core/jit/JIT.h	2015-08-19 20:41:30 UTC (rev 188648)
+++ trunk/Source/_javascript_Core/jit/JIT.h	2015-08-19 21:18:15 UTC (rev 188649)
@@ -739,6 +739,7 @@
         MacroAssembler::Call callOperation(J_JITOperation_EPc, int, Instruction*);
         MacroAssembler::Call callOperation(J_JITOperation_EZ, int, int32_t);
         MacroAssembler::Call callOperation(J_JITOperation_EZZ, int, int32_t, int32_t);
+        MacroAssembler::Call callOperation(P_JITOperation_E);
         MacroAssembler::Call callOperation(P_JITOperation_EJS, GPRReg, size_t);
         MacroAssembler::Call callOperation(S_JITOperation_ECC, RegisterID, RegisterID);
         MacroAssembler::Call callOperation(S_JITOperation_EJ, RegisterID);

Modified: trunk/Source/_javascript_Core/jit/JITInlines.h (188648 => 188649)


--- trunk/Source/_javascript_Core/jit/JITInlines.h	2015-08-19 20:41:30 UTC (rev 188648)
+++ trunk/Source/_javascript_Core/jit/JITInlines.h	2015-08-19 21:18:15 UTC (rev 188649)
@@ -187,6 +187,12 @@
     return call;
 }
 
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(P_JITOperation_E operation)
+{
+    setupArgumentsExecState();
+    return appendCallWithExceptionCheck(operation);
+}
+
 ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(C_JITOperation_E operation)
 {
     setupArgumentsExecState();

Modified: trunk/Source/_javascript_Core/jit/JITOperations.cpp (188648 => 188649)


--- trunk/Source/_javascript_Core/jit/JITOperations.cpp	2015-08-19 20:41:30 UTC (rev 188648)
+++ trunk/Source/_javascript_Core/jit/JITOperations.cpp	2015-08-19 21:18:15 UTC (rev 188649)
@@ -988,13 +988,19 @@
     return JSValue::encode(RegExpObject::create(vm, exec->lexicalGlobalObject()->regExpStructure(), regexp));
 }
 
-void JIT_OPERATION operationHandleWatchdogTimer(ExecState* exec)
+// The only reason for returning an UnusedPtr (instead of void) is so that we can reuse the
+// existing DFG slow path generator machinery when creating the slow path for CheckWatchdogTimer
+// in the DFG. If a DFG slow path generator that supports a void return type is added in the
+// future, we can switch to using that then.
+UnusedPtr JIT_OPERATION operationHandleWatchdogTimer(ExecState* exec)
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
 
     if (UNLIKELY(vm.watchdog && vm.watchdog->didFire(exec)))
         vm.throwException(exec, createTerminatedExecutionException(&vm));
+
+    return nullptr;
 }
 
 void JIT_OPERATION operationThrowStaticError(ExecState* exec, EncodedJSValue encodedValue, int32_t referenceErrorFlag)

Modified: trunk/Source/_javascript_Core/jit/JITOperations.h (188648 => 188649)


--- trunk/Source/_javascript_Core/jit/JITOperations.h	2015-08-19 20:41:30 UTC (rev 188648)
+++ trunk/Source/_javascript_Core/jit/JITOperations.h	2015-08-19 21:18:15 UTC (rev 188649)
@@ -51,6 +51,8 @@
 
 extern "C" {
 
+typedef char* UnusedPtr;
+
 // These typedefs provide typechecking when generating calls out to helper routines;
 // this helps prevent calling a helper routine with the wrong arguments!
 /*
@@ -293,7 +295,7 @@
 EncodedJSValue JIT_OPERATION operationNewArrowFunctionWithInvalidatedReallocationWatchpoint(ExecState*, JSScope*, JSCell*, EncodedJSValue) WTF_INTERNAL;
 JSCell* JIT_OPERATION operationNewObject(ExecState*, Structure*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationNewRegexp(ExecState*, void*) WTF_INTERNAL;
-void JIT_OPERATION operationHandleWatchdogTimer(ExecState*) WTF_INTERNAL;
+UnusedPtr JIT_OPERATION operationHandleWatchdogTimer(ExecState*) WTF_INTERNAL;
 void JIT_OPERATION operationThrowStaticError(ExecState*, EncodedJSValue, int32_t) WTF_INTERNAL;
 void JIT_OPERATION operationThrow(ExecState*, EncodedJSValue) WTF_INTERNAL;
 void JIT_OPERATION operationDebug(ExecState*, int32_t) WTF_INTERNAL;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to