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 563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
574 if (objectFields[i] != 0) | 574 if (objectFields[i] != 0) |
575 return false; | 575 return false; |
576 } | 576 } |
577 return true; | 577 return true; |
578 } | 578 } |
579 #endif | 579 #endif |
580 | 580 |
581 template<> | 581 template<> |
582 void LargeObject<FinalizedHeapObjectHeader>::mark(Visitor* visitor) | 582 void LargeObject<FinalizedHeapObjectHeader>::mark(Visitor* visitor) |
583 { | 583 { |
584 if (heapObjectHeader()->hasVTable() && !vTableInitialized(payload())) { | 584 FinalizedHeapObjectHeader* header = heapObjectHeader(); |
585 FinalizedHeapObjectHeader* header = heapObjectHeader(); | 585 if (header->hasVTable() && !vTableInitialized(payload())) { |
586 visitor->markNoTracing(header); | 586 visitor->markNoTracing(header); |
587 ASSERT(isUninitializedMemory(header->payload(), header->payloadSize())); | 587 ASSERT(isUninitializedMemory(header->payload(), header->payloadSize())); |
588 } else { | 588 } else { |
589 visitor->mark(heapObjectHeader(), heapObjectHeader()->traceCallback()); | 589 visitor->mark(header, header->traceCallback()); |
590 } | 590 } |
591 } | 591 } |
592 | 592 |
593 template<> | 593 template<> |
594 void LargeObject<HeapObjectHeader>::mark(Visitor* visitor) | 594 void LargeObject<HeapObjectHeader>::mark(Visitor* visitor) |
595 { | 595 { |
596 ASSERT(gcInfo()); | 596 ASSERT(gcInfo()); |
597 if (gcInfo()->hasVTable() && !vTableInitialized(payload())) { | 597 if (gcInfo()->hasVTable() && !vTableInitialized(payload())) { |
598 HeapObjectHeader* header = heapObjectHeader(); | 598 HeapObjectHeader* header = heapObjectHeader(); |
599 visitor->markNoTracing(header); | 599 visitor->markNoTracing(header); |
(...skipping 901 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1501 { | 1501 { |
1502 setAllocationPoint(0, 0); | 1502 setAllocationPoint(0, 0); |
1503 clearFreeLists(); | 1503 clearFreeLists(); |
1504 } | 1504 } |
1505 | 1505 |
1506 template<typename Header> | 1506 template<typename Header> |
1507 void ThreadHeap<Header>::markUnmarkedObjectsDead() | 1507 void ThreadHeap<Header>::markUnmarkedObjectsDead() |
1508 { | 1508 { |
1509 ASSERT(Heap::isInGC()); | 1509 ASSERT(Heap::isInGC()); |
1510 ASSERT(isConsistentForSweeping()); | 1510 ASSERT(isConsistentForSweeping()); |
1511 for (HeapPage<Header>* page = m_firstPage; page; page = page->next()) { | 1511 for (HeapPage<Header>* page = m_firstPage; page; page = page->next()) { |
kouhei (in TOK)
2014/12/02 00:41:58
Nit: Unintended {}?
kouhei (in TOK)
2014/12/02 06:51:02
Sorry, this was unrelated to your CL. Please ignor
sof
2014/12/02 09:52:15
Your bracing preference is identical to mine thoug
| |
1512 page->markUnmarkedObjectsDead(); | 1512 page->markUnmarkedObjectsDead(); |
1513 } | 1513 } |
1514 for (LargeObject<Header>* largeObject = m_firstLargeObject; largeObject; lar geObject = largeObject->next()) { | 1514 for (LargeObject<Header>* largeObject = m_firstLargeObject; largeObject; lar geObject = largeObject->next()) { |
1515 largeObject->markUnmarkedObjectsDead(); | 1515 largeObject->markUnmarkedObjectsDead(); |
1516 } | 1516 } |
1517 } | 1517 } |
1518 | 1518 |
1519 template<typename Header> | 1519 template<typename Header> |
1520 void ThreadHeap<Header>::clearFreeLists() | 1520 void ThreadHeap<Header>::clearFreeLists() |
1521 { | 1521 { |
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1962 } | 1962 } |
1963 | 1963 |
1964 class MarkingVisitor final : public Visitor { | 1964 class MarkingVisitor final : public Visitor { |
1965 public: | 1965 public: |
1966 #if ENABLE(GC_PROFILE_MARKING) | 1966 #if ENABLE(GC_PROFILE_MARKING) |
1967 typedef HashSet<uintptr_t> LiveObjectSet; | 1967 typedef HashSet<uintptr_t> LiveObjectSet; |
1968 typedef HashMap<String, LiveObjectSet> LiveObjectMap; | 1968 typedef HashMap<String, LiveObjectSet> LiveObjectMap; |
1969 typedef HashMap<uintptr_t, std::pair<uintptr_t, String> > ObjectGraph; | 1969 typedef HashMap<uintptr_t, std::pair<uintptr_t, String> > ObjectGraph; |
1970 #endif | 1970 #endif |
1971 | 1971 |
1972 MarkingVisitor(CallbackStack* markingStack) : m_markingStack(markingStack) | 1972 MarkingVisitor(CallbackStack* markingStack) |
haraken
2014/12/02 06:16:04
Add explicit.
sof
2014/12/02 09:52:15
Done.
| |
1973 : m_markingStack(markingStack) | |
1974 , m_checkIfNeedsTracing(false) | |
1973 { | 1975 { |
1974 } | 1976 } |
1975 | 1977 |
1976 inline void visitHeader(HeapObjectHeader* header, const void* objectPointer, TraceCallback callback) | 1978 inline void visitHeader(HeapObjectHeader* header, const void* objectPointer, TraceCallback callback) |
1977 { | 1979 { |
1978 ASSERT(header); | 1980 ASSERT(header); |
1979 #if ENABLE(ASSERT) | |
1980 { | |
1981 // Check that we are not marking objects that are outside | |
1982 // the heap by calling Heap::contains. However we cannot | |
1983 // call Heap::contains when outside a GC and we call mark | |
1984 // when doing weakness for ephemerons. Hence we only check | |
1985 // when called within. | |
1986 ASSERT(!Heap::isInGC() || Heap::containedInHeapOrOrphanedPage(header )); | |
1987 } | |
1988 #endif | |
1989 ASSERT(objectPointer); | 1981 ASSERT(objectPointer); |
1982 // Check that we are not marking objects that are outside | |
1983 // the heap by calling Heap::contains. However we cannot | |
1984 // call Heap::contains when outside a GC and we call mark | |
1985 // when doing weakness for ephemerons. Hence we only check | |
1986 // when called within. | |
1987 ASSERT(!Heap::isInGC() || Heap::containedInHeapOrOrphanedPage(header)); | |
1988 | |
1990 if (header->isMarked()) | 1989 if (header->isMarked()) |
1991 return; | 1990 return; |
1992 header->mark(); | 1991 header->mark(); |
1992 | |
1993 #if ENABLE(GC_PROFILE_MARKING) | 1993 #if ENABLE(GC_PROFILE_MARKING) |
1994 MutexLocker locker(objectGraphMutex()); | 1994 MutexLocker locker(objectGraphMutex()); |
1995 String className(classOf(objectPointer)); | 1995 String className(classOf(objectPointer)); |
1996 { | 1996 { |
1997 LiveObjectMap::AddResult result = currentlyLive().add(className, Liv eObjectSet()); | 1997 LiveObjectMap::AddResult result = currentlyLive().add(className, Liv eObjectSet()); |
1998 result.storedValue->value.add(reinterpret_cast<uintptr_t>(objectPoin ter)); | 1998 result.storedValue->value.add(reinterpret_cast<uintptr_t>(objectPoin ter)); |
1999 } | 1999 } |
2000 ObjectGraph::AddResult result = objectGraph().add(reinterpret_cast<uintp tr_t>(objectPointer), std::make_pair(reinterpret_cast<uintptr_t>(m_hostObject), m_hostName)); | 2000 ObjectGraph::AddResult result = objectGraph().add(reinterpret_cast<uintp tr_t>(objectPointer), std::make_pair(reinterpret_cast<uintptr_t>(m_hostObject), m_hostName)); |
2001 ASSERT(result.isNewEntry); | 2001 ASSERT(result.isNewEntry); |
2002 // fprintf(stderr, "%s[%p] -> %s[%p]\n", m_hostName.ascii().data(), m_ho stObject, className.ascii().data(), objectPointer); | 2002 // fprintf(stderr, "%s[%p] -> %s[%p]\n", m_hostName.ascii().data(), m_ho stObject, className.ascii().data(), objectPointer); |
2003 #endif | 2003 #endif |
2004 if (callback) | 2004 #if ENABLE(ASSERT) |
2005 { | |
2006 BaseHeapPage* page = pageFromObject(objectPointer); | |
2007 // If you hit this ASSERT, it means that there is a dangling pointer | |
2008 // from a live thread heap to a dead thread heap. We must eliminate | |
2009 // the dangling pointer. | |
2010 // Release builds don't have the ASSERT, but it is OK because | |
2011 // release builds will crash at the following item->call | |
haraken
2014/12/02 06:16:04
Update this comment. Now we don't have "the follow
| |
2012 // because all the entries of the orphaned heaps are zeroed out and | |
2013 // thus the item does not have a valid vtable. | |
2014 ASSERT(!page->orphaned()); | |
2015 } | |
2016 #endif | |
2017 if (callback) { | |
2018 if (UNLIKELY(m_checkIfNeedsTracing && !needsTracing(objectPointer))) | |
2019 return; | |
2020 | |
2005 Heap::pushTraceCallback(m_markingStack, const_cast<void*>(objectPoin ter), callback); | 2021 Heap::pushTraceCallback(m_markingStack, const_cast<void*>(objectPoin ter), callback); |
2022 } | |
2006 } | 2023 } |
2007 | 2024 |
2025 // We need both HeapObjectHeader and FinalizedHeapObjectHeader versions to c orrectly find the payload. | |
2008 virtual void mark(HeapObjectHeader* header, TraceCallback callback) override | 2026 virtual void mark(HeapObjectHeader* header, TraceCallback callback) override |
2009 { | 2027 { |
2010 // We need both the HeapObjectHeader and FinalizedHeapObjectHeader | |
2011 // version to correctly find the payload. | |
2012 visitHeader(header, header->payload(), callback); | 2028 visitHeader(header, header->payload(), callback); |
2013 } | 2029 } |
2014 | 2030 |
2015 virtual void mark(FinalizedHeapObjectHeader* header, TraceCallback callback) override | 2031 virtual void mark(FinalizedHeapObjectHeader* header, TraceCallback callback) override |
2016 { | 2032 { |
2017 // We need both the HeapObjectHeader and FinalizedHeapObjectHeader | |
2018 // version to correctly find the payload. | |
2019 visitHeader(header, header->payload(), callback); | 2033 visitHeader(header, header->payload(), callback); |
2020 } | 2034 } |
2021 | 2035 |
2022 virtual void mark(const void* objectPointer, TraceCallback callback) overrid e | 2036 virtual void mark(const void* objectPointer, TraceCallback callback) overrid e |
2023 { | 2037 { |
2024 if (!objectPointer) | 2038 if (!objectPointer) |
2025 return; | 2039 return; |
2026 FinalizedHeapObjectHeader* header = FinalizedHeapObjectHeader::fromPaylo ad(objectPointer); | 2040 FinalizedHeapObjectHeader* header = FinalizedHeapObjectHeader::fromPaylo ad(objectPointer); |
2027 visitHeader(header, header->payload(), callback); | 2041 visitHeader(header, header->payload(), callback); |
2028 } | 2042 } |
(...skipping 18 matching lines...) Expand all Loading... | |
2047 { | 2061 { |
2048 return Heap::weakTableRegistered(closure); | 2062 return Heap::weakTableRegistered(closure); |
2049 } | 2063 } |
2050 #endif | 2064 #endif |
2051 | 2065 |
2052 virtual bool isMarked(const void* objectPointer) override | 2066 virtual bool isMarked(const void* objectPointer) override |
2053 { | 2067 { |
2054 return FinalizedHeapObjectHeader::fromPayload(objectPointer)->isMarked() ; | 2068 return FinalizedHeapObjectHeader::fromPayload(objectPointer)->isMarked() ; |
2055 } | 2069 } |
2056 | 2070 |
2071 virtual bool ensureMarked(const void* objectPointer) override | |
2072 { | |
2073 if (!objectPointer) | |
2074 return false; | |
2075 #if ENABLE(ASSERT) | |
2076 if (isMarked(objectPointer)) | |
2077 return false; | |
2078 | |
2079 markNoTracing(objectPointer); | |
2080 #else | |
2081 FinalizedHeapObjectHeader* header = | |
2082 FinalizedHeapObjectHeader::fromPayload(objectPointer); | |
2083 if (header->isMarked()) | |
2084 return false; | |
2085 header->mark(); | |
2086 | |
2087 if (UNLIKELY(m_checkIfNeedsTracing && !needsTracing(objectPointer))) | |
haraken
2014/12/02 06:16:04
Hmm, it's a bit unfortunate we need to have this b
sof
2014/12/02 06:19:27
As I said in the previous comment, I don't see a w
sof
2014/12/02 09:52:15
Had a go at the former; acceptable?
| |
2088 return false; | |
2089 #endif | |
2090 return true; | |
2091 } | |
2092 | |
2093 #if ENABLE(ASSERT) | |
2094 #define DEFINE_ENSURE_MARKED_METHOD(Type) \ | |
2095 virtual bool ensureMarked(const Type* objectPointer) override \ | |
2096 { \ | |
2097 if (!objectPointer) \ | |
2098 return false; \ | |
2099 COMPILE_ASSERT(!NeedsAdjustAndMark<Type>::value, CanOnlyUseIsMarkedOnNon AdjustedTypes); \ | |
2100 if (isMarked(objectPointer)) \ | |
2101 return false; \ | |
2102 markNoTracing(objectPointer); \ | |
2103 return true; \ | |
2104 } | |
2105 #else | |
2106 #define DEFINE_ENSURE_MARKED_METHOD(Type) \ | |
2107 virtual bool ensureMarked(const Type* objectPointer) override \ | |
2108 { \ | |
2109 if (!objectPointer) \ | |
2110 return false; \ | |
2111 HeapObjectHeader* header = \ | |
2112 HeapObjectHeader::fromPayload(objectPointer); \ | |
2113 if (header->isMarked()) \ | |
2114 return false; \ | |
2115 header->mark(); \ | |
2116 if (UNLIKELY(m_checkIfNeedsTracing && !needsTracing(objectPointer))) \ | |
2117 return false; \ | |
2118 return true; \ | |
2119 } | |
2120 #endif | |
2121 | |
2057 // This macro defines the necessary visitor methods for typed heaps | 2122 // This macro defines the necessary visitor methods for typed heaps |
2058 #define DEFINE_VISITOR_METHODS(Type) \ | 2123 #define DEFINE_VISITOR_METHODS(Type) \ |
2059 virtual void mark(const Type* objectPointer, TraceCallback callback) overrid e \ | 2124 virtual void mark(const Type* objectPointer, TraceCallback callback) overrid e \ |
2060 { \ | 2125 { \ |
2061 if (!objectPointer) \ | 2126 if (!objectPointer) \ |
2062 return; \ | 2127 return; \ |
2063 HeapObjectHeader* header = \ | 2128 HeapObjectHeader* header = \ |
2064 HeapObjectHeader::fromPayload(objectPointer); \ | 2129 HeapObjectHeader::fromPayload(objectPointer); \ |
2065 visitHeader(header, header->payload(), callback); \ | 2130 visitHeader(header, header->payload(), callback); \ |
2066 } \ | 2131 } \ |
2067 virtual bool isMarked(const Type* objectPointer) override \ | 2132 virtual bool isMarked(const Type* objectPointer) override \ |
2068 { \ | 2133 { \ |
2069 return HeapObjectHeader::fromPayload(objectPointer)->isMarked(); \ | 2134 return HeapObjectHeader::fromPayload(objectPointer)->isMarked(); \ |
2070 } | 2135 } \ |
2136 DEFINE_ENSURE_MARKED_METHOD(Type) | |
2071 | 2137 |
2072 FOR_EACH_TYPED_HEAP(DEFINE_VISITOR_METHODS) | 2138 FOR_EACH_TYPED_HEAP(DEFINE_VISITOR_METHODS) |
2073 #undef DEFINE_VISITOR_METHODS | 2139 #undef DEFINE_VISITOR_METHODS |
2074 | 2140 |
2075 #if ENABLE(GC_PROFILE_MARKING) | 2141 #if ENABLE(GC_PROFILE_MARKING) |
2076 void reportStats() | 2142 void reportStats() |
2077 { | 2143 { |
2078 fprintf(stderr, "\n---------- AFTER MARKING -------------------\n"); | 2144 fprintf(stderr, "\n---------- AFTER MARKING -------------------\n"); |
2079 for (LiveObjectMap::iterator it = currentlyLive().begin(), end = current lyLive().end(); it != end; ++it) { | 2145 for (LiveObjectMap::iterator it = currentlyLive().begin(), end = current lyLive().end(); it != end; ++it) { |
2080 fprintf(stderr, "%s %u", it->key.ascii().data(), it->value.size()); | 2146 fprintf(stderr, "%s %u", it->key.ascii().data(), it->value.size()); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2161 return graph; | 2227 return graph; |
2162 } | 2228 } |
2163 | 2229 |
2164 static HashSet<uintptr_t>& objectsToFindPath() | 2230 static HashSet<uintptr_t>& objectsToFindPath() |
2165 { | 2231 { |
2166 DEFINE_STATIC_LOCAL(HashSet<uintptr_t>, set, ()); | 2232 DEFINE_STATIC_LOCAL(HashSet<uintptr_t>, set, ()); |
2167 return set; | 2233 return set; |
2168 } | 2234 } |
2169 #endif | 2235 #endif |
2170 | 2236 |
2237 static inline bool needsTracing(const void* objectPointer) | |
2238 { | |
2239 BaseHeapPage* page = pageFromObject(objectPointer); | |
2240 ASSERT(!page->orphaned()); | |
2241 // When doing a thread local GC, the marker checks if | |
2242 // the object resides in another thread's heap. The | |
2243 // object should not be traced, if it does. | |
2244 if (!page->terminating()) | |
2245 return false; | |
2246 | |
2247 return true; | |
2248 } | |
2249 | |
2171 protected: | 2250 protected: |
2172 virtual void registerWeakCell(void** cell, WeakPointerCallback callback) ove rride | 2251 virtual void registerWeakCell(void** cell, WeakPointerCallback callback) ove rride |
2173 { | 2252 { |
2174 Heap::pushWeakCellPointerCallback(cell, callback); | 2253 Heap::pushWeakCellPointerCallback(cell, callback); |
2175 } | 2254 } |
2176 | 2255 |
2177 private: | 2256 private: |
2257 friend class ThreadLocalMarkingScope; | |
2258 | |
2178 CallbackStack* m_markingStack; | 2259 CallbackStack* m_markingStack; |
2260 bool m_checkIfNeedsTracing; | |
2261 }; | |
2262 | |
2263 class ThreadLocalMarkingScope { | |
2264 STACK_ALLOCATED(); | |
2265 public: | |
2266 ThreadLocalMarkingScope(MarkingVisitor* visitor) | |
2267 : m_visitor(visitor) | |
2268 { | |
2269 ASSERT(m_visitor); | |
2270 m_visitor->m_checkIfNeedsTracing = true; | |
2271 } | |
2272 | |
2273 ~ThreadLocalMarkingScope() | |
2274 { | |
2275 m_visitor->m_checkIfNeedsTracing = false; | |
2276 } | |
2277 | |
2278 private: | |
2279 MarkingVisitor* m_visitor; | |
2179 }; | 2280 }; |
2180 | 2281 |
2181 void Heap::init() | 2282 void Heap::init() |
2182 { | 2283 { |
2183 ThreadState::init(); | 2284 ThreadState::init(); |
2184 s_markingStack = new CallbackStack(); | 2285 s_markingStack = new CallbackStack(); |
2185 s_postMarkingCallbackStack = new CallbackStack(); | 2286 s_postMarkingCallbackStack = new CallbackStack(); |
2186 s_weakCallbackStack = new CallbackStack(); | 2287 s_weakCallbackStack = new CallbackStack(); |
2187 s_ephemeronStack = new CallbackStack(); | 2288 s_ephemeronStack = new CallbackStack(); |
2188 s_heapDoesNotContainCache = new HeapDoesNotContainCache(); | 2289 s_heapDoesNotContainCache = new HeapDoesNotContainCache(); |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2321 builder.append("\n\t"); | 2422 builder.append("\n\t"); |
2322 builder.append(frameToName.nullableName()); | 2423 builder.append(frameToName.nullableName()); |
2323 --framesToShow; | 2424 --framesToShow; |
2324 } | 2425 } |
2325 return builder.toString().replace("blink::", ""); | 2426 return builder.toString().replace("blink::", ""); |
2326 } | 2427 } |
2327 #endif | 2428 #endif |
2328 | 2429 |
2329 void Heap::pushTraceCallback(CallbackStack* stack, void* object, TraceCallback c allback) | 2430 void Heap::pushTraceCallback(CallbackStack* stack, void* object, TraceCallback c allback) |
2330 { | 2431 { |
2331 #if ENABLE(ASSERT) | 2432 ASSERT(Heap::containedInHeapOrOrphanedPage(object)); |
2332 { | |
2333 ASSERT(Heap::containedInHeapOrOrphanedPage(object)); | |
2334 } | |
2335 #endif | |
2336 CallbackStack::Item* slot = stack->allocateEntry(); | 2433 CallbackStack::Item* slot = stack->allocateEntry(); |
2337 *slot = CallbackStack::Item(object, callback); | 2434 *slot = CallbackStack::Item(object, callback); |
2338 } | 2435 } |
2339 | 2436 |
2340 template<CallbackInvocationMode Mode> | |
2341 bool Heap::popAndInvokeTraceCallback(CallbackStack* stack, Visitor* visitor) | 2437 bool Heap::popAndInvokeTraceCallback(CallbackStack* stack, Visitor* visitor) |
2342 { | 2438 { |
2343 CallbackStack::Item* item = stack->pop(); | 2439 CallbackStack::Item* item = stack->pop(); |
2344 if (!item) | 2440 if (!item) |
2345 return false; | 2441 return false; |
2346 #if ENABLE(ASSERT) | |
2347 if (Mode == GlobalMarking) { | |
2348 BaseHeapPage* page = pageFromObject(item->object()); | |
2349 // If you hit this ASSERT, it means that there is a dangling pointer | |
2350 // from a live thread heap to a dead thread heap. We must eliminate | |
2351 // the dangling pointer. | |
2352 // Release builds don't have the ASSERT, but it is OK because | |
2353 // release builds will crash at the following item->call | |
2354 // because all the entries of the orphaned heaps are zeroed out and | |
2355 // thus the item does not have a valid vtable. | |
2356 ASSERT(!page->orphaned()); | |
2357 } | |
2358 #endif | |
2359 if (Mode == ThreadLocalMarking) { | |
2360 BaseHeapPage* page = pageFromObject(item->object()); | |
2361 ASSERT(!page->orphaned()); | |
2362 // When doing a thread local GC, don't trace an object located in | |
2363 // a heap of another thread. | |
2364 if (!page->terminating()) | |
2365 return true; | |
2366 } | |
2367 | 2442 |
2368 #if ENABLE(GC_PROFILE_MARKING) | 2443 #if ENABLE(GC_PROFILE_MARKING) |
2369 visitor->setHostInfo(item->object(), classOf(item->object())); | 2444 visitor->setHostInfo(item->object(), classOf(item->object())); |
2370 #endif | 2445 #endif |
2371 item->call(visitor); | 2446 item->call(visitor); |
2372 return true; | 2447 return true; |
2373 } | 2448 } |
2374 | 2449 |
2375 void Heap::pushPostMarkingCallback(void* object, TraceCallback callback) | 2450 void Heap::pushPostMarkingCallback(void* object, TraceCallback callback) |
2376 { | 2451 { |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2492 enterGC(); | 2567 enterGC(); |
2493 preGC(); | 2568 preGC(); |
2494 | 2569 |
2495 Heap::resetMarkedObjectSize(); | 2570 Heap::resetMarkedObjectSize(); |
2496 Heap::resetAllocatedObjectSize(); | 2571 Heap::resetAllocatedObjectSize(); |
2497 | 2572 |
2498 // 1. trace persistent roots. | 2573 // 1. trace persistent roots. |
2499 ThreadState::visitPersistentRoots(s_markingVisitor); | 2574 ThreadState::visitPersistentRoots(s_markingVisitor); |
2500 | 2575 |
2501 // 2. trace objects reachable from the persistent roots including ephemerons . | 2576 // 2. trace objects reachable from the persistent roots including ephemerons . |
2502 processMarkingStack<GlobalMarking>(); | 2577 processMarkingStack(); |
2503 | 2578 |
2504 // 3. trace objects reachable from the stack. We do this independent of the | 2579 // 3. trace objects reachable from the stack. We do this independent of the |
2505 // given stackState since other threads might have a different stack state. | 2580 // given stackState since other threads might have a different stack state. |
2506 ThreadState::visitStackRoots(s_markingVisitor); | 2581 ThreadState::visitStackRoots(s_markingVisitor); |
2507 | 2582 |
2508 // 4. trace objects reachable from the stack "roots" including ephemerons. | 2583 // 4. trace objects reachable from the stack "roots" including ephemerons. |
2509 // Only do the processing if we found a pointer to an object on one of the | 2584 // Only do the processing if we found a pointer to an object on one of the |
2510 // thread stacks. | 2585 // thread stacks. |
2511 if (lastGCWasConservative()) { | 2586 if (lastGCWasConservative()) |
2512 processMarkingStack<GlobalMarking>(); | 2587 processMarkingStack(); |
2513 } | |
2514 | 2588 |
2515 postMarkingProcessing(); | 2589 postMarkingProcessing(); |
2516 globalWeakProcessing(); | 2590 globalWeakProcessing(); |
2517 | 2591 |
2518 // Now we can delete all orphaned pages because there are no dangling | 2592 // Now we can delete all orphaned pages because there are no dangling |
2519 // pointers to the orphaned pages. (If we have such dangling pointers, | 2593 // pointers to the orphaned pages. (If we have such dangling pointers, |
2520 // we should have crashed during marking before getting here.) | 2594 // we should have crashed during marking before getting here.) |
2521 orphanedPagePool()->decommitOrphanedPages(); | 2595 orphanedPagePool()->decommitOrphanedPages(); |
2522 | 2596 |
2523 postGC(); | 2597 postGC(); |
(...skipping 18 matching lines...) Expand all Loading... | |
2542 // We explicitly do not enter a safepoint while doing thread specific | 2616 // We explicitly do not enter a safepoint while doing thread specific |
2543 // garbage collection since we don't want to allow a global GC at the | 2617 // garbage collection since we don't want to allow a global GC at the |
2544 // same time as a thread local GC. | 2618 // same time as a thread local GC. |
2545 | 2619 |
2546 { | 2620 { |
2547 NoAllocationScope<AnyThread> noAllocationScope; | 2621 NoAllocationScope<AnyThread> noAllocationScope; |
2548 | 2622 |
2549 enterGC(); | 2623 enterGC(); |
2550 state->preGC(); | 2624 state->preGC(); |
2551 | 2625 |
2552 // 1. trace the thread local persistent roots. For thread local GCs we | 2626 { |
2553 // don't trace the stack (ie. no conservative scanning) since this is | 2627 ThreadLocalMarkingScope markingScope(static_cast<MarkingVisitor*>(s_ markingVisitor)); |
2554 // only called during thread shutdown where there should be no objects | |
2555 // on the stack. | |
2556 // We also assume that orphaned pages have no objects reachable from | |
2557 // persistent handles on other threads or CrossThreadPersistents. The | |
2558 // only cases where this could happen is if a subsequent conservative | |
2559 // global GC finds a "pointer" on the stack or due to a programming | |
2560 // error where an object has a dangling cross-thread pointer to an | |
2561 // object on this heap. | |
2562 state->visitPersistents(s_markingVisitor); | |
2563 | 2628 |
2564 // 2. trace objects reachable from the thread's persistent roots | 2629 // 1. trace the thread local persistent roots. For thread local GCs we |
2565 // including ephemerons. | 2630 // don't trace the stack (ie. no conservative scanning) since this i s |
2566 processMarkingStack<ThreadLocalMarking>(); | 2631 // only called during thread shutdown where there should be no objec ts |
2632 // on the stack. | |
2633 // We also assume that orphaned pages have no objects reachable from | |
2634 // persistent handles on other threads or CrossThreadPersistents. Th e | |
2635 // only cases where this could happen is if a subsequent conservativ e | |
2636 // global GC finds a "pointer" on the stack or due to a programming | |
2637 // error where an object has a dangling cross-thread pointer to an | |
2638 // object on this heap. | |
2639 state->visitPersistents(s_markingVisitor); | |
2640 | |
2641 // 2. trace objects reachable from the thread's persistent roots | |
2642 // including ephemerons. | |
2643 processMarkingStack(); | |
2644 } | |
2567 | 2645 |
2568 postMarkingProcessing(); | 2646 postMarkingProcessing(); |
2569 globalWeakProcessing(); | 2647 globalWeakProcessing(); |
2570 | 2648 |
2571 state->postGC(); | 2649 state->postGC(); |
2572 leaveGC(); | 2650 leaveGC(); |
2573 } | 2651 } |
2574 state->performPendingSweep(); | 2652 state->performPendingSweep(); |
2575 } | 2653 } |
2576 | 2654 |
2577 template<CallbackInvocationMode Mode> | |
2578 void Heap::processMarkingStack() | 2655 void Heap::processMarkingStack() |
2579 { | 2656 { |
2580 // Ephemeron fixed point loop. | 2657 // Ephemeron fixed point loop. |
2581 do { | 2658 do { |
2582 { | 2659 { |
2583 // Iteratively mark all objects that are reachable from the objects | 2660 // Iteratively mark all objects that are reachable from the objects |
2584 // currently pushed onto the marking stack. If Mode is ThreadLocalMa rking | 2661 // currently pushed onto the marking stack. |
2585 // don't continue tracing if the trace hits an object on another thr ead's | |
2586 // heap. | |
2587 TRACE_EVENT0("blink_gc", "Heap::processMarkingStackSingleThreaded"); | 2662 TRACE_EVENT0("blink_gc", "Heap::processMarkingStackSingleThreaded"); |
2588 while (popAndInvokeTraceCallback<Mode>(s_markingStack, s_markingVisi tor)) { } | 2663 while (popAndInvokeTraceCallback(s_markingStack, s_markingVisitor)) { } |
2589 } | 2664 } |
2590 | 2665 |
2591 { | 2666 { |
2592 // Mark any strong pointers that have now become reachable in epheme ron | 2667 // Mark any strong pointers that have now become reachable in epheme ron |
2593 // maps. | 2668 // maps. |
2594 TRACE_EVENT0("blink_gc", "Heap::processEphemeronStack"); | 2669 TRACE_EVENT0("blink_gc", "Heap::processEphemeronStack"); |
2595 s_ephemeronStack->invokeEphemeronCallbacks(s_markingVisitor); | 2670 s_ephemeronStack->invokeEphemeronCallbacks(s_markingVisitor); |
2596 } | 2671 } |
2597 | 2672 |
2598 // Rerun loop if ephemeron processing queued more objects for tracing. | 2673 // Rerun loop if ephemeron processing queued more objects for tracing. |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2844 bool Heap::s_lastGCWasConservative = false; | 2919 bool Heap::s_lastGCWasConservative = false; |
2845 bool Heap::s_inGC = false; | 2920 bool Heap::s_inGC = false; |
2846 FreePagePool* Heap::s_freePagePool; | 2921 FreePagePool* Heap::s_freePagePool; |
2847 OrphanedPagePool* Heap::s_orphanedPagePool; | 2922 OrphanedPagePool* Heap::s_orphanedPagePool; |
2848 Heap::RegionTree* Heap::s_regionTree = 0; | 2923 Heap::RegionTree* Heap::s_regionTree = 0; |
2849 size_t Heap::s_allocatedObjectSize = 0; | 2924 size_t Heap::s_allocatedObjectSize = 0; |
2850 size_t Heap::s_allocatedSpace = 0; | 2925 size_t Heap::s_allocatedSpace = 0; |
2851 size_t Heap::s_markedObjectSize = 0; | 2926 size_t Heap::s_markedObjectSize = 0; |
2852 | 2927 |
2853 } // namespace blink | 2928 } // namespace blink |
OLD | NEW |