Title: [162940] trunk
Revision
162940
Author
mark....@apple.com
Date
2014-01-28 09:43:07 -0800 (Tue, 28 Jan 2014)

Log Message

Jettison DFG code when neither breakpoints or the profiler are active.
<https://webkit.org/b/127766>

Reviewed by Geoffrey Garen.

Source/_javascript_Core: 

We need to jettison the DFG CodeBlocks under the following circumstances:
1. When adding breakpoints to a CodeBlock, jettison it if it is a DFG CodeBlock.
2. When enabling stepping mode in a CodeBlock, jettison it if it a DFG CodeBlock.
3. When settign the enabled profiler in the VM, we need to jettison all DFG
   CodeBlocks.

Instead of emitting speculation checks, the DFG code will now treat Breakpoint,
ProfileWillCall, and ProfileDidCall as no-ops similar to a Phantom node. We
still need to track these nodes so that they match the corresponding opcodes
in the baseline JIT when we jettison and OSR exit. Without them, we would OSR
exit to the wrong location in the baseline JIT code.

In DFGDriver's compileImpl() and DFGPlan's finalizeWithoutNotifyingCallback()
we fail the compilation effort with a CompilationInvalidated result. This allows
the DFG compiler to re-attampt the compilation of the function after some time
if it is hot. The CompilationInvalidated result is supposed to cause the DFG
to exercise an exponential back off before re-attempting compilation again
(see runtime/CompilationResult.h).

This patch improves the Octane score from ~2950 to ~3067.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::addBreakpoint):
(JSC::CodeBlock::setSteppingMode):
* bytecode/CodeBlock.h:
* debugger/Debugger.h:
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDriver.cpp:
(JSC::DFG::compileImpl):
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::finalizeWithoutNotifyingCallback):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* profiler/LegacyProfiler.cpp:
(JSC::LegacyProfiler::startProfiling):
(JSC::LegacyProfiler::stopProfiling):
* runtime/VM.cpp:
(JSC::VM::VM):
(JSC::SetEnabledProfilerFunctor::operator()):
(JSC::VM::setEnabledProfiler):
* runtime/VM.h:
(JSC::VM::enabledProfiler):

LayoutTests: 

Added a test to exercise setting a breakpoint in 2 DFG compiled functions:
1 not inlined, and 1 inlined.

* inspector-protocol/debugger/resources/breakpoint.js:
(notInlineable):
(inlineable):
(notInliningFoo):
(inliningFoo):
(dfgWithoutInline):
(dfgWithInline):
* inspector-protocol/debugger/setBreakpoint-dfg-expected.txt: Added.
* inspector-protocol/debugger/setBreakpoint-dfg.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (162939 => 162940)


--- trunk/LayoutTests/ChangeLog	2014-01-28 17:38:49 UTC (rev 162939)
+++ trunk/LayoutTests/ChangeLog	2014-01-28 17:43:07 UTC (rev 162940)
@@ -1,3 +1,23 @@
+2014-01-28  Mark Lam  <mark....@apple.com>
+
+        Jettison DFG code when neither breakpoints or the profiler are active.
+        <https://webkit.org/b/127766>
+
+        Reviewed by Geoffrey Garen.
+
+        Added a test to exercise setting a breakpoint in 2 DFG compiled functions:
+        1 not inlined, and 1 inlined.
+
+        * inspector-protocol/debugger/resources/breakpoint.js:
+        (notInlineable):
+        (inlineable):
+        (notInliningFoo):
+        (inliningFoo):
+        (dfgWithoutInline):
+        (dfgWithInline):
+        * inspector-protocol/debugger/setBreakpoint-dfg-expected.txt: Added.
+        * inspector-protocol/debugger/setBreakpoint-dfg.html: Added.
+
 2014-01-28  Gurpreet Kaur  <k.gurpr...@samsung.com>
 
         Add support for menclose element

Modified: trunk/LayoutTests/inspector-protocol/debugger/resources/breakpoint.js (162939 => 162940)


--- trunk/LayoutTests/inspector-protocol/debugger/resources/breakpoint.js	2014-01-28 17:38:49 UTC (rev 162939)
+++ trunk/LayoutTests/inspector-protocol/debugger/resources/breakpoint.js	2014-01-28 17:43:07 UTC (rev 162940)
@@ -17,3 +17,42 @@
 {
     log("inside breakpointActions a:(" + a + ") b:(" + b + ")");
 }
+
+function notInlineable(x)
+{
+    var func = new Function("return x + 100;");
+    return x + 3;
+}
+
+function inlineable(x)
+{
+    return x + 5;
+}
+
+function notInliningFoo(x)
+{
+    return notInlineable(x);
+}
+
+function inliningFoo(x)
+{
+    return inlineable(x);
+}
+
+function dfgWithoutInline()
+{
+    var i;
+    var result = 0;
+    for (i = 0; i < 1000; i++)
+        result += notInliningFoo(i);
+    log("dfgWithoutInline result: " + result);    
+}
+
+function dfgWithInline()
+{
+    var i;
+    var result = 0;
+    for (i = 0; i < 1000; i++)
+        result += inliningFoo(i);
+    log("dfgWithInline result: " + result);    
+}

Added: trunk/LayoutTests/inspector-protocol/debugger/setBreakpoint-dfg-expected.txt (0 => 162940)


--- trunk/LayoutTests/inspector-protocol/debugger/setBreakpoint-dfg-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/inspector-protocol/debugger/setBreakpoint-dfg-expected.txt	2014-01-28 17:43:07 UTC (rev 162940)
@@ -0,0 +1,18 @@
+Debugger.setBreakpoint in DFG compiled functions.
+
+Found breakpoint.js
+dfgWithoutInline result: 502500
+dfgWithInline result: 504500
+dfg functions warmed up
+
+Breakpoint set in notInlineable()
+Breakpoint set in inlineable()
+
+Hit Breakpoint 1!
+Removed Breakpoint 1!
+dfgWithoutInline result: 502500
+Hit Breakpoint 2!
+Removed Breakpoint 2!
+PASS
+dfgWithInline result: 504500
+

Added: trunk/LayoutTests/inspector-protocol/debugger/setBreakpoint-dfg.html (0 => 162940)


--- trunk/LayoutTests/inspector-protocol/debugger/setBreakpoint-dfg.html	                        (rev 0)
+++ trunk/LayoutTests/inspector-protocol/debugger/setBreakpoint-dfg.html	2014-01-28 17:43:07 UTC (rev 162940)
@@ -0,0 +1,85 @@
+<html>
+<head>
+<script src=""
+<script src=""
+
+<script>
+// Put this here instead of on <body onload> to prevent an extra Debugger.scriptParsed event.
+window._onload_ = runTest;
+
+function test()
+{
+    // This test setting 2 breakpoints in DFG compiled functions: one inlined,
+    // and one not inlined.
+
+    InspectorTest.sendCommand("Debugger.enable", {});
+
+    var dfgNonInlinedBreakpointId = null;
+    var dfgInlinedBreakpointId = null;
+    var scriptIdentifier = 0;
+    var startLine = 0;
+
+    InspectorTest.eventHandler["Debugger.scriptParsed"] = function(messageObject)
+    {
+        if (/resources\/breakpoint\.js$/.test(messageObject.params.url)) {
+            InspectorTest.log("Found breakpoint.js");
+            scriptIdentifier = messageObject.params.scriptId;
+            startLine = messageObject.params.startLine;
+
+            InspectorTest.sendCommand("Runtime.evaluate", {
+                _expression_: "dfgWithoutInline(); dfgWithInline();"
+            }, function(responseObject) {
+                InspectorTest.log("dfg functions warmed up\n");
+
+                var location1 = {scriptId: scriptIdentifier, lineNumber: 22, columnNumber: 0};
+
+                InspectorTest.sendCommand("Debugger.setBreakpoint", {location: location1}, function(responseObject) {
+                    InspectorTest.checkForError(responseObject);
+                    InspectorTest.log("Breakpoint set in notInlineable()");
+
+                    dfgNonInlinedBreakpointId = responseObject.result.breakpointId;
+                    var location2 = {scriptId: scriptIdentifier, lineNumber: 28, columnNumber: 0};
+                    InspectorTest.sendCommand("Debugger.setBreakpoint", {location: location2}, function(responseObject) {
+                        InspectorTest.checkForError(responseObject);
+                        InspectorTest.log("Breakpoint set in inlineable()\n");
+
+                        dfgInlinedBreakpointId = responseObject.result.breakpointId;
+                        InspectorTest.sendCommand("Runtime.evaluate", {
+                            _expression_: "dfgWithoutInline(); dfgWithInline();"
+                        });
+                    });
+                });
+            });
+        }
+    }
+
+    var breakpointsHit = 0;
+    InspectorTest.eventHandler["Debugger.paused"] = function(messageObject)
+    {
+        var breakpointId = null;
+        breakpointsHit++;
+        InspectorTest.log("Hit Breakpoint " + breakpointsHit + "!");
+        if (breakpointsHit == 1)
+            breakpointId = dfgNonInlinedBreakpointId;
+        else if (breakpointsHit == 2)
+            breakpointId = dfgInlinedBreakpointId;
+        else
+            InspectorTest.log("Unexpected breakpoint");
+
+        InspectorTest.sendCommand("Debugger.removeBreakpoint", {"breakpointId": breakpointId}, function(responseObject) {
+            InspectorTest.log("Removed Breakpoint " + breakpointsHit + "!");
+            InspectorTest.sendCommand("Debugger.resume", {}, function(responseObject) {
+                if (breakpointsHit == 2) {
+                    InspectorTest.log("PASS");
+                    InspectorTest.completeTest();
+                }
+            });
+        });
+    }
+}
+</script>
+</head>
+<body>
+<p>Debugger.setBreakpoint in DFG compiled functions.</p>
+</body>
+</html>

Modified: trunk/Source/_javascript_Core/ChangeLog (162939 => 162940)


--- trunk/Source/_javascript_Core/ChangeLog	2014-01-28 17:38:49 UTC (rev 162939)
+++ trunk/Source/_javascript_Core/ChangeLog	2014-01-28 17:43:07 UTC (rev 162940)
@@ -1,3 +1,58 @@
+2014-01-28  Mark Lam  <mark....@apple.com>
+
+        Jettison DFG code when neither breakpoints or the profiler are active.
+        <https://webkit.org/b/127766>
+
+        Reviewed by Geoffrey Garen.
+
+        We need to jettison the DFG CodeBlocks under the following circumstances:
+        1. When adding breakpoints to a CodeBlock, jettison it if it is a DFG CodeBlock.
+        2. When enabling stepping mode in a CodeBlock, jettison it if it a DFG CodeBlock.
+        3. When settign the enabled profiler in the VM, we need to jettison all DFG
+           CodeBlocks.
+
+        Instead of emitting speculation checks, the DFG code will now treat Breakpoint,
+        ProfileWillCall, and ProfileDidCall as no-ops similar to a Phantom node. We
+        still need to track these nodes so that they match the corresponding opcodes
+        in the baseline JIT when we jettison and OSR exit. Without them, we would OSR
+        exit to the wrong location in the baseline JIT code.
+
+        In DFGDriver's compileImpl() and DFGPlan's finalizeWithoutNotifyingCallback()
+        we fail the compilation effort with a CompilationInvalidated result. This allows
+        the DFG compiler to re-attampt the compilation of the function after some time
+        if it is hot. The CompilationInvalidated result is supposed to cause the DFG
+        to exercise an exponential back off before re-attempting compilation again
+        (see runtime/CompilationResult.h).
+
+        This patch improves the Octane score from ~2950 to ~3067.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::addBreakpoint):
+        (JSC::CodeBlock::setSteppingMode):
+        * bytecode/CodeBlock.h:
+        * debugger/Debugger.h:
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDriver.cpp:
+        (JSC::DFG::compileImpl):
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::finalizeWithoutNotifyingCallback):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * profiler/LegacyProfiler.cpp:
+        (JSC::LegacyProfiler::startProfiling):
+        (JSC::LegacyProfiler::stopProfiling):
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        (JSC::SetEnabledProfilerFunctor::operator()):
+        (JSC::VM::setEnabledProfiler):
+        * runtime/VM.h:
+        (JSC::VM::enabledProfiler):
+
 2014-01-27  Joseph Pecoraro  <pecor...@apple.com>
 
         -[JSContext evaluteScript:] calls JSEvaluteScript with startingLineNumber 0, later interpreted as a oneBasedInt

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (162939 => 162940)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2014-01-28 17:38:49 UTC (rev 162939)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2014-01-28 17:43:07 UTC (rev 162940)
@@ -3531,4 +3531,19 @@
     RELEASE_ASSERT_NOT_REACHED();
 }
 
+void CodeBlock::addBreakpoint(unsigned numBreakpoints)
+{
+    m_numBreakpoints += numBreakpoints;
+    ASSERT(m_numBreakpoints);
+    if (jitType() == JITCode::DFGJIT)
+        jettison();
+}
+
+void CodeBlock::setSteppingMode(CodeBlock::SteppingMode mode)
+{
+    m_steppingMode = mode;
+    if (mode == SteppingModeEnabled && jitType() == JITCode::DFGJIT)
+        jettison();
+}
+
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (162939 => 162940)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h	2014-01-28 17:38:49 UTC (rev 162939)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h	2014-01-28 17:43:07 UTC (rev 162940)
@@ -872,7 +872,7 @@
     int hasDebuggerRequests() const { return !!m_debuggerRequests; }
     void* debuggerRequestsAddress() { return &m_debuggerRequests; }
 
-    void addBreakpoint(unsigned numBreakpoints) { m_numBreakpoints += numBreakpoints; }
+    void addBreakpoint(unsigned numBreakpoints);
     void removeBreakpoint(unsigned numBreakpoints)
     {
         ASSERT(m_numBreakpoints >= numBreakpoints);
@@ -883,7 +883,7 @@
         SteppingModeDisabled,
         SteppingModeEnabled
     };
-    void setSteppingMode(SteppingMode mode) { m_steppingMode = mode; }
+    void setSteppingMode(SteppingMode);
 
     void clearDebuggerRequests() { m_debuggerRequests = 0; }
 

Modified: trunk/Source/_javascript_Core/debugger/Debugger.h (162939 => 162940)


--- trunk/Source/_javascript_Core/debugger/Debugger.h	2014-01-28 17:38:49 UTC (rev 162939)
+++ trunk/Source/_javascript_Core/debugger/Debugger.h	2014-01-28 17:43:07 UTC (rev 162940)
@@ -90,6 +90,7 @@
     void stepOutOfFunction();
 
     bool isPaused() { return m_isPaused; }
+    bool isStepping() const { return m_steppingMode == SteppingModeEnabled; }
 
     virtual void sourceParsed(ExecState*, SourceProvider*, int errorLineNumber, const WTF::String& errorMessage) = 0;
 
@@ -170,7 +171,6 @@
         SteppingModeEnabled
     };
     void setSteppingMode(SteppingMode);
-    bool isStepping() const { return m_steppingMode == SteppingModeEnabled; }
 
     enum BreakpointState {
         BreakpointDisabled,

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (162939 => 162940)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2014-01-28 17:38:49 UTC (rev 162939)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2014-01-28 17:43:07 UTC (rev 162940)
@@ -1754,13 +1754,13 @@
         node->setCanExit(true);
         break;
 
-    case Breakpoint:
-    case ProfileWillCall:
-    case ProfileDidCall:
     case CheckWatchdogTimer:
         node->setCanExit(true);
         break;
 
+    case Breakpoint:
+    case ProfileWillCall:
+    case ProfileDidCall:
     case Phantom:
     case Check:
     case CountExecution:

Modified: trunk/Source/_javascript_Core/dfg/DFGClobberize.h (162939 => 162940)


--- trunk/Source/_javascript_Core/dfg/DFGClobberize.h	2014-01-28 17:38:49 UTC (rev 162939)
+++ trunk/Source/_javascript_Core/dfg/DFGClobberize.h	2014-01-28 17:43:07 UTC (rev 162940)
@@ -88,6 +88,9 @@
     case WeakJSConstant:
     case Identity:
     case Phantom:
+    case Breakpoint:
+    case ProfileWillCall:
+    case ProfileDidCall:
     case BitAnd:
     case BitOr:
     case BitXor:
@@ -618,9 +621,6 @@
         clobberizeForAllocation(read, write);
         return;
         
-    case Breakpoint:
-    case ProfileWillCall:
-    case ProfileDidCall:
     case CountExecution:
     case CheckWatchdogTimer:
         read(InternalState);

Modified: trunk/Source/_javascript_Core/dfg/DFGDriver.cpp (162939 => 162940)


--- trunk/Source/_javascript_Core/dfg/DFGDriver.cpp	2014-01-28 17:38:49 UTC (rev 162939)
+++ trunk/Source/_javascript_Core/dfg/DFGDriver.cpp	2014-01-28 17:43:07 UTC (rev 162940)
@@ -34,6 +34,7 @@
 #include "DFGPlan.h"
 #include "DFGThunks.h"
 #include "DFGWorklist.h"
+#include "Debugger.h"
 #include "JITCode.h"
 #include "Operations.h"
 #include "Options.h"
@@ -73,6 +74,13 @@
     if (!Options::bytecodeRangeToDFGCompile().isInRange(codeBlock->instructionCount()))
         return CompilationFailed;
     
+    if (vm.enabledProfiler())
+        return CompilationInvalidated;
+
+    Debugger* debugger = codeBlock->globalObject()->debugger();
+    if (debugger && (debugger->isStepping() || codeBlock->baselineAlternative()->hasDebuggerRequests()))
+        return CompilationInvalidated;
+
     if (logCompilationChanges())
         dataLog("DFG(Driver) compiling ", *codeBlock, " with ", mode, ", number of instructions = ", codeBlock->instructionCount(), "\n");
     

Modified: trunk/Source/_javascript_Core/dfg/DFGPlan.cpp (162939 => 162940)


--- trunk/Source/_javascript_Core/dfg/DFGPlan.cpp	2014-01-28 17:38:49 UTC (rev 162939)
+++ trunk/Source/_javascript_Core/dfg/DFGPlan.cpp	2014-01-28 17:43:07 UTC (rev 162940)
@@ -62,6 +62,7 @@
 #include "DFGValidate.h"
 #include "DFGVirtualRegisterAllocationPhase.h"
 #include "DFGWatchpointCollectionPhase.h"
+#include "Debugger.h"
 #include "OperandsInlines.h"
 #include "Operations.h"
 #include <wtf/CurrentTime.h>
@@ -346,7 +347,14 @@
 {
     if (!isStillValid())
         return CompilationInvalidated;
-    
+
+    if (vm.enabledProfiler())
+        return CompilationInvalidated;
+
+    Debugger* debugger = codeBlock->globalObject()->debugger();
+    if (debugger && (debugger->isStepping() || codeBlock->baselineAlternative()->hasDebuggerRequests()))
+        return CompilationInvalidated;
+
     bool result;
     if (codeBlock->codeType() == FunctionCode)
         result = finalizer->finalizeFunction();

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (162939 => 162940)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2014-01-28 17:38:49 UTC (rev 162939)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2014-01-28 17:43:07 UTC (rev 162940)
@@ -4232,26 +4232,6 @@
     case Flush:
         break;
 
-    case Breakpoint: {
-        GPRTemporary temp(this);
-        GPRReg debuggerRequestsGPR = temp.gpr();
-        m_jit.load32(m_jit.codeBlock()->debuggerRequestsAddress(), debuggerRequestsGPR);
-        speculationCheck(
-            DebuggerEvent, JSValueRegs(), 0,
-            m_jit.branchTest32(JITCompiler::NonZero, debuggerRequestsGPR));
-        break;
-    }
-
-    case ProfileWillCall:
-    case ProfileDidCall: {
-        GPRTemporary temp(this);
-        m_jit.loadPtr(m_jit.vm()->enabledProfilerAddress(), temp.gpr());
-        speculationCheck(
-            DebuggerEvent, JSValueRegs(), 0,
-            m_jit.branchTestPtr(JITCompiler::NonZero, temp.gpr()));
-        break;
-    }
-
     case Call:
     case Construct:
         emitCall(node);
@@ -4690,6 +4670,9 @@
         noResult(node);
         break;
 
+    case Breakpoint:
+    case ProfileWillCall:
+    case ProfileDidCall:
     case PhantomLocal:
     case LoopHint:
         // This is a no-op.

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (162939 => 162940)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2014-01-28 17:38:49 UTC (rev 162939)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2014-01-28 17:43:07 UTC (rev 162940)
@@ -4524,25 +4524,6 @@
     case Flush:
         break;
 
-    case Breakpoint: {
-        GPRTemporary temp(this);
-        GPRReg debuggerRequestsGPR = temp.gpr();
-        m_jit.load32(m_jit.codeBlock()->debuggerRequestsAddress(), debuggerRequestsGPR);
-        speculationCheck(
-            DebuggerEvent, JSValueRegs(), 0,
-            m_jit.branchTest32(JITCompiler::NonZero, debuggerRequestsGPR));
-        break;
-    }
-
-    case ProfileWillCall:
-    case ProfileDidCall:
-        speculationCheck(
-            DebuggerEvent, JSValueRegs(), 0,
-            m_jit.branchTestPtr(
-                JITCompiler::NonZero,
-                JITCompiler::AbsoluteAddress(m_jit.vm()->enabledProfilerAddress())));
-        break;
-
     case Call:
     case Construct:
         emitCall(node);
@@ -4939,6 +4920,9 @@
         noResult(node);
         break;
         
+    case Breakpoint:
+    case ProfileWillCall:
+    case ProfileDidCall:
     case PhantomLocal:
     case LoopHint:
         // This is a no-op.

Modified: trunk/Source/_javascript_Core/profiler/LegacyProfiler.cpp (162939 => 162940)


--- trunk/Source/_javascript_Core/profiler/LegacyProfiler.cpp	2014-01-28 17:38:49 UTC (rev 162939)
+++ trunk/Source/_javascript_Core/profiler/LegacyProfiler.cpp	2014-01-28 17:43:07 UTC (rev 162940)
@@ -75,7 +75,7 @@
             return;
     }
 
-    exec->vm().m_enabledProfiler = this;
+    exec->vm().setEnabledProfiler(this);
     RefPtr<ProfileGenerator> profileGenerator = ProfileGenerator::create(exec, title, ++ProfilesUID);
     m_currentProfiles.append(profileGenerator);
 }
@@ -94,7 +94,7 @@
 
             m_currentProfiles.remove(i);
             if (!m_currentProfiles.size())
-                exec->vm().m_enabledProfiler = 0;
+                exec->vm().setEnabledProfiler(nullptr);
             
             return returnProfile;
         }
@@ -111,7 +111,7 @@
             profileGenerator->stopProfiling();
             m_currentProfiles.remove(i);
             if (!m_currentProfiles.size())
-                origin->vm().m_enabledProfiler = 0;
+                origin->vm().setEnabledProfiler(nullptr);
         }
     }
 }

Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (162939 => 162940)


--- trunk/Source/_javascript_Core/runtime/VM.cpp	2014-01-28 17:38:49 UTC (rev 162939)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp	2014-01-28 17:43:07 UTC (rev 162940)
@@ -197,7 +197,6 @@
     , jsFinalObjectClassInfo(JSFinalObject::info())
     , sizeOfLastScratchBuffer(0)
     , entryScope(0)
-    , m_enabledProfiler(0)
     , m_regExpCache(new RegExpCache(this))
 #if ENABLE(REGEXP_TRACING)
     , m_rtTraceList(new RTTraceList())
@@ -222,6 +221,7 @@
 #endif
     , m_inDefineOwnProperty(false)
     , m_codeCache(CodeCache::create())
+    , m_enabledProfiler(nullptr)
 {
     interpreter = new Interpreter(*this);
     StackBounds stack = wtfThreadData().stack();
@@ -780,4 +780,23 @@
         watchpointSet->fireAll();
 }
 
+class SetEnabledProfilerFunctor {
+public:
+    bool operator()(CodeBlock* codeBlock)
+    {
+        if (codeBlock->jitType() == JITCode::DFGJIT)
+            codeBlock->jettison();
+        return false;
+    }
+};
+
+void VM::setEnabledProfiler(LegacyProfiler* profiler)
+{
+    m_enabledProfiler = profiler;
+    if (m_enabledProfiler) {
+        SetEnabledProfilerFunctor functor;
+        heap.forEachCodeBlock(functor);
+    }
+}
+
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/VM.h (162939 => 162940)


--- trunk/Source/_javascript_Core/runtime/VM.h	2014-01-28 17:38:49 UTC (rev 162939)
+++ trunk/Source/_javascript_Core/runtime/VM.h	2014-01-28 17:43:07 UTC (rev 162940)
@@ -304,10 +304,9 @@
             return m_inDefineOwnProperty;
         }
 
-        LegacyProfiler* enabledProfiler()
-        {
-            return m_enabledProfiler;
-        }
+        LegacyProfiler* enabledProfiler() { return m_enabledProfiler; }
+        void setEnabledProfiler(LegacyProfiler*);
+
         void* enabledProfilerAddress() { return &m_enabledProfiler; }
 
 #if ENABLE(JIT) && ENABLE(LLINT)
@@ -432,7 +431,6 @@
         String cachedDateString;
         double cachedDateStringValue;
 
-        LegacyProfiler* m_enabledProfiler;
         OwnPtr<Profiler::Database> m_perBytecodeProfiler;
         RefPtr<TypedArrayController> m_typedArrayController;
         RegExpCache* m_regExpCache;
@@ -524,6 +522,8 @@
         OwnPtr<CodeCache> m_codeCache;
         RefCountedArray<StackFrame> m_exceptionStack;
 
+        LegacyProfiler* m_enabledProfiler;
+
         HashMap<String, RefPtr<WatchpointSet>> m_impurePropertyWatchpointSets;
     };
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to