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(0, 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<StringImpl*, 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).utf8().data()); 131 132 printf("\nSort by top of stack, same collapsed (when >= 5):\n"); 133 } 134 #endif 135 136 } // namespace JSC 137