| 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 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 575 if (objectFields[i] != 0) | 575 if (objectFields[i] != 0) |
| 576 return false; | 576 return false; |
| 577 } | 577 } |
| 578 return true; | 578 return true; |
| 579 } | 579 } |
| 580 #endif | 580 #endif |
| 581 | 581 |
| 582 template<> | 582 template<> |
| 583 void LargeObject<FinalizedHeapObjectHeader>::mark(Visitor* visitor) | 583 void LargeObject<FinalizedHeapObjectHeader>::mark(Visitor* visitor) |
| 584 { | 584 { |
| 585 if (heapObjectHeader()->hasVTable() && !vTableInitialized(payload())) { | 585 FinalizedHeapObjectHeader* header = heapObjectHeader(); |
| 586 FinalizedHeapObjectHeader* header = heapObjectHeader(); | 586 if (header->hasVTable() && !vTableInitialized(payload())) { |
| 587 visitor->markNoTracing(header); | 587 visitor->markNoTracing(header); |
| 588 ASSERT(isUninitializedMemory(header->payload(), header->payloadSize())); | 588 ASSERT(isUninitializedMemory(header->payload(), header->payloadSize())); |
| 589 } else { | 589 } else { |
| 590 visitor->mark(heapObjectHeader(), heapObjectHeader()->traceCallback()); | 590 visitor->mark(header, header->traceCallback()); |
| 591 } | 591 } |
| 592 } | 592 } |
| 593 | 593 |
| 594 template<> | 594 template<> |
| 595 void LargeObject<HeapObjectHeader>::mark(Visitor* visitor) | 595 void LargeObject<HeapObjectHeader>::mark(Visitor* visitor) |
| 596 { | 596 { |
| 597 ASSERT(gcInfo()); | 597 ASSERT(gcInfo()); |
| 598 if (gcInfo()->hasVTable() && !vTableInitialized(payload())) { | 598 if (gcInfo()->hasVTable() && !vTableInitialized(payload())) { |
| 599 HeapObjectHeader* header = heapObjectHeader(); | 599 HeapObjectHeader* header = heapObjectHeader(); |
| 600 visitor->markNoTracing(header); | 600 visitor->markNoTracing(header); |
| (...skipping 1355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1956 void Heap::flushHeapDoesNotContainCache() | 1956 void Heap::flushHeapDoesNotContainCache() |
| 1957 { | 1957 { |
| 1958 s_heapDoesNotContainCache->flush(); | 1958 s_heapDoesNotContainCache->flush(); |
| 1959 } | 1959 } |
| 1960 | 1960 |
| 1961 static void markNoTracingCallback(Visitor* visitor, void* object) | 1961 static void markNoTracingCallback(Visitor* visitor, void* object) |
| 1962 { | 1962 { |
| 1963 visitor->markNoTracing(object); | 1963 visitor->markNoTracing(object); |
| 1964 } | 1964 } |
| 1965 | 1965 |
| 1966 enum MarkingMode { |
| 1967 GlobalMarking, |
| 1968 ThreadLocalMarking, |
| 1969 }; |
| 1970 |
| 1971 template<MarkingMode Mode> |
| 1966 class MarkingVisitor final : public Visitor { | 1972 class MarkingVisitor final : public Visitor { |
| 1967 public: | 1973 public: |
| 1968 #if ENABLE(GC_PROFILE_MARKING) | 1974 #if ENABLE(GC_PROFILE_MARKING) |
| 1969 typedef HashSet<uintptr_t> LiveObjectSet; | 1975 typedef HashSet<uintptr_t> LiveObjectSet; |
| 1970 typedef HashMap<String, LiveObjectSet> LiveObjectMap; | 1976 typedef HashMap<String, LiveObjectSet> LiveObjectMap; |
| 1971 typedef HashMap<uintptr_t, std::pair<uintptr_t, String> > ObjectGraph; | 1977 typedef HashMap<uintptr_t, std::pair<uintptr_t, String> > ObjectGraph; |
| 1972 #endif | 1978 #endif |
| 1973 | 1979 |
| 1974 MarkingVisitor(CallbackStack* markingStack) : m_markingStack(markingStack) | 1980 explicit MarkingVisitor(CallbackStack* markingStack) |
| 1981 : m_markingStack(markingStack) |
| 1975 { | 1982 { |
| 1976 } | 1983 } |
| 1977 | 1984 |
| 1978 inline void visitHeader(HeapObjectHeader* header, const void* objectPointer,
TraceCallback callback) | 1985 inline void visitHeader(HeapObjectHeader* header, const void* objectPointer,
TraceCallback callback) |
| 1979 { | 1986 { |
| 1980 ASSERT(header); | 1987 ASSERT(header); |
| 1981 #if ENABLE(ASSERT) | |
| 1982 { | |
| 1983 // Check that we are not marking objects that are outside | |
| 1984 // the heap by calling Heap::contains. However we cannot | |
| 1985 // call Heap::contains when outside a GC and we call mark | |
| 1986 // when doing weakness for ephemerons. Hence we only check | |
| 1987 // when called within. | |
| 1988 ASSERT(!Heap::isInGC() || Heap::containedInHeapOrOrphanedPage(header
)); | |
| 1989 } | |
| 1990 #endif | |
| 1991 ASSERT(objectPointer); | 1988 ASSERT(objectPointer); |
| 1989 // Check that we are not marking objects that are outside |
| 1990 // the heap by calling Heap::contains. However we cannot |
| 1991 // call Heap::contains when outside a GC and we call mark |
| 1992 // when doing weakness for ephemerons. Hence we only check |
| 1993 // when called within. |
| 1994 ASSERT(!Heap::isInGC() || Heap::containedInHeapOrOrphanedPage(header)); |
| 1995 |
| 1992 if (header->isMarked()) | 1996 if (header->isMarked()) |
| 1993 return; | 1997 return; |
| 1994 header->mark(); | 1998 header->mark(); |
| 1999 |
| 1995 #if ENABLE(GC_PROFILE_MARKING) | 2000 #if ENABLE(GC_PROFILE_MARKING) |
| 1996 MutexLocker locker(objectGraphMutex()); | 2001 MutexLocker locker(objectGraphMutex()); |
| 1997 String className(classOf(objectPointer)); | 2002 String className(classOf(objectPointer)); |
| 1998 { | 2003 { |
| 1999 LiveObjectMap::AddResult result = currentlyLive().add(className, Liv
eObjectSet()); | 2004 LiveObjectMap::AddResult result = currentlyLive().add(className, Liv
eObjectSet()); |
| 2000 result.storedValue->value.add(reinterpret_cast<uintptr_t>(objectPoin
ter)); | 2005 result.storedValue->value.add(reinterpret_cast<uintptr_t>(objectPoin
ter)); |
| 2001 } | 2006 } |
| 2002 ObjectGraph::AddResult result = objectGraph().add(reinterpret_cast<uintp
tr_t>(objectPointer), std::make_pair(reinterpret_cast<uintptr_t>(m_hostObject),
m_hostName)); | 2007 ObjectGraph::AddResult result = objectGraph().add(reinterpret_cast<uintp
tr_t>(objectPointer), std::make_pair(reinterpret_cast<uintptr_t>(m_hostObject),
m_hostName)); |
| 2003 ASSERT(result.isNewEntry); | 2008 ASSERT(result.isNewEntry); |
| 2004 // fprintf(stderr, "%s[%p] -> %s[%p]\n", m_hostName.ascii().data(), m_ho
stObject, className.ascii().data(), objectPointer); | 2009 // fprintf(stderr, "%s[%p] -> %s[%p]\n", m_hostName.ascii().data(), m_ho
stObject, className.ascii().data(), objectPointer); |
| 2005 #endif | 2010 #endif |
| 2011 // If you hit this ASSERT, it means that there is a dangling pointer |
| 2012 // from a live thread heap to a dead thread heap. We must eliminate |
| 2013 // the dangling pointer. |
| 2014 // Release builds don't have the ASSERT, but it is OK because |
| 2015 // release builds will crash upon invoking the trace callback |
| 2016 // as all the entries of the orphaned heaps are zeroed out |
| 2017 // (=> 'objectPointer' will not have a valid vtable.) |
| 2018 ASSERT(!pageFromObject(objectPointer)->orphaned()); |
| 2019 |
| 2020 if (Mode == ThreadLocalMarking && !objectInTerminatingThreadHeap(objectP
ointer)) |
| 2021 return; |
| 2022 |
| 2006 if (callback) | 2023 if (callback) |
| 2007 Heap::pushTraceCallback(m_markingStack, const_cast<void*>(objectPoin
ter), callback); | 2024 Heap::pushTraceCallback(m_markingStack, const_cast<void*>(objectPoin
ter), callback); |
| 2008 } | 2025 } |
| 2009 | 2026 |
| 2027 // We need both HeapObjectHeader and FinalizedHeapObjectHeader versions to c
orrectly find the payload. |
| 2010 virtual void mark(HeapObjectHeader* header, TraceCallback callback) override | 2028 virtual void mark(HeapObjectHeader* header, TraceCallback callback) override |
| 2011 { | 2029 { |
| 2012 // We need both the HeapObjectHeader and FinalizedHeapObjectHeader | |
| 2013 // version to correctly find the payload. | |
| 2014 visitHeader(header, header->payload(), callback); | 2030 visitHeader(header, header->payload(), callback); |
| 2015 } | 2031 } |
| 2016 | 2032 |
| 2017 virtual void mark(FinalizedHeapObjectHeader* header, TraceCallback callback)
override | 2033 virtual void mark(FinalizedHeapObjectHeader* header, TraceCallback callback)
override |
| 2018 { | 2034 { |
| 2019 // We need both the HeapObjectHeader and FinalizedHeapObjectHeader | |
| 2020 // version to correctly find the payload. | |
| 2021 visitHeader(header, header->payload(), callback); | 2035 visitHeader(header, header->payload(), callback); |
| 2022 } | 2036 } |
| 2023 | 2037 |
| 2024 virtual void mark(const void* objectPointer, TraceCallback callback) overrid
e | 2038 virtual void mark(const void* objectPointer, TraceCallback callback) overrid
e |
| 2025 { | 2039 { |
| 2026 if (!objectPointer) | 2040 if (!objectPointer) |
| 2027 return; | 2041 return; |
| 2028 FinalizedHeapObjectHeader* header = FinalizedHeapObjectHeader::fromPaylo
ad(objectPointer); | 2042 FinalizedHeapObjectHeader* header = FinalizedHeapObjectHeader::fromPaylo
ad(objectPointer); |
| 2029 visitHeader(header, header->payload(), callback); | 2043 visitHeader(header, header->payload(), callback); |
| 2030 } | 2044 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2049 { | 2063 { |
| 2050 return Heap::weakTableRegistered(closure); | 2064 return Heap::weakTableRegistered(closure); |
| 2051 } | 2065 } |
| 2052 #endif | 2066 #endif |
| 2053 | 2067 |
| 2054 virtual bool isMarked(const void* objectPointer) override | 2068 virtual bool isMarked(const void* objectPointer) override |
| 2055 { | 2069 { |
| 2056 return FinalizedHeapObjectHeader::fromPayload(objectPointer)->isMarked()
; | 2070 return FinalizedHeapObjectHeader::fromPayload(objectPointer)->isMarked()
; |
| 2057 } | 2071 } |
| 2058 | 2072 |
| 2073 virtual bool ensureMarked(const void* objectPointer) override |
| 2074 { |
| 2075 if (!objectPointer) |
| 2076 return false; |
| 2077 #if ENABLE(ASSERT) |
| 2078 if (isMarked(objectPointer)) |
| 2079 return false; |
| 2080 |
| 2081 markNoTracing(objectPointer); |
| 2082 #else |
| 2083 // Inline what the above markNoTracing() call expands to, |
| 2084 // so as to make sure that we do get all the benefits. |
| 2085 FinalizedHeapObjectHeader* header = |
| 2086 FinalizedHeapObjectHeader::fromPayload(objectPointer); |
| 2087 if (header->isMarked()) |
| 2088 return false; |
| 2089 header->mark(); |
| 2090 #endif |
| 2091 if (Mode == ThreadLocalMarking && !objectInTerminatingThreadHeap(objectP
ointer)) |
| 2092 return false; |
| 2093 return true; |
| 2094 } |
| 2095 |
| 2096 #if ENABLE(ASSERT) |
| 2097 #define DEFINE_ENSURE_MARKED_METHOD(Type)
\ |
| 2098 virtual bool ensureMarked(const Type* objectPointer) override
\ |
| 2099 {
\ |
| 2100 if (!objectPointer)
\ |
| 2101 return false;
\ |
| 2102 COMPILE_ASSERT(!NeedsAdjustAndMark<Type>::value, CanOnlyUseIsMarkedOnNon
AdjustedTypes); \ |
| 2103 if (isMarked(objectPointer))
\ |
| 2104 return false;
\ |
| 2105 markNoTracing(objectPointer);
\ |
| 2106 if (Mode == ThreadLocalMarking && !objectInTerminatingThreadHeap(objectP
ointer)) \ |
| 2107 return false;
\ |
| 2108 return true;
\ |
| 2109 } |
| 2110 #else |
| 2111 #define DEFINE_ENSURE_MARKED_METHOD(Type)
\ |
| 2112 virtual bool ensureMarked(const Type* objectPointer) override
\ |
| 2113 {
\ |
| 2114 if (!objectPointer)
\ |
| 2115 return false;
\ |
| 2116 HeapObjectHeader* header =
\ |
| 2117 HeapObjectHeader::fromPayload(objectPointer);
\ |
| 2118 if (header->isMarked())
\ |
| 2119 return false;
\ |
| 2120 header->mark();
\ |
| 2121 if (Mode == ThreadLocalMarking && !objectInTerminatingThreadHeap(objectP
ointer)) \ |
| 2122 return false;
\ |
| 2123 return true;
\ |
| 2124 } |
| 2125 #endif |
| 2126 |
| 2059 // This macro defines the necessary visitor methods for typed heaps | 2127 // This macro defines the necessary visitor methods for typed heaps |
| 2060 #define DEFINE_VISITOR_METHODS(Type)
\ | 2128 #define DEFINE_VISITOR_METHODS(Type)
\ |
| 2061 virtual void mark(const Type* objectPointer, TraceCallback callback) overrid
e \ | 2129 virtual void mark(const Type* objectPointer, TraceCallback callback) overrid
e \ |
| 2062 {
\ | 2130 {
\ |
| 2063 if (!objectPointer)
\ | 2131 if (!objectPointer)
\ |
| 2064 return;
\ | 2132 return;
\ |
| 2065 HeapObjectHeader* header =
\ | 2133 HeapObjectHeader* header =
\ |
| 2066 HeapObjectHeader::fromPayload(objectPointer);
\ | 2134 HeapObjectHeader::fromPayload(objectPointer);
\ |
| 2067 visitHeader(header, header->payload(), callback);
\ | 2135 visitHeader(header, header->payload(), callback);
\ |
| 2068 }
\ | 2136 }
\ |
| 2069 virtual bool isMarked(const Type* objectPointer) override
\ | 2137 virtual bool isMarked(const Type* objectPointer) override
\ |
| 2070 {
\ | 2138 {
\ |
| 2071 return HeapObjectHeader::fromPayload(objectPointer)->isMarked();
\ | 2139 return HeapObjectHeader::fromPayload(objectPointer)->isMarked();
\ |
| 2072 } | 2140 }
\ |
| 2141 DEFINE_ENSURE_MARKED_METHOD(Type) |
| 2073 | 2142 |
| 2074 FOR_EACH_TYPED_HEAP(DEFINE_VISITOR_METHODS) | 2143 FOR_EACH_TYPED_HEAP(DEFINE_VISITOR_METHODS) |
| 2075 #undef DEFINE_VISITOR_METHODS | 2144 #undef DEFINE_VISITOR_METHODS |
| 2076 | 2145 |
| 2077 #if ENABLE(GC_PROFILE_MARKING) | 2146 #if ENABLE(GC_PROFILE_MARKING) |
| 2078 void reportStats() | 2147 void reportStats() |
| 2079 { | 2148 { |
| 2080 fprintf(stderr, "\n---------- AFTER MARKING -------------------\n"); | 2149 fprintf(stderr, "\n---------- AFTER MARKING -------------------\n"); |
| 2081 for (LiveObjectMap::iterator it = currentlyLive().begin(), end = current
lyLive().end(); it != end; ++it) { | 2150 for (LiveObjectMap::iterator it = currentlyLive().begin(), end = current
lyLive().end(); it != end; ++it) { |
| 2082 fprintf(stderr, "%s %u", it->key.ascii().data(), it->value.size()); | 2151 fprintf(stderr, "%s %u", it->key.ascii().data(), it->value.size()); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2163 return graph; | 2232 return graph; |
| 2164 } | 2233 } |
| 2165 | 2234 |
| 2166 static HashSet<uintptr_t>& objectsToFindPath() | 2235 static HashSet<uintptr_t>& objectsToFindPath() |
| 2167 { | 2236 { |
| 2168 DEFINE_STATIC_LOCAL(HashSet<uintptr_t>, set, ()); | 2237 DEFINE_STATIC_LOCAL(HashSet<uintptr_t>, set, ()); |
| 2169 return set; | 2238 return set; |
| 2170 } | 2239 } |
| 2171 #endif | 2240 #endif |
| 2172 | 2241 |
| 2242 static inline bool objectInTerminatingThreadHeap(const void* objectPointer) |
| 2243 { |
| 2244 BaseHeapPage* page = pageFromObject(objectPointer); |
| 2245 ASSERT(!page->orphaned()); |
| 2246 // When doing a thread local GC, the marker checks if |
| 2247 // the object resides in another thread's heap. The |
| 2248 // object should not be traced, if it does. |
| 2249 return page->terminating(); |
| 2250 } |
| 2251 |
| 2173 protected: | 2252 protected: |
| 2174 virtual void registerWeakCell(void** cell, WeakPointerCallback callback) ove
rride | 2253 virtual void registerWeakCell(void** cell, WeakPointerCallback callback) ove
rride |
| 2175 { | 2254 { |
| 2176 Heap::pushWeakCellPointerCallback(cell, callback); | 2255 Heap::pushWeakCellPointerCallback(cell, callback); |
| 2177 } | 2256 } |
| 2178 | 2257 |
| 2179 private: | 2258 private: |
| 2180 CallbackStack* m_markingStack; | 2259 CallbackStack* m_markingStack; |
| 2181 }; | 2260 }; |
| 2182 | 2261 |
| 2183 void Heap::init() | 2262 void Heap::init() |
| 2184 { | 2263 { |
| 2185 ThreadState::init(); | 2264 ThreadState::init(); |
| 2186 s_markingStack = new CallbackStack(); | 2265 s_markingStack = new CallbackStack(); |
| 2187 s_postMarkingCallbackStack = new CallbackStack(); | 2266 s_postMarkingCallbackStack = new CallbackStack(); |
| 2188 s_weakCallbackStack = new CallbackStack(); | 2267 s_weakCallbackStack = new CallbackStack(); |
| 2189 s_ephemeronStack = new CallbackStack(); | 2268 s_ephemeronStack = new CallbackStack(); |
| 2190 s_heapDoesNotContainCache = new HeapDoesNotContainCache(); | 2269 s_heapDoesNotContainCache = new HeapDoesNotContainCache(); |
| 2191 s_markingVisitor = new MarkingVisitor(s_markingStack); | 2270 s_markingVisitor = new MarkingVisitor<GlobalMarking>(s_markingStack); |
| 2192 s_freePagePool = new FreePagePool(); | 2271 s_freePagePool = new FreePagePool(); |
| 2193 s_orphanedPagePool = new OrphanedPagePool(); | 2272 s_orphanedPagePool = new OrphanedPagePool(); |
| 2194 s_allocatedObjectSize = 0; | 2273 s_allocatedObjectSize = 0; |
| 2195 s_allocatedSpace = 0; | 2274 s_allocatedSpace = 0; |
| 2196 s_markedObjectSize = 0; | 2275 s_markedObjectSize = 0; |
| 2197 } | 2276 } |
| 2198 | 2277 |
| 2199 void Heap::shutdown() | 2278 void Heap::shutdown() |
| 2200 { | 2279 { |
| 2201 s_shutdownCalled = true; | 2280 s_shutdownCalled = true; |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2323 builder.append("\n\t"); | 2402 builder.append("\n\t"); |
| 2324 builder.append(frameToName.nullableName()); | 2403 builder.append(frameToName.nullableName()); |
| 2325 --framesToShow; | 2404 --framesToShow; |
| 2326 } | 2405 } |
| 2327 return builder.toString().replace("blink::", ""); | 2406 return builder.toString().replace("blink::", ""); |
| 2328 } | 2407 } |
| 2329 #endif | 2408 #endif |
| 2330 | 2409 |
| 2331 void Heap::pushTraceCallback(CallbackStack* stack, void* object, TraceCallback c
allback) | 2410 void Heap::pushTraceCallback(CallbackStack* stack, void* object, TraceCallback c
allback) |
| 2332 { | 2411 { |
| 2333 #if ENABLE(ASSERT) | 2412 ASSERT(Heap::containedInHeapOrOrphanedPage(object)); |
| 2334 { | |
| 2335 ASSERT(Heap::containedInHeapOrOrphanedPage(object)); | |
| 2336 } | |
| 2337 #endif | |
| 2338 CallbackStack::Item* slot = stack->allocateEntry(); | 2413 CallbackStack::Item* slot = stack->allocateEntry(); |
| 2339 *slot = CallbackStack::Item(object, callback); | 2414 *slot = CallbackStack::Item(object, callback); |
| 2340 } | 2415 } |
| 2341 | 2416 |
| 2342 template<CallbackInvocationMode Mode> | |
| 2343 bool Heap::popAndInvokeTraceCallback(CallbackStack* stack, Visitor* visitor) | 2417 bool Heap::popAndInvokeTraceCallback(CallbackStack* stack, Visitor* visitor) |
| 2344 { | 2418 { |
| 2345 CallbackStack::Item* item = stack->pop(); | 2419 CallbackStack::Item* item = stack->pop(); |
| 2346 if (!item) | 2420 if (!item) |
| 2347 return false; | 2421 return false; |
| 2348 #if ENABLE(ASSERT) | |
| 2349 if (Mode == GlobalMarking) { | |
| 2350 BaseHeapPage* page = pageFromObject(item->object()); | |
| 2351 // If you hit this ASSERT, it means that there is a dangling pointer | |
| 2352 // from a live thread heap to a dead thread heap. We must eliminate | |
| 2353 // the dangling pointer. | |
| 2354 // Release builds don't have the ASSERT, but it is OK because | |
| 2355 // release builds will crash at the following item->call | |
| 2356 // because all the entries of the orphaned heaps are zeroed out and | |
| 2357 // thus the item does not have a valid vtable. | |
| 2358 ASSERT(!page->orphaned()); | |
| 2359 } | |
| 2360 #endif | |
| 2361 if (Mode == ThreadLocalMarking) { | |
| 2362 BaseHeapPage* page = pageFromObject(item->object()); | |
| 2363 ASSERT(!page->orphaned()); | |
| 2364 // When doing a thread local GC, don't trace an object located in | |
| 2365 // a heap of another thread. | |
| 2366 if (!page->terminating()) | |
| 2367 return true; | |
| 2368 } | |
| 2369 | 2422 |
| 2370 #if ENABLE(GC_PROFILE_MARKING) | 2423 #if ENABLE(GC_PROFILE_MARKING) |
| 2371 visitor->setHostInfo(item->object(), classOf(item->object())); | 2424 visitor->setHostInfo(item->object(), classOf(item->object())); |
| 2372 #endif | 2425 #endif |
| 2373 item->call(visitor); | 2426 item->call(visitor); |
| 2374 return true; | 2427 return true; |
| 2375 } | 2428 } |
| 2376 | 2429 |
| 2377 void Heap::pushPostMarkingCallback(void* object, TraceCallback callback) | 2430 void Heap::pushPostMarkingCallback(void* object, TraceCallback callback) |
| 2378 { | 2431 { |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2494 enterGC(); | 2547 enterGC(); |
| 2495 preGC(); | 2548 preGC(); |
| 2496 | 2549 |
| 2497 Heap::resetMarkedObjectSize(); | 2550 Heap::resetMarkedObjectSize(); |
| 2498 Heap::resetAllocatedObjectSize(); | 2551 Heap::resetAllocatedObjectSize(); |
| 2499 | 2552 |
| 2500 // 1. trace persistent roots. | 2553 // 1. trace persistent roots. |
| 2501 ThreadState::visitPersistentRoots(s_markingVisitor); | 2554 ThreadState::visitPersistentRoots(s_markingVisitor); |
| 2502 | 2555 |
| 2503 // 2. trace objects reachable from the persistent roots including ephemerons
. | 2556 // 2. trace objects reachable from the persistent roots including ephemerons
. |
| 2504 processMarkingStack<GlobalMarking>(); | 2557 processMarkingStack(s_markingVisitor); |
| 2505 | 2558 |
| 2506 // 3. trace objects reachable from the stack. We do this independent of the | 2559 // 3. trace objects reachable from the stack. We do this independent of the |
| 2507 // given stackState since other threads might have a different stack state. | 2560 // given stackState since other threads might have a different stack state. |
| 2508 ThreadState::visitStackRoots(s_markingVisitor); | 2561 ThreadState::visitStackRoots(s_markingVisitor); |
| 2509 | 2562 |
| 2510 // 4. trace objects reachable from the stack "roots" including ephemerons. | 2563 // 4. trace objects reachable from the stack "roots" including ephemerons. |
| 2511 // Only do the processing if we found a pointer to an object on one of the | 2564 // Only do the processing if we found a pointer to an object on one of the |
| 2512 // thread stacks. | 2565 // thread stacks. |
| 2513 if (lastGCWasConservative()) { | 2566 if (lastGCWasConservative()) |
| 2514 processMarkingStack<GlobalMarking>(); | 2567 processMarkingStack(s_markingVisitor); |
| 2515 } | |
| 2516 | 2568 |
| 2517 postMarkingProcessing(); | 2569 postMarkingProcessing(s_markingVisitor); |
| 2518 globalWeakProcessing(); | 2570 globalWeakProcessing(s_markingVisitor); |
| 2519 | 2571 |
| 2520 // Now we can delete all orphaned pages because there are no dangling | 2572 // Now we can delete all orphaned pages because there are no dangling |
| 2521 // pointers to the orphaned pages. (If we have such dangling pointers, | 2573 // pointers to the orphaned pages. (If we have such dangling pointers, |
| 2522 // we should have crashed during marking before getting here.) | 2574 // we should have crashed during marking before getting here.) |
| 2523 orphanedPagePool()->decommitOrphanedPages(); | 2575 orphanedPagePool()->decommitOrphanedPages(); |
| 2524 | 2576 |
| 2525 postGC(); | 2577 postGC(); |
| 2526 leaveGC(); | 2578 leaveGC(); |
| 2527 | 2579 |
| 2528 #if ENABLE(GC_PROFILE_MARKING) | 2580 #if ENABLE(GC_PROFILE_MARKING) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2539 ScriptForbiddenScope::exit(); | 2591 ScriptForbiddenScope::exit(); |
| 2540 } | 2592 } |
| 2541 | 2593 |
| 2542 void Heap::collectGarbageForTerminatingThread(ThreadState* state) | 2594 void Heap::collectGarbageForTerminatingThread(ThreadState* state) |
| 2543 { | 2595 { |
| 2544 // We explicitly do not enter a safepoint while doing thread specific | 2596 // We explicitly do not enter a safepoint while doing thread specific |
| 2545 // garbage collection since we don't want to allow a global GC at the | 2597 // garbage collection since we don't want to allow a global GC at the |
| 2546 // same time as a thread local GC. | 2598 // same time as a thread local GC. |
| 2547 | 2599 |
| 2548 { | 2600 { |
| 2601 MarkingVisitor<ThreadLocalMarking> markingVisitor(s_markingStack); |
| 2549 ThreadState::NoAllocationScope noAllocationScope(state); | 2602 ThreadState::NoAllocationScope noAllocationScope(state); |
| 2550 | 2603 |
| 2551 enterGC(); | 2604 enterGC(); |
| 2552 state->preGC(); | 2605 state->preGC(); |
| 2553 | 2606 |
| 2554 // 1. trace the thread local persistent roots. For thread local GCs we | 2607 // 1. trace the thread local persistent roots. For thread local GCs we |
| 2555 // don't trace the stack (ie. no conservative scanning) since this is | 2608 // don't trace the stack (ie. no conservative scanning) since this is |
| 2556 // only called during thread shutdown where there should be no objects | 2609 // only called during thread shutdown where there should be no objects |
| 2557 // on the stack. | 2610 // on the stack. |
| 2558 // We also assume that orphaned pages have no objects reachable from | 2611 // We also assume that orphaned pages have no objects reachable from |
| 2559 // persistent handles on other threads or CrossThreadPersistents. The | 2612 // persistent handles on other threads or CrossThreadPersistents. The |
| 2560 // only cases where this could happen is if a subsequent conservative | 2613 // only cases where this could happen is if a subsequent conservative |
| 2561 // global GC finds a "pointer" on the stack or due to a programming | 2614 // global GC finds a "pointer" on the stack or due to a programming |
| 2562 // error where an object has a dangling cross-thread pointer to an | 2615 // error where an object has a dangling cross-thread pointer to an |
| 2563 // object on this heap. | 2616 // object on this heap. |
| 2564 state->visitPersistents(s_markingVisitor); | 2617 state->visitPersistents(&markingVisitor); |
| 2565 | 2618 |
| 2566 // 2. trace objects reachable from the thread's persistent roots | 2619 // 2. trace objects reachable from the thread's persistent roots |
| 2567 // including ephemerons. | 2620 // including ephemerons. |
| 2568 processMarkingStack<ThreadLocalMarking>(); | 2621 processMarkingStack(&markingVisitor); |
| 2569 | 2622 |
| 2570 postMarkingProcessing(); | 2623 postMarkingProcessing(&markingVisitor); |
| 2571 globalWeakProcessing(); | 2624 globalWeakProcessing(&markingVisitor); |
| 2572 | 2625 |
| 2573 state->postGC(); | 2626 state->postGC(); |
| 2574 leaveGC(); | 2627 leaveGC(); |
| 2575 } | 2628 } |
| 2576 state->performPendingSweep(); | 2629 state->performPendingSweep(); |
| 2577 } | 2630 } |
| 2578 | 2631 |
| 2579 template<CallbackInvocationMode Mode> | 2632 void Heap::processMarkingStack(Visitor* markingVisitor) |
| 2580 void Heap::processMarkingStack() | |
| 2581 { | 2633 { |
| 2582 // Ephemeron fixed point loop. | 2634 // Ephemeron fixed point loop. |
| 2583 do { | 2635 do { |
| 2584 { | 2636 { |
| 2585 // Iteratively mark all objects that are reachable from the objects | 2637 // Iteratively mark all objects that are reachable from the objects |
| 2586 // currently pushed onto the marking stack. If Mode is ThreadLocalMa
rking | 2638 // currently pushed onto the marking stack. |
| 2587 // don't continue tracing if the trace hits an object on another thr
ead's | |
| 2588 // heap. | |
| 2589 TRACE_EVENT0("blink_gc", "Heap::processMarkingStackSingleThreaded"); | 2639 TRACE_EVENT0("blink_gc", "Heap::processMarkingStackSingleThreaded"); |
| 2590 while (popAndInvokeTraceCallback<Mode>(s_markingStack, s_markingVisi
tor)) { } | 2640 while (popAndInvokeTraceCallback(s_markingStack, markingVisitor)) {
} |
| 2591 } | 2641 } |
| 2592 | 2642 |
| 2593 { | 2643 { |
| 2594 // Mark any strong pointers that have now become reachable in epheme
ron | 2644 // Mark any strong pointers that have now become reachable in epheme
ron |
| 2595 // maps. | 2645 // maps. |
| 2596 TRACE_EVENT0("blink_gc", "Heap::processEphemeronStack"); | 2646 TRACE_EVENT0("blink_gc", "Heap::processEphemeronStack"); |
| 2597 s_ephemeronStack->invokeEphemeronCallbacks(s_markingVisitor); | 2647 s_ephemeronStack->invokeEphemeronCallbacks(markingVisitor); |
| 2598 } | 2648 } |
| 2599 | 2649 |
| 2600 // Rerun loop if ephemeron processing queued more objects for tracing. | 2650 // Rerun loop if ephemeron processing queued more objects for tracing. |
| 2601 } while (!s_markingStack->isEmpty()); | 2651 } while (!s_markingStack->isEmpty()); |
| 2602 } | 2652 } |
| 2603 | 2653 |
| 2604 void Heap::postMarkingProcessing() | 2654 void Heap::postMarkingProcessing(Visitor* markingVisitor) |
| 2605 { | 2655 { |
| 2606 TRACE_EVENT0("blink_gc", "Heap::postMarkingProcessing"); | 2656 TRACE_EVENT0("blink_gc", "Heap::postMarkingProcessing"); |
| 2607 // Call post-marking callbacks including: | 2657 // Call post-marking callbacks including: |
| 2608 // 1. the ephemeronIterationDone callbacks on weak tables to do cleanup | 2658 // 1. the ephemeronIterationDone callbacks on weak tables to do cleanup |
| 2609 // (specifically to clear the queued bits for weak hash tables), and | 2659 // (specifically to clear the queued bits for weak hash tables), and |
| 2610 // 2. the markNoTracing callbacks on collection backings to mark them | 2660 // 2. the markNoTracing callbacks on collection backings to mark them |
| 2611 // if they are only reachable from their front objects. | 2661 // if they are only reachable from their front objects. |
| 2612 while (popAndInvokePostMarkingCallback(s_markingVisitor)) { } | 2662 while (popAndInvokePostMarkingCallback(markingVisitor)) { } |
| 2613 | 2663 |
| 2614 s_ephemeronStack->clear(); | 2664 s_ephemeronStack->clear(); |
| 2615 | 2665 |
| 2616 // Post-marking callbacks should not trace any objects and | 2666 // Post-marking callbacks should not trace any objects and |
| 2617 // therefore the marking stack should be empty after the | 2667 // therefore the marking stack should be empty after the |
| 2618 // post-marking callbacks. | 2668 // post-marking callbacks. |
| 2619 ASSERT(s_markingStack->isEmpty()); | 2669 ASSERT(s_markingStack->isEmpty()); |
| 2620 } | 2670 } |
| 2621 | 2671 |
| 2622 void Heap::globalWeakProcessing() | 2672 void Heap::globalWeakProcessing(Visitor* markingVisitor) |
| 2623 { | 2673 { |
| 2624 TRACE_EVENT0("blink_gc", "Heap::globalWeakProcessing"); | 2674 TRACE_EVENT0("blink_gc", "Heap::globalWeakProcessing"); |
| 2625 // Call weak callbacks on objects that may now be pointing to dead | 2675 // Call weak callbacks on objects that may now be pointing to dead |
| 2626 // objects. | 2676 // objects. |
| 2627 while (popAndInvokeWeakPointerCallback(s_markingVisitor)) { } | 2677 while (popAndInvokeWeakPointerCallback(markingVisitor)) { } |
| 2628 | 2678 |
| 2629 // It is not permitted to trace pointers of live objects in the weak | 2679 // It is not permitted to trace pointers of live objects in the weak |
| 2630 // callback phase, so the marking stack should still be empty here. | 2680 // callback phase, so the marking stack should still be empty here. |
| 2631 ASSERT(s_markingStack->isEmpty()); | 2681 ASSERT(s_markingStack->isEmpty()); |
| 2632 } | 2682 } |
| 2633 | 2683 |
| 2634 void Heap::collectAllGarbage() | 2684 void Heap::collectAllGarbage() |
| 2635 { | 2685 { |
| 2636 // FIXME: oilpan: we should perform a single GC and everything | 2686 // FIXME: oilpan: we should perform a single GC and everything |
| 2637 // should die. Unfortunately it is not the case for all objects | 2687 // should die. Unfortunately it is not the case for all objects |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2884 bool Heap::s_lastGCWasConservative = false; | 2934 bool Heap::s_lastGCWasConservative = false; |
| 2885 bool Heap::s_inGC = false; | 2935 bool Heap::s_inGC = false; |
| 2886 FreePagePool* Heap::s_freePagePool; | 2936 FreePagePool* Heap::s_freePagePool; |
| 2887 OrphanedPagePool* Heap::s_orphanedPagePool; | 2937 OrphanedPagePool* Heap::s_orphanedPagePool; |
| 2888 Heap::RegionTree* Heap::s_regionTree = 0; | 2938 Heap::RegionTree* Heap::s_regionTree = 0; |
| 2889 size_t Heap::s_allocatedObjectSize = 0; | 2939 size_t Heap::s_allocatedObjectSize = 0; |
| 2890 size_t Heap::s_allocatedSpace = 0; | 2940 size_t Heap::s_allocatedSpace = 0; |
| 2891 size_t Heap::s_markedObjectSize = 0; | 2941 size_t Heap::s_markedObjectSize = 0; |
| 2892 | 2942 |
| 2893 } // namespace blink | 2943 } // namespace blink |
| OLD | NEW |