Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(212)

Side by Side Diff: src/heap/mark-compact.cc

Issue 2377273002: [heap] Always use getter when accessing MarkingDeque (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/heap/mark-compact-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/heap/mark-compact.h" 5 #include "src/heap/mark-compact.h"
6 6
7 #include "src/base/atomicops.h" 7 #include "src/base/atomicops.h"
8 #include "src/base/bits.h" 8 #include "src/base/bits.h"
9 #include "src/base/sys-info.h" 9 #include "src/base/sys-info.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 1959 matching lines...) Expand 10 before | Expand all | Expand 10 after
1970 1970
1971 void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) { 1971 void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) {
1972 // Mark the heap roots including global variables, stack variables, 1972 // Mark the heap roots including global variables, stack variables,
1973 // etc., and all objects reachable from them. 1973 // etc., and all objects reachable from them.
1974 heap()->IterateStrongRoots(visitor, VISIT_ONLY_STRONG); 1974 heap()->IterateStrongRoots(visitor, VISIT_ONLY_STRONG);
1975 1975
1976 // Handle the string table specially. 1976 // Handle the string table specially.
1977 MarkStringTable(visitor); 1977 MarkStringTable(visitor);
1978 1978
1979 // There may be overflowed objects in the heap. Visit them now. 1979 // There may be overflowed objects in the heap. Visit them now.
1980 while (marking_deque_.overflowed()) { 1980 while (marking_deque()->overflowed()) {
1981 RefillMarkingDeque(); 1981 RefillMarkingDeque();
1982 EmptyMarkingDeque(); 1982 EmptyMarkingDeque();
1983 } 1983 }
1984 } 1984 }
1985 1985
1986 1986
1987 void MarkCompactCollector::MarkImplicitRefGroups( 1987 void MarkCompactCollector::MarkImplicitRefGroups(
1988 MarkObjectFunction mark_object) { 1988 MarkObjectFunction mark_object) {
1989 List<ImplicitRefGroup*>* ref_groups = 1989 List<ImplicitRefGroup*>* ref_groups =
1990 isolate()->global_handles()->implicit_ref_groups(); 1990 isolate()->global_handles()->implicit_ref_groups();
(...skipping 22 matching lines...) Expand all
2013 } 2013 }
2014 ref_groups->Rewind(last); 2014 ref_groups->Rewind(last);
2015 } 2015 }
2016 2016
2017 2017
2018 // Mark all objects reachable from the objects on the marking stack. 2018 // Mark all objects reachable from the objects on the marking stack.
2019 // Before: the marking stack contains zero or more heap object pointers. 2019 // Before: the marking stack contains zero or more heap object pointers.
2020 // After: the marking stack is empty, and all objects reachable from the 2020 // After: the marking stack is empty, and all objects reachable from the
2021 // marking stack have been marked, or are overflowed in the heap. 2021 // marking stack have been marked, or are overflowed in the heap.
2022 void MarkCompactCollector::EmptyMarkingDeque() { 2022 void MarkCompactCollector::EmptyMarkingDeque() {
2023 while (!marking_deque_.IsEmpty()) { 2023 while (!marking_deque()->IsEmpty()) {
2024 HeapObject* object = marking_deque_.Pop(); 2024 HeapObject* object = marking_deque()->Pop();
2025 2025
2026 DCHECK(!object->IsFiller()); 2026 DCHECK(!object->IsFiller());
2027 DCHECK(object->IsHeapObject()); 2027 DCHECK(object->IsHeapObject());
2028 DCHECK(heap()->Contains(object)); 2028 DCHECK(heap()->Contains(object));
2029 DCHECK(!Marking::IsWhite(ObjectMarking::MarkBitFrom(object))); 2029 DCHECK(!Marking::IsWhite(ObjectMarking::MarkBitFrom(object)));
2030 2030
2031 Map* map = object->map(); 2031 Map* map = object->map();
2032 MarkBit map_mark = ObjectMarking::MarkBitFrom(map); 2032 MarkBit map_mark = ObjectMarking::MarkBitFrom(map);
2033 MarkObject(map, map_mark); 2033 MarkObject(map, map_mark);
2034 2034
2035 MarkCompactMarkingVisitor::IterateBody(map, object); 2035 MarkCompactMarkingVisitor::IterateBody(map, object);
2036 } 2036 }
2037 } 2037 }
2038 2038
2039 2039
2040 // Sweep the heap for overflowed objects, clear their overflow bits, and 2040 // Sweep the heap for overflowed objects, clear their overflow bits, and
2041 // push them on the marking stack. Stop early if the marking stack fills 2041 // push them on the marking stack. Stop early if the marking stack fills
2042 // before sweeping completes. If sweeping completes, there are no remaining 2042 // before sweeping completes. If sweeping completes, there are no remaining
2043 // overflowed objects in the heap so the overflow flag on the markings stack 2043 // overflowed objects in the heap so the overflow flag on the markings stack
2044 // is cleared. 2044 // is cleared.
2045 void MarkCompactCollector::RefillMarkingDeque() { 2045 void MarkCompactCollector::RefillMarkingDeque() {
2046 isolate()->CountUsage(v8::Isolate::UseCounterFeature::kMarkDequeOverflow); 2046 isolate()->CountUsage(v8::Isolate::UseCounterFeature::kMarkDequeOverflow);
2047 DCHECK(marking_deque_.overflowed()); 2047 DCHECK(marking_deque()->overflowed());
2048 2048
2049 DiscoverGreyObjectsInNewSpace(); 2049 DiscoverGreyObjectsInNewSpace();
2050 if (marking_deque_.IsFull()) return; 2050 if (marking_deque()->IsFull()) return;
2051 2051
2052 DiscoverGreyObjectsInSpace(heap()->old_space()); 2052 DiscoverGreyObjectsInSpace(heap()->old_space());
2053 if (marking_deque_.IsFull()) return; 2053 if (marking_deque()->IsFull()) return;
2054 2054
2055 DiscoverGreyObjectsInSpace(heap()->code_space()); 2055 DiscoverGreyObjectsInSpace(heap()->code_space());
2056 if (marking_deque_.IsFull()) return; 2056 if (marking_deque()->IsFull()) return;
2057 2057
2058 DiscoverGreyObjectsInSpace(heap()->map_space()); 2058 DiscoverGreyObjectsInSpace(heap()->map_space());
2059 if (marking_deque_.IsFull()) return; 2059 if (marking_deque()->IsFull()) return;
2060 2060
2061 LargeObjectIterator lo_it(heap()->lo_space()); 2061 LargeObjectIterator lo_it(heap()->lo_space());
2062 DiscoverGreyObjectsWithIterator(&lo_it); 2062 DiscoverGreyObjectsWithIterator(&lo_it);
2063 if (marking_deque_.IsFull()) return; 2063 if (marking_deque()->IsFull()) return;
2064 2064
2065 marking_deque_.ClearOverflowed(); 2065 marking_deque()->ClearOverflowed();
2066 } 2066 }
2067 2067
2068 2068
2069 // Mark all objects reachable (transitively) from objects on the marking 2069 // Mark all objects reachable (transitively) from objects on the marking
2070 // stack. Before: the marking stack contains zero or more heap object 2070 // stack. Before: the marking stack contains zero or more heap object
2071 // pointers. After: the marking stack is empty and there are no overflowed 2071 // pointers. After: the marking stack is empty and there are no overflowed
2072 // objects in the heap. 2072 // objects in the heap.
2073 void MarkCompactCollector::ProcessMarkingDeque() { 2073 void MarkCompactCollector::ProcessMarkingDeque() {
2074 EmptyMarkingDeque(); 2074 EmptyMarkingDeque();
2075 while (marking_deque_.overflowed()) { 2075 while (marking_deque()->overflowed()) {
2076 RefillMarkingDeque(); 2076 RefillMarkingDeque();
2077 EmptyMarkingDeque(); 2077 EmptyMarkingDeque();
2078 } 2078 }
2079 } 2079 }
2080 2080
2081 // Mark all objects reachable (transitively) from objects on the marking 2081 // Mark all objects reachable (transitively) from objects on the marking
2082 // stack including references only considered in the atomic marking pause. 2082 // stack including references only considered in the atomic marking pause.
2083 void MarkCompactCollector::ProcessEphemeralMarking( 2083 void MarkCompactCollector::ProcessEphemeralMarking(
2084 ObjectVisitor* visitor, bool only_process_harmony_weak_collections) { 2084 ObjectVisitor* visitor, bool only_process_harmony_weak_collections) {
2085 DCHECK(marking_deque_.IsEmpty() && !marking_deque_.overflowed()); 2085 DCHECK(marking_deque()->IsEmpty() && !marking_deque()->overflowed());
2086 bool work_to_do = true; 2086 bool work_to_do = true;
2087 while (work_to_do) { 2087 while (work_to_do) {
2088 if (heap_->UsingEmbedderHeapTracer()) { 2088 if (heap_->UsingEmbedderHeapTracer()) {
2089 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_WRAPPER_TRACING); 2089 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_WRAPPER_TRACING);
2090 heap_->RegisterWrappersWithEmbedderHeapTracer(); 2090 heap_->RegisterWrappersWithEmbedderHeapTracer();
2091 heap_->embedder_heap_tracer()->AdvanceTracing( 2091 heap_->embedder_heap_tracer()->AdvanceTracing(
2092 0, EmbedderHeapTracer::AdvanceTracingActions( 2092 0, EmbedderHeapTracer::AdvanceTracingActions(
2093 EmbedderHeapTracer::ForceCompletionAction::FORCE_COMPLETION)); 2093 EmbedderHeapTracer::ForceCompletionAction::FORCE_COMPLETION));
2094 } 2094 }
2095 if (!only_process_harmony_weak_collections) { 2095 if (!only_process_harmony_weak_collections) {
2096 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_OBJECT_GROUPING); 2096 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_OBJECT_GROUPING);
2097 isolate()->global_handles()->IterateObjectGroups( 2097 isolate()->global_handles()->IterateObjectGroups(
2098 visitor, &IsUnmarkedHeapObjectWithHeap); 2098 visitor, &IsUnmarkedHeapObjectWithHeap);
2099 MarkImplicitRefGroups(&MarkCompactMarkingVisitor::MarkObject); 2099 MarkImplicitRefGroups(&MarkCompactMarkingVisitor::MarkObject);
2100 } 2100 }
2101 ProcessWeakCollections(); 2101 ProcessWeakCollections();
2102 work_to_do = !marking_deque_.IsEmpty(); 2102 work_to_do = !marking_deque()->IsEmpty();
2103 ProcessMarkingDeque(); 2103 ProcessMarkingDeque();
2104 } 2104 }
2105 } 2105 }
2106 2106
2107 void MarkCompactCollector::ProcessTopOptimizedFrame(ObjectVisitor* visitor) { 2107 void MarkCompactCollector::ProcessTopOptimizedFrame(ObjectVisitor* visitor) {
2108 for (StackFrameIterator it(isolate(), isolate()->thread_local_top()); 2108 for (StackFrameIterator it(isolate(), isolate()->thread_local_top());
2109 !it.done(); it.Advance()) { 2109 !it.done(); it.Advance()) {
2110 if (it.frame()->type() == StackFrame::JAVA_SCRIPT) { 2110 if (it.frame()->type() == StackFrame::JAVA_SCRIPT) {
2111 return; 2111 return;
2112 } 2112 }
2113 if (it.frame()->type() == StackFrame::OPTIMIZED) { 2113 if (it.frame()->type() == StackFrame::OPTIMIZED) {
2114 Code* code = it.frame()->LookupCode(); 2114 Code* code = it.frame()->LookupCode();
2115 if (!code->CanDeoptAt(it.frame()->pc())) { 2115 if (!code->CanDeoptAt(it.frame()->pc())) {
2116 Code::BodyDescriptor::IterateBody(code, visitor); 2116 Code::BodyDescriptor::IterateBody(code, visitor);
2117 } 2117 }
2118 ProcessMarkingDeque(); 2118 ProcessMarkingDeque();
2119 return; 2119 return;
2120 } 2120 }
2121 } 2121 }
2122 } 2122 }
2123 2123
2124 2124
2125 void MarkCompactCollector::EnsureMarkingDequeIsReserved() { 2125 void MarkCompactCollector::EnsureMarkingDequeIsReserved() {
2126 DCHECK(!marking_deque_.in_use()); 2126 DCHECK(!marking_deque()->in_use());
2127 if (marking_deque_memory_ == NULL) { 2127 if (marking_deque_memory_ == NULL) {
2128 marking_deque_memory_ = new base::VirtualMemory(kMaxMarkingDequeSize); 2128 marking_deque_memory_ = new base::VirtualMemory(kMaxMarkingDequeSize);
2129 marking_deque_memory_committed_ = 0; 2129 marking_deque_memory_committed_ = 0;
2130 } 2130 }
2131 if (marking_deque_memory_ == NULL) { 2131 if (marking_deque_memory_ == NULL) {
2132 V8::FatalProcessOutOfMemory("EnsureMarkingDequeIsReserved"); 2132 V8::FatalProcessOutOfMemory("EnsureMarkingDequeIsReserved");
2133 } 2133 }
2134 } 2134 }
2135 2135
2136 2136
2137 void MarkCompactCollector::EnsureMarkingDequeIsCommitted(size_t max_size) { 2137 void MarkCompactCollector::EnsureMarkingDequeIsCommitted(size_t max_size) {
2138 // If the marking deque is too small, we try to allocate a bigger one. 2138 // If the marking deque is too small, we try to allocate a bigger one.
2139 // If that fails, make do with a smaller one. 2139 // If that fails, make do with a smaller one.
2140 CHECK(!marking_deque_.in_use()); 2140 CHECK(!marking_deque()->in_use());
2141 for (size_t size = max_size; size >= kMinMarkingDequeSize; size >>= 1) { 2141 for (size_t size = max_size; size >= kMinMarkingDequeSize; size >>= 1) {
2142 base::VirtualMemory* memory = marking_deque_memory_; 2142 base::VirtualMemory* memory = marking_deque_memory_;
2143 size_t currently_committed = marking_deque_memory_committed_; 2143 size_t currently_committed = marking_deque_memory_committed_;
2144 2144
2145 if (currently_committed == size) return; 2145 if (currently_committed == size) return;
2146 2146
2147 if (currently_committed > size) { 2147 if (currently_committed > size) {
2148 bool success = marking_deque_memory_->Uncommit( 2148 bool success = marking_deque_memory_->Uncommit(
2149 reinterpret_cast<Address>(marking_deque_memory_->address()) + size, 2149 reinterpret_cast<Address>(marking_deque_memory_->address()) + size,
2150 currently_committed - size); 2150 currently_committed - size);
(...skipping 11 matching lines...) Expand all
2162 if (success) { 2162 if (success) {
2163 marking_deque_memory_committed_ = size; 2163 marking_deque_memory_committed_ = size;
2164 return; 2164 return;
2165 } 2165 }
2166 } 2166 }
2167 V8::FatalProcessOutOfMemory("EnsureMarkingDequeIsCommitted"); 2167 V8::FatalProcessOutOfMemory("EnsureMarkingDequeIsCommitted");
2168 } 2168 }
2169 2169
2170 2170
2171 void MarkCompactCollector::InitializeMarkingDeque() { 2171 void MarkCompactCollector::InitializeMarkingDeque() {
2172 DCHECK(!marking_deque_.in_use()); 2172 DCHECK(!marking_deque()->in_use());
2173 DCHECK(marking_deque_memory_committed_ > 0); 2173 DCHECK(marking_deque_memory_committed_ > 0);
2174 Address addr = static_cast<Address>(marking_deque_memory_->address()); 2174 Address addr = static_cast<Address>(marking_deque_memory_->address());
2175 size_t size = marking_deque_memory_committed_; 2175 size_t size = marking_deque_memory_committed_;
2176 if (FLAG_force_marking_deque_overflows) size = 64 * kPointerSize; 2176 if (FLAG_force_marking_deque_overflows) size = 64 * kPointerSize;
2177 marking_deque_.Initialize(addr, addr + size); 2177 marking_deque()->Initialize(addr, addr + size);
2178 } 2178 }
2179 2179
2180 2180
2181 void MarkingDeque::Initialize(Address low, Address high) { 2181 void MarkingDeque::Initialize(Address low, Address high) {
2182 DCHECK(!in_use_); 2182 DCHECK(!in_use_);
2183 HeapObject** obj_low = reinterpret_cast<HeapObject**>(low); 2183 HeapObject** obj_low = reinterpret_cast<HeapObject**>(low);
2184 HeapObject** obj_high = reinterpret_cast<HeapObject**>(high); 2184 HeapObject** obj_high = reinterpret_cast<HeapObject**>(high);
2185 array_ = obj_low; 2185 array_ = obj_low;
2186 mask_ = base::bits::RoundDownToPowerOfTwo32( 2186 mask_ = base::bits::RoundDownToPowerOfTwo32(
2187 static_cast<uint32_t>(obj_high - obj_low)) - 2187 static_cast<uint32_t>(obj_high - obj_low)) -
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
2263 PostponeInterruptsScope postpone(isolate()); 2263 PostponeInterruptsScope postpone(isolate());
2264 2264
2265 { 2265 {
2266 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_FINISH_INCREMENTAL); 2266 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_FINISH_INCREMENTAL);
2267 IncrementalMarking* incremental_marking = heap_->incremental_marking(); 2267 IncrementalMarking* incremental_marking = heap_->incremental_marking();
2268 if (was_marked_incrementally_) { 2268 if (was_marked_incrementally_) {
2269 incremental_marking->Finalize(); 2269 incremental_marking->Finalize();
2270 } else { 2270 } else {
2271 // Abort any pending incremental activities e.g. incremental sweeping. 2271 // Abort any pending incremental activities e.g. incremental sweeping.
2272 incremental_marking->Stop(); 2272 incremental_marking->Stop();
2273 if (marking_deque_.in_use()) { 2273 if (marking_deque()->in_use()) {
2274 marking_deque_.Uninitialize(true); 2274 marking_deque()->Uninitialize(true);
2275 } 2275 }
2276 } 2276 }
2277 } 2277 }
2278 2278
2279 #ifdef DEBUG 2279 #ifdef DEBUG
2280 DCHECK(state_ == PREPARE_GC); 2280 DCHECK(state_ == PREPARE_GC);
2281 state_ = MARK_LIVE_OBJECTS; 2281 state_ = MARK_LIVE_OBJECTS;
2282 #endif 2282 #endif
2283 2283
2284 EnsureMarkingDequeIsCommittedAndInitialize( 2284 EnsureMarkingDequeIsCommittedAndInitialize(
(...skipping 1709 matching lines...) Expand 10 before | Expand all | Expand 10 after
3994 // The target is always in old space, we don't have to record the slot in 3994 // The target is always in old space, we don't have to record the slot in
3995 // the old-to-new remembered set. 3995 // the old-to-new remembered set.
3996 DCHECK(!heap()->InNewSpace(target)); 3996 DCHECK(!heap()->InNewSpace(target));
3997 RecordRelocSlot(host, &rinfo, target); 3997 RecordRelocSlot(host, &rinfo, target);
3998 } 3998 }
3999 } 3999 }
4000 } 4000 }
4001 4001
4002 } // namespace internal 4002 } // namespace internal
4003 } // namespace v8 4003 } // namespace v8
OLDNEW
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/heap/mark-compact-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698