Changeset 246507 in webkit


Ignore:
Timestamp:
Jun 17, 2019 11:54:30 AM (5 years ago)
Author:
Tadeu Zagallo
Message:

Concurrent GC should check the conn before starting a new collection cycle
https://bugs.webkit.org/show_bug.cgi?id=198913
<rdar://problem/49515149>

Reviewed by Filip Pizlo.

Heap::requestCollection tries to steal the conn as an optimization to avoid waking up the collector
thread if it's idle. We determine if the collector is idle by ensuring that there are no pending collections
and that the current GC phase is NotRunning. However, that's not safe immediately after the concurrent
GC has finished processing the last pending request. The collector thread will runEndPhase and immediately
start runNotRunningPhase, without checking if it still has the conn. If the mutator has stolen the conn in
the mean time, this will lead to both threads collecting concurrently, and eventually we'll crash in checkConn,
since the collector is running but doesn't have the conn anymore.

To solve this, we check if we still have the conn after holding the lock in runNotRunningPhase, in case the mutator
has stolen the conn. Ideally, we wouldn't let the mutator steal the conn in the first place, but that doesn't seem
trivial to determine.

  • heap/Heap.cpp:

(JSC::Heap::runNotRunningPhase):

Location:
trunk/Source/JavaScriptCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r246505 r246507  
     12019-06-17  Tadeu Zagallo  <tzagallo@apple.com>
     2
     3        Concurrent GC should check the conn before starting a new collection cycle
     4        https://bugs.webkit.org/show_bug.cgi?id=198913
     5        <rdar://problem/49515149>
     6
     7        Reviewed by Filip Pizlo.
     8
     9        Heap::requestCollection tries to steal the conn as an optimization to avoid waking up the collector
     10        thread if it's idle. We determine if the collector is idle by ensuring that there are no pending collections
     11        and that the current GC phase is NotRunning. However, that's not safe immediately after the concurrent
     12        GC has finished processing the last pending request. The collector thread will runEndPhase and immediately
     13        start runNotRunningPhase, without checking if it still has the conn. If the mutator has stolen the conn in
     14        the mean time, this will lead to both threads collecting concurrently, and eventually we'll crash in checkConn,
     15        since the collector is running but doesn't have the conn anymore.
     16
     17        To solve this, we check if we still have the conn after holding the lock in runNotRunningPhase, in case the mutator
     18        has stolen the conn. Ideally, we wouldn't let the mutator steal the conn in the first place, but that doesn't seem
     19        trivial to determine.
     20
     21        * heap/Heap.cpp:
     22        (JSC::Heap::runNotRunningPhase):
     23
    1242019-06-17  Yusuke Suzuki  <ysuzuki@apple.com>
    225
  • trunk/Source/JavaScriptCore/heap/Heap.cpp

    r246490 r246507  
    12351235        if (m_requests.isEmpty())
    12361236            return false;
     1237        // Check if the mutator has stolen the conn while the collector transitioned from End to NotRunning
     1238        if (conn == GCConductor::Collector && !!(m_worldState.load() & mutatorHasConnBit))
     1239            return false;
    12371240    }
    12381241   
Note: See TracChangeset for help on using the changeset viewer.