Title: [153143] trunk/Source/_javascript_Core
Revision
153143
Author
oli...@apple.com
Date
2013-07-24 20:59:31 -0700 (Wed, 24 Jul 2013)

Log Message

fourthTier: Profiler should be thread-safe
https://bugs.webkit.org/show_bug.cgi?id=115445

Reviewed by Geoffrey Garen.

Change the Profiler::Database API for Compilation creation so that we don't add
it to the Database until it's completely constructed. This prevents the Database
from seeing Compilations that are being concurrently constructed.

Change the Profiler::Database itself to do locking for creation of Bytecodes and
for modifying the map. This map may be consulted by both the main thread and the
concurrent thread.

* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::Graph):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::link):
(JSC::DFG::JITCompiler::linkFunction):
* jit/JIT.cpp:
(JSC::JIT::privateCompile):
* profiler/ProfilerBytecodes.h:
* profiler/ProfilerDatabase.cpp:
(JSC::Profiler::Database::ensureBytecodesFor):
(JSC::Profiler::Database::notifyDestruction):
(JSC::Profiler::Database::addCompilation):
* profiler/ProfilerDatabase.h:
(Database):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (153142 => 153143)


--- trunk/Source/_javascript_Core/ChangeLog	2013-07-25 03:59:29 UTC (rev 153142)
+++ trunk/Source/_javascript_Core/ChangeLog	2013-07-25 03:59:31 UTC (rev 153143)
@@ -1,5 +1,35 @@
 2013-05-02  Filip Pizlo  <fpi...@apple.com>
 
+        fourthTier: Profiler should be thread-safe
+        https://bugs.webkit.org/show_bug.cgi?id=115445
+
+        Reviewed by Geoffrey Garen.
+        
+        Change the Profiler::Database API for Compilation creation so that we don't add
+        it to the Database until it's completely constructed. This prevents the Database
+        from seeing Compilations that are being concurrently constructed.
+        
+        Change the Profiler::Database itself to do locking for creation of Bytecodes and
+        for modifying the map. This map may be consulted by both the main thread and the
+        concurrent thread.
+
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::Graph):
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::link):
+        (JSC::DFG::JITCompiler::linkFunction):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompile):
+        * profiler/ProfilerBytecodes.h:
+        * profiler/ProfilerDatabase.cpp:
+        (JSC::Profiler::Database::ensureBytecodesFor):
+        (JSC::Profiler::Database::notifyDestruction):
+        (JSC::Profiler::Database::addCompilation):
+        * profiler/ProfilerDatabase.h:
+        (Database):
+
+2013-05-02  Filip Pizlo  <fpi...@apple.com>
+
         fourthTier: DFG tries to ref/deref StringImpls in a ton of places
         https://bugs.webkit.org/show_bug.cgi?id=115300
 

Modified: trunk/Source/_javascript_Core/dfg/DFGGraph.cpp (153142 => 153143)


--- trunk/Source/_javascript_Core/dfg/DFGGraph.cpp	2013-07-25 03:59:29 UTC (rev 153142)
+++ trunk/Source/_javascript_Core/dfg/DFGGraph.cpp	2013-07-25 03:59:31 UTC (rev 153143)
@@ -47,7 +47,7 @@
 Graph::Graph(VM& vm, CodeBlock* codeBlock, unsigned osrEntryBytecodeIndex, const Operands<JSValue>& mustHandleValues)
     : m_vm(vm)
     , m_codeBlock(codeBlock)
-    , m_compilation(vm.m_perBytecodeProfiler ? vm.m_perBytecodeProfiler->newCompilation(codeBlock, Profiler::DFG) : 0)
+    , m_compilation(vm.m_perBytecodeProfiler ? adoptRef(new Profiler::Compilation(vm.m_perBytecodeProfiler->ensureBytecodesFor(codeBlock), Profiler::DFG)) : 0)
     , m_profiledBlock(codeBlock->alternative())
     , m_allocator(vm.m_dfgState->m_allocator)
     , m_hasArguments(false)

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp (153142 => 153143)


--- trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp	2013-07-25 03:59:29 UTC (rev 153142)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp	2013-07-25 03:59:31 UTC (rev 153143)
@@ -286,8 +286,10 @@
 
     if (shouldShowDisassembly())
         m_disassembler->dump(linkBuffer);
-    if (m_graph.m_compilation)
+    if (m_graph.m_compilation) {
         m_disassembler->reportToProfiler(m_graph.m_compilation.get(), linkBuffer);
+        m_vm->m_perBytecodeProfiler->addCompilation(m_graph.m_compilation);
+    }
 
     m_jitCode->initializeCodeRef(linkBuffer.finalizeCodeWithoutDisassembly());
     entry = m_jitCode;
@@ -389,8 +391,10 @@
     
     if (shouldShowDisassembly())
         m_disassembler->dump(linkBuffer);
-    if (m_graph.m_compilation)
+    if (m_graph.m_compilation) {
         m_disassembler->reportToProfiler(m_graph.m_compilation.get(), linkBuffer);
+        m_vm->m_perBytecodeProfiler->addCompilation(m_graph.m_compilation);
+    }
 
     entryWithArityCheck = linkBuffer.locationOf(m_arityCheck);
     m_jitCode->initializeCodeRef(linkBuffer.finalizeCodeWithoutDisassembly());

Modified: trunk/Source/_javascript_Core/jit/JIT.cpp (153142 => 153143)


--- trunk/Source/_javascript_Core/jit/JIT.cpp	2013-07-25 03:59:29 UTC (rev 153142)
+++ trunk/Source/_javascript_Core/jit/JIT.cpp	2013-07-25 03:59:31 UTC (rev 153143)
@@ -594,7 +594,10 @@
     if (Options::showDisassembly() || m_vm->m_perBytecodeProfiler)
         m_disassembler = adoptPtr(new JITDisassembler(m_codeBlock));
     if (m_vm->m_perBytecodeProfiler) {
-        m_compilation = m_vm->m_perBytecodeProfiler->newCompilation(m_codeBlock, Profiler::Baseline);
+        m_compilation = adoptRef(
+            new Profiler::Compilation(
+                m_vm->m_perBytecodeProfiler->ensureBytecodesFor(m_codeBlock),
+                Profiler::Baseline));
         m_compilation->addProfiledBytecodes(*m_vm->m_perBytecodeProfiler, m_codeBlock);
     }
     
@@ -784,8 +787,10 @@
 
     if (Options::showDisassembly())
         m_disassembler->dump(patchBuffer);
-    if (m_compilation)
+    if (m_compilation) {
         m_disassembler->reportToProfiler(m_compilation.get(), patchBuffer);
+        m_vm->m_perBytecodeProfiler->addCompilation(m_compilation);
+    }
     
     CodeRef result = patchBuffer.finalizeCodeWithoutDisassembly();
     

Modified: trunk/Source/_javascript_Core/profiler/ProfilerBytecodes.h (153142 => 153143)


--- trunk/Source/_javascript_Core/profiler/ProfilerBytecodes.h	2013-07-25 03:59:29 UTC (rev 153142)
+++ trunk/Source/_javascript_Core/profiler/ProfilerBytecodes.h	2013-07-25 03:59:31 UTC (rev 153143)
@@ -29,6 +29,7 @@
 #include "CodeBlockHash.h"
 #include "JSCJSValue.h"
 #include "ProfilerBytecodeSequence.h"
+#include <wtf/ByteSpinLock.h>
 #include <wtf/PrintStream.h>
 #include <wtf/text/WTFString.h>
 

Modified: trunk/Source/_javascript_Core/profiler/ProfilerDatabase.cpp (153142 => 153143)


--- trunk/Source/_javascript_Core/profiler/ProfilerDatabase.cpp	2013-07-25 03:59:29 UTC (rev 153142)
+++ trunk/Source/_javascript_Core/profiler/ProfilerDatabase.cpp	2013-07-25 03:59:31 UTC (rev 153143)
@@ -60,6 +60,8 @@
 
 Bytecodes* Database::ensureBytecodesFor(CodeBlock* codeBlock)
 {
+    Locker locker(m_lock);
+    
     codeBlock = codeBlock->baselineVersion();
     
     HashMap<CodeBlock*, Bytecodes*>::iterator iter = m_bytecodesMap.find(codeBlock);
@@ -76,21 +78,18 @@
 
 void Database::notifyDestruction(CodeBlock* codeBlock)
 {
+    Locker locker(m_lock);
+    
     m_bytecodesMap.remove(codeBlock);
 }
 
-PassRefPtr<Compilation> Database::newCompilation(Bytecodes* bytecodes, CompilationKind kind)
+void Database::addCompilation(PassRefPtr<Compilation> compilation)
 {
-    RefPtr<Compilation> compilation = adoptRef(new Compilation(bytecodes, kind));
+    ASSERT(!isCompilationThread());
+    
     m_compilations.append(compilation);
-    return compilation.release();
 }
 
-PassRefPtr<Compilation> Database::newCompilation(CodeBlock* codeBlock, CompilationKind kind)
-{
-    return newCompilation(ensureBytecodesFor(codeBlock), kind);
-}
-
 JSValue Database::toJS(ExecState* exec) const
 {
     JSObject* result = constructEmptyObject(exec);

Modified: trunk/Source/_javascript_Core/profiler/ProfilerDatabase.h (153142 => 153143)


--- trunk/Source/_javascript_Core/profiler/ProfilerDatabase.h	2013-07-25 03:59:29 UTC (rev 153142)
+++ trunk/Source/_javascript_Core/profiler/ProfilerDatabase.h	2013-07-25 03:59:31 UTC (rev 153143)
@@ -35,6 +35,7 @@
 #include <wtf/Noncopyable.h>
 #include <wtf/PassRefPtr.h>
 #include <wtf/SegmentedVector.h>
+#include <wtf/ThreadingPrimitives.h>
 #include <wtf/text/WTFString.h>
 
 namespace JSC { namespace Profiler {
@@ -50,8 +51,7 @@
     Bytecodes* ensureBytecodesFor(CodeBlock*);
     void notifyDestruction(CodeBlock*);
     
-    PassRefPtr<Compilation> newCompilation(CodeBlock*, CompilationKind);
-    PassRefPtr<Compilation> newCompilation(Bytecodes*, CompilationKind);
+    void addCompilation(PassRefPtr<Compilation>);
     
     // Converts the database to a _javascript_ object that is suitable for JSON stringification.
     // Note that it's probably a good idea to use an ExecState* associated with a global
@@ -70,6 +70,20 @@
     void registerToSaveAtExit(const char* filename);
     
 private:
+    // Use a full-blown adaptive mutex because:
+    // - There is only one ProfilerDatabase per VM. The size overhead of the system's
+    //   mutex is negligible if you only have one of them.
+    // - It's locked infrequently - once per bytecode generation, compilation, and
+    //   code block collection - so the fact that the fast path still requires a
+    //   function call is neglible.
+    // - It tends to be held for a while. Currently, we hold it while generating
+    //   Profiler::Bytecodes for a CodeBlock. That's uncommon and shouldn't affect
+    //   performance, but if we did have contention, we would want a sensible,
+    //   power-aware backoff. An adaptive mutex will do this as a matter of course,
+    //   but a spinlock won't.
+    typedef Mutex Lock;
+    typedef MutexLocker Locker;
+    
 
     void addDatabaseToAtExit();
     void removeDatabaseFromAtExit();
@@ -85,6 +99,7 @@
     bool m_shouldSaveAtExit;
     CString m_atExitSaveFilename;
     Database* m_nextRegisteredDatabase;
+    Lock m_lock;
 };
 
 } } // namespace JSC::Profiler
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to