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 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 Page* p = it.next(); | 131 Page* p = it.next(); |
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_space()); | 138 VerifyMarking(heap->old_space()); |
139 VerifyMarking(heap->code_space()); | 139 VerifyMarking(heap->code_space()); |
140 VerifyMarking(heap->cell_space()); | 140 VerifyMarking(heap->cell_space()); |
141 VerifyMarking(heap->property_cell_space()); | |
142 VerifyMarking(heap->map_space()); | 141 VerifyMarking(heap->map_space()); |
143 VerifyMarking(heap->new_space()); | 142 VerifyMarking(heap->new_space()); |
144 | 143 |
145 VerifyMarkingVisitor visitor(heap); | 144 VerifyMarkingVisitor visitor(heap); |
146 | 145 |
147 LargeObjectIterator it(heap->lo_space()); | 146 LargeObjectIterator it(heap->lo_space()); |
148 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { | 147 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { |
149 if (MarkCompactCollector::IsMarked(obj)) { | 148 if (MarkCompactCollector::IsMarked(obj)) { |
150 obj->Iterate(&visitor); | 149 obj->Iterate(&visitor); |
151 } | 150 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 if (p->IsEvacuationCandidate()) continue; | 209 if (p->IsEvacuationCandidate()) continue; |
211 VerifyEvacuation(p); | 210 VerifyEvacuation(p); |
212 } | 211 } |
213 } | 212 } |
214 | 213 |
215 | 214 |
216 static void VerifyEvacuation(Heap* heap) { | 215 static void VerifyEvacuation(Heap* heap) { |
217 VerifyEvacuation(heap, heap->old_space()); | 216 VerifyEvacuation(heap, heap->old_space()); |
218 VerifyEvacuation(heap, heap->code_space()); | 217 VerifyEvacuation(heap, heap->code_space()); |
219 VerifyEvacuation(heap, heap->cell_space()); | 218 VerifyEvacuation(heap, heap->cell_space()); |
220 VerifyEvacuation(heap, heap->property_cell_space()); | |
221 VerifyEvacuation(heap, heap->map_space()); | 219 VerifyEvacuation(heap, heap->map_space()); |
222 VerifyEvacuation(heap->new_space()); | 220 VerifyEvacuation(heap->new_space()); |
223 | 221 |
224 VerifyEvacuationVisitor visitor; | 222 VerifyEvacuationVisitor visitor; |
225 heap->IterateStrongRoots(&visitor, VISIT_ALL); | 223 heap->IterateStrongRoots(&visitor, VISIT_ALL); |
226 } | 224 } |
227 #endif // VERIFY_HEAP | 225 #endif // VERIFY_HEAP |
228 | 226 |
229 | 227 |
230 void MarkCompactCollector::SetUp() { | 228 void MarkCompactCollector::SetUp() { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 if (FLAG_compact_code_space && (mode == NON_INCREMENTAL_COMPACTION || | 262 if (FLAG_compact_code_space && (mode == NON_INCREMENTAL_COMPACTION || |
265 FLAG_incremental_code_compaction)) { | 263 FLAG_incremental_code_compaction)) { |
266 CollectEvacuationCandidates(heap()->code_space()); | 264 CollectEvacuationCandidates(heap()->code_space()); |
267 } else if (FLAG_trace_fragmentation) { | 265 } else if (FLAG_trace_fragmentation) { |
268 TraceFragmentation(heap()->code_space()); | 266 TraceFragmentation(heap()->code_space()); |
269 } | 267 } |
270 | 268 |
271 if (FLAG_trace_fragmentation) { | 269 if (FLAG_trace_fragmentation) { |
272 TraceFragmentation(heap()->map_space()); | 270 TraceFragmentation(heap()->map_space()); |
273 TraceFragmentation(heap()->cell_space()); | 271 TraceFragmentation(heap()->cell_space()); |
274 TraceFragmentation(heap()->property_cell_space()); | |
275 } | 272 } |
276 | 273 |
277 heap()->old_space()->EvictEvacuationCandidatesFromFreeLists(); | 274 heap()->old_space()->EvictEvacuationCandidatesFromFreeLists(); |
278 heap()->code_space()->EvictEvacuationCandidatesFromFreeLists(); | 275 heap()->code_space()->EvictEvacuationCandidatesFromFreeLists(); |
279 | 276 |
280 compacting_ = evacuation_candidates_.length() > 0; | 277 compacting_ = evacuation_candidates_.length() > 0; |
281 } | 278 } |
282 | 279 |
283 return compacting_; | 280 return compacting_; |
284 } | 281 } |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 CHECK(p->markbits()->IsClean()); | 354 CHECK(p->markbits()->IsClean()); |
358 CHECK_EQ(0, p->LiveBytes()); | 355 CHECK_EQ(0, p->LiveBytes()); |
359 } | 356 } |
360 } | 357 } |
361 | 358 |
362 | 359 |
363 void MarkCompactCollector::VerifyMarkbitsAreClean() { | 360 void MarkCompactCollector::VerifyMarkbitsAreClean() { |
364 VerifyMarkbitsAreClean(heap_->old_space()); | 361 VerifyMarkbitsAreClean(heap_->old_space()); |
365 VerifyMarkbitsAreClean(heap_->code_space()); | 362 VerifyMarkbitsAreClean(heap_->code_space()); |
366 VerifyMarkbitsAreClean(heap_->cell_space()); | 363 VerifyMarkbitsAreClean(heap_->cell_space()); |
367 VerifyMarkbitsAreClean(heap_->property_cell_space()); | |
368 VerifyMarkbitsAreClean(heap_->map_space()); | 364 VerifyMarkbitsAreClean(heap_->map_space()); |
369 VerifyMarkbitsAreClean(heap_->new_space()); | 365 VerifyMarkbitsAreClean(heap_->new_space()); |
370 | 366 |
371 LargeObjectIterator it(heap_->lo_space()); | 367 LargeObjectIterator it(heap_->lo_space()); |
372 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { | 368 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { |
373 MarkBit mark_bit = Marking::MarkBitFrom(obj); | 369 MarkBit mark_bit = Marking::MarkBitFrom(obj); |
374 CHECK(Marking::IsWhite(mark_bit)); | 370 CHECK(Marking::IsWhite(mark_bit)); |
375 CHECK_EQ(0, Page::FromAddress(obj->address())->LiveBytes()); | 371 CHECK_EQ(0, Page::FromAddress(obj->address())->LiveBytes()); |
376 } | 372 } |
377 } | 373 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 Bitmap::Clear(it.next()); | 411 Bitmap::Clear(it.next()); |
416 } | 412 } |
417 } | 413 } |
418 | 414 |
419 | 415 |
420 void MarkCompactCollector::ClearMarkbits() { | 416 void MarkCompactCollector::ClearMarkbits() { |
421 ClearMarkbitsInPagedSpace(heap_->code_space()); | 417 ClearMarkbitsInPagedSpace(heap_->code_space()); |
422 ClearMarkbitsInPagedSpace(heap_->map_space()); | 418 ClearMarkbitsInPagedSpace(heap_->map_space()); |
423 ClearMarkbitsInPagedSpace(heap_->old_space()); | 419 ClearMarkbitsInPagedSpace(heap_->old_space()); |
424 ClearMarkbitsInPagedSpace(heap_->cell_space()); | 420 ClearMarkbitsInPagedSpace(heap_->cell_space()); |
425 ClearMarkbitsInPagedSpace(heap_->property_cell_space()); | |
426 ClearMarkbitsInNewSpace(heap_->new_space()); | 421 ClearMarkbitsInNewSpace(heap_->new_space()); |
427 | 422 |
428 LargeObjectIterator it(heap_->lo_space()); | 423 LargeObjectIterator it(heap_->lo_space()); |
429 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { | 424 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { |
430 MarkBit mark_bit = Marking::MarkBitFrom(obj); | 425 MarkBit mark_bit = Marking::MarkBitFrom(obj); |
431 mark_bit.Clear(); | 426 mark_bit.Clear(); |
432 mark_bit.Next().Clear(); | 427 mark_bit.Next().Clear(); |
433 Page::FromAddress(obj->address())->ResetProgressBar(); | 428 Page::FromAddress(obj->address())->ResetProgressBar(); |
434 Page::FromAddress(obj->address())->ResetLiveBytes(); | 429 Page::FromAddress(obj->address())->ResetLiveBytes(); |
435 } | 430 } |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
561 case NEW_SPACE: | 556 case NEW_SPACE: |
562 return "NEW_SPACE"; | 557 return "NEW_SPACE"; |
563 case OLD_SPACE: | 558 case OLD_SPACE: |
564 return "OLD_SPACE"; | 559 return "OLD_SPACE"; |
565 case CODE_SPACE: | 560 case CODE_SPACE: |
566 return "CODE_SPACE"; | 561 return "CODE_SPACE"; |
567 case MAP_SPACE: | 562 case MAP_SPACE: |
568 return "MAP_SPACE"; | 563 return "MAP_SPACE"; |
569 case CELL_SPACE: | 564 case CELL_SPACE: |
570 return "CELL_SPACE"; | 565 return "CELL_SPACE"; |
571 case PROPERTY_CELL_SPACE: | |
572 return "PROPERTY_CELL_SPACE"; | |
573 case LO_SPACE: | 566 case LO_SPACE: |
574 return "LO_SPACE"; | 567 return "LO_SPACE"; |
575 default: | 568 default: |
576 UNREACHABLE(); | 569 UNREACHABLE(); |
577 } | 570 } |
578 | 571 |
579 return NULL; | 572 return NULL; |
580 } | 573 } |
581 | 574 |
582 | 575 |
(...skipping 1444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2027 | 2020 |
2028 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->code_space()); | 2021 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->code_space()); |
2029 if (marking_deque_.IsFull()) return; | 2022 if (marking_deque_.IsFull()) return; |
2030 | 2023 |
2031 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->map_space()); | 2024 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->map_space()); |
2032 if (marking_deque_.IsFull()) return; | 2025 if (marking_deque_.IsFull()) return; |
2033 | 2026 |
2034 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->cell_space()); | 2027 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->cell_space()); |
2035 if (marking_deque_.IsFull()) return; | 2028 if (marking_deque_.IsFull()) return; |
2036 | 2029 |
2037 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, | |
2038 heap()->property_cell_space()); | |
2039 if (marking_deque_.IsFull()) return; | |
2040 | |
2041 LargeObjectIterator lo_it(heap()->lo_space()); | 2030 LargeObjectIterator lo_it(heap()->lo_space()); |
2042 DiscoverGreyObjectsWithIterator(heap(), &marking_deque_, &lo_it); | 2031 DiscoverGreyObjectsWithIterator(heap(), &marking_deque_, &lo_it); |
2043 if (marking_deque_.IsFull()) return; | 2032 if (marking_deque_.IsFull()) return; |
2044 | 2033 |
2045 marking_deque_.ClearOverflowed(); | 2034 marking_deque_.ClearOverflowed(); |
2046 } | 2035 } |
2047 | 2036 |
2048 | 2037 |
2049 // Mark all objects reachable (transitively) from objects on the marking | 2038 // Mark all objects reachable (transitively) from objects on the marking |
2050 // stack. Before: the marking stack contains zero or more heap object | 2039 // stack. Before: the marking stack contains zero or more heap object |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2235 HeapObject* cell; | 2224 HeapObject* cell; |
2236 while ((cell = cell_iterator.Next()) != NULL) { | 2225 while ((cell = cell_iterator.Next()) != NULL) { |
2237 DCHECK(cell->IsCell()); | 2226 DCHECK(cell->IsCell()); |
2238 if (IsMarked(cell)) { | 2227 if (IsMarked(cell)) { |
2239 int offset = Cell::kValueOffset; | 2228 int offset = Cell::kValueOffset; |
2240 MarkCompactMarkingVisitor::VisitPointer( | 2229 MarkCompactMarkingVisitor::VisitPointer( |
2241 heap(), reinterpret_cast<Object**>(cell->address() + offset)); | 2230 heap(), reinterpret_cast<Object**>(cell->address() + offset)); |
2242 } | 2231 } |
2243 } | 2232 } |
2244 } | 2233 } |
2245 { | |
2246 HeapObjectIterator js_global_property_cell_iterator( | |
2247 heap()->property_cell_space()); | |
2248 HeapObject* cell; | |
2249 while ((cell = js_global_property_cell_iterator.Next()) != NULL) { | |
2250 DCHECK(cell->IsPropertyCell()); | |
2251 if (IsMarked(cell)) { | |
2252 MarkCompactMarkingVisitor::VisitPropertyCell(cell->map(), cell); | |
2253 } | |
2254 } | |
2255 } | |
2256 } | 2234 } |
2257 | 2235 |
2258 RootMarkingVisitor root_visitor(heap()); | 2236 RootMarkingVisitor root_visitor(heap()); |
2259 MarkRoots(&root_visitor); | 2237 MarkRoots(&root_visitor); |
2260 | 2238 |
2261 ProcessTopOptimizedFrame(&root_visitor); | 2239 ProcessTopOptimizedFrame(&root_visitor); |
2262 | 2240 |
2263 // Retaining dying maps should happen before or during ephemeral marking | 2241 // Retaining dying maps should happen before or during ephemeral marking |
2264 // because a map could keep the key of an ephemeron alive. Note that map | 2242 // because a map could keep the key of an ephemeron alive. Note that map |
2265 // aging is imprecise: maps that are kept alive only by ephemerons will age. | 2243 // 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... |
2902 } else if (heap->new_space()->FromSpaceContains(slot_address)) { | 2880 } else if (heap->new_space()->FromSpaceContains(slot_address)) { |
2903 space_owner_id = 2; | 2881 space_owner_id = 2; |
2904 } else if (heap->old_space()->ContainsSafe(slot_address)) { | 2882 } else if (heap->old_space()->ContainsSafe(slot_address)) { |
2905 space_owner_id = 3; | 2883 space_owner_id = 3; |
2906 } else if (heap->code_space()->ContainsSafe(slot_address)) { | 2884 } else if (heap->code_space()->ContainsSafe(slot_address)) { |
2907 space_owner_id = 4; | 2885 space_owner_id = 4; |
2908 } else if (heap->map_space()->ContainsSafe(slot_address)) { | 2886 } else if (heap->map_space()->ContainsSafe(slot_address)) { |
2909 space_owner_id = 5; | 2887 space_owner_id = 5; |
2910 } else if (heap->cell_space()->ContainsSafe(slot_address)) { | 2888 } else if (heap->cell_space()->ContainsSafe(slot_address)) { |
2911 space_owner_id = 6; | 2889 space_owner_id = 6; |
2912 } else if (heap->property_cell_space()->ContainsSafe(slot_address)) { | |
2913 space_owner_id = 7; | |
2914 } else { | 2890 } else { |
2915 // Lo space or other. | 2891 // Lo space or other. |
2916 space_owner_id = 8; | 2892 space_owner_id = 7; |
2917 } | 2893 } |
2918 data[index++] = space_owner_id; | 2894 data[index++] = space_owner_id; |
2919 data[index++] = 0x20aaaaaaaaUL; | 2895 data[index++] = 0x20aaaaaaaaUL; |
2920 | 2896 |
2921 // Find map word lying near before the slot address (usually the map word is | 2897 // Find map word lying near before the slot address (usually the map word is |
2922 // at -3 words from the slot but just in case we look up further. | 2898 // at -3 words from the slot but just in case we look up further. |
2923 Object** map_slot = slot; | 2899 Object** map_slot = slot; |
2924 bool found = false; | 2900 bool found = false; |
2925 const int kMaxDistanceToMap = 64; | 2901 const int kMaxDistanceToMap = 64; |
2926 for (int i = 0; i < kMaxDistanceToMap; i++, map_slot--) { | 2902 for (int i = 0; i < kMaxDistanceToMap; i++, map_slot--) { |
(...skipping 776 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3703 | 3679 |
3704 // Update pointers from cells. | 3680 // Update pointers from cells. |
3705 HeapObjectIterator cell_iterator(heap_->cell_space()); | 3681 HeapObjectIterator cell_iterator(heap_->cell_space()); |
3706 for (HeapObject* cell = cell_iterator.Next(); cell != NULL; | 3682 for (HeapObject* cell = cell_iterator.Next(); cell != NULL; |
3707 cell = cell_iterator.Next()) { | 3683 cell = cell_iterator.Next()) { |
3708 if (cell->IsCell()) { | 3684 if (cell->IsCell()) { |
3709 Cell::BodyDescriptor::IterateBody(cell, &updating_visitor); | 3685 Cell::BodyDescriptor::IterateBody(cell, &updating_visitor); |
3710 } | 3686 } |
3711 } | 3687 } |
3712 | 3688 |
3713 HeapObjectIterator js_global_property_cell_iterator( | |
3714 heap_->property_cell_space()); | |
3715 for (HeapObject* cell = js_global_property_cell_iterator.Next(); cell != NULL; | |
3716 cell = js_global_property_cell_iterator.Next()) { | |
3717 if (cell->IsPropertyCell()) { | |
3718 PropertyCell::BodyDescriptor::IterateBody(cell, &updating_visitor); | |
3719 } | |
3720 } | |
3721 | |
3722 heap_->string_table()->Iterate(&updating_visitor); | 3689 heap_->string_table()->Iterate(&updating_visitor); |
3723 | 3690 |
3724 // Update pointers from external string table. | 3691 // Update pointers from external string table. |
3725 heap_->UpdateReferencesInExternalStringTable( | 3692 heap_->UpdateReferencesInExternalStringTable( |
3726 &UpdateReferenceInExternalStringTableEntry); | 3693 &UpdateReferenceInExternalStringTableEntry); |
3727 | 3694 |
3728 EvacuationWeakObjectRetainer evacuation_object_retainer; | 3695 EvacuationWeakObjectRetainer evacuation_object_retainer; |
3729 heap()->ProcessAllWeakReferences(&evacuation_object_retainer); | 3696 heap()->ProcessAllWeakReferences(&evacuation_object_retainer); |
3730 | 3697 |
3731 // Collects callback info for handles that are pending (about to be | 3698 // Collects callback info for handles that are pending (about to be |
(...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4330 { | 4297 { |
4331 GCTracer::Scope sweep_scope(heap()->tracer(), | 4298 GCTracer::Scope sweep_scope(heap()->tracer(), |
4332 GCTracer::Scope::MC_SWEEP_CODE); | 4299 GCTracer::Scope::MC_SWEEP_CODE); |
4333 SweepSpace(heap()->code_space(), SEQUENTIAL_SWEEPING); | 4300 SweepSpace(heap()->code_space(), SEQUENTIAL_SWEEPING); |
4334 } | 4301 } |
4335 | 4302 |
4336 { | 4303 { |
4337 GCTracer::Scope sweep_scope(heap()->tracer(), | 4304 GCTracer::Scope sweep_scope(heap()->tracer(), |
4338 GCTracer::Scope::MC_SWEEP_CELL); | 4305 GCTracer::Scope::MC_SWEEP_CELL); |
4339 SweepSpace(heap()->cell_space(), SEQUENTIAL_SWEEPING); | 4306 SweepSpace(heap()->cell_space(), SEQUENTIAL_SWEEPING); |
4340 SweepSpace(heap()->property_cell_space(), SEQUENTIAL_SWEEPING); | |
4341 } | 4307 } |
4342 | 4308 |
4343 EvacuateNewSpaceAndCandidates(); | 4309 EvacuateNewSpaceAndCandidates(); |
4344 | 4310 |
4345 // ClearNonLiveReferences depends on precise sweeping of map space to | 4311 // ClearNonLiveReferences depends on precise sweeping of map space to |
4346 // detect whether unmarked map became dead in this collection or in one | 4312 // detect whether unmarked map became dead in this collection or in one |
4347 // of the previous ones. | 4313 // of the previous ones. |
4348 { | 4314 { |
4349 GCTracer::Scope sweep_scope(heap()->tracer(), | 4315 GCTracer::Scope sweep_scope(heap()->tracer(), |
4350 GCTracer::Scope::MC_SWEEP_MAP); | 4316 GCTracer::Scope::MC_SWEEP_MAP); |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4586 SlotsBuffer* buffer = *buffer_address; | 4552 SlotsBuffer* buffer = *buffer_address; |
4587 while (buffer != NULL) { | 4553 while (buffer != NULL) { |
4588 SlotsBuffer* next_buffer = buffer->next(); | 4554 SlotsBuffer* next_buffer = buffer->next(); |
4589 DeallocateBuffer(buffer); | 4555 DeallocateBuffer(buffer); |
4590 buffer = next_buffer; | 4556 buffer = next_buffer; |
4591 } | 4557 } |
4592 *buffer_address = NULL; | 4558 *buffer_address = NULL; |
4593 } | 4559 } |
4594 } | 4560 } |
4595 } // namespace v8::internal | 4561 } // namespace v8::internal |
OLD | NEW |