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

Changeset 211115 in webkit


Ignore:
Timestamp:
Jan 24, 2017, 3:29:25 PM (10 years ago)
Author:
matthew_hanson@apple.com
Message:

Merge r211069. rdar://problem/30173274

Location:
branches/safari-603-branch/Source/JavaScriptCore
Files:
2 added
11 edited

Legend:

Unmodified
Added
Removed
  • branches/safari-603-branch/Source/JavaScriptCore/CMakeLists.txt

    r210868 r211115  
    504504    heap/SlotVisitor.cpp
    505505    heap/SpaceTimeMutatorScheduler.cpp
     506    heap/StochasticSpaceTimeMutatorScheduler.cpp
    506507    heap/StopIfNecessaryTimer.cpp
    507508    heap/Subspace.cpp
  • branches/safari-603-branch/Source/JavaScriptCore/ChangeLog

    r211106 r211115  
     12017-01-24  Matthew Hanson  <matthew_hanson@apple.com>
     2
     3        Merge r211069. rdar://problem/30173274
     4
     5    2017-01-22  Filip Pizlo  <fpizlo@apple.com>
     6
     7            Land the stochastic space-time scheduler disabled
     8            https://bugs.webkit.org/show_bug.cgi?id=167249
     9
     10            Reviewed by Saam Barati.
     11
     12            The space-time scheduler is pretty weird. It uses a periodic scheduler where the next period is
     13            simply determined by an integer multiple of time since when the scheduler last snapped phase. It
     14            snaps phase after constraint solving. Both the snapping of the phase after constraint solving and
     15            the periodicity appear to be necessary for good performance. For example, if the space-time
     16            scheduler decided that it was in the resume part of the phase just by virtue of having just
     17            resumed, then it would be empirically worse than our scheduler which asks "what time is it?" to
     18            decide whether it should be suspended or resumed even if it just suspended or resumed. I've spent
     19            a lot of time wondering why these two features are essential, and I think I found a reason.
     20
     21            What's happening is that sometimes the GC has an overrun and its increment takes longer than it
     22            should have. The current scheduler forgives overruns when constraint solving, which seems to
     23            make sense because it cannot control whether constraint solving runs with the mutator resumed or
     24            suspended. It has to be suspended currently. Snapping phase after constraint solving accomplishes
     25            this. What's more surprising is how important it is to manage deadline misses during draining.
     26            The relevant kind of deadline miss is when doing mutator-suspended draining to catch up to the
     27            retreating wavefront. Deadline misses while doing this can happen systematically in some
     28            workloads, like JetStream/hash-map and some test in Speedometer. It's because they have some
     29            ginormous object and it takes like ~3ms+-1.5ms just to scan it. The space-time scheduler's use
     30            of time to decide what to do saves the day here: after the deadline miss, the scheduler will
     31            initially realize that it missed its deadline to resume the mutator. But as soon as it does this
     32            it asks: "based on current time since phase snap, what should I do?". In the case of a deadline
     33            miss, this question is essentially a weighted coin flip because of the high noise in the amount
     34            of time that it takes to do things in the GC. If you overrun, you will probably overrun by
     35            multiple milliseconds, which is enough that where you land in the space-time scheduler's timeline
     36            is random. The likelihood that you land in the "resume mutator" part of the timeline has a
     37            probability that is roughly the same as what the space-time scheduler calls mutator utilization.
     38            This is a super weird property. I did not intend for it to have this property, but it appears to
     39            be the most important property of this scheduler.
     40
     41            Based on this, it seems that the fact that the space-time scheduler could suspend the mutator
     42            before draining runs out of work doesn't accomplish anything. As soon as you resume the
     43            mutator, you have a retreating wavefront to worry about. But if the collector is happily scanning
     44            things then it's almost certain that the collector will outpace the mutator. Also, anything that
     45            the mutator asks us to revisit is deferred anyway.
     46
     47            In the past I've tried to replace the scheduler in one patch and this turned out to be annoying
     48            because even a poorly conceived scheduler should be iterated on. This patch lands a new scheduler
     49            called the StochasticSpaceTime scheduler. It replaces two of the known-good features of the old
     50            scheduler: (1) it forgives constraint pauses and (2) after deadline overrun its choice is random,
     51            weighted by the mutator utilization target. Unlike the old scheduler, this one will only suspend
     52            the mutator when the draining terminates, but it may pause for any amount of time after an
     53            iteration of constraint solving. It computes the targetPause by measuring constraint solving time
     54            and multiplying by the pauseScale (0.3 by default). If smaller then minimumPause (0.3ms by
     55            default), then it uses minimumPause instead. The stochastic scheduler will then definitely do at
     56            least targetPause worth of suspended draining after the constraint solving iteration, and then
     57            it will decide whether or not to do another one at random. The probability that it will choose to
     58            resume is exactly mutatorUtilization, which is computed exactly as before. Therefore, the
     59            probability of resumption starts at 0.7 and goes down as memory usage rises. Conversely, the
     60            probability that we will stay suspended starts at 0.3 and goes up from there.
     61
     62            This new scheduler looks like it might be a 25% improvement on splay-latency. It also looks like
     63            a small progression on hash-map. Hash-map is a great test of one of the worst cases of retreating
     64            wavefront, since it is repeatedly storing to a ginormous array. This array is sure to take a
     65            while to scan, and to complete, the GC must be smart enough to visit any new objects it finds
     66            while scanning the array immediately after scanning that array. This new scheduler means that
     67            after scanning the array, the probability that you will scan whatever you found in it starts at
     68            0.3 and rises as the program allocates. It's sure to be 0.3, and not 0.3^k, because after the
     69            wavefront stops advancing, the only object on the mark stack after a constraint iteration will be
     70            that array. Since there is sure to be a 0.3ms or longer pause, the GC will be sure to start
     71            visiting this object. The GC can then complete if it just allows enough time after this to scan
     72            whatever new objects it finds. If scanning the array overruns the deadline (and it almost
     73            certainly will) then the probability that the GC keeps the mutator suspended is simply
     74            1 - mutatorUtilization.
     75
     76            This scheduler is disabled by default. You can enable it with
     77            --useStochasticMutatorScheduler=true.
     78
     79            * CMakeLists.txt:
     80            * JavaScriptCore.xcodeproj/project.pbxproj:
     81            * heap/Heap.cpp:
     82            (JSC::Heap::Heap):
     83            (JSC::Heap::markToFixpoint):
     84            * heap/Heap.h:
     85            * heap/MarkingConstraintSet.cpp:
     86            (JSC::MarkingConstraintSet::didStartMarking):
     87            (JSC::MarkingConstraintSet::executeConvergenceImpl):
     88            (JSC::MarkingConstraintSet::resetStats): Deleted.
     89            (JSC::MarkingConstraintSet::executeBootstrap): Deleted.
     90            * heap/MarkingConstraintSet.h:
     91            * heap/MutatorScheduler.cpp:
     92            (JSC::MutatorScheduler::didReachTermination):
     93            (JSC::MutatorScheduler::synchronousDrainingDidStall):
     94            * heap/MutatorScheduler.h:
     95            * heap/SlotVisitor.cpp:
     96            (JSC::SlotVisitor::didReachTermination):
     97            (JSC::SlotVisitor::drainFromShared):
     98            * heap/StochasticSpaceTimeMutatorScheduler.cpp: Added.
     99            (JSC::StochasticSpaceTimeMutatorScheduler::Snapshot::Snapshot):
     100            (JSC::StochasticSpaceTimeMutatorScheduler::Snapshot::now):
     101            (JSC::StochasticSpaceTimeMutatorScheduler::Snapshot::bytesAllocatedThisCycle):
     102            (JSC::StochasticSpaceTimeMutatorScheduler::StochasticSpaceTimeMutatorScheduler):
     103            (JSC::StochasticSpaceTimeMutatorScheduler::~StochasticSpaceTimeMutatorScheduler):
     104            (JSC::StochasticSpaceTimeMutatorScheduler::state):
     105            (JSC::StochasticSpaceTimeMutatorScheduler::beginCollection):
     106            (JSC::StochasticSpaceTimeMutatorScheduler::didStop):
     107            (JSC::StochasticSpaceTimeMutatorScheduler::willResume):
     108            (JSC::StochasticSpaceTimeMutatorScheduler::didReachTermination):
     109            (JSC::StochasticSpaceTimeMutatorScheduler::didExecuteConstraints):
     110            (JSC::StochasticSpaceTimeMutatorScheduler::synchronousDrainingDidStall):
     111            (JSC::StochasticSpaceTimeMutatorScheduler::timeToStop):
     112            (JSC::StochasticSpaceTimeMutatorScheduler::timeToResume):
     113            (JSC::StochasticSpaceTimeMutatorScheduler::log):
     114            (JSC::StochasticSpaceTimeMutatorScheduler::endCollection):
     115            (JSC::StochasticSpaceTimeMutatorScheduler::setResumeTime):
     116            (JSC::StochasticSpaceTimeMutatorScheduler::bytesAllocatedThisCycleImpl):
     117            (JSC::StochasticSpaceTimeMutatorScheduler::bytesSinceBeginningOfCycle):
     118            (JSC::StochasticSpaceTimeMutatorScheduler::maxHeadroom):
     119            (JSC::StochasticSpaceTimeMutatorScheduler::headroomFullness):
     120            (JSC::StochasticSpaceTimeMutatorScheduler::mutatorUtilization):
     121            * heap/StochasticSpaceTimeMutatorScheduler.h: Added.
     122            * runtime/Options.cpp:
     123            (JSC::overrideDefaults):
     124            * runtime/Options.h:
     125
    11262017-01-24  Matthew Hanson  <matthew_hanson@apple.com>
    2127
  • branches/safari-603-branch/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r210868 r211115  
    409409                0F4F29DF18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4F29DD18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp */; };
    410410                0F4F29E018B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4F29DE18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h */; };
     411                0F4F828B1E31B9740075184C /* StochasticSpaceTimeMutatorScheduler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4F82891E31B9710075184C /* StochasticSpaceTimeMutatorScheduler.cpp */; };
     412                0F4F828C1E31B9760075184C /* StochasticSpaceTimeMutatorScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4F828A1E31B9710075184C /* StochasticSpaceTimeMutatorScheduler.h */; };
    411413                0F50AF3C193E8B3900674EE8 /* DFGStructureClobberState.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F50AF3B193E8B3900674EE8 /* DFGStructureClobberState.h */; };
    412414                0F5513A61D5A682C00C32BD8 /* FreeList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5513A51D5A682A00C32BD8 /* FreeList.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    28472849                0F4F29DD18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGStaticExecutionCountEstimationPhase.cpp; path = dfg/DFGStaticExecutionCountEstimationPhase.cpp; sourceTree = "<group>"; };
    28482850                0F4F29DE18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStaticExecutionCountEstimationPhase.h; path = dfg/DFGStaticExecutionCountEstimationPhase.h; sourceTree = "<group>"; };
     2851                0F4F82891E31B9710075184C /* StochasticSpaceTimeMutatorScheduler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StochasticSpaceTimeMutatorScheduler.cpp; sourceTree = "<group>"; };
     2852                0F4F828A1E31B9710075184C /* StochasticSpaceTimeMutatorScheduler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StochasticSpaceTimeMutatorScheduler.h; sourceTree = "<group>"; };
    28492853                0F50AF3B193E8B3900674EE8 /* DFGStructureClobberState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStructureClobberState.h; path = dfg/DFGStructureClobberState.h; sourceTree = "<group>"; };
    28502854                0F5513A51D5A682A00C32BD8 /* FreeList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FreeList.h; sourceTree = "<group>"; };
     
    57925796                                0FDE87FA1DFE6E500064C390 /* SpaceTimeMutatorScheduler.cpp */,
    57935797                                0FDE87FB1DFE6E500064C390 /* SpaceTimeMutatorScheduler.h */,
     5798                                0F4F82891E31B9710075184C /* StochasticSpaceTimeMutatorScheduler.cpp */,
     5799                                0F4F828A1E31B9710075184C /* StochasticSpaceTimeMutatorScheduler.h */,
    57945800                                0F7CF9501DC027D70098CC12 /* StopIfNecessaryTimer.cpp */,
    57955801                                0F7CF9511DC027D70098CC12 /* StopIfNecessaryTimer.h */,
     
    81488154                                A7D89CF817A0B8CC00773AD8 /* DFGFlushFormat.h in Headers */,
    81498155                                0F2DD8151AB3D8BE00BBB8E8 /* DFGForAllKills.h in Headers */,
     8156                                0F4F828C1E31B9760075184C /* StochasticSpaceTimeMutatorScheduler.h in Headers */,
    81508157                                0F69CC89193AC60A0045759E /* DFGFrozenValue.h in Headers */,
    81518158                                86EC9DC61328DF82002B2AD7 /* DFGGenerationInfo.h in Headers */,
     
    99379944                                0FC097A1146B28CA00CF2442 /* DFGThunks.cpp in Sources */,
    99389945                                0FD8A32717D51F5700CA2C40 /* DFGTierUpCheckInjectionPhase.cpp in Sources */,
     9946                                0F4F828B1E31B9740075184C /* StochasticSpaceTimeMutatorScheduler.cpp in Sources */,
    99399947                                0FD8A32917D51F5700CA2C40 /* DFGToFTLDeferredCompilationCallback.cpp in Sources */,
    99409948                                0FD8A32B17D51F5700CA2C40 /* DFGToFTLForOSREntryDeferredCompilationCallback.cpp in Sources */,
  • branches/safari-603-branch/Source/JavaScriptCore/heap/Heap.cpp

    r210868 r211115  
    5656#include "SpaceTimeMutatorScheduler.h"
    5757#include "SuperSampler.h"
     58#include "StochasticSpaceTimeMutatorScheduler.h"
    5859#include "StopIfNecessaryTimer.h"
    5960#include "SynchronousStopTheWorldMutatorScheduler.h"
     
    285286    , m_sharedMutatorMarkStack(std::make_unique<MarkStackArray>())
    286287    , m_helperClient(&heapHelperPool())
    287     , m_scheduler(std::make_unique<SpaceTimeMutatorScheduler>(*this))
    288288    , m_threadLock(Box<Lock>::create())
    289289    , m_threadCondition(AutomaticThreadCondition::create())
     
    291291    m_worldState.store(0);
    292292   
    293     if (Options::useConcurrentGC())
    294         m_scheduler = std::make_unique<SpaceTimeMutatorScheduler>(*this);
    295     else {
     293    if (Options::useConcurrentGC()) {
     294        if (Options::useStochasticMutatorScheduler())
     295            m_scheduler = std::make_unique<StochasticSpaceTimeMutatorScheduler>(*this);
     296        else
     297            m_scheduler = std::make_unique<SpaceTimeMutatorScheduler>(*this);
     298    } else {
    296299        // We simulate turning off concurrent GC by making the scheduler say that the world
    297300        // should always be stopped when the collector is running.
     
    571574    SlotVisitor& slotVisitor = *m_collectorSlotVisitor;
    572575    slotVisitor.didStartMarking();
    573 
    574     m_constraintSet->resetStats();
     576    m_constraintSet->didStartMarking();
    575577   
    576578    m_scheduler->beginCollection();
     
    578580        m_scheduler->log();
    579581   
    580     // Wondering what m_constraintSet->executeXYZ does? It's running the constraints created by
    581     // Heap::buildConstraintSet().
    582    
    583     m_constraintSet->executeBootstrap(slotVisitor, MonotonicTime::infinity());
    584     m_scheduler->didExecuteConstraints();
    585 
    586582    // After this, we will almost certainly fall through all of the "slotVisitor.isEmpty()"
    587583    // checks because bootstrap would have put things into the visitor. So, we should fall
    588584    // through to draining.
    589585   
    590     unsigned iteration = 1;
     586    if (!slotVisitor.didReachTermination()) {
     587        dataLog("Fatal: SlotVisitor should think that GC should terminate before constraint solving, but it does not think this.\n");
     588        dataLog("slotVisitor.isEmpty(): ", slotVisitor.isEmpty(), "\n");
     589        dataLog("slotVisitor.collectorMarkStack().isEmpty(): ", slotVisitor.collectorMarkStack().isEmpty(), "\n");
     590        dataLog("slotVisitor.mutatorMarkStack().isEmpty(): ", slotVisitor.mutatorMarkStack().isEmpty(), "\n");
     591        dataLog("m_numberOfActiveParallelMarkers: ", m_numberOfActiveParallelMarkers, "\n");
     592        dataLog("m_sharedCollectorMarkStack->isEmpty(): ", m_sharedCollectorMarkStack->isEmpty(), "\n");
     593        dataLog("m_sharedMutatorMarkStack->isEmpty(): ", m_sharedMutatorMarkStack->isEmpty(), "\n");
     594        dataLog("slotVisitor.didReachTermination(): ", slotVisitor.didReachTermination(), "\n");
     595        RELEASE_ASSERT_NOT_REACHED();
     596    }
     597   
    591598    for (;;) {
    592599        if (Options::logGC())
     
    594601       
    595602        if (slotVisitor.didReachTermination()) {
    596             if (Options::logGC())
    597                 dataLog("i#", iteration, " ");
    598        
     603            m_scheduler->didReachTermination();
     604           
    599605            assertSharedMarkStacksEmpty();
    600606           
     
    614620            // https://bugs.webkit.org/show_bug.cgi?id=166831
    615621           
     622            // Wondering what this does? Look at Heap::addCoreConstraints(). The DOM and others can also
     623            // add their own using Heap::addMarkingConstraint().
    616624            bool converged =
    617625                m_constraintSet->executeConvergence(slotVisitor, MonotonicTime::infinity());
     
    622630           
    623631            m_scheduler->didExecuteConstraints();
    624             iteration++;
    625632        }
    626633       
     
    632639            slotVisitor.drainInParallel(m_scheduler->timeToResume());
    633640        }
     641       
     642        m_scheduler->synchronousDrainingDidStall();
     643
     644        if (slotVisitor.didReachTermination())
     645            continue;
    634646       
    635647        if (!m_scheduler->shouldResume())
  • branches/safari-603-branch/Source/JavaScriptCore/heap/Heap.h

    r210868 r211115  
    369369    friend class SlotVisitor;
    370370    friend class SpaceTimeMutatorScheduler;
     371    friend class StochasticSpaceTimeMutatorScheduler;
    371372    friend class IncrementalSweeper;
    372373    friend class HeapStatistics;
  • branches/safari-603-branch/Source/JavaScriptCore/heap/MarkingConstraintSet.cpp

    r210868 r211115  
    8787}
    8888
    89 void MarkingConstraintSet::resetStats()
     89void MarkingConstraintSet::didStartMarking()
    9090{
    9191    m_unexecutedRoots.clearAll();
     
    104104        }
    105105    }
     106    m_iteration = 1;
    106107}
    107108
     
    130131}
    131132
    132 bool MarkingConstraintSet::executeBootstrap(SlotVisitor& visitor, MonotonicTime timeout)
    133 {
    134     // Bootstrap means that we haven't done any object visiting yet. This means that we want to
    135     // only execute root constraints (which also happens to be those that we say are greyed by
    136     // resumption), since the other constraints are super unlikely to trigger without some object
    137     // visiting. The expectation is that the caller will go straight to object visiting after
    138     // this.
    139     ExecutionContext executionContext(*this, visitor, timeout);
    140     if (Options::logGC())
    141         dataLog("boot:");
    142     bool result = executionContext.drain(m_unexecutedRoots);
    143     if (Options::logGC())
    144         dataLog(" ");
    145     return result;
    146 }
    147 
    148133bool MarkingConstraintSet::executeConvergence(SlotVisitor& visitor, MonotonicTime timeout)
    149134{
     
    167152    ExecutionContext executionContext(*this, visitor, timeout);
    168153   
     154    unsigned iteration = m_iteration++;
     155   
    169156    if (Options::logGC())
    170         dataLog("converge:");
     157        dataLog("i#", iteration, ":");
    171158
    172159    // If there are any constraints that we have not executed at all during this cycle, then
     
    174161    if (!executionContext.drain(m_unexecutedRoots))
    175162        return false;
     163   
     164    // First iteration is before any visitor draining, so it's unlikely to trigger any constraints other
     165    // than roots.
     166    if (iteration == 1)
     167        return false;
     168   
    176169    if (!executionContext.drain(m_unexecutedOutgrowths))
    177170        return false;
  • branches/safari-603-branch/Source/JavaScriptCore/heap/MarkingConstraintSet.h

    r210868 r211115  
    3737    ~MarkingConstraintSet();
    3838   
    39     void resetStats();
     39    void didStartMarking();
    4040   
    4141    void add(
     
    5858    bool isWavefrontAdvancing(SlotVisitor&);
    5959    bool isWavefrontRetreating(SlotVisitor& visitor) { return !isWavefrontAdvancing(visitor); }
    60    
    61     // Executes only roots. Returns true if all roots have been executed. It's expected
    62     // that you'll do some draining after this and then use executeConvergence().
    63     bool executeBootstrap(SlotVisitor&, MonotonicTime timeout = MonotonicTime::infinity());
    6460   
    6561    // Returns true if this executed all constraints and none of them produced new work. This
     
    8581    Vector<MarkingConstraint*> m_ordered;
    8682    Vector<MarkingConstraint*> m_outgrowths;
     83    unsigned m_iteration { 1 };
    8784};
    8885
  • branches/safari-603-branch/Source/JavaScriptCore/heap/MutatorScheduler.cpp

    r210653 r211115  
    4747}
    4848
     49void MutatorScheduler::didReachTermination()
     50{
     51}
     52
    4953void MutatorScheduler::didExecuteConstraints()
     54{
     55}
     56
     57void MutatorScheduler::synchronousDrainingDidStall()
    5058{
    5159}
  • branches/safari-603-branch/Source/JavaScriptCore/heap/MutatorScheduler.h

    r210653 r211115  
    5151    virtual void didStop();
    5252    virtual void willResume();
     53   
     54    // At the top of an iteration, the GC will may call didReachTermination.
     55    virtual void didReachTermination();
     56   
     57    // If it called didReachTermination, it will then later call didExecuteConstraints.
    5358    virtual void didExecuteConstraints();
     59   
     60    // After doing that, it will do synchronous draining. When this stalls - either due to timeout or
     61    // just 'cause, it will call this.
     62    virtual void synchronousDrainingDidStall();
    5463   
    5564    virtual MonotonicTime timeToStop() = 0; // Call while resumed, to ask when to stop.
  • branches/safari-603-branch/Source/JavaScriptCore/heap/SlotVisitor.cpp

    r210868 r211115  
    493493{
    494494    LockHolder locker(m_heap.m_markingMutex);
    495     return isEmpty() && didReachTermination(locker);
     495    return didReachTermination(locker);
    496496}
    497497
    498498bool SlotVisitor::didReachTermination(const LockHolder&)
    499499{
    500     return !m_heap.m_numberOfActiveParallelMarkers
     500    return isEmpty()
     501        && !m_heap.m_numberOfActiveParallelMarkers
    501502        && m_heap.m_sharedCollectorMarkStack->isEmpty()
    502503        && m_heap.m_sharedMutatorMarkStack->isEmpty();
     
    515516    ASSERT(Options::numberOfGCMarkers());
    516517   
    517     {
    518         LockHolder locker(m_heap.m_markingMutex);
    519         m_heap.m_numberOfActiveParallelMarkers++;
    520     }
     518    bool isActive = false;
    521519    while (true) {
    522520        {
    523521            LockHolder locker(m_heap.m_markingMutex);
    524             m_heap.m_numberOfActiveParallelMarkers--;
     522            if (isActive)
     523                m_heap.m_numberOfActiveParallelMarkers--;
    525524            m_heap.m_numberOfWaitingParallelMarkers++;
    526525
     
    569568       
    570569        drain(timeout);
     570        isActive = true;
    571571    }
    572572}
  • branches/safari-603-branch/Source/JavaScriptCore/runtime/Options.h

    r211099 r211115  
    199199    v(double, mediumHeapGrowthFactor, 1.5, Normal, nullptr) \
    200200    v(double, largeHeapGrowthFactor, 1.24, Normal, nullptr) \
    201     v(bool, useCollectorTimeslicing, true, Normal, nullptr) \
    202201    v(double, minimumMutatorUtilization, 0, Normal, nullptr) \
    203202    v(double, maximumMutatorUtilization, 0.7, Normal, nullptr) \
    204203    v(double, concurrentGCMaxHeadroom, 1.5, Normal, nullptr) \
    205204    v(double, concurrentGCPeriodMS, 2, Normal, nullptr) \
     205    v(bool, useStochasticMutatorScheduler, false, Normal, nullptr) \
     206    v(double, minimumGCPauseMS, 0.3, Normal, nullptr) \
     207    v(double, gcPauseScale, 0.3, Normal, nullptr) \
    206208    v(bool, scribbleFreeCells, false, Normal, nullptr) \
    207209    v(double, sizeClassProgression, 1.4, Normal, nullptr) \
Note: See TracChangeset for help on using the changeset viewer.