Title: [249740] trunk/Source/_javascript_Core
Revision
249740
Author
ysuz...@apple.com
Date
2019-09-10 16:18:11 -0700 (Tue, 10 Sep 2019)

Log Message

[JSC] CodeBlock::calleeSaveRegisters should not see half-baked JITData
https://bugs.webkit.org/show_bug.cgi?id=201664
<rdar://problem/52126927>

Reviewed by Tadeu Zagallo.

We are hitting the crash accessing invalid-pointer as CodeBlock::calleeSaveRegisters result.
This is because concurrent Baseline JIT compiler can access m_jitData without taking a lock through CodeBlock::calleeSaveRegisters.
Since m_jitData can be initialized in the main thread while calling CodeBlock::calleeSaveRegisters from concurrent Baseline JIT compiler thread,
we can see half-baked JITData structure which holds garbage pointers.

But we do not want to make CodeBlock::calleeSaveRegisters() call with CodeBlock::m_lock due to several reasons.

1. This function is very primitive one and it is called from various AssemblyHelpers functions and other code-generation functions. Some of these functions are
   called while taking this exact same lock, so dead-lock can happen.
2. JITData::m_calleeSaveRegisters is filled only for DFG and FTL CodeBlock. And DFG and FTL code accesses these field after initializing properly. For Baseline JIT
   compiler case, only thing we should do is that JITData should say m_calleeSaveRegisters is nullptr and it won't be filled for this CodeBlock.

Instead of guarding CodeBlock::calleeSaveRegisters() function with CodeBlock::m_lock, this patch inserts WTF::storeStoreFence when filling m_jitData. This ensures that
JITData::m_calleeSaveRegisters is initialized with nullptr when this JITData pointer is exposed to concurrent Baseline JIT compiler thread.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::ensureJITDataSlow):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (249739 => 249740)


--- trunk/Source/_javascript_Core/ChangeLog	2019-09-10 23:12:49 UTC (rev 249739)
+++ trunk/Source/_javascript_Core/ChangeLog	2019-09-10 23:18:11 UTC (rev 249740)
@@ -1,5 +1,31 @@
 2019-09-10  Yusuke Suzuki  <ysuz...@apple.com>
 
+        [JSC] CodeBlock::calleeSaveRegisters should not see half-baked JITData
+        https://bugs.webkit.org/show_bug.cgi?id=201664
+        <rdar://problem/52126927>
+
+        Reviewed by Tadeu Zagallo.
+
+        We are hitting the crash accessing invalid-pointer as CodeBlock::calleeSaveRegisters result.
+        This is because concurrent Baseline JIT compiler can access m_jitData without taking a lock through CodeBlock::calleeSaveRegisters.
+        Since m_jitData can be initialized in the main thread while calling CodeBlock::calleeSaveRegisters from concurrent Baseline JIT compiler thread,
+        we can see half-baked JITData structure which holds garbage pointers.
+
+        But we do not want to make CodeBlock::calleeSaveRegisters() call with CodeBlock::m_lock due to several reasons.
+
+        1. This function is very primitive one and it is called from various AssemblyHelpers functions and other code-generation functions. Some of these functions are
+           called while taking this exact same lock, so dead-lock can happen.
+        2. JITData::m_calleeSaveRegisters is filled only for DFG and FTL CodeBlock. And DFG and FTL code accesses these field after initializing properly. For Baseline JIT
+           compiler case, only thing we should do is that JITData should say m_calleeSaveRegisters is nullptr and it won't be filled for this CodeBlock.
+
+        Instead of guarding CodeBlock::calleeSaveRegisters() function with CodeBlock::m_lock, this patch inserts WTF::storeStoreFence when filling m_jitData. This ensures that
+        JITData::m_calleeSaveRegisters is initialized with nullptr when this JITData pointer is exposed to concurrent Baseline JIT compiler thread.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::ensureJITDataSlow):
+
+2019-09-10  Yusuke Suzuki  <ysuz...@apple.com>
+
         [JSC] ResultType implementation is wrong for bit ops, and ends up making ArithDiv take the DFG Int32 fast path even if Baseline constantly produces Double result
         https://bugs.webkit.org/show_bug.cgi?id=198253
 

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (249739 => 249740)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2019-09-10 23:12:49 UTC (rev 249739)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2019-09-10 23:18:11 UTC (rev 249740)
@@ -1344,7 +1344,11 @@
 CodeBlock::JITData& CodeBlock::ensureJITDataSlow(const ConcurrentJSLocker&)
 {
     ASSERT(!m_jitData);
-    m_jitData = makeUnique<JITData>();
+    auto jitData = makeUnique<JITData>();
+    // calleeSaveRegisters() can access m_jitData without taking a lock from Baseline JIT. This is OK since JITData::m_calleeSaveRegisters is filled in DFG and FTL CodeBlocks.
+    // But we should not see garbage pointer in that case. We ensure JITData::m_calleeSaveRegisters is initialized as nullptr before exposing it to BaselineJIT by store-store-fence.
+    WTF::storeStoreFence();
+    m_jitData = WTFMove(jitData);
     return *m_jitData;
 }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to