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

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

Issue 7867040: Reduce imprecision of incremental marking. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/gc
Patch Set: Created 9 years, 3 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 | Annotate | Revision Log
« no previous file with comments | « src/incremental-marking.h ('k') | src/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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 12 matching lines...) Expand all
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "incremental-marking.h" 30 #include "incremental-marking.h"
31 31
32 #include "code-stubs.h" 32 #include "code-stubs.h"
33 #include "compilation-cache.h"
33 #include "v8conversions.h" 34 #include "v8conversions.h"
34 35
35 namespace v8 { 36 namespace v8 {
36 namespace internal { 37 namespace internal {
37 38
38 39
39 IncrementalMarking::IncrementalMarking(Heap* heap) 40 IncrementalMarking::IncrementalMarking(Heap* heap)
40 : heap_(heap), 41 : heap_(heap),
41 state_(STOPPED), 42 state_(STOPPED),
42 marking_deque_memory_(NULL), 43 marking_deque_memory_(NULL),
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 if (FLAG_trace_incremental_marking) { 394 if (FLAG_trace_incremental_marking) {
394 PrintF("[IncrementalMarking] Start sweeping.\n"); 395 PrintF("[IncrementalMarking] Start sweeping.\n");
395 } 396 }
396 state_ = SWEEPING; 397 state_ = SWEEPING;
397 } 398 }
398 399
399 heap_->new_space()->LowerInlineAllocationLimit(kAllocatedThreshold); 400 heap_->new_space()->LowerInlineAllocationLimit(kAllocatedThreshold);
400 } 401 }
401 402
402 403
404 static void MarkObjectGrey(Object* obj) {
405 if (obj->IsHeapObject()) {
406 MarkBit mark_bit = Marking::MarkBitFrom(HeapObject::cast(obj));
407 Marking::AnyToGrey(mark_bit);
408 }
409 }
410
411
403 void IncrementalMarking::StartMarking() { 412 void IncrementalMarking::StartMarking() {
404 if (FLAG_trace_incremental_marking) { 413 if (FLAG_trace_incremental_marking) {
405 PrintF("[IncrementalMarking] Start marking\n"); 414 PrintF("[IncrementalMarking] Start marking\n");
406 } 415 }
407 416
408 is_compacting_ = !FLAG_never_compact && 417 is_compacting_ = !FLAG_never_compact &&
409 heap_->mark_compact_collector()->StartCompaction(); 418 heap_->mark_compact_collector()->StartCompaction();
410 419
411 state_ = MARKING; 420 state_ = MARKING;
412 421
(...skipping 10 matching lines...) Expand all
423 if (FLAG_force_marking_deque_overflows) size = 64 * kPointerSize; 432 if (FLAG_force_marking_deque_overflows) size = 64 * kPointerSize;
424 marking_deque_.Initialize(addr, addr + size); 433 marking_deque_.Initialize(addr, addr + size);
425 434
426 ActivateIncrementalWriteBarrier(); 435 ActivateIncrementalWriteBarrier();
427 436
428 #ifdef DEBUG 437 #ifdef DEBUG
429 // Marking bits are cleared by the sweeper. 438 // Marking bits are cleared by the sweeper.
430 heap_->mark_compact_collector()->VerifyMarkbitsAreClean(); 439 heap_->mark_compact_collector()->VerifyMarkbitsAreClean();
431 #endif 440 #endif
432 441
442 heap_->CompletelyClearInstanceofCache();
443 heap_->isolate()->compilation_cache()->MarkCompactPrologue();
444
445 if (FLAG_cleanup_code_caches_at_gc) {
446 MarkObjectGrey(heap_->polymorphic_code_cache());
447 }
448
433 // Mark strong roots grey. 449 // Mark strong roots grey.
434 IncrementalMarkingRootMarkingVisitor visitor(heap_, this); 450 IncrementalMarkingRootMarkingVisitor visitor(heap_, this);
435 heap_->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG); 451 heap_->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG);
436 452
437 // Ready to start incremental marking. 453 // Ready to start incremental marking.
438 if (FLAG_trace_incremental_marking) { 454 if (FLAG_trace_incremental_marking) {
439 PrintF("[IncrementalMarking] Running\n"); 455 PrintF("[IncrementalMarking] Running\n");
440 } 456 }
441 } 457 }
442 458
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
485 } 501 }
486 } 502 }
487 marking_deque_.set_top(new_top); 503 marking_deque_.set_top(new_top);
488 504
489 steps_took_since_last_gc_ = 0; 505 steps_took_since_last_gc_ = 0;
490 steps_count_since_last_gc_ = 0; 506 steps_count_since_last_gc_ = 0;
491 longest_step_ = 0.0; 507 longest_step_ = 0.0;
492 } 508 }
493 509
494 510
511 void IncrementalMarking::VisitGlobalContext(Context* ctx, ObjectVisitor* v) {
512 v->VisitPointers(
513 HeapObject::RawField(
514 ctx, Context::MarkCompactBodyDescriptor::kStartOffset),
515 HeapObject::RawField(
516 ctx, Context::MarkCompactBodyDescriptor::kEndOffset));
517
518 MarkCompactCollector* collector = heap_->mark_compact_collector();
519 for (int idx = Context::FIRST_WEAK_SLOT;
520 idx < Context::GLOBAL_CONTEXT_SLOTS;
521 ++idx) {
522 Object** slot =
523 HeapObject::RawField(ctx, FixedArray::OffsetOfElementAt(idx));
524 collector->RecordSlot(slot, slot, *slot);
525 }
526 }
527
528
495 void IncrementalMarking::Hurry() { 529 void IncrementalMarking::Hurry() {
496 if (state() == MARKING) { 530 if (state() == MARKING) {
497 double start = 0.0; 531 double start = 0.0;
498 if (FLAG_trace_incremental_marking) { 532 if (FLAG_trace_incremental_marking) {
499 PrintF("[IncrementalMarking] Hurry\n"); 533 PrintF("[IncrementalMarking] Hurry\n");
500 start = OS::TimeCurrentMillis(); 534 start = OS::TimeCurrentMillis();
501 } 535 }
502 // TODO(gc) hurry can mark objects it encounters black as mutator 536 // TODO(gc) hurry can mark objects it encounters black as mutator
503 // was stopped. 537 // was stopped.
504 Map* filler_map = heap_->one_pointer_filler_map(); 538 Map* filler_map = heap_->one_pointer_filler_map();
539 Map* global_context_map = heap_->global_context_map();
505 IncrementalMarkingMarkingVisitor marking_visitor(heap_, this); 540 IncrementalMarkingMarkingVisitor marking_visitor(heap_, this);
506 while (!marking_deque_.IsEmpty()) { 541 while (!marking_deque_.IsEmpty()) {
507 HeapObject* obj = marking_deque_.Pop(); 542 HeapObject* obj = marking_deque_.Pop();
508 543
509 // Explicitly skip one word fillers. Incremental markbit patterns are 544 // Explicitly skip one word fillers. Incremental markbit patterns are
510 // correct only for objects that occupy at least two words. 545 // correct only for objects that occupy at least two words.
511 if (obj->map() != filler_map) { 546 Map* map = obj->map();
547 if (map == filler_map) {
548 continue;
549 } else if (map == global_context_map) {
550 // Global contexts have weak fields.
551 VisitGlobalContext(Context::cast(obj), &marking_visitor);
552 } else {
512 obj->Iterate(&marking_visitor); 553 obj->Iterate(&marking_visitor);
513 MarkBit mark_bit = Marking::MarkBitFrom(obj);
514 ASSERT(!Marking::IsBlack(mark_bit));
515 Marking::MarkBlack(mark_bit);
516 MemoryChunk::IncrementLiveBytes(obj->address(), obj->Size());
517 } 554 }
555
556 MarkBit mark_bit = Marking::MarkBitFrom(obj);
557 ASSERT(!Marking::IsBlack(mark_bit));
558 Marking::MarkBlack(mark_bit);
559 MemoryChunk::IncrementLiveBytes(obj->address(), obj->Size());
518 } 560 }
519 state_ = COMPLETE; 561 state_ = COMPLETE;
520 if (FLAG_trace_incremental_marking) { 562 if (FLAG_trace_incremental_marking) {
521 double end = OS::TimeCurrentMillis(); 563 double end = OS::TimeCurrentMillis();
522 PrintF("[IncrementalMarking] Complete (hurry), spent %d ms.\n", 564 PrintF("[IncrementalMarking] Complete (hurry), spent %d ms.\n",
523 static_cast<int>(end - start)); 565 static_cast<int>(end - start));
524 } 566 }
525 } 567 }
568
569 if (FLAG_cleanup_code_caches_at_gc) {
570 Marking::GreyToBlack(Marking::MarkBitFrom(heap_->polymorphic_code_cache()));
571 }
572
573 Object* context = heap_->global_contexts_list();
574 while (!context->IsUndefined()) {
575 NormalizedMapCache* cache = Context::cast(context)->normalized_map_cache();
576 MarkBit mark_bit = Marking::MarkBitFrom(cache);
577 if (Marking::IsGrey(mark_bit)) Marking::GreyToBlack(mark_bit);
578 context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK);
579 }
526 } 580 }
527 581
528 582
529 void IncrementalMarking::Abort() { 583 void IncrementalMarking::Abort() {
530 if (IsStopped()) return; 584 if (IsStopped()) return;
531 if (FLAG_trace_incremental_marking) { 585 if (FLAG_trace_incremental_marking) {
532 PrintF("[IncrementalMarking] Aborting.\n"); 586 PrintF("[IncrementalMarking] Aborting.\n");
533 } 587 }
534 heap_->new_space()->LowerInlineAllocationLimit(0); 588 heap_->new_space()->LowerInlineAllocationLimit(0);
535 IncrementalMarking::set_should_hurry(false); 589 IncrementalMarking::set_should_hurry(false);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
595 start = OS::TimeCurrentMillis(); 649 start = OS::TimeCurrentMillis();
596 } 650 }
597 651
598 if (state_ == SWEEPING) { 652 if (state_ == SWEEPING) {
599 if (heap_->old_pointer_space()->AdvanceSweeper(bytes_to_process) && 653 if (heap_->old_pointer_space()->AdvanceSweeper(bytes_to_process) &&
600 heap_->old_data_space()->AdvanceSweeper(bytes_to_process)) { 654 heap_->old_data_space()->AdvanceSweeper(bytes_to_process)) {
601 StartMarking(); 655 StartMarking();
602 } 656 }
603 } else if (state_ == MARKING) { 657 } else if (state_ == MARKING) {
604 Map* filler_map = heap_->one_pointer_filler_map(); 658 Map* filler_map = heap_->one_pointer_filler_map();
659 Map* global_context_map = heap_->global_context_map();
605 IncrementalMarkingMarkingVisitor marking_visitor(heap_, this); 660 IncrementalMarkingMarkingVisitor marking_visitor(heap_, this);
606 while (!marking_deque_.IsEmpty() && bytes_to_process > 0) { 661 while (!marking_deque_.IsEmpty() && bytes_to_process > 0) {
607 HeapObject* obj = marking_deque_.Pop(); 662 HeapObject* obj = marking_deque_.Pop();
608 663
609 // Explicitly skip one word fillers. Incremental markbit patterns are 664 // Explicitly skip one word fillers. Incremental markbit patterns are
610 // correct only for objects that occupy at least two words. 665 // correct only for objects that occupy at least two words.
611 Map* map = obj->map(); 666 Map* map = obj->map();
612 if (map != filler_map) { 667 if (map == filler_map) continue;
613 ASSERT(Marking::IsGrey(Marking::MarkBitFrom(obj))); 668
614 int size = obj->SizeFromMap(map); 669 ASSERT(Marking::IsGrey(Marking::MarkBitFrom(obj)));
615 bytes_to_process -= size; 670 int size = obj->SizeFromMap(map);
616 MarkBit map_mark_bit = Marking::MarkBitFrom(map); 671 bytes_to_process -= size;
617 if (Marking::IsWhite(map_mark_bit)) { 672 MarkBit map_mark_bit = Marking::MarkBitFrom(map);
618 WhiteToGreyAndPush(map, map_mark_bit); 673 if (Marking::IsWhite(map_mark_bit)) {
619 } 674 WhiteToGreyAndPush(map, map_mark_bit);
620 // TODO(gc) switch to static visitor instead of normal visitor. 675 }
676
677 // TODO(gc) switch to static visitor instead of normal visitor.
678 if (map == global_context_map) {
679 // Global contexts have weak fields.
680 Context* ctx = Context::cast(obj);
681
682 // Mark grey without pushing it to the stack.
683 MarkObjectGrey(ctx->normalized_map_cache());
Erik Corry 2011/09/13 07:07:44 Perhaps the fact that this routine does not push t
684
685 VisitGlobalContext(ctx, &marking_visitor);
686 } else {
621 obj->IterateBody(map->instance_type(), size, &marking_visitor); 687 obj->IterateBody(map->instance_type(), size, &marking_visitor);
622 MarkBit obj_mark_bit = Marking::MarkBitFrom(obj);
623 ASSERT(!Marking::IsBlack(obj_mark_bit));
624 Marking::MarkBlack(obj_mark_bit);
625 MemoryChunk::IncrementLiveBytes(obj->address(), size);
626 } 688 }
689
690 MarkBit obj_mark_bit = Marking::MarkBitFrom(obj);
691 ASSERT(!Marking::IsBlack(obj_mark_bit));
692 Marking::MarkBlack(obj_mark_bit);
693 MemoryChunk::IncrementLiveBytes(obj->address(), size);
627 } 694 }
628 if (marking_deque_.IsEmpty()) MarkingComplete(); 695 if (marking_deque_.IsEmpty()) MarkingComplete();
629 } 696 }
630 697
631 allocated_ = 0; 698 allocated_ = 0;
632 699
633 steps_count_++; 700 steps_count_++;
634 steps_count_since_last_gc_++; 701 steps_count_since_last_gc_++;
635 702
636 bool speed_up = false; 703 bool speed_up = false;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
690 bytes_rescanned_ = 0; 757 bytes_rescanned_ = 0;
691 allocation_marking_factor_ = kInitialAllocationMarkingFactor; 758 allocation_marking_factor_ = kInitialAllocationMarkingFactor;
692 } 759 }
693 760
694 761
695 int64_t IncrementalMarking::SpaceLeftInOldSpace() { 762 int64_t IncrementalMarking::SpaceLeftInOldSpace() {
696 return heap_->MaxOldGenerationSize() - heap_->PromotedSpaceSize(); 763 return heap_->MaxOldGenerationSize() - heap_->PromotedSpaceSize();
697 } 764 }
698 765
699 } } // namespace v8::internal 766 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/incremental-marking.h ('k') | src/mark-compact.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698