Changeset 42808 in webkit for trunk/JavaScriptCore


Ignore:
Timestamp:
Apr 23, 2009, 8:47:50 PM (16 years ago)
Author:
[email protected]
Message:

BUG 24604: WebKit profiler reports incorrect total times

JavaScriptCore:

2009-04-23 Francisco Tolmasky <[email protected]>

BUG 24604: WebKit profiler reports incorrect total times
<https://bugs.webkit.org/show_bug.cgi?id=24604>

Reviewed by Timothy Hatcher and Kevin McCullough.

  • JavaScriptCore.exp:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • profiler/CallIdentifier.h: (JSC::CallIdentifier::Hash::hash): (JSC::CallIdentifier::Hash::equal): (JSC::CallIdentifier::hash): (WTF::):
  • profiler/HeavyProfile.cpp: Removed.
  • profiler/HeavyProfile.h: Removed.
  • profiler/Profile.cpp: No more need for TreeProfile/HeavyProfile (JSC::Profile::create):
  • profiler/Profile.h:
  • profiler/ProfileNode.cpp:
  • profiler/ProfileNode.h:
  • profiler/TreeProfile.cpp: Removed.
  • profiler/TreeProfile.h: Removed.

WebCore:

2009-04-23 Francisco Tolmasky <[email protected]>

BUG 24604: WebKit profiler reports incorrect total times
<https://bugs.webkit.org/show_bug.cgi?id=24604>

Reviewed by Timothy Hatcher and Kevin McCullough.

Made it so that most of the profiler functions now match the behavior of Shark. Most notably, in the
heavy view, child nodes now represent the statistics of the root node. Each root node of heavy view
displays flattened statistics for a particular function that ran during the profile, and each child
of these root nodes represents a callpath that lead to it. Thus, the statistics for each of these child
nodes should show how much of the root nodes values came from it. For example, if you had the following to
stacks take place during the profile:

A ->calls 1 times-> B ->calls 2 times-> C
D ->calls 4 times-> C

The tree for the C root node would look like this:

C -> B -> A

-> D

The number of calls values would look like this:

C (6) -> B (2) -> A(2)

-> D (4)

What this means is that "2 of the total 6 C calls came from B", "2 of the total C calls came from A", and
"4 of the total C calls came from D". Notice that the "A ->calls 2 time->" is completely ignored. This becomes
particularly tricky during recursive calls, because each child note can represent multiple possible paths. This
is the reason that we would get things like 40000% previously with recursion.

This is also the way gprof works, and as close as we can get to Shark's behavior (Shark is not instrumented so it
can't know exactly how many calls came from where, etc).

  • English.lproj/localizedStrings.js: Added "Average" for average times in the profile.
  • inspector/JavaScriptProfile.cpp: (WebCore::ProfileClass):
  • inspector/JavaScriptProfileNode.cpp: (WebCore::getParent): (WebCore::getHead): (WebCore::getCallUID): (WebCore::ProfileNodeClass):
  • inspector/front-end/BottomUpProfileDataGridTree.js: Added. (WebInspector.BottomUpProfileDataGridTree): (WebInspector.BottomUpProfileDataGridTree.prototype.focus): (WebInspector.BottomUpProfileDataGridNode): (WebInspector.BottomUpProfileDataGridNode.prototype._takePropertiesFromProfileDataGridNode): (WebInspector.BottomUpProfileDataGridNode.prototype._keepOnlyChild): (WebInspector.BottomUpProfileDataGridNode.prototype._exclude): (WebInspector.BottomUpProfileDataGridNode.prototype._merge): (WebInspector.BottomUpProfileDataGridNode.prototype._populate):
  • inspector/front-end/DataGrid.js: (WebInspector.DataGrid.prototype.insertChild): (WebInspector.DataGrid.prototype.removeChild): (WebInspector.DataGrid.prototype.removeChildren): (WebInspector.DataGridNode.prototype.set hasChildren): (WebInspector.DataGridNode.prototype.get hasChildren):
  • inspector/front-end/ProfileDataGridTree.js: Added. (WebInspector.ProfileDataGridNode): (WebInspector.ProfileDataGridNode.prototype.get data.formatMilliseconds): (WebInspector.ProfileDataGridNode.prototype.get data): (WebInspector.ProfileDataGridNode.prototype.createCell): (WebInspector.ProfileDataGridNode.prototype.select): (WebInspector.ProfileDataGridNode.prototype.deselect): (WebInspector.ProfileDataGridNode.prototype.expand): (WebInspector.ProfileDataGridNode.prototype.insertChild): (WebInspector.ProfileDataGridNode.prototype.removeChild): (WebInspector.ProfileDataGridNode.prototype.removeChildren): (WebInspector.ProfileDataGridNode.prototype.findChild): (WebInspector.ProfileDataGridNode.prototype.get averageTime): (WebInspector.ProfileDataGridNode.prototype.get averagePercent): (WebInspector.ProfileDataGridNode.prototype.get selfPercent): (WebInspector.ProfileDataGridNode.prototype.get totalPercent): (WebInspector.ProfileDataGridNode.prototype._save): (WebInspector.ProfileDataGridNode.prototype._restore): (WebInspector.ProfileDataGridNode.prototype._merge): (WebInspector.ProfileDataGridTree): (WebInspector.ProfileDataGridTree.prototype.get expanded): (WebInspector.ProfileDataGridTree.prototype.appendChild): (WebInspector.ProfileDataGridTree.prototype.insertChild): (WebInspector.ProfileDataGridTree.prototype.removeChildren): (WebInspector.ProfileDataGridTree.prototype.findChild.WebInspector.ProfileDataGridNode.prototype.findChild.sort.WebInspector.ProfileDataGridNode.prototype.sort._save): (WebInspector.ProfileDataGridTree.propertyComparator.comparator): (WebInspector.ProfileDataGridTree.propertyComparator.else.comparator): (WebInspector.ProfileDataGridTree.propertyComparator):
  • inspector/front-end/ProfileView.js: (WebInspector.ProfileView): (WebInspector.ProfileView.prototype.set profile): (WebInspector.ProfileView.prototype.get bottomUpProfileDataGridTree): (WebInspector.ProfileView.prototype.get topDownProfileDataGridTree): (WebInspector.ProfileView.prototype.get currentTree): (WebInspector.ProfileView.prototype.set currentTree): (WebInspector.ProfileView.prototype.get topDownTree): (WebInspector.ProfileView.prototype.get bottomUpTree): (WebInspector.ProfileView.prototype.refresh): (WebInspector.ProfileView.prototype.refreshVisibleData): (WebInspector.ProfileView.prototype.refreshShowAsPercents): (WebInspector.ProfileView.prototype.performSearch.matchesQuery): (WebInspector.ProfileView.prototype.performSearch): (WebInspector.ProfileView.prototype._changeView): (WebInspector.ProfileView.prototype._focusClicked): (WebInspector.ProfileView.prototype._excludeClicked): (WebInspector.ProfileView.prototype._resetClicked): (WebInspector.ProfileView.prototype._sortProfile):
  • inspector/front-end/ProfilesPanel.js: (WebInspector.ProfilesPanel.prototype.showProfile): (WebInspector.ProfilesPanel.prototype.showView): (WebInspector.ProfilesPanel.prototype.searchMatchFound):
  • inspector/front-end/TopDownProfileDataGridTree.js: Added. (WebInspector.TopDownProfileDataGridNode): (WebInspector.TopDownProfileDataGridNode.prototype._populate): (WebInspector.TopDownProfileDataGridNode.prototype._exclude): (WebInspector.TopDownProfileDataGridTree): (WebInspector.TopDownProfileDataGridTree.prototype.focus): (WebInspector.TopDownProfileDataGridTree.prototype.exclude):
  • inspector/front-end/WebKit.qrc:
  • inspector/front-end/inspector.css:
  • inspector/front-end/inspector.html:

LayoutTests:

2009-04-23 Francisco Tolmasky <[email protected]>

BUG 24604: WebKit profiler reports incorrect total times
<https://bugs.webkit.org/show_bug.cgi?id=24604>

Reviewed by Timothy Hatcher and Kevin McCullough.

Changed profile.treeProfile to just profile, since these aren't generated in C++ anymore.
Removed heavy-view test since heavy-view isn't an actual tree that is generated in C++ land anymore,
but rather just a different display of the normal treeProfile in the JS data grid.

  • fast/profiler/heavy-view-expected.txt: Removed.
  • fast/profiler/heavy-view.html: Removed.
  • fast/profiler/resources/profiler-test-JS-resources.js: profiles[i].treeProfile -> profiles[i].treeProfile (printProfilesDataWithoutTime):
Location:
trunk/JavaScriptCore
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r42805 r42808  
     12009-04-23  Francisco Tolmasky  <[email protected]>
     2
     3        BUG 24604: WebKit profiler reports incorrect total times
     4        <https://bugs.webkit.org/show_bug.cgi?id=24604>
     5
     6        Reviewed by Timothy Hatcher and Kevin McCullough.
     7
     8        * JavaScriptCore.exp:
     9        * JavaScriptCore.xcodeproj/project.pbxproj:
     10        * profiler/CallIdentifier.h:
     11        (JSC::CallIdentifier::Hash::hash):
     12        (JSC::CallIdentifier::Hash::equal):
     13        (JSC::CallIdentifier::hash):
     14        (WTF::):
     15        * profiler/HeavyProfile.cpp: Removed.
     16        * profiler/HeavyProfile.h: Removed.
     17        * profiler/Profile.cpp: No more need for TreeProfile/HeavyProfile
     18        (JSC::Profile::create):
     19        * profiler/Profile.h:
     20        * profiler/ProfileNode.cpp:
     21        * profiler/ProfileNode.h:
     22        * profiler/TreeProfile.cpp: Removed.
     23        * profiler/TreeProfile.h: Removed.
     24
    1252009-04-23  Gavin Barraclough  <[email protected]>
    226
  • trunk/JavaScriptCore/JavaScriptCore.exp

    r41168 r42808  
    106106__ZN3JSC11JSImmediate8toStringENS_10JSValuePtrE
    107107__ZN3JSC11JSImmediate9prototypeENS_10JSValuePtrEPNS_9ExecStateE
    108 __ZN3JSC11ProfileNode4sortEPFbRKN3WTF6RefPtrIS0_EES5_E
    109108__ZN3JSC11checkSyntaxEPNS_9ExecStateERKNS_10SourceCodeE
    110109__ZN3JSC12DateInstance4infoE
     
    213212__ZN3JSC7Profile7excludeEPKNS_11ProfileNodeE
    214213__ZN3JSC7Profile7forEachEMNS_11ProfileNodeEFvvE
     214__ZN3JSC7UString3Rep11computeHashEPKci
    215215__ZN3JSC7UString3Rep11computeHashEPKti
    216216__ZN3JSC7UString3Rep14nullBaseStringE
  • trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r42705 r42808  
    155155                95AB83420DA4322500BC83F3 /* Profiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95AB832E0DA42CAD00BC83F3 /* Profiler.cpp */; };
    156156                95AB83560DA43C3000BC83F3 /* ProfileNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95AB83540DA43B4400BC83F3 /* ProfileNode.cpp */; };
    157                 95CD41B30E1BF6560085358E /* TreeProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95CD41B10E1BF6560085358E /* TreeProfile.cpp */; };
    158                 95CD41B40E1BF6560085358E /* TreeProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 95CD41B20E1BF6560085358E /* TreeProfile.h */; };
    159157                95CD45760E1C4FDD0085358E /* ProfileGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95CD45740E1C4FDD0085358E /* ProfileGenerator.cpp */; };
    160158                95CD45770E1C4FDD0085358E /* ProfileGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 95CD45750E1C4FDD0085358E /* ProfileGenerator.h */; settings = {ATTRIBUTES = (); }; };
    161159                95E3BC050E1AE68200B2D1C1 /* CallIdentifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 95E3BC040E1AE68200B2D1C1 /* CallIdentifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
    162160                95F6E6950E5B5F970091E860 /* JSProfilerPrivate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95988BA90E477BEC00D28D4D /* JSProfilerPrivate.cpp */; };
    163                 95FDFA140E22998F0006FB00 /* HeavyProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95FDFA130E22998F0006FB00 /* HeavyProfile.cpp */; };
    164                 95FDFA160E2299980006FB00 /* HeavyProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 95FDFA150E2299980006FB00 /* HeavyProfile.h */; };
    165161                960097A60EBABB58007A7297 /* LabelScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 960097A50EBABB58007A7297 /* LabelScope.h */; };
    166162                9688CB150ED12B4E001D649F /* AssemblerBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9688CB130ED12B4E001D649F /* AssemblerBuffer.h */; };
     
    673669                95AB83550DA43B4400BC83F3 /* ProfileNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfileNode.h; path = profiler/ProfileNode.h; sourceTree = "<group>"; };
    674670                95C18D3E0C90E7EF00E72F73 /* JSRetainPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSRetainPtr.h; sourceTree = "<group>"; };
    675                 95CD41B10E1BF6560085358E /* TreeProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TreeProfile.cpp; path = profiler/TreeProfile.cpp; sourceTree = "<group>"; };
    676                 95CD41B20E1BF6560085358E /* TreeProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TreeProfile.h; path = profiler/TreeProfile.h; sourceTree = "<group>"; };
    677671                95CD45740E1C4FDD0085358E /* ProfileGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProfileGenerator.cpp; path = profiler/ProfileGenerator.cpp; sourceTree = "<group>"; };
    678672                95CD45750E1C4FDD0085358E /* ProfileGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfileGenerator.h; path = profiler/ProfileGenerator.h; sourceTree = "<group>"; };
    679673                95E3BC040E1AE68200B2D1C1 /* CallIdentifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CallIdentifier.h; path = profiler/CallIdentifier.h; sourceTree = "<group>"; };
    680                 95FDFA130E22998F0006FB00 /* HeavyProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HeavyProfile.cpp; path = profiler/HeavyProfile.cpp; sourceTree = "<group>"; };
    681                 95FDFA150E2299980006FB00 /* HeavyProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HeavyProfile.h; path = profiler/HeavyProfile.h; sourceTree = "<group>"; };
    682674                960097A50EBABB58007A7297 /* LabelScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LabelScope.h; sourceTree = "<group>"; };
    683675                9688CB130ED12B4E001D649F /* AssemblerBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AssemblerBuffer.h; sourceTree = "<group>"; };
     
    14821474                        children = (
    14831475                                95E3BC040E1AE68200B2D1C1 /* CallIdentifier.h */,
    1484                                 95FDFA130E22998F0006FB00 /* HeavyProfile.cpp */,
    1485                                 95FDFA150E2299980006FB00 /* HeavyProfile.h */,
    14861476                                95742F630DD11F5A000917FB /* Profile.cpp */,
    14871477                                95742F640DD11F5A000917FB /* Profile.h */,
     
    14941484                                1C61516B0EBAC7A00031376F /* ProfilerServer.h */,
    14951485                                1C61516A0EBAC7A00031376F /* ProfilerServer.mm */,
    1496                                 95CD41B10E1BF6560085358E /* TreeProfile.cpp */,
    1497                                 95CD41B20E1BF6560085358E /* TreeProfile.h */,
    14981486                        );
    14991487                        name = profiler;
     
    16341622                                BC18C40D0E16F5CD00B34460 /* HashTable.h in Headers */,
    16351623                                BC18C40E0E16F5CD00B34460 /* HashTraits.h in Headers */,
    1636                                 95FDFA160E2299980006FB00 /* HeavyProfile.h in Headers */,
    16371624                                BC18C40F0E16F5CD00B34460 /* Identifier.h in Headers */,
    16381625                                BC18C4100E16F5CD00B34460 /* InitializeThreading.h in Headers */,
     
    17661753                                BC18C4700E16F5CD00B34460 /* Threading.h in Headers */,
    17671754                                5D53726F0E1C54880021E549 /* Tracing.h in Headers */,
    1768                                 95CD41B40E1BF6560085358E /* TreeProfile.h in Headers */,
    17691755                                6507D29E0E871E5E00D7D896 /* TypeInfo.h in Headers */,
    17701756                                0B4D7E630F319AC800AD7E58 /* TypeTraits.h in Headers */,
     
    21022088                                A782F1A50EEC9FA20036273F /* ExecutableAllocatorPosix.cpp in Sources */,
    21032089                                65DFC93308EA173A00F7300B /* HashTable.cpp in Sources */,
    2104                                 95FDFA140E22998F0006FB00 /* HeavyProfile.cpp in Sources */,
    21052090                                E178636D0D9BEEC300D74E75 /* InitializeThreading.cpp in Sources */,
    21062091                                1429D7D40ED2128200B89619 /* Interpreter.cpp in Sources */,
     
    21452130                                5D6A566B0F05995500266145 /* Threading.cpp in Sources */,
    21462131                                E1EE793D0D6C9B9200FEA3BA /* ThreadingPthreads.cpp in Sources */,
    2147                                 95CD41B30E1BF6560085358E /* TreeProfile.cpp in Sources */,
    21482132                                E1EF79AA0CE97BA60088D500 /* UTF8.cpp in Sources */,
    21492133                                869083150E6518D7000D36ED /* WREC.cpp in Sources */,
  • trunk/JavaScriptCore/profiler/CallIdentifier.h

    r38137 r42808  
    5252        inline bool operator!=(const CallIdentifier& ci) const { return !(*this == ci); }
    5353
     54        struct Hash {
     55            static unsigned hash(const CallIdentifier& key)
     56            {
     57                unsigned hashCodes[3] = {
     58                    key.m_name.rep()->hash(),
     59                    key.m_url.rep()->hash(),
     60                    key.m_lineNumber
     61                };
     62                return UString::Rep::computeHash(reinterpret_cast<char*>(hashCodes), sizeof(hashCodes));
     63            }
     64
     65            static bool equal(const CallIdentifier& a, const CallIdentifier& b) { return a == b; }
     66            static const bool safeToCompareToEmptyOrDeleted = true;
     67        };
     68
     69        unsigned hash() const { return Hash::hash(*this); }
     70
    5471#ifndef NDEBUG
    5572        operator const char*() const { return c_str(); }
     
    5875    };
    5976
    60     struct CallIdentifierHash {
    61         static unsigned hash(const CallIdentifier& key)
    62         {
    63             unsigned hashCodes[3] = {
    64                 key.m_name.rep()->hash(),
    65                 key.m_url.rep()->hash(),
    66                 key.m_lineNumber
    67             };
    68             return UString::Rep::computeHash(reinterpret_cast<char*>(hashCodes), sizeof(hashCodes));
    69         }
    70 
    71         static bool equal(const CallIdentifier& a, const CallIdentifier& b) { return a == b; }
    72         static const bool safeToCompareToEmptyOrDeleted = true;
    73     };
    74 
    7577} // namespace JSC
    7678
    7779namespace WTF {
    7880
    79     template<> struct DefaultHash<JSC::CallIdentifier> { typedef JSC::CallIdentifierHash Hash; };
     81    template<> struct DefaultHash<JSC::CallIdentifier> { typedef JSC::CallIdentifier::Hash Hash; };
    8082
    8183    template<> struct HashTraits<JSC::CallIdentifier> : GenericHashTraits<JSC::CallIdentifier> {
  • trunk/JavaScriptCore/profiler/HeavyProfile.cpp

    r36263 r42808  
    1 /*
    2  * Copyright (C) 2008 Apple Inc. All Rights Reserved.
    3  *
    4  * Redistribution and use in source and binary forms, with or without
    5  * modification, are permitted provided that the following conditions
    6  * are met:
    7  * 1. Redistributions of source code must retain the above copyright
    8  *    notice, this list of conditions and the following disclaimer.
    9  * 2. Redistributions in binary form must reproduce the above copyright
    10  *    notice, this list of conditions and the following disclaimer in the
    11  *    documentation and/or other materials provided with the distribution.
    12  *
    13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
    14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
    17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
    21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    24  */
    25 
    26 #include "config.h"
    27 #include "HeavyProfile.h"
    28 
    29 #include "TreeProfile.h"
    30 
    31 namespace JSC {
    32 
    33 HeavyProfile::HeavyProfile(TreeProfile* treeProfile)
    34     : Profile(treeProfile->title(), treeProfile->uid())
    35 {
    36     m_treeProfile = treeProfile;
    37     head()->setTotalTime(m_treeProfile->head()->actualTotalTime());
    38     head()->setSelfTime(m_treeProfile->head()->actualSelfTime());
    39     generateHeavyStructure();
    40 }
    41 
    42 void HeavyProfile::generateHeavyStructure()
    43 {
    44     ProfileNode* treeHead = m_treeProfile->head();
    45     ProfileNode* currentNode = treeHead->firstChild();
    46     for (ProfileNode* nextNode = currentNode; nextNode; nextNode = nextNode->firstChild())
    47         currentNode = nextNode;
    48 
    49     // For each node
    50     HashMap<CallIdentifier, ProfileNode*> foundChildren;
    51     while (currentNode && currentNode != treeHead) {
    52         ProfileNode* child = foundChildren.get(currentNode->callIdentifier());
    53         if (child) // currentNode is in the set already
    54             mergeProfiles(child, currentNode);
    55         else { // currentNode is not in the set
    56             child = addNode(currentNode);
    57             foundChildren.set(currentNode->callIdentifier(), child);
    58         }
    59 
    60         currentNode = currentNode->traverseNextNodePostOrder();
    61     }
    62 }
    63 
    64 ProfileNode* HeavyProfile::addNode(ProfileNode* currentNode)
    65 {
    66     RefPtr<ProfileNode> node = ProfileNode::create(head(), currentNode);
    67     head()->addChild(node);
    68 
    69     addAncestorsAsChildren(currentNode->parent(), node.get());
    70     return node.get();
    71 }
    72 
    73 void HeavyProfile::mergeProfiles(ProfileNode* heavyProfileHead, ProfileNode* treeProfileHead)
    74 {
    75     ASSERT_ARG(heavyProfileHead, heavyProfileHead);
    76     ASSERT_ARG(treeProfileHead, treeProfileHead);
    77 
    78     ProfileNode* currentTreeNode = treeProfileHead;
    79     ProfileNode* currentHeavyNode = heavyProfileHead;
    80     ProfileNode* previousHeavyNode = 0;
    81    
    82     while (currentHeavyNode) {
    83         previousHeavyNode = currentHeavyNode;
    84 
    85         currentHeavyNode->setTotalTime(currentHeavyNode->actualTotalTime() + currentTreeNode->actualTotalTime());
    86         currentHeavyNode->setSelfTime(currentHeavyNode->actualSelfTime() + currentTreeNode->actualSelfTime());
    87         currentHeavyNode->setNumberOfCalls(currentHeavyNode->numberOfCalls() + currentTreeNode->numberOfCalls());
    88 
    89         currentTreeNode = currentTreeNode->parent();
    90         currentHeavyNode = currentHeavyNode->findChild(currentTreeNode);
    91     }
    92 
    93     // If currentTreeNode is null then we already have the whole tree we wanted to copy.
    94     // If not we need to copy the subset of the tree that remains different between the two.
    95     if (currentTreeNode)
    96         addAncestorsAsChildren(currentTreeNode, previousHeavyNode);
    97 }
    98 
    99 void HeavyProfile::addAncestorsAsChildren(ProfileNode* getFrom, ProfileNode* addTo)
    100 {
    101     ASSERT_ARG(getFrom, getFrom);
    102     ASSERT_ARG(addTo, addTo);
    103 
    104     if (!getFrom->head())
    105         return;
    106 
    107     RefPtr<ProfileNode> currentNode = addTo;
    108     for (ProfileNode* treeAncestor = getFrom; treeAncestor && treeAncestor != getFrom->head(); treeAncestor = treeAncestor->parent()) {
    109         RefPtr<ProfileNode> newChild = ProfileNode::create(currentNode->head(), treeAncestor);
    110         currentNode->addChild(newChild);
    111         currentNode = newChild.release();
    112     }
    113 }
    114 
    115 }   // namespace JSC
  • trunk/JavaScriptCore/profiler/HeavyProfile.h

    r37433 r42808  
    1 /*
    2  * Copyright (C) 2008 Apple Inc. All Rights Reserved.
    3  *
    4  * Redistribution and use in source and binary forms, with or without
    5  * modification, are permitted provided that the following conditions
    6  * are met:
    7  * 1. Redistributions of source code must retain the above copyright
    8  *    notice, this list of conditions and the following disclaimer.
    9  * 2. Redistributions in binary form must reproduce the above copyright
    10  *    notice, this list of conditions and the following disclaimer in the
    11  *    documentation and/or other materials provided with the distribution.
    12  *
    13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
    14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
    17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
    21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    24  */
    25  
    26 #ifndef HeavyProfile_h
    27 #define HeavyProfile_h
    28 
    29 #include "Profile.h"
    30 #include "ProfileNode.h"
    31 #include "TreeProfile.h"
    32 
    33 namespace JSC {
    34 
    35     class UString;
    36 
    37     class HeavyProfile : public Profile {
    38     public:
    39         static PassRefPtr<HeavyProfile> create(TreeProfile* treeProfile)
    40         {
    41             return adoptRef(new HeavyProfile(treeProfile));
    42         }
    43 
    44         virtual Profile* heavyProfile() { return this; }
    45         virtual Profile* treeProfile()
    46         {
    47             return m_treeProfile;
    48         }
    49 
    50 
    51     private:
    52         HeavyProfile(TreeProfile*);
    53         void generateHeavyStructure();
    54         ProfileNode* addNode(ProfileNode*);
    55         void mergeProfiles(ProfileNode* heavyProfileHead, ProfileNode* treeProfileHead);
    56         void addAncestorsAsChildren(ProfileNode* getFrom, ProfileNode* addTo);
    57 
    58         TreeProfile* m_treeProfile;
    59     };
    60 
    61 } // namespace JSC
    62 
    63 #endif // HeavyProfile_h
  • trunk/JavaScriptCore/profiler/Profile.cpp

    r36263 r42808  
    2828
    2929#include "ProfileNode.h"
    30 #include "TreeProfile.h"
    3130#include <stdio.h>
    3231
     
    3534PassRefPtr<Profile> Profile::create(const UString& title, unsigned uid)
    3635{
    37     return TreeProfile::create(title, uid);
     36    return adoptRef(new Profile(title, uid));
    3837}
    3938
  • trunk/JavaScriptCore/profiler/Profile.h

    r38137 r42808  
    4646
    4747        void forEach(void (ProfileNode::*)());
    48         void sortTotalTimeDescending() { forEach(&ProfileNode::sortTotalTimeDescending); }
    49         void sortTotalTimeAscending() { forEach(&ProfileNode::sortTotalTimeAscending); }
    50         void sortSelfTimeDescending() { forEach(&ProfileNode::sortSelfTimeDescending); }
    51         void sortSelfTimeAscending() { forEach(&ProfileNode::sortSelfTimeAscending); }
    52         void sortCallsDescending() { forEach(&ProfileNode::sortCallsDescending); }
    53         void sortCallsAscending() { forEach(&ProfileNode::sortCallsAscending); }
    54         void sortFunctionNameDescending() { forEach(&ProfileNode::sortFunctionNameDescending); }
    55         void sortFunctionNameAscending() { forEach(&ProfileNode::sortFunctionNameAscending); }
    5648
    5749        void focus(const ProfileNode*);
    5850        void exclude(const ProfileNode*);
    5951        void restoreAll();
    60 
    61         virtual Profile* heavyProfile() = 0;
    62         virtual Profile* treeProfile() = 0;
    6352
    6453#ifndef NDEBUG
  • trunk/JavaScriptCore/profiler/ProfileNode.cpp

    r36263 r42808  
    205205}
    206206
    207 void ProfileNode::sort(bool comparator(const RefPtr<ProfileNode>& , const RefPtr<ProfileNode>& ))
    208 {
    209     std::sort(childrenBegin(), childrenEnd(), comparator);   
    210     resetChildrensSiblings();
    211 }
    212 
    213207void ProfileNode::setTreeVisible(ProfileNode* node, bool visible)
    214208{
  • trunk/JavaScriptCore/profiler/ProfileNode.h

    r36263 r42808  
    113113        ProfileNode* traverseNextNodePreOrder(bool processChildren = true) const;
    114114
    115         void sort(bool (*)(const RefPtr<ProfileNode>&, const RefPtr<ProfileNode>&));
    116         void sortTotalTimeDescending() { sort(totalTimeDescendingComparator); }
    117         void sortTotalTimeAscending() { sort(totalTimeAscendingComparator); }
    118         void sortSelfTimeDescending() { sort(selfTimeDescendingComparator); }
    119         void sortSelfTimeAscending() { sort(selfTimeAscendingComparator); }
    120         void sortCallsDescending() { sort(callsDescendingComparator); }
    121         void sortCallsAscending() { sort(callsAscendingComparator); }
    122         void sortFunctionNameDescending() { sort(functionNameDescendingComparator); }
    123         void sortFunctionNameAscending() { sort(functionNameAscendingComparator); }
    124 
    125115        // Views
    126116        void calculateVisibleTotalTime();
  • trunk/JavaScriptCore/profiler/TreeProfile.cpp

    r36263 r42808  
    1 /*
    2  * Copyright (C) 2008 Apple Inc. All Rights Reserved.
    3  *
    4  * Redistribution and use in source and binary forms, with or without
    5  * modification, are permitted provided that the following conditions
    6  * are met:
    7  * 1. Redistributions of source code must retain the above copyright
    8  *    notice, this list of conditions and the following disclaimer.
    9  * 2. Redistributions in binary form must reproduce the above copyright
    10  *    notice, this list of conditions and the following disclaimer in the
    11  *    documentation and/or other materials provided with the distribution.
    12  *
    13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
    14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
    17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
    21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    24  */
    25 
    26 #include "config.h"
    27 #include "TreeProfile.h"
    28 
    29 #include "HeavyProfile.h"
    30 
    31 namespace JSC {
    32 
    33 PassRefPtr<TreeProfile> TreeProfile::create(const UString& title, unsigned uid)
    34 {
    35     return adoptRef(new TreeProfile(title, uid));
    36 }
    37 
    38 TreeProfile::TreeProfile(const UString& title, unsigned uid)
    39     : Profile(title, uid)
    40 {
    41 }
    42 
    43 Profile* TreeProfile::heavyProfile()
    44 {
    45     if (!m_heavyProfile)
    46         m_heavyProfile = HeavyProfile::create(this);
    47 
    48     return m_heavyProfile.get();
    49 }
    50 
    51 } // namespace JSC
  • trunk/JavaScriptCore/profiler/TreeProfile.h

    r36263 r42808  
    1 /*
    2  * Copyright (C) 2008 Apple Inc. All Rights Reserved.
    3  *
    4  * Redistribution and use in source and binary forms, with or without
    5  * modification, are permitted provided that the following conditions
    6  * are met:
    7  * 1. Redistributions of source code must retain the above copyright
    8  *    notice, this list of conditions and the following disclaimer.
    9  * 2. Redistributions in binary form must reproduce the above copyright
    10  *    notice, this list of conditions and the following disclaimer in the
    11  *    documentation and/or other materials provided with the distribution.
    12  *
    13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
    14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
    17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
    21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    24  */
    25  
    26 #ifndef TreeProfile_h
    27 #define TreeProfile_h
    28 
    29 #include "Profile.h"
    30 
    31 namespace JSC {
    32 
    33     class ExecState;
    34     class HeavyProfile;
    35     class UString;
    36 
    37     class TreeProfile : public Profile {
    38     public:
    39         static PassRefPtr<TreeProfile> create(const UString& title, unsigned uid);
    40 
    41         virtual Profile* heavyProfile();
    42         virtual Profile* treeProfile() { return this; }
    43 
    44     private:
    45         TreeProfile(const UString& title, unsigned uid);
    46         RefPtr<HeavyProfile> m_heavyProfile;
    47     };
    48 
    49 } // namespace JSC
    50 
    51 #endif // TreeProfiler_h
Note: See TracChangeset for help on using the changeset viewer.