⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 181456 in webkit


Ignore:
Timestamp:
Mar 12, 2015, 3:14:32 PM (11 years ago)
Author:
mark.lam@apple.com
Message:

Use std::atomic for CodeBlock::m_visitAggregateHasBeenCalled.
<https://webkit.org/b/142640>

Reviewed by Mark Hahnenberg.

We used to spin our own compare and swap on a uint8_t. Now that we can
use C++11, let's use std::atomic instead.

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::visitAggregate):

  • The CAS here needs std::memory_order_acquire ordering because it requires lock acquisition semantics to visit the CodeBlock.
  • bytecode/CodeBlock.h:

(JSC::CodeBlockSet::mark):

  • heap/CodeBlockSet.cpp:

(JSC::CodeBlockSet::clearMarksForFullCollection):
(JSC::CodeBlockSet::clearMarksForEdenCollection):

  • These can go with relaxed ordering because they are all done before the GC starts parallel marking.
Location:
trunk/Source/JavaScriptCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r181435 r181456  
     12015-03-12  Mark Lam  <mark.lam@apple.com>
     2
     3        Use std::atomic for CodeBlock::m_visitAggregateHasBeenCalled.
     4        <https://webkit.org/b/142640>
     5
     6        Reviewed by Mark Hahnenberg.
     7
     8        We used to spin our own compare and swap on a uint8_t.  Now that we can
     9        use C++11, let's use std::atomic instead.
     10
     11        * bytecode/CodeBlock.cpp:
     12        (JSC::CodeBlock::visitAggregate):
     13        - The CAS here needs std::memory_order_acquire ordering because it
     14          requires lock acquisition semantics to visit the CodeBlock.
     15
     16        * bytecode/CodeBlock.h:
     17        (JSC::CodeBlockSet::mark):
     18        * heap/CodeBlockSet.cpp:
     19        (JSC::CodeBlockSet::clearMarksForFullCollection):
     20        (JSC::CodeBlockSet::clearMarksForEdenCollection):
     21        - These can go with relaxed ordering because they are all done before
     22          the GC starts parallel marking.
     23
    1242015-03-12  Csaba Osztrogonác  <ossy@webkit.org>
    225
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r181407 r181456  
    21962196#if ENABLE(PARALLEL_GC)
    21972197    // I may be asked to scan myself more than once, and it may even happen concurrently.
    2198     // To this end, use a CAS loop to check if I've been called already. Only one thread
    2199     // may proceed past this point - whichever one wins the CAS race.
    2200     unsigned oldValue;
    2201     do {
    2202         oldValue = m_visitAggregateHasBeenCalled;
    2203         if (oldValue) {
    2204             // Looks like someone else won! Return immediately to ensure that we don't
    2205             // trace the same CodeBlock concurrently. Doing so is hazardous since we will
    2206             // be mutating the state of ValueProfiles, which contain JSValues, which can
    2207             // have word-tearing on 32-bit, leading to awesome timing-dependent crashes
    2208             // that are nearly impossible to track down.
    2209            
    2210             // Also note that it must be safe to return early as soon as we see the
    2211             // value true (well, (unsigned)1), since once a GC thread is in this method
    2212             // and has won the CAS race (i.e. was responsible for setting the value true)
    2213             // it will definitely complete the rest of this method before declaring
    2214             // termination.
    2215             return;
    2216         }
    2217     } while (!WTF::weakCompareAndSwap(&m_visitAggregateHasBeenCalled, 0, 1));
     2198    // To this end, use an atomic operation to check (and set) if I've been called already.
     2199    // Only one thread may proceed past this point - whichever one wins the atomic set race.
     2200    bool expected = false;
     2201    bool setByMe = m_visitAggregateHasBeenCalled.compare_exchange_strong(expected, true, std::memory_order_acquire);
     2202    if (!setByMe)
     2203        return;
    22182204#endif // ENABLE(PARALLEL_GC)
    22192205   
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.h

    r181407 r181456  
    10661066    bool m_needsActivation;
    10671067    bool m_mayBeExecuting;
    1068     uint8_t m_visitAggregateHasBeenCalled;
     1068    std::atomic<bool> m_visitAggregateHasBeenCalled;
    10691069
    10701070    RefPtr<SourceProvider> m_source;
     
    13021302    codeBlock->m_mayBeExecuting = true;
    13031303    // We might not have cleared the marks for this CodeBlock, but we need to visit it.
    1304     codeBlock->m_visitAggregateHasBeenCalled = false;
     1304    codeBlock->m_visitAggregateHasBeenCalled.store(false, std::memory_order_relaxed);
    13051305#if ENABLE(GGC)
    13061306    m_currentlyExecuting.append(codeBlock);
  • trunk/Source/JavaScriptCore/heap/CodeBlockSet.cpp

    r179359 r181456  
    6666    for (CodeBlock* codeBlock : m_oldCodeBlocks) {
    6767        codeBlock->m_mayBeExecuting = false;
    68         codeBlock->m_visitAggregateHasBeenCalled = false;
     68        codeBlock->m_visitAggregateHasBeenCalled.store(false, std::memory_order_relaxed);
    6969    }
    7070
     
    8383        executable->forEachCodeBlock([](CodeBlock* codeBlock) {
    8484            codeBlock->m_mayBeExecuting = false;
    85             codeBlock->m_visitAggregateHasBeenCalled = false;
     85            codeBlock->m_visitAggregateHasBeenCalled.store(false, std::memory_order_relaxed);
    8686        });
    8787    }
Note: See TracChangeset for help on using the changeset viewer.