Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(367)

Unified Diff: src/heap/mark-compact.cc

Issue 2828323004: [heap] Refactor MC and introduce MarkCompactCollectorBase (Closed)
Patch Set: More refactoring Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/heap/mark-compact.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/heap/mark-compact.cc
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc
index fe886ac8136ebe99d1924a9b9250aa357038eadf..2e862977812c14d67ddad01a8a76283c7a23bca7 100644
--- a/src/heap/mark-compact.cc
+++ b/src/heap/mark-compact.cc
@@ -283,12 +283,39 @@ class FullEvacuationVerifier : public EvacuationVerifier {
#endif // VERIFY_HEAP
// =============================================================================
-// MarkCompactCollector
+// MarkCompactCollectorBase, MinorMarkCompactCollector, MarkCompactCollector
// =============================================================================
+int MarkCompactCollectorBase::NumberOfParallelCompactionTasks(
+ int pages, intptr_t live_bytes) {
+ if (!FLAG_parallel_compaction) return 1;
+ // Compute the number of needed tasks based on a target compaction time, the
+ // profiled compaction speed and marked live memory.
+ //
+ // The number of parallel compaction tasks is limited by:
+ // - #evacuation pages
+ // - #cores
+ const double kTargetCompactionTimeInMs = .5;
+
+ double compaction_speed =
+ heap()->tracer()->CompactionSpeedInBytesPerMillisecond();
+
+ const int available_cores = Max(
+ 1, static_cast<int>(
+ V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads()));
+ int tasks;
+ if (compaction_speed > 0) {
+ tasks = 1 + static_cast<int>(live_bytes / compaction_speed /
+ kTargetCompactionTimeInMs);
+ } else {
+ tasks = pages;
+ }
+ const int tasks_capped_pages = Min(pages, tasks);
+ return Min(available_cores, tasks_capped_pages);
+}
+
MarkCompactCollector::MarkCompactCollector(Heap* heap)
- : // NOLINT
- heap_(heap),
+ : MarkCompactCollectorBase(heap),
page_parallel_job_semaphore_(0),
#ifdef DEBUG
state_(IDLE),
@@ -616,25 +643,6 @@ bool MarkCompactCollector::Sweeper::AreSweeperTasksRunning() {
return num_sweeping_tasks_.Value() != 0;
}
-const char* AllocationSpaceName(AllocationSpace space) {
- switch (space) {
- case NEW_SPACE:
- return "NEW_SPACE";
- case OLD_SPACE:
- return "OLD_SPACE";
- case CODE_SPACE:
- return "CODE_SPACE";
- case MAP_SPACE:
- return "MAP_SPACE";
- case LO_SPACE:
- return "LO_SPACE";
- default:
- UNREACHABLE();
- }
-
- return NULL;
-}
-
void MarkCompactCollector::ComputeEvacuationHeuristics(
size_t area_size, int* target_fragmentation_percent,
size_t* max_evacuated_bytes) {
@@ -3140,7 +3148,7 @@ class Evacuator : public Malloced {
virtual ~Evacuator() {}
- virtual bool EvacuatePage(Page* page, const MarkingState& state) = 0;
+ bool EvacuatePage(Page* page, const MarkingState& state);
// Merge back locally cached info sequentially. Note that this method needs
// to be called from the main thread.
@@ -3152,6 +3160,8 @@ class Evacuator : public Malloced {
protected:
static const int kInitialLocalPretenuringFeedbackCapacity = 256;
+ virtual bool RawEvacuatePage(Page* page, const MarkingState& state) = 0;
+
inline Heap* heap() { return heap_; }
void ReportCompactionProgress(double duration, intptr_t bytes_compacted) {
@@ -3178,6 +3188,34 @@ class Evacuator : public Malloced {
intptr_t bytes_compacted_;
};
+bool Evacuator::EvacuatePage(Page* page, const MarkingState& state) {
+ bool success = false;
+ DCHECK(page->SweepingDone());
+ intptr_t saved_live_bytes = state.live_bytes();
+ double evacuation_time = 0.0;
+ {
+ AlwaysAllocateScope always_allocate(heap()->isolate());
+ TimedScope timed_scope(&evacuation_time);
+ success = RawEvacuatePage(page, state);
+ }
+ ReportCompactionProgress(evacuation_time, saved_live_bytes);
+ if (FLAG_trace_evacuation) {
+ PrintIsolate(
+ heap()->isolate(),
+ "evacuation[%p]: page=%p new_space=%d "
+ "page_evacuation=%d executable=%d contains_age_mark=%d "
+ "live_bytes=%" V8PRIdPTR " time=%f page_promotion_qualifies=%d\n",
+ static_cast<void*>(this), static_cast<void*>(page), page->InNewSpace(),
+ page->IsFlagSet(Page::PAGE_NEW_OLD_PROMOTION) ||
+ page->IsFlagSet(Page::PAGE_NEW_NEW_PROMOTION),
+ page->IsFlagSet(MemoryChunk::IS_EXECUTABLE),
+ page->Contains(heap()->new_space()->age_mark()), saved_live_bytes,
+ evacuation_time,
+ saved_live_bytes > Evacuator::PageEvacuationThreshold());
+ }
+ return success;
+}
+
void Evacuator::Finalize() {
heap()->old_space()->MergeCompactionSpace(compaction_spaces_.Get(OLD_SPACE));
heap()->code_space()->MergeCompactionSpace(
@@ -3201,116 +3239,66 @@ class FullEvacuator : public Evacuator {
FullEvacuator(Heap* heap, RecordMigratedSlotVisitor* record_visitor)
: Evacuator(heap, record_visitor) {}
- bool EvacuatePage(Page* page, const MarkingState& state) override;
+ protected:
+ bool RawEvacuatePage(Page* page, const MarkingState& state) override;
};
-bool FullEvacuator::EvacuatePage(Page* page, const MarkingState& state) {
+bool FullEvacuator::RawEvacuatePage(Page* page, const MarkingState& state) {
bool success = false;
- DCHECK(page->SweepingDone());
- intptr_t saved_live_bytes = state.live_bytes();
- double evacuation_time = 0.0;
- {
- AlwaysAllocateScope always_allocate(heap()->isolate());
- TimedScope timed_scope(&evacuation_time);
- LiveObjectVisitor object_visitor;
- switch (ComputeEvacuationMode(page)) {
- case kObjectsNewToOld:
- success =
- object_visitor.VisitBlackObjects(page, state, &new_space_visitor_,
- LiveObjectVisitor::kClearMarkbits);
+ LiveObjectVisitor object_visitor;
+ switch (ComputeEvacuationMode(page)) {
+ case kObjectsNewToOld:
+ success = object_visitor.VisitBlackObjects(
+ page, state, &new_space_visitor_, LiveObjectVisitor::kClearMarkbits);
+ DCHECK(success);
+ ArrayBufferTracker::ProcessBuffers(
+ page, ArrayBufferTracker::kUpdateForwardedRemoveOthers);
+ break;
+ case kPageNewToOld:
+ success = object_visitor.VisitBlackObjects(
+ page, state, &new_to_old_page_visitor_,
+ LiveObjectVisitor::kKeepMarking);
+ DCHECK(success);
+ new_to_old_page_visitor_.account_moved_bytes(
+ MarkingState::Internal(page).live_bytes());
+ // ArrayBufferTracker will be updated during sweeping.
+ break;
+ case kPageNewToNew:
+ success = object_visitor.VisitBlackObjects(
+ page, state, &new_to_new_page_visitor_,
+ LiveObjectVisitor::kKeepMarking);
+ DCHECK(success);
+ new_to_new_page_visitor_.account_moved_bytes(
+ MarkingState::Internal(page).live_bytes());
+ // ArrayBufferTracker will be updated during sweeping.
+ break;
+ case kObjectsOldToOld:
+ success = object_visitor.VisitBlackObjects(
+ page, state, &old_space_visitor_, LiveObjectVisitor::kClearMarkbits);
+ if (!success) {
+ // Aborted compaction page. We have to record slots here, since we
+ // might not have recorded them in first place.
+ // Note: We mark the page as aborted here to be able to record slots
+ // for code objects in |RecordMigratedSlotVisitor|.
+ page->SetFlag(Page::COMPACTION_WAS_ABORTED);
+ EvacuateRecordOnlyVisitor record_visitor(heap());
+ success = object_visitor.VisitBlackObjects(
+ page, state, &record_visitor, LiveObjectVisitor::kKeepMarking);
+ ArrayBufferTracker::ProcessBuffers(
+ page, ArrayBufferTracker::kUpdateForwardedKeepOthers);
DCHECK(success);
+ // We need to return failure here to indicate that we want this page
+ // added to the sweeper.
+ success = false;
+ } else {
ArrayBufferTracker::ProcessBuffers(
page, ArrayBufferTracker::kUpdateForwardedRemoveOthers);
- break;
- case kPageNewToOld:
- success = object_visitor.VisitBlackObjects(
- page, state, &new_to_old_page_visitor_,
- LiveObjectVisitor::kKeepMarking);
- DCHECK(success);
- new_to_old_page_visitor_.account_moved_bytes(
- MarkingState::Internal(page).live_bytes());
- // ArrayBufferTracker will be updated during sweeping.
- break;
- case kPageNewToNew:
- success = object_visitor.VisitBlackObjects(
- page, state, &new_to_new_page_visitor_,
- LiveObjectVisitor::kKeepMarking);
- DCHECK(success);
- new_to_new_page_visitor_.account_moved_bytes(
- MarkingState::Internal(page).live_bytes());
- // ArrayBufferTracker will be updated during sweeping.
- break;
- case kObjectsOldToOld:
- success =
- object_visitor.VisitBlackObjects(page, state, &old_space_visitor_,
- LiveObjectVisitor::kClearMarkbits);
- if (!success) {
- // Aborted compaction page. We have to record slots here, since we
- // might not have recorded them in first place.
- // Note: We mark the page as aborted here to be able to record slots
- // for code objects in |RecordMigratedSlotVisitor|.
- page->SetFlag(Page::COMPACTION_WAS_ABORTED);
- EvacuateRecordOnlyVisitor record_visitor(heap());
- success = object_visitor.VisitBlackObjects(
- page, state, &record_visitor, LiveObjectVisitor::kKeepMarking);
- ArrayBufferTracker::ProcessBuffers(
- page, ArrayBufferTracker::kUpdateForwardedKeepOthers);
- DCHECK(success);
- // We need to return failure here to indicate that we want this page
- // added to the sweeper.
- success = false;
- } else {
- ArrayBufferTracker::ProcessBuffers(
- page, ArrayBufferTracker::kUpdateForwardedRemoveOthers);
- }
- break;
- }
- }
- ReportCompactionProgress(evacuation_time, saved_live_bytes);
- if (FLAG_trace_evacuation) {
- PrintIsolate(heap()->isolate(),
- "evacuation[%p]: page=%p new_space=%d "
- "page_evacuation=%d executable=%d contains_age_mark=%d "
- "live_bytes=%" V8PRIdPTR " time=%f\n",
- static_cast<void*>(this), static_cast<void*>(page),
- page->InNewSpace(),
- page->IsFlagSet(Page::PAGE_NEW_OLD_PROMOTION) ||
- page->IsFlagSet(Page::PAGE_NEW_NEW_PROMOTION),
- page->IsFlagSet(MemoryChunk::IS_EXECUTABLE),
- page->Contains(heap()->new_space()->age_mark()),
- saved_live_bytes, evacuation_time);
+ }
+ break;
}
return success;
}
-int MarkCompactCollector::NumberOfParallelCompactionTasks(int pages,
- intptr_t live_bytes) {
- if (!FLAG_parallel_compaction) return 1;
- // Compute the number of needed tasks based on a target compaction time, the
- // profiled compaction speed and marked live memory.
- //
- // The number of parallel compaction tasks is limited by:
- // - #evacuation pages
- // - #cores
- const double kTargetCompactionTimeInMs = .5;
-
- double compaction_speed =
- heap()->tracer()->CompactionSpeedInBytesPerMillisecond();
-
- const int available_cores = Max(
- 1, static_cast<int>(
- V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads()));
- int tasks;
- if (compaction_speed > 0) {
- tasks = 1 + static_cast<int>(live_bytes / compaction_speed /
- kTargetCompactionTimeInMs);
- } else {
- tasks = pages;
- }
- const int tasks_capped_pages = Min(pages, tasks);
- return Min(available_cores, tasks_capped_pages);
-}
-
class EvacuationJobTraits {
public:
typedef int* PerPageData; // Pointer to number of aborted pages.
« no previous file with comments | « src/heap/mark-compact.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698