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/v8.h" | 5 #include "src/v8.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/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/compilation-cache.h" | 10 #include "src/compilation-cache.h" |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 VerifyMarking(space->heap(), p->area_start(), p->area_end()); | 132 VerifyMarking(space->heap(), p->area_start(), p->area_end()); |
133 } | 133 } |
134 } | 134 } |
135 | 135 |
136 | 136 |
137 static void VerifyMarking(Heap* heap) { | 137 static void VerifyMarking(Heap* heap) { |
138 VerifyMarking(heap->old_pointer_space()); | 138 VerifyMarking(heap->old_pointer_space()); |
139 VerifyMarking(heap->old_data_space()); | 139 VerifyMarking(heap->old_data_space()); |
140 VerifyMarking(heap->code_space()); | 140 VerifyMarking(heap->code_space()); |
141 VerifyMarking(heap->cell_space()); | 141 VerifyMarking(heap->cell_space()); |
142 VerifyMarking(heap->property_cell_space()); | |
143 VerifyMarking(heap->map_space()); | 142 VerifyMarking(heap->map_space()); |
144 VerifyMarking(heap->new_space()); | 143 VerifyMarking(heap->new_space()); |
145 | 144 |
146 VerifyMarkingVisitor visitor(heap); | 145 VerifyMarkingVisitor visitor(heap); |
147 | 146 |
148 LargeObjectIterator it(heap->lo_space()); | 147 LargeObjectIterator it(heap->lo_space()); |
149 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { | 148 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { |
150 if (MarkCompactCollector::IsMarked(obj)) { | 149 if (MarkCompactCollector::IsMarked(obj)) { |
151 obj->Iterate(&visitor); | 150 obj->Iterate(&visitor); |
152 } | 151 } |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 VerifyEvacuation(p); | 212 VerifyEvacuation(p); |
214 } | 213 } |
215 } | 214 } |
216 | 215 |
217 | 216 |
218 static void VerifyEvacuation(Heap* heap) { | 217 static void VerifyEvacuation(Heap* heap) { |
219 VerifyEvacuation(heap, heap->old_pointer_space()); | 218 VerifyEvacuation(heap, heap->old_pointer_space()); |
220 VerifyEvacuation(heap, heap->old_data_space()); | 219 VerifyEvacuation(heap, heap->old_data_space()); |
221 VerifyEvacuation(heap, heap->code_space()); | 220 VerifyEvacuation(heap, heap->code_space()); |
222 VerifyEvacuation(heap, heap->cell_space()); | 221 VerifyEvacuation(heap, heap->cell_space()); |
223 VerifyEvacuation(heap, heap->property_cell_space()); | |
224 VerifyEvacuation(heap, heap->map_space()); | 222 VerifyEvacuation(heap, heap->map_space()); |
225 VerifyEvacuation(heap->new_space()); | 223 VerifyEvacuation(heap->new_space()); |
226 | 224 |
227 VerifyEvacuationVisitor visitor; | 225 VerifyEvacuationVisitor visitor; |
228 heap->IterateStrongRoots(&visitor, VISIT_ALL); | 226 heap->IterateStrongRoots(&visitor, VISIT_ALL); |
229 } | 227 } |
230 #endif // VERIFY_HEAP | 228 #endif // VERIFY_HEAP |
231 | 229 |
232 | 230 |
233 void MarkCompactCollector::SetUp() { | 231 void MarkCompactCollector::SetUp() { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 if (FLAG_compact_code_space && (mode == NON_INCREMENTAL_COMPACTION || | 267 if (FLAG_compact_code_space && (mode == NON_INCREMENTAL_COMPACTION || |
270 FLAG_incremental_code_compaction)) { | 268 FLAG_incremental_code_compaction)) { |
271 CollectEvacuationCandidates(heap()->code_space()); | 269 CollectEvacuationCandidates(heap()->code_space()); |
272 } else if (FLAG_trace_fragmentation) { | 270 } else if (FLAG_trace_fragmentation) { |
273 TraceFragmentation(heap()->code_space()); | 271 TraceFragmentation(heap()->code_space()); |
274 } | 272 } |
275 | 273 |
276 if (FLAG_trace_fragmentation) { | 274 if (FLAG_trace_fragmentation) { |
277 TraceFragmentation(heap()->map_space()); | 275 TraceFragmentation(heap()->map_space()); |
278 TraceFragmentation(heap()->cell_space()); | 276 TraceFragmentation(heap()->cell_space()); |
279 TraceFragmentation(heap()->property_cell_space()); | |
280 } | 277 } |
281 | 278 |
282 heap()->old_pointer_space()->EvictEvacuationCandidatesFromFreeLists(); | 279 heap()->old_pointer_space()->EvictEvacuationCandidatesFromFreeLists(); |
283 heap()->old_data_space()->EvictEvacuationCandidatesFromFreeLists(); | 280 heap()->old_data_space()->EvictEvacuationCandidatesFromFreeLists(); |
284 heap()->code_space()->EvictEvacuationCandidatesFromFreeLists(); | 281 heap()->code_space()->EvictEvacuationCandidatesFromFreeLists(); |
285 | 282 |
286 compacting_ = evacuation_candidates_.length() > 0; | 283 compacting_ = evacuation_candidates_.length() > 0; |
287 } | 284 } |
288 | 285 |
289 return compacting_; | 286 return compacting_; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 CHECK_EQ(0, p->LiveBytes()); | 361 CHECK_EQ(0, p->LiveBytes()); |
365 } | 362 } |
366 } | 363 } |
367 | 364 |
368 | 365 |
369 void MarkCompactCollector::VerifyMarkbitsAreClean() { | 366 void MarkCompactCollector::VerifyMarkbitsAreClean() { |
370 VerifyMarkbitsAreClean(heap_->old_pointer_space()); | 367 VerifyMarkbitsAreClean(heap_->old_pointer_space()); |
371 VerifyMarkbitsAreClean(heap_->old_data_space()); | 368 VerifyMarkbitsAreClean(heap_->old_data_space()); |
372 VerifyMarkbitsAreClean(heap_->code_space()); | 369 VerifyMarkbitsAreClean(heap_->code_space()); |
373 VerifyMarkbitsAreClean(heap_->cell_space()); | 370 VerifyMarkbitsAreClean(heap_->cell_space()); |
374 VerifyMarkbitsAreClean(heap_->property_cell_space()); | |
375 VerifyMarkbitsAreClean(heap_->map_space()); | 371 VerifyMarkbitsAreClean(heap_->map_space()); |
376 VerifyMarkbitsAreClean(heap_->new_space()); | 372 VerifyMarkbitsAreClean(heap_->new_space()); |
377 | 373 |
378 LargeObjectIterator it(heap_->lo_space()); | 374 LargeObjectIterator it(heap_->lo_space()); |
379 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { | 375 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { |
380 MarkBit mark_bit = Marking::MarkBitFrom(obj); | 376 MarkBit mark_bit = Marking::MarkBitFrom(obj); |
381 CHECK(Marking::IsWhite(mark_bit)); | 377 CHECK(Marking::IsWhite(mark_bit)); |
382 CHECK_EQ(0, Page::FromAddress(obj->address())->LiveBytes()); | 378 CHECK_EQ(0, Page::FromAddress(obj->address())->LiveBytes()); |
383 } | 379 } |
384 } | 380 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
423 } | 419 } |
424 } | 420 } |
425 | 421 |
426 | 422 |
427 void MarkCompactCollector::ClearMarkbits() { | 423 void MarkCompactCollector::ClearMarkbits() { |
428 ClearMarkbitsInPagedSpace(heap_->code_space()); | 424 ClearMarkbitsInPagedSpace(heap_->code_space()); |
429 ClearMarkbitsInPagedSpace(heap_->map_space()); | 425 ClearMarkbitsInPagedSpace(heap_->map_space()); |
430 ClearMarkbitsInPagedSpace(heap_->old_pointer_space()); | 426 ClearMarkbitsInPagedSpace(heap_->old_pointer_space()); |
431 ClearMarkbitsInPagedSpace(heap_->old_data_space()); | 427 ClearMarkbitsInPagedSpace(heap_->old_data_space()); |
432 ClearMarkbitsInPagedSpace(heap_->cell_space()); | 428 ClearMarkbitsInPagedSpace(heap_->cell_space()); |
433 ClearMarkbitsInPagedSpace(heap_->property_cell_space()); | |
434 ClearMarkbitsInNewSpace(heap_->new_space()); | 429 ClearMarkbitsInNewSpace(heap_->new_space()); |
435 | 430 |
436 LargeObjectIterator it(heap_->lo_space()); | 431 LargeObjectIterator it(heap_->lo_space()); |
437 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { | 432 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { |
438 MarkBit mark_bit = Marking::MarkBitFrom(obj); | 433 MarkBit mark_bit = Marking::MarkBitFrom(obj); |
439 mark_bit.Clear(); | 434 mark_bit.Clear(); |
440 mark_bit.Next().Clear(); | 435 mark_bit.Next().Clear(); |
441 Page::FromAddress(obj->address())->ResetProgressBar(); | 436 Page::FromAddress(obj->address())->ResetProgressBar(); |
442 Page::FromAddress(obj->address())->ResetLiveBytes(); | 437 Page::FromAddress(obj->address())->ResetLiveBytes(); |
443 } | 438 } |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
581 case OLD_POINTER_SPACE: | 576 case OLD_POINTER_SPACE: |
582 return "OLD_POINTER_SPACE"; | 577 return "OLD_POINTER_SPACE"; |
583 case OLD_DATA_SPACE: | 578 case OLD_DATA_SPACE: |
584 return "OLD_DATA_SPACE"; | 579 return "OLD_DATA_SPACE"; |
585 case CODE_SPACE: | 580 case CODE_SPACE: |
586 return "CODE_SPACE"; | 581 return "CODE_SPACE"; |
587 case MAP_SPACE: | 582 case MAP_SPACE: |
588 return "MAP_SPACE"; | 583 return "MAP_SPACE"; |
589 case CELL_SPACE: | 584 case CELL_SPACE: |
590 return "CELL_SPACE"; | 585 return "CELL_SPACE"; |
591 case PROPERTY_CELL_SPACE: | |
592 return "PROPERTY_CELL_SPACE"; | |
593 case LO_SPACE: | 586 case LO_SPACE: |
594 return "LO_SPACE"; | 587 return "LO_SPACE"; |
595 default: | 588 default: |
596 UNREACHABLE(); | 589 UNREACHABLE(); |
597 } | 590 } |
598 | 591 |
599 return NULL; | 592 return NULL; |
600 } | 593 } |
601 | 594 |
602 | 595 |
(...skipping 1450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2053 | 2046 |
2054 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->code_space()); | 2047 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->code_space()); |
2055 if (marking_deque_.IsFull()) return; | 2048 if (marking_deque_.IsFull()) return; |
2056 | 2049 |
2057 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->map_space()); | 2050 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->map_space()); |
2058 if (marking_deque_.IsFull()) return; | 2051 if (marking_deque_.IsFull()) return; |
2059 | 2052 |
2060 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->cell_space()); | 2053 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->cell_space()); |
2061 if (marking_deque_.IsFull()) return; | 2054 if (marking_deque_.IsFull()) return; |
2062 | 2055 |
2063 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, | |
2064 heap()->property_cell_space()); | |
2065 if (marking_deque_.IsFull()) return; | |
2066 | |
2067 LargeObjectIterator lo_it(heap()->lo_space()); | 2056 LargeObjectIterator lo_it(heap()->lo_space()); |
2068 DiscoverGreyObjectsWithIterator(heap(), &marking_deque_, &lo_it); | 2057 DiscoverGreyObjectsWithIterator(heap(), &marking_deque_, &lo_it); |
2069 if (marking_deque_.IsFull()) return; | 2058 if (marking_deque_.IsFull()) return; |
2070 | 2059 |
2071 marking_deque_.ClearOverflowed(); | 2060 marking_deque_.ClearOverflowed(); |
2072 } | 2061 } |
2073 | 2062 |
2074 | 2063 |
2075 // Mark all objects reachable (transitively) from objects on the marking | 2064 // Mark all objects reachable (transitively) from objects on the marking |
2076 // stack. Before: the marking stack contains zero or more heap object | 2065 // stack. Before: the marking stack contains zero or more heap object |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2261 HeapObject* cell; | 2250 HeapObject* cell; |
2262 while ((cell = cell_iterator.Next()) != NULL) { | 2251 while ((cell = cell_iterator.Next()) != NULL) { |
2263 DCHECK(cell->IsCell()); | 2252 DCHECK(cell->IsCell()); |
2264 if (IsMarked(cell)) { | 2253 if (IsMarked(cell)) { |
2265 int offset = Cell::kValueOffset; | 2254 int offset = Cell::kValueOffset; |
2266 MarkCompactMarkingVisitor::VisitPointer( | 2255 MarkCompactMarkingVisitor::VisitPointer( |
2267 heap(), reinterpret_cast<Object**>(cell->address() + offset)); | 2256 heap(), reinterpret_cast<Object**>(cell->address() + offset)); |
2268 } | 2257 } |
2269 } | 2258 } |
2270 } | 2259 } |
2271 { | |
2272 HeapObjectIterator js_global_property_cell_iterator( | |
2273 heap()->property_cell_space()); | |
2274 HeapObject* cell; | |
2275 while ((cell = js_global_property_cell_iterator.Next()) != NULL) { | |
2276 DCHECK(cell->IsPropertyCell()); | |
2277 if (IsMarked(cell)) { | |
2278 MarkCompactMarkingVisitor::VisitPropertyCell(cell->map(), cell); | |
2279 } | |
2280 } | |
2281 } | |
2282 } | 2260 } |
2283 | 2261 |
2284 RootMarkingVisitor root_visitor(heap()); | 2262 RootMarkingVisitor root_visitor(heap()); |
2285 MarkRoots(&root_visitor); | 2263 MarkRoots(&root_visitor); |
2286 | 2264 |
2287 ProcessTopOptimizedFrame(&root_visitor); | 2265 ProcessTopOptimizedFrame(&root_visitor); |
2288 | 2266 |
2289 // Retaining dying maps should happen before or during ephemeral marking | 2267 // Retaining dying maps should happen before or during ephemeral marking |
2290 // because a map could keep the key of an ephemeron alive. Note that map | 2268 // because a map could keep the key of an ephemeron alive. Note that map |
2291 // aging is imprecise: maps that are kept alive only by ephemerons will age. | 2269 // aging is imprecise: maps that are kept alive only by ephemerons will age. |
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2928 } else if (heap->old_pointer_space()->ContainsSafe(slot_address)) { | 2906 } else if (heap->old_pointer_space()->ContainsSafe(slot_address)) { |
2929 space_owner_id = 3; | 2907 space_owner_id = 3; |
2930 } else if (heap->old_data_space()->ContainsSafe(slot_address)) { | 2908 } else if (heap->old_data_space()->ContainsSafe(slot_address)) { |
2931 space_owner_id = 4; | 2909 space_owner_id = 4; |
2932 } else if (heap->code_space()->ContainsSafe(slot_address)) { | 2910 } else if (heap->code_space()->ContainsSafe(slot_address)) { |
2933 space_owner_id = 5; | 2911 space_owner_id = 5; |
2934 } else if (heap->map_space()->ContainsSafe(slot_address)) { | 2912 } else if (heap->map_space()->ContainsSafe(slot_address)) { |
2935 space_owner_id = 6; | 2913 space_owner_id = 6; |
2936 } else if (heap->cell_space()->ContainsSafe(slot_address)) { | 2914 } else if (heap->cell_space()->ContainsSafe(slot_address)) { |
2937 space_owner_id = 7; | 2915 space_owner_id = 7; |
2938 } else if (heap->property_cell_space()->ContainsSafe(slot_address)) { | |
2939 space_owner_id = 8; | |
2940 } else { | 2916 } else { |
2941 // Lo space or other. | 2917 // Lo space or other. |
2942 space_owner_id = 9; | 2918 space_owner_id = 8; |
2943 } | 2919 } |
2944 data[index++] = space_owner_id; | 2920 data[index++] = space_owner_id; |
2945 data[index++] = 0x20aaaaaaaaUL; | 2921 data[index++] = 0x20aaaaaaaaUL; |
2946 | 2922 |
2947 // Find map word lying near before the slot address (usually the map word is | 2923 // Find map word lying near before the slot address (usually the map word is |
2948 // at -3 words from the slot but just in case we look up further. | 2924 // at -3 words from the slot but just in case we look up further. |
2949 Object** map_slot = slot; | 2925 Object** map_slot = slot; |
2950 bool found = false; | 2926 bool found = false; |
2951 const int kMaxDistanceToMap = 64; | 2927 const int kMaxDistanceToMap = 64; |
2952 for (int i = 0; i < kMaxDistanceToMap; i++, map_slot--) { | 2928 for (int i = 0; i < kMaxDistanceToMap; i++, map_slot--) { |
(...skipping 784 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3737 | 3713 |
3738 // Update pointers from cells. | 3714 // Update pointers from cells. |
3739 HeapObjectIterator cell_iterator(heap_->cell_space()); | 3715 HeapObjectIterator cell_iterator(heap_->cell_space()); |
3740 for (HeapObject* cell = cell_iterator.Next(); cell != NULL; | 3716 for (HeapObject* cell = cell_iterator.Next(); cell != NULL; |
3741 cell = cell_iterator.Next()) { | 3717 cell = cell_iterator.Next()) { |
3742 if (cell->IsCell()) { | 3718 if (cell->IsCell()) { |
3743 Cell::BodyDescriptor::IterateBody(cell, &updating_visitor); | 3719 Cell::BodyDescriptor::IterateBody(cell, &updating_visitor); |
3744 } | 3720 } |
3745 } | 3721 } |
3746 | 3722 |
3747 HeapObjectIterator js_global_property_cell_iterator( | |
3748 heap_->property_cell_space()); | |
3749 for (HeapObject* cell = js_global_property_cell_iterator.Next(); cell != NULL; | |
3750 cell = js_global_property_cell_iterator.Next()) { | |
3751 if (cell->IsPropertyCell()) { | |
3752 PropertyCell::BodyDescriptor::IterateBody(cell, &updating_visitor); | |
3753 } | |
3754 } | |
3755 | |
3756 heap_->string_table()->Iterate(&updating_visitor); | 3723 heap_->string_table()->Iterate(&updating_visitor); |
3757 | 3724 |
3758 // Update pointers from external string table. | 3725 // Update pointers from external string table. |
3759 heap_->UpdateReferencesInExternalStringTable( | 3726 heap_->UpdateReferencesInExternalStringTable( |
3760 &UpdateReferenceInExternalStringTableEntry); | 3727 &UpdateReferenceInExternalStringTableEntry); |
3761 | 3728 |
3762 EvacuationWeakObjectRetainer evacuation_object_retainer; | 3729 EvacuationWeakObjectRetainer evacuation_object_retainer; |
3763 heap()->ProcessAllWeakReferences(&evacuation_object_retainer); | 3730 heap()->ProcessAllWeakReferences(&evacuation_object_retainer); |
3764 | 3731 |
3765 // Collects callback info for handles that are pending (about to be | 3732 // Collects callback info for handles that are pending (about to be |
(...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4369 { | 4336 { |
4370 GCTracer::Scope sweep_scope(heap()->tracer(), | 4337 GCTracer::Scope sweep_scope(heap()->tracer(), |
4371 GCTracer::Scope::MC_SWEEP_CODE); | 4338 GCTracer::Scope::MC_SWEEP_CODE); |
4372 SweepSpace(heap()->code_space(), SEQUENTIAL_SWEEPING); | 4339 SweepSpace(heap()->code_space(), SEQUENTIAL_SWEEPING); |
4373 } | 4340 } |
4374 | 4341 |
4375 { | 4342 { |
4376 GCTracer::Scope sweep_scope(heap()->tracer(), | 4343 GCTracer::Scope sweep_scope(heap()->tracer(), |
4377 GCTracer::Scope::MC_SWEEP_CELL); | 4344 GCTracer::Scope::MC_SWEEP_CELL); |
4378 SweepSpace(heap()->cell_space(), SEQUENTIAL_SWEEPING); | 4345 SweepSpace(heap()->cell_space(), SEQUENTIAL_SWEEPING); |
4379 SweepSpace(heap()->property_cell_space(), SEQUENTIAL_SWEEPING); | |
4380 } | 4346 } |
4381 | 4347 |
4382 EvacuateNewSpaceAndCandidates(); | 4348 EvacuateNewSpaceAndCandidates(); |
4383 | 4349 |
4384 // ClearNonLiveReferences depends on precise sweeping of map space to | 4350 // ClearNonLiveReferences depends on precise sweeping of map space to |
4385 // detect whether unmarked map became dead in this collection or in one | 4351 // detect whether unmarked map became dead in this collection or in one |
4386 // of the previous ones. | 4352 // of the previous ones. |
4387 { | 4353 { |
4388 GCTracer::Scope sweep_scope(heap()->tracer(), | 4354 GCTracer::Scope sweep_scope(heap()->tracer(), |
4389 GCTracer::Scope::MC_SWEEP_MAP); | 4355 GCTracer::Scope::MC_SWEEP_MAP); |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4626 SlotsBuffer* buffer = *buffer_address; | 4592 SlotsBuffer* buffer = *buffer_address; |
4627 while (buffer != NULL) { | 4593 while (buffer != NULL) { |
4628 SlotsBuffer* next_buffer = buffer->next(); | 4594 SlotsBuffer* next_buffer = buffer->next(); |
4629 DeallocateBuffer(buffer); | 4595 DeallocateBuffer(buffer); |
4630 buffer = next_buffer; | 4596 buffer = next_buffer; |
4631 } | 4597 } |
4632 *buffer_address = NULL; | 4598 *buffer_address = NULL; |
4633 } | 4599 } |
4634 } | 4600 } |
4635 } // namespace v8::internal | 4601 } // namespace v8::internal |
OLD | NEW |