Changeset 173199 in webkit


Ignore:
Timestamp:
Sep 2, 2014 9:58:55 PM (10 years ago)
Author:
Brian Burg
Message:

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

Reviewed by Timothy Hatcher.

Source/JavaScriptCore:

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):

Location:
trunk
Files:
21 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r173184 r173199  
     12014-09-02  Brian J. Burg  <burg@cs.washington.edu>
     2
     3        LegacyProfiler: remove redundant ProfileNode members and other cleanup
     4        https://bugs.webkit.org/show_bug.cgi?id=136380
     5
     6        Reviewed by Timothy Hatcher.
     7
     8        Renamed Profile.head to Profile.rootNode.
     9
     10        * fast/profiler/resources/profiler-test-JS-resources.js:
     11        (printHeavyProfilesDataWithoutTime):
     12        (printProfilesDataWithoutTime):
     13
    1142014-09-02  Simon Fraser  <simon.fraser@apple.com>
    215
  • trunk/LayoutTests/fast/profiler/resources/profiler-test-JS-resources.js

    r164730 r173199  
    5353    for (var i = 0; i < profiles.length; ++i) {
    5454        preElement.appendChild(document.createTextNode("Profile title: " + profiles[i].title + "\n"));
    55         printProfileNodeWithoutTime(preElement, profiles[i].heavyProfile.head, 0);
     55        printProfileNodeWithoutTime(preElement, profiles[i].heavyProfile.rootNode, 0);
    5656        preElement.appendChild(document.createTextNode("\n"));
    5757    }
     
    6868    for (var i = 0; i < profiles.length; ++i) {
    6969        preElement.appendChild(document.createTextNode("Profile title: " + profiles[i].title + "\n"));
    70         printProfileNodeWithoutTime(preElement, profiles[i].head, 0);
     70        printProfileNodeWithoutTime(preElement, profiles[i].rootNode, 0);
    7171        preElement.appendChild(document.createTextNode("\n"));
    7272    }
  • trunk/Source/JavaScriptCore/ChangeLog

    r173198 r173199  
     12014-09-02  Brian J. Burg  <burg@cs.washington.edu>
     2
     3        LegacyProfiler: remove redundant ProfileNode members and other cleanup
     4        https://bugs.webkit.org/show_bug.cgi?id=136380
     5
     6        Reviewed by Timothy Hatcher.
     7
     8        ProfileNode's selfTime and totalTime members are redundant and only used
     9        for dumping profile data from debug-only code. Remove the members and compute
     10        the same data on-demand when necessary using a postorder traversal functor.
     11
     12        Remove ProfileNode.head since it is only used to calculate percentages for
     13        dumped profile data. This can be explicitly passed around when needed.
     14
     15        Rename Profile.head to Profile.rootNode, and other various renamings.
     16
     17        Rearrange some header includes so that touching LegacyProfiler-related headers
     18        will no longer cause a full rebuild.
     19
     20        * inspector/JSConsoleClient.cpp: Add header include.
     21        * inspector/agents/InspectorProfilerAgent.cpp:
     22        (Inspector::InspectorProfilerAgent::buildProfileInspectorObject):
     23        * inspector/protocol/Profiler.json: Remove unused Profile.idleTime member.
     24        * jit/JIT.h: Remove header include.
     25        * jit/JITCode.h: Remove header include.
     26        * jit/JITOperations.cpp: Sort and add header include.
     27        * llint/LLIntSlowPaths.cpp: Sort and add header include.
     28        * profiler/Profile.cpp: Rename the debug dumping functions. Move the node
     29        postorder traversal code to ProfileNode so we can traverse any subtree.
     30        (JSC::Profile::Profile):
     31        (JSC::Profile::debugPrint):
     32        (JSC::Profile::debugPrintSampleStyle):
     33        (JSC::Profile::forEach): Deleted.
     34        (JSC::Profile::debugPrintData): Deleted.
     35        (JSC::Profile::debugPrintDataSampleStyle): Deleted.
     36        * profiler/Profile.h:
     37        * profiler/ProfileGenerator.cpp:
     38        (JSC::ProfileGenerator::ProfileGenerator):
     39        (JSC::AddParentForConsoleStartFunctor::AddParentForConsoleStartFunctor):
     40        (JSC::AddParentForConsoleStartFunctor::operator()):
     41        (JSC::ProfileGenerator::addParentForConsoleStart):
     42        (JSC::ProfileGenerator::didExecute):
     43        (JSC::StopProfilingFunctor::operator()):
     44        (JSC::ProfileGenerator::stopProfiling):
     45        (JSC::ProfileGenerator::removeProfileStart):
     46        (JSC::ProfileGenerator::removeProfileEnd):
     47        * profiler/ProfileGenerator.h:
     48        * profiler/ProfileNode.cpp:
     49        (JSC::ProfileNode::ProfileNode):
     50        (JSC::ProfileNode::willExecute):
     51        (JSC::ProfileNode::removeChild):
     52        (JSC::ProfileNode::stopProfiling):
     53        (JSC::ProfileNode::endAndRecordCall):
     54        (JSC::ProfileNode::debugPrint):
     55        (JSC::ProfileNode::debugPrintSampleStyle):
     56        (JSC::ProfileNode::debugPrintRecursively):
     57        (JSC::ProfileNode::debugPrintSampleStyleRecursively):
     58        (JSC::ProfileNode::debugPrintData): Deleted.
     59        (JSC::ProfileNode::debugPrintDataSampleStyle): Deleted.
     60        * profiler/ProfileNode.h: Calculate per-node self and total times using a postorder traversal.
     61        The forEachNodePostorder functor traverses the subtree rooted at |this|.
     62        (JSC::ProfileNode::create):
     63        (JSC::ProfileNode::calls):
     64        (JSC::ProfileNode::forEachNodePostorder):
     65        (JSC::CalculateProfileSubtreeDataFunctor::returnValue):
     66        (JSC::CalculateProfileSubtreeDataFunctor::operator()):
     67        (JSC::ProfileNode::head): Deleted.
     68        (JSC::ProfileNode::setHead): Deleted.
     69        (JSC::ProfileNode::totalTime): Deleted.
     70        (JSC::ProfileNode::setTotalTime): Deleted.
     71        (JSC::ProfileNode::selfTime): Deleted.
     72        (JSC::ProfileNode::setSelfTime): Deleted.
     73        (JSC::ProfileNode::totalPercent): Deleted.
     74        (JSC::ProfileNode::selfPercent): Deleted.
     75        * runtime/ConsoleClient.h: Remove header include.
     76
    1772014-09-02  Brian J. Burg  <burg@cs.washington.edu>
    278
  • trunk/Source/JavaScriptCore/jit/JIT.h

    r172820 r173199  
    4545#include "JITInlineCacheGenerator.h"
    4646#include "JSInterfaceJIT.h"
    47 #include "LegacyProfiler.h"
    4847#include "Opcode.h"
    4948#include "ResultType.h"
  • trunk/Source/JavaScriptCore/jit/JITCode.h

    r163027 r173199  
    3232#include "JITStubs.h"
    3333#include "JSCJSValue.h"
    34 #include "LegacyProfiler.h"
    3534#include "MacroAssemblerCodeRef.h"
    3635#include "RegisterPreservationMode.h"
  • trunk/Source/JavaScriptCore/jit/JITOperations.cpp

    r173188 r173199  
    4444#include "JIT.h"
    4545#include "JITToDFGDeferredCompilationCallback.h"
     46#include "JSCInlines.h"
    4647#include "JSGlobalObjectFunctions.h"
    4748#include "JSNameScope.h"
     
    4950#include "JSStackInlines.h"
    5051#include "JSWithScope.h"
     52#include "LegacyProfiler.h"
    5153#include "ObjectConstructor.h"
    52 #include "JSCInlines.h"
    5354#include "Repatch.h"
    5455#include "RepatchBuffer.h"
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp

    r173188 r173199  
    2626#include "config.h"
    2727#include "LLIntSlowPaths.h"
     28
    2829#include "Arguments.h"
    2930#include "ArrayConstructor.h"
     
    3940#include "JITExceptions.h"
    4041#include "JSActivation.h"
     42#include "JSCInlines.h"
    4143#include "JSCJSValue.h"
    4244#include "JSGlobalObjectFunctions.h"
     
    4749#include "LLIntCommon.h"
    4850#include "LLIntExceptions.h"
     51#include "LegacyProfiler.h"
    4952#include "LowLevelInterpreter.h"
    5053#include "ObjectConstructor.h"
    51 #include "JSCInlines.h"
    5254#include "ProtoCallFrame.h"
    5355#include "StructureRareDataInlines.h"
  • trunk/Source/JavaScriptCore/profiler/Profile.cpp

    r173120 r173199  
    4040    : m_title(title)
    4141    , m_uid(uid)
    42     , m_idleTime(0)
    4342{
    4443    // FIXME: When multi-threading is supported this will be a vector and calls
    4544    // into the profiler will need to know which thread it is executing on.
    46     m_head = ProfileNode::create(0, CallIdentifier(ASCIILiteral("Thread_1"), String(), 0, 0), 0, 0);
     45    m_rootNode = ProfileNode::create(nullptr, CallIdentifier(ASCIILiteral("Thread_1"), String(), 0, 0), nullptr);
    4746}
    4847
     
    5150}
    5251
    53 void Profile::forEach(void (ProfileNode::*function)())
     52#ifndef NDEBUG
     53void Profile::debugPrint()
    5454{
    55     ProfileNode* currentNode = m_head->firstChild();
    56     for (ProfileNode* nextNode = currentNode; nextNode; nextNode = nextNode->firstChild())
    57         currentNode = nextNode;
     55    CalculateProfileSubtreeDataFunctor functor;
     56    m_rootNode->forEachNodePostorder(functor);
     57    ProfileNode::ProfileSubtreeData data = functor.returnValue();
    5858
    59     if (!currentNode)
    60         currentNode = m_head.get();
    61 
    62     ProfileNode* endNode = m_head->traverseNextNodePostOrder();
    63     while (currentNode && currentNode != endNode) {
    64         (currentNode->*function)();
    65         currentNode = currentNode->traverseNextNodePostOrder();
    66     }
    67 }
    68 
    69 #ifndef NDEBUG
    70 void Profile::debugPrintData() const
    71 {
    7259    dataLogF("Call graph:\n");
    73     m_head->debugPrintData(0);
     60    m_rootNode->debugPrintRecursively(0, data);
    7461}
    7562
     
    8168}
    8269
    83 void Profile::debugPrintDataSampleStyle() const
     70void Profile::debugPrintSampleStyle()
    8471{
    8572    typedef Vector<NameCountPair> NameCountPairVector;
    8673
     74    CalculateProfileSubtreeDataFunctor functor;
     75    m_rootNode->forEachNodePostorder(functor);
     76    ProfileNode::ProfileSubtreeData data = functor.returnValue();
     77
    8778    FunctionCallHashCount countedFunctions;
    8879    dataLogF("Call graph:\n");
    89     m_head->debugPrintDataSampleStyle(0, countedFunctions);
     80    m_rootNode->debugPrintSampleStyleRecursively(0, countedFunctions, data);
    9081
    9182    dataLogF("\nTotal number in stack:\n");
  • trunk/Source/JavaScriptCore/profiler/Profile.h

    r167530 r173199  
    4242    unsigned uid() const { return m_uid; }
    4343
    44     ProfileNode* head() const { return m_head.get(); }
    45     void setHead(PassRefPtr<ProfileNode> head) { m_head = head; }
    46 
    47     double totalTime() const { return m_head->totalTime(); }
    48 
    49     double idleTime() const { return m_idleTime; }
    50     void setIdleTime(double idleTime) { m_idleTime = idleTime; }
    51 
    52     void forEach(void (ProfileNode::*)());
     44    ProfileNode* rootNode() const { return m_rootNode.get(); }
     45    void setRootNode(PassRefPtr<ProfileNode> rootNode) { m_rootNode = rootNode; }
    5346
    5447#ifndef NDEBUG
    55     void debugPrintData() const;
    56     void debugPrintDataSampleStyle() const;
     48    void debugPrint();
     49    void debugPrintSampleStyle();
    5750#endif
    5851
     
    6558
    6659    String m_title;
    67     RefPtr<ProfileNode> m_head;
     60    RefPtr<ProfileNode> m_rootNode;
    6861    unsigned m_uid;
    69     double m_idleTime;
    7062};
    7163
  • trunk/Source/JavaScriptCore/profiler/ProfileGenerator.cpp

    r173162 r173199  
    5151{
    5252    m_profile = Profile::create(title, uid);
    53     m_currentNode = m_head = m_profile->head();
     53    m_currentNode = m_rootNode = m_profile->rootNode();
    5454    if (exec)
    5555        addParentForConsoleStart(exec);
     
    5858class AddParentForConsoleStartFunctor {
    5959public:
    60     AddParentForConsoleStartFunctor(ExecState* exec, RefPtr<ProfileNode>& head, RefPtr<ProfileNode>& currentNode)
     60    AddParentForConsoleStartFunctor(ExecState* exec, RefPtr<ProfileNode>& rootNode, RefPtr<ProfileNode>& currentNode)
    6161        : m_exec(exec)
    6262        , m_hasSkippedFirstFrame(false)
    6363        , m_foundParent(false)
    64         , m_head(head)
     64        , m_rootNode(rootNode)
    6565        , m_currentNode(currentNode)
    6666    {
     
    7979        unsigned column = 0;
    8080        visitor->computeLineAndColumn(line, column);
    81         m_currentNode = ProfileNode::create(m_exec, LegacyProfiler::createCallIdentifier(m_exec, visitor->callee(), visitor->sourceURL(), line, column), m_head.get(), m_head.get());
    82         m_head->insertNode(m_currentNode.get());
     81        m_currentNode = ProfileNode::create(m_exec, LegacyProfiler::createCallIdentifier(m_exec, visitor->callee(), visitor->sourceURL(), line, column), m_rootNode.get());
     82        m_rootNode->insertNode(m_currentNode.get());
    8383
    8484        m_foundParent = true;
     
    8989    ExecState* m_exec;
    9090    bool m_hasSkippedFirstFrame;
    91     bool m_foundParent; 
    92     RefPtr<ProfileNode>& m_head;
     91    bool m_foundParent;
     92    RefPtr<ProfileNode>& m_rootNode;
    9393    RefPtr<ProfileNode>& m_currentNode;
    9494};
     
    9696void ProfileGenerator::addParentForConsoleStart(ExecState* exec)
    9797{
    98     AddParentForConsoleStartFunctor functor(exec, m_head, m_currentNode);
     98    AddParentForConsoleStartFunctor functor(exec, m_rootNode, m_currentNode);
    9999    exec->iterate(functor);
    100100
     
    135135    ASSERT(m_currentNode);
    136136    if (m_currentNode->callIdentifier() != callIdentifier) {
    137         RefPtr<ProfileNode> returningNode = ProfileNode::create(callerCallFrame, callIdentifier, m_head.get(), m_currentNode.get());
     137        RefPtr<ProfileNode> returningNode = ProfileNode::create(callerCallFrame, callIdentifier, m_currentNode.get());
    138138        returningNode->lastCall().setStartTime(m_currentNode->lastCall().startTime());
    139139        returningNode->didExecute();
     
    156156}
    157157
     158struct StopProfilingFunctor {
     159    void operator()(ProfileNode* node) { node->stopProfiling(); }
     160};
     161
    158162void ProfileGenerator::stopProfiling()
    159163{
    160     m_profile->forEach(&ProfileNode::stopProfiling);
     164    // FIXME: we shouldn't need a full traversal here, since only the spine from
     165    // m_currentNode to m_rootNode should have any nodes currently accruing time.
     166    StopProfilingFunctor functor;
     167    m_profile->rootNode()->forEachNodePostorder(functor);
    161168
    162169    if (m_foundConsoleStartParent) {
     
    170177    // will not get didExecute call.
    171178    m_currentNode = m_currentNode->parent();
    172 
    173     if (double headSelfTime = m_head->selfTime()) {
    174         m_head->setSelfTime(0.0);
    175         m_profile->setIdleTime(headSelfTime);
    176     }
    177179}
    178180
     
    181183{
    182184    ProfileNode* currentNode = 0;
    183     for (ProfileNode* next = m_head.get(); next; next = next->firstChild())
     185    for (ProfileNode* next = m_rootNode.get(); next; next = next->firstChild())
    184186        currentNode = next;
    185187
     
    187189        return;
    188190
    189     // Attribute the time of the node aobut to be removed to the self time of its parent
    190     currentNode->parent()->setSelfTime(currentNode->parent()->selfTime() + currentNode->totalTime());
    191191    currentNode->parent()->removeChild(currentNode);
    192192}
     
    196196{
    197197    ProfileNode* currentNode = 0;
    198     for (ProfileNode* next = m_head.get(); next; next = next->lastChild())
     198    for (ProfileNode* next = m_rootNode.get(); next; next = next->lastChild())
    199199        currentNode = next;
    200200
    201201    if (currentNode->callIdentifier().functionName() != "profileEnd")
    202202        return;
    203 
    204     // Attribute the time of the node aobut to be removed to the self time of its parent
    205     currentNode->parent()->setSelfTime(currentNode->parent()->selfTime() + currentNode->totalTime());
    206203
    207204    ASSERT(currentNode->callIdentifier() == (currentNode->parent()->children()[currentNode->parent()->children().size() - 1])->callIdentifier());
  • trunk/Source/JavaScriptCore/profiler/ProfileGenerator.h

    r163140 r173199  
    2323 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2424 */
    25  
     25
    2626#ifndef ProfileGenerator_h
    2727#define ProfileGenerator_h
     
    3838    class Profile;
    3939    class ProfileNode;
    40     struct CallIdentifier;   
     40    struct CallIdentifier;
    4141
    4242    class ProfileGenerator : public RefCounted<ProfileGenerator>  {
     
    7171        JSGlobalObject* m_origin;
    7272        unsigned m_profileGroup;
    73         RefPtr<ProfileNode> m_head;
     73        RefPtr<ProfileNode> m_rootNode;
    7474        RefPtr<ProfileNode> m_currentNode;
    7575        bool m_foundConsoleStartParent;
  • trunk/Source/JavaScriptCore/profiler/ProfileNode.cpp

    r165676 r173199  
    3939namespace JSC {
    4040
    41 ProfileNode::ProfileNode(ExecState* callerCallFrame, const CallIdentifier& callIdentifier, ProfileNode* headNode, ProfileNode* parentNode)
     41ProfileNode::ProfileNode(ExecState* callerCallFrame, const CallIdentifier& callIdentifier, ProfileNode* parentNode)
    4242    : m_callerCallFrame(callerCallFrame)
    4343    , m_callIdentifier(callIdentifier)
    44     , m_head(headNode)
    4544    , m_parent(parentNode)
    4645    , m_nextSibling(nullptr)
    47     , m_totalTime(0)
    48     , m_selfTime(0)
    4946{
    5047    startTimer();
    5148}
    5249
    53 ProfileNode::ProfileNode(ExecState* callerCallFrame, ProfileNode* headNode, ProfileNode* nodeToCopy)
     50ProfileNode::ProfileNode(ExecState* callerCallFrame, ProfileNode* nodeToCopy)
    5451    : m_callerCallFrame(callerCallFrame)
    5552    , m_callIdentifier(nodeToCopy->callIdentifier())
    56     , m_head(headNode)
    5753    , m_parent(nodeToCopy->parent())
    58     , m_nextSibling(0)
    59     , m_totalTime(nodeToCopy->totalTime())
    60     , m_selfTime(nodeToCopy->selfTime())
     54    , m_nextSibling(nullptr)
    6155    , m_calls(nodeToCopy->calls())
    6256{
     
    7266    }
    7367
    74     RefPtr<ProfileNode> newChild = ProfileNode::create(callerCallFrame, callIdentifier, m_head ? m_head : this, this); // If this ProfileNode has no head it is the head.
     68    RefPtr<ProfileNode> newChild = ProfileNode::create(callerCallFrame, callIdentifier, this);
    7569    if (m_children.size())
    7670        m_children.last()->setNextSibling(newChild.get());
     
    10599        }
    106100    }
    107    
     101
    108102    resetChildrensSiblings();
    109103}
     
    126120    if (isnan(m_calls.last().totalTime()))
    127121        endAndRecordCall();
    128 
    129     // Because we iterate in post order all of our children have been stopped before us.
    130     for (unsigned i = 0; i < m_children.size(); ++i)
    131         m_selfTime += m_children[i]->totalTime();
    132 
    133     ASSERT(m_selfTime <= m_totalTime);
    134     m_selfTime = m_totalTime - m_selfTime;
    135122}
    136123
     
    151138
    152139    last.setTotalTime(currentTime() - last.startTime());
    153 
    154     m_totalTime += last.totalTime();
    155140}
    156141
     
    168153
    169154#ifndef NDEBUG
    170 void ProfileNode::debugPrintData(int indentLevel) const
     155void ProfileNode::debugPrint()
     156{
     157    CalculateProfileSubtreeDataFunctor functor;
     158    forEachNodePostorder(functor);
     159    ProfileNode::ProfileSubtreeData data = functor.returnValue();
     160
     161    debugPrintRecursively(0, data);
     162}
     163
     164void ProfileNode::debugPrintSampleStyle()
     165{
     166    FunctionCallHashCount countedFunctions;
     167
     168    CalculateProfileSubtreeDataFunctor functor;
     169    forEachNodePostorder(functor);
     170    ProfileNode::ProfileSubtreeData data = functor.returnValue();
     171
     172    debugPrintSampleStyleRecursively(0, countedFunctions, data);
     173}
     174
     175void ProfileNode::debugPrintRecursively(int indentLevel, const ProfileSubtreeData& data)
    171176{
    172177    // Print function names
     
    174179        dataLogF("  ");
    175180
     181    auto it = data.selfAndTotalTimes.find(this);
     182    ASSERT(it != data.selfAndTotalTimes.end());
     183
     184    double nodeSelfTime = it->value.first;
     185    double nodeTotalTime = it->value.second;
     186    double rootTotalTime = data.rootTotalTime;
     187
    176188    dataLogF("Function Name %s %zu SelfTime %.3fms/%.3f%% TotalTime %.3fms/%.3f%% Next Sibling %s\n",
    177189        functionName().utf8().data(),
    178         numberOfCalls(), m_selfTime, selfPercent(), m_totalTime, totalPercent(),
     190        numberOfCalls(), nodeSelfTime, nodeSelfTime / rootTotalTime * 100.0, nodeTotalTime, nodeTotalTime / rootTotalTime * 100.0,
    179191        m_nextSibling ? m_nextSibling->functionName().utf8().data() : "");
    180192
     
    183195    // Print children's names and information
    184196    for (StackIterator currentChild = m_children.begin(); currentChild != m_children.end(); ++currentChild)
    185         (*currentChild)->debugPrintData(indentLevel);
     197        (*currentChild)->debugPrintRecursively(indentLevel, data);
    186198}
    187199
    188200// print the profiled data in a format that matches the tool sample's output.
    189 double ProfileNode::debugPrintDataSampleStyle(int indentLevel, FunctionCallHashCount& countedFunctions) const
     201double ProfileNode::debugPrintSampleStyleRecursively(int indentLevel, FunctionCallHashCount& countedFunctions, const ProfileSubtreeData& data)
    190202{
    191203    dataLogF("    ");
     204
     205    auto it = data.selfAndTotalTimes.find(this);
     206    ASSERT(it != data.selfAndTotalTimes.end());
     207    double nodeTotalTime = it->value.second;
    192208
    193209    // Print function names
    194210    const char* name = functionName().utf8().data();
    195     double sampleCount = m_totalTime * 1000;
     211    double sampleCount = nodeTotalTime * 1000;
    196212    if (indentLevel) {
    197213        for (int i = 0; i < indentLevel; ++i)
     
    209225    double sumOfChildrensCount = 0.0;
    210226    for (StackIterator currentChild = m_children.begin(); currentChild != m_children.end(); ++currentChild)
    211         sumOfChildrensCount += (*currentChild)->debugPrintDataSampleStyle(indentLevel, countedFunctions);
     227        sumOfChildrensCount += (*currentChild)->debugPrintSampleStyleRecursively(indentLevel, countedFunctions, data);
    212228
    213229    sumOfChildrensCount *= 1000;    //
     
    221237    }
    222238
    223     return m_totalTime;
     239    return nodeTotalTime;
    224240}
    225241#endif
  • trunk/Source/JavaScriptCore/profiler/ProfileNode.h

    r165676 r173199  
    4545    class ProfileNode : public RefCounted<ProfileNode> {
    4646    public:
    47         static PassRefPtr<ProfileNode> create(ExecState* callerCallFrame, const CallIdentifier& callIdentifier, ProfileNode* headNode, ProfileNode* parentNode)
     47        static PassRefPtr<ProfileNode> create(ExecState* callerCallFrame, const CallIdentifier& callIdentifier, ProfileNode* parentNode)
    4848        {
    49             return adoptRef(new ProfileNode(callerCallFrame, callIdentifier, headNode, parentNode));
     49            return adoptRef(new ProfileNode(callerCallFrame, callIdentifier, parentNode));
    5050        }
    5151
    52         static PassRefPtr<ProfileNode> create(ExecState* callerCallFrame, ProfileNode* headNode, ProfileNode* node)
     52        static PassRefPtr<ProfileNode> create(ExecState* callerCallFrame, ProfileNode* node)
    5353        {
    54             return adoptRef(new ProfileNode(callerCallFrame, headNode, node));
     54            return adoptRef(new ProfileNode(callerCallFrame, node));
    5555        }
    5656
     
    9191
    9292        // Relationships
    93         ProfileNode* head() const { return m_head; }
    94         void setHead(ProfileNode* head) { m_head = head; }
    95 
    9693        ProfileNode* parent() const { return m_parent; }
    9794        void setParent(ProfileNode* parent) { m_parent = parent; }
     
    10097        void setNextSibling(ProfileNode* nextSibling) { m_nextSibling = nextSibling; }
    10198
    102         // Time members
    103         double totalTime() const { return m_totalTime; }
    104         void setTotalTime(double time) { m_totalTime = time; }
    105 
    106         double selfTime() const { return m_selfTime; }
    107         void setSelfTime(double time) { m_selfTime = time; }
    108 
    109         double totalPercent() const { return (m_totalTime / (m_head ? m_head->totalTime() : totalTime())) * 100.0; }
    110         double selfPercent() const { return (m_selfTime / (m_head ? m_head->totalTime() : totalTime())) * 100.0; }
    111 
    112         Vector<Call> calls() const { return m_calls; }
     99        const Vector<Call>& calls() const { return m_calls; }
    113100        Call& lastCall() { ASSERT(!m_calls.isEmpty()); return m_calls.last(); }
    114101        size_t numberOfCalls() const { return m_calls.size(); }
     
    122109        void insertNode(PassRefPtr<ProfileNode> prpNode);
    123110
    124         ProfileNode* traverseNextNodePostOrder() const;
     111        template <typename Functor> void forEachNodePostorder(Functor&);
    125112
    126113#ifndef NDEBUG
     114        struct ProfileSubtreeData {
     115            HashMap<ProfileNode*, std::pair<double, double>> selfAndTotalTimes;
     116            double rootTotalTime;
     117        };
     118
    127119        const char* c_str() const { return m_callIdentifier; }
    128         void debugPrintData(int indentLevel) const;
    129         double debugPrintDataSampleStyle(int indentLevel, FunctionCallHashCount&) const;
     120        // Use these functions to dump the subtree rooted at this node.
     121        void debugPrint();
     122        void debugPrintSampleStyle();
     123
     124        // These are used to recursively print entire subtrees using precomputed self and total times.
     125        void debugPrintRecursively(int indentLevel, const ProfileSubtreeData&);
     126        double debugPrintSampleStyleRecursively(int indentLevel, FunctionCallHashCount&, const ProfileSubtreeData&);
    130127#endif
    131128
     
    133130        typedef Vector<RefPtr<ProfileNode>>::const_iterator StackIterator;
    134131
    135         ProfileNode(ExecState* callerCallFrame, const CallIdentifier&, ProfileNode* headNode, ProfileNode* parentNode);
    136         ProfileNode(ExecState* callerCallFrame, ProfileNode* headNode, ProfileNode* nodeToCopy);
     132        ProfileNode(ExecState* callerCallFrame, const CallIdentifier&, ProfileNode* parentNode);
     133        ProfileNode(ExecState* callerCallFrame, ProfileNode* nodeToCopy);
    137134
    138135        void startTimer();
    139136        void resetChildrensSiblings();
    140137        void endAndRecordCall();
     138        ProfileNode* traverseNextNodePostOrder() const;
    141139
    142140        ExecState* m_callerCallFrame;
    143141        CallIdentifier m_callIdentifier;
    144         ProfileNode* m_head;
    145142        ProfileNode* m_parent;
    146143        ProfileNode* m_nextSibling;
    147144
    148         double m_totalTime;
    149         double m_selfTime;
    150 
    151         Vector<Call, 1> m_calls;
     145        Vector<Call> m_calls;
    152146        Vector<RefPtr<ProfileNode>> m_children;
    153147    };
     148
     149    template <typename Functor> inline void ProfileNode::forEachNodePostorder(Functor& functor)
     150    {
     151        ProfileNode* currentNode = this;
     152        // Go down to the first node of the traversal, and slowly walk back up.
     153        for (ProfileNode* nextNode = currentNode; nextNode; nextNode = nextNode->firstChild())
     154            currentNode = nextNode;
     155
     156        ProfileNode* endNode = this;
     157        while (currentNode && currentNode != endNode) {
     158            functor(currentNode);
     159            currentNode = currentNode->traverseNextNodePostOrder();
     160        }
     161
     162        functor(endNode);
     163    }
     164
     165#ifndef NDEBUG
     166    struct CalculateProfileSubtreeDataFunctor {
     167        void operator()(ProfileNode* node)
     168        {
     169            double selfTime = 0.0;
     170            for (const ProfileNode::Call& call : node->calls())
     171                selfTime += call.totalTime();
     172
     173            double totalTime = selfTime;
     174            for (RefPtr<ProfileNode> child : node->children()) {
     175                auto it = m_data.selfAndTotalTimes.find(child.get());
     176                if (it != m_data.selfAndTotalTimes.end())
     177                    totalTime += it->value.second;
     178            }
     179
     180            ASSERT(node);
     181            m_data.selfAndTotalTimes.set(node, std::make_pair(selfTime, totalTime));
     182        }
     183
     184        ProfileNode::ProfileSubtreeData returnValue() { return WTF::move(m_data); }
     185
     186        ProfileNode::ProfileSubtreeData m_data;
     187    };
     188#endif
    154189
    155190} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/ConsoleClient.h

    r167530 r173199  
    2828
    2929#include "ConsoleTypes.h"
    30 #include "Profile.h"
    3130#include <wtf/Forward.h>
    3231
  • trunk/Source/WebCore/ChangeLog

    r173198 r173199  
     12014-09-02  Brian J. Burg  <burg@cs.washington.edu>
     2
     3        LegacyProfiler: remove redundant ProfileNode members and other cleanup
     4        https://bugs.webkit.org/show_bug.cgi?id=136380
     5
     6        Reviewed by Timothy Hatcher.
     7
     8        Remove Profile.idleTime, rename head to rootNode, and remove ProfileNode members.
     9
     10        Covered by existing tests.
     11
     12        * inspector/ScriptProfile.idl:
     13        * inspector/ScriptProfileNode.idl:
     14        * inspector/TimelineRecordFactory.cpp:
     15
    1162014-09-02  Brian J. Burg  <burg@cs.washington.edu>
    217
  • trunk/Source/WebCore/inspector/ScriptProfile.idl

    r168302 r173199  
    3131    readonly attribute DOMString title;
    3232    readonly attribute unsigned long uid;
    33     readonly attribute ScriptProfileNode head;
    34     readonly attribute unrestricted double idleTime;
     33    readonly attribute ScriptProfileNode rootNode;
    3534};
    3635
  • trunk/Source/WebCore/inspector/ScriptProfileNode.idl

    r168302 r173199  
    3737    readonly attribute unsigned long columnNumber;
    3838
    39     readonly attribute unrestricted double totalTime;
    40     readonly attribute unrestricted double selfTime;
    41 
    4239    readonly attribute unsigned long numberOfCalls;
    4340
  • trunk/Source/WebCore/inspector/TimelineRecordFactory.cpp

    r173198 r173199  
    311311{
    312312    RefPtr<Protocol::Array<Protocol::Timeline::CPUProfileNode>> rootNodes = Protocol::Array<Protocol::Timeline::CPUProfileNode>::create();
    313     for (RefPtr<JSC::ProfileNode> profileNode : profile->head()->children())
     313    for (RefPtr<JSC::ProfileNode> profileNode : profile->rootNode()->children())
    314314        rootNodes->addItem(buildInspectorObject(profileNode.get()));
    315315
     
    317317        .setRootNodes(rootNodes);
    318318
    319     if (profile->idleTime())
    320         result->setIdleTime(profile->idleTime());
    321 
    322319    return result.release();
    323320}
  • trunk/Source/WebInspectorUI/ChangeLog

    r173198 r173199  
     12014-09-02  Brian J. Burg  <burg@cs.washington.edu>
     2
     3        LegacyProfiler: remove redundant ProfileNode members and other cleanup
     4        https://bugs.webkit.org/show_bug.cgi?id=136380
     5
     6        Reviewed by Timothy Hatcher.
     7
     8        Remove unused Profile.idleTime member.
     9
     10        * UserInterface/Models/Profile.js:
     11        (WebInspector.Profile.prototype.get idleTime): Deleted.
     12        * UserInterface/Models/ScriptTimelineRecord.js:
     13        (WebInspector.ScriptTimelineRecord.prototype._initializeProfileFromPayload):
     14
    1152014-09-02  Brian J. Burg  <burg@cs.washington.edu>
    216
  • trunk/Source/WebInspectorUI/UserInterface/Models/Profile.js

    r164543 r173199  
    2424 */
    2525
    26 WebInspector.Profile = function(topDownRootNodes, idleTime)
     26WebInspector.Profile = function(topDownRootNodes)
    2727{
    2828    WebInspector.Object.call(this);
     
    3434
    3535    this._topDownRootNodes = topDownRootNodes;
    36     this._idleTime = idleTime || 0;
    3736};
    3837
     
    4241
    4342    // Public
    44 
    45     get idleTime()
    46     {
    47         return this._idleTime;
    48     },
    4943
    5044    get topDownRootNodes()
  • trunk/Source/WebInspectorUI/UserInterface/Models/ScriptTimelineRecord.js

    r171866 r173199  
    347347        }
    348348
    349         this._profile = new WebInspector.Profile(rootNodes, payload.idleTime);
     349        this._profile = new WebInspector.Profile(rootNodes);
    350350    }
    351351};
Note: See TracChangeset for help on using the changeset viewer.