| 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 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 while (it.has_next()) { | 130 while (it.has_next()) { |
| 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()); | |
| 141 VerifyMarking(heap->map_space()); | 140 VerifyMarking(heap->map_space()); |
| 142 VerifyMarking(heap->new_space()); | 141 VerifyMarking(heap->new_space()); |
| 143 | 142 |
| 144 VerifyMarkingVisitor visitor(heap); | 143 VerifyMarkingVisitor visitor(heap); |
| 145 | 144 |
| 146 LargeObjectIterator it(heap->lo_space()); | 145 LargeObjectIterator it(heap->lo_space()); |
| 147 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { | 146 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { |
| 148 if (MarkCompactCollector::IsMarked(obj)) { | 147 if (MarkCompactCollector::IsMarked(obj)) { |
| 149 obj->Iterate(&visitor); | 148 obj->Iterate(&visitor); |
| 150 } | 149 } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 208 Page* p = it.next(); | 207 Page* p = it.next(); |
| 209 if (p->IsEvacuationCandidate()) continue; | 208 if (p->IsEvacuationCandidate()) continue; |
| 210 VerifyEvacuation(p); | 209 VerifyEvacuation(p); |
| 211 } | 210 } |
| 212 } | 211 } |
| 213 | 212 |
| 214 | 213 |
| 215 static void VerifyEvacuation(Heap* heap) { | 214 static void VerifyEvacuation(Heap* heap) { |
| 216 VerifyEvacuation(heap, heap->old_space()); | 215 VerifyEvacuation(heap, heap->old_space()); |
| 217 VerifyEvacuation(heap, heap->code_space()); | 216 VerifyEvacuation(heap, heap->code_space()); |
| 218 VerifyEvacuation(heap, heap->cell_space()); | |
| 219 VerifyEvacuation(heap, heap->map_space()); | 217 VerifyEvacuation(heap, heap->map_space()); |
| 220 VerifyEvacuation(heap->new_space()); | 218 VerifyEvacuation(heap->new_space()); |
| 221 | 219 |
| 222 VerifyEvacuationVisitor visitor; | 220 VerifyEvacuationVisitor visitor; |
| 223 heap->IterateStrongRoots(&visitor, VISIT_ALL); | 221 heap->IterateStrongRoots(&visitor, VISIT_ALL); |
| 224 } | 222 } |
| 225 #endif // VERIFY_HEAP | 223 #endif // VERIFY_HEAP |
| 226 | 224 |
| 227 | 225 |
| 228 void MarkCompactCollector::SetUp() { | 226 void MarkCompactCollector::SetUp() { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 261 | 259 |
| 262 if (FLAG_compact_code_space && (mode == NON_INCREMENTAL_COMPACTION || | 260 if (FLAG_compact_code_space && (mode == NON_INCREMENTAL_COMPACTION || |
| 263 FLAG_incremental_code_compaction)) { | 261 FLAG_incremental_code_compaction)) { |
| 264 CollectEvacuationCandidates(heap()->code_space()); | 262 CollectEvacuationCandidates(heap()->code_space()); |
| 265 } else if (FLAG_trace_fragmentation) { | 263 } else if (FLAG_trace_fragmentation) { |
| 266 TraceFragmentation(heap()->code_space()); | 264 TraceFragmentation(heap()->code_space()); |
| 267 } | 265 } |
| 268 | 266 |
| 269 if (FLAG_trace_fragmentation) { | 267 if (FLAG_trace_fragmentation) { |
| 270 TraceFragmentation(heap()->map_space()); | 268 TraceFragmentation(heap()->map_space()); |
| 271 TraceFragmentation(heap()->cell_space()); | |
| 272 } | 269 } |
| 273 | 270 |
| 274 heap()->old_space()->EvictEvacuationCandidatesFromFreeLists(); | 271 heap()->old_space()->EvictEvacuationCandidatesFromFreeLists(); |
| 275 heap()->code_space()->EvictEvacuationCandidatesFromFreeLists(); | 272 heap()->code_space()->EvictEvacuationCandidatesFromFreeLists(); |
| 276 | 273 |
| 277 compacting_ = evacuation_candidates_.length() > 0; | 274 compacting_ = evacuation_candidates_.length() > 0; |
| 278 } | 275 } |
| 279 | 276 |
| 280 return compacting_; | 277 return compacting_; |
| 281 } | 278 } |
| 282 | 279 |
| 283 | 280 |
| 284 void MarkCompactCollector::ClearInvalidSlotsBufferEntries(PagedSpace* space) { | 281 void MarkCompactCollector::ClearInvalidSlotsBufferEntries(PagedSpace* space) { |
| 285 PageIterator it(space); | 282 PageIterator it(space); |
| 286 while (it.has_next()) { | 283 while (it.has_next()) { |
| 287 Page* p = it.next(); | 284 Page* p = it.next(); |
| 288 SlotsBuffer::RemoveInvalidSlots(heap_, p->slots_buffer()); | 285 SlotsBuffer::RemoveInvalidSlots(heap_, p->slots_buffer()); |
| 289 } | 286 } |
| 290 } | 287 } |
| 291 | 288 |
| 292 | 289 |
| 293 void MarkCompactCollector::ClearInvalidStoreAndSlotsBufferEntries() { | 290 void MarkCompactCollector::ClearInvalidStoreAndSlotsBufferEntries() { |
| 294 heap_->store_buffer()->ClearInvalidStoreBufferEntries(); | 291 heap_->store_buffer()->ClearInvalidStoreBufferEntries(); |
| 295 | 292 |
| 296 ClearInvalidSlotsBufferEntries(heap_->old_space()); | 293 ClearInvalidSlotsBufferEntries(heap_->old_space()); |
| 297 ClearInvalidSlotsBufferEntries(heap_->code_space()); | 294 ClearInvalidSlotsBufferEntries(heap_->code_space()); |
| 298 ClearInvalidSlotsBufferEntries(heap_->cell_space()); | |
| 299 ClearInvalidSlotsBufferEntries(heap_->map_space()); | 295 ClearInvalidSlotsBufferEntries(heap_->map_space()); |
| 300 | 296 |
| 301 LargeObjectIterator it(heap_->lo_space()); | 297 LargeObjectIterator it(heap_->lo_space()); |
| 302 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) { | 298 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) { |
| 303 MemoryChunk* chunk = MemoryChunk::FromAddress(object->address()); | 299 MemoryChunk* chunk = MemoryChunk::FromAddress(object->address()); |
| 304 SlotsBuffer::RemoveInvalidSlots(heap_, chunk->slots_buffer()); | 300 SlotsBuffer::RemoveInvalidSlots(heap_, chunk->slots_buffer()); |
| 305 } | 301 } |
| 306 } | 302 } |
| 307 | 303 |
| 308 | 304 |
| 309 #ifdef VERIFY_HEAP | 305 #ifdef VERIFY_HEAP |
| 310 static void VerifyValidSlotsBufferEntries(Heap* heap, PagedSpace* space) { | 306 static void VerifyValidSlotsBufferEntries(Heap* heap, PagedSpace* space) { |
| 311 PageIterator it(space); | 307 PageIterator it(space); |
| 312 while (it.has_next()) { | 308 while (it.has_next()) { |
| 313 Page* p = it.next(); | 309 Page* p = it.next(); |
| 314 SlotsBuffer::VerifySlots(heap, p->slots_buffer()); | 310 SlotsBuffer::VerifySlots(heap, p->slots_buffer()); |
| 315 } | 311 } |
| 316 } | 312 } |
| 317 | 313 |
| 318 | 314 |
| 319 static void VerifyValidStoreAndSlotsBufferEntries(Heap* heap) { | 315 static void VerifyValidStoreAndSlotsBufferEntries(Heap* heap) { |
| 320 heap->store_buffer()->VerifyValidStoreBufferEntries(); | 316 heap->store_buffer()->VerifyValidStoreBufferEntries(); |
| 321 | 317 |
| 322 VerifyValidSlotsBufferEntries(heap, heap->old_space()); | 318 VerifyValidSlotsBufferEntries(heap, heap->old_space()); |
| 323 VerifyValidSlotsBufferEntries(heap, heap->code_space()); | 319 VerifyValidSlotsBufferEntries(heap, heap->code_space()); |
| 324 VerifyValidSlotsBufferEntries(heap, heap->cell_space()); | |
| 325 VerifyValidSlotsBufferEntries(heap, heap->map_space()); | 320 VerifyValidSlotsBufferEntries(heap, heap->map_space()); |
| 326 | 321 |
| 327 LargeObjectIterator it(heap->lo_space()); | 322 LargeObjectIterator it(heap->lo_space()); |
| 328 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) { | 323 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) { |
| 329 MemoryChunk* chunk = MemoryChunk::FromAddress(object->address()); | 324 MemoryChunk* chunk = MemoryChunk::FromAddress(object->address()); |
| 330 SlotsBuffer::VerifySlots(heap, chunk->slots_buffer()); | 325 SlotsBuffer::VerifySlots(heap, chunk->slots_buffer()); |
| 331 } | 326 } |
| 332 } | 327 } |
| 333 #endif | 328 #endif |
| 334 | 329 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 NewSpacePage* p = it.next(); | 400 NewSpacePage* p = it.next(); |
| 406 CHECK(p->markbits()->IsClean()); | 401 CHECK(p->markbits()->IsClean()); |
| 407 CHECK_EQ(0, p->LiveBytes()); | 402 CHECK_EQ(0, p->LiveBytes()); |
| 408 } | 403 } |
| 409 } | 404 } |
| 410 | 405 |
| 411 | 406 |
| 412 void MarkCompactCollector::VerifyMarkbitsAreClean() { | 407 void MarkCompactCollector::VerifyMarkbitsAreClean() { |
| 413 VerifyMarkbitsAreClean(heap_->old_space()); | 408 VerifyMarkbitsAreClean(heap_->old_space()); |
| 414 VerifyMarkbitsAreClean(heap_->code_space()); | 409 VerifyMarkbitsAreClean(heap_->code_space()); |
| 415 VerifyMarkbitsAreClean(heap_->cell_space()); | |
| 416 VerifyMarkbitsAreClean(heap_->map_space()); | 410 VerifyMarkbitsAreClean(heap_->map_space()); |
| 417 VerifyMarkbitsAreClean(heap_->new_space()); | 411 VerifyMarkbitsAreClean(heap_->new_space()); |
| 418 | 412 |
| 419 LargeObjectIterator it(heap_->lo_space()); | 413 LargeObjectIterator it(heap_->lo_space()); |
| 420 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { | 414 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { |
| 421 MarkBit mark_bit = Marking::MarkBitFrom(obj); | 415 MarkBit mark_bit = Marking::MarkBitFrom(obj); |
| 422 CHECK(Marking::IsWhite(mark_bit)); | 416 CHECK(Marking::IsWhite(mark_bit)); |
| 423 CHECK_EQ(0, Page::FromAddress(obj->address())->LiveBytes()); | 417 CHECK_EQ(0, Page::FromAddress(obj->address())->LiveBytes()); |
| 424 } | 418 } |
| 425 } | 419 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 while (it.has_next()) { | 456 while (it.has_next()) { |
| 463 Bitmap::Clear(it.next()); | 457 Bitmap::Clear(it.next()); |
| 464 } | 458 } |
| 465 } | 459 } |
| 466 | 460 |
| 467 | 461 |
| 468 void MarkCompactCollector::ClearMarkbits() { | 462 void MarkCompactCollector::ClearMarkbits() { |
| 469 ClearMarkbitsInPagedSpace(heap_->code_space()); | 463 ClearMarkbitsInPagedSpace(heap_->code_space()); |
| 470 ClearMarkbitsInPagedSpace(heap_->map_space()); | 464 ClearMarkbitsInPagedSpace(heap_->map_space()); |
| 471 ClearMarkbitsInPagedSpace(heap_->old_space()); | 465 ClearMarkbitsInPagedSpace(heap_->old_space()); |
| 472 ClearMarkbitsInPagedSpace(heap_->cell_space()); | |
| 473 ClearMarkbitsInNewSpace(heap_->new_space()); | 466 ClearMarkbitsInNewSpace(heap_->new_space()); |
| 474 | 467 |
| 475 LargeObjectIterator it(heap_->lo_space()); | 468 LargeObjectIterator it(heap_->lo_space()); |
| 476 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { | 469 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { |
| 477 Marking::MarkWhite(Marking::MarkBitFrom(obj)); | 470 Marking::MarkWhite(Marking::MarkBitFrom(obj)); |
| 478 Page::FromAddress(obj->address())->ResetProgressBar(); | 471 Page::FromAddress(obj->address())->ResetProgressBar(); |
| 479 Page::FromAddress(obj->address())->ResetLiveBytes(); | 472 Page::FromAddress(obj->address())->ResetLiveBytes(); |
| 480 } | 473 } |
| 481 } | 474 } |
| 482 | 475 |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 629 const char* AllocationSpaceName(AllocationSpace space) { | 622 const char* AllocationSpaceName(AllocationSpace space) { |
| 630 switch (space) { | 623 switch (space) { |
| 631 case NEW_SPACE: | 624 case NEW_SPACE: |
| 632 return "NEW_SPACE"; | 625 return "NEW_SPACE"; |
| 633 case OLD_SPACE: | 626 case OLD_SPACE: |
| 634 return "OLD_SPACE"; | 627 return "OLD_SPACE"; |
| 635 case CODE_SPACE: | 628 case CODE_SPACE: |
| 636 return "CODE_SPACE"; | 629 return "CODE_SPACE"; |
| 637 case MAP_SPACE: | 630 case MAP_SPACE: |
| 638 return "MAP_SPACE"; | 631 return "MAP_SPACE"; |
| 639 case CELL_SPACE: | |
| 640 return "CELL_SPACE"; | |
| 641 case LO_SPACE: | 632 case LO_SPACE: |
| 642 return "LO_SPACE"; | 633 return "LO_SPACE"; |
| 643 default: | 634 default: |
| 644 UNREACHABLE(); | 635 UNREACHABLE(); |
| 645 } | 636 } |
| 646 | 637 |
| 647 return NULL; | 638 return NULL; |
| 648 } | 639 } |
| 649 | 640 |
| 650 | 641 |
| (...skipping 1461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2112 | 2103 |
| 2113 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->old_space()); | 2104 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->old_space()); |
| 2114 if (marking_deque_.IsFull()) return; | 2105 if (marking_deque_.IsFull()) return; |
| 2115 | 2106 |
| 2116 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->code_space()); | 2107 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->code_space()); |
| 2117 if (marking_deque_.IsFull()) return; | 2108 if (marking_deque_.IsFull()) return; |
| 2118 | 2109 |
| 2119 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->map_space()); | 2110 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->map_space()); |
| 2120 if (marking_deque_.IsFull()) return; | 2111 if (marking_deque_.IsFull()) return; |
| 2121 | 2112 |
| 2122 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->cell_space()); | |
| 2123 if (marking_deque_.IsFull()) return; | |
| 2124 | |
| 2125 LargeObjectIterator lo_it(heap()->lo_space()); | 2113 LargeObjectIterator lo_it(heap()->lo_space()); |
| 2126 DiscoverGreyObjectsWithIterator(heap(), &marking_deque_, &lo_it); | 2114 DiscoverGreyObjectsWithIterator(heap(), &marking_deque_, &lo_it); |
| 2127 if (marking_deque_.IsFull()) return; | 2115 if (marking_deque_.IsFull()) return; |
| 2128 | 2116 |
| 2129 marking_deque_.ClearOverflowed(); | 2117 marking_deque_.ClearOverflowed(); |
| 2130 } | 2118 } |
| 2131 | 2119 |
| 2132 | 2120 |
| 2133 // Mark all objects reachable (transitively) from objects on the marking | 2121 // Mark all objects reachable (transitively) from objects on the marking |
| 2134 // stack. Before: the marking stack contains zero or more heap object | 2122 // stack. Before: the marking stack contains zero or more heap object |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2305 | 2293 |
| 2306 #ifdef DEBUG | 2294 #ifdef DEBUG |
| 2307 DCHECK(state_ == PREPARE_GC); | 2295 DCHECK(state_ == PREPARE_GC); |
| 2308 state_ = MARK_LIVE_OBJECTS; | 2296 state_ = MARK_LIVE_OBJECTS; |
| 2309 #endif | 2297 #endif |
| 2310 | 2298 |
| 2311 EnsureMarkingDequeIsCommittedAndInitialize(); | 2299 EnsureMarkingDequeIsCommittedAndInitialize(); |
| 2312 | 2300 |
| 2313 PrepareForCodeFlushing(); | 2301 PrepareForCodeFlushing(); |
| 2314 | 2302 |
| 2315 if (was_marked_incrementally_) { | |
| 2316 // There is no write barrier on cells so we have to scan them now at the end | |
| 2317 // of the incremental marking. | |
| 2318 { | |
| 2319 HeapObjectIterator cell_iterator(heap()->cell_space()); | |
| 2320 HeapObject* cell; | |
| 2321 while ((cell = cell_iterator.Next()) != NULL) { | |
| 2322 DCHECK(cell->IsCell()); | |
| 2323 if (IsMarked(cell)) { | |
| 2324 int offset = Cell::kValueOffset; | |
| 2325 MarkCompactMarkingVisitor::VisitPointer( | |
| 2326 heap(), reinterpret_cast<Object**>(cell->address() + offset)); | |
| 2327 } | |
| 2328 } | |
| 2329 } | |
| 2330 } | |
| 2331 | |
| 2332 RootMarkingVisitor root_visitor(heap()); | 2303 RootMarkingVisitor root_visitor(heap()); |
| 2333 MarkRoots(&root_visitor); | 2304 MarkRoots(&root_visitor); |
| 2334 | 2305 |
| 2335 ProcessTopOptimizedFrame(&root_visitor); | 2306 ProcessTopOptimizedFrame(&root_visitor); |
| 2336 | 2307 |
| 2337 // Retaining dying maps should happen before or during ephemeral marking | 2308 // Retaining dying maps should happen before or during ephemeral marking |
| 2338 // because a map could keep the key of an ephemeron alive. Note that map | 2309 // because a map could keep the key of an ephemeron alive. Note that map |
| 2339 // aging is imprecise: maps that are kept alive only by ephemerons will age. | 2310 // aging is imprecise: maps that are kept alive only by ephemerons will age. |
| 2340 RetainMaps(); | 2311 RetainMaps(); |
| 2341 | 2312 |
| (...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2874 class PointersUpdatingVisitor : public ObjectVisitor { | 2845 class PointersUpdatingVisitor : public ObjectVisitor { |
| 2875 public: | 2846 public: |
| 2876 explicit PointersUpdatingVisitor(Heap* heap) : heap_(heap) {} | 2847 explicit PointersUpdatingVisitor(Heap* heap) : heap_(heap) {} |
| 2877 | 2848 |
| 2878 void VisitPointer(Object** p) { UpdatePointer(p); } | 2849 void VisitPointer(Object** p) { UpdatePointer(p); } |
| 2879 | 2850 |
| 2880 void VisitPointers(Object** start, Object** end) { | 2851 void VisitPointers(Object** start, Object** end) { |
| 2881 for (Object** p = start; p < end; p++) UpdatePointer(p); | 2852 for (Object** p = start; p < end; p++) UpdatePointer(p); |
| 2882 } | 2853 } |
| 2883 | 2854 |
| 2855 void VisitCell(RelocInfo* rinfo) { |
| 2856 DCHECK(rinfo->rmode() == RelocInfo::CELL); |
| 2857 Object* cell = rinfo->target_cell(); |
| 2858 Object* old_cell = cell; |
| 2859 VisitPointer(&cell); |
| 2860 if (cell != old_cell) { |
| 2861 rinfo->set_target_cell(reinterpret_cast<Cell*>(cell)); |
| 2862 } |
| 2863 } |
| 2864 |
| 2884 void VisitEmbeddedPointer(RelocInfo* rinfo) { | 2865 void VisitEmbeddedPointer(RelocInfo* rinfo) { |
| 2885 DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); | 2866 DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); |
| 2886 Object* target = rinfo->target_object(); | 2867 Object* target = rinfo->target_object(); |
| 2887 Object* old_target = target; | 2868 Object* old_target = target; |
| 2888 VisitPointer(&target); | 2869 VisitPointer(&target); |
| 2889 // Avoid unnecessary changes that might unnecessary flush the instruction | 2870 // Avoid unnecessary changes that might unnecessary flush the instruction |
| 2890 // cache. | 2871 // cache. |
| 2891 if (target != old_target) { | 2872 if (target != old_target) { |
| 2892 rinfo->set_target_object(target); | 2873 rinfo->set_target_object(target); |
| 2893 } | 2874 } |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2982 if (heap->new_space()->ToSpaceContains(slot_address)) { | 2963 if (heap->new_space()->ToSpaceContains(slot_address)) { |
| 2983 space_owner_id = 1; | 2964 space_owner_id = 1; |
| 2984 } else if (heap->new_space()->FromSpaceContains(slot_address)) { | 2965 } else if (heap->new_space()->FromSpaceContains(slot_address)) { |
| 2985 space_owner_id = 2; | 2966 space_owner_id = 2; |
| 2986 } else if (heap->old_space()->ContainsSafe(slot_address)) { | 2967 } else if (heap->old_space()->ContainsSafe(slot_address)) { |
| 2987 space_owner_id = 3; | 2968 space_owner_id = 3; |
| 2988 } else if (heap->code_space()->ContainsSafe(slot_address)) { | 2969 } else if (heap->code_space()->ContainsSafe(slot_address)) { |
| 2989 space_owner_id = 4; | 2970 space_owner_id = 4; |
| 2990 } else if (heap->map_space()->ContainsSafe(slot_address)) { | 2971 } else if (heap->map_space()->ContainsSafe(slot_address)) { |
| 2991 space_owner_id = 5; | 2972 space_owner_id = 5; |
| 2992 } else if (heap->cell_space()->ContainsSafe(slot_address)) { | |
| 2993 space_owner_id = 6; | |
| 2994 } else { | 2973 } else { |
| 2995 // Lo space or other. | 2974 // Lo space or other. |
| 2996 space_owner_id = 7; | 2975 space_owner_id = 6; |
| 2997 } | 2976 } |
| 2998 data[index++] = space_owner_id; | 2977 data[index++] = space_owner_id; |
| 2999 data[index++] = 0x20aaaaaaaaUL; | 2978 data[index++] = 0x20aaaaaaaaUL; |
| 3000 | 2979 |
| 3001 // Find map word lying near before the slot address (usually the map word is | 2980 // Find map word lying near before the slot address (usually the map word is |
| 3002 // at -3 words from the slot but just in case we look up further. | 2981 // at -3 words from the slot but just in case we look up further. |
| 3003 Object** map_slot = slot; | 2982 Object** map_slot = slot; |
| 3004 bool found = false; | 2983 bool found = false; |
| 3005 const int kMaxDistanceToMap = 64; | 2984 const int kMaxDistanceToMap = 64; |
| 3006 for (int i = 0; i < kMaxDistanceToMap; i++, map_slot--) { | 2985 for (int i = 0; i < kMaxDistanceToMap; i++, map_slot--) { |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3415 | 3394 |
| 3416 | 3395 |
| 3417 static inline void UpdateSlot(Isolate* isolate, ObjectVisitor* v, | 3396 static inline void UpdateSlot(Isolate* isolate, ObjectVisitor* v, |
| 3418 SlotsBuffer::SlotType slot_type, Address addr) { | 3397 SlotsBuffer::SlotType slot_type, Address addr) { |
| 3419 switch (slot_type) { | 3398 switch (slot_type) { |
| 3420 case SlotsBuffer::CODE_TARGET_SLOT: { | 3399 case SlotsBuffer::CODE_TARGET_SLOT: { |
| 3421 RelocInfo rinfo(addr, RelocInfo::CODE_TARGET, 0, NULL); | 3400 RelocInfo rinfo(addr, RelocInfo::CODE_TARGET, 0, NULL); |
| 3422 rinfo.Visit(isolate, v); | 3401 rinfo.Visit(isolate, v); |
| 3423 break; | 3402 break; |
| 3424 } | 3403 } |
| 3404 case SlotsBuffer::CELL_TARGET_SLOT: { |
| 3405 RelocInfo rinfo(addr, RelocInfo::CELL, 0, NULL); |
| 3406 rinfo.Visit(isolate, v); |
| 3407 break; |
| 3408 } |
| 3425 case SlotsBuffer::CODE_ENTRY_SLOT: { | 3409 case SlotsBuffer::CODE_ENTRY_SLOT: { |
| 3426 v->VisitCodeEntry(addr); | 3410 v->VisitCodeEntry(addr); |
| 3427 break; | 3411 break; |
| 3428 } | 3412 } |
| 3429 case SlotsBuffer::RELOCATED_CODE_OBJECT: { | 3413 case SlotsBuffer::RELOCATED_CODE_OBJECT: { |
| 3430 HeapObject* obj = HeapObject::FromAddress(addr); | 3414 HeapObject* obj = HeapObject::FromAddress(addr); |
| 3431 Code::cast(obj)->CodeIterateBody(v); | 3415 Code::cast(obj)->CodeIterateBody(v); |
| 3432 break; | 3416 break; |
| 3433 } | 3417 } |
| 3434 case SlotsBuffer::DEBUG_TARGET_SLOT: { | 3418 case SlotsBuffer::DEBUG_TARGET_SLOT: { |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3799 UNREACHABLE(); | 3783 UNREACHABLE(); |
| 3800 break; | 3784 break; |
| 3801 } | 3785 } |
| 3802 } | 3786 } |
| 3803 } | 3787 } |
| 3804 } | 3788 } |
| 3805 | 3789 |
| 3806 GCTracer::Scope gc_scope(heap()->tracer(), | 3790 GCTracer::Scope gc_scope(heap()->tracer(), |
| 3807 GCTracer::Scope::MC_UPDATE_MISC_POINTERS); | 3791 GCTracer::Scope::MC_UPDATE_MISC_POINTERS); |
| 3808 | 3792 |
| 3809 // Update pointers from cells. | |
| 3810 HeapObjectIterator cell_iterator(heap_->cell_space()); | |
| 3811 for (HeapObject* cell = cell_iterator.Next(); cell != NULL; | |
| 3812 cell = cell_iterator.Next()) { | |
| 3813 if (cell->IsCell()) { | |
| 3814 Cell::BodyDescriptor::IterateBody(cell, &updating_visitor); | |
| 3815 } | |
| 3816 } | |
| 3817 | |
| 3818 heap_->string_table()->Iterate(&updating_visitor); | 3793 heap_->string_table()->Iterate(&updating_visitor); |
| 3819 | 3794 |
| 3820 // Update pointers from external string table. | 3795 // Update pointers from external string table. |
| 3821 heap_->UpdateReferencesInExternalStringTable( | 3796 heap_->UpdateReferencesInExternalStringTable( |
| 3822 &UpdateReferenceInExternalStringTableEntry); | 3797 &UpdateReferenceInExternalStringTableEntry); |
| 3823 | 3798 |
| 3824 EvacuationWeakObjectRetainer evacuation_object_retainer; | 3799 EvacuationWeakObjectRetainer evacuation_object_retainer; |
| 3825 heap()->ProcessAllWeakReferences(&evacuation_object_retainer); | 3800 heap()->ProcessAllWeakReferences(&evacuation_object_retainer); |
| 3826 | 3801 |
| 3827 // Collects callback info for handles that are pending (about to be | 3802 // Collects callback info for handles that are pending (about to be |
| (...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4422 } | 4397 } |
| 4423 } | 4398 } |
| 4424 RemoveDeadInvalidatedCode(); | 4399 RemoveDeadInvalidatedCode(); |
| 4425 | 4400 |
| 4426 { | 4401 { |
| 4427 GCTracer::Scope sweep_scope(heap()->tracer(), | 4402 GCTracer::Scope sweep_scope(heap()->tracer(), |
| 4428 GCTracer::Scope::MC_SWEEP_CODE); | 4403 GCTracer::Scope::MC_SWEEP_CODE); |
| 4429 SweepSpace(heap()->code_space(), SEQUENTIAL_SWEEPING); | 4404 SweepSpace(heap()->code_space(), SEQUENTIAL_SWEEPING); |
| 4430 } | 4405 } |
| 4431 | 4406 |
| 4432 { | |
| 4433 GCTracer::Scope sweep_scope(heap()->tracer(), | |
| 4434 GCTracer::Scope::MC_SWEEP_CELL); | |
| 4435 SweepSpace(heap()->cell_space(), SEQUENTIAL_SWEEPING); | |
| 4436 } | |
| 4437 | |
| 4438 EvacuateNewSpaceAndCandidates(); | 4407 EvacuateNewSpaceAndCandidates(); |
| 4439 | 4408 |
| 4440 // ClearNonLiveReferences depends on precise sweeping of map space to | 4409 // ClearNonLiveReferences depends on precise sweeping of map space to |
| 4441 // detect whether unmarked map became dead in this collection or in one | 4410 // detect whether unmarked map became dead in this collection or in one |
| 4442 // of the previous ones. | 4411 // of the previous ones. |
| 4443 { | 4412 { |
| 4444 GCTracer::Scope sweep_scope(heap()->tracer(), | 4413 GCTracer::Scope sweep_scope(heap()->tracer(), |
| 4445 GCTracer::Scope::MC_SWEEP_MAP); | 4414 GCTracer::Scope::MC_SWEEP_MAP); |
| 4446 SweepSpace(heap()->map_space(), SEQUENTIAL_SWEEPING); | 4415 SweepSpace(heap()->map_space(), SEQUENTIAL_SWEEPING); |
| 4447 } | 4416 } |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4606 } | 4575 } |
| 4607 } | 4576 } |
| 4608 buffer = buffer->next(); | 4577 buffer = buffer->next(); |
| 4609 } | 4578 } |
| 4610 } | 4579 } |
| 4611 | 4580 |
| 4612 | 4581 |
| 4613 static inline SlotsBuffer::SlotType SlotTypeForRMode(RelocInfo::Mode rmode) { | 4582 static inline SlotsBuffer::SlotType SlotTypeForRMode(RelocInfo::Mode rmode) { |
| 4614 if (RelocInfo::IsCodeTarget(rmode)) { | 4583 if (RelocInfo::IsCodeTarget(rmode)) { |
| 4615 return SlotsBuffer::CODE_TARGET_SLOT; | 4584 return SlotsBuffer::CODE_TARGET_SLOT; |
| 4585 } else if (RelocInfo::IsCell(rmode)) { |
| 4586 return SlotsBuffer::CELL_TARGET_SLOT; |
| 4616 } else if (RelocInfo::IsEmbeddedObject(rmode)) { | 4587 } else if (RelocInfo::IsEmbeddedObject(rmode)) { |
| 4617 return SlotsBuffer::EMBEDDED_OBJECT_SLOT; | 4588 return SlotsBuffer::EMBEDDED_OBJECT_SLOT; |
| 4618 } else if (RelocInfo::IsDebugBreakSlot(rmode)) { | 4589 } else if (RelocInfo::IsDebugBreakSlot(rmode)) { |
| 4619 return SlotsBuffer::DEBUG_TARGET_SLOT; | 4590 return SlotsBuffer::DEBUG_TARGET_SLOT; |
| 4620 } else if (RelocInfo::IsJSReturn(rmode)) { | 4591 } else if (RelocInfo::IsJSReturn(rmode)) { |
| 4621 return SlotsBuffer::JS_RETURN_SLOT; | 4592 return SlotsBuffer::JS_RETURN_SLOT; |
| 4622 } | 4593 } |
| 4623 UNREACHABLE(); | 4594 UNREACHABLE(); |
| 4624 return SlotsBuffer::NUMBER_OF_SLOT_TYPES; | 4595 return SlotsBuffer::NUMBER_OF_SLOT_TYPES; |
| 4625 } | 4596 } |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4764 SlotsBuffer* buffer = *buffer_address; | 4735 SlotsBuffer* buffer = *buffer_address; |
| 4765 while (buffer != NULL) { | 4736 while (buffer != NULL) { |
| 4766 SlotsBuffer* next_buffer = buffer->next(); | 4737 SlotsBuffer* next_buffer = buffer->next(); |
| 4767 DeallocateBuffer(buffer); | 4738 DeallocateBuffer(buffer); |
| 4768 buffer = next_buffer; | 4739 buffer = next_buffer; |
| 4769 } | 4740 } |
| 4770 *buffer_address = NULL; | 4741 *buffer_address = NULL; |
| 4771 } | 4742 } |
| 4772 } | 4743 } |
| 4773 } // namespace v8::internal | 4744 } // namespace v8::internal |
| OLD | NEW |