Title: [93560] trunk/Source/_javascript_Core
Revision
93560
Author
[email protected]
Date
2011-08-22 16:41:20 -0700 (Mon, 22 Aug 2011)

Log Message

Sampling counter support is in the bytecode directory
https://bugs.webkit.org/show_bug.cgi?id=66724

Reviewed by Darin Adler.

Moved SamplingCounter to a separate header in runtime/.

* GNUmakefile.list.am:
* _javascript_Core.pro:
* _javascript_Core.vcproj/_javascript_Core/_javascript_Core.vcproj:
* _javascript_Core.xcodeproj/project.pbxproj:
* bytecode/SamplingTool.cpp:
* bytecode/SamplingTool.h:
* runtime/SamplingCounter.cpp: Added.
(JSC::AbstractSamplingCounter::dump):
* runtime/SamplingCounter.h: Added.
(JSC::AbstractSamplingCounter::count):
(JSC::AbstractSamplingCounter::addressOfCounter):
(JSC::AbstractSamplingCounter::init):
(JSC::SamplingCounter::SamplingCounter):
(JSC::GlobalSamplingCounter::name):
(JSC::DeletableSamplingCounter::DeletableSamplingCounter):
(JSC::DeletableSamplingCounter::~DeletableSamplingCounter):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (93559 => 93560)


--- trunk/Source/_javascript_Core/ChangeLog	2011-08-22 23:34:31 UTC (rev 93559)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-08-22 23:41:20 UTC (rev 93560)
@@ -1,3 +1,29 @@
+2011-08-22  Filip Pizlo  <[email protected]>
+
+        Sampling counter support is in the bytecode directory
+        https://bugs.webkit.org/show_bug.cgi?id=66724
+
+        Reviewed by Darin Adler.
+        
+        Moved SamplingCounter to a separate header in runtime/.
+
+        * GNUmakefile.list.am:
+        * _javascript_Core.pro:
+        * _javascript_Core.vcproj/_javascript_Core/_javascript_Core.vcproj:
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * bytecode/SamplingTool.cpp:
+        * bytecode/SamplingTool.h:
+        * runtime/SamplingCounter.cpp: Added.
+        (JSC::AbstractSamplingCounter::dump):
+        * runtime/SamplingCounter.h: Added.
+        (JSC::AbstractSamplingCounter::count):
+        (JSC::AbstractSamplingCounter::addressOfCounter):
+        (JSC::AbstractSamplingCounter::init):
+        (JSC::SamplingCounter::SamplingCounter):
+        (JSC::GlobalSamplingCounter::name):
+        (JSC::DeletableSamplingCounter::DeletableSamplingCounter):
+        (JSC::DeletableSamplingCounter::~DeletableSamplingCounter):
+
 2011-08-21  Martin Robinson  <[email protected]>
 
         Fix 'make dist' for WebKitGTK+.

Modified: trunk/Source/_javascript_Core/GNUmakefile.list.am (93559 => 93560)


--- trunk/Source/_javascript_Core/GNUmakefile.list.am	2011-08-22 23:34:31 UTC (rev 93559)
+++ trunk/Source/_javascript_Core/GNUmakefile.list.am	2011-08-22 23:41:20 UTC (rev 93560)
@@ -406,6 +406,8 @@
 	Source/_javascript_Core/runtime/RegExpPrototype.h \
 	Source/_javascript_Core/runtime/RopeImpl.cpp \
 	Source/_javascript_Core/runtime/RopeImpl.h \
+	Source/_javascript_Core/runtime/SamplingCounter.cpp \
+	Source/_javascript_Core/runtime/SamplingCounter.h \
 	Source/_javascript_Core/runtime/ScopeChain.cpp \
 	Source/_javascript_Core/runtime/ScopeChain.h \
 	Source/_javascript_Core/runtime/ScopeChainMark.h \

Modified: trunk/Source/_javascript_Core/_javascript_Core.pro (93559 => 93560)


--- trunk/Source/_javascript_Core/_javascript_Core.pro	2011-08-22 23:34:31 UTC (rev 93559)
+++ trunk/Source/_javascript_Core/_javascript_Core.pro	2011-08-22 23:41:20 UTC (rev 93560)
@@ -183,6 +183,7 @@
     runtime/RegExpPrototype.cpp \
     runtime/RegExpCache.cpp \
     runtime/RopeImpl.cpp \
+    runtime/SamplingCounter.cpp \
     runtime/ScopeChain.cpp \
     runtime/SmallStrings.cpp \
     runtime/StrictEvalActivation.cpp \

Modified: trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.vcproj (93559 => 93560)


--- trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.vcproj	2011-08-22 23:34:31 UTC (rev 93559)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.vcproj	2011-08-22 23:41:20 UTC (rev 93560)
@@ -1113,6 +1113,14 @@
 				RelativePath="..\..\runtime\ScopeChainMark.h"
 				>
 			</File>
+                        <File
+                                RelativePath="..\..\runtime\SamplingCounter.cpp"
+                                >
+                        </File>
+                        <File
+                                RelativePath="..\..\runtime\SamplingCounter.h"
+                                >
+                        </File>
 			<File
 				RelativePath="..\..\runtime\SmallStrings.cpp"
 				>

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (93559 => 93560)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2011-08-22 23:34:31 UTC (rev 93559)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2011-08-22 23:41:20 UTC (rev 93560)
@@ -49,6 +49,8 @@
 		0BDFFAE10FC6193100D69EF4 /* OwnFastMallocPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BDFFAD10FC616EC00D69EF4 /* OwnFastMallocPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0BF28A2911A33DC300638F84 /* SizeLimits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0BF28A2811A33DC300638F84 /* SizeLimits.cpp */; };
 		0F29479C126E698C00B3ABF5 /* DecimalNumber.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F29479B126E698C00B3ABF5 /* DecimalNumber.cpp */; };
+		0F7700901402FDE40078EB39 /* SamplingCounter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F77008E1402FDD60078EB39 /* SamplingCounter.h */; };
+		0F7700921402FF3C0078EB39 /* SamplingCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7700911402FF280078EB39 /* SamplingCounter.cpp */; };
 		0F963B3813FC6FE90002D9B2 /* ValueProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F963B3613FC6FDE0002D9B2 /* ValueProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		1400067712A6F7830064D123 /* OSAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 1400067612A6F7830064D123 /* OSAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		1400069312A6F9E10064D123 /* OSAllocatorPosix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1400069212A6F9E10064D123 /* OSAllocatorPosix.cpp */; };
@@ -730,6 +732,8 @@
 		0BDFFAD40FC6171000D69EF4 /* CrossThreadRefCounted.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CrossThreadRefCounted.h; sourceTree = "<group>"; };
 		0BF28A2811A33DC300638F84 /* SizeLimits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SizeLimits.cpp; sourceTree = "<group>"; };
 		0F29479B126E698C00B3ABF5 /* DecimalNumber.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DecimalNumber.cpp; sourceTree = "<group>"; };
+		0F77008E1402FDD60078EB39 /* SamplingCounter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SamplingCounter.h; sourceTree = "<group>"; };
+		0F7700911402FF280078EB39 /* SamplingCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SamplingCounter.cpp; sourceTree = "<group>"; };
 		0F963B3613FC6FDE0002D9B2 /* ValueProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValueProfile.h; sourceTree = "<group>"; };
 		1400067612A6F7830064D123 /* OSAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSAllocator.h; sourceTree = "<group>"; };
 		1400069212A6F9E10064D123 /* OSAllocatorPosix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OSAllocatorPosix.cpp; sourceTree = "<group>"; };
@@ -1839,6 +1843,8 @@
 		7EF6E0BB0EB7A1EC0079AFAF /* runtime */ = {
 			isa = PBXGroup;
 			children = (
+				0F7700911402FF280078EB39 /* SamplingCounter.cpp */,
+				0F77008E1402FDD60078EB39 /* SamplingCounter.h */,
 				BCF605110E203EF800B9A64D /* ArgList.cpp */,
 				BCF605120E203EF800B9A64D /* ArgList.h */,
 				BC257DE50E1F51C50016B6C9 /* Arguments.cpp */,
@@ -2468,6 +2474,7 @@
 				90D3469C0E285280009492EE /* RefCountedLeakCounter.h in Headers */,
 				BC18C4580E16F5CD00B34460 /* RefPtr.h in Headers */,
 				BC18C4590E16F5CD00B34460 /* RefPtrHashMap.h in Headers */,
+				0F7700901402FDE40078EB39 /* SamplingCounter.h in Headers */,
 				BC18C45A0E16F5CD00B34460 /* RegExp.h in Headers */,
 				A1712B3F11C7B228007A5315 /* RegExpCache.h in Headers */,
 				BCD202C20E1706A7002C7E82 /* RegExpConstructor.h in Headers */,
@@ -2841,6 +2848,7 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				0F7700921402FF3C0078EB39 /* SamplingCounter.cpp in Sources */,
 				147F39BD107EC37600427A48 /* ArgList.cpp in Sources */,
 				147F39BE107EC37600427A48 /* Arguments.cpp in Sources */,
 				86D3B2C310156BDE002865E7 /* ARMAssembler.cpp in Sources */,

Modified: trunk/Source/_javascript_Core/bytecode/SamplingTool.cpp (93559 => 93560)


--- trunk/Source/_javascript_Core/bytecode/SamplingTool.cpp	2011-08-22 23:34:31 UTC (rev 93559)
+++ trunk/Source/_javascript_Core/bytecode/SamplingTool.cpp	2011-08-22 23:41:20 UTC (rev 93560)
@@ -387,21 +387,4 @@
 
 #endif
 
-void AbstractSamplingCounter::dump()
-{
-#if ENABLE(SAMPLING_COUNTERS)
-    if (s_abstractSamplingCounterChain != &s_abstractSamplingCounterChainEnd) {
-        printf("\nSampling Counter Values:\n");
-        for (AbstractSamplingCounter* currCounter = s_abstractSamplingCounterChain; (currCounter != &s_abstractSamplingCounterChainEnd); currCounter = currCounter->m_next)
-            printf("\t%s\t: %lld\n", currCounter->m_name, currCounter->m_counter);
-        printf("\n\n");
-    }
-    s_completed = true;
-#endif
-}
-
-AbstractSamplingCounter AbstractSamplingCounter::s_abstractSamplingCounterChainEnd;
-AbstractSamplingCounter* AbstractSamplingCounter::s_abstractSamplingCounterChain = &s_abstractSamplingCounterChainEnd;
-bool AbstractSamplingCounter::s_completed = false;
-
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/bytecode/SamplingTool.h (93559 => 93560)


--- trunk/Source/_javascript_Core/bytecode/SamplingTool.h	2011-08-22 23:34:31 UTC (rev 93559)
+++ trunk/Source/_javascript_Core/bytecode/SamplingTool.h	2011-08-22 23:41:20 UTC (rev 93560)
@@ -32,6 +32,7 @@
 #include "Strong.h"
 #include "Nodes.h"
 #include "Opcode.h"
+#include "SamplingCounter.h"
 #include <wtf/Assertions.h>
 #include <wtf/HashMap.h>
 #include <wtf/Threading.h>
@@ -279,143 +280,6 @@
 #endif
     };
 
-    // AbstractSamplingCounter:
-    //
-    // Implements a named set of counters, printed on exit if ENABLE(SAMPLING_COUNTERS).
-    // See subclasses below, SamplingCounter, GlobalSamplingCounter and DeletableSamplingCounter.
-    class AbstractSamplingCounter {
-        friend class DeletableSamplingCounter;
-    public:
-        void count(uint32_t count = 1)
-        {
-            m_counter += count;
-        }
-
-        static void dump();
-
-        int64_t* addressOfCounter() { return &m_counter; }
-
-    protected:
-        // Effectively the contructor, however called lazily in the case of GlobalSamplingCounter.
-        void init(const char* name)
-        {
-            m_counter = 0;
-            m_name = name;
-
-            // Set m_next to point to the head of the chain, and inform whatever is
-            // currently at the head that this node will now hold the pointer to it.
-            m_next = s_abstractSamplingCounterChain;
-            s_abstractSamplingCounterChain->m_referer = &m_next;
-            // Add this node to the head of the list.
-            s_abstractSamplingCounterChain = this;
-            m_referer = &s_abstractSamplingCounterChain;
-        }
-
-        int64_t m_counter;
-        const char* m_name;
-        AbstractSamplingCounter* m_next;
-        // This is a pointer to the pointer to this node in the chain; used to
-        // allow fast linked list deletion.
-        AbstractSamplingCounter** m_referer;
-        // Null object used to detect end of static chain.
-        static AbstractSamplingCounter s_abstractSamplingCounterChainEnd;
-        static AbstractSamplingCounter* s_abstractSamplingCounterChain;
-        static bool s_completed;
-    };
-
-#if ENABLE(SAMPLING_COUNTERS)
-    // SamplingCounter:
-    //
-    // This class is suitable and (hopefully!) convenient for cases where a counter is
-    // required within the scope of a single function.  It can be instantiated as a
-    // static variable since it contains a constructor but not a destructor (static
-    // variables in WebKit cannot have destructors).
-    //
-    // For example:
-    //
-    // void someFunction()
-    // {
-    //     static SamplingCounter countMe("This is my counter.  There are many like it, but this one is mine.");
-    //     countMe.count();
-    //     // ...
-    // }
-    //
-    class SamplingCounter : public AbstractSamplingCounter {
-    public:
-        SamplingCounter(const char* name) { init(name); }
-    };
-
-    // GlobalSamplingCounter:
-    //
-    // This class is suitable for use where a counter is to be declared globally,
-    // since it contains neither a constructor nor destructor.  Instead, ensure
-    // that 'name()' is called to provide the counter with a name (and also to
-    // allow it to be printed out on exit).
-    //
-    // GlobalSamplingCounter globalCounter;
-    //
-    // void firstFunction()
-    // {
-    //     // Put this within a function that is definitely called!
-    //     // (Or alternatively alongside all calls to 'count()').
-    //     globalCounter.name("I Name You Destroyer.");
-    //     globalCounter.count();
-    //     // ...
-    // }
-    //
-    // void secondFunction()
-    // {
-    //     globalCounter.count();
-    //     // ...
-    // }
-    //
-    class GlobalSamplingCounter : public AbstractSamplingCounter {
-    public:
-        void name(const char* name)
-        {
-            // Global objects should be mapped in zero filled memory, so this should
-            // be a safe (albeit not necessarily threadsafe) check for 'first call'.
-            if (!m_next)
-                init(name);
-        }
-    };
-
-    // DeletableSamplingCounter:
-    //
-    // The above classes (SamplingCounter, GlobalSamplingCounter), are intended for
-    // use within a global or static scope, and as such cannot have a destructor.
-    // This means there is no convenient way for them to remove themselves from the
-    // static list of counters, and should an instance of either class be freed
-    // before 'dump()' has walked over the list it will potentially walk over an
-    // invalid pointer.
-    //
-    // This class is intended for use where the counter may possibly be deleted before
-    // the program exits.  Should this occur, the counter will print it's value to
-    // stderr, and remove itself from the static list.  Example:
-    //
-    // DeletableSamplingCounter* counter = new DeletableSamplingCounter("The Counter With No Name");
-    // counter->count();
-    // delete counter;
-    //
-    class DeletableSamplingCounter : public AbstractSamplingCounter {
-    public:
-        DeletableSamplingCounter(const char* name) { init(name); }
-
-        ~DeletableSamplingCounter()
-        {
-            if (!s_completed)
-                fprintf(stderr, "DeletableSamplingCounter \"%s\" deleted early (with count %lld)\n", m_name, m_counter);
-            // Our m_referer pointer should know where the pointer to this node is,
-            // and m_next should know that this node is the previous node in the list.
-            ASSERT(*m_referer == this);
-            ASSERT(m_next->m_referer == &m_next);
-            // Remove this node from the list, and inform m_next that we have done so.
-            m_next->m_referer = m_referer;
-            *m_referer = m_next;
-        }
-    };
-#endif
-
 } // namespace JSC
 
 #endif // SamplingTool_h

Added: trunk/Source/_javascript_Core/runtime/SamplingCounter.cpp (0 => 93560)


--- trunk/Source/_javascript_Core/runtime/SamplingCounter.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/runtime/SamplingCounter.cpp	2011-08-22 23:41:20 UTC (rev 93560)
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2011 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.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 "SamplingCounter.h"
+
+namespace JSC {
+
+void AbstractSamplingCounter::dump()
+{
+#if ENABLE(SAMPLING_COUNTERS)
+    if (s_abstractSamplingCounterChain != &s_abstractSamplingCounterChainEnd) {
+        printf("\nSampling Counter Values:\n");
+        for (AbstractSamplingCounter* currCounter = s_abstractSamplingCounterChain; (currCounter != &s_abstractSamplingCounterChainEnd); currCounter = currCounter->m_next)
+            printf("\t%s\t: %lld\n", currCounter->m_name, currCounter->m_counter);
+        printf("\n\n");
+    }
+    s_completed = true;
+#endif
+}
+
+AbstractSamplingCounter AbstractSamplingCounter::s_abstractSamplingCounterChainEnd;
+AbstractSamplingCounter* AbstractSamplingCounter::s_abstractSamplingCounterChain = &s_abstractSamplingCounterChainEnd;
+bool AbstractSamplingCounter::s_completed = false;
+
+} // namespace JSC
+

Added: trunk/Source/_javascript_Core/runtime/SamplingCounter.h (0 => 93560)


--- trunk/Source/_javascript_Core/runtime/SamplingCounter.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/runtime/SamplingCounter.h	2011-08-22 23:41:20 UTC (rev 93560)
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2011 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.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 SamplingCounter_h
+#define SamplingCounter_h
+
+#include <wtf/Assertions.h>
+
+namespace JSC {
+
+// AbstractSamplingCounter:
+//
+// Implements a named set of counters, printed on exit if ENABLE(SAMPLING_COUNTERS).
+// See subclasses below, SamplingCounter, GlobalSamplingCounter and DeletableSamplingCounter.
+class AbstractSamplingCounter {
+    friend class DeletableSamplingCounter;
+public:
+    void count(uint32_t count = 1)
+    {
+        m_counter += count;
+    }
+
+    static void dump();
+
+    int64_t* addressOfCounter() { return &m_counter; }
+
+protected:
+    // Effectively the contructor, however called lazily in the case of GlobalSamplingCounter.
+    void init(const char* name)
+    {
+        m_counter = 0;
+        m_name = name;
+
+        // Set m_next to point to the head of the chain, and inform whatever is
+        // currently at the head that this node will now hold the pointer to it.
+        m_next = s_abstractSamplingCounterChain;
+        s_abstractSamplingCounterChain->m_referer = &m_next;
+        // Add this node to the head of the list.
+        s_abstractSamplingCounterChain = this;
+        m_referer = &s_abstractSamplingCounterChain;
+    }
+
+    int64_t m_counter;
+    const char* m_name;
+    AbstractSamplingCounter* m_next;
+    // This is a pointer to the pointer to this node in the chain; used to
+    // allow fast linked list deletion.
+    AbstractSamplingCounter** m_referer;
+    // Null object used to detect end of static chain.
+    static AbstractSamplingCounter s_abstractSamplingCounterChainEnd;
+    static AbstractSamplingCounter* s_abstractSamplingCounterChain;
+    static bool s_completed;
+};
+
+#if ENABLE(SAMPLING_COUNTERS)
+// SamplingCounter:
+//
+// This class is suitable and (hopefully!) convenient for cases where a counter is
+// required within the scope of a single function. It can be instantiated as a
+// static variable since it contains a constructor but not a destructor (static
+// variables in WebKit cannot have destructors).
+//
+// For example:
+//
+// void someFunction()
+// {
+//     static SamplingCounter countMe("This is my counter. There are many like it, but this one is mine.");
+//     countMe.count();
+//     // ...
+// }
+//
+class SamplingCounter : public AbstractSamplingCounter {
+public:
+    SamplingCounter(const char* name) { init(name); }
+};
+
+// GlobalSamplingCounter:
+//
+// This class is suitable for use where a counter is to be declared globally,
+// since it contains neither a constructor nor destructor. Instead, ensure
+// that 'name()' is called to provide the counter with a name (and also to
+// allow it to be printed out on exit).
+//
+// GlobalSamplingCounter globalCounter;
+//
+// void firstFunction()
+// {
+//     // Put this within a function that is definitely called!
+//     // (Or alternatively alongside all calls to 'count()').
+//     globalCounter.name("I Name You Destroyer.");
+//     globalCounter.count();
+//     // ...
+// }
+//
+// void secondFunction()
+// {
+//     globalCounter.count();
+//     // ...
+// }
+//
+class GlobalSamplingCounter : public AbstractSamplingCounter {
+public:
+    void name(const char* name)
+    {
+        // Global objects should be mapped in zero filled memory, so this should
+        // be a safe (albeit not necessarily threadsafe) check for 'first call'.
+        if (!m_next)
+            init(name);
+    }
+};
+
+// DeletableSamplingCounter:
+//
+// The above classes (SamplingCounter, GlobalSamplingCounter), are intended for
+// use within a global or static scope, and as such cannot have a destructor.
+// This means there is no convenient way for them to remove themselves from the
+// static list of counters, and should an instance of either class be freed
+// before 'dump()' has walked over the list it will potentially walk over an
+// invalid pointer.
+//
+// This class is intended for use where the counter may possibly be deleted before
+// the program exits. Should this occur, the counter will print it's value to
+// stderr, and remove itself from the static list. Example:
+//
+// DeletableSamplingCounter* counter = new DeletableSamplingCounter("The Counter With No Name");
+// counter->count();
+// delete counter;
+//
+class DeletableSamplingCounter : public AbstractSamplingCounter {
+public:
+    DeletableSamplingCounter(const char* name) { init(name); }
+
+    ~DeletableSamplingCounter()
+    {
+        if (!s_completed)
+            fprintf(stderr, "DeletableSamplingCounter \"%s\" deleted early (with count %lld)\n", m_name, m_counter);
+        // Our m_referer pointer should know where the pointer to this node is,
+        // and m_next should know that this node is the previous node in the list.
+        ASSERT(*m_referer == this);
+        ASSERT(m_next->m_referer == &m_next);
+        // Remove this node from the list, and inform m_next that we have done so.
+        m_next->m_referer = m_referer;
+        *m_referer = m_next;
+    }
+};
+#endif
+
+} // namespace JSC
+
+#endif // SamplingCounter_h
+
+
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to