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

Side by Side Diff: src/heap/incremental-marking.cc

Issue 1420423009: [heap] Black allocation. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 9 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 unified diff | Download patch
« no previous file with comments | « src/heap/incremental-marking.h ('k') | src/heap/mark-compact.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/heap/incremental-marking.h" 5 #include "src/heap/incremental-marking.h"
6 6
7 #include "src/code-stubs.h" 7 #include "src/code-stubs.h"
8 #include "src/compilation-cache.h" 8 #include "src/compilation-cache.h"
9 #include "src/conversions.h" 9 #include "src/conversions.h"
10 #include "src/heap/gc-idle-time-handler.h" 10 #include "src/heap/gc-idle-time-handler.h"
(...skipping 24 matching lines...) Expand all
35 bytes_rescanned_(0), 35 bytes_rescanned_(0),
36 should_hurry_(false), 36 should_hurry_(false),
37 marking_speed_(0), 37 marking_speed_(0),
38 bytes_scanned_(0), 38 bytes_scanned_(0),
39 allocated_(0), 39 allocated_(0),
40 write_barriers_invoked_since_last_step_(0), 40 write_barriers_invoked_since_last_step_(0),
41 idle_marking_delay_counter_(0), 41 idle_marking_delay_counter_(0),
42 no_marking_scope_depth_(0), 42 no_marking_scope_depth_(0),
43 unscanned_bytes_of_large_object_(0), 43 unscanned_bytes_of_large_object_(0),
44 was_activated_(false), 44 was_activated_(false),
45 black_allocation_(false),
45 finalize_marking_completed_(false), 46 finalize_marking_completed_(false),
46 incremental_marking_finalization_rounds_(0), 47 incremental_marking_finalization_rounds_(0),
47 request_type_(COMPLETE_MARKING) {} 48 request_type_(COMPLETE_MARKING) {}
48 49
49 bool IncrementalMarking::BaseRecordWrite(HeapObject* obj, Object* value) { 50 bool IncrementalMarking::BaseRecordWrite(HeapObject* obj, Object* value) {
50 HeapObject* value_heap_obj = HeapObject::cast(value); 51 HeapObject* value_heap_obj = HeapObject::cast(value);
51 MarkBit value_bit = Marking::MarkBitFrom(value_heap_obj); 52 MarkBit value_bit = Marking::MarkBitFrom(value_heap_obj);
52 DCHECK(!Marking::IsImpossible(value_bit)); 53 DCHECK(!Marking::IsImpossible(value_bit));
53 54
54 MarkBit obj_bit = Marking::MarkBitFrom(obj); 55 MarkBit obj_bit = Marking::MarkBitFrom(obj);
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 MarkBit mark_bit = Marking::MarkBitFrom(heap_object); 315 MarkBit mark_bit = Marking::MarkBitFrom(heap_object);
315 if (Marking::IsWhite(mark_bit)) { 316 if (Marking::IsWhite(mark_bit)) {
316 Marking::MarkBlack(mark_bit); 317 Marking::MarkBlack(mark_bit);
317 MemoryChunk::IncrementLiveBytesFromGC(heap_object, heap_object->Size()); 318 MemoryChunk::IncrementLiveBytesFromGC(heap_object, heap_object->Size());
318 return true; 319 return true;
319 } 320 }
320 return false; 321 return false;
321 } 322 }
322 }; 323 };
323 324
325 void IncrementalMarking::IterateBlackObject(HeapObject* object) {
326 if (black_allocation() &&
327 Page::FromAddress(object->address())->IsFlagSet(Page::BLACK_PAGE)) {
328 IncrementalMarkingMarkingVisitor::IterateBody(object->map(), object);
329 }
330 }
324 331
325 class IncrementalMarkingRootMarkingVisitor : public ObjectVisitor { 332 class IncrementalMarkingRootMarkingVisitor : public ObjectVisitor {
326 public: 333 public:
327 explicit IncrementalMarkingRootMarkingVisitor( 334 explicit IncrementalMarkingRootMarkingVisitor(
328 IncrementalMarking* incremental_marking) 335 IncrementalMarking* incremental_marking)
329 : heap_(incremental_marking->heap()) {} 336 : heap_(incremental_marking->heap()) {}
330 337
331 void VisitPointer(Object** p) override { MarkObjectByPointer(p); } 338 void VisitPointer(Object** p) override { MarkObjectByPointer(p); }
332 339
333 void VisitPointers(Object** start, Object** end) override { 340 void VisitPointers(Object** start, Object** end) override {
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 state_ = SWEEPING; 554 state_ = SWEEPING;
548 } 555 }
549 556
550 heap_->new_space()->AddAllocationObserver(&observer_); 557 heap_->new_space()->AddAllocationObserver(&observer_);
551 558
552 incremental_marking_job()->Start(heap_); 559 incremental_marking_job()->Start(heap_);
553 } 560 }
554 561
555 562
556 void IncrementalMarking::StartMarking() { 563 void IncrementalMarking::StartMarking() {
564 if (heap_->isolate()->serializer_enabled()) {
565 // Black allocation currently starts when we start incremental marking,
566 // but we cannot enable black allocation while deserializing. Hence, we
567 // have to delay the start of incremental marking in that case.
568 if (FLAG_trace_incremental_marking) {
569 PrintF("[IncrementalMarking] Start delayed - serializer\n");
570 }
571 return;
572 }
557 if (FLAG_trace_incremental_marking) { 573 if (FLAG_trace_incremental_marking) {
558 PrintF("[IncrementalMarking] Start marking\n"); 574 PrintF("[IncrementalMarking] Start marking\n");
559 } 575 }
560 576
561 is_compacting_ = !FLAG_never_compact && 577 is_compacting_ = !FLAG_never_compact &&
562 heap_->mark_compact_collector()->StartCompaction( 578 heap_->mark_compact_collector()->StartCompaction(
563 MarkCompactCollector::INCREMENTAL_COMPACTION); 579 MarkCompactCollector::INCREMENTAL_COMPACTION);
564 580
565 state_ = MARKING; 581 state_ = MARKING;
566 582
(...skipping 21 matching lines...) Expand all
588 if (FLAG_cleanup_code_caches_at_gc) { 604 if (FLAG_cleanup_code_caches_at_gc) {
589 // We will mark cache black with a separate pass 605 // We will mark cache black with a separate pass
590 // when we finish marking. 606 // when we finish marking.
591 MarkObjectGreyDoNotEnqueue(heap_->polymorphic_code_cache()); 607 MarkObjectGreyDoNotEnqueue(heap_->polymorphic_code_cache());
592 } 608 }
593 609
594 // Mark strong roots grey. 610 // Mark strong roots grey.
595 IncrementalMarkingRootMarkingVisitor visitor(this); 611 IncrementalMarkingRootMarkingVisitor visitor(this);
596 heap_->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG); 612 heap_->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG);
597 613
614 if (FLAG_black_allocation) {
615 StartBlackAllocation();
616 }
617
598 // Ready to start incremental marking. 618 // Ready to start incremental marking.
599 if (FLAG_trace_incremental_marking) { 619 if (FLAG_trace_incremental_marking) {
600 PrintF("[IncrementalMarking] Running\n"); 620 PrintF("[IncrementalMarking] Running\n");
601 } 621 }
602 } 622 }
603 623
624 void IncrementalMarking::StartBlackAllocation() {
625 DCHECK(FLAG_black_allocation);
626 DCHECK(IsMarking());
627 black_allocation_ = true;
628 PagedSpaces spaces(heap());
629 for (PagedSpace* space = spaces.next(); space != NULL;
630 space = spaces.next()) {
631 space->EmptyAllocationInfo();
632 space->free_list()->Reset();
633 }
634 if (FLAG_trace_incremental_marking) {
635 PrintF("[IncrementalMarking] Black allocation started\n");
636 }
637 }
638
639 void IncrementalMarking::FinishBlackAllocation() {
640 black_allocation_ = false;
641 if (FLAG_trace_incremental_marking) {
642 PrintF("[IncrementalMarking] Black allocation finished\n");
643 }
644 }
604 645
605 void IncrementalMarking::MarkRoots() { 646 void IncrementalMarking::MarkRoots() {
606 DCHECK(!finalize_marking_completed_); 647 DCHECK(!finalize_marking_completed_);
607 DCHECK(IsMarking()); 648 DCHECK(IsMarking());
608 649
609 IncrementalMarkingRootMarkingVisitor visitor(this); 650 IncrementalMarkingRootMarkingVisitor visitor(this);
610 heap_->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG); 651 heap_->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG);
611 } 652 }
612 653
613 654
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
796 // Only pointers to from space have to be updated. 837 // Only pointers to from space have to be updated.
797 if (heap_->InFromSpace(obj)) { 838 if (heap_->InFromSpace(obj)) {
798 MapWord map_word = obj->map_word(); 839 MapWord map_word = obj->map_word();
799 // There may be objects on the marking deque that do not exist anymore, 840 // There may be objects on the marking deque that do not exist anymore,
800 // e.g. left trimmed objects or objects from the root set (frames). 841 // e.g. left trimmed objects or objects from the root set (frames).
801 // If these object are dead at scavenging time, their marking deque 842 // If these object are dead at scavenging time, their marking deque
802 // entries will not point to forwarding addresses. Hence, we can discard 843 // entries will not point to forwarding addresses. Hence, we can discard
803 // them. 844 // them.
804 if (map_word.IsForwardingAddress()) { 845 if (map_word.IsForwardingAddress()) {
805 HeapObject* dest = map_word.ToForwardingAddress(); 846 HeapObject* dest = map_word.ToForwardingAddress();
847 if (Page::FromAddress(dest->address())->IsFlagSet(Page::BLACK_PAGE))
848 continue;
806 array[new_top] = dest; 849 array[new_top] = dest;
807 new_top = ((new_top + 1) & mask); 850 new_top = ((new_top + 1) & mask);
808 DCHECK(new_top != marking_deque->bottom()); 851 DCHECK(new_top != marking_deque->bottom());
809 #ifdef DEBUG 852 #ifdef DEBUG
810 MarkBit mark_bit = Marking::MarkBitFrom(obj); 853 MarkBit mark_bit = Marking::MarkBitFrom(obj);
811 DCHECK(Marking::IsGrey(mark_bit) || 854 DCHECK(Marking::IsGrey(mark_bit) ||
812 (obj->IsFiller() && Marking::IsWhite(mark_bit))); 855 (obj->IsFiller() && Marking::IsWhite(mark_bit)));
813 #endif 856 #endif
814 } 857 }
815 } else if (obj->map() != filler_map) { 858 } else if (obj->map() != filler_map) {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
895 // correct only for objects that occupy at least two words. 938 // correct only for objects that occupy at least two words.
896 Map* map = obj->map(); 939 Map* map = obj->map();
897 if (map == filler_map) continue; 940 if (map == filler_map) continue;
898 941
899 VisitObject(map, obj, obj->SizeFromMap(map)); 942 VisitObject(map, obj, obj->SizeFromMap(map));
900 } 943 }
901 } 944 }
902 945
903 946
904 void IncrementalMarking::Hurry() { 947 void IncrementalMarking::Hurry() {
905 if (state() == MARKING) { 948 // A scavenge may have pushed new objects on the marking deque (due to black
949 // allocation) even in COMPLETE state. This may happen if scavenges are
950 // forced e.g. in tests. It should not happen when COMPLETE was set when
951 // incremental marking finished and a regular GC was triggered after that
952 // because should_hurry_ will force a full GC.
953 if (!heap_->mark_compact_collector()->marking_deque()->IsEmpty()) {
906 double start = 0.0; 954 double start = 0.0;
907 if (FLAG_trace_incremental_marking || FLAG_print_cumulative_gc_stat) { 955 if (FLAG_trace_incremental_marking || FLAG_print_cumulative_gc_stat) {
908 start = heap_->MonotonicallyIncreasingTimeInMs(); 956 start = heap_->MonotonicallyIncreasingTimeInMs();
909 if (FLAG_trace_incremental_marking) { 957 if (FLAG_trace_incremental_marking) {
910 PrintF("[IncrementalMarking] Hurry\n"); 958 PrintF("[IncrementalMarking] Hurry\n");
911 } 959 }
912 } 960 }
913 // TODO(gc) hurry can mark objects it encounters black as mutator 961 // TODO(gc) hurry can mark objects it encounters black as mutator
914 // was stopped. 962 // was stopped.
915 ProcessMarkingDeque(); 963 ProcessMarkingDeque();
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 IncrementalMarking::set_should_hurry(false); 1008 IncrementalMarking::set_should_hurry(false);
961 ResetStepCounters(); 1009 ResetStepCounters();
962 if (IsMarking()) { 1010 if (IsMarking()) {
963 PatchIncrementalMarkingRecordWriteStubs(heap_, 1011 PatchIncrementalMarkingRecordWriteStubs(heap_,
964 RecordWriteStub::STORE_BUFFER_ONLY); 1012 RecordWriteStub::STORE_BUFFER_ONLY);
965 DeactivateIncrementalWriteBarrier(); 1013 DeactivateIncrementalWriteBarrier();
966 } 1014 }
967 heap_->isolate()->stack_guard()->ClearGC(); 1015 heap_->isolate()->stack_guard()->ClearGC();
968 state_ = STOPPED; 1016 state_ = STOPPED;
969 is_compacting_ = false; 1017 is_compacting_ = false;
1018 FinishBlackAllocation();
970 } 1019 }
971 1020
972 1021
973 void IncrementalMarking::Finalize() { 1022 void IncrementalMarking::Finalize() {
974 Hurry(); 1023 Hurry();
975 Stop(); 1024 Stop();
976 } 1025 }
977 1026
978 1027
979 void IncrementalMarking::FinalizeMarking(CompletionAction action) { 1028 void IncrementalMarking::FinalizeMarking(CompletionAction action) {
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
1244 void IncrementalMarking::IncrementIdleMarkingDelayCounter() { 1293 void IncrementalMarking::IncrementIdleMarkingDelayCounter() {
1245 idle_marking_delay_counter_++; 1294 idle_marking_delay_counter_++;
1246 } 1295 }
1247 1296
1248 1297
1249 void IncrementalMarking::ClearIdleMarkingDelayCounter() { 1298 void IncrementalMarking::ClearIdleMarkingDelayCounter() {
1250 idle_marking_delay_counter_ = 0; 1299 idle_marking_delay_counter_ = 0;
1251 } 1300 }
1252 } // namespace internal 1301 } // namespace internal
1253 } // namespace v8 1302 } // namespace v8
OLDNEW
« no previous file with comments | « src/heap/incremental-marking.h ('k') | src/heap/mark-compact.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698