Changeset 173199 in webkit for trunk/Source/JavaScriptCore
- Timestamp:
- Sep 2, 2014, 9:58:55 PM (11 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r173198 r173199 1 2014-09-02 Brian J. Burg <[email protected]> 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 1 77 2014-09-02 Brian J. Burg <[email protected]> 2 78 -
trunk/Source/JavaScriptCore/jit/JIT.h
r172820 r173199 45 45 #include "JITInlineCacheGenerator.h" 46 46 #include "JSInterfaceJIT.h" 47 #include "LegacyProfiler.h"48 47 #include "Opcode.h" 49 48 #include "ResultType.h" -
trunk/Source/JavaScriptCore/jit/JITCode.h
r163027 r173199 32 32 #include "JITStubs.h" 33 33 #include "JSCJSValue.h" 34 #include "LegacyProfiler.h"35 34 #include "MacroAssemblerCodeRef.h" 36 35 #include "RegisterPreservationMode.h" -
trunk/Source/JavaScriptCore/jit/JITOperations.cpp
r173188 r173199 44 44 #include "JIT.h" 45 45 #include "JITToDFGDeferredCompilationCallback.h" 46 #include "JSCInlines.h" 46 47 #include "JSGlobalObjectFunctions.h" 47 48 #include "JSNameScope.h" … … 49 50 #include "JSStackInlines.h" 50 51 #include "JSWithScope.h" 52 #include "LegacyProfiler.h" 51 53 #include "ObjectConstructor.h" 52 #include "JSCInlines.h"53 54 #include "Repatch.h" 54 55 #include "RepatchBuffer.h" -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
r173188 r173199 26 26 #include "config.h" 27 27 #include "LLIntSlowPaths.h" 28 28 29 #include "Arguments.h" 29 30 #include "ArrayConstructor.h" … … 39 40 #include "JITExceptions.h" 40 41 #include "JSActivation.h" 42 #include "JSCInlines.h" 41 43 #include "JSCJSValue.h" 42 44 #include "JSGlobalObjectFunctions.h" … … 47 49 #include "LLIntCommon.h" 48 50 #include "LLIntExceptions.h" 51 #include "LegacyProfiler.h" 49 52 #include "LowLevelInterpreter.h" 50 53 #include "ObjectConstructor.h" 51 #include "JSCInlines.h"52 54 #include "ProtoCallFrame.h" 53 55 #include "StructureRareDataInlines.h" -
trunk/Source/JavaScriptCore/profiler/Profile.cpp
r173120 r173199 40 40 : m_title(title) 41 41 , m_uid(uid) 42 , m_idleTime(0)43 42 { 44 43 // FIXME: When multi-threading is supported this will be a vector and calls 45 44 // 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); 47 46 } 48 47 … … 51 50 } 52 51 53 void Profile::forEach(void (ProfileNode::*function)()) 52 #ifndef NDEBUG 53 void Profile::debugPrint() 54 54 { 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(); 58 58 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 NDEBUG70 void Profile::debugPrintData() const71 {72 59 dataLogF("Call graph:\n"); 73 m_ head->debugPrintData(0);60 m_rootNode->debugPrintRecursively(0, data); 74 61 } 75 62 … … 81 68 } 82 69 83 void Profile::debugPrint DataSampleStyle() const70 void Profile::debugPrintSampleStyle() 84 71 { 85 72 typedef Vector<NameCountPair> NameCountPairVector; 86 73 74 CalculateProfileSubtreeDataFunctor functor; 75 m_rootNode->forEachNodePostorder(functor); 76 ProfileNode::ProfileSubtreeData data = functor.returnValue(); 77 87 78 FunctionCallHashCount countedFunctions; 88 79 dataLogF("Call graph:\n"); 89 m_ head->debugPrintDataSampleStyle(0, countedFunctions);80 m_rootNode->debugPrintSampleStyleRecursively(0, countedFunctions, data); 90 81 91 82 dataLogF("\nTotal number in stack:\n"); -
trunk/Source/JavaScriptCore/profiler/Profile.h
r167530 r173199 42 42 unsigned uid() const { return m_uid; } 43 43 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; } 53 46 54 47 #ifndef NDEBUG 55 void debugPrint Data() const;56 void debugPrint DataSampleStyle() const;48 void debugPrint(); 49 void debugPrintSampleStyle(); 57 50 #endif 58 51 … … 65 58 66 59 String m_title; 67 RefPtr<ProfileNode> m_ head;60 RefPtr<ProfileNode> m_rootNode; 68 61 unsigned m_uid; 69 double m_idleTime;70 62 }; 71 63 -
trunk/Source/JavaScriptCore/profiler/ProfileGenerator.cpp
r173162 r173199 51 51 { 52 52 m_profile = Profile::create(title, uid); 53 m_currentNode = m_ head = m_profile->head();53 m_currentNode = m_rootNode = m_profile->rootNode(); 54 54 if (exec) 55 55 addParentForConsoleStart(exec); … … 58 58 class AddParentForConsoleStartFunctor { 59 59 public: 60 AddParentForConsoleStartFunctor(ExecState* exec, RefPtr<ProfileNode>& head, RefPtr<ProfileNode>& currentNode)60 AddParentForConsoleStartFunctor(ExecState* exec, RefPtr<ProfileNode>& rootNode, RefPtr<ProfileNode>& currentNode) 61 61 : m_exec(exec) 62 62 , m_hasSkippedFirstFrame(false) 63 63 , m_foundParent(false) 64 , m_ head(head)64 , m_rootNode(rootNode) 65 65 , m_currentNode(currentNode) 66 66 { … … 79 79 unsigned column = 0; 80 80 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()); 83 83 84 84 m_foundParent = true; … … 89 89 ExecState* m_exec; 90 90 bool m_hasSkippedFirstFrame; 91 bool m_foundParent; 92 RefPtr<ProfileNode>& m_ head;91 bool m_foundParent; 92 RefPtr<ProfileNode>& m_rootNode; 93 93 RefPtr<ProfileNode>& m_currentNode; 94 94 }; … … 96 96 void ProfileGenerator::addParentForConsoleStart(ExecState* exec) 97 97 { 98 AddParentForConsoleStartFunctor functor(exec, m_ head, m_currentNode);98 AddParentForConsoleStartFunctor functor(exec, m_rootNode, m_currentNode); 99 99 exec->iterate(functor); 100 100 … … 135 135 ASSERT(m_currentNode); 136 136 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()); 138 138 returningNode->lastCall().setStartTime(m_currentNode->lastCall().startTime()); 139 139 returningNode->didExecute(); … … 156 156 } 157 157 158 struct StopProfilingFunctor { 159 void operator()(ProfileNode* node) { node->stopProfiling(); } 160 }; 161 158 162 void ProfileGenerator::stopProfiling() 159 163 { 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); 161 168 162 169 if (m_foundConsoleStartParent) { … … 170 177 // will not get didExecute call. 171 178 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 }177 179 } 178 180 … … 181 183 { 182 184 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()) 184 186 currentNode = next; 185 187 … … 187 189 return; 188 190 189 // Attribute the time of the node aobut to be removed to the self time of its parent190 currentNode->parent()->setSelfTime(currentNode->parent()->selfTime() + currentNode->totalTime());191 191 currentNode->parent()->removeChild(currentNode); 192 192 } … … 196 196 { 197 197 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()) 199 199 currentNode = next; 200 200 201 201 if (currentNode->callIdentifier().functionName() != "profileEnd") 202 202 return; 203 204 // Attribute the time of the node aobut to be removed to the self time of its parent205 currentNode->parent()->setSelfTime(currentNode->parent()->selfTime() + currentNode->totalTime());206 203 207 204 ASSERT(currentNode->callIdentifier() == (currentNode->parent()->children()[currentNode->parent()->children().size() - 1])->callIdentifier()); -
trunk/Source/JavaScriptCore/profiler/ProfileGenerator.h
r163140 r173199 23 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 24 */ 25 25 26 26 #ifndef ProfileGenerator_h 27 27 #define ProfileGenerator_h … … 38 38 class Profile; 39 39 class ProfileNode; 40 struct CallIdentifier; 40 struct CallIdentifier; 41 41 42 42 class ProfileGenerator : public RefCounted<ProfileGenerator> { … … 71 71 JSGlobalObject* m_origin; 72 72 unsigned m_profileGroup; 73 RefPtr<ProfileNode> m_ head;73 RefPtr<ProfileNode> m_rootNode; 74 74 RefPtr<ProfileNode> m_currentNode; 75 75 bool m_foundConsoleStartParent; -
trunk/Source/JavaScriptCore/profiler/ProfileNode.cpp
r165676 r173199 39 39 namespace JSC { 40 40 41 ProfileNode::ProfileNode(ExecState* callerCallFrame, const CallIdentifier& callIdentifier, ProfileNode* headNode, ProfileNode*parentNode)41 ProfileNode::ProfileNode(ExecState* callerCallFrame, const CallIdentifier& callIdentifier, ProfileNode* parentNode) 42 42 : m_callerCallFrame(callerCallFrame) 43 43 , m_callIdentifier(callIdentifier) 44 , m_head(headNode)45 44 , m_parent(parentNode) 46 45 , m_nextSibling(nullptr) 47 , m_totalTime(0)48 , m_selfTime(0)49 46 { 50 47 startTimer(); 51 48 } 52 49 53 ProfileNode::ProfileNode(ExecState* callerCallFrame, ProfileNode* headNode, ProfileNode*nodeToCopy)50 ProfileNode::ProfileNode(ExecState* callerCallFrame, ProfileNode* nodeToCopy) 54 51 : m_callerCallFrame(callerCallFrame) 55 52 , m_callIdentifier(nodeToCopy->callIdentifier()) 56 , m_head(headNode)57 53 , m_parent(nodeToCopy->parent()) 58 , m_nextSibling(0) 59 , m_totalTime(nodeToCopy->totalTime()) 60 , m_selfTime(nodeToCopy->selfTime()) 54 , m_nextSibling(nullptr) 61 55 , m_calls(nodeToCopy->calls()) 62 56 { … … 72 66 } 73 67 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); 75 69 if (m_children.size()) 76 70 m_children.last()->setNextSibling(newChild.get()); … … 105 99 } 106 100 } 107 101 108 102 resetChildrensSiblings(); 109 103 } … … 126 120 if (isnan(m_calls.last().totalTime())) 127 121 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;135 122 } 136 123 … … 151 138 152 139 last.setTotalTime(currentTime() - last.startTime()); 153 154 m_totalTime += last.totalTime();155 140 } 156 141 … … 168 153 169 154 #ifndef NDEBUG 170 void ProfileNode::debugPrintData(int indentLevel) const 155 void ProfileNode::debugPrint() 156 { 157 CalculateProfileSubtreeDataFunctor functor; 158 forEachNodePostorder(functor); 159 ProfileNode::ProfileSubtreeData data = functor.returnValue(); 160 161 debugPrintRecursively(0, data); 162 } 163 164 void 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 175 void ProfileNode::debugPrintRecursively(int indentLevel, const ProfileSubtreeData& data) 171 176 { 172 177 // Print function names … … 174 179 dataLogF(" "); 175 180 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 176 188 dataLogF("Function Name %s %zu SelfTime %.3fms/%.3f%% TotalTime %.3fms/%.3f%% Next Sibling %s\n", 177 189 functionName().utf8().data(), 178 numberOfCalls(), m_selfTime, selfPercent(), m_totalTime, totalPercent(),190 numberOfCalls(), nodeSelfTime, nodeSelfTime / rootTotalTime * 100.0, nodeTotalTime, nodeTotalTime / rootTotalTime * 100.0, 179 191 m_nextSibling ? m_nextSibling->functionName().utf8().data() : ""); 180 192 … … 183 195 // Print children's names and information 184 196 for (StackIterator currentChild = m_children.begin(); currentChild != m_children.end(); ++currentChild) 185 (*currentChild)->debugPrint Data(indentLevel);197 (*currentChild)->debugPrintRecursively(indentLevel, data); 186 198 } 187 199 188 200 // print the profiled data in a format that matches the tool sample's output. 189 double ProfileNode::debugPrint DataSampleStyle(int indentLevel, FunctionCallHashCount& countedFunctions) const201 double ProfileNode::debugPrintSampleStyleRecursively(int indentLevel, FunctionCallHashCount& countedFunctions, const ProfileSubtreeData& data) 190 202 { 191 203 dataLogF(" "); 204 205 auto it = data.selfAndTotalTimes.find(this); 206 ASSERT(it != data.selfAndTotalTimes.end()); 207 double nodeTotalTime = it->value.second; 192 208 193 209 // Print function names 194 210 const char* name = functionName().utf8().data(); 195 double sampleCount = m_totalTime * 1000;211 double sampleCount = nodeTotalTime * 1000; 196 212 if (indentLevel) { 197 213 for (int i = 0; i < indentLevel; ++i) … … 209 225 double sumOfChildrensCount = 0.0; 210 226 for (StackIterator currentChild = m_children.begin(); currentChild != m_children.end(); ++currentChild) 211 sumOfChildrensCount += (*currentChild)->debugPrint DataSampleStyle(indentLevel, countedFunctions);227 sumOfChildrensCount += (*currentChild)->debugPrintSampleStyleRecursively(indentLevel, countedFunctions, data); 212 228 213 229 sumOfChildrensCount *= 1000; // … … 221 237 } 222 238 223 return m_totalTime;239 return nodeTotalTime; 224 240 } 225 241 #endif -
trunk/Source/JavaScriptCore/profiler/ProfileNode.h
r165676 r173199 45 45 class ProfileNode : public RefCounted<ProfileNode> { 46 46 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) 48 48 { 49 return adoptRef(new ProfileNode(callerCallFrame, callIdentifier, headNode,parentNode));49 return adoptRef(new ProfileNode(callerCallFrame, callIdentifier, parentNode)); 50 50 } 51 51 52 static PassRefPtr<ProfileNode> create(ExecState* callerCallFrame, ProfileNode* headNode, ProfileNode*node)52 static PassRefPtr<ProfileNode> create(ExecState* callerCallFrame, ProfileNode* node) 53 53 { 54 return adoptRef(new ProfileNode(callerCallFrame, headNode,node));54 return adoptRef(new ProfileNode(callerCallFrame, node)); 55 55 } 56 56 … … 91 91 92 92 // Relationships 93 ProfileNode* head() const { return m_head; }94 void setHead(ProfileNode* head) { m_head = head; }95 96 93 ProfileNode* parent() const { return m_parent; } 97 94 void setParent(ProfileNode* parent) { m_parent = parent; } … … 100 97 void setNextSibling(ProfileNode* nextSibling) { m_nextSibling = nextSibling; } 101 98 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; } 113 100 Call& lastCall() { ASSERT(!m_calls.isEmpty()); return m_calls.last(); } 114 101 size_t numberOfCalls() const { return m_calls.size(); } … … 122 109 void insertNode(PassRefPtr<ProfileNode> prpNode); 123 110 124 ProfileNode* traverseNextNodePostOrder() const;111 template <typename Functor> void forEachNodePostorder(Functor&); 125 112 126 113 #ifndef NDEBUG 114 struct ProfileSubtreeData { 115 HashMap<ProfileNode*, std::pair<double, double>> selfAndTotalTimes; 116 double rootTotalTime; 117 }; 118 127 119 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&); 130 127 #endif 131 128 … … 133 130 typedef Vector<RefPtr<ProfileNode>>::const_iterator StackIterator; 134 131 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); 137 134 138 135 void startTimer(); 139 136 void resetChildrensSiblings(); 140 137 void endAndRecordCall(); 138 ProfileNode* traverseNextNodePostOrder() const; 141 139 142 140 ExecState* m_callerCallFrame; 143 141 CallIdentifier m_callIdentifier; 144 ProfileNode* m_head;145 142 ProfileNode* m_parent; 146 143 ProfileNode* m_nextSibling; 147 144 148 double m_totalTime; 149 double m_selfTime; 150 151 Vector<Call, 1> m_calls; 145 Vector<Call> m_calls; 152 146 Vector<RefPtr<ProfileNode>> m_children; 153 147 }; 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 154 189 155 190 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/ConsoleClient.h
r167530 r173199 28 28 29 29 #include "ConsoleTypes.h" 30 #include "Profile.h"31 30 #include <wtf/Forward.h> 32 31
Note:
See TracChangeset
for help on using the changeset viewer.