Title: [99374] trunk/Source
Revision
99374
Author
[email protected]
Date
2011-11-06 03:39:12 -0800 (Sun, 06 Nov 2011)

Log Message

JSC should be able to sample itself in a more flexible way than just sampling flags
https://bugs.webkit.org/show_bug.cgi?id=71522

Source/_javascript_Core: 

Reviewed by Gavin Barraclough.
        
Added a construct that looks like SamplingRegion samplingRegion("name").

* _javascript_Core.exp:
* _javascript_Core.xcodeproj/project.pbxproj:
* bytecode/SamplingTool.cpp:
(JSC::SamplingRegion::Locker::Locker):
(JSC::SamplingRegion::Locker::~Locker):
(JSC::SamplingRegion::sample):
(JSC::SamplingRegion::dump):
(JSC::SamplingRegion::dumpInternal):
(JSC::SamplingThread::threadStartFunc):
* bytecode/SamplingTool.h:
(JSC::SamplingRegion::SamplingRegion):
(JSC::SamplingRegion::~SamplingRegion):
(JSC::SamplingRegion::exchangeCurrent):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::generate):
* dfg/DFGDriver.cpp:
(JSC::DFG::compile):
* heap/Heap.cpp:
(JSC::Heap::markRoots):
(JSC::Heap::collect):
* heap/VTableSpectrum.cpp:
(JSC::VTableSpectrum::countVPtr):
(JSC::VTableSpectrum::dump):
* heap/VTableSpectrum.h:
* jsc.cpp:
(main):
(runWithScripts):
* parser/Parser.h:
(JSC::parse):
* runtime/Executable.cpp:
(JSC::EvalExecutable::compileInternal):
(JSC::ProgramExecutable::compileInternal):
(JSC::FunctionExecutable::compileForCallInternal):
(JSC::FunctionExecutable::compileForConstructInternal):
* wtf/Atomics.h:
(WTF::weakCompareAndSwap):
* wtf/Platform.h:
* wtf/Spectrum.h: Added.
(WTF::Spectrum::Spectrum):
(WTF::Spectrum::add):
(WTF::Spectrum::get):
(WTF::Spectrum::begin):
(WTF::Spectrum::end):
(WTF::Spectrum::KeyAndCount::KeyAndCount):
(WTF::Spectrum::KeyAndCount::operator<):
(WTF::Spectrum::buildList):
* wtf/wtf.pri:

Source/_javascript_Glue: 

Reviewed by Gavin Barraclough.
        
* ForwardingHeaders/wtf/Spectrum.h: Added.

Source/WebCore: 

Reviewed by Gavin Barraclough.

No new tests, since no functionality changed.

* ForwardingHeaders/wtf/Spectrum.h: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (99373 => 99374)


--- trunk/Source/_javascript_Core/ChangeLog	2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-11-06 11:39:12 UTC (rev 99374)
@@ -1,3 +1,60 @@
+2011-11-03  Filip Pizlo  <[email protected]>
+
+        JSC should be able to sample itself in a more flexible way than just sampling flags
+        https://bugs.webkit.org/show_bug.cgi?id=71522
+
+        Reviewed by Gavin Barraclough.
+        
+        Added a construct that looks like SamplingRegion samplingRegion("name").
+
+        * _javascript_Core.exp:
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * bytecode/SamplingTool.cpp:
+        (JSC::SamplingRegion::Locker::Locker):
+        (JSC::SamplingRegion::Locker::~Locker):
+        (JSC::SamplingRegion::sample):
+        (JSC::SamplingRegion::dump):
+        (JSC::SamplingRegion::dumpInternal):
+        (JSC::SamplingThread::threadStartFunc):
+        * bytecode/SamplingTool.h:
+        (JSC::SamplingRegion::SamplingRegion):
+        (JSC::SamplingRegion::~SamplingRegion):
+        (JSC::SamplingRegion::exchangeCurrent):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::generate):
+        * dfg/DFGDriver.cpp:
+        (JSC::DFG::compile):
+        * heap/Heap.cpp:
+        (JSC::Heap::markRoots):
+        (JSC::Heap::collect):
+        * heap/VTableSpectrum.cpp:
+        (JSC::VTableSpectrum::countVPtr):
+        (JSC::VTableSpectrum::dump):
+        * heap/VTableSpectrum.h:
+        * jsc.cpp:
+        (main):
+        (runWithScripts):
+        * parser/Parser.h:
+        (JSC::parse):
+        * runtime/Executable.cpp:
+        (JSC::EvalExecutable::compileInternal):
+        (JSC::ProgramExecutable::compileInternal):
+        (JSC::FunctionExecutable::compileForCallInternal):
+        (JSC::FunctionExecutable::compileForConstructInternal):
+        * wtf/Atomics.h:
+        (WTF::weakCompareAndSwap):
+        * wtf/Platform.h:
+        * wtf/Spectrum.h: Added.
+        (WTF::Spectrum::Spectrum):
+        (WTF::Spectrum::add):
+        (WTF::Spectrum::get):
+        (WTF::Spectrum::begin):
+        (WTF::Spectrum::end):
+        (WTF::Spectrum::KeyAndCount::KeyAndCount):
+        (WTF::Spectrum::KeyAndCount::operator<):
+        (WTF::Spectrum::buildList):
+        * wtf/wtf.pri:
+
 2011-11-05  Sam Weinig  <[email protected]>
 
         Fix windows build.

Modified: trunk/Source/_javascript_Core/_javascript_Core.exp (99373 => 99374)


--- trunk/Source/_javascript_Core/_javascript_Core.exp	2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/_javascript_Core.exp	2011-11-06 11:39:12 UTC (rev 99374)
@@ -179,6 +179,7 @@
 __ZN3JSC14JSGlobalObjectD2Ev
 __ZN3JSC14MachineThreads16addCurrentThreadEv
 __ZN3JSC14MarkStackArray6expandEv
+__ZN3JSC14SamplingRegion4dumpEv
 __ZN3JSC14SamplingThread4stopEv
 __ZN3JSC14SamplingThread5startEj
 __ZN3JSC14ScopeChainNode6s_infoE

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (99373 => 99374)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2011-11-06 11:39:12 UTC (rev 99374)
@@ -50,6 +50,7 @@
 		0BF28A2911A33DC300638F84 /* SizeLimits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0BF28A2811A33DC300638F84 /* SizeLimits.cpp */; };
 		0F16D726142C39C000CF784A /* BitVector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F16D724142C39A200CF784A /* BitVector.cpp */; };
 		0F242DA713F3B1E8007ADD4C /* WeakReferenceHarvester.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F242DA513F3B1BB007ADD4C /* WeakReferenceHarvester.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0F2E5BF7146357D5003EB2EB /* Spectrum.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2E5BF5146357D2003EB2EB /* Spectrum.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F426A481460CBB300131F8F /* ValueRecovery.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F426A451460CBAB00131F8F /* ValueRecovery.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F426A491460CBB700131F8F /* VirtualRegister.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F426A461460CBAB00131F8F /* VirtualRegister.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F426A4B1460CD6E00131F8F /* DataFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F426A4A1460CD6B00131F8F /* DataFormat.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -813,6 +814,7 @@
 		0BF28A2811A33DC300638F84 /* SizeLimits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SizeLimits.cpp; sourceTree = "<group>"; };
 		0F16D724142C39A200CF784A /* BitVector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BitVector.cpp; sourceTree = "<group>"; };
 		0F242DA513F3B1BB007ADD4C /* WeakReferenceHarvester.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakReferenceHarvester.h; sourceTree = "<group>"; };
+		0F2E5BF5146357D2003EB2EB /* Spectrum.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Spectrum.h; sourceTree = "<group>"; };
 		0F426A451460CBAB00131F8F /* ValueRecovery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValueRecovery.h; sourceTree = "<group>"; };
 		0F426A461460CBAB00131F8F /* VirtualRegister.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VirtualRegister.h; sourceTree = "<group>"; };
 		0F426A4A1460CD6B00131F8F /* DataFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataFormat.h; sourceTree = "<group>"; };
@@ -1855,6 +1857,7 @@
 		65162EF108E6A21C007556CD /* wtf */ = {
 			isa = PBXGroup;
 			children = (
+				0F2E5BF5146357D2003EB2EB /* Spectrum.h */,
 				0FD52AAC1430359D0026DC9F /* UnionFind.h */,
 				0F636D9F142D27D200B2E66A /* PackedIntVector.h */,
 				0F16D724142C39A200CF784A /* BitVector.cpp */,
@@ -2897,6 +2900,7 @@
 				0F426A481460CBB300131F8F /* ValueRecovery.h in Headers */,
 				0F426A491460CBB700131F8F /* VirtualRegister.h in Headers */,
 				0F426A4B1460CD6E00131F8F /* DataFormat.h in Headers */,
+				0F2E5BF7146357D5003EB2EB /* Spectrum.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

Modified: trunk/Source/_javascript_Core/bytecode/SamplingTool.cpp (99373 => 99374)


--- trunk/Source/_javascript_Core/bytecode/SamplingTool.cpp	2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/bytecode/SamplingTool.cpp	2011-11-06 11:39:12 UTC (rev 99374)
@@ -83,6 +83,93 @@
 void SamplingFlags::stop() {}
 #endif
 
+#if ENABLE(SAMPLING_REGIONS)
+volatile uintptr_t SamplingRegion::s_currentOrReserved;
+Spectrum<const char*>* SamplingRegion::s_spectrum;
+unsigned long SamplingRegion::s_noneOfTheAbove;
+unsigned SamplingRegion::s_numberOfSamplesSinceDump;
+
+SamplingRegion::Locker::Locker()
+{
+    uintptr_t previous;
+    while (true) {
+        previous = s_currentOrReserved;
+        if (previous & 1) {
+#if OS(UNIX)
+            sched_yield();
+#endif
+            continue;
+        }
+        if (WTF::weakCompareAndSwap(&s_currentOrReserved, previous, previous | 1))
+            break;
+    }
+}
+
+SamplingRegion::Locker::~Locker()
+{
+    // We don't need the CAS, but we do it out of an
+    // abundance of caution (and because it gives us a memory fence, which is
+    // never bad).
+    uintptr_t previous;
+    do {
+        previous = s_currentOrReserved;
+    } while (!WTF::weakCompareAndSwap(&s_currentOrReserved, previous, previous & ~1));
+}
+
+void SamplingRegion::sample()
+{
+    // Make sure we lock s_current.
+    Locker locker;
+    
+    // Create a spectrum if we don't have one already.
+    if (!s_spectrum)
+        s_spectrum = new Spectrum<const char*>();
+    
+    ASSERT(s_currentOrReserved & 1);
+    
+    // Walk the region stack, and record each region we see.
+    SamplingRegion* region = bitwise_cast<SamplingRegion*>(s_currentOrReserved & ~1);
+    if (region) {
+        for (; region; region = region->m_previous)
+            s_spectrum->add(region->m_name);
+    } else
+        s_noneOfTheAbove++;
+    
+    if (s_numberOfSamplesSinceDump++ == SamplingThread::s_hertz) {
+        s_numberOfSamplesSinceDump = 0;
+        dumpInternal();
+    }
+}
+
+void SamplingRegion::dump()
+{
+    Locker locker;
+    
+    dumpInternal();
+}
+
+void SamplingRegion::dumpInternal()
+{
+    if (!s_spectrum) {
+        printf("\nSamplingRegion: was never sampled.\n\n");
+        return;
+    }
+    
+    Vector<Spectrum<const char*>::KeyAndCount> list = s_spectrum->buildList();
+    
+    unsigned long total = s_noneOfTheAbove;
+    for (unsigned i = list.size(); i--;)
+        total += list[i].count;
+    
+    printf("\nSamplingRegion: sample counts for regions: (%lu samples)\n", total);
+
+    for (unsigned i = list.size(); i--;)
+        printf("    %3.2lf%%  %s\n", (100.0 * list[i].count) / total, list[i].key);
+}
+#else // ENABLE(SAMPLING_REGIONS)
+void SamplingRegion::dump() { }
+#endif // ENABLE(SAMPLING_REGIONS)
+
 /*
   Start with flag 16 set.
   By doing this the monitoring of lower valued flags will be masked out
@@ -131,6 +218,9 @@
 #if ENABLE(SAMPLING_FLAGS)
         SamplingFlags::sample();
 #endif
+#if ENABLE(SAMPLING_REGIONS)
+        SamplingRegion::sample();
+#endif
 #if ENABLE(OPCODE_SAMPLING)
         SamplingTool::sample();
 #endif

Modified: trunk/Source/_javascript_Core/bytecode/SamplingTool.h (99373 => 99374)


--- trunk/Source/_javascript_Core/bytecode/SamplingTool.h	2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/bytecode/SamplingTool.h	2011-11-06 11:39:12 UTC (rev 99374)
@@ -34,7 +34,9 @@
 #include "Opcode.h"
 #include "SamplingCounter.h"
 #include <wtf/Assertions.h>
+#include <wtf/Atomics.h>
 #include <wtf/HashMap.h>
+#include <wtf/MainThread.h>
 #include <wtf/Threading.h>
 
 namespace JSC {
@@ -93,6 +95,89 @@
 #endif
     };
 
+#if ENABLE(SAMPLING_REGIONS)
+    class SamplingRegion {
+    public:
+        // Create a scoped sampling region using a C string constant name that describes
+        // what you are doing. This must be a string constant that persists for the
+        // lifetime of the process and is immutable.
+        SamplingRegion(const char* name)
+        {
+            if (!isMainThread()) {
+                m_name = 0;
+                return;
+            }
+            
+            m_name = name;
+            exchangeCurrent(this, &m_previous);
+            ASSERT(!m_previous || m_previous > this);
+        }
+        
+        ~SamplingRegion()
+        {
+            if (!m_name)
+                return;
+            
+            ASSERT(bitwise_cast<SamplingRegion*>(s_currentOrReserved & ~1) == this);
+            exchangeCurrent(m_previous);
+        }
+        
+        static void sample();
+        
+        static void dump();
+        
+    private:
+        const char* m_name;
+        SamplingRegion* m_previous;
+
+        static void exchangeCurrent(SamplingRegion* current, SamplingRegion** previousPtr = 0)
+        {
+            uintptr_t previous;
+            while (true) {
+                previous = s_currentOrReserved;
+                
+                // If it's reserved (i.e. sampling thread is reading it), loop around.
+                if (previous & 1) {
+#if OS(UNIX)
+                    sched_yield();
+#endif
+                    continue;
+                }
+                
+                // If we're going to CAS, then make sure previous is set.
+                if (previousPtr)
+                    *previousPtr = bitwise_cast<SamplingRegion*>(previous);
+                
+                if (WTF::weakCompareAndSwap(&s_currentOrReserved, previous, bitwise_cast<uintptr_t>(current)))
+                    break;
+            }
+        }
+        
+        static void dumpInternal();
+
+        class Locker {
+        public:
+            Locker();
+            ~Locker();
+        };
+
+        static volatile uintptr_t s_currentOrReserved;
+        
+        // rely on identity hashing of string constants
+        static Spectrum<const char*>* s_spectrum;
+        
+        static unsigned long s_noneOfTheAbove;
+        
+        static unsigned s_numberOfSamplesSinceDump;
+    };
+#else // ENABLE(SAMPLING_REGIONS)
+    class SamplingRegion {
+    public:
+        SamplingRegion(const char*) { }
+        void dump();
+    };
+#endif // ENABLE(SAMPLING_REGIONS)
+
     class CodeBlock;
     class ExecState;
     class Interpreter;

Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (99373 => 99374)


--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2011-11-06 11:39:12 UTC (rev 99374)
@@ -140,6 +140,8 @@
 
 JSObject* BytecodeGenerator::generate()
 {
+    SamplingRegion samplingRegion("Bytecode Generation");
+    
     m_codeBlock->setThisRegister(m_thisRegister.index());
 
     m_scopeNode->emitBytecode(*this);

Modified: trunk/Source/_javascript_Core/dfg/DFGDriver.cpp (99373 => 99374)


--- trunk/Source/_javascript_Core/dfg/DFGDriver.cpp	2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/dfg/DFGDriver.cpp	2011-11-06 11:39:12 UTC (rev 99374)
@@ -37,6 +37,8 @@
 enum CompileMode { CompileFunction, CompileOther };
 inline bool compile(CompileMode compileMode, ExecState* exec, CodeBlock* codeBlock, JITCode& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck)
 {
+    SamplingRegion samplingRegion("DFG Compilation (Driver)");
+    
     JSGlobalData* globalData = &exec->globalData();
     Graph dfg;
     if (!parse(dfg, globalData, codeBlock))

Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (99373 => 99374)


--- trunk/Source/_javascript_Core/heap/Heap.cpp	2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp	2011-11-06 11:39:12 UTC (rev 99374)
@@ -553,6 +553,8 @@
 
 void Heap::markRoots(bool fullGC)
 {
+    SamplingRegion samplingRegion("Garbage Collection: Tracing");
+
     COND_GCPHASE(fullGC, MarkFullRoots, MarkYoungRoots);
     UNUSED_PARAM(fullGC);
     ASSERT(isValidThreadState(m_globalData));
@@ -759,6 +761,8 @@
 
 void Heap::collect(SweepToggle sweepToggle)
 {
+    SamplingRegion samplingRegion("Garbage Collection");
+    
     GCPHASE(Collect);
     ASSERT(globalData()->identifierTable == wtfThreadData().currentIdentifierTable());
     ASSERT(m_isSafeToCollect);
@@ -792,6 +796,7 @@
     }
 
     if (sweepToggle == DoSweep) {
+        SamplingRegion samplingRegion("Garbage Collection: Sweeping");
         GCPHASE(Sweeping);
         sweep();
         shrink();

Modified: trunk/Source/_javascript_Core/heap/VTableSpectrum.cpp (99373 => 99374)


--- trunk/Source/_javascript_Core/heap/VTableSpectrum.cpp	2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/heap/VTableSpectrum.cpp	2011-11-06 11:39:12 UTC (rev 99374)
@@ -49,9 +49,7 @@
 
 void VTableSpectrum::countVPtr(void* vTablePointer)
 {
-    std::pair<HashMap<void*, unsigned long>::iterator, bool> result = m_map.add(vTablePointer, 1);
-    if (!result.second)
-        result.first->second++;
+    add(vTablePointer);
 }
 
 void VTableSpectrum::count(JSCell* cell)
@@ -59,45 +57,17 @@
     countVPtr(cell->vptr());
 }
 
-struct VTableAndCount {
-    void* vtable;
-    unsigned long count;
-    
-    VTableAndCount() { }
-    
-    VTableAndCount(void* vtable, unsigned long count)
-        : vtable(vtable)
-        , count(count)
-    {
-    }
-    
-    bool operator<(const VTableAndCount& other) const
-    {
-        if (count != other.count)
-            return count < other.count;
-        return vtable > other.vtable; // this results in lower-addressed vtables being printed first
-    }
-};
-
 void VTableSpectrum::dump(FILE* output, const char* comment)
 {
     fprintf(output, "%s:\n", comment);
     
-    HashMap<void*, unsigned long>::iterator begin = m_map.begin();
-    HashMap<void*, unsigned long>::iterator end = m_map.end();
+    Vector<KeyAndCount> list = buildList();
     
-    Vector<VTableAndCount, 0> list;
-    
-    for (HashMap<void*, unsigned long>::iterator iter = begin; iter != end; ++iter)
-        list.append(VTableAndCount(iter->first, iter->second));
-    
-    std::sort(list.begin(), list.end());
-    
     for (size_t index = list.size(); index-- > 0;) {
-        VTableAndCount item = list.at(index);
+        KeyAndCount item = list.at(index);
 #if PLATFORM(MAC)
         Dl_info info;
-        if (dladdr(item.vtable, &info)) {
+        if (dladdr(item.key, &info)) {
             char* findResult = strrchr(info.dli_fname, '/');
             const char* strippedFileName;
             
@@ -106,11 +76,11 @@
             else
                 strippedFileName = info.dli_fname;
             
-            fprintf(output, "    %s:%s(%p): %lu\n", strippedFileName, info.dli_sname, item.vtable, item.count);
+            fprintf(output, "    %s:%s(%p): %lu\n", strippedFileName, info.dli_sname, item.key, item.count);
             continue;
         }
 #endif
-        fprintf(output, "    %p: %lu\n", item.vtable, item.count);
+        fprintf(output, "    %p: %lu\n", item.key, item.count);
     }
     
     fflush(output);

Modified: trunk/Source/_javascript_Core/heap/VTableSpectrum.h (99373 => 99374)


--- trunk/Source/_javascript_Core/heap/VTableSpectrum.h	2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/heap/VTableSpectrum.h	2011-11-06 11:39:12 UTC (rev 99374)
@@ -27,13 +27,13 @@
 #define VTableSpectrum_h
 
 #include <stdio.h>
-#include <wtf/HashMap.h>
+#include <wtf/Spectrum.h>
 
 namespace JSC {
 
 class JSCell;
 
-class VTableSpectrum {
+class VTableSpectrum: Spectrum<void*> {
 public:
     VTableSpectrum();
     ~VTableSpectrum();
@@ -42,9 +42,6 @@
     void count(JSCell*);
     
     void dump(FILE* output, const char* comment);
-    
-private:
-    HashMap<void*, unsigned long> m_map;
 };
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/jsc.cpp (99373 => 99374)


--- trunk/Source/_javascript_Core/jsc.cpp	2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/jsc.cpp	2011-11-06 11:39:12 UTC (rev 99374)
@@ -31,6 +31,7 @@
 #include "JSFunction.h"
 #include "JSLock.h"
 #include "JSString.h"
+#include "MainThread.h"
 #include "SamplingTool.h"
 #include <math.h>
 #include <stdio.h>
@@ -404,6 +405,7 @@
 #endif
 
     // Initialize JSC before getting JSGlobalData.
+    WTF::initializeMainThread();
     JSC::initializeThreading();
 
     // We can't use destructors in the following code because it uses Windows
@@ -472,6 +474,9 @@
 #if ENABLE(SAMPLING_FLAGS)
     SamplingFlags::stop();
 #endif
+#if ENABLE(SAMPLING_REGIONS)
+    SamplingRegion::dump();
+#endif
     globalData.dumpSampleData(globalObject->globalExec());
 #if ENABLE(SAMPLING_COUNTERS)
     AbstractSamplingCounter::dump();

Modified: trunk/Source/_javascript_Core/parser/Parser.h (99373 => 99374)


--- trunk/Source/_javascript_Core/parser/Parser.h	2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/parser/Parser.h	2011-11-06 11:39:12 UTC (rev 99374)
@@ -1029,6 +1029,7 @@
 template <class ParsedNode>
 PassRefPtr<ParsedNode> parse(JSGlobalData* globalData, JSGlobalObject* lexicalGlobalObject, const SourceCode& source, FunctionParameters* parameters, JSParserStrictness strictness, JSParserMode parserMode, Debugger* debugger, ExecState* execState, JSObject** exception)
 {
+    SamplingRegion samplingRegion("Parsing");
     Parser parser(globalData, source, parameters, strictness, parserMode);
     return parser.parse<ParsedNode>(lexicalGlobalObject, debugger, execState, exception);
 }

Modified: trunk/Source/_javascript_Core/runtime/Executable.cpp (99373 => 99374)


--- trunk/Source/_javascript_Core/runtime/Executable.cpp	2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/runtime/Executable.cpp	2011-11-06 11:39:12 UTC (rev 99374)
@@ -148,6 +148,8 @@
 
 JSObject* EvalExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
 {
+    SamplingRegion samplingRegion(jitType == JITCode::BaselineJIT ? "Baseline Compilation (TOTAL)" : "DFG Compilation (TOTAL)");
+    
 #if !ENABLE(JIT)
     UNUSED_PARAM(jitType);
 #endif
@@ -280,6 +282,8 @@
 
 JSObject* ProgramExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
 {
+    SamplingRegion samplingRegion(jitType == JITCode::BaselineJIT ? "Baseline Compilation (TOTAL)" : "DFG Compilation (TOTAL)");
+    
 #if !ENABLE(JIT)
     UNUSED_PARAM(jitType);
 #endif
@@ -455,6 +459,8 @@
 
 JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
 {
+    SamplingRegion samplingRegion(jitType == JITCode::BaselineJIT ? "Baseline Compilation (TOTAL)" : "DFG Compilation (TOTAL)");
+    
 #if !ENABLE(JIT)
     UNUSED_PARAM(exec);
     UNUSED_PARAM(jitType);
@@ -515,6 +521,8 @@
 
 JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
 {
+    SamplingRegion samplingRegion(jitType == JITCode::BaselineJIT ? "Baseline Compilation (TOTAL)" : "DFG Compilation (TOTAL)");
+    
 #if !ENABLE(JIT)
     UNUSED_PARAM(jitType);
     UNUSED_PARAM(exec);

Modified: trunk/Source/_javascript_Core/wtf/Atomics.h (99373 => 99374)


--- trunk/Source/_javascript_Core/wtf/Atomics.h	2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/wtf/Atomics.h	2011-11-06 11:39:12 UTC (rev 99374)
@@ -126,7 +126,7 @@
     asm volatile(
         "lock; cmpxchgl %3, %2\n\t"
         "sete %1"
-        : "+a"(expected), "=r"(result), "+m"(*location)
+        : "+a"(expected), "=q"(result), "+m"(*location)
         : "r"(newValue)
         : "memory"
         );
@@ -140,6 +140,38 @@
 #endif
 }
 
+inline bool weakCompareAndSwap(void*volatile* location, void* expected, void* newValue)
+{
+    // FIXME: Implement COMPARE_AND_SWAP on other architectures and compilers. Currently
+    // it only works on X86 or X86_64 with a GCC-style compiler.
+#if ENABLE(COMPARE_AND_SWAP)
+    bool result;
+    asm volatile(
+#if CPU(X86_64)
+        "lock; cmpxchgq %3, %2\n\t"
+#else
+        "lock; cmpxchgl %3, %2\n\t"
+#endif
+        "sete %1"
+        : "+a"(expected), "=q"(result), "+m"(*location)
+        : "r"(newValue)
+        : "memory"
+        );
+    return result;
+#else // ENABLE(COMPARE_AND_SWAP)
+    UNUSED_PARAM(location);
+    UNUSED_PARAM(expected);
+    UNUSED_PARAM(newValue);
+    CRASH();
+    return 0;
+#endif // ENABLE(COMPARE_AND_SWAP)
+}
+
+inline bool weakCompareAndSwap(volatile uintptr_t* location, uintptr_t expected, uintptr_t newValue)
+{
+    return weakCompareAndSwap(reinterpret_cast<void*volatile*>(location), reinterpret_cast<void*>(expected), reinterpret_cast<void*>(newValue));
+}
+
 } // namespace WTF
 
 #if USE(LOCKFREE_THREADSAFEREFCOUNTED)

Modified: trunk/Source/_javascript_Core/wtf/Platform.h (99373 => 99374)


--- trunk/Source/_javascript_Core/wtf/Platform.h	2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/wtf/Platform.h	2011-11-06 11:39:12 UTC (rev 99374)
@@ -808,12 +808,13 @@
 #define ENABLE_DEBUG_WITH_BREAKPOINT 0
 #define ENABLE_SAMPLING_COUNTERS 0
 #define ENABLE_SAMPLING_FLAGS 0
+#define ENABLE_SAMPLING_REGIONS 0
 #define ENABLE_OPCODE_SAMPLING 0
 #define ENABLE_CODEBLOCK_SAMPLING 0
 #if ENABLE(CODEBLOCK_SAMPLING) && !ENABLE(OPCODE_SAMPLING)
 #error "CODEBLOCK_SAMPLING requires OPCODE_SAMPLING"
 #endif
-#if ENABLE(OPCODE_SAMPLING) || ENABLE(SAMPLING_FLAGS)
+#if ENABLE(OPCODE_SAMPLING) || ENABLE(SAMPLING_FLAGS) || ENABLE(SAMPLING_REGIONS)
 #define ENABLE_SAMPLING_THREAD 1
 #endif
 

Added: trunk/Source/_javascript_Core/wtf/Spectrum.h (0 => 99374)


--- trunk/Source/_javascript_Core/wtf/Spectrum.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/wtf/Spectrum.h	2011-11-06 11:39:12 UTC (rev 99374)
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ *
+ * 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 Spectrum_h
+#define Spectrum_h
+
+#include "HashMap.h"
+#include "Vector.h"
+#include <algorithm>
+
+namespace WTF {
+
+template<typename T>
+class Spectrum {
+public:
+    typedef typename HashMap<T, unsigned long>::iterator iterator;
+    typedef typename HashMap<T, unsigned long>::const_iterator const_iterator;
+    
+    Spectrum() { }
+    
+    void add(const T& key, unsigned long count = 1)
+    {
+        std::pair<iterator, bool> result = m_map.add(key, count);
+        if (!result.second)
+            result.first->second += count;
+    }
+    
+    unsigned long get(const T& key) const
+    {
+        const_iterator iter = m_map.find(key);
+        if (iter == m_map.end())
+            return 0;
+        return iter->second;
+    }
+    
+    iterator begin() { return m_map.begin(); }
+    iterator end() { return m_map.end(); }
+    const_iterator begin() const { return m_map.begin(); }
+    const_iterator end() const { return m_map.end(); }
+    
+    struct KeyAndCount {
+        KeyAndCount() { }
+        
+        KeyAndCount(const T& key, unsigned long count)
+            : key(key)
+            , count(count)
+        {
+        }
+        
+        bool operator<(const KeyAndCount& other) const
+        {
+            if (count != other.count)
+                return count < other.count;
+            // This causes lower-ordered keys being returned first; this is really just
+            // here to make sure that the order is somewhat deterministic rather than being
+            // determined by hashing.
+            return key > other.key;
+        }
+
+        T key;
+        unsigned long count;
+    };
+    
+    // Returns a list ordered from lowest-count to highest-count.
+    Vector<KeyAndCount> buildList() const
+    {
+        Vector<KeyAndCount> list;
+        for (const_iterator iter = begin(); iter != end(); ++iter)
+            list.append(KeyAndCount(iter->first, iter->second));
+        
+        std::sort(list.begin(), list.end());
+        return list;
+    }
+    
+private:
+    HashMap<T, unsigned long> m_map;
+};
+
+} // namespace WTF
+
+using WTF::Spectrum;
+
+#endif // Spectrum_h

Modified: trunk/Source/_javascript_Core/wtf/wtf.pri (99373 => 99374)


--- trunk/Source/_javascript_Core/wtf/wtf.pri	2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/wtf/wtf.pri	2011-11-06 11:39:12 UTC (rev 99374)
@@ -97,6 +97,7 @@
     wtf/RefPtrHashMap.h \
     wtf/RetainPtr.h \
     wtf/SHA1.h \
+    wtf/Spectrum.h \
     wtf/StackBounds.h \
     wtf/StaticConstructors.h \
     wtf/StdLibExtras.h \

Modified: trunk/Source/_javascript_Glue/ChangeLog (99373 => 99374)


--- trunk/Source/_javascript_Glue/ChangeLog	2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Glue/ChangeLog	2011-11-06 11:39:12 UTC (rev 99374)
@@ -1,3 +1,12 @@
+2011-11-03  Filip Pizlo  <[email protected]>
+
+        JSC should be able to sample itself in a more flexible way than just sampling flags
+        https://bugs.webkit.org/show_bug.cgi?id=71522
+
+        Reviewed by Gavin Barraclough.
+        
+        * ForwardingHeaders/wtf/Spectrum.h: Added.
+
 2011-11-03  Mark Hahnenberg  <[email protected]>
 
         De-virtualize JSObject::getPropertyNames

Added: trunk/Source/_javascript_Glue/ForwardingHeaders/wtf/Spectrum.h (0 => 99374)


--- trunk/Source/_javascript_Glue/ForwardingHeaders/wtf/Spectrum.h	                        (rev 0)
+++ trunk/Source/_javascript_Glue/ForwardingHeaders/wtf/Spectrum.h	2011-11-06 11:39:12 UTC (rev 99374)
@@ -0,0 +1 @@
+#include <_javascript_Core/Spectrum.h>

Modified: trunk/Source/WebCore/ChangeLog (99373 => 99374)


--- trunk/Source/WebCore/ChangeLog	2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/WebCore/ChangeLog	2011-11-06 11:39:12 UTC (rev 99374)
@@ -1,3 +1,14 @@
+2011-11-03  Filip Pizlo  <[email protected]>
+
+        JSC should be able to sample itself in a more flexible way than just sampling flags
+        https://bugs.webkit.org/show_bug.cgi?id=71522
+
+        Reviewed by Gavin Barraclough.
+
+        No new tests, since no functionality changed.
+
+        * ForwardingHeaders/wtf/Spectrum.h: Added.
+
 2011-11-06  Nikita Vasilyev  <[email protected]>
 
         Web Inspector: Unindent edited text by pressing Shift + Tab

Added: trunk/Source/WebCore/ForwardingHeaders/wtf/Spectrum.h (0 => 99374)


--- trunk/Source/WebCore/ForwardingHeaders/wtf/Spectrum.h	                        (rev 0)
+++ trunk/Source/WebCore/ForwardingHeaders/wtf/Spectrum.h	2011-11-06 11:39:12 UTC (rev 99374)
@@ -0,0 +1 @@
+#include <_javascript_Core/Spectrum.h>
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to