Chromium Code Reviews| 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 2061 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2072 static_cast<MarkingVisitor*>(s_markingVisitor)->objectGraph().clear(); | 2072 static_cast<MarkingVisitor*>(s_markingVisitor)->objectGraph().clear(); |
| 2073 #endif | 2073 #endif |
| 2074 | 2074 |
| 2075 // Disallow allocation during garbage collection (but not | 2075 // Disallow allocation during garbage collection (but not |
| 2076 // during the finalization that happens when the gcScope is | 2076 // during the finalization that happens when the gcScope is |
| 2077 // torn down). | 2077 // torn down). |
| 2078 NoAllocationScope<AnyThread> noAllocationScope; | 2078 NoAllocationScope<AnyThread> noAllocationScope; |
| 2079 | 2079 |
| 2080 prepareForGC(); | 2080 prepareForGC(); |
| 2081 | 2081 |
| 2082 traceRootsAndPerformGlobalWeakProcessing<GlobalMarking>(); | 2082 // 1. trace persistent roots. |
| 2083 ThreadState::visitPersistentRoots(s_markingVisitor); | |
| 2084 | |
| 2085 // 2. trace object reachable from the persistent roots including ephemerons. | |
|
haraken
2014/07/22 11:32:43
object => objects
wibling-chromium
2014/07/22 11:56:56
Done.
| |
| 2086 processMarkingStack<GlobalMarking>(); | |
| 2087 | |
| 2088 // 3. trace objects reachable from the stack. We do this independent of the | |
| 2089 // given stackState since other threads might have a different stack state. | |
| 2090 ThreadState::visitStackRoots(s_markingVisitor); | |
| 2091 | |
| 2092 // 4. trace objects reachable from the stack "roots" including ephemerons. | |
|
Erik Corry
2014/07/22 12:39:27
This will always do at least one run through the e
wibling-chromium
2014/07/22 12:46:33
Good idea. I guarded it by lastGCWasConservative()
| |
| 2093 processMarkingStack<GlobalMarking>(); | |
| 2094 | |
| 2095 globalWeakProcessingAndCleanup(); | |
| 2083 | 2096 |
| 2084 // After a global marking we know that any orphaned page that was not reache d | 2097 // After a global marking we know that any orphaned page that was not reache d |
| 2085 // cannot be reached in a subsequent GC. This is due to a thread either havi ng | 2098 // cannot be reached in a subsequent GC. This is due to a thread either havi ng |
| 2086 // swept its heap or having done a "poor mans sweep" in prepareForGC which m arks | 2099 // swept its heap or having done a "poor mans sweep" in prepareForGC which m arks |
| 2087 // objects that are dead, but not swept in the previous GC as dead. In this GC's | 2100 // objects that are dead, but not swept in the previous GC as dead. In this GC's |
| 2088 // marking we check that any object marked as dead is not traced. E.g. via a | 2101 // marking we check that any object marked as dead is not traced. E.g. via a |
| 2089 // conservatively found pointer or a programming error with an object contai ning | 2102 // conservatively found pointer or a programming error with an object contai ning |
| 2090 // a dangling pointer. | 2103 // a dangling pointer. |
| 2091 orphanedPagePool()->decommitOrphanedPages(); | 2104 orphanedPagePool()->decommitOrphanedPages(); |
| 2092 | 2105 |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 2109 // We explicitly do not enter a safepoint while doing thread specific | 2122 // We explicitly do not enter a safepoint while doing thread specific |
| 2110 // garbage collection since we don't want to allow a global GC at the | 2123 // garbage collection since we don't want to allow a global GC at the |
| 2111 // same time as a thread local GC. | 2124 // same time as a thread local GC. |
| 2112 | 2125 |
| 2113 { | 2126 { |
| 2114 NoAllocationScope<AnyThread> noAllocationScope; | 2127 NoAllocationScope<AnyThread> noAllocationScope; |
| 2115 | 2128 |
| 2116 state->enterGC(); | 2129 state->enterGC(); |
| 2117 state->prepareForGC(); | 2130 state->prepareForGC(); |
| 2118 | 2131 |
| 2119 traceRootsAndPerformGlobalWeakProcessing<ThreadLocalMarking>(); | 2132 // 1. trace the thread local persistent roots. For thread local GCs we |
| 2133 // don't trace the stack (ie. no conservative scanning) since this is | |
| 2134 // only called during thread shutdown where there should be no objects | |
| 2135 // on the stack. | |
| 2136 // We also assume that orphaned pages have no objects reachable from | |
| 2137 // persistent handles on other threads or CrossThreadPersistents. The | |
| 2138 // only cases where this could happen is if a subsequent conservative | |
|
haraken
2014/07/22 11:32:43
cases => case
wibling-chromium
2014/07/22 11:56:56
I think it should be "cases" since I mention two s
| |
| 2139 // global GC finds a "pointer" on the stack or due to a programming | |
| 2140 // error where an object has a dangling cross-thread pointer to an | |
| 2141 // object on this heap. | |
| 2142 state->visitPersistents(s_markingVisitor); | |
| 2143 | |
| 2144 // 2. trace objects reachable from the thread's persistent roots | |
| 2145 // including ephemerons. | |
| 2146 processMarkingStack<ThreadLocalMarking>(); | |
| 2147 | |
| 2148 globalWeakProcessingAndCleanup(); | |
| 2120 | 2149 |
| 2121 state->leaveGC(); | 2150 state->leaveGC(); |
| 2122 } | 2151 } |
| 2123 state->performPendingSweep(); | 2152 state->performPendingSweep(); |
| 2124 } | 2153 } |
| 2125 | 2154 |
| 2126 template<CallbackInvocationMode Mode> | 2155 template<CallbackInvocationMode Mode> |
| 2127 void Heap::traceRootsAndPerformGlobalWeakProcessing() | 2156 void Heap::processMarkingStack() |
| 2128 { | 2157 { |
| 2129 if (Mode == ThreadLocalMarking) | |
| 2130 ThreadState::current()->visitLocalRoots(s_markingVisitor); | |
| 2131 else | |
| 2132 ThreadState::visitRoots(s_markingVisitor); | |
| 2133 | |
| 2134 // Ephemeron fixed point loop. | 2158 // Ephemeron fixed point loop. |
| 2135 do { | 2159 do { |
| 2136 // Recursively mark all objects that are reachable from the roots for | 2160 // Iteratively mark all objects that are reachable from the objects |
| 2137 // this thread. If Mode is ThreadLocalMarking don't continue tracing if | 2161 // currently pushed onto the marking stack. If Mode is ThreadLocalMarkin g |
| 2138 // the trace hits an object on another thread's heap. | 2162 // don't continue tracing if the trace hits an object on another thread' s |
| 2163 // heap. | |
| 2139 while (popAndInvokeTraceCallback<Mode>(s_markingVisitor)) { } | 2164 while (popAndInvokeTraceCallback<Mode>(s_markingVisitor)) { } |
| 2140 | 2165 |
| 2141 // Mark any strong pointers that have now become reachable in ephemeron | 2166 // Mark any strong pointers that have now become reachable in ephemeron |
| 2142 // maps. | 2167 // maps. |
| 2143 CallbackStack::invokeCallbacks(&s_ephemeronStack, s_markingVisitor); | 2168 CallbackStack::invokeCallbacks(&s_ephemeronStack, s_markingVisitor); |
| 2144 | 2169 |
| 2145 // Rerun loop if ephemeron processing queued more objects for tracing. | 2170 // Rerun loop if ephemeron processing queued more objects for tracing. |
| 2146 } while (!s_markingStack->isEmpty()); | 2171 } while (!s_markingStack->isEmpty()); |
| 2172 } | |
| 2147 | 2173 |
| 2174 void Heap::globalWeakProcessingAndCleanup() | |
| 2175 { | |
| 2148 // Call weak callbacks on objects that may now be pointing to dead | 2176 // Call weak callbacks on objects that may now be pointing to dead |
| 2149 // objects and call ephemeronIterationDone callbacks on weak tables | 2177 // objects and call ephemeronIterationDone callbacks on weak tables |
| 2150 // to do cleanup (specifically clear the queued bits for weak hash | 2178 // to do cleanup (specifically clear the queued bits for weak hash |
| 2151 // tables). | 2179 // tables). |
| 2152 while (popAndInvokeWeakPointerCallback(s_markingVisitor)) { } | 2180 while (popAndInvokeWeakPointerCallback(s_markingVisitor)) { } |
| 2153 | 2181 |
| 2154 CallbackStack::clear(&s_ephemeronStack); | 2182 CallbackStack::clear(&s_ephemeronStack); |
| 2155 | 2183 |
| 2156 // It is not permitted to trace pointers of live objects in the weak | 2184 // It is not permitted to trace pointers of live objects in the weak |
| 2157 // callback phase, so the marking stack should still be empty here. | 2185 // callback phase, so the marking stack should still be empty here. |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2242 Visitor* Heap::s_markingVisitor; | 2270 Visitor* Heap::s_markingVisitor; |
| 2243 CallbackStack* Heap::s_markingStack; | 2271 CallbackStack* Heap::s_markingStack; |
| 2244 CallbackStack* Heap::s_weakCallbackStack; | 2272 CallbackStack* Heap::s_weakCallbackStack; |
| 2245 CallbackStack* Heap::s_ephemeronStack; | 2273 CallbackStack* Heap::s_ephemeronStack; |
| 2246 HeapDoesNotContainCache* Heap::s_heapDoesNotContainCache; | 2274 HeapDoesNotContainCache* Heap::s_heapDoesNotContainCache; |
| 2247 bool Heap::s_shutdownCalled = false; | 2275 bool Heap::s_shutdownCalled = false; |
| 2248 bool Heap::s_lastGCWasConservative = false; | 2276 bool Heap::s_lastGCWasConservative = false; |
| 2249 FreePagePool* Heap::s_freePagePool; | 2277 FreePagePool* Heap::s_freePagePool; |
| 2250 OrphanedPagePool* Heap::s_orphanedPagePool; | 2278 OrphanedPagePool* Heap::s_orphanedPagePool; |
| 2251 } | 2279 } |
| OLD | NEW |