Title: [173199] trunk
Revision
173199
Author
[email protected]
Date
2014-09-02 21:58:55 -0700 (Tue, 02 Sep 2014)

Log Message

LegacyProfiler: remove redundant ProfileNode members and other cleanup
https://bugs.webkit.org/show_bug.cgi?id=136380

Reviewed by Timothy Hatcher.

Source/_javascript_Core:

ProfileNode's selfTime and totalTime members are redundant and only used
for dumping profile data from debug-only code. Remove the members and compute
the same data on-demand when necessary using a postorder traversal functor.

Remove ProfileNode.head since it is only used to calculate percentages for
dumped profile data. This can be explicitly passed around when needed.

Rename Profile.head to Profile.rootNode, and other various renamings.

Rearrange some header includes so that touching LegacyProfiler-related headers
will no longer cause a full rebuild.

* inspector/JSConsoleClient.cpp: Add header include.
* inspector/agents/InspectorProfilerAgent.cpp:
(Inspector::InspectorProfilerAgent::buildProfileInspectorObject):
* inspector/protocol/Profiler.json: Remove unused Profile.idleTime member.
* jit/JIT.h: Remove header include.
* jit/JITCode.h: Remove header include.
* jit/JITOperations.cpp: Sort and add header include.
* llint/LLIntSlowPaths.cpp: Sort and add header include.
* profiler/Profile.cpp: Rename the debug dumping functions. Move the node
postorder traversal code to ProfileNode so we can traverse any subtree.
(JSC::Profile::Profile):
(JSC::Profile::debugPrint):
(JSC::Profile::debugPrintSampleStyle):
(JSC::Profile::forEach): Deleted.
(JSC::Profile::debugPrintData): Deleted.
(JSC::Profile::debugPrintDataSampleStyle): Deleted.
* profiler/Profile.h:
* profiler/ProfileGenerator.cpp:
(JSC::ProfileGenerator::ProfileGenerator):
(JSC::AddParentForConsoleStartFunctor::AddParentForConsoleStartFunctor):
(JSC::AddParentForConsoleStartFunctor::operator()):
(JSC::ProfileGenerator::addParentForConsoleStart):
(JSC::ProfileGenerator::didExecute):
(JSC::StopProfilingFunctor::operator()):
(JSC::ProfileGenerator::stopProfiling):
(JSC::ProfileGenerator::removeProfileStart):
(JSC::ProfileGenerator::removeProfileEnd):
* profiler/ProfileGenerator.h:
* profiler/ProfileNode.cpp:
(JSC::ProfileNode::ProfileNode):
(JSC::ProfileNode::willExecute):
(JSC::ProfileNode::removeChild):
(JSC::ProfileNode::stopProfiling):
(JSC::ProfileNode::endAndRecordCall):
(JSC::ProfileNode::debugPrint):
(JSC::ProfileNode::debugPrintSampleStyle):
(JSC::ProfileNode::debugPrintRecursively):
(JSC::ProfileNode::debugPrintSampleStyleRecursively):
(JSC::ProfileNode::debugPrintData): Deleted.
(JSC::ProfileNode::debugPrintDataSampleStyle): Deleted.
* profiler/ProfileNode.h: Calculate per-node self and total times using a postorder traversal.
The forEachNodePostorder functor traverses the subtree rooted at |this|.
(JSC::ProfileNode::create):
(JSC::ProfileNode::calls):
(JSC::ProfileNode::forEachNodePostorder):
(JSC::CalculateProfileSubtreeDataFunctor::returnValue):
(JSC::CalculateProfileSubtreeDataFunctor::operator()):
(JSC::ProfileNode::head): Deleted.
(JSC::ProfileNode::setHead): Deleted.
(JSC::ProfileNode::totalTime): Deleted.
(JSC::ProfileNode::setTotalTime): Deleted.
(JSC::ProfileNode::selfTime): Deleted.
(JSC::ProfileNode::setSelfTime): Deleted.
(JSC::ProfileNode::totalPercent): Deleted.
(JSC::ProfileNode::selfPercent): Deleted.
* runtime/ConsoleClient.h: Remove header include.

Source/WebCore:

Remove Profile.idleTime, rename head to rootNode, and remove ProfileNode members.

Covered by existing tests.

* inspector/ScriptProfile.idl:
* inspector/ScriptProfileNode.idl:
* inspector/TimelineRecordFactory.cpp:

Source/WebInspectorUI:

Remove unused Profile.idleTime member.

* UserInterface/Models/Profile.js:
(WebInspector.Profile.prototype.get idleTime): Deleted.
* UserInterface/Models/ScriptTimelineRecord.js:
(WebInspector.ScriptTimelineRecord.prototype._initializeProfileFromPayload):

LayoutTests:

Renamed Profile.head to Profile.rootNode.

* fast/profiler/resources/profiler-test-JS-resources.js:
(printHeavyProfilesDataWithoutTime):
(printProfilesDataWithoutTime):

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (173198 => 173199)


--- trunk/LayoutTests/ChangeLog	2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/LayoutTests/ChangeLog	2014-09-03 04:58:55 UTC (rev 173199)
@@ -1,3 +1,16 @@
+2014-09-02  Brian J. Burg  <[email protected]>
+
+        LegacyProfiler: remove redundant ProfileNode members and other cleanup
+        https://bugs.webkit.org/show_bug.cgi?id=136380
+
+        Reviewed by Timothy Hatcher.
+
+        Renamed Profile.head to Profile.rootNode.
+
+        * fast/profiler/resources/profiler-test-JS-resources.js:
+        (printHeavyProfilesDataWithoutTime):
+        (printProfilesDataWithoutTime):
+
 2014-09-02  Simon Fraser  <[email protected]>
 
         Avoid backing store allocation with some combinations of replaced elements, masking and visibility:hidden

Modified: trunk/LayoutTests/fast/profiler/resources/profiler-test-JS-resources.js (173198 => 173199)


--- trunk/LayoutTests/fast/profiler/resources/profiler-test-JS-resources.js	2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/LayoutTests/fast/profiler/resources/profiler-test-JS-resources.js	2014-09-03 04:58:55 UTC (rev 173199)
@@ -52,7 +52,7 @@
     var profiles = internals.consoleProfiles;
     for (var i = 0; i < profiles.length; ++i) {
         preElement.appendChild(document.createTextNode("Profile title: " + profiles[i].title + "\n"));
-        printProfileNodeWithoutTime(preElement, profiles[i].heavyProfile.head, 0);
+        printProfileNodeWithoutTime(preElement, profiles[i].heavyProfile.rootNode, 0);
         preElement.appendChild(document.createTextNode("\n"));
     }
 
@@ -67,7 +67,7 @@
     var profiles = internals.consoleProfiles;
     for (var i = 0; i < profiles.length; ++i) {
         preElement.appendChild(document.createTextNode("Profile title: " + profiles[i].title + "\n"));
-        printProfileNodeWithoutTime(preElement, profiles[i].head, 0);
+        printProfileNodeWithoutTime(preElement, profiles[i].rootNode, 0);
         preElement.appendChild(document.createTextNode("\n"));
     }
 

Modified: trunk/Source/_javascript_Core/ChangeLog (173198 => 173199)


--- trunk/Source/_javascript_Core/ChangeLog	2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/_javascript_Core/ChangeLog	2014-09-03 04:58:55 UTC (rev 173199)
@@ -1,5 +1,81 @@
 2014-09-02  Brian J. Burg  <[email protected]>
 
+        LegacyProfiler: remove redundant ProfileNode members and other cleanup
+        https://bugs.webkit.org/show_bug.cgi?id=136380
+
+        Reviewed by Timothy Hatcher.
+
+        ProfileNode's selfTime and totalTime members are redundant and only used
+        for dumping profile data from debug-only code. Remove the members and compute
+        the same data on-demand when necessary using a postorder traversal functor.
+
+        Remove ProfileNode.head since it is only used to calculate percentages for
+        dumped profile data. This can be explicitly passed around when needed.
+
+        Rename Profile.head to Profile.rootNode, and other various renamings.
+
+        Rearrange some header includes so that touching LegacyProfiler-related headers
+        will no longer cause a full rebuild.
+
+        * inspector/JSConsoleClient.cpp: Add header include.
+        * inspector/agents/InspectorProfilerAgent.cpp:
+        (Inspector::InspectorProfilerAgent::buildProfileInspectorObject):
+        * inspector/protocol/Profiler.json: Remove unused Profile.idleTime member.
+        * jit/JIT.h: Remove header include.
+        * jit/JITCode.h: Remove header include.
+        * jit/JITOperations.cpp: Sort and add header include.
+        * llint/LLIntSlowPaths.cpp: Sort and add header include.
+        * profiler/Profile.cpp: Rename the debug dumping functions. Move the node
+        postorder traversal code to ProfileNode so we can traverse any subtree.
+        (JSC::Profile::Profile):
+        (JSC::Profile::debugPrint):
+        (JSC::Profile::debugPrintSampleStyle):
+        (JSC::Profile::forEach): Deleted.
+        (JSC::Profile::debugPrintData): Deleted.
+        (JSC::Profile::debugPrintDataSampleStyle): Deleted.
+        * profiler/Profile.h:
+        * profiler/ProfileGenerator.cpp:
+        (JSC::ProfileGenerator::ProfileGenerator):
+        (JSC::AddParentForConsoleStartFunctor::AddParentForConsoleStartFunctor):
+        (JSC::AddParentForConsoleStartFunctor::operator()):
+        (JSC::ProfileGenerator::addParentForConsoleStart):
+        (JSC::ProfileGenerator::didExecute):
+        (JSC::StopProfilingFunctor::operator()):
+        (JSC::ProfileGenerator::stopProfiling):
+        (JSC::ProfileGenerator::removeProfileStart):
+        (JSC::ProfileGenerator::removeProfileEnd):
+        * profiler/ProfileGenerator.h:
+        * profiler/ProfileNode.cpp:
+        (JSC::ProfileNode::ProfileNode):
+        (JSC::ProfileNode::willExecute):
+        (JSC::ProfileNode::removeChild):
+        (JSC::ProfileNode::stopProfiling):
+        (JSC::ProfileNode::endAndRecordCall):
+        (JSC::ProfileNode::debugPrint):
+        (JSC::ProfileNode::debugPrintSampleStyle):
+        (JSC::ProfileNode::debugPrintRecursively):
+        (JSC::ProfileNode::debugPrintSampleStyleRecursively):
+        (JSC::ProfileNode::debugPrintData): Deleted.
+        (JSC::ProfileNode::debugPrintDataSampleStyle): Deleted.
+        * profiler/ProfileNode.h: Calculate per-node self and total times using a postorder traversal.
+        The forEachNodePostorder functor traverses the subtree rooted at |this|.
+        (JSC::ProfileNode::create):
+        (JSC::ProfileNode::calls):
+        (JSC::ProfileNode::forEachNodePostorder):
+        (JSC::CalculateProfileSubtreeDataFunctor::returnValue):
+        (JSC::CalculateProfileSubtreeDataFunctor::operator()):
+        (JSC::ProfileNode::head): Deleted.
+        (JSC::ProfileNode::setHead): Deleted.
+        (JSC::ProfileNode::totalTime): Deleted.
+        (JSC::ProfileNode::setTotalTime): Deleted.
+        (JSC::ProfileNode::selfTime): Deleted.
+        (JSC::ProfileNode::setSelfTime): Deleted.
+        (JSC::ProfileNode::totalPercent): Deleted.
+        (JSC::ProfileNode::selfPercent): Deleted.
+        * runtime/ConsoleClient.h: Remove header include.
+
+2014-09-02  Brian J. Burg  <[email protected]>
+
         Web Inspector: remove ProfilerAgent and legacy profiler files in the frontend
         https://bugs.webkit.org/show_bug.cgi?id=136462
 

Modified: trunk/Source/_javascript_Core/jit/JIT.h (173198 => 173199)


--- trunk/Source/_javascript_Core/jit/JIT.h	2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/_javascript_Core/jit/JIT.h	2014-09-03 04:58:55 UTC (rev 173199)
@@ -44,7 +44,6 @@
 #include "JITDisassembler.h"
 #include "JITInlineCacheGenerator.h"
 #include "JSInterfaceJIT.h"
-#include "LegacyProfiler.h"
 #include "Opcode.h"
 #include "ResultType.h"
 #include "SamplingTool.h"

Modified: trunk/Source/_javascript_Core/jit/JITCode.h (173198 => 173199)


--- trunk/Source/_javascript_Core/jit/JITCode.h	2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/_javascript_Core/jit/JITCode.h	2014-09-03 04:58:55 UTC (rev 173199)
@@ -31,7 +31,6 @@
 #include "Disassembler.h"
 #include "JITStubs.h"
 #include "JSCJSValue.h"
-#include "LegacyProfiler.h"
 #include "MacroAssemblerCodeRef.h"
 #include "RegisterPreservationMode.h"
 

Modified: trunk/Source/_javascript_Core/jit/JITOperations.cpp (173198 => 173199)


--- trunk/Source/_javascript_Core/jit/JITOperations.cpp	2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/_javascript_Core/jit/JITOperations.cpp	2014-09-03 04:58:55 UTC (rev 173199)
@@ -43,13 +43,14 @@
 #include "HostCallReturnValue.h"
 #include "JIT.h"
 #include "JITToDFGDeferredCompilationCallback.h"
+#include "JSCInlines.h"
 #include "JSGlobalObjectFunctions.h"
 #include "JSNameScope.h"
 #include "JSPropertyNameEnumerator.h"
 #include "JSStackInlines.h"
 #include "JSWithScope.h"
+#include "LegacyProfiler.h"
 #include "ObjectConstructor.h"
-#include "JSCInlines.h"
 #include "Repatch.h"
 #include "RepatchBuffer.h"
 #include "TestRunnerUtils.h"

Modified: trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp (173198 => 173199)


--- trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp	2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp	2014-09-03 04:58:55 UTC (rev 173199)
@@ -25,6 +25,7 @@
 
 #include "config.h"
 #include "LLIntSlowPaths.h"
+
 #include "Arguments.h"
 #include "ArrayConstructor.h"
 #include "CallFrame.h"
@@ -38,6 +39,7 @@
 #include "JIT.h"
 #include "JITExceptions.h"
 #include "JSActivation.h"
+#include "JSCInlines.h"
 #include "JSCJSValue.h"
 #include "JSGlobalObjectFunctions.h"
 #include "JSNameScope.h"
@@ -46,9 +48,9 @@
 #include "JSWithScope.h"
 #include "LLIntCommon.h"
 #include "LLIntExceptions.h"
+#include "LegacyProfiler.h"
 #include "LowLevelInterpreter.h"
 #include "ObjectConstructor.h"
-#include "JSCInlines.h"
 #include "ProtoCallFrame.h"
 #include "StructureRareDataInlines.h"
 #include <wtf/StringPrintStream.h>

Modified: trunk/Source/_javascript_Core/profiler/Profile.cpp (173198 => 173199)


--- trunk/Source/_javascript_Core/profiler/Profile.cpp	2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/_javascript_Core/profiler/Profile.cpp	2014-09-03 04:58:55 UTC (rev 173199)
@@ -39,38 +39,25 @@
 Profile::Profile(const String& title, unsigned uid)
     : m_title(title)
     , m_uid(uid)
-    , m_idleTime(0)
 {
     // FIXME: When multi-threading is supported this will be a vector and calls
     // into the profiler will need to know which thread it is executing on.
-    m_head = ProfileNode::create(0, CallIdentifier(ASCIILiteral("Thread_1"), String(), 0, 0), 0, 0);
+    m_rootNode = ProfileNode::create(nullptr, CallIdentifier(ASCIILiteral("Thread_1"), String(), 0, 0), nullptr);
 }
 
 Profile::~Profile()
 {
 }
 
-void Profile::forEach(void (ProfileNode::*function)())
-{
-    ProfileNode* currentNode = m_head->firstChild();
-    for (ProfileNode* nextNode = currentNode; nextNode; nextNode = nextNode->firstChild())
-        currentNode = nextNode;
-
-    if (!currentNode)
-        currentNode = m_head.get();
-
-    ProfileNode* endNode = m_head->traverseNextNodePostOrder();
-    while (currentNode && currentNode != endNode) {
-        (currentNode->*function)();
-        currentNode = currentNode->traverseNextNodePostOrder();
-    } 
-}
-
 #ifndef NDEBUG
-void Profile::debugPrintData() const
+void Profile::debugPrint()
 {
+    CalculateProfileSubtreeDataFunctor functor;
+    m_rootNode->forEachNodePostorder(functor);
+    ProfileNode::ProfileSubtreeData data = ""
+
     dataLogF("Call graph:\n");
-    m_head->debugPrintData(0);
+    m_rootNode->debugPrintRecursively(0, data);
 }
 
 typedef WTF::KeyValuePair<FunctionCallHashCount::ValueType, unsigned> NameCountPair;
@@ -80,13 +67,17 @@
     return a.value > b.value;
 }
 
-void Profile::debugPrintDataSampleStyle() const
+void Profile::debugPrintSampleStyle()
 {
     typedef Vector<NameCountPair> NameCountPairVector;
 
+    CalculateProfileSubtreeDataFunctor functor;
+    m_rootNode->forEachNodePostorder(functor);
+    ProfileNode::ProfileSubtreeData data = ""
+
     FunctionCallHashCount countedFunctions;
     dataLogF("Call graph:\n");
-    m_head->debugPrintDataSampleStyle(0, countedFunctions);
+    m_rootNode->debugPrintSampleStyleRecursively(0, countedFunctions, data);
 
     dataLogF("\nTotal number in stack:\n");
     NameCountPairVector sortedFunctions(countedFunctions.size());

Modified: trunk/Source/_javascript_Core/profiler/Profile.h (173198 => 173199)


--- trunk/Source/_javascript_Core/profiler/Profile.h	2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/_javascript_Core/profiler/Profile.h	2014-09-03 04:58:55 UTC (rev 173199)
@@ -41,19 +41,12 @@
     const String& title() const { return m_title; }
     unsigned uid() const { return m_uid; }
 
-    ProfileNode* head() const { return m_head.get(); }
-    void setHead(PassRefPtr<ProfileNode> head) { m_head = head; }
+    ProfileNode* rootNode() const { return m_rootNode.get(); }
+    void setRootNode(PassRefPtr<ProfileNode> rootNode) { m_rootNode = rootNode; }
 
-    double totalTime() const { return m_head->totalTime(); }
-
-    double idleTime() const { return m_idleTime; }
-    void setIdleTime(double idleTime) { m_idleTime = idleTime; }
-
-    void forEach(void (ProfileNode::*)());
-
 #ifndef NDEBUG
-    void debugPrintData() const;
-    void debugPrintDataSampleStyle() const;
+    void debugPrint();
+    void debugPrintSampleStyle();
 #endif
 
 protected:
@@ -64,9 +57,8 @@
     void removeProfileEnd();
 
     String m_title;
-    RefPtr<ProfileNode> m_head;
+    RefPtr<ProfileNode> m_rootNode;
     unsigned m_uid;
-    double m_idleTime;
 };
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/profiler/ProfileGenerator.cpp (173198 => 173199)


--- trunk/Source/_javascript_Core/profiler/ProfileGenerator.cpp	2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/_javascript_Core/profiler/ProfileGenerator.cpp	2014-09-03 04:58:55 UTC (rev 173199)
@@ -50,18 +50,18 @@
     , m_foundConsoleStartParent(false)
 {
     m_profile = Profile::create(title, uid);
-    m_currentNode = m_head = m_profile->head();
+    m_currentNode = m_rootNode = m_profile->rootNode();
     if (exec)
         addParentForConsoleStart(exec);
 }
 
 class AddParentForConsoleStartFunctor {
 public:
-    AddParentForConsoleStartFunctor(ExecState* exec, RefPtr<ProfileNode>& head, RefPtr<ProfileNode>& currentNode)
+    AddParentForConsoleStartFunctor(ExecState* exec, RefPtr<ProfileNode>& rootNode, RefPtr<ProfileNode>& currentNode)
         : m_exec(exec)
         , m_hasSkippedFirstFrame(false)
         , m_foundParent(false)
-        , m_head(head)
+        , m_rootNode(rootNode)
         , m_currentNode(currentNode)
     {
     }
@@ -78,8 +78,8 @@
         unsigned line = 0;
         unsigned column = 0;
         visitor->computeLineAndColumn(line, column);
-        m_currentNode = ProfileNode::create(m_exec, LegacyProfiler::createCallIdentifier(m_exec, visitor->callee(), visitor->sourceURL(), line, column), m_head.get(), m_head.get());
-        m_head->insertNode(m_currentNode.get());
+        m_currentNode = ProfileNode::create(m_exec, LegacyProfiler::createCallIdentifier(m_exec, visitor->callee(), visitor->sourceURL(), line, column), m_rootNode.get());
+        m_rootNode->insertNode(m_currentNode.get());
 
         m_foundParent = true;
         return StackVisitor::Done;
@@ -88,14 +88,14 @@
 private:
     ExecState* m_exec;
     bool m_hasSkippedFirstFrame;
-    bool m_foundParent; 
-    RefPtr<ProfileNode>& m_head;
+    bool m_foundParent;
+    RefPtr<ProfileNode>& m_rootNode;
     RefPtr<ProfileNode>& m_currentNode;
 };
 
 void ProfileGenerator::addParentForConsoleStart(ExecState* exec)
 {
-    AddParentForConsoleStartFunctor functor(exec, m_head, m_currentNode);
+    AddParentForConsoleStartFunctor functor(exec, m_rootNode, m_currentNode);
     exec->iterate(functor);
 
     m_foundConsoleStartParent = functor.foundParent();
@@ -134,7 +134,7 @@
 
     ASSERT(m_currentNode);
     if (m_currentNode->callIdentifier() != callIdentifier) {
-        RefPtr<ProfileNode> returningNode = ProfileNode::create(callerCallFrame, callIdentifier, m_head.get(), m_currentNode.get());
+        RefPtr<ProfileNode> returningNode = ProfileNode::create(callerCallFrame, callIdentifier, m_currentNode.get());
         returningNode->lastCall().setStartTime(m_currentNode->lastCall().startTime());
         returningNode->didExecute();
         m_currentNode->insertNode(returningNode.release());
@@ -155,9 +155,16 @@
     }
 }
 
+struct StopProfilingFunctor {
+    void operator()(ProfileNode* node) { node->stopProfiling(); }
+};
+
 void ProfileGenerator::stopProfiling()
 {
-    m_profile->forEach(&ProfileNode::stopProfiling);
+    // FIXME: we shouldn't need a full traversal here, since only the spine from
+    // m_currentNode to m_rootNode should have any nodes currently accruing time.
+    StopProfilingFunctor functor;
+    m_profile->rootNode()->forEachNodePostorder(functor);
 
     if (m_foundConsoleStartParent) {
         removeProfileStart();
@@ -169,25 +176,18 @@
     // Set the current node to the parent, because we are in a call that
     // will not get didExecute call.
     m_currentNode = m_currentNode->parent();
-
-    if (double headSelfTime = m_head->selfTime()) {
-        m_head->setSelfTime(0.0);
-        m_profile->setIdleTime(headSelfTime);
-    }
 }
 
 // The console.profile that started this ProfileGenerator will be the first child.
 void ProfileGenerator::removeProfileStart()
 {
     ProfileNode* currentNode = 0;
-    for (ProfileNode* next = m_head.get(); next; next = next->firstChild())
+    for (ProfileNode* next = m_rootNode.get(); next; next = next->firstChild())
         currentNode = next;
 
     if (currentNode->callIdentifier().functionName() != "profile")
         return;
 
-    // Attribute the time of the node aobut to be removed to the self time of its parent
-    currentNode->parent()->setSelfTime(currentNode->parent()->selfTime() + currentNode->totalTime());
     currentNode->parent()->removeChild(currentNode);
 }
 
@@ -195,15 +195,12 @@
 void ProfileGenerator::removeProfileEnd()
 {
     ProfileNode* currentNode = 0;
-    for (ProfileNode* next = m_head.get(); next; next = next->lastChild())
+    for (ProfileNode* next = m_rootNode.get(); next; next = next->lastChild())
         currentNode = next;
 
     if (currentNode->callIdentifier().functionName() != "profileEnd")
         return;
 
-    // Attribute the time of the node aobut to be removed to the self time of its parent
-    currentNode->parent()->setSelfTime(currentNode->parent()->selfTime() + currentNode->totalTime());
-
     ASSERT(currentNode->callIdentifier() == (currentNode->parent()->children()[currentNode->parent()->children().size() - 1])->callIdentifier());
     currentNode->parent()->removeChild(currentNode);
 }

Modified: trunk/Source/_javascript_Core/profiler/ProfileGenerator.h (173198 => 173199)


--- trunk/Source/_javascript_Core/profiler/ProfileGenerator.h	2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/_javascript_Core/profiler/ProfileGenerator.h	2014-09-03 04:58:55 UTC (rev 173199)
@@ -22,7 +22,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
- 
+
 #ifndef ProfileGenerator_h
 #define ProfileGenerator_h
 
@@ -37,7 +37,7 @@
     class JSGlobalObject;
     class Profile;
     class ProfileNode;
-    struct CallIdentifier;    
+    struct CallIdentifier;
 
     class ProfileGenerator : public RefCounted<ProfileGenerator>  {
     public:
@@ -70,7 +70,7 @@
         RefPtr<Profile> m_profile;
         JSGlobalObject* m_origin;
         unsigned m_profileGroup;
-        RefPtr<ProfileNode> m_head;
+        RefPtr<ProfileNode> m_rootNode;
         RefPtr<ProfileNode> m_currentNode;
         bool m_foundConsoleStartParent;
     };

Modified: trunk/Source/_javascript_Core/profiler/ProfileNode.cpp (173198 => 173199)


--- trunk/Source/_javascript_Core/profiler/ProfileNode.cpp	2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/_javascript_Core/profiler/ProfileNode.cpp	2014-09-03 04:58:55 UTC (rev 173199)
@@ -38,26 +38,20 @@
 
 namespace JSC {
 
-ProfileNode::ProfileNode(ExecState* callerCallFrame, const CallIdentifier& callIdentifier, ProfileNode* headNode, ProfileNode* parentNode)
+ProfileNode::ProfileNode(ExecState* callerCallFrame, const CallIdentifier& callIdentifier, ProfileNode* parentNode)
     : m_callerCallFrame(callerCallFrame)
     , m_callIdentifier(callIdentifier)
-    , m_head(headNode)
     , m_parent(parentNode)
     , m_nextSibling(nullptr)
-    , m_totalTime(0)
-    , m_selfTime(0)
 {
     startTimer();
 }
 
-ProfileNode::ProfileNode(ExecState* callerCallFrame, ProfileNode* headNode, ProfileNode* nodeToCopy)
+ProfileNode::ProfileNode(ExecState* callerCallFrame, ProfileNode* nodeToCopy)
     : m_callerCallFrame(callerCallFrame)
     , m_callIdentifier(nodeToCopy->callIdentifier())
-    , m_head(headNode)
     , m_parent(nodeToCopy->parent())
-    , m_nextSibling(0)
-    , m_totalTime(nodeToCopy->totalTime())
-    , m_selfTime(nodeToCopy->selfTime())
+    , m_nextSibling(nullptr)
     , m_calls(nodeToCopy->calls())
 {
 }
@@ -71,7 +65,7 @@
         }
     }
 
-    RefPtr<ProfileNode> newChild = ProfileNode::create(callerCallFrame, callIdentifier, m_head ? m_head : this, this); // If this ProfileNode has no head it is the head.
+    RefPtr<ProfileNode> newChild = ProfileNode::create(callerCallFrame, callIdentifier, this);
     if (m_children.size())
         m_children.last()->setNextSibling(newChild.get());
     m_children.append(newChild.release());
@@ -104,7 +98,7 @@
             break;
         }
     }
-    
+
     resetChildrensSiblings();
 }
 
@@ -125,13 +119,6 @@
 
     if (isnan(m_calls.last().totalTime()))
         endAndRecordCall();
-
-    // Because we iterate in post order all of our children have been stopped before us.
-    for (unsigned i = 0; i < m_children.size(); ++i)
-        m_selfTime += m_children[i]->totalTime();
-
-    ASSERT(m_selfTime <= m_totalTime);
-    m_selfTime = m_totalTime - m_selfTime;
 }
 
 ProfileNode* ProfileNode::traverseNextNodePostOrder() const
@@ -150,8 +137,6 @@
     ASSERT(isnan(last.totalTime()));
 
     last.setTotalTime(currentTime() - last.startTime());
-
-    m_totalTime += last.totalTime();
 }
 
 void ProfileNode::startTimer()
@@ -167,32 +152,63 @@
 }
 
 #ifndef NDEBUG
-void ProfileNode::debugPrintData(int indentLevel) const
+void ProfileNode::debugPrint()
 {
+    CalculateProfileSubtreeDataFunctor functor;
+    forEachNodePostorder(functor);
+    ProfileNode::ProfileSubtreeData data = ""
+
+    debugPrintRecursively(0, data);
+}
+
+void ProfileNode::debugPrintSampleStyle()
+{
+    FunctionCallHashCount countedFunctions;
+
+    CalculateProfileSubtreeDataFunctor functor;
+    forEachNodePostorder(functor);
+    ProfileNode::ProfileSubtreeData data = ""
+
+    debugPrintSampleStyleRecursively(0, countedFunctions, data);
+}
+
+void ProfileNode::debugPrintRecursively(int indentLevel, const ProfileSubtreeData& data)
+{
     // Print function names
     for (int i = 0; i < indentLevel; ++i)
         dataLogF("  ");
 
+    auto it = data.selfAndTotalTimes.find(this);
+    ASSERT(it != data.selfAndTotalTimes.end());
+
+    double nodeSelfTime = it->value.first;
+    double nodeTotalTime = it->value.second;
+    double rootTotalTime = data.rootTotalTime;
+
     dataLogF("Function Name %s %zu SelfTime %.3fms/%.3f%% TotalTime %.3fms/%.3f%% Next Sibling %s\n",
         functionName().utf8().data(),
-        numberOfCalls(), m_selfTime, selfPercent(), m_totalTime, totalPercent(),
+        numberOfCalls(), nodeSelfTime, nodeSelfTime / rootTotalTime * 100.0, nodeTotalTime, nodeTotalTime / rootTotalTime * 100.0,
         m_nextSibling ? m_nextSibling->functionName().utf8().data() : "");
 
     ++indentLevel;
 
     // Print children's names and information
     for (StackIterator currentChild = m_children.begin(); currentChild != m_children.end(); ++currentChild)
-        (*currentChild)->debugPrintData(indentLevel);
+        (*currentChild)->debugPrintRecursively(indentLevel, data);
 }
 
 // print the profiled data in a format that matches the tool sample's output.
-double ProfileNode::debugPrintDataSampleStyle(int indentLevel, FunctionCallHashCount& countedFunctions) const
+double ProfileNode::debugPrintSampleStyleRecursively(int indentLevel, FunctionCallHashCount& countedFunctions, const ProfileSubtreeData& data)
 {
     dataLogF("    ");
 
+    auto it = data.selfAndTotalTimes.find(this);
+    ASSERT(it != data.selfAndTotalTimes.end());
+    double nodeTotalTime = it->value.second;
+
     // Print function names
     const char* name = functionName().utf8().data();
-    double sampleCount = m_totalTime * 1000;
+    double sampleCount = nodeTotalTime * 1000;
     if (indentLevel) {
         for (int i = 0; i < indentLevel; ++i)
             dataLogF("  ");
@@ -208,7 +224,7 @@
     // Print children's names and information
     double sumOfChildrensCount = 0.0;
     for (StackIterator currentChild = m_children.begin(); currentChild != m_children.end(); ++currentChild)
-        sumOfChildrensCount += (*currentChild)->debugPrintDataSampleStyle(indentLevel, countedFunctions);
+        sumOfChildrensCount += (*currentChild)->debugPrintSampleStyleRecursively(indentLevel, countedFunctions, data);
 
     sumOfChildrensCount *= 1000;    //
     // Print remainder of samples to match sample's output
@@ -220,7 +236,7 @@
         dataLogF("%.0f %s\n", sampleCount - sumOfChildrensCount, functionName().utf8().data());
     }
 
-    return m_totalTime;
+    return nodeTotalTime;
 }
 #endif
 

Modified: trunk/Source/_javascript_Core/profiler/ProfileNode.h (173198 => 173199)


--- trunk/Source/_javascript_Core/profiler/ProfileNode.h	2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/_javascript_Core/profiler/ProfileNode.h	2014-09-03 04:58:55 UTC (rev 173199)
@@ -44,14 +44,14 @@
 
     class ProfileNode : public RefCounted<ProfileNode> {
     public:
-        static PassRefPtr<ProfileNode> create(ExecState* callerCallFrame, const CallIdentifier& callIdentifier, ProfileNode* headNode, ProfileNode* parentNode)
+        static PassRefPtr<ProfileNode> create(ExecState* callerCallFrame, const CallIdentifier& callIdentifier, ProfileNode* parentNode)
         {
-            return adoptRef(new ProfileNode(callerCallFrame, callIdentifier, headNode, parentNode));
+            return adoptRef(new ProfileNode(callerCallFrame, callIdentifier, parentNode));
         }
 
-        static PassRefPtr<ProfileNode> create(ExecState* callerCallFrame, ProfileNode* headNode, ProfileNode* node)
+        static PassRefPtr<ProfileNode> create(ExecState* callerCallFrame, ProfileNode* node)
         {
-            return adoptRef(new ProfileNode(callerCallFrame, headNode, node));
+            return adoptRef(new ProfileNode(callerCallFrame, node));
         }
 
         struct Call {
@@ -90,26 +90,13 @@
         unsigned columnNumber() const { return m_callIdentifier.columnNumber(); }
 
         // Relationships
-        ProfileNode* head() const { return m_head; }
-        void setHead(ProfileNode* head) { m_head = head; }
-
         ProfileNode* parent() const { return m_parent; }
         void setParent(ProfileNode* parent) { m_parent = parent; }
 
         ProfileNode* nextSibling() const { return m_nextSibling; }
         void setNextSibling(ProfileNode* nextSibling) { m_nextSibling = nextSibling; }
 
-        // Time members
-        double totalTime() const { return m_totalTime; }
-        void setTotalTime(double time) { m_totalTime = time; }
-
-        double selfTime() const { return m_selfTime; }
-        void setSelfTime(double time) { m_selfTime = time; }
-
-        double totalPercent() const { return (m_totalTime / (m_head ? m_head->totalTime() : totalTime())) * 100.0; }
-        double selfPercent() const { return (m_selfTime / (m_head ? m_head->totalTime() : totalTime())) * 100.0; }
-
-        Vector<Call> calls() const { return m_calls; }
+        const Vector<Call>& calls() const { return m_calls; }
         Call& lastCall() { ASSERT(!m_calls.isEmpty()); return m_calls.last(); }
         size_t numberOfCalls() const { return m_calls.size(); }
 
@@ -121,37 +108,85 @@
         void addChild(PassRefPtr<ProfileNode> prpChild);
         void insertNode(PassRefPtr<ProfileNode> prpNode);
 
-        ProfileNode* traverseNextNodePostOrder() const;
+        template <typename Functor> void forEachNodePostorder(Functor&);
 
 #ifndef NDEBUG
+        struct ProfileSubtreeData {
+            HashMap<ProfileNode*, std::pair<double, double>> selfAndTotalTimes;
+            double rootTotalTime;
+        };
+
         const char* c_str() const { return m_callIdentifier; }
-        void debugPrintData(int indentLevel) const;
-        double debugPrintDataSampleStyle(int indentLevel, FunctionCallHashCount&) const;
+        // Use these functions to dump the subtree rooted at this node.
+        void debugPrint();
+        void debugPrintSampleStyle();
+
+        // These are used to recursively print entire subtrees using precomputed self and total times.
+        void debugPrintRecursively(int indentLevel, const ProfileSubtreeData&);
+        double debugPrintSampleStyleRecursively(int indentLevel, FunctionCallHashCount&, const ProfileSubtreeData&);
 #endif
 
     private:
         typedef Vector<RefPtr<ProfileNode>>::const_iterator StackIterator;
 
-        ProfileNode(ExecState* callerCallFrame, const CallIdentifier&, ProfileNode* headNode, ProfileNode* parentNode);
-        ProfileNode(ExecState* callerCallFrame, ProfileNode* headNode, ProfileNode* nodeToCopy);
+        ProfileNode(ExecState* callerCallFrame, const CallIdentifier&, ProfileNode* parentNode);
+        ProfileNode(ExecState* callerCallFrame, ProfileNode* nodeToCopy);
 
         void startTimer();
         void resetChildrensSiblings();
         void endAndRecordCall();
+        ProfileNode* traverseNextNodePostOrder() const;
 
         ExecState* m_callerCallFrame;
         CallIdentifier m_callIdentifier;
-        ProfileNode* m_head;
         ProfileNode* m_parent;
         ProfileNode* m_nextSibling;
 
-        double m_totalTime;
-        double m_selfTime;
-
-        Vector<Call, 1> m_calls;
+        Vector<Call> m_calls;
         Vector<RefPtr<ProfileNode>> m_children;
     };
 
+    template <typename Functor> inline void ProfileNode::forEachNodePostorder(Functor& functor)
+    {
+        ProfileNode* currentNode = this;
+        // Go down to the first node of the traversal, and slowly walk back up.
+        for (ProfileNode* nextNode = currentNode; nextNode; nextNode = nextNode->firstChild())
+            currentNode = nextNode;
+
+        ProfileNode* endNode = this;
+        while (currentNode && currentNode != endNode) {
+            functor(currentNode);
+            currentNode = currentNode->traverseNextNodePostOrder();
+        }
+
+        functor(endNode);
+    }
+
+#ifndef NDEBUG
+    struct CalculateProfileSubtreeDataFunctor {
+        void operator()(ProfileNode* node)
+        {
+            double selfTime = 0.0;
+            for (const ProfileNode::Call& call : node->calls())
+                selfTime += call.totalTime();
+
+            double totalTime = selfTime;
+            for (RefPtr<ProfileNode> child : node->children()) {
+                auto it = m_data.selfAndTotalTimes.find(child.get());
+                if (it != m_data.selfAndTotalTimes.end())
+                    totalTime += it->value.second;
+            }
+
+            ASSERT(node);
+            m_data.selfAndTotalTimes.set(node, std::make_pair(selfTime, totalTime));
+        }
+
+        ProfileNode::ProfileSubtreeData returnValue() { return WTF::move(m_data); }
+
+        ProfileNode::ProfileSubtreeData m_data;
+    };
+#endif
+
 } // namespace JSC
 
 #endif // ProfileNode_h

Modified: trunk/Source/_javascript_Core/runtime/ConsoleClient.h (173198 => 173199)


--- trunk/Source/_javascript_Core/runtime/ConsoleClient.h	2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/_javascript_Core/runtime/ConsoleClient.h	2014-09-03 04:58:55 UTC (rev 173199)
@@ -27,7 +27,6 @@
 #define ConsoleClient_h
 
 #include "ConsoleTypes.h"
-#include "Profile.h"
 #include <wtf/Forward.h>
 
 namespace Inspector {

Modified: trunk/Source/WebCore/ChangeLog (173198 => 173199)


--- trunk/Source/WebCore/ChangeLog	2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/WebCore/ChangeLog	2014-09-03 04:58:55 UTC (rev 173199)
@@ -1,5 +1,20 @@
 2014-09-02  Brian J. Burg  <[email protected]>
 
+        LegacyProfiler: remove redundant ProfileNode members and other cleanup
+        https://bugs.webkit.org/show_bug.cgi?id=136380
+
+        Reviewed by Timothy Hatcher.
+
+        Remove Profile.idleTime, rename head to rootNode, and remove ProfileNode members.
+
+        Covered by existing tests.
+
+        * inspector/ScriptProfile.idl:
+        * inspector/ScriptProfileNode.idl:
+        * inspector/TimelineRecordFactory.cpp:
+
+2014-09-02  Brian J. Burg  <[email protected]>
+
         Web Inspector: remove ProfilerAgent and legacy profiler files in the frontend
         https://bugs.webkit.org/show_bug.cgi?id=136462
 

Modified: trunk/Source/WebCore/inspector/ScriptProfile.idl (173198 => 173199)


--- trunk/Source/WebCore/inspector/ScriptProfile.idl	2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/WebCore/inspector/ScriptProfile.idl	2014-09-03 04:58:55 UTC (rev 173199)
@@ -30,7 +30,6 @@
 ] interface ScriptProfile {
     readonly attribute DOMString title;
     readonly attribute unsigned long uid;
-    readonly attribute ScriptProfileNode head;
-    readonly attribute unrestricted double idleTime;
+    readonly attribute ScriptProfileNode rootNode;
 };
 

Modified: trunk/Source/WebCore/inspector/ScriptProfileNode.idl (173198 => 173199)


--- trunk/Source/WebCore/inspector/ScriptProfileNode.idl	2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/WebCore/inspector/ScriptProfileNode.idl	2014-09-03 04:58:55 UTC (rev 173199)
@@ -36,9 +36,6 @@
     readonly attribute unsigned long lineNumber;
     readonly attribute unsigned long columnNumber;
 
-    readonly attribute unrestricted double totalTime;
-    readonly attribute unrestricted double selfTime;
-
     readonly attribute unsigned long numberOfCalls;
 
     sequence<ScriptProfileNode> children();

Modified: trunk/Source/WebCore/inspector/TimelineRecordFactory.cpp (173198 => 173199)


--- trunk/Source/WebCore/inspector/TimelineRecordFactory.cpp	2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/WebCore/inspector/TimelineRecordFactory.cpp	2014-09-03 04:58:55 UTC (rev 173199)
@@ -310,15 +310,12 @@
 static PassRefPtr<Protocol::Timeline::CPUProfile> buildProfileInspectorObject(const JSC::Profile* profile)
 {
     RefPtr<Protocol::Array<Protocol::Timeline::CPUProfileNode>> rootNodes = Protocol::Array<Protocol::Timeline::CPUProfileNode>::create();
-    for (RefPtr<JSC::ProfileNode> profileNode : profile->head()->children())
+    for (RefPtr<JSC::ProfileNode> profileNode : profile->rootNode()->children())
         rootNodes->addItem(buildInspectorObject(profileNode.get()));
 
     RefPtr<Protocol::Timeline::CPUProfile> result = Protocol::Timeline::CPUProfile::create()
         .setRootNodes(rootNodes);
 
-    if (profile->idleTime())
-        result->setIdleTime(profile->idleTime());
-
     return result.release();
 }
 

Modified: trunk/Source/WebInspectorUI/ChangeLog (173198 => 173199)


--- trunk/Source/WebInspectorUI/ChangeLog	2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/WebInspectorUI/ChangeLog	2014-09-03 04:58:55 UTC (rev 173199)
@@ -1,5 +1,19 @@
 2014-09-02  Brian J. Burg  <[email protected]>
 
+        LegacyProfiler: remove redundant ProfileNode members and other cleanup
+        https://bugs.webkit.org/show_bug.cgi?id=136380
+
+        Reviewed by Timothy Hatcher.
+
+        Remove unused Profile.idleTime member.
+
+        * UserInterface/Models/Profile.js:
+        (WebInspector.Profile.prototype.get idleTime): Deleted.
+        * UserInterface/Models/ScriptTimelineRecord.js:
+        (WebInspector.ScriptTimelineRecord.prototype._initializeProfileFromPayload):
+
+2014-09-02  Brian J. Burg  <[email protected]>
+
         Web Inspector: remove ProfilerAgent and legacy profiler files in the frontend
         https://bugs.webkit.org/show_bug.cgi?id=136462
 

Modified: trunk/Source/WebInspectorUI/UserInterface/Models/Profile.js (173198 => 173199)


--- trunk/Source/WebInspectorUI/UserInterface/Models/Profile.js	2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/Profile.js	2014-09-03 04:58:55 UTC (rev 173199)
@@ -23,7 +23,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-WebInspector.Profile = "" idleTime)
+WebInspector.Profile = ""
 {
     WebInspector.Object.call(this);
 
@@ -33,7 +33,6 @@
     console.assert(topDownRootNodes.reduce(function(previousValue, node) { return previousValue && node instanceof WebInspector.ProfileNode; }, true));
 
     this._topDownRootNodes = topDownRootNodes;
-    this._idleTime = idleTime || 0;
 };
 
 WebInspector.Profile.prototype = {
@@ -42,11 +41,6 @@
 
     // Public
 
-    get idleTime()
-    {
-        return this._idleTime;
-    },
-
     get topDownRootNodes()
     {
         return this._topDownRootNodes;

Modified: trunk/Source/WebInspectorUI/UserInterface/Models/ScriptTimelineRecord.js (173198 => 173199)


--- trunk/Source/WebInspectorUI/UserInterface/Models/ScriptTimelineRecord.js	2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/ScriptTimelineRecord.js	2014-09-03 04:58:55 UTC (rev 173199)
@@ -346,7 +346,7 @@
             }
         }
 
-        this._profile = new WebInspector.Profile(rootNodes, payload.idleTime);
+        this._profile = new WebInspector.Profile(rootNodes);
     }
 };
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to