Changeset 249740 in webkit


Ignore:
Timestamp:
Sep 10, 2019 4:18:11 PM (5 years ago)
Author:
ysuzuki@apple.com
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):

Location:
trunk/Source/JavaScriptCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r249736 r249740  
     12019-09-10  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] CodeBlock::calleeSaveRegisters should not see half-baked JITData
     4        https://bugs.webkit.org/show_bug.cgi?id=201664
     5        <rdar://problem/52126927>
     6
     7        Reviewed by Tadeu Zagallo.
     8
     9        We are hitting the crash accessing invalid-pointer as CodeBlock::calleeSaveRegisters result.
     10        This is because concurrent Baseline JIT compiler can access m_jitData without taking a lock through CodeBlock::calleeSaveRegisters.
     11        Since m_jitData can be initialized in the main thread while calling CodeBlock::calleeSaveRegisters from concurrent Baseline JIT compiler thread,
     12        we can see half-baked JITData structure which holds garbage pointers.
     13
     14        But we do not want to make CodeBlock::calleeSaveRegisters() call with CodeBlock::m_lock due to several reasons.
     15
     16        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
     17           called while taking this exact same lock, so dead-lock can happen.
     18        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
     19           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.
     20
     21        Instead of guarding CodeBlock::calleeSaveRegisters() function with CodeBlock::m_lock, this patch inserts WTF::storeStoreFence when filling m_jitData. This ensures that
     22        JITData::m_calleeSaveRegisters is initialized with nullptr when this JITData pointer is exposed to concurrent Baseline JIT compiler thread.
     23
     24        * bytecode/CodeBlock.cpp:
     25        (JSC::CodeBlock::ensureJITDataSlow):
     26
    1272019-09-10  Yusuke Suzuki  <ysuzuki@apple.com>
    228
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r249706 r249740  
    13451345{
    13461346    ASSERT(!m_jitData);
    1347     m_jitData = makeUnique<JITData>();
     1347    auto jitData = makeUnique<JITData>();
     1348    // 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.
     1349    // 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.
     1350    WTF::storeStoreFence();
     1351    m_jitData = WTFMove(jitData);
    13481352    return *m_jitData;
    13491353}
Note: See TracChangeset for help on using the changeset viewer.