JavaScriptCore/profiler/Profile.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     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 "Profile.h"
       
    28 
       
    29 #include "ProfileNode.h"
       
    30 #include <stdio.h>
       
    31 
       
    32 namespace JSC {
       
    33 
       
    34 PassRefPtr<Profile> Profile::create(const UString& title, unsigned uid)
       
    35 {
       
    36     return adoptRef(new Profile(title, uid));
       
    37 }
       
    38 
       
    39 Profile::Profile(const UString& title, unsigned uid)
       
    40     : m_title(title)
       
    41     , m_uid(uid)
       
    42 {
       
    43     // FIXME: When multi-threading is supported this will be a vector and calls
       
    44     // into the profiler will need to know which thread it is executing on.
       
    45     m_head = ProfileNode::create(CallIdentifier("Thread_1", UString(), 0), 0, 0);
       
    46 }
       
    47 
       
    48 Profile::~Profile()
       
    49 {
       
    50 }
       
    51 
       
    52 void Profile::forEach(void (ProfileNode::*function)())
       
    53 {
       
    54     ProfileNode* currentNode = m_head->firstChild();
       
    55     for (ProfileNode* nextNode = currentNode; nextNode; nextNode = nextNode->firstChild())
       
    56         currentNode = nextNode;
       
    57 
       
    58     if (!currentNode)
       
    59         currentNode = m_head.get();
       
    60 
       
    61     ProfileNode* endNode = m_head->traverseNextNodePostOrder();
       
    62     while (currentNode && currentNode != endNode) {
       
    63         (currentNode->*function)();
       
    64         currentNode = currentNode->traverseNextNodePostOrder();
       
    65     } 
       
    66 }
       
    67 
       
    68 void Profile::focus(const ProfileNode* profileNode)
       
    69 {
       
    70     if (!profileNode || !m_head)
       
    71         return;
       
    72 
       
    73     bool processChildren;
       
    74     const CallIdentifier& callIdentifier = profileNode->callIdentifier();
       
    75     for (ProfileNode* currentNode = m_head.get(); currentNode; currentNode = currentNode->traverseNextNodePreOrder(processChildren))
       
    76         processChildren = currentNode->focus(callIdentifier);
       
    77 
       
    78     // Set the visible time of all nodes so that the %s display correctly.
       
    79     forEach(&ProfileNode::calculateVisibleTotalTime);
       
    80 }
       
    81 
       
    82 void Profile::exclude(const ProfileNode* profileNode)
       
    83 {
       
    84     if (!profileNode || !m_head)
       
    85         return;
       
    86 
       
    87     const CallIdentifier& callIdentifier = profileNode->callIdentifier();
       
    88 
       
    89     for (ProfileNode* currentNode = m_head.get(); currentNode; currentNode = currentNode->traverseNextNodePreOrder())
       
    90         currentNode->exclude(callIdentifier);
       
    91 
       
    92     // Set the visible time of the head so the %s display correctly.
       
    93     m_head->setVisibleTotalTime(m_head->totalTime() - m_head->selfTime());
       
    94     m_head->setVisibleSelfTime(0.0);
       
    95 }
       
    96 
       
    97 void Profile::restoreAll()
       
    98 {
       
    99     forEach(&ProfileNode::restore);
       
   100 }
       
   101 
       
   102 #ifndef NDEBUG
       
   103 void Profile::debugPrintData() const
       
   104 {
       
   105     printf("Call graph:\n");
       
   106     m_head->debugPrintData(0);
       
   107 }
       
   108 
       
   109 typedef pair<UString::Rep*, unsigned> NameCountPair;
       
   110 
       
   111 static inline bool functionNameCountPairComparator(const NameCountPair& a, const NameCountPair& b)
       
   112 {
       
   113     return a.second > b.second;
       
   114 }
       
   115 
       
   116 void Profile::debugPrintDataSampleStyle() const
       
   117 {
       
   118     typedef Vector<NameCountPair> NameCountPairVector;
       
   119 
       
   120     FunctionCallHashCount countedFunctions;
       
   121     printf("Call graph:\n");
       
   122     m_head->debugPrintDataSampleStyle(0, countedFunctions);
       
   123 
       
   124     printf("\nTotal number in stack:\n");
       
   125     NameCountPairVector sortedFunctions(countedFunctions.size());
       
   126     copyToVector(countedFunctions, sortedFunctions);
       
   127 
       
   128     std::sort(sortedFunctions.begin(), sortedFunctions.end(), functionNameCountPairComparator);
       
   129     for (NameCountPairVector::iterator it = sortedFunctions.begin(); it != sortedFunctions.end(); ++it)
       
   130         printf("        %-12d%s\n", (*it).second, UString((*it).first).UTF8String().data());
       
   131 
       
   132     printf("\nSort by top of stack, same collapsed (when >= 5):\n");
       
   133 }
       
   134 #endif
       
   135 
       
   136 } // namespace JSC