| OLD | NEW | 
|    1 /* |    1 /* | 
|    2  * Copyright (C) 2013 Google Inc. All rights reserved. |    2  * Copyright (C) 2013 Google Inc. All rights reserved. | 
|    3  * |    3  * | 
|    4  * Redistribution and use in source and binary forms, with or without |    4  * Redistribution and use in source and binary forms, with or without | 
|    5  * modification, are permitted provided that the following conditions are |    5  * modification, are permitted provided that the following conditions are | 
|    6  * met: |    6  * met: | 
|    7  * |    7  * | 
|    8  *     * Redistributions of source code must retain the above copyright |    8  *     * Redistributions of source code must retain the above copyright | 
|    9  * notice, this list of conditions and the following disclaimer. |    9  * notice, this list of conditions and the following disclaimer. | 
|   10  *     * Redistributions in binary form must reproduce the above |   10  *     * Redistributions in binary form must reproduce the above | 
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   74     { |   74     { | 
|   75         m_state->leaveGCForbiddenScope(); |   75         m_state->leaveGCForbiddenScope(); | 
|   76     } |   76     } | 
|   77  |   77  | 
|   78 private: |   78 private: | 
|   79     ThreadState* m_state; |   79     ThreadState* m_state; | 
|   80 }; |   80 }; | 
|   81  |   81  | 
|   82 class GCScope final { |   82 class GCScope final { | 
|   83 public: |   83 public: | 
|   84     GCScope(ThreadState* state, ThreadState::StackState stackState, ThreadState:
     :GCType gcType) |   84     GCScope(ThreadState* state, BlinkGC::StackState stackState, BlinkGC::GCType 
     gcType) | 
|   85         : m_state(state) |   85         : m_state(state) | 
|   86         , m_gcForbiddenScope(state) |   86         , m_gcForbiddenScope(state) | 
|   87         // See collectGarbageForTerminatingThread() comment on why a |   87         // See collectGarbageForTerminatingThread() comment on why a | 
|   88         // safepoint scope isn't entered for its GCScope. |   88         // safepoint scope isn't entered for its GCScope. | 
|   89         , m_safePointScope(stackState, gcType != ThreadState::ThreadTerminationG
     C ? state : nullptr) |   89         , m_safePointScope(stackState, gcType != BlinkGC::ThreadTerminationGC ? 
     state : nullptr) | 
|   90         , m_gcType(gcType) |   90         , m_gcType(gcType) | 
|   91         , m_parkedAllThreads(false) |   91         , m_parkedAllThreads(false) | 
|   92     { |   92     { | 
|   93         TRACE_EVENT0("blink_gc", "Heap::GCScope"); |   93         TRACE_EVENT0("blink_gc", "Heap::GCScope"); | 
|   94         const char* samplingState = TRACE_EVENT_GET_SAMPLING_STATE(); |   94         const char* samplingState = TRACE_EVENT_GET_SAMPLING_STATE(); | 
|   95         if (m_state->isMainThread()) |   95         if (m_state->isMainThread()) | 
|   96             TRACE_EVENT_SET_SAMPLING_STATE("blink_gc", "BlinkGCWaiting"); |   96             TRACE_EVENT_SET_SAMPLING_STATE("blink_gc", "BlinkGCWaiting"); | 
|   97  |   97  | 
|   98         ASSERT(m_state->checkThread()); |   98         ASSERT(m_state->checkThread()); | 
|   99  |   99  | 
|  100         // TODO(haraken): In an unlikely coincidence that two threads decide |  100         // TODO(haraken): In an unlikely coincidence that two threads decide | 
|  101         // to collect garbage at the same time, avoid doing two GCs in |  101         // to collect garbage at the same time, avoid doing two GCs in | 
|  102         // a row. |  102         // a row. | 
|  103         if (LIKELY(gcType != ThreadState::ThreadTerminationGC && ThreadState::st
     opThreads())) |  103         if (LIKELY(gcType != BlinkGC::ThreadTerminationGC && ThreadState::stopTh
     reads())) | 
|  104             m_parkedAllThreads = true; |  104             m_parkedAllThreads = true; | 
|  105  |  105  | 
|  106         switch (gcType) { |  106         switch (gcType) { | 
|  107         case ThreadState::GCWithSweep: |  107         case BlinkGC::GCWithSweep: | 
|  108         case ThreadState::GCWithoutSweep: |  108         case BlinkGC::GCWithoutSweep: | 
|  109             m_visitor = adoptPtr(new MarkingVisitor<Visitor::GlobalMarking>()); |  109             m_visitor = adoptPtr(new MarkingVisitor<Visitor::GlobalMarking>()); | 
|  110             break; |  110             break; | 
|  111         case ThreadState::TakeSnapshot: |  111         case BlinkGC::TakeSnapshot: | 
|  112             m_visitor = adoptPtr(new MarkingVisitor<Visitor::SnapshotMarking>())
     ; |  112             m_visitor = adoptPtr(new MarkingVisitor<Visitor::SnapshotMarking>())
     ; | 
|  113             break; |  113             break; | 
|  114         case ThreadState::ThreadTerminationGC: |  114         case BlinkGC::ThreadTerminationGC: | 
|  115             m_visitor = adoptPtr(new MarkingVisitor<Visitor::ThreadLocalMarking>
     ()); |  115             m_visitor = adoptPtr(new MarkingVisitor<Visitor::ThreadLocalMarking>
     ()); | 
|  116             break; |  116             break; | 
|  117         default: |  117         default: | 
|  118             ASSERT_NOT_REACHED(); |  118             ASSERT_NOT_REACHED(); | 
|  119         } |  119         } | 
|  120  |  120  | 
|  121         if (m_state->isMainThread()) |  121         if (m_state->isMainThread()) | 
|  122             TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(samplingState); |  122             TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(samplingState); | 
|  123     } |  123     } | 
|  124  |  124  | 
|  125     bool allThreadsParked() const { return m_parkedAllThreads; } |  125     bool allThreadsParked() const { return m_parkedAllThreads; } | 
|  126     Visitor* visitor() const { return m_visitor.get(); } |  126     Visitor* visitor() const { return m_visitor.get(); } | 
|  127  |  127  | 
|  128     ~GCScope() |  128     ~GCScope() | 
|  129     { |  129     { | 
|  130         // Only cleanup if we parked all threads in which case the GC happened |  130         // Only cleanup if we parked all threads in which case the GC happened | 
|  131         // and we need to resume the other threads. |  131         // and we need to resume the other threads. | 
|  132         if (LIKELY(m_gcType != ThreadState::ThreadTerminationGC && m_parkedAllTh
     reads)) |  132         if (LIKELY(m_gcType != BlinkGC::ThreadTerminationGC && m_parkedAllThread
     s)) | 
|  133             ThreadState::resumeThreads(); |  133             ThreadState::resumeThreads(); | 
|  134     } |  134     } | 
|  135  |  135  | 
|  136 private: |  136 private: | 
|  137     ThreadState* m_state; |  137     ThreadState* m_state; | 
|  138     // The ordering of the two scope objects matters: GCs must first be forbidde
     n |  138     // The ordering of the two scope objects matters: GCs must first be forbidde
     n | 
|  139     // before entering the safe point scope. Prior to reaching the safe point, |  139     // before entering the safe point scope. Prior to reaching the safe point, | 
|  140     // ThreadState::runScheduledGC() is called. See its comment why we need |  140     // ThreadState::runScheduledGC() is called. See its comment why we need | 
|  141     // to be in a GC forbidden scope when doing so. |  141     // to be in a GC forbidden scope when doing so. | 
|  142     GCForbiddenScope m_gcForbiddenScope; |  142     GCForbiddenScope m_gcForbiddenScope; | 
|  143     SafePointScope m_safePointScope; |  143     SafePointScope m_safePointScope; | 
|  144     ThreadState::GCType m_gcType; |  144     BlinkGC::GCType m_gcType; | 
|  145     OwnPtr<Visitor> m_visitor; |  145     OwnPtr<Visitor> m_visitor; | 
|  146     bool m_parkedAllThreads; // False if we fail to park all threads |  146     bool m_parkedAllThreads; // False if we fail to park all threads | 
|  147 }; |  147 }; | 
|  148  |  148  | 
|  149 void Heap::flushHeapDoesNotContainCache() |  149 void Heap::flushHeapDoesNotContainCache() | 
|  150 { |  150 { | 
|  151     s_heapDoesNotContainCache->flush(); |  151     s_heapDoesNotContainCache->flush(); | 
|  152 } |  152 } | 
|  153  |  153  | 
|  154 void Heap::init() |  154 void Heap::init() | 
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  385 } |  385 } | 
|  386 #endif |  386 #endif | 
|  387  |  387  | 
|  388 void Heap::preGC() |  388 void Heap::preGC() | 
|  389 { |  389 { | 
|  390     ASSERT(!ThreadState::current()->isInGC()); |  390     ASSERT(!ThreadState::current()->isInGC()); | 
|  391     for (ThreadState* state : ThreadState::attachedThreads()) |  391     for (ThreadState* state : ThreadState::attachedThreads()) | 
|  392         state->preGC(); |  392         state->preGC(); | 
|  393 } |  393 } | 
|  394  |  394  | 
|  395 void Heap::postGC(ThreadState::GCType gcType) |  395 void Heap::postGC(BlinkGC::GCType gcType) | 
|  396 { |  396 { | 
|  397     ASSERT(ThreadState::current()->isInGC()); |  397     ASSERT(ThreadState::current()->isInGC()); | 
|  398     for (ThreadState* state : ThreadState::attachedThreads()) |  398     for (ThreadState* state : ThreadState::attachedThreads()) | 
|  399         state->postGC(gcType); |  399         state->postGC(gcType); | 
|  400 } |  400 } | 
|  401  |  401  | 
|  402 const char* Heap::gcReasonString(GCReason reason) |  402 const char* Heap::gcReasonString(GCReason reason) | 
|  403 { |  403 { | 
|  404     switch (reason) { |  404     switch (reason) { | 
|  405 #define STRINGIFY_REASON(reason) case reason: return #reason; |  405 #define STRINGIFY_REASON(reason) case reason: return #reason; | 
|  406         STRINGIFY_REASON(IdleGC); |  406         STRINGIFY_REASON(IdleGC); | 
|  407         STRINGIFY_REASON(PreciseGC); |  407         STRINGIFY_REASON(PreciseGC); | 
|  408         STRINGIFY_REASON(ConservativeGC); |  408         STRINGIFY_REASON(ConservativeGC); | 
|  409         STRINGIFY_REASON(ForcedGC); |  409         STRINGIFY_REASON(ForcedGC); | 
|  410         STRINGIFY_REASON(MemoryPressureGC); |  410         STRINGIFY_REASON(MemoryPressureGC); | 
|  411         STRINGIFY_REASON(PageNavigationGC); |  411         STRINGIFY_REASON(PageNavigationGC); | 
|  412 #undef STRINGIFY_REASON |  412 #undef STRINGIFY_REASON | 
|  413     case NumberOfGCReason: ASSERT_NOT_REACHED(); |  413     case NumberOfGCReason: ASSERT_NOT_REACHED(); | 
|  414     } |  414     } | 
|  415     return "<Unknown>"; |  415     return "<Unknown>"; | 
|  416 } |  416 } | 
|  417  |  417  | 
|  418 void Heap::collectGarbage(ThreadState::StackState stackState, ThreadState::GCTyp
     e gcType, GCReason reason) |  418 void Heap::collectGarbage(BlinkGC::StackState stackState, BlinkGC::GCType gcType
     , GCReason reason) | 
|  419 { |  419 { | 
|  420     ThreadState* state = ThreadState::current(); |  420     ThreadState* state = ThreadState::current(); | 
|  421     // Nested collectGarbage() invocations aren't supported. |  421     // Nested collectGarbage() invocations aren't supported. | 
|  422     RELEASE_ASSERT(!state->isGCForbidden()); |  422     RELEASE_ASSERT(!state->isGCForbidden()); | 
|  423     state->completeSweep(); |  423     state->completeSweep(); | 
|  424  |  424  | 
|  425     GCScope gcScope(state, stackState, gcType); |  425     GCScope gcScope(state, stackState, gcType); | 
|  426     // Check if we successfully parked the other threads.  If not we bail out of |  426     // Check if we successfully parked the other threads.  If not we bail out of | 
|  427     // the GC. |  427     // the GC. | 
|  428     if (!gcScope.allThreadsParked()) |  428     if (!gcScope.allThreadsParked()) | 
|  429         return; |  429         return; | 
|  430  |  430  | 
|  431     if (state->isMainThread()) |  431     if (state->isMainThread()) | 
|  432         ScriptForbiddenScope::enter(); |  432         ScriptForbiddenScope::enter(); | 
|  433  |  433  | 
|  434     TRACE_EVENT2("blink_gc", "Heap::collectGarbage", |  434     TRACE_EVENT2("blink_gc", "Heap::collectGarbage", | 
|  435         "lazySweeping", gcType == ThreadState::GCWithoutSweep, |  435         "lazySweeping", gcType == BlinkGC::GCWithoutSweep, | 
|  436         "gcReason", gcReasonString(reason)); |  436         "gcReason", gcReasonString(reason)); | 
|  437     TRACE_EVENT_SCOPED_SAMPLING_STATE("blink_gc", "BlinkGC"); |  437     TRACE_EVENT_SCOPED_SAMPLING_STATE("blink_gc", "BlinkGC"); | 
|  438     double timeStamp = WTF::currentTimeMS(); |  438     double timeStamp = WTF::currentTimeMS(); | 
|  439  |  439  | 
|  440     if (gcType == ThreadState::TakeSnapshot) |  440     if (gcType == BlinkGC::TakeSnapshot) | 
|  441         BlinkGCMemoryDumpProvider::instance()->clearProcessDumpForCurrentGC(); |  441         BlinkGCMemoryDumpProvider::instance()->clearProcessDumpForCurrentGC(); | 
|  442  |  442  | 
|  443     // Disallow allocation during garbage collection (but not during the |  443     // Disallow allocation during garbage collection (but not during the | 
|  444     // finalization that happens when the gcScope is torn down). |  444     // finalization that happens when the gcScope is torn down). | 
|  445     ThreadState::NoAllocationScope noAllocationScope(state); |  445     ThreadState::NoAllocationScope noAllocationScope(state); | 
|  446  |  446  | 
|  447     preGC(); |  447     preGC(); | 
|  448  |  448  | 
|  449     StackFrameDepthScope stackDepthScope; |  449     StackFrameDepthScope stackDepthScope; | 
|  450  |  450  | 
|  451     size_t totalObjectSize = Heap::allocatedObjectSize() + Heap::markedObjectSiz
     e(); |  451     size_t totalObjectSize = Heap::allocatedObjectSize() + Heap::markedObjectSiz
     e(); | 
|  452     if (gcType != ThreadState::TakeSnapshot) |  452     if (gcType != BlinkGC::TakeSnapshot) | 
|  453         Heap::resetHeapCounters(); |  453         Heap::resetHeapCounters(); | 
|  454  |  454  | 
|  455     // 1. Trace persistent roots. |  455     // 1. Trace persistent roots. | 
|  456     ThreadState::visitPersistentRoots(gcScope.visitor()); |  456     ThreadState::visitPersistentRoots(gcScope.visitor()); | 
|  457  |  457  | 
|  458     // 2. Trace objects reachable from the stack.  We do this independent of the |  458     // 2. Trace objects reachable from the stack.  We do this independent of the | 
|  459     // given stackState since other threads might have a different stack state. |  459     // given stackState since other threads might have a different stack state. | 
|  460     ThreadState::visitStackRoots(gcScope.visitor()); |  460     ThreadState::visitStackRoots(gcScope.visitor()); | 
|  461  |  461  | 
|  462     // 3. Transitive closure to trace objects including ephemerons. |  462     // 3. Transitive closure to trace objects including ephemerons. | 
|  463     processMarkingStack(gcScope.visitor()); |  463     processMarkingStack(gcScope.visitor()); | 
|  464  |  464  | 
|  465     postMarkingProcessing(gcScope.visitor()); |  465     postMarkingProcessing(gcScope.visitor()); | 
|  466     globalWeakProcessing(gcScope.visitor()); |  466     globalWeakProcessing(gcScope.visitor()); | 
|  467  |  467  | 
|  468     // Now we can delete all orphaned pages because there are no dangling |  468     // Now we can delete all orphaned pages because there are no dangling | 
|  469     // pointers to the orphaned pages.  (If we have such dangling pointers, |  469     // pointers to the orphaned pages.  (If we have such dangling pointers, | 
|  470     // we should have crashed during marking before getting here.) |  470     // we should have crashed during marking before getting here.) | 
|  471     orphanedPagePool()->decommitOrphanedPages(); |  471     orphanedPagePool()->decommitOrphanedPages(); | 
|  472  |  472  | 
|  473     double markingTimeInMilliseconds = WTF::currentTimeMS() - timeStamp; |  473     double markingTimeInMilliseconds = WTF::currentTimeMS() - timeStamp; | 
|  474     s_estimatedMarkingTimePerByte = totalObjectSize ? (markingTimeInMilliseconds
      / 1000 / totalObjectSize) : 0; |  474     s_estimatedMarkingTimePerByte = totalObjectSize ? (markingTimeInMilliseconds
      / 1000 / totalObjectSize) : 0; | 
|  475  |  475  | 
|  476 #if PRINT_HEAP_STATS |  476 #if PRINT_HEAP_STATS | 
|  477     dataLogF("Heap::collectGarbage (gcReason=%s, lazySweeping=%d, time=%.1lfms)\
     n", gcReasonString(reason), gcType == ThreadState::GCWithoutSweep, markingTimeIn
     Milliseconds); |  477     dataLogF("Heap::collectGarbage (gcReason=%s, lazySweeping=%d, time=%.1lfms)\
     n", gcReasonString(reason), gcType == BlinkGC::GCWithoutSweep, markingTimeInMill
     iseconds); | 
|  478 #endif |  478 #endif | 
|  479  |  479  | 
|  480     Platform::current()->histogramCustomCounts("BlinkGC.CollectGarbage", marking
     TimeInMilliseconds, 0, 10 * 1000, 50); |  480     Platform::current()->histogramCustomCounts("BlinkGC.CollectGarbage", marking
     TimeInMilliseconds, 0, 10 * 1000, 50); | 
|  481     Platform::current()->histogramCustomCounts("BlinkGC.TotalObjectSpace", Heap:
     :allocatedObjectSize() / 1024, 0, 4 * 1024 * 1024, 50); |  481     Platform::current()->histogramCustomCounts("BlinkGC.TotalObjectSpace", Heap:
     :allocatedObjectSize() / 1024, 0, 4 * 1024 * 1024, 50); | 
|  482     Platform::current()->histogramCustomCounts("BlinkGC.TotalAllocatedSpace", He
     ap::allocatedSpace() / 1024, 0, 4 * 1024 * 1024, 50); |  482     Platform::current()->histogramCustomCounts("BlinkGC.TotalAllocatedSpace", He
     ap::allocatedSpace() / 1024, 0, 4 * 1024 * 1024, 50); | 
|  483     Platform::current()->histogramEnumeration("BlinkGC.GCReason", reason, Number
     OfGCReason); |  483     Platform::current()->histogramEnumeration("BlinkGC.GCReason", reason, Number
     OfGCReason); | 
|  484     Heap::reportMemoryUsageHistogram(); |  484     Heap::reportMemoryUsageHistogram(); | 
|  485     WTF::Partitions::reportMemoryUsageHistogram(); |  485     WTF::Partitions::reportMemoryUsageHistogram(); | 
|  486  |  486  | 
|  487     postGC(gcType); |  487     postGC(gcType); | 
|  488  |  488  | 
|  489     if (state->isMainThread()) |  489     if (state->isMainThread()) | 
|  490         ScriptForbiddenScope::exit(); |  490         ScriptForbiddenScope::exit(); | 
|  491 } |  491 } | 
|  492  |  492  | 
|  493 void Heap::collectGarbageForTerminatingThread(ThreadState* state) |  493 void Heap::collectGarbageForTerminatingThread(ThreadState* state) | 
|  494 { |  494 { | 
|  495     { |  495     { | 
|  496         // A thread-specific termination GC must not allow other global GCs to g
     o |  496         // A thread-specific termination GC must not allow other global GCs to g
     o | 
|  497         // ahead while it is running, hence the termination GC does not enter a |  497         // ahead while it is running, hence the termination GC does not enter a | 
|  498         // safepoint. GCScope will not enter also a safepoint scope for |  498         // safepoint. GCScope will not enter also a safepoint scope for | 
|  499         // ThreadTerminationGC. |  499         // ThreadTerminationGC. | 
|  500         GCScope gcScope(state, ThreadState::NoHeapPointersOnStack, ThreadState::
     ThreadTerminationGC); |  500         GCScope gcScope(state, BlinkGC::NoHeapPointersOnStack, BlinkGC::ThreadTe
     rminationGC); | 
|  501  |  501  | 
|  502         ThreadState::NoAllocationScope noAllocationScope(state); |  502         ThreadState::NoAllocationScope noAllocationScope(state); | 
|  503  |  503  | 
|  504         state->preGC(); |  504         state->preGC(); | 
|  505         StackFrameDepthScope stackDepthScope; |  505         StackFrameDepthScope stackDepthScope; | 
|  506  |  506  | 
|  507         // 1. Trace the thread local persistent roots. For thread local GCs we |  507         // 1. Trace the thread local persistent roots. For thread local GCs we | 
|  508         // don't trace the stack (ie. no conservative scanning) since this is |  508         // don't trace the stack (ie. no conservative scanning) since this is | 
|  509         // only called during thread shutdown where there should be no objects |  509         // only called during thread shutdown where there should be no objects | 
|  510         // on the stack. |  510         // on the stack. | 
|  511         // We also assume that orphaned pages have no objects reachable from |  511         // We also assume that orphaned pages have no objects reachable from | 
|  512         // persistent handles on other threads or CrossThreadPersistents.  The |  512         // persistent handles on other threads or CrossThreadPersistents.  The | 
|  513         // only cases where this could happen is if a subsequent conservative |  513         // only cases where this could happen is if a subsequent conservative | 
|  514         // global GC finds a "pointer" on the stack or due to a programming |  514         // global GC finds a "pointer" on the stack or due to a programming | 
|  515         // error where an object has a dangling cross-thread pointer to an |  515         // error where an object has a dangling cross-thread pointer to an | 
|  516         // object on this heap. |  516         // object on this heap. | 
|  517         state->visitPersistents(gcScope.visitor()); |  517         state->visitPersistents(gcScope.visitor()); | 
|  518  |  518  | 
|  519         // 2. Trace objects reachable from the thread's persistent roots |  519         // 2. Trace objects reachable from the thread's persistent roots | 
|  520         // including ephemerons. |  520         // including ephemerons. | 
|  521         processMarkingStack(gcScope.visitor()); |  521         processMarkingStack(gcScope.visitor()); | 
|  522  |  522  | 
|  523         postMarkingProcessing(gcScope.visitor()); |  523         postMarkingProcessing(gcScope.visitor()); | 
|  524         globalWeakProcessing(gcScope.visitor()); |  524         globalWeakProcessing(gcScope.visitor()); | 
|  525  |  525  | 
|  526         state->postGC(ThreadState::GCWithSweep); |  526         state->postGC(BlinkGC::GCWithSweep); | 
|  527     } |  527     } | 
|  528     state->preSweep(); |  528     state->preSweep(); | 
|  529 } |  529 } | 
|  530  |  530  | 
|  531 void Heap::processMarkingStack(Visitor* visitor) |  531 void Heap::processMarkingStack(Visitor* visitor) | 
|  532 { |  532 { | 
|  533     // Ephemeron fixed point loop. |  533     // Ephemeron fixed point loop. | 
|  534     do { |  534     do { | 
|  535         { |  535         { | 
|  536             // Iteratively mark all objects that are reachable from the objects |  536             // Iteratively mark all objects that are reachable from the objects | 
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  577     // It is not permitted to trace pointers of live objects in the weak |  577     // It is not permitted to trace pointers of live objects in the weak | 
|  578     // callback phase, so the marking stack should still be empty here. |  578     // callback phase, so the marking stack should still be empty here. | 
|  579     ASSERT(s_markingStack->isEmpty()); |  579     ASSERT(s_markingStack->isEmpty()); | 
|  580 } |  580 } | 
|  581  |  581  | 
|  582 void Heap::collectAllGarbage() |  582 void Heap::collectAllGarbage() | 
|  583 { |  583 { | 
|  584     // We need to run multiple GCs to collect a chain of persistent handles. |  584     // We need to run multiple GCs to collect a chain of persistent handles. | 
|  585     size_t previousLiveObjects = 0; |  585     size_t previousLiveObjects = 0; | 
|  586     for (int i = 0; i < 5; ++i) { |  586     for (int i = 0; i < 5; ++i) { | 
|  587         collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWithSw
     eep, ForcedGC); |  587         collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSweep, For
     cedGC); | 
|  588         size_t liveObjects = Heap::markedObjectSize(); |  588         size_t liveObjects = Heap::markedObjectSize(); | 
|  589         if (liveObjects == previousLiveObjects) |  589         if (liveObjects == previousLiveObjects) | 
|  590             break; |  590             break; | 
|  591         previousLiveObjects = liveObjects; |  591         previousLiveObjects = liveObjects; | 
|  592     } |  592     } | 
|  593 } |  593 } | 
|  594  |  594  | 
|  595 double Heap::estimatedMarkingTime() |  595 double Heap::estimatedMarkingTime() | 
|  596 { |  596 { | 
|  597     ASSERT(ThreadState::current()->isMainThread()); |  597     ASSERT(ThreadState::current()->isMainThread()); | 
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  786 size_t Heap::s_objectSizeAtLastGC = 0; |  786 size_t Heap::s_objectSizeAtLastGC = 0; | 
|  787 size_t Heap::s_markedObjectSize = 0; |  787 size_t Heap::s_markedObjectSize = 0; | 
|  788 size_t Heap::s_markedObjectSizeAtLastCompleteSweep = 0; |  788 size_t Heap::s_markedObjectSizeAtLastCompleteSweep = 0; | 
|  789 size_t Heap::s_wrapperCount = 0; |  789 size_t Heap::s_wrapperCount = 0; | 
|  790 size_t Heap::s_wrapperCountAtLastGC = 0; |  790 size_t Heap::s_wrapperCountAtLastGC = 0; | 
|  791 size_t Heap::s_collectedWrapperCount = 0; |  791 size_t Heap::s_collectedWrapperCount = 0; | 
|  792 size_t Heap::s_partitionAllocSizeAtLastGC = 0; |  792 size_t Heap::s_partitionAllocSizeAtLastGC = 0; | 
|  793 double Heap::s_estimatedMarkingTimePerByte = 0.0; |  793 double Heap::s_estimatedMarkingTimePerByte = 0.0; | 
|  794  |  794  | 
|  795 } // namespace blink |  795 } // namespace blink | 
| OLD | NEW |