Changeset 32760 in webkit for trunk/JavaScriptCore
- Timestamp:
- May 1, 2008, 9:32:32 AM (17 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 1 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r32712 r32760 1 2008-05-01 Kevin McCullough <[email protected]> 2 3 Reviewed by Darin. 4 5 <rdar://problem/5770054> JavaScript profiler (10928) 6 - Fix "sample" output so that it can be imported into Instruments 7 - Also keep track of number of times a function is profiled. 8 9 * JavaScriptCore.xcodeproj/project.pbxproj: Add StrHash.h which needed 10 to be pulled out of identifier.cpp so that it could be used by the 11 profiler and identifiers. 12 * kjs/identifier.cpp: Ditto. 13 * profiler/FunctionCallProfile.cpp: 14 (KJS::FunctionCallProfile::printDataInspectorStyle): Inspector style 15 printing should show microseconds. 16 (KJS::FunctionCallProfile::printDataSampleStyle): Sample style printing 17 now counts the number of times a function is in the stack tree and does 18 not print microseconds since that does not make sense for a sampler. 19 * profiler/FunctionCallProfile.h: Keep track of number of times a 20 function is profiled. 21 (KJS::FunctionCallProfile::numberOfCalls): 22 * profiler/Profiler.cpp: 23 (KJS::functionNameCountPairComparator): Comparator for sort function in 24 printDataSampleStyle. 25 (KJS::Profiler::printDataSampleStyle): Print the number of times that a 26 function is listed in the stack tree in order of most times listed. 27 * wtf/HashCountedSet.h: Added copyToVector since it didn't exist and is 28 a more standard way to copy a HashSet to a Vector. I added on variant 29 that takes a pair as the Vector's type and so the HashCountedSet simply 30 fills in that pair with its internal pair, and another variant that 31 takes a Vector of the type of the HashCountedSet and only fills in the 32 Vector with the first element of the pair. 33 (WTF::copyToVector): 34 * wtf/StrHash.h: Added. 35 (WTF::): 36 1 37 2008-04-29 David Kilzer <[email protected]> 2 38 -
trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r32587 r32760 186 186 93E26BFE08B151D400F85226 /* ucpinternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 93E26BFC08B151D400F85226 /* ucpinternal.h */; }; 187 187 93F0B3AC09BB4DC00068FCE3 /* Parser.h in Headers */ = {isa = PBXBuildFile; fileRef = 93F0B3AA09BB4DC00068FCE3 /* Parser.h */; settings = {ATTRIBUTES = (Private, ); }; }; 188 958D85830DC93230008ABF27 /* StrHash.h in Headers */ = {isa = PBXBuildFile; fileRef = 958D85820DC93230008ABF27 /* StrHash.h */; }; 188 189 95AB83420DA4322500BC83F3 /* Profiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95AB832E0DA42CAD00BC83F3 /* Profiler.cpp */; }; 189 190 95AB83480DA432EB00BC83F3 /* Profiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 95AB832F0DA42CAD00BC83F3 /* Profiler.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 493 494 93F0B3AA09BB4DC00068FCE3 /* Parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Parser.h; sourceTree = "<group>"; }; 494 495 93F1981A08245AAE001E9ABC /* keywords.table */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = text; path = keywords.table; sourceTree = "<group>"; tabWidth = 8; }; 496 958D85820DC93230008ABF27 /* StrHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StrHash.h; sourceTree = "<group>"; }; 495 497 95AB832E0DA42CAD00BC83F3 /* Profiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Profiler.cpp; path = profiler/Profiler.cpp; sourceTree = "<group>"; }; 496 498 95AB832F0DA42CAD00BC83F3 /* Profiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Profiler.h; path = profiler/Profiler.h; sourceTree = "<group>"; }; … … 821 823 6592C316098B7DE10003D4F6 /* Vector.h */, 822 824 6592C317098B7DE10003D4F6 /* VectorTraits.h */, 825 958D85820DC93230008ABF27 /* StrHash.h */, 823 826 ); 824 827 path = wtf; … … 1141 1144 E1B7C8BE0DA3A3360074B0DC /* ThreadSpecific.h in Headers */, 1142 1145 06D358B20DAADA93003B174E /* MainThread.h in Headers */, 1146 958D85830DC93230008ABF27 /* StrHash.h in Headers */, 1143 1147 ); 1144 1148 runOnlyForDeploymentPostprocessing = 0; -
trunk/JavaScriptCore/kjs/identifier.cpp
r32222 r32760 29 29 #include <wtf/FastMalloc.h> 30 30 #include <wtf/HashSet.h> 31 //#include <wtf/StrHash.h> 31 32 #if USE(MULTIPLE_THREADS) 32 33 #include <wtf/ThreadSpecific.h> 33 34 using namespace WTF; 34 35 #endif 35 36 namespace WTF {37 38 template<typename T> struct DefaultHash;39 template<typename T> struct StrHash;40 41 template<> struct StrHash<KJS::UString::Rep *> {42 static unsigned hash(const KJS::UString::Rep *key) { return key->hash(); }43 static bool equal(const KJS::UString::Rep *a, const KJS::UString::Rep *b) { return KJS::Identifier::equal(a, b); }44 static const bool safeToCompareToEmptyOrDeleted = false;45 };46 47 template<> struct DefaultHash<KJS::UString::Rep *> {48 typedef StrHash<KJS::UString::Rep *> Hash;49 };50 51 }52 36 53 37 namespace KJS { -
trunk/JavaScriptCore/profiler/FunctionCallProfile.cpp
r32693 r32760 112 112 printf(" "); 113 113 114 printf("%. 0fms %s\n", m_timeSum, m_functionName.UTF8String().c_str());114 printf("%.3fms %s\n", m_timeSum, m_functionName.UTF8String().c_str()); 115 115 } else 116 116 printf("%s\n", m_functionName.UTF8String().c_str()); … … 124 124 125 125 // print the profiled data in a format that matches the tool sample's output. 126 double FunctionCallProfile::printDataSampleStyle(int indentLevel ) const126 double FunctionCallProfile::printDataSampleStyle(int indentLevel, FunctionCallHashCount& countedFunctions) const 127 127 { 128 128 printf(" "); 129 129 130 130 // Print function names 131 const char* name = m_functionName.UTF8String().c_str(); 132 double sampleCount = m_timeSum * 1000; 131 133 if (indentLevel) { 132 134 for (int i = 0; i < indentLevel; ++i) 133 135 printf(" "); 134 136 135 // We've previously asserted that m_timeSum will always be >= 1 136 printf("%.0f %s\n", m_timeSum ? m_timeSum : 1, m_functionName.UTF8String().c_str()); 137 countedFunctions.add(m_functionName.rep()); 138 139 printf("%.0f %s\n", sampleCount ? sampleCount : 1, name); 137 140 } else 138 printf("%s\n", m_functionName.UTF8String().c_str());141 printf("%s\n", name); 139 142 140 143 ++indentLevel; 141 144 142 145 // Print children's names and information 143 double sumOfChildrens Times= 0.0;146 double sumOfChildrensCount = 0.0; 144 147 for (StackIterator currentChild = m_children.begin(); currentChild != m_children.end(); ++currentChild) 145 sumOfChildrens Times += (*currentChild)->printDataSampleStyle(indentLevel);148 sumOfChildrensCount += (*currentChild)->printDataSampleStyle(indentLevel, countedFunctions); 146 149 147 // Print remainder of time to match sample's output 148 if (sumOfChildrensTimes < m_timeSum) { 150 sumOfChildrensCount *= 1000; // 151 // Print remainder of samples to match sample's output 152 if (sumOfChildrensCount < sampleCount) { 149 153 printf(" "); 150 154 while (indentLevel--) 151 155 printf(" "); 152 156 153 printf("% f %s\n", m_timeSum - sumOfChildrensTimes, m_functionName.UTF8String().c_str());157 printf("%.0f %s\n", sampleCount - sumOfChildrensCount, m_functionName.UTF8String().c_str()); 154 158 } 155 159 -
trunk/JavaScriptCore/profiler/FunctionCallProfile.h
r32693 r32760 32 32 #include <kjs/ustring.h> 33 33 #include <wtf/Deque.h> 34 #include <wtf/StrHash.h> 34 35 35 36 namespace KJS { … … 38 39 39 40 typedef Deque<FunctionCallProfile*>::const_iterator StackIterator; 41 typedef HashCountedSet<UString::Rep*> FunctionCallHashCount; 40 42 41 43 class FunctionCallProfile { … … 54 56 UString functionName() const { return m_functionName; } 55 57 double milliSecs() const { return m_timeSum; } 58 unsigned numberOfCalls() const { return m_numberOfCalls; } 56 59 57 60 void printDataInspectorStyle(int indentLevel) const; 58 double printDataSampleStyle(int indentLevel ) const;61 double printDataSampleStyle(int indentLevel, FunctionCallHashCount&) const; 59 62 60 63 private: -
trunk/JavaScriptCore/profiler/Profiler.cpp
r32495 r32760 178 178 } 179 179 180 typedef pair<UString::Rep*, unsigned> NameCountPair; 181 182 static inline bool functionNameCountPairComparator(const NameCountPair a, const NameCountPair b) 183 { 184 return a.second > b.second; 185 } 186 180 187 void Profiler::printDataSampleStyle() const 181 188 { 189 typedef Vector<NameCountPair> NameCountPairVector; 190 191 FunctionCallHashCount countedFunctions; 182 192 printf("Call graph:\n"); 183 m_callTree->printDataSampleStyle(0); 184 185 // FIXME: Since no one seems to understand this part of sample's output I will implement it when I have a better idea of what it's meant to be doing. 186 printf("\nTotal number in stack (recursive counted multiple, when >=5):\n"); 193 m_callTree->printDataSampleStyle(0, countedFunctions); 194 195 printf("\nTotal number in stack:\n"); 196 NameCountPairVector sortedFunctions(countedFunctions.size()); 197 copyToVector(countedFunctions, sortedFunctions); 198 199 std::sort(sortedFunctions.begin(), sortedFunctions.end(), functionNameCountPairComparator); 200 for (NameCountPairVector::iterator it = sortedFunctions.begin(); it != sortedFunctions.end(); ++it) 201 printf(" %-12d%s\n", (*it).second, UString((*it).first).UTF8String().c_str()); 202 187 203 printf("\nSort by top of stack, same collapsed (when >= 5):\n"); 188 204 } -
trunk/JavaScriptCore/wtf/HashCountedSet.h
r17127 r32760 26 26 #include "Assertions.h" 27 27 #include "HashMap.h" 28 #include "Vector.h" 28 29 29 30 namespace WTF { … … 171 172 m_impl.clear(); 172 173 } 174 175 template<typename Value, typename HashFunctions, typename Traits, typename VectorType> 176 inline void copyToVector(const HashCountedSet<Value, HashFunctions, Traits>& collection, VectorType& vector) 177 { 178 typedef typename HashCountedSet<Value, HashFunctions, Traits>::const_iterator iterator; 179 180 vector.resize(collection.size()); 181 182 iterator it = collection.begin(); 183 iterator end = collection.end(); 184 for (unsigned i = 0; it != end; ++it, ++i) 185 vector[i] = *it; 186 } 187 188 template<typename Value, typename HashFunctions, typename Traits> 189 inline void copyToVector(const HashCountedSet<Value, HashFunctions, Traits>& collection, Vector<Value>& vector) 190 { 191 typedef typename HashCountedSet<Value, HashFunctions, Traits>::const_iterator iterator; 192 193 vector.resize(collection.size()); 194 195 iterator it = collection.begin(); 196 iterator end = collection.end(); 197 for (unsigned i = 0; it != end; ++it, ++i) 198 vector[i] = (*it).first; 199 } 200 173 201 174 202 } // namespace khtml
Note:
See TracChangeset
for help on using the changeset viewer.