2008-05-09 Kevin McCullough <kmccullough@apple.com>
authorkmccullough@apple.com <kmccullough@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 9 May 2008 20:18:08 +0000 (20:18 +0000)
committerkmccullough@apple.com <kmccullough@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 9 May 2008 20:18:08 +0000 (20:18 +0000)
        Reviewed by Tim.

        -<rdar://problem/5770054> JavaScript profiler (10928)
        -Add Profile class so that all profiles can be stored and retrieved by
        the WebInspector when that time comes.

        * JavaScriptCore.exp: Export the new function signatures.
        * JavaScriptCore.xcodeproj/project.pbxproj: Add the new files to the
        project
        * profiler/Profile.cpp: Added. This class represents a single run of the
        profiler.
        (KJS::Profile::Profile):
        (KJS::Profile::willExecute):
        (KJS::Profile::didExecute):
        (KJS::Profile::printDataInspectorStyle):
        (KJS::functionNameCountPairComparator):
        (KJS::Profile::printDataSampleStyle):
        * profiler/Profile.h: Added. Ditto
        (KJS::Profile::stopProfiling):
        * profiler/Profiler.cpp: Now the profiler keeps track of many profiles
        but only runs one at a time.
        (KJS::Profiler::startProfiling):
        (KJS::Profiler::stopProfiling):
        (KJS::Profiler::willExecute):
        (KJS::Profiler::didExecute):
        (KJS::Profiler::printDataInspectorStyle):
        (KJS::Profiler::printDataSampleStyle):
        * profiler/Profiler.h: Ditto.
        (KJS::Profiler::~Profiler):
        (KJS::Profiler::allProfiles):
        (KJS::Profiler::clearProfiles):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@33007 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JavaScriptCore/ChangeLog
JavaScriptCore/JavaScriptCore.exp
JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
JavaScriptCore/profiler/Profile.cpp [new file with mode: 0644]
JavaScriptCore/profiler/Profile.h [new file with mode: 0644]
JavaScriptCore/profiler/Profiler.cpp
JavaScriptCore/profiler/Profiler.h

index 8f7bc8f..36d810b 100644 (file)
@@ -1,3 +1,37 @@
+2008-05-09  Kevin McCullough  <kmccullough@apple.com>
+
+        Reviewed by Tim.
+
+        -<rdar://problem/5770054> JavaScript profiler (10928)
+        -Add Profile class so that all profiles can be stored and retrieved by
+        the WebInspector when that time comes.
+
+        * JavaScriptCore.exp: Export the new function signatures.
+        * JavaScriptCore.xcodeproj/project.pbxproj: Add the new files to the
+        project
+        * profiler/Profile.cpp: Added. This class represents a single run of the
+        profiler.
+        (KJS::Profile::Profile):
+        (KJS::Profile::willExecute):
+        (KJS::Profile::didExecute):
+        (KJS::Profile::printDataInspectorStyle):
+        (KJS::functionNameCountPairComparator):
+        (KJS::Profile::printDataSampleStyle):
+        * profiler/Profile.h: Added. Ditto
+        (KJS::Profile::stopProfiling):
+        * profiler/Profiler.cpp: Now the profiler keeps track of many profiles
+        but only runs one at a time.
+        (KJS::Profiler::startProfiling):
+        (KJS::Profiler::stopProfiling):
+        (KJS::Profiler::willExecute):
+        (KJS::Profiler::didExecute):
+        (KJS::Profiler::printDataInspectorStyle):
+        (KJS::Profiler::printDataSampleStyle):
+        * profiler/Profiler.h: Ditto.
+        (KJS::Profiler::~Profiler):
+        (KJS::Profiler::allProfiles):
+        (KJS::Profiler::clearProfiles):
+
 2008-05-08  Anders Carlsson  <andersca@apple.com>
 
         Reviewed by Mark.
index 4aa8823..db459f5 100644 (file)
@@ -125,7 +125,7 @@ __ZN3KJS8JSObject9putDirectERKNS_10IdentifierEPNS_7JSValueEi
 __ZN3KJS8jsStringEPNS_9ExecStateEPKc
 __ZN3KJS8jsStringEPNS_9ExecStateERKNS_7UStringE
 __ZN3KJS8Profiler13stopProfilingEv
-__ZN3KJS8Profiler14startProfilingEj
+__ZN3KJS8Profiler14startProfilingEjRKNS_7UStringE
 __ZN3KJS8Profiler8profilerEv
 __ZN3KJSeqERKNS_7UStringEPKc
 __ZN3WTF10fastCallocEmm
@@ -202,8 +202,7 @@ __ZNK3KJS8JSObject8toStringEPNS_9ExecStateE
 __ZNK3KJS8JSObject9classInfoEv
 __ZNK3KJS8JSObject9classNameEv
 __ZNK3KJS8JSObject9toBooleanEPNS_9ExecStateE
-__ZNK3KJS8Profiler20printDataSampleStyleEv
-__ZNK3KJS8Profiler23printDataInspectorStyleEv
+__ZNK3KJS8Profiler23printDataInspectorStyleEj
 __ZNK3KJS9ExecState19lexicalGlobalObjectEv
 __ZNK3KJS9HashTable11createTableEv
 __ZNK3WTF8Collator7collateEPKtmS2_m
index b118360..5514153 100644 (file)
                93E26BE608B1517100F85226 /* pcre_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 93E26BE508B1517100F85226 /* pcre_internal.h */; };
                93E26BFE08B151D400F85226 /* ucpinternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 93E26BFC08B151D400F85226 /* ucpinternal.h */; };
                93F0B3AC09BB4DC00068FCE3 /* Parser.h in Headers */ = {isa = PBXBuildFile; fileRef = 93F0B3AA09BB4DC00068FCE3 /* Parser.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               95742F650DD11F5A000917FB /* Profile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95742F630DD11F5A000917FB /* Profile.cpp */; };
+               95742F660DD11F5A000917FB /* Profile.h in Headers */ = {isa = PBXBuildFile; fileRef = 95742F640DD11F5A000917FB /* Profile.h */; settings = {ATTRIBUTES = (Private, ); }; };
                958D85830DC93230008ABF27 /* StrHash.h in Headers */ = {isa = PBXBuildFile; fileRef = 958D85820DC93230008ABF27 /* StrHash.h */; settings = {ATTRIBUTES = (Private, ); }; };
                95AB83420DA4322500BC83F3 /* Profiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95AB832E0DA42CAD00BC83F3 /* Profiler.cpp */; };
                95AB83480DA432EB00BC83F3 /* Profiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 95AB832F0DA42CAD00BC83F3 /* Profiler.h */; settings = {ATTRIBUTES = (Private, ); }; };
                93F0B3A909BB4DC00068FCE3 /* Parser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Parser.cpp; sourceTree = "<group>"; };
                93F0B3AA09BB4DC00068FCE3 /* Parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Parser.h; sourceTree = "<group>"; };
                93F1981A08245AAE001E9ABC /* keywords.table */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = text; path = keywords.table; sourceTree = "<group>"; tabWidth = 8; };
+               95742F630DD11F5A000917FB /* Profile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Profile.cpp; path = profiler/Profile.cpp; sourceTree = "<group>"; };
+               95742F640DD11F5A000917FB /* Profile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Profile.h; path = profiler/Profile.h; sourceTree = "<group>"; };
                958D85820DC93230008ABF27 /* StrHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StrHash.h; sourceTree = "<group>"; };
                95AB832E0DA42CAD00BC83F3 /* Profiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Profiler.cpp; path = profiler/Profiler.cpp; sourceTree = "<group>"; };
                95AB832F0DA42CAD00BC83F3 /* Profiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Profiler.h; path = profiler/Profiler.h; sourceTree = "<group>"; };
                        children = (
                                95AB83540DA43B4400BC83F3 /* FunctionCallProfile.cpp */,
                                95AB83550DA43B4400BC83F3 /* FunctionCallProfile.h */,
+                               95742F630DD11F5A000917FB /* Profile.cpp */,
+                               95742F640DD11F5A000917FB /* Profile.h */,
                                95AB832E0DA42CAD00BC83F3 /* Profiler.cpp */,
                                95AB832F0DA42CAD00BC83F3 /* Profiler.h */,
                        );
                                E1B7C8BE0DA3A3360074B0DC /* ThreadSpecific.h in Headers */,
                                06D358B20DAADA93003B174E /* MainThread.h in Headers */,
                                958D85830DC93230008ABF27 /* StrHash.h in Headers */,
+                               95742F660DD11F5A000917FB /* Profile.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                95AB83560DA43C3000BC83F3 /* FunctionCallProfile.cpp in Sources */,
                                06D358B30DAADAA4003B174E /* MainThread.cpp in Sources */,
                                06D358B40DAADAAA003B174E /* MainThreadMac.mm in Sources */,
+                               95742F650DD11F5A000917FB /* Profile.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
diff --git a/JavaScriptCore/profiler/Profile.cpp b/JavaScriptCore/profiler/Profile.cpp
new file mode 100644 (file)
index 0000000..74abad7
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Profile.h"
+
+#include "FunctionCallProfile.h"
+#include "JSGlobalObject.h"
+#include "ExecState.h"
+#include "function.h"
+
+#include <stdio.h>
+
+namespace KJS {
+
+typedef Vector<UString>::const_iterator NameIterator;
+
+Profile::Profile(const UString& title)
+    : m_title(title)
+{
+    // FIXME: When multi-threading is supported this will be a vector and calls
+    // into the profiler will need to know which thread it is executing on.
+    m_callTree.set(new FunctionCallProfile("Thread_1"));
+}
+
+void Profile::willExecute(const Vector<UString>& callStackNames)
+{
+    FunctionCallProfile* callTreeInsertionPoint = 0;
+    FunctionCallProfile* foundNameInTree = m_callTree.get();
+    NameIterator callStackLocation = callStackNames.begin();
+
+    while (callStackLocation != callStackNames.end() && foundNameInTree) {
+        callTreeInsertionPoint = foundNameInTree;
+        foundNameInTree = callTreeInsertionPoint->findChild(*callStackLocation);
+        ++callStackLocation;
+    }
+
+    if (!foundNameInTree) {   // Insert remains of the stack into the call tree.
+        --callStackLocation;
+        for (FunctionCallProfile* next; callStackLocation != callStackNames.end(); ++callStackLocation) {
+            next = new FunctionCallProfile(*callStackLocation);
+            callTreeInsertionPoint->addChild(next);
+            callTreeInsertionPoint = next;
+        }
+    } else    // We are calling a function that is already in the call tree.
+        foundNameInTree->willExecute();
+}
+
+void Profile::didExecute(Vector<UString> stackNames)
+{
+    m_callTree->didExecute(stackNames, 0);    
+}
+
+void Profile::printDataInspectorStyle() const
+{
+    printf("Call graph:\n");
+    m_callTree->printDataInspectorStyle(0);
+}
+
+typedef pair<UString::Rep*, unsigned> NameCountPair;
+
+static inline bool functionNameCountPairComparator(const NameCountPair a, const NameCountPair b)
+{
+    return a.second > b.second;
+}
+
+void Profile::printDataSampleStyle() const
+{
+    typedef Vector<NameCountPair> NameCountPairVector;
+
+    FunctionCallHashCount countedFunctions;
+    printf("Call graph:\n");
+    m_callTree->printDataSampleStyle(0, countedFunctions);
+
+    printf("\nTotal number in stack:\n");
+    NameCountPairVector sortedFunctions(countedFunctions.size());
+    copyToVector(countedFunctions, sortedFunctions);
+
+    std::sort(sortedFunctions.begin(), sortedFunctions.end(), functionNameCountPairComparator);
+    for (NameCountPairVector::iterator it = sortedFunctions.begin(); it != sortedFunctions.end(); ++it)
+        printf("        %-12d%s\n", (*it).second, UString((*it).first).UTF8String().c_str());
+
+    printf("\nSort by top of stack, same collapsed (when >= 5):\n");
+}
+
+}   // namespace KJS
diff --git a/JavaScriptCore/profiler/Profile.h b/JavaScriptCore/profiler/Profile.h
new file mode 100644 (file)
index 0000000..1fcf99b
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef Profile_h
+#define Profile_h
+
+#include "FunctionCallProfile.h"
+#include <wtf/OwnPtr.h>
+
+namespace KJS {
+
+    class ExecState;
+    class FunctionImp;
+    class JSObject;
+
+    class Profile {
+    public:
+        Profile(const UString& title);
+
+        void willExecute(const Vector<UString>& callStackNames);
+        void didExecute(Vector<UString> stackNames);
+
+        void stopProfiling() { m_callTree->stopProfiling(); };
+
+        void printDataInspectorStyle() const;
+        void printDataSampleStyle() const;
+
+    private:
+        const UString& m_title;
+
+        void insertStackNamesInTree(const Vector<UString>& callStackNames);
+
+        OwnPtr<FunctionCallProfile> m_callTree;
+    };
+
+} // namespace KJS
+
+#endif // Profiler_h
index 1b9bc82..c752070 100644 (file)
 #include "config.h"
 #include "Profiler.h"
 
-#include "FunctionCallProfile.h"
-#include "JSGlobalObject.h"
 #include "ExecState.h"
 #include "function.h"
+#include "FunctionCallProfile.h"
+#include "JSGlobalObject.h"
+#include "Profile.h"
 
 #include <stdio.h>
 
@@ -53,23 +54,26 @@ Profiler* Profiler::profiler()
     return sharedProfiler;
 }
 
-void Profiler::startProfiling(unsigned pageGroupIdentifier)
+void Profiler::startProfiling(unsigned pageGroupIdentifier, const UString& title)
 {
     if (m_profiling)
         return;
 
     m_pageGroupIdentifier = pageGroupIdentifier;
 
-    // FIXME: When multi-threading is supported this will be a vector and calls
-    // into the profiler will need to know which thread it is executing on.
-    m_callTree.set(new FunctionCallProfile("Thread_1"));
+    m_currentProfile.set(new Profile(title));
     m_profiling = true;
 }
 
 void Profiler::stopProfiling()
 {
     m_profiling = false;
-    m_callTree->stopProfiling();
+
+    if (!m_currentProfile)
+        return;
+
+    m_currentProfile->stopProfiling();
+    m_allProfiles.append(m_currentProfile.release());
 }
 
 void Profiler::willExecute(ExecState* exec, JSObject* calledFunction)
@@ -79,7 +83,7 @@ void Profiler::willExecute(ExecState* exec, JSObject* calledFunction)
 
     Vector<UString> callStackNames;
     getStackNames(callStackNames, exec, calledFunction);
-    insertStackNamesInTree(callStackNames);
+    m_currentProfile->willExecute(callStackNames);
 }
 
 void Profiler::willExecute(ExecState* exec, const UString& sourceURL, int startingLineNumber)
@@ -89,7 +93,7 @@ void Profiler::willExecute(ExecState* exec, const UString& sourceURL, int starti
 
     Vector<UString> callStackNames;
     getStackNames(callStackNames, exec, sourceURL, startingLineNumber);
-    insertStackNamesInTree(callStackNames);
+    m_currentProfile->willExecute(callStackNames);
 }
 
 void Profiler::didExecute(ExecState* exec, JSObject* calledFunction)
@@ -99,7 +103,7 @@ void Profiler::didExecute(ExecState* exec, JSObject* calledFunction)
 
     Vector<UString> callStackNames;
     getStackNames(callStackNames, exec, calledFunction);
-    m_callTree->didExecute(callStackNames, 0);
+    m_currentProfile->didExecute(callStackNames);
 }
 
 void Profiler::didExecute(ExecState* exec, const UString& sourceURL, int startingLineNumber)
@@ -109,30 +113,7 @@ void Profiler::didExecute(ExecState* exec, const UString& sourceURL, int startin
 
     Vector<UString> callStackNames;
     getStackNames(callStackNames, exec, sourceURL, startingLineNumber);
-    m_callTree->didExecute(callStackNames, 0);
-}
-
-void Profiler::insertStackNamesInTree(const Vector<UString>& callStackNames)
-{
-    FunctionCallProfile* callTreeInsertionPoint = 0;
-    FunctionCallProfile* foundNameInTree = m_callTree.get();
-    NameIterator callStackLocation = callStackNames.begin();
-
-    while (callStackLocation != callStackNames.end() && foundNameInTree) {
-        callTreeInsertionPoint = foundNameInTree;
-        foundNameInTree = callTreeInsertionPoint->findChild(*callStackLocation);
-        ++callStackLocation;
-    }
-
-    if (!foundNameInTree) {   // Insert remains of the stack into the call tree.
-        --callStackLocation;
-        for (FunctionCallProfile* next; callStackLocation != callStackNames.end(); ++callStackLocation) {
-            next = new FunctionCallProfile(*callStackLocation);
-            callTreeInsertionPoint->addChild(next);
-            callTreeInsertionPoint = next;
-        }
-    } else    // We are calling a function that is already in the call tree.
-        foundNameInTree->willExecute();
+    m_currentProfile->didExecute(callStackNames);
 }
 
 void getStackNames(Vector<UString>& names, ExecState* exec)
@@ -171,36 +152,14 @@ UString getFunctionName(FunctionImp* functionImp)
     return (name.isEmpty() ? "[anonymous function]" : name) + " " + URL + ": " + UString::from(lineNumber);
 }
 
-void Profiler::printDataInspectorStyle() const
-{
-    printf("Profiler Call graph:\n");
-    m_callTree->printDataInspectorStyle(0);
-}
-
-typedef pair<UString::Rep*, unsigned> NameCountPair;
-
-static inline bool functionNameCountPairComparator(const NameCountPair a, const NameCountPair b)
+void Profiler::printDataInspectorStyle(unsigned whichProfile) const
 {
-    return a.second > b.second;
+    m_allProfiles[whichProfile]->printDataInspectorStyle();
 }
 
-void Profiler::printDataSampleStyle() const
+void Profiler::printDataSampleStyle(unsigned whichProfile) const
 {
-    typedef Vector<NameCountPair> NameCountPairVector;
-
-    FunctionCallHashCount countedFunctions;
-    printf("Call graph:\n");
-    m_callTree->printDataSampleStyle(0, countedFunctions);
-
-    printf("\nTotal number in stack:\n");
-    NameCountPairVector sortedFunctions(countedFunctions.size());
-    copyToVector(countedFunctions, sortedFunctions);
-
-    std::sort(sortedFunctions.begin(), sortedFunctions.end(), functionNameCountPairComparator);
-    for (NameCountPairVector::iterator it = sortedFunctions.begin(); it != sortedFunctions.end(); ++it)
-        printf("        %-12d%s\n", (*it).second, UString((*it).first).UTF8String().c_str());
-
-    printf("\nSort by top of stack, same collapsed (when >= 5):\n");
+    m_allProfiles[whichProfile]->printDataSampleStyle();
 }
 
 void Profiler::debugLog(UString message)
index 3732994..ab9ddad 100644 (file)
@@ -29,7 +29,7 @@
 #ifndef Profiler_h
 #define Profiler_h
 
-#include "FunctionCallProfile.h"
+#include "Profile.h"
 #include <wtf/OwnPtr.h>
 
 namespace KJS {
@@ -39,21 +39,25 @@ namespace KJS {
     class JSObject;
 
     class Profiler {
-        typedef Vector<UString>::const_iterator NameIterator;
-
     public:
         static Profiler* profiler();
         static void debugLog(UString);
 
-        void startProfiling(unsigned Identifier);
+        ~Profiler() { deleteAllValues(m_allProfiles); }
+
+        void startProfiling(unsigned pageGroupIdentifier, const UString&);
         void stopProfiling();
+
         void willExecute(ExecState*, JSObject* calledFunction);
         void willExecute(ExecState*, const UString& sourceURL, int startingLineNumber);
         void didExecute(ExecState*, JSObject* calledFunction);
         void didExecute(ExecState*, const UString& sourceURL, int startingLineNumber);
 
-        void printDataInspectorStyle() const;
-        void printDataSampleStyle() const;
+        Vector<Profile*>& allProfiles() { return m_allProfiles; };
+        void clearProfiles() { if (!m_profiling) deleteAllValues(m_allProfiles); };
+
+        void printDataInspectorStyle(unsigned whichProfile) const;
+        void printDataSampleStyle(unsigned whichProfile) const;
 
     private:
         Profiler()
@@ -62,14 +66,11 @@ namespace KJS {
         {
         }
 
-        void insertStackNamesInTree(const Vector<UString>& callStackNames);
-
         bool m_profiling;
         unsigned m_pageGroupIdentifier;
 
-        // FIXME: Make this a vector of FunctionCallProfiles where each one is the
-        // root of a new thread.
-        OwnPtr<FunctionCallProfile> m_callTree;
+        OwnPtr<Profile> m_currentProfile;
+        Vector<Profile*> m_allProfiles;
     };
 
 } // namespace KJS