OLD | NEW |
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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 #ifdef DEBUG | 52 #ifdef DEBUG |
53 state_(IDLE), | 53 state_(IDLE), |
54 #endif | 54 #endif |
55 marking_parity_(ODD_MARKING_PARITY), | 55 marking_parity_(ODD_MARKING_PARITY), |
56 was_marked_incrementally_(false), | 56 was_marked_incrementally_(false), |
57 evacuation_(false), | 57 evacuation_(false), |
58 heap_(heap), | 58 heap_(heap), |
59 marking_deque_memory_(NULL), | 59 marking_deque_memory_(NULL), |
60 marking_deque_memory_committed_(0), | 60 marking_deque_memory_committed_(0), |
61 code_flusher_(nullptr), | 61 code_flusher_(nullptr), |
| 62 embedder_heap_tracer_(nullptr), |
62 have_code_to_deoptimize_(false), | 63 have_code_to_deoptimize_(false), |
63 compacting_(false), | 64 compacting_(false), |
64 sweeping_in_progress_(false), | 65 sweeping_in_progress_(false), |
65 pending_sweeper_tasks_semaphore_(0), | 66 pending_sweeper_tasks_semaphore_(0), |
66 pending_compaction_tasks_semaphore_(0) { | 67 pending_compaction_tasks_semaphore_(0) { |
67 } | 68 } |
68 | 69 |
69 #ifdef VERIFY_HEAP | 70 #ifdef VERIFY_HEAP |
70 class VerifyMarkingVisitor : public ObjectVisitor { | 71 class VerifyMarkingVisitor : public ObjectVisitor { |
71 public: | 72 public: |
(...skipping 1882 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1954 // pointers. After: the marking stack is empty and there are no overflowed | 1955 // pointers. After: the marking stack is empty and there are no overflowed |
1955 // objects in the heap. | 1956 // objects in the heap. |
1956 void MarkCompactCollector::ProcessMarkingDeque() { | 1957 void MarkCompactCollector::ProcessMarkingDeque() { |
1957 EmptyMarkingDeque(); | 1958 EmptyMarkingDeque(); |
1958 while (marking_deque_.overflowed()) { | 1959 while (marking_deque_.overflowed()) { |
1959 RefillMarkingDeque(); | 1960 RefillMarkingDeque(); |
1960 EmptyMarkingDeque(); | 1961 EmptyMarkingDeque(); |
1961 } | 1962 } |
1962 } | 1963 } |
1963 | 1964 |
1964 | |
1965 // Mark all objects reachable (transitively) from objects on the marking | 1965 // Mark all objects reachable (transitively) from objects on the marking |
1966 // stack including references only considered in the atomic marking pause. | 1966 // stack including references only considered in the atomic marking pause. |
1967 void MarkCompactCollector::ProcessEphemeralMarking( | 1967 void MarkCompactCollector::ProcessEphemeralMarking( |
1968 ObjectVisitor* visitor, bool only_process_harmony_weak_collections) { | 1968 ObjectVisitor* visitor, bool only_process_harmony_weak_collections) { |
1969 bool work_to_do = true; | 1969 bool work_to_do = true; |
1970 DCHECK(marking_deque_.IsEmpty() && !marking_deque_.overflowed()); | 1970 DCHECK(marking_deque_.IsEmpty() && !marking_deque_.overflowed()); |
1971 while (work_to_do) { | 1971 while (work_to_do) { |
1972 if (!only_process_harmony_weak_collections) { | 1972 if (UsingEmbedderHeapTracer()) { |
| 1973 embedder_heap_tracer()->TraceWrappableFrom( |
| 1974 reinterpret_cast<v8::Isolate*>(isolate()), wrappers_to_trace_); |
| 1975 wrappers_to_trace_.clear(); |
| 1976 } else if (!only_process_harmony_weak_collections) { |
1973 isolate()->global_handles()->IterateObjectGroups( | 1977 isolate()->global_handles()->IterateObjectGroups( |
1974 visitor, &IsUnmarkedHeapObjectWithHeap); | 1978 visitor, &IsUnmarkedHeapObjectWithHeap); |
1975 MarkImplicitRefGroups(&MarkCompactMarkingVisitor::MarkObject); | 1979 MarkImplicitRefGroups(&MarkCompactMarkingVisitor::MarkObject); |
1976 } | 1980 } |
1977 ProcessWeakCollections(); | 1981 ProcessWeakCollections(); |
1978 work_to_do = !marking_deque_.IsEmpty(); | 1982 work_to_do = !marking_deque_.IsEmpty(); |
1979 ProcessMarkingDeque(); | 1983 ProcessMarkingDeque(); |
1980 } | 1984 } |
1981 } | 1985 } |
1982 | 1986 |
1983 | |
1984 void MarkCompactCollector::ProcessTopOptimizedFrame(ObjectVisitor* visitor) { | 1987 void MarkCompactCollector::ProcessTopOptimizedFrame(ObjectVisitor* visitor) { |
1985 for (StackFrameIterator it(isolate(), isolate()->thread_local_top()); | 1988 for (StackFrameIterator it(isolate(), isolate()->thread_local_top()); |
1986 !it.done(); it.Advance()) { | 1989 !it.done(); it.Advance()) { |
1987 if (it.frame()->type() == StackFrame::JAVA_SCRIPT) { | 1990 if (it.frame()->type() == StackFrame::JAVA_SCRIPT) { |
1988 return; | 1991 return; |
1989 } | 1992 } |
1990 if (it.frame()->type() == StackFrame::OPTIMIZED) { | 1993 if (it.frame()->type() == StackFrame::OPTIMIZED) { |
1991 Code* code = it.frame()->LookupCode(); | 1994 Code* code = it.frame()->LookupCode(); |
1992 if (!code->CanDeoptAt(it.frame()->pc())) { | 1995 if (!code->CanDeoptAt(it.frame()->pc())) { |
1993 Code::BodyDescriptor::IterateBody(code, visitor); | 1996 Code::BodyDescriptor::IterateBody(code, visitor); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2072 void MarkingDeque::Uninitialize(bool aborting) { | 2075 void MarkingDeque::Uninitialize(bool aborting) { |
2073 if (!aborting) { | 2076 if (!aborting) { |
2074 DCHECK(IsEmpty()); | 2077 DCHECK(IsEmpty()); |
2075 DCHECK(!overflowed_); | 2078 DCHECK(!overflowed_); |
2076 } | 2079 } |
2077 DCHECK(in_use_); | 2080 DCHECK(in_use_); |
2078 top_ = bottom_ = 0xdecbad; | 2081 top_ = bottom_ = 0xdecbad; |
2079 in_use_ = false; | 2082 in_use_ = false; |
2080 } | 2083 } |
2081 | 2084 |
| 2085 void MarkCompactCollector::SetEmbedderHeapTracer(EmbedderHeapTracer* tracer) { |
| 2086 DCHECK_NOT_NULL(tracer); |
| 2087 CHECK_NULL(embedder_heap_tracer_); |
| 2088 embedder_heap_tracer_ = tracer; |
| 2089 } |
| 2090 |
| 2091 void MarkCompactCollector::TracePossibleWrapper(JSObject* js_object) { |
| 2092 DCHECK(js_object->WasConstructedFromApiFunction()); |
| 2093 if (js_object->GetInternalFieldCount() >= 2 && |
| 2094 js_object->GetInternalField(0) != heap_->undefined_value() && |
| 2095 js_object->GetInternalField(1) != heap_->undefined_value()) { |
| 2096 wrappers_to_trace().push_back(std::pair<void*, void*>( |
| 2097 reinterpret_cast<void*>(js_object->GetInternalField(0)), |
| 2098 reinterpret_cast<void*>(js_object->GetInternalField(1)))); |
| 2099 } |
| 2100 } |
| 2101 |
| 2102 void MarkCompactCollector::RegisterExternallyReferencedObject(Object** object) { |
| 2103 DCHECK(in_use()); |
| 2104 HeapObject* heap_object = HeapObject::cast(*object); |
| 2105 DCHECK(heap_->Contains(heap_object)); |
| 2106 MarkBit mark_bit = Marking::MarkBitFrom(heap_object); |
| 2107 MarkObject(heap_object, mark_bit); |
| 2108 } |
2082 | 2109 |
2083 void MarkCompactCollector::MarkLiveObjects() { | 2110 void MarkCompactCollector::MarkLiveObjects() { |
2084 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK); | 2111 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK); |
2085 double start_time = 0.0; | 2112 double start_time = 0.0; |
2086 if (FLAG_print_cumulative_gc_stat) { | 2113 if (FLAG_print_cumulative_gc_stat) { |
2087 start_time = heap_->MonotonicallyIncreasingTimeInMs(); | 2114 start_time = heap_->MonotonicallyIncreasingTimeInMs(); |
2088 } | 2115 } |
2089 // The recursive GC marker detects when it is nearing stack overflow, | 2116 // The recursive GC marker detects when it is nearing stack overflow, |
2090 // and switches to a different marking system. JS interrupts interfere | 2117 // and switches to a different marking system. JS interrupts interfere |
2091 // with the C stack limit check. | 2118 // with the C stack limit check. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2128 | 2155 |
2129 { | 2156 { |
2130 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_WEAK_CLOSURE); | 2157 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_WEAK_CLOSURE); |
2131 | 2158 |
2132 // The objects reachable from the roots are marked, yet unreachable | 2159 // The objects reachable from the roots are marked, yet unreachable |
2133 // objects are unmarked. Mark objects reachable due to host | 2160 // objects are unmarked. Mark objects reachable due to host |
2134 // application specific logic or through Harmony weak maps. | 2161 // application specific logic or through Harmony weak maps. |
2135 { | 2162 { |
2136 TRACE_GC(heap()->tracer(), | 2163 TRACE_GC(heap()->tracer(), |
2137 GCTracer::Scope::MC_MARK_WEAK_CLOSURE_EPHEMERAL); | 2164 GCTracer::Scope::MC_MARK_WEAK_CLOSURE_EPHEMERAL); |
| 2165 if (UsingEmbedderHeapTracer()) { |
| 2166 embedder_heap_tracer()->TraceRoots( |
| 2167 reinterpret_cast<v8::Isolate*>(isolate())); |
| 2168 } |
2138 ProcessEphemeralMarking(&root_visitor, false); | 2169 ProcessEphemeralMarking(&root_visitor, false); |
2139 ProcessMarkingDeque(); | 2170 ProcessMarkingDeque(); |
2140 } | 2171 } |
2141 | 2172 |
2142 // The objects reachable from the roots, weak maps or object groups | 2173 // The objects reachable from the roots, weak maps or object groups |
2143 // are marked. Objects pointed to only by weak global handles cannot be | 2174 // are marked. Objects pointed to only by weak global handles cannot be |
2144 // immediately reclaimed. Instead, we have to mark them as pending and mark | 2175 // immediately reclaimed. Instead, we have to mark them as pending and mark |
2145 // objects reachable from them. | 2176 // objects reachable from them. |
2146 // | 2177 // |
2147 // First we identify nonlive weak handles and mark them as pending | 2178 // First we identify nonlive weak handles and mark them as pending |
(...skipping 16 matching lines...) Expand all Loading... |
2164 | 2195 |
2165 // Repeat Harmony weak maps marking to mark unmarked objects reachable from | 2196 // Repeat Harmony weak maps marking to mark unmarked objects reachable from |
2166 // the weak roots we just marked as pending destruction. | 2197 // the weak roots we just marked as pending destruction. |
2167 // | 2198 // |
2168 // We only process harmony collections, as all object groups have been fully | 2199 // We only process harmony collections, as all object groups have been fully |
2169 // processed and no weakly reachable node can discover new objects groups. | 2200 // processed and no weakly reachable node can discover new objects groups. |
2170 { | 2201 { |
2171 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_WEAK_CLOSURE_HARMONY); | 2202 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_WEAK_CLOSURE_HARMONY); |
2172 ProcessEphemeralMarking(&root_visitor, true); | 2203 ProcessEphemeralMarking(&root_visitor, true); |
2173 ProcessMarkingDeque(); | 2204 ProcessMarkingDeque(); |
| 2205 if (UsingEmbedderHeapTracer()) { |
| 2206 embedder_heap_tracer()->ClearTracingMarks( |
| 2207 reinterpret_cast<v8::Isolate*>(isolate())); |
| 2208 } |
2174 } | 2209 } |
2175 } | 2210 } |
2176 | 2211 |
2177 if (FLAG_print_cumulative_gc_stat) { | 2212 if (FLAG_print_cumulative_gc_stat) { |
2178 heap_->tracer()->AddMarkingTime(heap_->MonotonicallyIncreasingTimeInMs() - | 2213 heap_->tracer()->AddMarkingTime(heap_->MonotonicallyIncreasingTimeInMs() - |
2179 start_time); | 2214 start_time); |
2180 } | 2215 } |
2181 if (FLAG_track_gc_object_stats) { | 2216 if (FLAG_track_gc_object_stats) { |
2182 if (FLAG_trace_gc_object_stats) { | 2217 if (FLAG_trace_gc_object_stats) { |
2183 heap()->object_stats_->TraceObjectStats(); | 2218 heap()->object_stats_->TraceObjectStats(); |
(...skipping 1622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3806 MarkBit mark_bit = Marking::MarkBitFrom(host); | 3841 MarkBit mark_bit = Marking::MarkBitFrom(host); |
3807 if (Marking::IsBlack(mark_bit)) { | 3842 if (Marking::IsBlack(mark_bit)) { |
3808 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); | 3843 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); |
3809 RecordRelocSlot(host, &rinfo, target); | 3844 RecordRelocSlot(host, &rinfo, target); |
3810 } | 3845 } |
3811 } | 3846 } |
3812 } | 3847 } |
3813 | 3848 |
3814 } // namespace internal | 3849 } // namespace internal |
3815 } // namespace v8 | 3850 } // namespace v8 |
OLD | NEW |