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
+
+