Changeset 32760 in webkit for trunk/JavaScriptCore


Ignore:
Timestamp:
May 1, 2008, 9:32:32 AM (17 years ago)
Author:
[email protected]
Message:

2008-05-01 Kevin McCullough <[email protected]>

Reviewed by Darin.

<rdar://problem/5770054> JavaScript profiler (10928)

  • Fix "sample" output so that it can be imported into Instruments
  • Also keep track of number of times a function is profiled.
  • JavaScriptCore.xcodeproj/project.pbxproj: Add StrHash.h which needed to be pulled out of identifier.cpp so that it could be used by the profiler and identifiers.
  • kjs/identifier.cpp: Ditto.
  • profiler/FunctionCallProfile.cpp: (KJS::FunctionCallProfile::printDataInspectorStyle): Inspector style printing should show microseconds. (KJS::FunctionCallProfile::printDataSampleStyle): Sample style printing now counts the number of times a function is in the stack tree and does not print microseconds since that does not make sense for a sampler.
  • profiler/FunctionCallProfile.h: Keep track of number of times a function is profiled. (KJS::FunctionCallProfile::numberOfCalls):
  • profiler/Profiler.cpp: (KJS::functionNameCountPairComparator): Comparator for sort function in printDataSampleStyle. (KJS::Profiler::printDataSampleStyle): Print the number of times that a function is listed in the stack tree in order of most times listed.
  • wtf/HashCountedSet.h: Added copyToVector since it didn't exist and is a more standard way to copy a HashSet to a Vector. I added on variant that takes a pair as the Vector's type and so the HashCountedSet simply fills in that pair with its internal pair, and another variant that takes a Vector of the type of the HashCountedSet and only fills in the Vector with the first element of the pair. (WTF::copyToVector):
  • wtf/StrHash.h: Added. (WTF::):
Location:
trunk/JavaScriptCore
Files:
1 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r32712 r32760  
     12008-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
    1372008-04-29  David Kilzer  <[email protected]>
    238
  • trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r32587 r32760  
    186186                93E26BFE08B151D400F85226 /* ucpinternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 93E26BFC08B151D400F85226 /* ucpinternal.h */; };
    187187                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 */; };
    188189                95AB83420DA4322500BC83F3 /* Profiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95AB832E0DA42CAD00BC83F3 /* Profiler.cpp */; };
    189190                95AB83480DA432EB00BC83F3 /* Profiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 95AB832F0DA42CAD00BC83F3 /* Profiler.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    493494                93F0B3AA09BB4DC00068FCE3 /* Parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Parser.h; sourceTree = "<group>"; };
    494495                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>"; };
    495497                95AB832E0DA42CAD00BC83F3 /* Profiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Profiler.cpp; path = profiler/Profiler.cpp; sourceTree = "<group>"; };
    496498                95AB832F0DA42CAD00BC83F3 /* Profiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Profiler.h; path = profiler/Profiler.h; sourceTree = "<group>"; };
     
    821823                                6592C316098B7DE10003D4F6 /* Vector.h */,
    822824                                6592C317098B7DE10003D4F6 /* VectorTraits.h */,
     825                                958D85820DC93230008ABF27 /* StrHash.h */,
    823826                        );
    824827                        path = wtf;
     
    11411144                                E1B7C8BE0DA3A3360074B0DC /* ThreadSpecific.h in Headers */,
    11421145                                06D358B20DAADA93003B174E /* MainThread.h in Headers */,
     1146                                958D85830DC93230008ABF27 /* StrHash.h in Headers */,
    11431147                        );
    11441148                        runOnlyForDeploymentPostprocessing = 0;
  • trunk/JavaScriptCore/kjs/identifier.cpp

    r32222 r32760  
    2929#include <wtf/FastMalloc.h>
    3030#include <wtf/HashSet.h>
     31//#include <wtf/StrHash.h>
    3132#if USE(MULTIPLE_THREADS)
    3233#include <wtf/ThreadSpecific.h>
    3334using namespace WTF;
    3435#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 }
    5236
    5337namespace KJS {
  • trunk/JavaScriptCore/profiler/FunctionCallProfile.cpp

    r32693 r32760  
    112112            printf("  ");
    113113
    114         printf("%.0fms %s\n", m_timeSum, m_functionName.UTF8String().c_str());
     114        printf("%.3fms %s\n", m_timeSum, m_functionName.UTF8String().c_str());
    115115    } else
    116116        printf("%s\n", m_functionName.UTF8String().c_str());
     
    124124
    125125// print the profiled data in a format that matches the tool sample's output.
    126 double FunctionCallProfile::printDataSampleStyle(int indentLevel) const
     126double FunctionCallProfile::printDataSampleStyle(int indentLevel, FunctionCallHashCount& countedFunctions) const
    127127{
    128128    printf("    ");
    129129
    130130    // Print function names
     131    const char* name = m_functionName.UTF8String().c_str();
     132    double sampleCount = m_timeSum * 1000;
    131133    if (indentLevel) {
    132134        for (int i = 0; i < indentLevel; ++i)
    133135            printf("  ");
    134136
    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);
    137140    } else
    138         printf("%s\n", m_functionName.UTF8String().c_str());
     141        printf("%s\n", name);
    139142
    140143    ++indentLevel;
    141144
    142145    // Print children's names and information
    143     double sumOfChildrensTimes = 0.0;
     146    double sumOfChildrensCount = 0.0;
    144147    for (StackIterator currentChild = m_children.begin(); currentChild != m_children.end(); ++currentChild)
    145         sumOfChildrensTimes += (*currentChild)->printDataSampleStyle(indentLevel);
     148        sumOfChildrensCount += (*currentChild)->printDataSampleStyle(indentLevel, countedFunctions);
    146149
    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) {
    149153        printf("    ");
    150154        while (indentLevel--)
    151155            printf("  ");
    152156
    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());
    154158    }
    155159
  • trunk/JavaScriptCore/profiler/FunctionCallProfile.h

    r32693 r32760  
    3232#include <kjs/ustring.h>
    3333#include <wtf/Deque.h>
     34#include <wtf/StrHash.h>
    3435
    3536namespace KJS {
     
    3839
    3940    typedef Deque<FunctionCallProfile*>::const_iterator StackIterator;
     41    typedef HashCountedSet<UString::Rep*> FunctionCallHashCount;
    4042
    4143    class FunctionCallProfile {
     
    5456        UString functionName() const { return m_functionName; }
    5557        double milliSecs() const { return m_timeSum; }
     58        unsigned numberOfCalls() const { return m_numberOfCalls; }
    5659
    5760        void printDataInspectorStyle(int indentLevel) const;
    58         double printDataSampleStyle(int indentLevel) const;
     61        double printDataSampleStyle(int indentLevel, FunctionCallHashCount&) const;
    5962
    6063    private:
  • trunk/JavaScriptCore/profiler/Profiler.cpp

    r32495 r32760  
    178178}
    179179
     180typedef pair<UString::Rep*, unsigned> NameCountPair;
     181
     182static inline bool functionNameCountPairComparator(const NameCountPair a, const NameCountPair b)
     183{
     184    return a.second > b.second;
     185}
     186
    180187void Profiler::printDataSampleStyle() const
    181188{
     189    typedef Vector<NameCountPair> NameCountPairVector;
     190
     191    FunctionCallHashCount countedFunctions;
    182192    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
    187203    printf("\nSort by top of stack, same collapsed (when >= 5):\n");
    188204}
  • trunk/JavaScriptCore/wtf/HashCountedSet.h

    r17127 r32760  
    2626#include "Assertions.h"
    2727#include "HashMap.h"
     28#include "Vector.h"
    2829
    2930namespace WTF {
     
    171172        m_impl.clear();
    172173    }
     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
    173201
    174202} // namespace khtml
Note: See TracChangeset for help on using the changeset viewer.