| Index: src/heap/incremental-marking.cc
|
| diff --git a/src/heap/incremental-marking.cc b/src/heap/incremental-marking.cc
|
| index a7ac6b2be75fbbda6880ec9251aa0a443d718fe4..e4230d159672de92cb642fc3f21401b0de6cd215 100644
|
| --- a/src/heap/incremental-marking.cc
|
| +++ b/src/heap/incremental-marking.cc
|
| @@ -23,7 +23,6 @@ IncrementalMarking::StepActions IncrementalMarking::IdleStepActions() {
|
| IncrementalMarking::DO_NOT_FORCE_COMPLETION);
|
| }
|
|
|
| -
|
| IncrementalMarking::IncrementalMarking(Heap* heap)
|
| : heap_(heap),
|
| observer_(*this, kAllocatedThreshold),
|
| @@ -42,11 +41,11 @@ IncrementalMarking::IncrementalMarking(Heap* heap)
|
| no_marking_scope_depth_(0),
|
| unscanned_bytes_of_large_object_(0),
|
| was_activated_(false),
|
| + black_allocation_(false),
|
| finalize_marking_completed_(false),
|
| incremental_marking_finalization_rounds_(0),
|
| request_type_(COMPLETE_MARKING) {}
|
|
|
| -
|
| bool IncrementalMarking::BaseRecordWrite(HeapObject* obj, Object* value) {
|
| HeapObject* value_heap_obj = HeapObject::cast(value);
|
| MarkBit value_bit = Marking::MarkBitFrom(value_heap_obj);
|
| @@ -324,6 +323,12 @@ class IncrementalMarkingMarkingVisitor
|
| }
|
| };
|
|
|
| +void IncrementalMarking::IterateBlackObject(HeapObject* object) {
|
| + if (black_allocation() &&
|
| + Page::FromAddress(object->address())->IsFlagSet(Page::BLACK_PAGE)) {
|
| + IncrementalMarkingMarkingVisitor::IterateBody(object->map(), object);
|
| + }
|
| +}
|
|
|
| class IncrementalMarkingRootMarkingVisitor : public ObjectVisitor {
|
| public:
|
| @@ -597,12 +602,43 @@ void IncrementalMarking::StartMarking() {
|
| IncrementalMarkingRootMarkingVisitor visitor(this);
|
| heap_->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG);
|
|
|
| + if (FLAG_black_allocation) {
|
| + StartBlackAllocation();
|
| + }
|
| +
|
| // Ready to start incremental marking.
|
| if (FLAG_trace_incremental_marking) {
|
| PrintF("[IncrementalMarking] Running\n");
|
| }
|
| }
|
|
|
| +void IncrementalMarking::StartBlackAllocation() {
|
| + if (heap_->isolate()->serializer_enabled()) {
|
| + if (FLAG_trace_incremental_marking) {
|
| + PrintF("[IncrementalMarking] Black allocation delayed - serializer\n");
|
| + }
|
| + return;
|
| + }
|
| + DCHECK(FLAG_black_allocation);
|
| + DCHECK(IsMarking());
|
| + black_allocation_ = true;
|
| + PagedSpaces spaces(heap());
|
| + for (PagedSpace* space = spaces.next(); space != NULL;
|
| + space = spaces.next()) {
|
| + space->EmptyAllocationInfo();
|
| + space->free_list()->Reset();
|
| + }
|
| + if (FLAG_trace_incremental_marking) {
|
| + PrintF("[IncrementalMarking] Black allocation started\n");
|
| + }
|
| +}
|
| +
|
| +void IncrementalMarking::FinishBlackAllocation() {
|
| + black_allocation_ = false;
|
| + if (FLAG_trace_incremental_marking) {
|
| + PrintF("[IncrementalMarking] Black allocation finished\n");
|
| + }
|
| +}
|
|
|
| void IncrementalMarking::MarkRoots() {
|
| DCHECK(!finalize_marking_completed_);
|
| @@ -805,6 +841,8 @@ void IncrementalMarking::UpdateMarkingDequeAfterScavenge() {
|
| // them.
|
| if (map_word.IsForwardingAddress()) {
|
| HeapObject* dest = map_word.ToForwardingAddress();
|
| + if (Page::FromAddress(dest->address())->IsFlagSet(Page::BLACK_PAGE))
|
| + continue;
|
| array[new_top] = dest;
|
| new_top = ((new_top + 1) & mask);
|
| DCHECK(new_top != marking_deque->bottom());
|
| @@ -899,7 +937,12 @@ void IncrementalMarking::ProcessMarkingDeque() {
|
|
|
|
|
| void IncrementalMarking::Hurry() {
|
| - if (state() == MARKING) {
|
| + // A scavenge may have pushed new objects on the marking deque (due to black
|
| + // allocation) even in COMPLETE state. This may happen if scavenges are
|
| + // forced e.g. in tests. It should not happen when COMPLETE was set when
|
| + // incremental marking finished and a regular GC was triggered after that
|
| + // because should_hurry_ will force a full GC.
|
| + if (!heap_->mark_compact_collector()->marking_deque()->IsEmpty()) {
|
| double start = 0.0;
|
| if (FLAG_trace_incremental_marking || FLAG_print_cumulative_gc_stat) {
|
| start = heap_->MonotonicallyIncreasingTimeInMs();
|
| @@ -964,6 +1007,7 @@ void IncrementalMarking::Stop() {
|
| heap_->isolate()->stack_guard()->ClearGC();
|
| state_ = STOPPED;
|
| is_compacting_ = false;
|
| + FinishBlackAllocation();
|
| }
|
|
|
|
|
| @@ -1182,6 +1226,11 @@ intptr_t IncrementalMarking::Step(intptr_t allocated_bytes,
|
| StartMarking();
|
| }
|
| } else if (state_ == MARKING) {
|
| + if (FLAG_black_allocation && !black_allocation()) {
|
| + // If black allocation was not started when incremental marking started
|
| + // start it now.
|
| + StartBlackAllocation();
|
| + }
|
| bytes_processed = ProcessMarkingDeque(bytes_to_process);
|
| if (heap_->mark_compact_collector()->marking_deque()->IsEmpty()) {
|
| if (completion == FORCE_COMPLETION ||
|
|
|