OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 11 matching lines...) Expand all Loading... |
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #include "v8.h" | 28 #include "v8.h" |
29 | 29 |
30 #include "code-stubs.h" | 30 #include "code-stubs.h" |
31 #include "compilation-cache.h" | 31 #include "compilation-cache.h" |
| 32 #include "cpu-profiler.h" |
32 #include "deoptimizer.h" | 33 #include "deoptimizer.h" |
33 #include "execution.h" | 34 #include "execution.h" |
34 #include "gdb-jit.h" | 35 #include "gdb-jit.h" |
35 #include "global-handles.h" | 36 #include "global-handles.h" |
36 #include "heap-profiler.h" | 37 #include "heap-profiler.h" |
37 #include "ic-inl.h" | 38 #include "ic-inl.h" |
38 #include "incremental-marking.h" | 39 #include "incremental-marking.h" |
39 #include "mark-compact.h" | 40 #include "mark-compact.h" |
40 #include "marking-thread.h" | 41 #include "marking-thread.h" |
41 #include "objects-visiting.h" | 42 #include "objects-visiting.h" |
(...skipping 2132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2174 isolate()->global_handles()->IterateObjectGroups( | 2175 isolate()->global_handles()->IterateObjectGroups( |
2175 visitor, &IsUnmarkedHeapObjectWithHeap); | 2176 visitor, &IsUnmarkedHeapObjectWithHeap); |
2176 MarkImplicitRefGroups(); | 2177 MarkImplicitRefGroups(); |
2177 ProcessWeakMaps(); | 2178 ProcessWeakMaps(); |
2178 work_to_do = !marking_deque_.IsEmpty(); | 2179 work_to_do = !marking_deque_.IsEmpty(); |
2179 ProcessMarkingDeque(); | 2180 ProcessMarkingDeque(); |
2180 } | 2181 } |
2181 } | 2182 } |
2182 | 2183 |
2183 | 2184 |
| 2185 void MarkCompactCollector::ProcessTopOptimizedFrame(ObjectVisitor* visitor) { |
| 2186 for (StackFrameIterator it(isolate(), isolate()->thread_local_top()); |
| 2187 !it.done(); it.Advance()) { |
| 2188 if (it.frame()->type() == StackFrame::JAVA_SCRIPT) { |
| 2189 return; |
| 2190 } |
| 2191 if (it.frame()->type() == StackFrame::OPTIMIZED) { |
| 2192 Code* code = it.frame()->LookupCode(); |
| 2193 if (!code->CanDeoptAt(it.frame()->pc())) { |
| 2194 code->CodeIterateBody(visitor); |
| 2195 } |
| 2196 ProcessMarkingDeque(); |
| 2197 return; |
| 2198 } |
| 2199 } |
| 2200 } |
| 2201 |
| 2202 |
2184 void MarkCompactCollector::MarkLiveObjects() { | 2203 void MarkCompactCollector::MarkLiveObjects() { |
2185 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_MARK); | 2204 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_MARK); |
2186 // The recursive GC marker detects when it is nearing stack overflow, | 2205 // The recursive GC marker detects when it is nearing stack overflow, |
2187 // and switches to a different marking system. JS interrupts interfere | 2206 // and switches to a different marking system. JS interrupts interfere |
2188 // with the C stack limit check. | 2207 // with the C stack limit check. |
2189 PostponeInterruptsScope postpone(isolate()); | 2208 PostponeInterruptsScope postpone(isolate()); |
2190 | 2209 |
2191 bool incremental_marking_overflowed = false; | 2210 bool incremental_marking_overflowed = false; |
2192 IncrementalMarking* incremental_marking = heap_->incremental_marking(); | 2211 IncrementalMarking* incremental_marking = heap_->incremental_marking(); |
2193 if (was_marked_incrementally_) { | 2212 if (was_marked_incrementally_) { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2253 if (IsMarked(cell)) { | 2272 if (IsMarked(cell)) { |
2254 MarkCompactMarkingVisitor::VisitPropertyCell(cell->map(), cell); | 2273 MarkCompactMarkingVisitor::VisitPropertyCell(cell->map(), cell); |
2255 } | 2274 } |
2256 } | 2275 } |
2257 } | 2276 } |
2258 } | 2277 } |
2259 | 2278 |
2260 RootMarkingVisitor root_visitor(heap()); | 2279 RootMarkingVisitor root_visitor(heap()); |
2261 MarkRoots(&root_visitor); | 2280 MarkRoots(&root_visitor); |
2262 | 2281 |
| 2282 ProcessTopOptimizedFrame(&root_visitor); |
| 2283 |
2263 // The objects reachable from the roots are marked, yet unreachable | 2284 // The objects reachable from the roots are marked, yet unreachable |
2264 // objects are unmarked. Mark objects reachable due to host | 2285 // objects are unmarked. Mark objects reachable due to host |
2265 // application specific logic or through Harmony weak maps. | 2286 // application specific logic or through Harmony weak maps. |
2266 ProcessEphemeralMarking(&root_visitor); | 2287 ProcessEphemeralMarking(&root_visitor); |
2267 | 2288 |
2268 // The objects reachable from the roots, weak maps or object groups | 2289 // The objects reachable from the roots, weak maps or object groups |
2269 // are marked, yet unreachable objects are unmarked. Mark objects | 2290 // are marked, yet unreachable objects are unmarked. Mark objects |
2270 // reachable only from weak global handles. | 2291 // reachable only from weak global handles. |
2271 // | 2292 // |
2272 // First we identify nonlive weak handles and mark them as pending | 2293 // First we identify nonlive weak handles and mark them as pending |
(...skipping 837 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3110 ASSERT(static_cast<unsigned>(cell_index) == | 3131 ASSERT(static_cast<unsigned>(cell_index) == |
3111 Bitmap::IndexToCell( | 3132 Bitmap::IndexToCell( |
3112 Bitmap::CellAlignIndex( | 3133 Bitmap::CellAlignIndex( |
3113 p->AddressToMarkbitIndex(object_address)))); | 3134 p->AddressToMarkbitIndex(object_address)))); |
3114 int live_objects = MarkWordToObjectStarts(cells[cell_index], offsets); | 3135 int live_objects = MarkWordToObjectStarts(cells[cell_index], offsets); |
3115 int live_index = 0; | 3136 int live_index = 0; |
3116 for ( ; live_objects != 0; live_objects--) { | 3137 for ( ; live_objects != 0; live_objects--) { |
3117 Address free_end = object_address + offsets[live_index++] * kPointerSize; | 3138 Address free_end = object_address + offsets[live_index++] * kPointerSize; |
3118 if (free_end != free_start) { | 3139 if (free_end != free_start) { |
3119 space->Free(free_start, static_cast<int>(free_end - free_start)); | 3140 space->Free(free_start, static_cast<int>(free_end - free_start)); |
| 3141 #ifdef ENABLE_GDB_JIT_INTERFACE |
| 3142 if (FLAG_gdbjit && space->identity() == CODE_SPACE) { |
| 3143 GDBJITInterface::RemoveCodeRange(free_start, free_end); |
| 3144 } |
| 3145 #endif |
3120 } | 3146 } |
3121 HeapObject* live_object = HeapObject::FromAddress(free_end); | 3147 HeapObject* live_object = HeapObject::FromAddress(free_end); |
3122 ASSERT(Marking::IsBlack(Marking::MarkBitFrom(live_object))); | 3148 ASSERT(Marking::IsBlack(Marking::MarkBitFrom(live_object))); |
3123 Map* map = live_object->map(); | 3149 Map* map = live_object->map(); |
3124 int size = live_object->SizeFromMap(map); | 3150 int size = live_object->SizeFromMap(map); |
3125 if (sweeping_mode == SWEEP_AND_VISIT_LIVE_OBJECTS) { | 3151 if (sweeping_mode == SWEEP_AND_VISIT_LIVE_OBJECTS) { |
3126 live_object->IterateBody(map->instance_type(), size, v); | 3152 live_object->IterateBody(map->instance_type(), size, v); |
3127 } | 3153 } |
3128 if ((skip_list_mode == REBUILD_SKIP_LIST) && skip_list != NULL) { | 3154 if ((skip_list_mode == REBUILD_SKIP_LIST) && skip_list != NULL) { |
3129 int new_region_start = | 3155 int new_region_start = |
3130 SkipList::RegionNumber(free_end); | 3156 SkipList::RegionNumber(free_end); |
3131 int new_region_end = | 3157 int new_region_end = |
3132 SkipList::RegionNumber(free_end + size - kPointerSize); | 3158 SkipList::RegionNumber(free_end + size - kPointerSize); |
3133 if (new_region_start != curr_region || | 3159 if (new_region_start != curr_region || |
3134 new_region_end != curr_region) { | 3160 new_region_end != curr_region) { |
3135 skip_list->AddObject(free_end, size); | 3161 skip_list->AddObject(free_end, size); |
3136 curr_region = new_region_end; | 3162 curr_region = new_region_end; |
3137 } | 3163 } |
3138 } | 3164 } |
3139 free_start = free_end + size; | 3165 free_start = free_end + size; |
3140 } | 3166 } |
3141 // Clear marking bits for current cell. | 3167 // Clear marking bits for current cell. |
3142 cells[cell_index] = 0; | 3168 cells[cell_index] = 0; |
3143 } | 3169 } |
3144 if (free_start != p->area_end()) { | 3170 if (free_start != p->area_end()) { |
3145 space->Free(free_start, static_cast<int>(p->area_end() - free_start)); | 3171 space->Free(free_start, static_cast<int>(p->area_end() - free_start)); |
| 3172 #ifdef ENABLE_GDB_JIT_INTERFACE |
| 3173 if (FLAG_gdbjit && space->identity() == CODE_SPACE) { |
| 3174 GDBJITInterface::RemoveCodeRange(free_start, p->area_end()); |
| 3175 } |
| 3176 #endif |
3146 } | 3177 } |
3147 p->ResetLiveBytes(); | 3178 p->ResetLiveBytes(); |
3148 if (FLAG_print_cumulative_gc_stat) { | 3179 if (FLAG_print_cumulative_gc_stat) { |
3149 space->heap()->AddSweepingTime(OS::TimeCurrentMillis() - start_time); | 3180 space->heap()->AddSweepingTime(OS::TimeCurrentMillis() - start_time); |
3150 } | 3181 } |
3151 } | 3182 } |
3152 | 3183 |
3153 | 3184 |
3154 static bool SetMarkBitsUnderInvalidatedCode(Code* code, bool value) { | 3185 static bool SetMarkBitsUnderInvalidatedCode(Code* code, bool value) { |
3155 Page* p = Page::FromAddress(code->address()); | 3186 Page* p = Page::FromAddress(code->address()); |
(...skipping 1130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4286 while (buffer != NULL) { | 4317 while (buffer != NULL) { |
4287 SlotsBuffer* next_buffer = buffer->next(); | 4318 SlotsBuffer* next_buffer = buffer->next(); |
4288 DeallocateBuffer(buffer); | 4319 DeallocateBuffer(buffer); |
4289 buffer = next_buffer; | 4320 buffer = next_buffer; |
4290 } | 4321 } |
4291 *buffer_address = NULL; | 4322 *buffer_address = NULL; |
4292 } | 4323 } |
4293 | 4324 |
4294 | 4325 |
4295 } } // namespace v8::internal | 4326 } } // namespace v8::internal |
OLD | NEW |