OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 #ifdef DEBUG | 60 #ifdef DEBUG |
61 state_(IDLE), | 61 state_(IDLE), |
62 #endif | 62 #endif |
63 sweep_precisely_(false), | 63 sweep_precisely_(false), |
64 reduce_memory_footprint_(false), | 64 reduce_memory_footprint_(false), |
65 abort_incremental_marking_(false), | 65 abort_incremental_marking_(false), |
66 marking_parity_(ODD_MARKING_PARITY), | 66 marking_parity_(ODD_MARKING_PARITY), |
67 compacting_(false), | 67 compacting_(false), |
68 was_marked_incrementally_(false), | 68 was_marked_incrementally_(false), |
69 sweeping_pending_(false), | 69 sweeping_pending_(false), |
| 70 pending_sweeper_jobs_semaphore_(0), |
70 sequential_sweeping_(false), | 71 sequential_sweeping_(false), |
71 tracer_(NULL), | 72 tracer_(NULL), |
72 migration_slots_buffer_(NULL), | 73 migration_slots_buffer_(NULL), |
73 heap_(heap), | 74 heap_(heap), |
74 code_flusher_(NULL), | 75 code_flusher_(NULL), |
75 encountered_weak_collections_(NULL), | 76 encountered_weak_collections_(NULL), |
76 have_code_to_deoptimize_(false) { } | 77 have_code_to_deoptimize_(false) { } |
77 | 78 |
78 #ifdef VERIFY_HEAP | 79 #ifdef VERIFY_HEAP |
79 class VerifyMarkingVisitor: public ObjectVisitor { | 80 class VerifyMarkingVisitor: public ObjectVisitor { |
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { | 563 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { |
563 MarkBit mark_bit = Marking::MarkBitFrom(obj); | 564 MarkBit mark_bit = Marking::MarkBitFrom(obj); |
564 mark_bit.Clear(); | 565 mark_bit.Clear(); |
565 mark_bit.Next().Clear(); | 566 mark_bit.Next().Clear(); |
566 Page::FromAddress(obj->address())->ResetProgressBar(); | 567 Page::FromAddress(obj->address())->ResetProgressBar(); |
567 Page::FromAddress(obj->address())->ResetLiveBytes(); | 568 Page::FromAddress(obj->address())->ResetLiveBytes(); |
568 } | 569 } |
569 } | 570 } |
570 | 571 |
571 | 572 |
| 573 class MarkCompactCollector::SweeperTask : public v8::Task { |
| 574 public: |
| 575 SweeperTask(Heap* heap, PagedSpace* space) |
| 576 : heap_(heap), space_(space) {} |
| 577 |
| 578 virtual ~SweeperTask() {} |
| 579 |
| 580 private: |
| 581 // v8::Task overrides. |
| 582 virtual void Run() V8_OVERRIDE { |
| 583 heap_->mark_compact_collector()->SweepInParallel(space_); |
| 584 heap_->mark_compact_collector()->pending_sweeper_jobs_semaphore_.Signal(); |
| 585 } |
| 586 |
| 587 Heap* heap_; |
| 588 PagedSpace* space_; |
| 589 |
| 590 DISALLOW_COPY_AND_ASSIGN(SweeperTask); |
| 591 }; |
| 592 |
| 593 |
572 void MarkCompactCollector::StartSweeperThreads() { | 594 void MarkCompactCollector::StartSweeperThreads() { |
573 sweeping_pending_ = true; | 595 sweeping_pending_ = true; |
574 for (int i = 0; i < isolate()->num_sweeper_threads(); i++) { | 596 for (int i = 0; i < isolate()->num_sweeper_threads(); i++) { |
575 isolate()->sweeper_threads()[i]->StartSweeping(); | 597 isolate()->sweeper_threads()[i]->StartSweeping(); |
576 } | 598 } |
| 599 if (FLAG_job_based_sweeping) { |
| 600 V8::GetCurrentPlatform()->CallOnBackgroundThread( |
| 601 new SweeperTask(heap(), heap()->old_data_space()), |
| 602 v8::Platform::kShortRunningTask); |
| 603 V8::GetCurrentPlatform()->CallOnBackgroundThread( |
| 604 new SweeperTask(heap(), heap()->old_pointer_space()), |
| 605 v8::Platform::kShortRunningTask); |
| 606 } |
577 } | 607 } |
578 | 608 |
579 | 609 |
580 void MarkCompactCollector::WaitUntilSweepingCompleted() { | 610 void MarkCompactCollector::WaitUntilSweepingCompleted() { |
581 ASSERT(sweeping_pending_ == true); | 611 ASSERT(sweeping_pending_ == true); |
582 for (int i = 0; i < isolate()->num_sweeper_threads(); i++) { | 612 for (int i = 0; i < isolate()->num_sweeper_threads(); i++) { |
583 isolate()->sweeper_threads()[i]->WaitForSweeperThread(); | 613 isolate()->sweeper_threads()[i]->WaitForSweeperThread(); |
584 } | 614 } |
| 615 if (FLAG_job_based_sweeping) { |
| 616 // Wait twice for both jobs. |
| 617 pending_sweeper_jobs_semaphore_.Wait(); |
| 618 pending_sweeper_jobs_semaphore_.Wait(); |
| 619 } |
585 sweeping_pending_ = false; | 620 sweeping_pending_ = false; |
586 RefillFreeLists(heap()->paged_space(OLD_DATA_SPACE)); | 621 RefillFreeLists(heap()->paged_space(OLD_DATA_SPACE)); |
587 RefillFreeLists(heap()->paged_space(OLD_POINTER_SPACE)); | 622 RefillFreeLists(heap()->paged_space(OLD_POINTER_SPACE)); |
588 heap()->paged_space(OLD_DATA_SPACE)->ResetUnsweptFreeBytes(); | 623 heap()->paged_space(OLD_DATA_SPACE)->ResetUnsweptFreeBytes(); |
589 heap()->paged_space(OLD_POINTER_SPACE)->ResetUnsweptFreeBytes(); | 624 heap()->paged_space(OLD_POINTER_SPACE)->ResetUnsweptFreeBytes(); |
590 } | 625 } |
591 | 626 |
592 | 627 |
593 intptr_t MarkCompactCollector::RefillFreeLists(PagedSpace* space) { | 628 intptr_t MarkCompactCollector::RefillFreeLists(PagedSpace* space) { |
594 FreeList* free_list = space == heap()->old_pointer_space() | 629 FreeList* free_list = space == heap()->old_pointer_space() |
595 ? free_list_old_pointer_space_.get() | 630 ? free_list_old_pointer_space_.get() |
596 : free_list_old_data_space_.get(); | 631 : free_list_old_data_space_.get(); |
597 intptr_t freed_bytes = space->free_list()->Concatenate(free_list); | 632 intptr_t freed_bytes = space->free_list()->Concatenate(free_list); |
598 space->AddToAccountingStats(freed_bytes); | 633 space->AddToAccountingStats(freed_bytes); |
599 space->DecrementUnsweptFreeBytes(freed_bytes); | 634 space->DecrementUnsweptFreeBytes(freed_bytes); |
600 return freed_bytes; | 635 return freed_bytes; |
601 } | 636 } |
602 | 637 |
603 | 638 |
604 bool MarkCompactCollector::AreSweeperThreadsActivated() { | 639 bool MarkCompactCollector::AreSweeperThreadsActivated() { |
605 return isolate()->sweeper_threads() != NULL; | 640 return isolate()->sweeper_threads() != NULL || FLAG_job_based_sweeping; |
606 } | 641 } |
607 | 642 |
608 | 643 |
609 bool MarkCompactCollector::IsConcurrentSweepingInProgress() { | 644 bool MarkCompactCollector::IsConcurrentSweepingInProgress() { |
610 return sweeping_pending_; | 645 return sweeping_pending_; |
611 } | 646 } |
612 | 647 |
613 | 648 |
614 bool Marking::TransferMark(Address old_start, Address new_start) { | 649 bool Marking::TransferMark(Address old_start, Address new_start) { |
615 // This is only used when resizing an object. | 650 // This is only used when resizing an object. |
(...skipping 3501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4117 } | 4152 } |
4118 | 4153 |
4119 | 4154 |
4120 void MarkCompactCollector::SweepSpaces() { | 4155 void MarkCompactCollector::SweepSpaces() { |
4121 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP); | 4156 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP); |
4122 #ifdef DEBUG | 4157 #ifdef DEBUG |
4123 state_ = SWEEP_SPACES; | 4158 state_ = SWEEP_SPACES; |
4124 #endif | 4159 #endif |
4125 SweeperType how_to_sweep = | 4160 SweeperType how_to_sweep = |
4126 FLAG_lazy_sweeping ? LAZY_CONSERVATIVE : CONSERVATIVE; | 4161 FLAG_lazy_sweeping ? LAZY_CONSERVATIVE : CONSERVATIVE; |
4127 if (isolate()->num_sweeper_threads() > 0) { | 4162 if (AreSweeperThreadsActivated()) { |
4128 if (FLAG_parallel_sweeping) how_to_sweep = PARALLEL_CONSERVATIVE; | 4163 if (FLAG_parallel_sweeping) how_to_sweep = PARALLEL_CONSERVATIVE; |
4129 if (FLAG_concurrent_sweeping) how_to_sweep = CONCURRENT_CONSERVATIVE; | 4164 if (FLAG_concurrent_sweeping) how_to_sweep = CONCURRENT_CONSERVATIVE; |
4130 } | 4165 } |
4131 if (sweep_precisely_) how_to_sweep = PRECISE; | 4166 if (sweep_precisely_) how_to_sweep = PRECISE; |
4132 | 4167 |
4133 // Unlink evacuation candidates before sweeper threads access the list of | 4168 // Unlink evacuation candidates before sweeper threads access the list of |
4134 // pages to avoid race condition. | 4169 // pages to avoid race condition. |
4135 UnlinkEvacuationCandidates(); | 4170 UnlinkEvacuationCandidates(); |
4136 | 4171 |
4137 // Noncompacting collections simply sweep the spaces to clear the mark | 4172 // Noncompacting collections simply sweep the spaces to clear the mark |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4375 while (buffer != NULL) { | 4410 while (buffer != NULL) { |
4376 SlotsBuffer* next_buffer = buffer->next(); | 4411 SlotsBuffer* next_buffer = buffer->next(); |
4377 DeallocateBuffer(buffer); | 4412 DeallocateBuffer(buffer); |
4378 buffer = next_buffer; | 4413 buffer = next_buffer; |
4379 } | 4414 } |
4380 *buffer_address = NULL; | 4415 *buffer_address = NULL; |
4381 } | 4416 } |
4382 | 4417 |
4383 | 4418 |
4384 } } // namespace v8::internal | 4419 } } // namespace v8::internal |
OLD | NEW |