Title: [162652] trunk/Source/_javascript_Core
Revision
162652
Author
mark....@apple.com
Date
2014-01-23 15:13:23 -0800 (Thu, 23 Jan 2014)

Log Message

Enable DFG for the Debugger and Profiler.
<https://webkit.org/b/122847>

Reviewed by Geoffrey Garen.

In this patch, we implement DFG op_debug as a series of 3 checks:
1. Check if the debugger pointer is non-null. This is needed in case
   the debugger has been detached but the DFG code is still running
   on the stack.
2. Check if Debugger::m_shouldPause is true.
3. Check if CodeBlock::m_numBreakpoints is non-zero.

These are the same 3 checks done in the LLINT and baselineJIT. But unlike
the LLINT and baselineJIT, these DFG checks are implemented as
speculationChecks. If the check fails, we OSR exit to the baselineJIT and
let it do the work of servicing the op_debug callback.

Stepping through code in the debugger would work the same way. The top
function being debugged has to be a LLINT or baselineJIT function because
we would have OSR exited if there is a breakpoint in that function. When
we step out of that function to its caller, we expect that the caller will
call back to the debugger at the next op_debug. If the caller function is
a DFG function, the op_debug site will fail its speculation check on
Debugger::m_shouldPause and deopt into a baselineJIT function. Execution
continues from there as usual, and the debugger gets its callback.

For the profile, op_profile_will_call and op_profile_did_call are
implemented as simple runtime calls to service the profiler.

With this patch, Octane performance with the WebInspector open jump from
~2000 to ~2500 (25% progression).

* bytecode/CodeBlock.h:
(JSC::CodeBlock::numBreakpointsAddress):
* bytecode/ExitKind.cpp:
(JSC::exitKindToString):
* bytecode/ExitKind.h:
* debugger/Debugger.cpp:
(JSC::Debugger::toggleBreakpoint):
- removed an obsolete assertion. The debugger can now handle DFG
  CodeBlocks too.
* debugger/Debugger.h:
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGNodeType.h:
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::callOperation):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::debuggerAddress):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (162651 => 162652)


--- trunk/Source/_javascript_Core/ChangeLog	2014-01-23 23:10:49 UTC (rev 162651)
+++ trunk/Source/_javascript_Core/ChangeLog	2014-01-23 23:13:23 UTC (rev 162652)
@@ -1,3 +1,71 @@
+2014-01-23  Mark Lam  <mark....@apple.com>
+
+        Enable DFG for the Debugger and Profiler.
+        <https://webkit.org/b/122847>
+
+        Reviewed by Geoffrey Garen.
+
+        In this patch, we implement DFG op_debug as a series of 3 checks:
+        1. Check if the debugger pointer is non-null. This is needed in case
+           the debugger has been detached but the DFG code is still running
+           on the stack.
+        2. Check if Debugger::m_shouldPause is true.
+        3. Check if CodeBlock::m_numBreakpoints is non-zero.
+
+        These are the same 3 checks done in the LLINT and baselineJIT. But unlike
+        the LLINT and baselineJIT, these DFG checks are implemented as
+        speculationChecks. If the check fails, we OSR exit to the baselineJIT and
+        let it do the work of servicing the op_debug callback.
+
+        Stepping through code in the debugger would work the same way. The top
+        function being debugged has to be a LLINT or baselineJIT function because
+        we would have OSR exited if there is a breakpoint in that function. When
+        we step out of that function to its caller, we expect that the caller will
+        call back to the debugger at the next op_debug. If the caller function is
+        a DFG function, the op_debug site will fail its speculation check on
+        Debugger::m_shouldPause and deopt into a baselineJIT function. Execution
+        continues from there as usual, and the debugger gets its callback.
+
+        For the profile, op_profile_will_call and op_profile_did_call are
+        implemented as simple runtime calls to service the profiler.
+
+        With this patch, Octane performance with the WebInspector open jump from
+        ~2000 to ~2500 (25% progression).
+
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::numBreakpointsAddress):
+        * bytecode/ExitKind.cpp:
+        (JSC::exitKindToString):
+        * bytecode/ExitKind.h:
+        * debugger/Debugger.cpp:
+        (JSC::Debugger::toggleBreakpoint):
+        - removed an obsolete assertion. The debugger can now handle DFG
+          CodeBlocks too.
+        * debugger/Debugger.h:
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::callOperation):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::debuggerAddress):
+
 2014-01-23  Max Vujovic  <mvujo...@adobe.com>
 
         Remove CSS Custom Filters code and tests

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (162651 => 162652)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h	2014-01-23 23:10:49 UTC (rev 162651)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h	2014-01-23 23:13:23 UTC (rev 162652)
@@ -873,6 +873,7 @@
 
     int numBreakpoints() const { return m_numBreakpoints; }
     static ptrdiff_t numBreakpointsOffset() { return OBJECT_OFFSETOF(CodeBlock, m_numBreakpoints); }
+    void* numBreakpointsAddress() { return &m_numBreakpoints; }
 
     void addBreakpoint(int numBreakpoints) { m_numBreakpoints += numBreakpoints; }
     void removeBreakpoint(int numBreakpoints)

Modified: trunk/Source/_javascript_Core/bytecode/ExitKind.cpp (162651 => 162652)


--- trunk/Source/_javascript_Core/bytecode/ExitKind.cpp	2014-01-23 23:10:49 UTC (rev 162651)
+++ trunk/Source/_javascript_Core/bytecode/ExitKind.cpp	2014-01-23 23:13:23 UTC (rev 162652)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -78,6 +78,8 @@
         return "UncountableInvalidation";
     case WatchdogTimerFired:
         return "WatchdogTimerFired";
+    case DebuggerEvent:
+        return "DebuggerEvent";
     }
     RELEASE_ASSERT_NOT_REACHED();
     return "Unknown";

Modified: trunk/Source/_javascript_Core/bytecode/ExitKind.h (162651 => 162652)


--- trunk/Source/_javascript_Core/bytecode/ExitKind.h	2014-01-23 23:10:49 UTC (rev 162651)
+++ trunk/Source/_javascript_Core/bytecode/ExitKind.h	2014-01-23 23:13:23 UTC (rev 162652)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -50,7 +50,8 @@
     Uncountable, // We exited for none of the above reasons, and we should not count it. Most uses of this should be viewed as a FIXME.
     UncountableInvalidation, // We exited because the code block was invalidated; this means that we've already counted the reasons why the code block was invalidated.
     UncountableWatchpoint, // We exited because of a watchpoint, which isn't counted because watchpoints do tracking themselves.
-    WatchdogTimerFired // We exited because we need to service the watchdog timer.
+    WatchdogTimerFired, // We exited because we need to service the watchdog timer.
+    DebuggerEvent // We exited because we need to service the debugger.
 };
 
 const char* exitKindToString(ExitKind);

Modified: trunk/Source/_javascript_Core/debugger/Debugger.cpp (162651 => 162652)


--- trunk/Source/_javascript_Core/debugger/Debugger.cpp	2014-01-23 23:10:49 UTC (rev 162651)
+++ trunk/Source/_javascript_Core/debugger/Debugger.cpp	2014-01-23 23:13:23 UTC (rev 162652)
@@ -211,9 +211,6 @@
 
 void Debugger::toggleBreakpoint(CodeBlock* codeBlock, Breakpoint& breakpoint, BreakpointState enabledOrNot)
 {
-    ASSERT(codeBlock->jitCode()->jitType() == JITCode::InterpreterThunk
-        || codeBlock->jitCode()->jitType() == JITCode::BaselineJIT);
-
     ScriptExecutable* executable = codeBlock->ownerExecutable();
 
     SourceID sourceID = static_cast<SourceID>(executable->sourceID());

Modified: trunk/Source/_javascript_Core/debugger/Debugger.h (162651 => 162652)


--- trunk/Source/_javascript_Core/debugger/Debugger.h	2014-01-23 23:10:49 UTC (rev 162651)
+++ trunk/Source/_javascript_Core/debugger/Debugger.h	2014-01-23 23:13:23 UTC (rev 162652)
@@ -50,6 +50,7 @@
 
     bool shouldPause() const { return m_shouldPause; }
     static ptrdiff_t shouldPauseOffset() { return OBJECT_OFFSETOF(Debugger, m_shouldPause); }
+    void* shouldPauseAddress() { return &m_shouldPause; }
 
     JSC::DebuggerCallFrame* currentDebuggerCallFrame() const;
     bool hasHandlerForExceptionCallback() const

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (162651 => 162652)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2014-01-23 23:10:49 UTC (rev 162651)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2014-01-23 23:13:23 UTC (rev 162652)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -1736,7 +1736,6 @@
         
     case Flush:
     case PhantomLocal:
-    case Breakpoint:
         break;
             
     case Call:
@@ -1754,11 +1753,14 @@
     case InvalidationPoint:
         node->setCanExit(true);
         break;
-            
+
+    case Breakpoint:
     case CheckWatchdogTimer:
         node->setCanExit(true);
         break;
-            
+
+    case ProfileWillCall:
+    case ProfileDidCall:
     case Phantom:
     case Check:
     case CountExecution:

Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (162651 => 162652)


--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2014-01-23 23:10:49 UTC (rev 162651)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2014-01-23 23:13:23 UTC (rev 162652)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -2146,11 +2146,22 @@
 
         // === Misc operations ===
 
-#if ENABLE(DEBUG_WITH_BREAKPOINT)
         case op_debug:
             addToGraph(Breakpoint);
             NEXT_OPCODE(op_debug);
-#endif
+
+        case op_profile_will_call: {
+            Node* profile = ""
+            addToGraph(ProfileWillCall, profile);
+            NEXT_OPCODE(op_profile_will_call);
+        }
+
+        case op_profile_did_call: {
+            Node* profile = ""
+            addToGraph(ProfileDidCall, profile);
+            NEXT_OPCODE(op_profile_did_call);
+        }
+
         case op_mov: {
             Node* op = get(VirtualRegister(currentInstruction[2].u.operand));
             set(VirtualRegister(currentInstruction[1].u.operand), op);

Modified: trunk/Source/_javascript_Core/dfg/DFGCapabilities.cpp (162651 => 162652)


--- trunk/Source/_javascript_Core/dfg/DFGCapabilities.cpp	2014-01-23 23:10:49 UTC (rev 162651)
+++ trunk/Source/_javascript_Core/dfg/DFGCapabilities.cpp	2014-01-23 23:13:23 UTC (rev 162652)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -100,9 +100,9 @@
     case op_mul:
     case op_mod:
     case op_div:
-#if ENABLE(DEBUG_WITH_BREAKPOINT)
     case op_debug:
-#endif
+    case op_profile_will_call:
+    case op_profile_did_call:
     case op_mov:
     case op_captured_mov:
     case op_check_has_instance:

Modified: trunk/Source/_javascript_Core/dfg/DFGClobberize.h (162651 => 162652)


--- trunk/Source/_javascript_Core/dfg/DFGClobberize.h	2014-01-23 23:10:49 UTC (rev 162651)
+++ trunk/Source/_javascript_Core/dfg/DFGClobberize.h	2014-01-23 23:13:23 UTC (rev 162652)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -139,7 +139,8 @@
     case Flush:
     case PhantomLocal:
     case SetArgument:
-    case Breakpoint:
+    case ProfileWillCall:
+    case ProfileDidCall:
     case PhantomArguments:
     case Jump:
     case Branch:
@@ -619,6 +620,7 @@
         clobberizeForAllocation(read, write);
         return;
         
+    case Breakpoint:
     case CountExecution:
     case CheckWatchdogTimer:
         read(InternalState);

Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (162651 => 162652)


--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2014-01-23 23:10:49 UTC (rev 162651)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2014-01-23 23:13:23 UTC (rev 162652)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -991,6 +991,8 @@
         case NewArrayBuffer:
         case NewRegexp:
         case Breakpoint:
+        case ProfileWillCall:
+        case ProfileDidCall:
         case IsUndefined:
         case IsBoolean:
         case IsNumber:

Modified: trunk/Source/_javascript_Core/dfg/DFGNodeType.h (162651 => 162652)


--- trunk/Source/_javascript_Core/dfg/DFGNodeType.h	2014-01-23 23:10:49 UTC (rev 162651)
+++ trunk/Source/_javascript_Core/dfg/DFGNodeType.h	2014-01-23 23:13:23 UTC (rev 162652)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -230,7 +230,9 @@
     macro(NewRegexp, NodeResultJS) \
     \
     /* Nodes for misc operations. */\
-    macro(Breakpoint, NodeMustGenerate | NodeClobbersWorld) \
+    macro(Breakpoint, NodeMustGenerate) \
+    macro(ProfileWillCall, NodeMustGenerate | NodeClobbersWorld) \
+    macro(ProfileDidCall, NodeMustGenerate | NodeClobbersWorld) \
     macro(CheckHasInstance, NodeMustGenerate) \
     macro(InstanceOf, NodeResultBoolean) \
     macro(IsUndefined, NodeResultBoolean) \

Modified: trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp (162651 => 162652)


--- trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp	2014-01-23 23:10:49 UTC (rev 162651)
+++ trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp	2014-01-23 23:13:23 UTC (rev 162652)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -554,6 +554,8 @@
         case Branch:
         case Switch:
         case Breakpoint:
+        case ProfileWillCall:
+        case ProfileDidCall:
         case CheckHasInstance:
         case ThrowReferenceError:
         case ForceOSRExit:

Modified: trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h (162651 => 162652)


--- trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h	2014-01-23 23:10:49 UTC (rev 162651)
+++ trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h	2014-01-23 23:13:23 UTC (rev 162652)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -193,6 +193,8 @@
     case NewArrayBuffer:
     case NewRegexp:
     case Breakpoint:
+    case ProfileWillCall:
+    case ProfileDidCall:
     case CheckHasInstance:
     case InstanceOf:
     case IsUndefined:

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (162651 => 162652)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2014-01-23 23:10:49 UTC (rev 162651)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2014-01-23 23:13:23 UTC (rev 162652)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -1372,6 +1372,11 @@
         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
         return appendCallWithExceptionCheck(operation);
     }
+    JITCompiler::Call callOperation(V_JITOperation_EJ operation, GPRReg arg1)
+    {
+        m_jit.setupArgumentsWithExecState(arg1);
+        return appendCallWithExceptionCheck(operation);
+    }
     JITCompiler::Call callOperation(V_JITOperation_EJPP operation, GPRReg arg1, GPRReg arg2, void* pointer)
     {
         m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(pointer));
@@ -1630,6 +1635,12 @@
         return appendCallWithExceptionCheck(operation);
     }
 
+    JITCompiler::Call callOperation(V_JITOperation_EJ operation, GPRReg arg1Tag, GPRReg arg1Payload)
+    {
+        m_jit.setupArgumentsWithExecState(arg1Tag, arg1Payload);
+        return appendCallWithExceptionCheck(operation);
+    }
+
     JITCompiler::Call callOperation(V_JITOperation_EJPP operation, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2, void* pointer)
     {
         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2, TrustedImmPtr(pointer));

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (162651 => 162652)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2014-01-23 23:10:49 UTC (rev 162651)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2014-01-23 23:13:23 UTC (rev 162652)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
  * Copyright (C) 2011 Intel Corporation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,6 +34,7 @@
 #include "DFGCallArrayAllocatorSlowPathGenerator.h"
 #include "DFGOperations.h"
 #include "DFGSlowPathGenerator.h"
+#include "Debugger.h"
 #include "JSActivation.h"
 #include "ObjectPrototype.h"
 #include "Operations.h"
@@ -4231,14 +4232,51 @@
     case Flush:
         break;
 
-    case Breakpoint:
-#if ENABLE(DEBUG_WITH_BREAKPOINT)
-        m_jit.breakpoint();
-#else
-        RELEASE_ASSERT_NOT_REACHED();
-#endif
+    case Breakpoint: {
+        JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(m_currentNode->codeOrigin);
+        GPRTemporary temp(this);
+        m_jit.loadPtr(globalObject->debuggerAddress(), temp.gpr());
+        speculationCheck(
+            DebuggerEvent, JSValueRegs(), 0,
+            m_jit.branchTestPtr(JITCompiler::Zero, temp.gpr()));
+
+        ASSERT(globalObject->hasDebugger());
+        speculationCheck(
+            DebuggerEvent, JSValueRegs(), 0,
+            m_jit.branchTest8(
+                JITCompiler::NonZero,
+                JITCompiler::AbsoluteAddress(globalObject->debugger()->shouldPauseAddress())));
+
+        GPRReg numBreakpointsGPR = temp.gpr();
+        m_jit.load32(m_jit.codeBlock()->numBreakpointsAddress(), numBreakpointsGPR);
+        speculationCheck(
+            DebuggerEvent, JSValueRegs(), 0,
+            m_jit.branchTest32(JITCompiler::NonZero, numBreakpointsGPR));
         break;
+    }
         
+    case ProfileWillCall: {
+        JSValueOperand profile(this, node->child1());
+        GPRReg profileTagGPR = profile.tagGPR();
+        GPRReg profilePayloadGPR = profile.payloadGPR();
+        silentSpillAllRegisters(InvalidGPRReg);
+        callOperation(operationProfileWillCall, profileTagGPR, profilePayloadGPR);
+        silentFillAllRegisters(InvalidGPRReg);
+        noResult(node);
+        break;
+    }
+
+    case ProfileDidCall: {
+        JSValueOperand profile(this, node->child1());
+        GPRReg profileTagGPR = profile.tagGPR();
+        GPRReg profilePayloadGPR = profile.payloadGPR();
+        silentSpillAllRegisters(InvalidGPRReg);
+        callOperation(operationProfileWillCall, profileTagGPR, profilePayloadGPR);
+        silentFillAllRegisters(InvalidGPRReg);
+        noResult(node);
+        break;
+    }
+
     case Call:
     case Construct:
         emitCall(node);

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (162651 => 162652)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2014-01-23 23:10:49 UTC (rev 162651)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2014-01-23 23:13:23 UTC (rev 162652)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -34,6 +34,7 @@
 #include "DFGCallArrayAllocatorSlowPathGenerator.h"
 #include "DFGOperations.h"
 #include "DFGSlowPathGenerator.h"
+#include "Debugger.h"
 #include "JSCJSValueInlines.h"
 #include "ObjectPrototype.h"
 
@@ -4508,14 +4509,50 @@
     case Flush:
         break;
 
-    case Breakpoint:
-#if ENABLE(DEBUG_WITH_BREAKPOINT)
-        m_jit.breakpoint();
-#else
-        RELEASE_ASSERT_NOT_REACHED();
-#endif
+    case Breakpoint: {
+        JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(m_currentNode->codeOrigin);
+        speculationCheck(
+            DebuggerEvent, JSValueRegs(), 0,
+            m_jit.branchTestPtr(
+                JITCompiler::Zero,
+                JITCompiler::AbsoluteAddress(globalObject->debuggerAddress())));
+
+        ASSERT(globalObject->hasDebugger());
+        speculationCheck(
+            DebuggerEvent, JSValueRegs(), 0,
+            m_jit.branchTest8(
+                JITCompiler::NonZero,
+                JITCompiler::AbsoluteAddress(globalObject->debugger()->shouldPauseAddress())));
+
+        GPRTemporary temp(this);
+        GPRReg numBreakpointsGPR = temp.gpr();
+        m_jit.load32(m_jit.codeBlock()->numBreakpointsAddress(), numBreakpointsGPR);
+        speculationCheck(
+            DebuggerEvent, JSValueRegs(), 0,
+            m_jit.branchTest32(JITCompiler::NonZero, numBreakpointsGPR));
         break;
+    }
         
+    case ProfileWillCall: {
+        JSValueOperand profile(this, node->child1());
+        GPRReg profileGPR = profile.gpr();
+        silentSpillAllRegisters(InvalidGPRReg);
+        callOperation(operationProfileWillCall, profileGPR);
+        silentFillAllRegisters(InvalidGPRReg);
+        noResult(node);
+        break;
+    }
+
+    case ProfileDidCall: {
+        JSValueOperand profile(this, node->child1());
+        GPRReg profileGPR = profile.gpr();
+        silentSpillAllRegisters(InvalidGPRReg);
+        callOperation(operationProfileDidCall, profileGPR);
+        silentFillAllRegisters(InvalidGPRReg);
+        noResult(node);
+        break;
+    }
+
     case Call:
     case Construct:
         emitCall(node);

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.h (162651 => 162652)


--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.h	2014-01-23 23:10:49 UTC (rev 162651)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.h	2014-01-23 23:13:23 UTC (rev 162652)
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 2007 Eric Seidel <e...@webkit.org>
- *  Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007, 2008, 2009, 2014 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
@@ -473,6 +473,7 @@
     Debugger* debugger() const { return m_debugger; }
     void setDebugger(Debugger* debugger) { m_debugger = debugger; }
     static ptrdiff_t debuggerOffset() { return OBJECT_OFFSETOF(JSGlobalObject, m_debugger); }
+    void* debuggerAddress() { return &m_debugger; }
 
     const GlobalObjectMethodTable* globalObjectMethodTable() const { return m_globalObjectMethodTable; }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to