[heap] Decouple RootMarkingVisitor used for seeding items from Minor MC

This visitor can be reused by the full MC when seeding root items.

Bug: chromium:750084
Change-Id: I9d46ce55737961d8f72a34b06f3314c8f75f3b4d
Reviewed-on: https://chromium-review.googlesource.com/591451
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46972}
This commit is contained in:
Michael Lippautz 2017-07-28 15:01:36 +02:00 committed by Commit Bot
parent ca33118d32
commit d9d059175e
2 changed files with 51 additions and 47 deletions

View File

@ -349,6 +349,55 @@ class YoungGenerationEvacuationVerifier : public EvacuationVerifier {
// MarkCompactCollectorBase, MinorMarkCompactCollector, MarkCompactCollector // MarkCompactCollectorBase, MinorMarkCompactCollector, MarkCompactCollector
// ============================================================================= // =============================================================================
namespace {
// This root visitor walks all roots and creates items bundling objects that
// are then processed later on. Slots have to be dereferenced as they could
// live on the native (C++) stack, which requires filtering out the indirection.
template <class BatchedItem>
class RootMarkingVisitorSeedOnly : public RootVisitor {
public:
explicit RootMarkingVisitorSeedOnly(ItemParallelJob* job) : job_(job) {
buffered_objects_.reserve(kBufferSize);
}
void VisitRootPointer(Root root, Object** p) override {
if (!(*p)->IsHeapObject()) return;
AddObject(*p);
}
void VisitRootPointers(Root root, Object** start, Object** end) override {
for (Object** p = start; p < end; p++) {
if (!(*p)->IsHeapObject()) continue;
AddObject(*p);
}
}
void FlushObjects() {
job_->AddItem(new BatchedItem(std::move(buffered_objects_)));
// Moving leaves the container in a valid but unspecified state. Reusing the
// container requires a call without precondition that resets the state.
buffered_objects_.clear();
buffered_objects_.reserve(kBufferSize);
}
private:
// Bundling several objects together in items avoids issues with allocating
// and deallocating items; both are operations that are performed on the main
// thread.
static const int kBufferSize = 128;
void AddObject(Object* object) {
buffered_objects_.push_back(object);
if (buffered_objects_.size() == kBufferSize) FlushObjects();
}
ItemParallelJob* job_;
std::vector<Object*> buffered_objects_;
};
} // namespace
static int NumberOfAvailableCores() { static int NumberOfAvailableCores() {
return Max( return Max(
1, static_cast<int>( 1, static_cast<int>(
@ -2327,51 +2376,6 @@ class GlobalHandlesMarkingItem : public MarkingItem {
size_t end_; size_t end_;
}; };
// This root visitor walks all roots and creates items bundling objects that
// are then processed later on. Slots have to be dereferenced as they could
// live on the native (C++) stack, which requires filtering out the indirection.
class MinorMarkCompactCollector::RootMarkingVisitorSeedOnly
: public RootVisitor {
public:
explicit RootMarkingVisitorSeedOnly(ItemParallelJob* job) : job_(job) {
buffered_objects_.reserve(kBufferSize);
}
void VisitRootPointer(Root root, Object** p) override {
if (!(*p)->IsHeapObject()) return;
AddObject(*p);
}
void VisitRootPointers(Root root, Object** start, Object** end) override {
for (Object** p = start; p < end; p++) {
if (!(*p)->IsHeapObject()) continue;
AddObject(*p);
}
}
void FlushObjects() {
job_->AddItem(new BatchedRootMarkingItem(std::move(buffered_objects_)));
// Moving leaves the container in a valid but unspecified state. Reusing the
// container requires a call without precondition that resets the state.
buffered_objects_.clear();
buffered_objects_.reserve(kBufferSize);
}
private:
// Bundling several objects together in items avoids issues with allocating
// and deallocating items; both are operations that are performed on the main
// thread.
static const int kBufferSize = 128;
void AddObject(Object* object) {
buffered_objects_.push_back(object);
if (buffered_objects_.size() == kBufferSize) FlushObjects();
}
ItemParallelJob* job_;
std::vector<Object*> buffered_objects_;
};
MinorMarkCompactCollector::MinorMarkCompactCollector(Heap* heap) MinorMarkCompactCollector::MinorMarkCompactCollector(Heap* heap)
: MarkCompactCollectorBase(heap), : MarkCompactCollectorBase(heap),
worklist_(new MinorMarkCompactCollector::MarkingWorklist()), worklist_(new MinorMarkCompactCollector::MarkingWorklist()),
@ -2419,7 +2423,8 @@ void MinorMarkCompactCollector::MarkRootSetInParallel() {
{ {
TRACE_GC(heap()->tracer(), GCTracer::Scope::MINOR_MC_MARK_SEED); TRACE_GC(heap()->tracer(), GCTracer::Scope::MINOR_MC_MARK_SEED);
// Create batches of roots. // Create batches of roots.
RootMarkingVisitorSeedOnly root_seed_visitor(&job); RootMarkingVisitorSeedOnly<BatchedRootMarkingItem> root_seed_visitor(
&job);
heap()->IterateRoots(&root_seed_visitor, VISIT_ALL_IN_MINOR_MC_MARK); heap()->IterateRoots(&root_seed_visitor, VISIT_ALL_IN_MINOR_MC_MARK);
// Create batches of global handles. // Create batches of global handles.
SeedGlobalHandles<GlobalHandlesMarkingItem>(isolate()->global_handles(), SeedGlobalHandles<GlobalHandlesMarkingItem>(isolate()->global_handles(),

View File

@ -347,7 +347,6 @@ class MinorMarkCompactCollector final : public MarkCompactCollectorBase {
private: private:
using MarkingWorklist = Worklist<HeapObject*, 64 /* segment size */>; using MarkingWorklist = Worklist<HeapObject*, 64 /* segment size */>;
class RootMarkingVisitorSeedOnly;
class RootMarkingVisitor; class RootMarkingVisitor;
static const int kNumMarkers = 8; static const int kNumMarkers = 8;