| 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 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 PageIterator it(space); | 128 PageIterator it(space); |
| 129 | 129 |
| 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_pointer_space()); |
| 139 VerifyMarking(heap->old_data_space()); |
| 139 VerifyMarking(heap->code_space()); | 140 VerifyMarking(heap->code_space()); |
| 140 VerifyMarking(heap->cell_space()); | 141 VerifyMarking(heap->cell_space()); |
| 141 VerifyMarking(heap->map_space()); | 142 VerifyMarking(heap->map_space()); |
| 142 VerifyMarking(heap->new_space()); | 143 VerifyMarking(heap->new_space()); |
| 143 | 144 |
| 144 VerifyMarkingVisitor visitor(heap); | 145 VerifyMarkingVisitor visitor(heap); |
| 145 | 146 |
| 146 LargeObjectIterator it(heap->lo_space()); | 147 LargeObjectIterator it(heap->lo_space()); |
| 147 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { | 148 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { |
| 148 if (MarkCompactCollector::IsMarked(obj)) { | 149 if (MarkCompactCollector::IsMarked(obj)) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 while (current < limit) { | 193 while (current < limit) { |
| 193 HeapObject* object = HeapObject::FromAddress(current); | 194 HeapObject* object = HeapObject::FromAddress(current); |
| 194 object->Iterate(&visitor); | 195 object->Iterate(&visitor); |
| 195 current += object->Size(); | 196 current += object->Size(); |
| 196 } | 197 } |
| 197 } | 198 } |
| 198 } | 199 } |
| 199 | 200 |
| 200 | 201 |
| 201 static void VerifyEvacuation(Heap* heap, PagedSpace* space) { | 202 static void VerifyEvacuation(Heap* heap, PagedSpace* space) { |
| 202 if (FLAG_use_allocation_folding && (space == heap->old_space())) { | 203 if (FLAG_use_allocation_folding && |
| 204 (space == heap->old_pointer_space() || space == heap->old_data_space())) { |
| 203 return; | 205 return; |
| 204 } | 206 } |
| 205 PageIterator it(space); | 207 PageIterator it(space); |
| 206 | 208 |
| 207 while (it.has_next()) { | 209 while (it.has_next()) { |
| 208 Page* p = it.next(); | 210 Page* p = it.next(); |
| 209 if (p->IsEvacuationCandidate()) continue; | 211 if (p->IsEvacuationCandidate()) continue; |
| 210 VerifyEvacuation(p); | 212 VerifyEvacuation(p); |
| 211 } | 213 } |
| 212 } | 214 } |
| 213 | 215 |
| 214 | 216 |
| 215 static void VerifyEvacuation(Heap* heap) { | 217 static void VerifyEvacuation(Heap* heap) { |
| 216 VerifyEvacuation(heap, heap->old_space()); | 218 VerifyEvacuation(heap, heap->old_pointer_space()); |
| 219 VerifyEvacuation(heap, heap->old_data_space()); |
| 217 VerifyEvacuation(heap, heap->code_space()); | 220 VerifyEvacuation(heap, heap->code_space()); |
| 218 VerifyEvacuation(heap, heap->cell_space()); | 221 VerifyEvacuation(heap, heap->cell_space()); |
| 219 VerifyEvacuation(heap, heap->map_space()); | 222 VerifyEvacuation(heap, heap->map_space()); |
| 220 VerifyEvacuation(heap->new_space()); | 223 VerifyEvacuation(heap->new_space()); |
| 221 | 224 |
| 222 VerifyEvacuationVisitor visitor; | 225 VerifyEvacuationVisitor visitor; |
| 223 heap->IterateStrongRoots(&visitor, VISIT_ALL); | 226 heap->IterateStrongRoots(&visitor, VISIT_ALL); |
| 224 } | 227 } |
| 225 #endif // VERIFY_HEAP | 228 #endif // VERIFY_HEAP |
| 226 | 229 |
| 227 | 230 |
| 228 void MarkCompactCollector::SetUp() { | 231 void MarkCompactCollector::SetUp() { |
| 229 free_list_old_space_.Reset(new FreeList(heap_->old_space())); | 232 free_list_old_data_space_.Reset(new FreeList(heap_->old_data_space())); |
| 233 free_list_old_pointer_space_.Reset(new FreeList(heap_->old_pointer_space())); |
| 230 } | 234 } |
| 231 | 235 |
| 232 | 236 |
| 233 void MarkCompactCollector::TearDown() { | 237 void MarkCompactCollector::TearDown() { |
| 234 AbortCompaction(); | 238 AbortCompaction(); |
| 235 delete marking_deque_memory_; | 239 delete marking_deque_memory_; |
| 236 } | 240 } |
| 237 | 241 |
| 238 | 242 |
| 239 void MarkCompactCollector::AddEvacuationCandidate(Page* p) { | 243 void MarkCompactCollector::AddEvacuationCandidate(Page* p) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 250 PrintF("[%s]: %d pages, %d (%.1f%%) free\n", | 254 PrintF("[%s]: %d pages, %d (%.1f%%) free\n", |
| 251 AllocationSpaceName(space->identity()), number_of_pages, | 255 AllocationSpaceName(space->identity()), number_of_pages, |
| 252 static_cast<int>(free), static_cast<double>(free) * 100 / reserved); | 256 static_cast<int>(free), static_cast<double>(free) * 100 / reserved); |
| 253 } | 257 } |
| 254 | 258 |
| 255 | 259 |
| 256 bool MarkCompactCollector::StartCompaction(CompactionMode mode) { | 260 bool MarkCompactCollector::StartCompaction(CompactionMode mode) { |
| 257 if (!compacting_) { | 261 if (!compacting_) { |
| 258 DCHECK(evacuation_candidates_.length() == 0); | 262 DCHECK(evacuation_candidates_.length() == 0); |
| 259 | 263 |
| 260 CollectEvacuationCandidates(heap()->old_space()); | 264 CollectEvacuationCandidates(heap()->old_pointer_space()); |
| 265 CollectEvacuationCandidates(heap()->old_data_space()); |
| 261 | 266 |
| 262 if (FLAG_compact_code_space && (mode == NON_INCREMENTAL_COMPACTION || | 267 if (FLAG_compact_code_space && (mode == NON_INCREMENTAL_COMPACTION || |
| 263 FLAG_incremental_code_compaction)) { | 268 FLAG_incremental_code_compaction)) { |
| 264 CollectEvacuationCandidates(heap()->code_space()); | 269 CollectEvacuationCandidates(heap()->code_space()); |
| 265 } else if (FLAG_trace_fragmentation) { | 270 } else if (FLAG_trace_fragmentation) { |
| 266 TraceFragmentation(heap()->code_space()); | 271 TraceFragmentation(heap()->code_space()); |
| 267 } | 272 } |
| 268 | 273 |
| 269 if (FLAG_trace_fragmentation) { | 274 if (FLAG_trace_fragmentation) { |
| 270 TraceFragmentation(heap()->map_space()); | 275 TraceFragmentation(heap()->map_space()); |
| 271 TraceFragmentation(heap()->cell_space()); | 276 TraceFragmentation(heap()->cell_space()); |
| 272 } | 277 } |
| 273 | 278 |
| 274 heap()->old_space()->EvictEvacuationCandidatesFromFreeLists(); | 279 heap()->old_pointer_space()->EvictEvacuationCandidatesFromFreeLists(); |
| 280 heap()->old_data_space()->EvictEvacuationCandidatesFromFreeLists(); |
| 275 heap()->code_space()->EvictEvacuationCandidatesFromFreeLists(); | 281 heap()->code_space()->EvictEvacuationCandidatesFromFreeLists(); |
| 276 | 282 |
| 277 compacting_ = evacuation_candidates_.length() > 0; | 283 compacting_ = evacuation_candidates_.length() > 0; |
| 278 } | 284 } |
| 279 | 285 |
| 280 return compacting_; | 286 return compacting_; |
| 281 } | 287 } |
| 282 | 288 |
| 283 | 289 |
| 284 void MarkCompactCollector::CollectGarbage() { | 290 void MarkCompactCollector::CollectGarbage() { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 | 357 |
| 352 while (it.has_next()) { | 358 while (it.has_next()) { |
| 353 NewSpacePage* p = it.next(); | 359 NewSpacePage* p = it.next(); |
| 354 CHECK(p->markbits()->IsClean()); | 360 CHECK(p->markbits()->IsClean()); |
| 355 CHECK_EQ(0, p->LiveBytes()); | 361 CHECK_EQ(0, p->LiveBytes()); |
| 356 } | 362 } |
| 357 } | 363 } |
| 358 | 364 |
| 359 | 365 |
| 360 void MarkCompactCollector::VerifyMarkbitsAreClean() { | 366 void MarkCompactCollector::VerifyMarkbitsAreClean() { |
| 361 VerifyMarkbitsAreClean(heap_->old_space()); | 367 VerifyMarkbitsAreClean(heap_->old_pointer_space()); |
| 368 VerifyMarkbitsAreClean(heap_->old_data_space()); |
| 362 VerifyMarkbitsAreClean(heap_->code_space()); | 369 VerifyMarkbitsAreClean(heap_->code_space()); |
| 363 VerifyMarkbitsAreClean(heap_->cell_space()); | 370 VerifyMarkbitsAreClean(heap_->cell_space()); |
| 364 VerifyMarkbitsAreClean(heap_->map_space()); | 371 VerifyMarkbitsAreClean(heap_->map_space()); |
| 365 VerifyMarkbitsAreClean(heap_->new_space()); | 372 VerifyMarkbitsAreClean(heap_->new_space()); |
| 366 | 373 |
| 367 LargeObjectIterator it(heap_->lo_space()); | 374 LargeObjectIterator it(heap_->lo_space()); |
| 368 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { | 375 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { |
| 369 MarkBit mark_bit = Marking::MarkBitFrom(obj); | 376 MarkBit mark_bit = Marking::MarkBitFrom(obj); |
| 370 CHECK(Marking::IsWhite(mark_bit)); | 377 CHECK(Marking::IsWhite(mark_bit)); |
| 371 CHECK_EQ(0, Page::FromAddress(obj->address())->LiveBytes()); | 378 CHECK_EQ(0, Page::FromAddress(obj->address())->LiveBytes()); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 409 | 416 |
| 410 while (it.has_next()) { | 417 while (it.has_next()) { |
| 411 Bitmap::Clear(it.next()); | 418 Bitmap::Clear(it.next()); |
| 412 } | 419 } |
| 413 } | 420 } |
| 414 | 421 |
| 415 | 422 |
| 416 void MarkCompactCollector::ClearMarkbits() { | 423 void MarkCompactCollector::ClearMarkbits() { |
| 417 ClearMarkbitsInPagedSpace(heap_->code_space()); | 424 ClearMarkbitsInPagedSpace(heap_->code_space()); |
| 418 ClearMarkbitsInPagedSpace(heap_->map_space()); | 425 ClearMarkbitsInPagedSpace(heap_->map_space()); |
| 419 ClearMarkbitsInPagedSpace(heap_->old_space()); | 426 ClearMarkbitsInPagedSpace(heap_->old_pointer_space()); |
| 427 ClearMarkbitsInPagedSpace(heap_->old_data_space()); |
| 420 ClearMarkbitsInPagedSpace(heap_->cell_space()); | 428 ClearMarkbitsInPagedSpace(heap_->cell_space()); |
| 421 ClearMarkbitsInNewSpace(heap_->new_space()); | 429 ClearMarkbitsInNewSpace(heap_->new_space()); |
| 422 | 430 |
| 423 LargeObjectIterator it(heap_->lo_space()); | 431 LargeObjectIterator it(heap_->lo_space()); |
| 424 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { | 432 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { |
| 425 MarkBit mark_bit = Marking::MarkBitFrom(obj); | 433 MarkBit mark_bit = Marking::MarkBitFrom(obj); |
| 426 mark_bit.Clear(); | 434 mark_bit.Clear(); |
| 427 mark_bit.Next().Clear(); | 435 mark_bit.Next().Clear(); |
| 428 Page::FromAddress(obj->address())->ResetProgressBar(); | 436 Page::FromAddress(obj->address())->ResetProgressBar(); |
| 429 Page::FromAddress(obj->address())->ResetLiveBytes(); | 437 Page::FromAddress(obj->address())->ResetLiveBytes(); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 445 } | 453 } |
| 446 | 454 |
| 447 Heap* heap_; | 455 Heap* heap_; |
| 448 PagedSpace* space_; | 456 PagedSpace* space_; |
| 449 | 457 |
| 450 DISALLOW_COPY_AND_ASSIGN(SweeperTask); | 458 DISALLOW_COPY_AND_ASSIGN(SweeperTask); |
| 451 }; | 459 }; |
| 452 | 460 |
| 453 | 461 |
| 454 void MarkCompactCollector::StartSweeperThreads() { | 462 void MarkCompactCollector::StartSweeperThreads() { |
| 455 DCHECK(free_list_old_space_.get()->IsEmpty()); | 463 DCHECK(free_list_old_pointer_space_.get()->IsEmpty()); |
| 464 DCHECK(free_list_old_data_space_.get()->IsEmpty()); |
| 456 V8::GetCurrentPlatform()->CallOnBackgroundThread( | 465 V8::GetCurrentPlatform()->CallOnBackgroundThread( |
| 457 new SweeperTask(heap(), heap()->old_space()), | 466 new SweeperTask(heap(), heap()->old_data_space()), |
| 467 v8::Platform::kShortRunningTask); |
| 468 V8::GetCurrentPlatform()->CallOnBackgroundThread( |
| 469 new SweeperTask(heap(), heap()->old_pointer_space()), |
| 458 v8::Platform::kShortRunningTask); | 470 v8::Platform::kShortRunningTask); |
| 459 } | 471 } |
| 460 | 472 |
| 461 | 473 |
| 462 void MarkCompactCollector::EnsureSweepingCompleted() { | 474 void MarkCompactCollector::EnsureSweepingCompleted() { |
| 463 DCHECK(sweeping_in_progress_ == true); | 475 DCHECK(sweeping_in_progress_ == true); |
| 464 | 476 |
| 465 // If sweeping is not completed or not running at all, we try to complete it | 477 // If sweeping is not completed or not running at all, we try to complete it |
| 466 // here. | 478 // here. |
| 467 if (!heap()->concurrent_sweeping_enabled() || !IsSweepingCompleted()) { | 479 if (!heap()->concurrent_sweeping_enabled() || !IsSweepingCompleted()) { |
| 468 SweepInParallel(heap()->paged_space(OLD_SPACE), 0); | 480 SweepInParallel(heap()->paged_space(OLD_DATA_SPACE), 0); |
| 481 SweepInParallel(heap()->paged_space(OLD_POINTER_SPACE), 0); |
| 469 } | 482 } |
| 470 // Wait twice for both jobs. | 483 // Wait twice for both jobs. |
| 471 if (heap()->concurrent_sweeping_enabled()) { | 484 if (heap()->concurrent_sweeping_enabled()) { |
| 472 pending_sweeper_jobs_semaphore_.Wait(); | 485 pending_sweeper_jobs_semaphore_.Wait(); |
| 486 pending_sweeper_jobs_semaphore_.Wait(); |
| 473 } | 487 } |
| 474 ParallelSweepSpacesComplete(); | 488 ParallelSweepSpacesComplete(); |
| 475 sweeping_in_progress_ = false; | 489 sweeping_in_progress_ = false; |
| 476 RefillFreeList(heap()->paged_space(OLD_SPACE)); | 490 RefillFreeList(heap()->paged_space(OLD_DATA_SPACE)); |
| 477 heap()->paged_space(OLD_SPACE)->ResetUnsweptFreeBytes(); | 491 RefillFreeList(heap()->paged_space(OLD_POINTER_SPACE)); |
| 492 heap()->paged_space(OLD_DATA_SPACE)->ResetUnsweptFreeBytes(); |
| 493 heap()->paged_space(OLD_POINTER_SPACE)->ResetUnsweptFreeBytes(); |
| 478 | 494 |
| 479 #ifdef VERIFY_HEAP | 495 #ifdef VERIFY_HEAP |
| 480 if (FLAG_verify_heap && !evacuation()) { | 496 if (FLAG_verify_heap && !evacuation()) { |
| 481 VerifyEvacuation(heap_); | 497 VerifyEvacuation(heap_); |
| 482 } | 498 } |
| 483 #endif | 499 #endif |
| 484 } | 500 } |
| 485 | 501 |
| 486 | 502 |
| 487 bool MarkCompactCollector::IsSweepingCompleted() { | 503 bool MarkCompactCollector::IsSweepingCompleted() { |
| 488 if (!pending_sweeper_jobs_semaphore_.WaitFor( | 504 if (!pending_sweeper_jobs_semaphore_.WaitFor( |
| 489 base::TimeDelta::FromSeconds(0))) { | 505 base::TimeDelta::FromSeconds(0))) { |
| 490 return false; | 506 return false; |
| 491 } | 507 } |
| 492 pending_sweeper_jobs_semaphore_.Signal(); | 508 pending_sweeper_jobs_semaphore_.Signal(); |
| 493 return true; | 509 return true; |
| 494 } | 510 } |
| 495 | 511 |
| 496 | 512 |
| 497 void MarkCompactCollector::RefillFreeList(PagedSpace* space) { | 513 void MarkCompactCollector::RefillFreeList(PagedSpace* space) { |
| 498 FreeList* free_list; | 514 FreeList* free_list; |
| 499 | 515 |
| 500 if (space == heap()->old_space()) { | 516 if (space == heap()->old_pointer_space()) { |
| 501 free_list = free_list_old_space_.get(); | 517 free_list = free_list_old_pointer_space_.get(); |
| 518 } else if (space == heap()->old_data_space()) { |
| 519 free_list = free_list_old_data_space_.get(); |
| 502 } else { | 520 } else { |
| 503 // Any PagedSpace might invoke RefillFreeLists, so we need to make sure | 521 // Any PagedSpace might invoke RefillFreeLists, so we need to make sure |
| 504 // to only refill them for the old space. | 522 // to only refill them for old data and pointer spaces. |
| 505 return; | 523 return; |
| 506 } | 524 } |
| 507 | 525 |
| 508 intptr_t freed_bytes = space->free_list()->Concatenate(free_list); | 526 intptr_t freed_bytes = space->free_list()->Concatenate(free_list); |
| 509 space->AddToAccountingStats(freed_bytes); | 527 space->AddToAccountingStats(freed_bytes); |
| 510 space->DecrementUnsweptFreeBytes(freed_bytes); | 528 space->DecrementUnsweptFreeBytes(freed_bytes); |
| 511 } | 529 } |
| 512 | 530 |
| 513 | 531 |
| 514 void Marking::TransferMark(Address old_start, Address new_start) { | 532 void Marking::TransferMark(Address old_start, Address new_start) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 548 ObjectColor new_color = Color(new_mark_bit); | 566 ObjectColor new_color = Color(new_mark_bit); |
| 549 DCHECK(new_color == old_color); | 567 DCHECK(new_color == old_color); |
| 550 #endif | 568 #endif |
| 551 } | 569 } |
| 552 | 570 |
| 553 | 571 |
| 554 const char* AllocationSpaceName(AllocationSpace space) { | 572 const char* AllocationSpaceName(AllocationSpace space) { |
| 555 switch (space) { | 573 switch (space) { |
| 556 case NEW_SPACE: | 574 case NEW_SPACE: |
| 557 return "NEW_SPACE"; | 575 return "NEW_SPACE"; |
| 558 case OLD_SPACE: | 576 case OLD_POINTER_SPACE: |
| 559 return "OLD_SPACE"; | 577 return "OLD_POINTER_SPACE"; |
| 578 case OLD_DATA_SPACE: |
| 579 return "OLD_DATA_SPACE"; |
| 560 case CODE_SPACE: | 580 case CODE_SPACE: |
| 561 return "CODE_SPACE"; | 581 return "CODE_SPACE"; |
| 562 case MAP_SPACE: | 582 case MAP_SPACE: |
| 563 return "MAP_SPACE"; | 583 return "MAP_SPACE"; |
| 564 case CELL_SPACE: | 584 case CELL_SPACE: |
| 565 return "CELL_SPACE"; | 585 return "CELL_SPACE"; |
| 566 case LO_SPACE: | 586 case LO_SPACE: |
| 567 return "LO_SPACE"; | 587 return "LO_SPACE"; |
| 568 default: | 588 default: |
| 569 UNREACHABLE(); | 589 UNREACHABLE(); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 618 return 1; | 638 return 1; |
| 619 } | 639 } |
| 620 | 640 |
| 621 if (ratio <= ratio_threshold) return 0; // Not fragmented. | 641 if (ratio <= ratio_threshold) return 0; // Not fragmented. |
| 622 | 642 |
| 623 return static_cast<int>(ratio - ratio_threshold); | 643 return static_cast<int>(ratio - ratio_threshold); |
| 624 } | 644 } |
| 625 | 645 |
| 626 | 646 |
| 627 void MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) { | 647 void MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) { |
| 628 DCHECK(space->identity() == OLD_SPACE || space->identity() == CODE_SPACE); | 648 DCHECK(space->identity() == OLD_POINTER_SPACE || |
| 649 space->identity() == OLD_DATA_SPACE || |
| 650 space->identity() == CODE_SPACE); |
| 629 | 651 |
| 630 static const int kMaxMaxEvacuationCandidates = 1000; | 652 static const int kMaxMaxEvacuationCandidates = 1000; |
| 631 int number_of_pages = space->CountTotalPages(); | 653 int number_of_pages = space->CountTotalPages(); |
| 632 int max_evacuation_candidates = | 654 int max_evacuation_candidates = |
| 633 static_cast<int>(std::sqrt(number_of_pages / 2.0) + 1); | 655 static_cast<int>(std::sqrt(number_of_pages / 2.0) + 1); |
| 634 | 656 |
| 635 if (FLAG_stress_compaction || FLAG_always_compact) { | 657 if (FLAG_stress_compaction || FLAG_always_compact) { |
| 636 max_evacuation_candidates = kMaxMaxEvacuationCandidates; | 658 max_evacuation_candidates = kMaxMaxEvacuationCandidates; |
| 637 } | 659 } |
| 638 | 660 |
| (...skipping 1145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1784 (next_cell << (Bitmap::kBitsPerCell - 1))); | 1806 (next_cell << (Bitmap::kBitsPerCell - 1))); |
| 1785 } else { | 1807 } else { |
| 1786 grey_objects = current_cell & (current_cell >> 1); | 1808 grey_objects = current_cell & (current_cell >> 1); |
| 1787 } | 1809 } |
| 1788 | 1810 |
| 1789 int offset = 0; | 1811 int offset = 0; |
| 1790 while (grey_objects != 0) { | 1812 while (grey_objects != 0) { |
| 1791 int trailing_zeros = base::bits::CountTrailingZeros32(grey_objects); | 1813 int trailing_zeros = base::bits::CountTrailingZeros32(grey_objects); |
| 1792 grey_objects >>= trailing_zeros; | 1814 grey_objects >>= trailing_zeros; |
| 1793 offset += trailing_zeros; | 1815 offset += trailing_zeros; |
| 1794 MarkBit markbit(cell, 1 << offset); | 1816 MarkBit markbit(cell, 1 << offset, false); |
| 1795 DCHECK(Marking::IsGrey(markbit)); | 1817 DCHECK(Marking::IsGrey(markbit)); |
| 1796 Marking::GreyToBlack(markbit); | 1818 Marking::GreyToBlack(markbit); |
| 1797 Address addr = cell_base + offset * kPointerSize; | 1819 Address addr = cell_base + offset * kPointerSize; |
| 1798 HeapObject* object = HeapObject::FromAddress(addr); | 1820 HeapObject* object = HeapObject::FromAddress(addr); |
| 1799 MemoryChunk::IncrementLiveBytesFromGC(object->address(), object->Size()); | 1821 MemoryChunk::IncrementLiveBytesFromGC(object->address(), object->Size()); |
| 1800 marking_deque->PushBlack(object); | 1822 marking_deque->PushBlack(object); |
| 1801 if (marking_deque->IsFull()) return; | 1823 if (marking_deque->IsFull()) return; |
| 1802 offset += 2; | 1824 offset += 2; |
| 1803 grey_objects >>= 2; | 1825 grey_objects >>= 2; |
| 1804 } | 1826 } |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2008 // push them on the marking stack. Stop early if the marking stack fills | 2030 // push them on the marking stack. Stop early if the marking stack fills |
| 2009 // before sweeping completes. If sweeping completes, there are no remaining | 2031 // before sweeping completes. If sweeping completes, there are no remaining |
| 2010 // overflowed objects in the heap so the overflow flag on the markings stack | 2032 // overflowed objects in the heap so the overflow flag on the markings stack |
| 2011 // is cleared. | 2033 // is cleared. |
| 2012 void MarkCompactCollector::RefillMarkingDeque() { | 2034 void MarkCompactCollector::RefillMarkingDeque() { |
| 2013 DCHECK(marking_deque_.overflowed()); | 2035 DCHECK(marking_deque_.overflowed()); |
| 2014 | 2036 |
| 2015 DiscoverGreyObjectsInNewSpace(heap(), &marking_deque_); | 2037 DiscoverGreyObjectsInNewSpace(heap(), &marking_deque_); |
| 2016 if (marking_deque_.IsFull()) return; | 2038 if (marking_deque_.IsFull()) return; |
| 2017 | 2039 |
| 2018 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->old_space()); | 2040 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, |
| 2041 heap()->old_pointer_space()); |
| 2042 if (marking_deque_.IsFull()) return; |
| 2043 |
| 2044 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->old_data_space()); |
| 2019 if (marking_deque_.IsFull()) return; | 2045 if (marking_deque_.IsFull()) return; |
| 2020 | 2046 |
| 2021 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->code_space()); | 2047 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->code_space()); |
| 2022 if (marking_deque_.IsFull()) return; | 2048 if (marking_deque_.IsFull()) return; |
| 2023 | 2049 |
| 2024 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->map_space()); | 2050 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->map_space()); |
| 2025 if (marking_deque_.IsFull()) return; | 2051 if (marking_deque_.IsFull()) return; |
| 2026 | 2052 |
| 2027 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->cell_space()); | 2053 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->cell_space()); |
| 2028 if (marking_deque_.IsFull()) return; | 2054 if (marking_deque_.IsFull()) return; |
| (...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2678 // to new space. We should clear them to avoid encountering them during next | 2704 // to new space. We should clear them to avoid encountering them during next |
| 2679 // pointer iteration. This is an issue if the store buffer overflows and we | 2705 // pointer iteration. This is an issue if the store buffer overflows and we |
| 2680 // have to scan the entire old space, including dead objects, looking for | 2706 // have to scan the entire old space, including dead objects, looking for |
| 2681 // pointers to new space. | 2707 // pointers to new space. |
| 2682 void MarkCompactCollector::MigrateObject(HeapObject* dst, HeapObject* src, | 2708 void MarkCompactCollector::MigrateObject(HeapObject* dst, HeapObject* src, |
| 2683 int size, AllocationSpace dest) { | 2709 int size, AllocationSpace dest) { |
| 2684 Address dst_addr = dst->address(); | 2710 Address dst_addr = dst->address(); |
| 2685 Address src_addr = src->address(); | 2711 Address src_addr = src->address(); |
| 2686 DCHECK(heap()->AllowedToBeMigrated(src, dest)); | 2712 DCHECK(heap()->AllowedToBeMigrated(src, dest)); |
| 2687 DCHECK(dest != LO_SPACE && size <= Page::kMaxRegularHeapObjectSize); | 2713 DCHECK(dest != LO_SPACE && size <= Page::kMaxRegularHeapObjectSize); |
| 2688 if (dest == OLD_SPACE) { | 2714 if (dest == OLD_POINTER_SPACE) { |
| 2689 Address src_slot = src_addr; | 2715 Address src_slot = src_addr; |
| 2690 Address dst_slot = dst_addr; | 2716 Address dst_slot = dst_addr; |
| 2691 DCHECK(IsAligned(size, kPointerSize)); | 2717 DCHECK(IsAligned(size, kPointerSize)); |
| 2692 | 2718 |
| 2693 bool may_contain_raw_values = src->MayContainRawValues(); | 2719 bool may_contain_raw_values = src->MayContainRawValues(); |
| 2694 #if V8_DOUBLE_FIELDS_UNBOXING | 2720 #if V8_DOUBLE_FIELDS_UNBOXING |
| 2695 LayoutDescriptorHelper helper(src->map()); | 2721 LayoutDescriptorHelper helper(src->map()); |
| 2696 bool has_only_tagged_fields = helper.all_fields_tagged(); | 2722 bool has_only_tagged_fields = helper.all_fields_tagged(); |
| 2697 #endif | 2723 #endif |
| 2698 for (int remaining = size / kPointerSize; remaining > 0; remaining--) { | 2724 for (int remaining = size / kPointerSize; remaining > 0; remaining--) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2750 } | 2776 } |
| 2751 } | 2777 } |
| 2752 } else if (dest == CODE_SPACE) { | 2778 } else if (dest == CODE_SPACE) { |
| 2753 PROFILE(isolate(), CodeMoveEvent(src_addr, dst_addr)); | 2779 PROFILE(isolate(), CodeMoveEvent(src_addr, dst_addr)); |
| 2754 heap()->MoveBlock(dst_addr, src_addr, size); | 2780 heap()->MoveBlock(dst_addr, src_addr, size); |
| 2755 SlotsBuffer::AddTo(&slots_buffer_allocator_, &migration_slots_buffer_, | 2781 SlotsBuffer::AddTo(&slots_buffer_allocator_, &migration_slots_buffer_, |
| 2756 SlotsBuffer::RELOCATED_CODE_OBJECT, dst_addr, | 2782 SlotsBuffer::RELOCATED_CODE_OBJECT, dst_addr, |
| 2757 SlotsBuffer::IGNORE_OVERFLOW); | 2783 SlotsBuffer::IGNORE_OVERFLOW); |
| 2758 Code::cast(dst)->Relocate(dst_addr - src_addr); | 2784 Code::cast(dst)->Relocate(dst_addr - src_addr); |
| 2759 } else { | 2785 } else { |
| 2760 DCHECK(dest == NEW_SPACE); | 2786 DCHECK(dest == OLD_DATA_SPACE || dest == NEW_SPACE); |
| 2761 heap()->MoveBlock(dst_addr, src_addr, size); | 2787 heap()->MoveBlock(dst_addr, src_addr, size); |
| 2762 } | 2788 } |
| 2763 heap()->OnMoveEvent(dst, src, size); | 2789 heap()->OnMoveEvent(dst, src, size); |
| 2764 Memory::Address_at(src_addr) = dst_addr; | 2790 Memory::Address_at(src_addr) = dst_addr; |
| 2765 } | 2791 } |
| 2766 | 2792 |
| 2767 | 2793 |
| 2768 // Visitor for updating pointers from live objects in old spaces to new space. | 2794 // Visitor for updating pointers from live objects in old spaces to new space. |
| 2769 // It does not expect to encounter pointers to dead objects. | 2795 // It does not expect to encounter pointers to dead objects. |
| 2770 class PointersUpdatingVisitor : public ObjectVisitor { | 2796 class PointersUpdatingVisitor : public ObjectVisitor { |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2872 data[index++] = reinterpret_cast<uintptr_t>(slot); | 2898 data[index++] = reinterpret_cast<uintptr_t>(slot); |
| 2873 data[index++] = 0x15aaaaaaaaUL; | 2899 data[index++] = 0x15aaaaaaaaUL; |
| 2874 | 2900 |
| 2875 Address slot_address = reinterpret_cast<Address>(slot); | 2901 Address slot_address = reinterpret_cast<Address>(slot); |
| 2876 | 2902 |
| 2877 uintptr_t space_owner_id = 0xb001; | 2903 uintptr_t space_owner_id = 0xb001; |
| 2878 if (heap->new_space()->ToSpaceContains(slot_address)) { | 2904 if (heap->new_space()->ToSpaceContains(slot_address)) { |
| 2879 space_owner_id = 1; | 2905 space_owner_id = 1; |
| 2880 } else if (heap->new_space()->FromSpaceContains(slot_address)) { | 2906 } else if (heap->new_space()->FromSpaceContains(slot_address)) { |
| 2881 space_owner_id = 2; | 2907 space_owner_id = 2; |
| 2882 } else if (heap->old_space()->ContainsSafe(slot_address)) { | 2908 } else if (heap->old_pointer_space()->ContainsSafe(slot_address)) { |
| 2883 space_owner_id = 3; | 2909 space_owner_id = 3; |
| 2910 } else if (heap->old_data_space()->ContainsSafe(slot_address)) { |
| 2911 space_owner_id = 4; |
| 2884 } else if (heap->code_space()->ContainsSafe(slot_address)) { | 2912 } else if (heap->code_space()->ContainsSafe(slot_address)) { |
| 2885 space_owner_id = 4; | 2913 space_owner_id = 5; |
| 2886 } else if (heap->map_space()->ContainsSafe(slot_address)) { | 2914 } else if (heap->map_space()->ContainsSafe(slot_address)) { |
| 2887 space_owner_id = 5; | 2915 space_owner_id = 6; |
| 2888 } else if (heap->cell_space()->ContainsSafe(slot_address)) { | 2916 } else if (heap->cell_space()->ContainsSafe(slot_address)) { |
| 2889 space_owner_id = 6; | 2917 space_owner_id = 7; |
| 2890 } else { | 2918 } else { |
| 2891 // Lo space or other. | 2919 // Lo space or other. |
| 2892 space_owner_id = 7; | 2920 space_owner_id = 8; |
| 2893 } | 2921 } |
| 2894 data[index++] = space_owner_id; | 2922 data[index++] = space_owner_id; |
| 2895 data[index++] = 0x20aaaaaaaaUL; | 2923 data[index++] = 0x20aaaaaaaaUL; |
| 2896 | 2924 |
| 2897 // Find map word lying near before the slot address (usually the map word is | 2925 // Find map word lying near before the slot address (usually the map word is |
| 2898 // at -3 words from the slot but just in case we look up further. | 2926 // at -3 words from the slot but just in case we look up further. |
| 2899 Object** map_slot = slot; | 2927 Object** map_slot = slot; |
| 2900 bool found = false; | 2928 bool found = false; |
| 2901 const int kMaxDistanceToMap = 64; | 2929 const int kMaxDistanceToMap = 64; |
| 2902 for (int i = 0; i < kMaxDistanceToMap; i++, map_slot--) { | 2930 for (int i = 0; i < kMaxDistanceToMap; i++, map_slot--) { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2973 } | 3001 } |
| 2974 | 3002 |
| 2975 return String::cast(*p); | 3003 return String::cast(*p); |
| 2976 } | 3004 } |
| 2977 | 3005 |
| 2978 | 3006 |
| 2979 bool MarkCompactCollector::TryPromoteObject(HeapObject* object, | 3007 bool MarkCompactCollector::TryPromoteObject(HeapObject* object, |
| 2980 int object_size) { | 3008 int object_size) { |
| 2981 DCHECK(object_size <= Page::kMaxRegularHeapObjectSize); | 3009 DCHECK(object_size <= Page::kMaxRegularHeapObjectSize); |
| 2982 | 3010 |
| 2983 OldSpace* old_space = heap()->old_space(); | 3011 OldSpace* target_space = heap()->TargetSpace(object); |
| 2984 | 3012 |
| 3013 DCHECK(target_space == heap()->old_pointer_space() || |
| 3014 target_space == heap()->old_data_space()); |
| 2985 HeapObject* target; | 3015 HeapObject* target; |
| 2986 AllocationResult allocation = old_space->AllocateRaw(object_size); | 3016 AllocationResult allocation = target_space->AllocateRaw(object_size); |
| 2987 if (allocation.To(&target)) { | 3017 if (allocation.To(&target)) { |
| 2988 MigrateObject(target, object, object_size, old_space->identity()); | 3018 MigrateObject(target, object, object_size, target_space->identity()); |
| 2989 heap()->IncrementPromotedObjectsSize(object_size); | 3019 heap()->IncrementPromotedObjectsSize(object_size); |
| 2990 return true; | 3020 return true; |
| 2991 } | 3021 } |
| 2992 | 3022 |
| 2993 return false; | 3023 return false; |
| 2994 } | 3024 } |
| 2995 | 3025 |
| 2996 | 3026 |
| 2997 bool MarkCompactCollector::IsSlotInBlackObject(Page* p, Address slot) { | 3027 bool MarkCompactCollector::IsSlotInBlackObject(Page* p, Address slot) { |
| 2998 // This function does not support large objects right now. | 3028 // This function does not support large objects right now. |
| (...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3464 | 3494 |
| 3465 return true; | 3495 return true; |
| 3466 } | 3496 } |
| 3467 | 3497 |
| 3468 | 3498 |
| 3469 static bool IsOnInvalidatedCodeObject(Address addr) { | 3499 static bool IsOnInvalidatedCodeObject(Address addr) { |
| 3470 // We did not record any slots in large objects thus | 3500 // We did not record any slots in large objects thus |
| 3471 // we can safely go to the page from the slot address. | 3501 // we can safely go to the page from the slot address. |
| 3472 Page* p = Page::FromAddress(addr); | 3502 Page* p = Page::FromAddress(addr); |
| 3473 | 3503 |
| 3474 // First check owner's identity because old space is swept concurrently or | 3504 // First check owner's identity because old pointer and old data spaces |
| 3475 // lazily and might still have non-zero mark-bits on some pages. | 3505 // are swept lazily and might still have non-zero mark-bits on some |
| 3506 // pages. |
| 3476 if (p->owner()->identity() != CODE_SPACE) return false; | 3507 if (p->owner()->identity() != CODE_SPACE) return false; |
| 3477 | 3508 |
| 3478 // In code space only bits on evacuation candidates (but we don't record | 3509 // In code space only bits on evacuation candidates (but we don't record |
| 3479 // any slots on them) and under invalidated code objects are non-zero. | 3510 // any slots on them) and under invalidated code objects are non-zero. |
| 3480 MarkBit mark_bit = | 3511 MarkBit mark_bit = |
| 3481 p->markbits()->MarkBitFromIndex(Page::FastAddressToMarkbitIndex(addr)); | 3512 p->markbits()->MarkBitFromIndex(Page::FastAddressToMarkbitIndex(addr)); |
| 3482 | 3513 |
| 3483 return mark_bit.Get(); | 3514 return mark_bit.Get(); |
| 3484 } | 3515 } |
| 3485 | 3516 |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3643 if (list != NULL) list->Clear(); | 3674 if (list != NULL) list->Clear(); |
| 3644 } else { | 3675 } else { |
| 3645 if (FLAG_gc_verbose) { | 3676 if (FLAG_gc_verbose) { |
| 3646 PrintF("Sweeping 0x%" V8PRIxPTR " during evacuation.\n", | 3677 PrintF("Sweeping 0x%" V8PRIxPTR " during evacuation.\n", |
| 3647 reinterpret_cast<intptr_t>(p)); | 3678 reinterpret_cast<intptr_t>(p)); |
| 3648 } | 3679 } |
| 3649 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); | 3680 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); |
| 3650 p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION); | 3681 p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION); |
| 3651 | 3682 |
| 3652 switch (space->identity()) { | 3683 switch (space->identity()) { |
| 3653 case OLD_SPACE: | 3684 case OLD_DATA_SPACE: |
| 3654 Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD, | 3685 Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD, |
| 3655 IGNORE_SKIP_LIST, IGNORE_FREE_SPACE>(space, NULL, p, | 3686 IGNORE_SKIP_LIST, IGNORE_FREE_SPACE>(space, NULL, p, |
| 3656 &updating_visitor); | 3687 &updating_visitor); |
| 3688 break; |
| 3689 case OLD_POINTER_SPACE: |
| 3690 Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD, |
| 3691 IGNORE_SKIP_LIST, IGNORE_FREE_SPACE>(space, NULL, p, |
| 3692 &updating_visitor); |
| 3657 break; | 3693 break; |
| 3658 case CODE_SPACE: | 3694 case CODE_SPACE: |
| 3659 if (FLAG_zap_code_space) { | 3695 if (FLAG_zap_code_space) { |
| 3660 Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD, | 3696 Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD, |
| 3661 REBUILD_SKIP_LIST, ZAP_FREE_SPACE>(space, NULL, p, | 3697 REBUILD_SKIP_LIST, ZAP_FREE_SPACE>(space, NULL, p, |
| 3662 &updating_visitor); | 3698 &updating_visitor); |
| 3663 } else { | 3699 } else { |
| 3664 Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD, | 3700 Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD, |
| 3665 REBUILD_SKIP_LIST, IGNORE_FREE_SPACE>(space, NULL, p, | 3701 REBUILD_SKIP_LIST, IGNORE_FREE_SPACE>(space, NULL, p, |
| 3666 &updating_visitor); | 3702 &updating_visitor); |
| (...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4154 max_freed_overall = Max(max_freed, max_freed_overall); | 4190 max_freed_overall = Max(max_freed, max_freed_overall); |
| 4155 if (p == space->end_of_unswept_pages()) break; | 4191 if (p == space->end_of_unswept_pages()) break; |
| 4156 } | 4192 } |
| 4157 return max_freed_overall; | 4193 return max_freed_overall; |
| 4158 } | 4194 } |
| 4159 | 4195 |
| 4160 | 4196 |
| 4161 int MarkCompactCollector::SweepInParallel(Page* page, PagedSpace* space) { | 4197 int MarkCompactCollector::SweepInParallel(Page* page, PagedSpace* space) { |
| 4162 int max_freed = 0; | 4198 int max_freed = 0; |
| 4163 if (page->TryParallelSweeping()) { | 4199 if (page->TryParallelSweeping()) { |
| 4164 FreeList* free_list = free_list_old_space_.get(); | 4200 FreeList* free_list = space == heap()->old_pointer_space() |
| 4201 ? free_list_old_pointer_space_.get() |
| 4202 : free_list_old_data_space_.get(); |
| 4165 FreeList private_free_list(space); | 4203 FreeList private_free_list(space); |
| 4166 max_freed = Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, IGNORE_SKIP_LIST, | 4204 max_freed = Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, IGNORE_SKIP_LIST, |
| 4167 IGNORE_FREE_SPACE>(space, &private_free_list, page, NULL); | 4205 IGNORE_FREE_SPACE>(space, &private_free_list, page, NULL); |
| 4168 free_list->Concatenate(&private_free_list); | 4206 free_list->Concatenate(&private_free_list); |
| 4169 } | 4207 } |
| 4170 return max_freed; | 4208 return max_freed; |
| 4171 } | 4209 } |
| 4172 | 4210 |
| 4173 | 4211 |
| 4174 void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) { | 4212 void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) { |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4279 MoveEvacuationCandidatesToEndOfPagesList(); | 4317 MoveEvacuationCandidatesToEndOfPagesList(); |
| 4280 | 4318 |
| 4281 // Noncompacting collections simply sweep the spaces to clear the mark | 4319 // Noncompacting collections simply sweep the spaces to clear the mark |
| 4282 // bits and free the nonlive blocks (for old and map spaces). We sweep | 4320 // bits and free the nonlive blocks (for old and map spaces). We sweep |
| 4283 // the map space last because freeing non-live maps overwrites them and | 4321 // the map space last because freeing non-live maps overwrites them and |
| 4284 // the other spaces rely on possibly non-live maps to get the sizes for | 4322 // the other spaces rely on possibly non-live maps to get the sizes for |
| 4285 // non-live objects. | 4323 // non-live objects. |
| 4286 { | 4324 { |
| 4287 GCTracer::Scope sweep_scope(heap()->tracer(), | 4325 GCTracer::Scope sweep_scope(heap()->tracer(), |
| 4288 GCTracer::Scope::MC_SWEEP_OLDSPACE); | 4326 GCTracer::Scope::MC_SWEEP_OLDSPACE); |
| 4289 { SweepSpace(heap()->old_space(), CONCURRENT_SWEEPING); } | 4327 { |
| 4328 SweepSpace(heap()->old_pointer_space(), CONCURRENT_SWEEPING); |
| 4329 SweepSpace(heap()->old_data_space(), CONCURRENT_SWEEPING); |
| 4330 } |
| 4290 sweeping_in_progress_ = true; | 4331 sweeping_in_progress_ = true; |
| 4291 if (heap()->concurrent_sweeping_enabled()) { | 4332 if (heap()->concurrent_sweeping_enabled()) { |
| 4292 StartSweeperThreads(); | 4333 StartSweeperThreads(); |
| 4293 } | 4334 } |
| 4294 } | 4335 } |
| 4295 RemoveDeadInvalidatedCode(); | 4336 RemoveDeadInvalidatedCode(); |
| 4296 | 4337 |
| 4297 { | 4338 { |
| 4298 GCTracer::Scope sweep_scope(heap()->tracer(), | 4339 GCTracer::Scope sweep_scope(heap()->tracer(), |
| 4299 GCTracer::Scope::MC_SWEEP_CODE); | 4340 GCTracer::Scope::MC_SWEEP_CODE); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4341 if (p->parallel_sweeping() == MemoryChunk::SWEEPING_FINALIZE) { | 4382 if (p->parallel_sweeping() == MemoryChunk::SWEEPING_FINALIZE) { |
| 4342 p->set_parallel_sweeping(MemoryChunk::SWEEPING_DONE); | 4383 p->set_parallel_sweeping(MemoryChunk::SWEEPING_DONE); |
| 4343 p->SetWasSwept(); | 4384 p->SetWasSwept(); |
| 4344 } | 4385 } |
| 4345 DCHECK(p->parallel_sweeping() == MemoryChunk::SWEEPING_DONE); | 4386 DCHECK(p->parallel_sweeping() == MemoryChunk::SWEEPING_DONE); |
| 4346 } | 4387 } |
| 4347 } | 4388 } |
| 4348 | 4389 |
| 4349 | 4390 |
| 4350 void MarkCompactCollector::ParallelSweepSpacesComplete() { | 4391 void MarkCompactCollector::ParallelSweepSpacesComplete() { |
| 4351 ParallelSweepSpaceComplete(heap()->old_space()); | 4392 ParallelSweepSpaceComplete(heap()->old_pointer_space()); |
| 4393 ParallelSweepSpaceComplete(heap()->old_data_space()); |
| 4352 } | 4394 } |
| 4353 | 4395 |
| 4354 | 4396 |
| 4355 void MarkCompactCollector::EnableCodeFlushing(bool enable) { | 4397 void MarkCompactCollector::EnableCodeFlushing(bool enable) { |
| 4356 if (isolate()->debug()->is_loaded() || | 4398 if (isolate()->debug()->is_loaded() || |
| 4357 isolate()->debug()->has_break_points()) { | 4399 isolate()->debug()->has_break_points()) { |
| 4358 enable = false; | 4400 enable = false; |
| 4359 } | 4401 } |
| 4360 | 4402 |
| 4361 if (enable) { | 4403 if (enable) { |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4552 SlotsBuffer* buffer = *buffer_address; | 4594 SlotsBuffer* buffer = *buffer_address; |
| 4553 while (buffer != NULL) { | 4595 while (buffer != NULL) { |
| 4554 SlotsBuffer* next_buffer = buffer->next(); | 4596 SlotsBuffer* next_buffer = buffer->next(); |
| 4555 DeallocateBuffer(buffer); | 4597 DeallocateBuffer(buffer); |
| 4556 buffer = next_buffer; | 4598 buffer = next_buffer; |
| 4557 } | 4599 } |
| 4558 *buffer_address = NULL; | 4600 *buffer_address = NULL; |
| 4559 } | 4601 } |
| 4560 } | 4602 } |
| 4561 } // namespace v8::internal | 4603 } // namespace v8::internal |
| OLD | NEW |