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

Side by Side Diff: src/mark-compact.cc

Issue 6691054: [Arguments] Merge (7442,7496] from bleeding_edge. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/arguments
Patch Set: Created 9 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/mark-compact.h ('k') | src/mips/frames-mips.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 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 MarkLiveObjects(); 79 MarkLiveObjects();
80 80
81 if (FLAG_collect_maps) ClearNonLiveTransitions(); 81 if (FLAG_collect_maps) ClearNonLiveTransitions();
82 82
83 SweepLargeObjectSpace(); 83 SweepLargeObjectSpace();
84 84
85 if (IsCompacting()) { 85 if (IsCompacting()) {
86 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_COMPACT); 86 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_COMPACT);
87 EncodeForwardingAddresses(); 87 EncodeForwardingAddresses();
88 88
89 heap_->MarkMapPointersAsEncoded(true); 89 heap()->MarkMapPointersAsEncoded(true);
90 UpdatePointers(); 90 UpdatePointers();
91 heap_->MarkMapPointersAsEncoded(false); 91 heap()->MarkMapPointersAsEncoded(false);
92 heap_->isolate()->pc_to_code_cache()->Flush(); 92 heap()->isolate()->pc_to_code_cache()->Flush();
93 93
94 RelocateObjects(); 94 RelocateObjects();
95 } else { 95 } else {
96 SweepSpaces(); 96 SweepSpaces();
97 heap_->isolate()->pc_to_code_cache()->Flush(); 97 heap()->isolate()->pc_to_code_cache()->Flush();
98 } 98 }
99 99
100 Finish(); 100 Finish();
101 101
102 // Save the count of marked objects remaining after the collection and 102 // Save the count of marked objects remaining after the collection and
103 // null out the GC tracer. 103 // null out the GC tracer.
104 previous_marked_count_ = tracer_->marked_count(); 104 previous_marked_count_ = tracer_->marked_count();
105 ASSERT(previous_marked_count_ == 0); 105 ASSERT(previous_marked_count_ == 0);
106 tracer_ = NULL; 106 tracer_ = NULL;
107 } 107 }
108 108
109 109
110 void MarkCompactCollector::Prepare(GCTracer* tracer) { 110 void MarkCompactCollector::Prepare(GCTracer* tracer) {
111 // Rather than passing the tracer around we stash it in a static member 111 // Rather than passing the tracer around we stash it in a static member
112 // variable. 112 // variable.
113 tracer_ = tracer; 113 tracer_ = tracer;
114 114
115 #ifdef DEBUG 115 #ifdef DEBUG
116 ASSERT(state_ == IDLE); 116 ASSERT(state_ == IDLE);
117 state_ = PREPARE_GC; 117 state_ = PREPARE_GC;
118 #endif 118 #endif
119 ASSERT(!FLAG_always_compact || !FLAG_never_compact); 119 ASSERT(!FLAG_always_compact || !FLAG_never_compact);
120 120
121 compacting_collection_ = 121 compacting_collection_ =
122 FLAG_always_compact || force_compaction_ || compact_on_next_gc_; 122 FLAG_always_compact || force_compaction_ || compact_on_next_gc_;
123 compact_on_next_gc_ = false; 123 compact_on_next_gc_ = false;
124 124
125 if (FLAG_never_compact) compacting_collection_ = false; 125 if (FLAG_never_compact) compacting_collection_ = false;
126 if (!HEAP->map_space()->MapPointersEncodable()) 126 if (!heap()->map_space()->MapPointersEncodable())
127 compacting_collection_ = false; 127 compacting_collection_ = false;
128 if (FLAG_collect_maps) CreateBackPointers(); 128 if (FLAG_collect_maps) CreateBackPointers();
129 #ifdef ENABLE_GDB_JIT_INTERFACE 129 #ifdef ENABLE_GDB_JIT_INTERFACE
130 if (FLAG_gdbjit) { 130 if (FLAG_gdbjit) {
131 // If GDBJIT interface is active disable compaction. 131 // If GDBJIT interface is active disable compaction.
132 compacting_collection_ = false; 132 compacting_collection_ = false;
133 } 133 }
134 #endif 134 #endif
135 135
136 PagedSpaces spaces; 136 PagedSpaces spaces;
(...skipping 17 matching lines...) Expand all
154 154
155 void MarkCompactCollector::Finish() { 155 void MarkCompactCollector::Finish() {
156 #ifdef DEBUG 156 #ifdef DEBUG
157 ASSERT(state_ == SWEEP_SPACES || state_ == RELOCATE_OBJECTS); 157 ASSERT(state_ == SWEEP_SPACES || state_ == RELOCATE_OBJECTS);
158 state_ = IDLE; 158 state_ = IDLE;
159 #endif 159 #endif
160 // The stub cache is not traversed during GC; clear the cache to 160 // The stub cache is not traversed during GC; clear the cache to
161 // force lazy re-initialization of it. This must be done after the 161 // force lazy re-initialization of it. This must be done after the
162 // GC, because it relies on the new address of certain old space 162 // GC, because it relies on the new address of certain old space
163 // objects (empty string, illegal builtin). 163 // objects (empty string, illegal builtin).
164 heap_->isolate()->stub_cache()->Clear(); 164 heap()->isolate()->stub_cache()->Clear();
165 165
166 heap_->external_string_table_.CleanUp(); 166 heap()->external_string_table_.CleanUp();
167 167
168 // If we've just compacted old space there's no reason to check the 168 // If we've just compacted old space there's no reason to check the
169 // fragmentation limit. Just return. 169 // fragmentation limit. Just return.
170 if (HasCompacted()) return; 170 if (HasCompacted()) return;
171 171
172 // We compact the old generation on the next GC if it has gotten too 172 // We compact the old generation on the next GC if it has gotten too
173 // fragmented (ie, we could recover an expected amount of space by 173 // fragmented (ie, we could recover an expected amount of space by
174 // reclaiming the waste and free list blocks). 174 // reclaiming the waste and free list blocks).
175 static const int kFragmentationLimit = 15; // Percent. 175 static const int kFragmentationLimit = 15; // Percent.
176 static const int kFragmentationAllowed = 1 * MB; // Absolute. 176 static const int kFragmentationAllowed = 1 * MB; // Absolute.
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 INLINE(static void VisitPointers(Heap* heap, Object** start, Object** end)) { 449 INLINE(static void VisitPointers(Heap* heap, Object** start, Object** end)) {
450 // Mark all objects pointed to in [start, end). 450 // Mark all objects pointed to in [start, end).
451 const int kMinRangeForMarkingRecursion = 64; 451 const int kMinRangeForMarkingRecursion = 64;
452 if (end - start >= kMinRangeForMarkingRecursion) { 452 if (end - start >= kMinRangeForMarkingRecursion) {
453 if (VisitUnmarkedObjects(heap, start, end)) return; 453 if (VisitUnmarkedObjects(heap, start, end)) return;
454 // We are close to a stack overflow, so just mark the objects. 454 // We are close to a stack overflow, so just mark the objects.
455 } 455 }
456 for (Object** p = start; p < end; p++) MarkObjectByPointer(heap, p); 456 for (Object** p = start; p < end; p++) MarkObjectByPointer(heap, p);
457 } 457 }
458 458
459 static inline void VisitCodeTarget(RelocInfo* rinfo) { 459 static inline void VisitCodeTarget(Heap* heap, RelocInfo* rinfo) {
460 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); 460 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
461 Code* code = Code::GetCodeFromTargetAddress(rinfo->target_address()); 461 Code* code = Code::GetCodeFromTargetAddress(rinfo->target_address());
462 if (FLAG_cleanup_ics_at_gc && code->is_inline_cache_stub()) { 462 if (FLAG_cleanup_ics_at_gc && code->is_inline_cache_stub()) {
463 IC::Clear(rinfo->pc()); 463 IC::Clear(rinfo->pc());
464 // Please note targets for cleared inline cached do not have to be 464 // Please note targets for cleared inline cached do not have to be
465 // marked since they are contained in HEAP->non_monomorphic_cache(). 465 // marked since they are contained in HEAP->non_monomorphic_cache().
466 } else { 466 } else {
467 HEAP->mark_compact_collector()->MarkObject(code); 467 heap->mark_compact_collector()->MarkObject(code);
468 } 468 }
469 } 469 }
470 470
471 static void VisitGlobalPropertyCell(RelocInfo* rinfo) { 471 static void VisitGlobalPropertyCell(Heap* heap, RelocInfo* rinfo) {
472 ASSERT(rinfo->rmode() == RelocInfo::GLOBAL_PROPERTY_CELL); 472 ASSERT(rinfo->rmode() == RelocInfo::GLOBAL_PROPERTY_CELL);
473 Object* cell = rinfo->target_cell(); 473 Object* cell = rinfo->target_cell();
474 Object* old_cell = cell; 474 Object* old_cell = cell;
475 VisitPointer(HEAP, &cell); 475 VisitPointer(heap, &cell);
476 if (cell != old_cell) { 476 if (cell != old_cell) {
477 rinfo->set_target_cell(reinterpret_cast<JSGlobalPropertyCell*>(cell)); 477 rinfo->set_target_cell(reinterpret_cast<JSGlobalPropertyCell*>(cell));
478 } 478 }
479 } 479 }
480 480
481 static inline void VisitDebugTarget(RelocInfo* rinfo) { 481 static inline void VisitDebugTarget(Heap* heap, RelocInfo* rinfo) {
482 ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) && 482 ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) &&
483 rinfo->IsPatchedReturnSequence()) || 483 rinfo->IsPatchedReturnSequence()) ||
484 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && 484 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
485 rinfo->IsPatchedDebugBreakSlotSequence())); 485 rinfo->IsPatchedDebugBreakSlotSequence()));
486 HeapObject* code = Code::GetCodeFromTargetAddress(rinfo->call_address()); 486 HeapObject* code = Code::GetCodeFromTargetAddress(rinfo->call_address());
487 HEAP->mark_compact_collector()->MarkObject(code); 487 heap->mark_compact_collector()->MarkObject(code);
488 } 488 }
489 489
490 // Mark object pointed to by p. 490 // Mark object pointed to by p.
491 INLINE(static void MarkObjectByPointer(Heap* heap, Object** p)) { 491 INLINE(static void MarkObjectByPointer(Heap* heap, Object** p)) {
492 if (!(*p)->IsHeapObject()) return; 492 if (!(*p)->IsHeapObject()) return;
493 HeapObject* object = ShortCircuitConsString(p); 493 HeapObject* object = ShortCircuitConsString(p);
494 heap->mark_compact_collector()->MarkObject(object); 494 if (!object->IsMarked()) {
495 heap->mark_compact_collector()->MarkUnmarkedObject(object);
496 }
495 } 497 }
496 498
497 499
498 // Visit an unmarked object. 500 // Visit an unmarked object.
499 static inline void VisitUnmarkedObject(HeapObject* obj) { 501 INLINE(static void VisitUnmarkedObject(MarkCompactCollector* collector,
502 HeapObject* obj)) {
500 #ifdef DEBUG 503 #ifdef DEBUG
501 ASSERT(HEAP->Contains(obj)); 504 ASSERT(Isolate::Current()->heap()->Contains(obj));
502 ASSERT(!obj->IsMarked()); 505 ASSERT(!obj->IsMarked());
503 #endif 506 #endif
504 Map* map = obj->map(); 507 Map* map = obj->map();
505 MarkCompactCollector* collector = map->heap()->mark_compact_collector();
506 collector->SetMark(obj); 508 collector->SetMark(obj);
507 // Mark the map pointer and the body. 509 // Mark the map pointer and the body.
508 collector->MarkObject(map); 510 if (!map->IsMarked()) collector->MarkUnmarkedObject(map);
509 IterateBody(map, obj); 511 IterateBody(map, obj);
510 } 512 }
511 513
512 // Visit all unmarked objects pointed to by [start, end). 514 // Visit all unmarked objects pointed to by [start, end).
513 // Returns false if the operation fails (lack of stack space). 515 // Returns false if the operation fails (lack of stack space).
514 static inline bool VisitUnmarkedObjects(Heap* heap, 516 static inline bool VisitUnmarkedObjects(Heap* heap,
515 Object** start, 517 Object** start,
516 Object** end) { 518 Object** end) {
517 // Return false is we are close to the stack limit. 519 // Return false is we are close to the stack limit.
518 StackLimitCheck check(heap->isolate()); 520 StackLimitCheck check(heap->isolate());
519 if (check.HasOverflowed()) return false; 521 if (check.HasOverflowed()) return false;
520 522
523 MarkCompactCollector* collector = heap->mark_compact_collector();
521 // Visit the unmarked objects. 524 // Visit the unmarked objects.
522 for (Object** p = start; p < end; p++) { 525 for (Object** p = start; p < end; p++) {
523 if (!(*p)->IsHeapObject()) continue; 526 if (!(*p)->IsHeapObject()) continue;
524 HeapObject* obj = HeapObject::cast(*p); 527 HeapObject* obj = HeapObject::cast(*p);
525 if (obj->IsMarked()) continue; 528 if (obj->IsMarked()) continue;
526 VisitUnmarkedObject(obj); 529 VisitUnmarkedObject(collector, obj);
527 } 530 }
528 return true; 531 return true;
529 } 532 }
530 533
531 static inline void VisitExternalReference(Address* p) { } 534 static inline void VisitExternalReference(Address* p) { }
532 static inline void VisitRuntimeEntry(RelocInfo* rinfo) { } 535 static inline void VisitRuntimeEntry(RelocInfo* rinfo) { }
533 536
534 private: 537 private:
535 class DataObjectVisitor { 538 class DataObjectVisitor {
536 public: 539 public:
(...skipping 17 matching lines...) Expand all
554 reinterpret_cast<Code*>(object)->CodeIterateBody<StaticMarkingVisitor>( 557 reinterpret_cast<Code*>(object)->CodeIterateBody<StaticMarkingVisitor>(
555 map->heap()); 558 map->heap());
556 } 559 }
557 560
558 // Code flushing support. 561 // Code flushing support.
559 562
560 // How many collections newly compiled code object will survive before being 563 // How many collections newly compiled code object will survive before being
561 // flushed. 564 // flushed.
562 static const int kCodeAgeThreshold = 5; 565 static const int kCodeAgeThreshold = 5;
563 566
564 inline static bool HasSourceCode(SharedFunctionInfo* info) { 567 inline static bool HasSourceCode(Heap* heap, SharedFunctionInfo* info) {
565 Object* undefined = HEAP->raw_unchecked_undefined_value(); 568 Object* undefined = heap->raw_unchecked_undefined_value();
566 return (info->script() != undefined) && 569 return (info->script() != undefined) &&
567 (reinterpret_cast<Script*>(info->script())->source() != undefined); 570 (reinterpret_cast<Script*>(info->script())->source() != undefined);
568 } 571 }
569 572
570 573
571 inline static bool IsCompiled(JSFunction* function) { 574 inline static bool IsCompiled(JSFunction* function) {
572 return function->unchecked_code() != 575 return function->unchecked_code() !=
573 function->GetIsolate()->builtins()->builtin(Builtins::kLazyCompile); 576 function->GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
574 } 577 }
575 578
576 inline static bool IsCompiled(SharedFunctionInfo* function) { 579 inline static bool IsCompiled(SharedFunctionInfo* function) {
577 return function->unchecked_code() != 580 return function->unchecked_code() !=
578 function->GetIsolate()->builtins()->builtin(Builtins::kLazyCompile); 581 function->GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
579 } 582 }
580 583
581 inline static bool IsFlushable(JSFunction* function) { 584 inline static bool IsFlushable(Heap* heap, JSFunction* function) {
582 SharedFunctionInfo* shared_info = function->unchecked_shared(); 585 SharedFunctionInfo* shared_info = function->unchecked_shared();
583 586
584 // Code is either on stack, in compilation cache or referenced 587 // Code is either on stack, in compilation cache or referenced
585 // by optimized version of function. 588 // by optimized version of function.
586 if (function->unchecked_code()->IsMarked()) { 589 if (function->unchecked_code()->IsMarked()) {
587 shared_info->set_code_age(0); 590 shared_info->set_code_age(0);
588 return false; 591 return false;
589 } 592 }
590 593
591 // We do not flush code for optimized functions. 594 // We do not flush code for optimized functions.
592 if (function->code() != shared_info->unchecked_code()) { 595 if (function->code() != shared_info->unchecked_code()) {
593 return false; 596 return false;
594 } 597 }
595 598
596 return IsFlushable(shared_info); 599 return IsFlushable(heap, shared_info);
597 } 600 }
598 601
599 inline static bool IsFlushable(SharedFunctionInfo* shared_info) { 602 inline static bool IsFlushable(Heap* heap, SharedFunctionInfo* shared_info) {
600 // Code is either on stack, in compilation cache or referenced 603 // Code is either on stack, in compilation cache or referenced
601 // by optimized version of function. 604 // by optimized version of function.
602 if (shared_info->unchecked_code()->IsMarked()) { 605 if (shared_info->unchecked_code()->IsMarked()) {
603 shared_info->set_code_age(0); 606 shared_info->set_code_age(0);
604 return false; 607 return false;
605 } 608 }
606 609
607 // The function must be compiled and have the source code available, 610 // The function must be compiled and have the source code available,
608 // to be able to recompile it in case we need the function again. 611 // to be able to recompile it in case we need the function again.
609 if (!(shared_info->is_compiled() && HasSourceCode(shared_info))) { 612 if (!(shared_info->is_compiled() && HasSourceCode(heap, shared_info))) {
610 return false; 613 return false;
611 } 614 }
612 615
613 // We never flush code for Api functions. 616 // We never flush code for Api functions.
614 Object* function_data = shared_info->function_data(); 617 Object* function_data = shared_info->function_data();
615 if (function_data->IsHeapObject() && 618 if (function_data->IsHeapObject() &&
616 (SafeMap(function_data)->instance_type() == 619 (SafeMap(function_data)->instance_type() ==
617 FUNCTION_TEMPLATE_INFO_TYPE)) { 620 FUNCTION_TEMPLATE_INFO_TYPE)) {
618 return false; 621 return false;
619 } 622 }
(...skipping 11 matching lines...) Expand all
631 if (shared_info->code_age() < kCodeAgeThreshold) { 634 if (shared_info->code_age() < kCodeAgeThreshold) {
632 shared_info->set_code_age(shared_info->code_age() + 1); 635 shared_info->set_code_age(shared_info->code_age() + 1);
633 return false; 636 return false;
634 } 637 }
635 638
636 return true; 639 return true;
637 } 640 }
638 641
639 642
640 static bool FlushCodeForFunction(Heap* heap, JSFunction* function) { 643 static bool FlushCodeForFunction(Heap* heap, JSFunction* function) {
641 if (!IsFlushable(function)) return false; 644 if (!IsFlushable(heap, function)) return false;
642 645
643 // This function's code looks flushable. But we have to postpone the 646 // This function's code looks flushable. But we have to postpone the
644 // decision until we see all functions that point to the same 647 // decision until we see all functions that point to the same
645 // SharedFunctionInfo because some of them might be optimized. 648 // SharedFunctionInfo because some of them might be optimized.
646 // That would make the nonoptimized version of the code nonflushable, 649 // That would make the nonoptimized version of the code nonflushable,
647 // because it is required for bailing out from optimized code. 650 // because it is required for bailing out from optimized code.
648 heap->mark_compact_collector()->code_flusher()->AddCandidate(function); 651 heap->mark_compact_collector()->code_flusher()->AddCandidate(function);
649 return true; 652 return true;
650 } 653 }
651 654
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 711
709 712
710 static void VisitSharedFunctionInfoAndFlushCodeGeneric( 713 static void VisitSharedFunctionInfoAndFlushCodeGeneric(
711 Map* map, HeapObject* object, bool known_flush_code_candidate) { 714 Map* map, HeapObject* object, bool known_flush_code_candidate) {
712 Heap* heap = map->heap(); 715 Heap* heap = map->heap();
713 SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(object); 716 SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(object);
714 717
715 if (shared->IsInobjectSlackTrackingInProgress()) shared->DetachInitialMap(); 718 if (shared->IsInobjectSlackTrackingInProgress()) shared->DetachInitialMap();
716 719
717 if (!known_flush_code_candidate) { 720 if (!known_flush_code_candidate) {
718 known_flush_code_candidate = IsFlushable(shared); 721 known_flush_code_candidate = IsFlushable(heap, shared);
719 if (known_flush_code_candidate) { 722 if (known_flush_code_candidate) {
720 heap->mark_compact_collector()->code_flusher()->AddCandidate(shared); 723 heap->mark_compact_collector()->code_flusher()->AddCandidate(shared);
721 } 724 }
722 } 725 }
723 726
724 VisitSharedFunctionInfoFields(heap, object, known_flush_code_candidate); 727 VisitSharedFunctionInfoFields(heap, object, known_flush_code_candidate);
725 } 728 }
726 729
727 730
728 static void VisitCodeEntry(Heap* heap, Address entry_address) { 731 static void VisitCodeEntry(Heap* heap, Address entry_address) {
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
858 explicit MarkingVisitor(Heap* heap) : heap_(heap) { } 861 explicit MarkingVisitor(Heap* heap) : heap_(heap) { }
859 862
860 void VisitPointer(Object** p) { 863 void VisitPointer(Object** p) {
861 StaticMarkingVisitor::VisitPointer(heap_, p); 864 StaticMarkingVisitor::VisitPointer(heap_, p);
862 } 865 }
863 866
864 void VisitPointers(Object** start, Object** end) { 867 void VisitPointers(Object** start, Object** end) {
865 StaticMarkingVisitor::VisitPointers(heap_, start, end); 868 StaticMarkingVisitor::VisitPointers(heap_, start, end);
866 } 869 }
867 870
868 void VisitCodeTarget(RelocInfo* rinfo) { 871 void VisitCodeTarget(Heap* heap, RelocInfo* rinfo) {
869 StaticMarkingVisitor::VisitCodeTarget(rinfo); 872 StaticMarkingVisitor::VisitCodeTarget(heap, rinfo);
870 } 873 }
871 874
872 void VisitGlobalPropertyCell(RelocInfo* rinfo) { 875 void VisitGlobalPropertyCell(Heap* heap, RelocInfo* rinfo) {
873 StaticMarkingVisitor::VisitGlobalPropertyCell(rinfo); 876 StaticMarkingVisitor::VisitGlobalPropertyCell(heap, rinfo);
874 } 877 }
875 878
876 void VisitDebugTarget(RelocInfo* rinfo) { 879 void VisitDebugTarget(Heap* heap, RelocInfo* rinfo) {
877 StaticMarkingVisitor::VisitDebugTarget(rinfo); 880 StaticMarkingVisitor::VisitDebugTarget(heap, rinfo);
878 } 881 }
879 882
880 private: 883 private:
881 Heap* heap_; 884 Heap* heap_;
882 }; 885 };
883 886
884 887
885 class CodeMarkingVisitor : public ThreadVisitor { 888 class CodeMarkingVisitor : public ThreadVisitor {
886 public: 889 public:
887 explicit CodeMarkingVisitor(MarkCompactCollector* collector) 890 explicit CodeMarkingVisitor(MarkCompactCollector* collector)
(...skipping 27 matching lines...) Expand all
915 collector_->MarkObject(shared); 918 collector_->MarkObject(shared);
916 } 919 }
917 } 920 }
918 921
919 private: 922 private:
920 MarkCompactCollector* collector_; 923 MarkCompactCollector* collector_;
921 }; 924 };
922 925
923 926
924 void MarkCompactCollector::PrepareForCodeFlushing() { 927 void MarkCompactCollector::PrepareForCodeFlushing() {
925 ASSERT(heap_ == Isolate::Current()->heap()); 928 ASSERT(heap() == Isolate::Current()->heap());
926 929
927 if (!FLAG_flush_code) { 930 if (!FLAG_flush_code) {
928 EnableCodeFlushing(false); 931 EnableCodeFlushing(false);
929 return; 932 return;
930 } 933 }
931 934
932 #ifdef ENABLE_DEBUGGER_SUPPORT 935 #ifdef ENABLE_DEBUGGER_SUPPORT
933 if (heap_->isolate()->debug()->IsLoaded() || 936 if (heap()->isolate()->debug()->IsLoaded() ||
934 heap_->isolate()->debug()->has_break_points()) { 937 heap()->isolate()->debug()->has_break_points()) {
935 EnableCodeFlushing(false); 938 EnableCodeFlushing(false);
936 return; 939 return;
937 } 940 }
938 #endif 941 #endif
939 EnableCodeFlushing(true); 942 EnableCodeFlushing(true);
940 943
941 // Ensure that empty descriptor array is marked. Method MarkDescriptorArray 944 // Ensure that empty descriptor array is marked. Method MarkDescriptorArray
942 // relies on it being marked before any other descriptor array. 945 // relies on it being marked before any other descriptor array.
943 MarkObject(heap_->raw_unchecked_empty_descriptor_array()); 946 MarkObject(heap()->raw_unchecked_empty_descriptor_array());
944 947
945 // Make sure we are not referencing the code from the stack. 948 // Make sure we are not referencing the code from the stack.
946 ASSERT(this == heap_->mark_compact_collector()); 949 ASSERT(this == heap()->mark_compact_collector());
947 for (StackFrameIterator it; !it.done(); it.Advance()) { 950 for (StackFrameIterator it; !it.done(); it.Advance()) {
948 MarkObject(it.frame()->unchecked_code()); 951 MarkObject(it.frame()->unchecked_code());
949 } 952 }
950 953
951 // Iterate the archived stacks in all threads to check if 954 // Iterate the archived stacks in all threads to check if
952 // the code is referenced. 955 // the code is referenced.
953 CodeMarkingVisitor code_marking_visitor(this); 956 CodeMarkingVisitor code_marking_visitor(this);
954 heap_->isolate()->thread_manager()->IterateArchivedThreads( 957 heap()->isolate()->thread_manager()->IterateArchivedThreads(
955 &code_marking_visitor); 958 &code_marking_visitor);
956 959
957 SharedFunctionInfoMarkingVisitor visitor(this); 960 SharedFunctionInfoMarkingVisitor visitor(this);
958 heap_->isolate()->compilation_cache()->IterateFunctions(&visitor); 961 heap()->isolate()->compilation_cache()->IterateFunctions(&visitor);
959 heap_->isolate()->handle_scope_implementer()->Iterate(&visitor); 962 heap()->isolate()->handle_scope_implementer()->Iterate(&visitor);
960 963
961 ProcessMarkingStack(); 964 ProcessMarkingStack();
962 } 965 }
963 966
964 967
965 // Visitor class for marking heap roots. 968 // Visitor class for marking heap roots.
966 class RootMarkingVisitor : public ObjectVisitor { 969 class RootMarkingVisitor : public ObjectVisitor {
967 public: 970 public:
968 explicit RootMarkingVisitor(Heap* heap) 971 explicit RootMarkingVisitor(Heap* heap)
969 : collector_(heap->mark_compact_collector()) { } 972 : collector_(heap->mark_compact_collector()) { }
(...skipping 27 matching lines...) Expand all
997 collector_->EmptyMarkingStack(); 1000 collector_->EmptyMarkingStack();
998 } 1001 }
999 1002
1000 MarkCompactCollector* collector_; 1003 MarkCompactCollector* collector_;
1001 }; 1004 };
1002 1005
1003 1006
1004 // Helper class for pruning the symbol table. 1007 // Helper class for pruning the symbol table.
1005 class SymbolTableCleaner : public ObjectVisitor { 1008 class SymbolTableCleaner : public ObjectVisitor {
1006 public: 1009 public:
1007 SymbolTableCleaner() : pointers_removed_(0) { } 1010 explicit SymbolTableCleaner(Heap* heap)
1011 : heap_(heap), pointers_removed_(0) { }
1008 1012
1009 virtual void VisitPointers(Object** start, Object** end) { 1013 virtual void VisitPointers(Object** start, Object** end) {
1010 // Visit all HeapObject pointers in [start, end). 1014 // Visit all HeapObject pointers in [start, end).
1011 for (Object** p = start; p < end; p++) { 1015 for (Object** p = start; p < end; p++) {
1012 if ((*p)->IsHeapObject() && !HeapObject::cast(*p)->IsMarked()) { 1016 if ((*p)->IsHeapObject() && !HeapObject::cast(*p)->IsMarked()) {
1013 // Check if the symbol being pruned is an external symbol. We need to 1017 // Check if the symbol being pruned is an external symbol. We need to
1014 // delete the associated external data as this symbol is going away. 1018 // delete the associated external data as this symbol is going away.
1015 1019
1016 // Since no objects have yet been moved we can safely access the map of 1020 // Since no objects have yet been moved we can safely access the map of
1017 // the object. 1021 // the object.
1018 if ((*p)->IsExternalString()) { 1022 if ((*p)->IsExternalString()) {
1019 HEAP->FinalizeExternalString(String::cast(*p)); 1023 heap_->FinalizeExternalString(String::cast(*p));
1020 } 1024 }
1021 // Set the entry to null_value (as deleted). 1025 // Set the entry to null_value (as deleted).
1022 *p = HEAP->raw_unchecked_null_value(); 1026 *p = heap_->raw_unchecked_null_value();
1023 pointers_removed_++; 1027 pointers_removed_++;
1024 } 1028 }
1025 } 1029 }
1026 } 1030 }
1027 1031
1028 int PointersRemoved() { 1032 int PointersRemoved() {
1029 return pointers_removed_; 1033 return pointers_removed_;
1030 } 1034 }
1031 private: 1035 private:
1036 Heap* heap_;
1032 int pointers_removed_; 1037 int pointers_removed_;
1033 }; 1038 };
1034 1039
1035 1040
1036 // Implementation of WeakObjectRetainer for mark compact GCs. All marked objects 1041 // Implementation of WeakObjectRetainer for mark compact GCs. All marked objects
1037 // are retained. 1042 // are retained.
1038 class MarkCompactWeakObjectRetainer : public WeakObjectRetainer { 1043 class MarkCompactWeakObjectRetainer : public WeakObjectRetainer {
1039 public: 1044 public:
1040 virtual Object* RetainAs(Object* object) { 1045 virtual Object* RetainAs(Object* object) {
1041 MapWord first_word = HeapObject::cast(object)->map_word(); 1046 MapWord first_word = HeapObject::cast(object)->map_word();
1042 if (first_word.IsMarked()) { 1047 if (first_word.IsMarked()) {
1043 return object; 1048 return object;
1044 } else { 1049 } else {
1045 return NULL; 1050 return NULL;
1046 } 1051 }
1047 } 1052 }
1048 }; 1053 };
1049 1054
1050 1055
1051 void MarkCompactCollector::MarkUnmarkedObject(HeapObject* object) { 1056 void MarkCompactCollector::MarkUnmarkedObject(HeapObject* object) {
1052 ASSERT(!object->IsMarked()); 1057 ASSERT(!object->IsMarked());
1053 ASSERT(HEAP->Contains(object)); 1058 ASSERT(HEAP->Contains(object));
1054 if (object->IsMap()) { 1059 if (object->IsMap()) {
1055 Map* map = Map::cast(object); 1060 Map* map = Map::cast(object);
1056 if (FLAG_cleanup_caches_in_maps_at_gc) { 1061 if (FLAG_cleanup_caches_in_maps_at_gc) {
1057 map->ClearCodeCache(heap_); 1062 map->ClearCodeCache(heap());
1058 } 1063 }
1059 SetMark(map); 1064 SetMark(map);
1060 if (FLAG_collect_maps && 1065 if (FLAG_collect_maps &&
1061 map->instance_type() >= FIRST_JS_OBJECT_TYPE && 1066 map->instance_type() >= FIRST_JS_OBJECT_TYPE &&
1062 map->instance_type() <= JS_FUNCTION_TYPE) { 1067 map->instance_type() <= JS_FUNCTION_TYPE) {
1063 MarkMapContents(map); 1068 MarkMapContents(map);
1064 } else { 1069 } else {
1065 marking_stack_.Push(map); 1070 marking_stack_.Push(map);
1066 } 1071 }
1067 } else { 1072 } else {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1118 } 1123 }
1119 } 1124 }
1120 } 1125 }
1121 // The DescriptorArray descriptors contains a pointer to its contents array, 1126 // The DescriptorArray descriptors contains a pointer to its contents array,
1122 // but the contents array is already marked. 1127 // but the contents array is already marked.
1123 marking_stack_.Push(descriptors); 1128 marking_stack_.Push(descriptors);
1124 } 1129 }
1125 1130
1126 1131
1127 void MarkCompactCollector::CreateBackPointers() { 1132 void MarkCompactCollector::CreateBackPointers() {
1128 HeapObjectIterator iterator(HEAP->map_space()); 1133 HeapObjectIterator iterator(heap()->map_space());
1129 for (HeapObject* next_object = iterator.next(); 1134 for (HeapObject* next_object = iterator.next();
1130 next_object != NULL; next_object = iterator.next()) { 1135 next_object != NULL; next_object = iterator.next()) {
1131 if (next_object->IsMap()) { // Could also be ByteArray on free list. 1136 if (next_object->IsMap()) { // Could also be ByteArray on free list.
1132 Map* map = Map::cast(next_object); 1137 Map* map = Map::cast(next_object);
1133 if (map->instance_type() >= FIRST_JS_OBJECT_TYPE && 1138 if (map->instance_type() >= FIRST_JS_OBJECT_TYPE &&
1134 map->instance_type() <= JS_FUNCTION_TYPE) { 1139 map->instance_type() <= JS_FUNCTION_TYPE) {
1135 map->CreateBackPointers(); 1140 map->CreateBackPointers();
1136 } else { 1141 } else {
1137 ASSERT(map->instance_descriptors() == HEAP->empty_descriptor_array()); 1142 ASSERT(map->instance_descriptors() == heap()->empty_descriptor_array());
1138 } 1143 }
1139 } 1144 }
1140 } 1145 }
1141 } 1146 }
1142 1147
1143 1148
1144 static int OverflowObjectSize(HeapObject* obj) { 1149 static int OverflowObjectSize(HeapObject* obj) {
1145 // Recover the normal map pointer, it might be marked as live and 1150 // Recover the normal map pointer, it might be marked as live and
1146 // overflowed. 1151 // overflowed.
1147 MapWord map_word = obj->map_word(); 1152 MapWord map_word = obj->map_word();
(...skipping 27 matching lines...) Expand all
1175 } 1180 }
1176 }; 1181 };
1177 1182
1178 1183
1179 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) { 1184 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) {
1180 return (*p)->IsHeapObject() && !HeapObject::cast(*p)->IsMarked(); 1185 return (*p)->IsHeapObject() && !HeapObject::cast(*p)->IsMarked();
1181 } 1186 }
1182 1187
1183 1188
1184 void MarkCompactCollector::MarkSymbolTable() { 1189 void MarkCompactCollector::MarkSymbolTable() {
1185 SymbolTable* symbol_table = heap_->raw_unchecked_symbol_table(); 1190 SymbolTable* symbol_table = heap()->raw_unchecked_symbol_table();
1186 // Mark the symbol table itself. 1191 // Mark the symbol table itself.
1187 SetMark(symbol_table); 1192 SetMark(symbol_table);
1188 // Explicitly mark the prefix. 1193 // Explicitly mark the prefix.
1189 MarkingVisitor marker(heap_); 1194 MarkingVisitor marker(heap());
1190 symbol_table->IteratePrefix(&marker); 1195 symbol_table->IteratePrefix(&marker);
1191 ProcessMarkingStack(); 1196 ProcessMarkingStack();
1192 } 1197 }
1193 1198
1194 1199
1195 void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) { 1200 void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) {
1196 // Mark the heap roots including global variables, stack variables, 1201 // Mark the heap roots including global variables, stack variables,
1197 // etc., and all objects reachable from them. 1202 // etc., and all objects reachable from them.
1198 HEAP->IterateStrongRoots(visitor, VISIT_ONLY_STRONG); 1203 heap()->IterateStrongRoots(visitor, VISIT_ONLY_STRONG);
1199 1204
1200 // Handle the symbol table specially. 1205 // Handle the symbol table specially.
1201 MarkSymbolTable(); 1206 MarkSymbolTable();
1202 1207
1203 // There may be overflowed objects in the heap. Visit them now. 1208 // There may be overflowed objects in the heap. Visit them now.
1204 while (marking_stack_.overflowed()) { 1209 while (marking_stack_.overflowed()) {
1205 RefillMarkingStack(); 1210 RefillMarkingStack();
1206 EmptyMarkingStack(); 1211 EmptyMarkingStack();
1207 } 1212 }
1208 } 1213 }
1209 1214
1210 1215
1211 void MarkCompactCollector::MarkObjectGroups() { 1216 void MarkCompactCollector::MarkObjectGroups() {
1212 List<ObjectGroup*>* object_groups = 1217 List<ObjectGroup*>* object_groups =
1213 heap_->isolate()->global_handles()->object_groups(); 1218 heap()->isolate()->global_handles()->object_groups();
1214 1219
1215 for (int i = 0; i < object_groups->length(); i++) { 1220 for (int i = 0; i < object_groups->length(); i++) {
1216 ObjectGroup* entry = object_groups->at(i); 1221 ObjectGroup* entry = object_groups->at(i);
1217 if (entry == NULL) continue; 1222 if (entry == NULL) continue;
1218 1223
1219 List<Object**>& objects = entry->objects_; 1224 List<Object**>& objects = entry->objects_;
1220 bool group_marked = false; 1225 bool group_marked = false;
1221 for (int j = 0; j < objects.length(); j++) { 1226 for (int j = 0; j < objects.length(); j++) {
1222 Object* object = *objects[j]; 1227 Object* object = *objects[j];
1223 if (object->IsHeapObject() && HeapObject::cast(object)->IsMarked()) { 1228 if (object->IsHeapObject() && HeapObject::cast(object)->IsMarked()) {
(...skipping 15 matching lines...) Expand all
1239 // Once the entire group has been colored gray, set the object group 1244 // Once the entire group has been colored gray, set the object group
1240 // to NULL so it won't be processed again. 1245 // to NULL so it won't be processed again.
1241 delete entry; 1246 delete entry;
1242 object_groups->at(i) = NULL; 1247 object_groups->at(i) = NULL;
1243 } 1248 }
1244 } 1249 }
1245 1250
1246 1251
1247 void MarkCompactCollector::MarkImplicitRefGroups() { 1252 void MarkCompactCollector::MarkImplicitRefGroups() {
1248 List<ImplicitRefGroup*>* ref_groups = 1253 List<ImplicitRefGroup*>* ref_groups =
1249 heap_->isolate()->global_handles()->implicit_ref_groups(); 1254 heap()->isolate()->global_handles()->implicit_ref_groups();
1250 1255
1251 for (int i = 0; i < ref_groups->length(); i++) { 1256 for (int i = 0; i < ref_groups->length(); i++) {
1252 ImplicitRefGroup* entry = ref_groups->at(i); 1257 ImplicitRefGroup* entry = ref_groups->at(i);
1253 if (entry == NULL) continue; 1258 if (entry == NULL) continue;
1254 1259
1255 if (!entry->parent_->IsMarked()) continue; 1260 if (!entry->parent_->IsMarked()) continue;
1256 1261
1257 List<Object**>& children = entry->children_; 1262 List<Object**>& children = entry->children_;
1258 // A parent object is marked, so mark as gray all child white heap 1263 // A parent object is marked, so mark as gray all child white heap
1259 // objects. 1264 // objects.
(...skipping 12 matching lines...) Expand all
1272 1277
1273 1278
1274 // Mark all objects reachable from the objects on the marking stack. 1279 // Mark all objects reachable from the objects on the marking stack.
1275 // Before: the marking stack contains zero or more heap object pointers. 1280 // Before: the marking stack contains zero or more heap object pointers.
1276 // After: the marking stack is empty, and all objects reachable from the 1281 // After: the marking stack is empty, and all objects reachable from the
1277 // marking stack have been marked, or are overflowed in the heap. 1282 // marking stack have been marked, or are overflowed in the heap.
1278 void MarkCompactCollector::EmptyMarkingStack() { 1283 void MarkCompactCollector::EmptyMarkingStack() {
1279 while (!marking_stack_.is_empty()) { 1284 while (!marking_stack_.is_empty()) {
1280 HeapObject* object = marking_stack_.Pop(); 1285 HeapObject* object = marking_stack_.Pop();
1281 ASSERT(object->IsHeapObject()); 1286 ASSERT(object->IsHeapObject());
1282 ASSERT(heap_->Contains(object)); 1287 ASSERT(heap()->Contains(object));
1283 ASSERT(object->IsMarked()); 1288 ASSERT(object->IsMarked());
1284 ASSERT(!object->IsOverflowed()); 1289 ASSERT(!object->IsOverflowed());
1285 1290
1286 // Because the object is marked, we have to recover the original map 1291 // Because the object is marked, we have to recover the original map
1287 // pointer and use it to mark the object's body. 1292 // pointer and use it to mark the object's body.
1288 MapWord map_word = object->map_word(); 1293 MapWord map_word = object->map_word();
1289 map_word.ClearMark(); 1294 map_word.ClearMark();
1290 Map* map = map_word.ToMap(); 1295 Map* map = map_word.ToMap();
1291 MarkObject(map); 1296 MarkObject(map);
1292 1297
1293 StaticMarkingVisitor::IterateBody(map, object); 1298 StaticMarkingVisitor::IterateBody(map, object);
1294 } 1299 }
1295 } 1300 }
1296 1301
1297 1302
1298 // Sweep the heap for overflowed objects, clear their overflow bits, and 1303 // Sweep the heap for overflowed objects, clear their overflow bits, and
1299 // push them on the marking stack. Stop early if the marking stack fills 1304 // push them on the marking stack. Stop early if the marking stack fills
1300 // before sweeping completes. If sweeping completes, there are no remaining 1305 // before sweeping completes. If sweeping completes, there are no remaining
1301 // overflowed objects in the heap so the overflow flag on the markings stack 1306 // overflowed objects in the heap so the overflow flag on the markings stack
1302 // is cleared. 1307 // is cleared.
1303 void MarkCompactCollector::RefillMarkingStack() { 1308 void MarkCompactCollector::RefillMarkingStack() {
1304 ASSERT(marking_stack_.overflowed()); 1309 ASSERT(marking_stack_.overflowed());
1305 1310
1306 SemiSpaceIterator new_it(HEAP->new_space(), &OverflowObjectSize); 1311 SemiSpaceIterator new_it(heap()->new_space(), &OverflowObjectSize);
1307 OverflowedObjectsScanner::ScanOverflowedObjects(this, &new_it); 1312 OverflowedObjectsScanner::ScanOverflowedObjects(this, &new_it);
1308 if (marking_stack_.is_full()) return; 1313 if (marking_stack_.is_full()) return;
1309 1314
1310 HeapObjectIterator old_pointer_it(HEAP->old_pointer_space(), 1315 HeapObjectIterator old_pointer_it(heap()->old_pointer_space(),
1311 &OverflowObjectSize); 1316 &OverflowObjectSize);
1312 OverflowedObjectsScanner::ScanOverflowedObjects(this, &old_pointer_it); 1317 OverflowedObjectsScanner::ScanOverflowedObjects(this, &old_pointer_it);
1313 if (marking_stack_.is_full()) return; 1318 if (marking_stack_.is_full()) return;
1314 1319
1315 HeapObjectIterator old_data_it(HEAP->old_data_space(), &OverflowObjectSize); 1320 HeapObjectIterator old_data_it(heap()->old_data_space(), &OverflowObjectSize);
1316 OverflowedObjectsScanner::ScanOverflowedObjects(this, &old_data_it); 1321 OverflowedObjectsScanner::ScanOverflowedObjects(this, &old_data_it);
1317 if (marking_stack_.is_full()) return; 1322 if (marking_stack_.is_full()) return;
1318 1323
1319 HeapObjectIterator code_it(HEAP->code_space(), &OverflowObjectSize); 1324 HeapObjectIterator code_it(heap()->code_space(), &OverflowObjectSize);
1320 OverflowedObjectsScanner::ScanOverflowedObjects(this, &code_it); 1325 OverflowedObjectsScanner::ScanOverflowedObjects(this, &code_it);
1321 if (marking_stack_.is_full()) return; 1326 if (marking_stack_.is_full()) return;
1322 1327
1323 HeapObjectIterator map_it(HEAP->map_space(), &OverflowObjectSize); 1328 HeapObjectIterator map_it(heap()->map_space(), &OverflowObjectSize);
1324 OverflowedObjectsScanner::ScanOverflowedObjects(this, &map_it); 1329 OverflowedObjectsScanner::ScanOverflowedObjects(this, &map_it);
1325 if (marking_stack_.is_full()) return; 1330 if (marking_stack_.is_full()) return;
1326 1331
1327 HeapObjectIterator cell_it(HEAP->cell_space(), &OverflowObjectSize); 1332 HeapObjectIterator cell_it(heap()->cell_space(), &OverflowObjectSize);
1328 OverflowedObjectsScanner::ScanOverflowedObjects(this, &cell_it); 1333 OverflowedObjectsScanner::ScanOverflowedObjects(this, &cell_it);
1329 if (marking_stack_.is_full()) return; 1334 if (marking_stack_.is_full()) return;
1330 1335
1331 LargeObjectIterator lo_it(HEAP->lo_space(), &OverflowObjectSize); 1336 LargeObjectIterator lo_it(heap()->lo_space(), &OverflowObjectSize);
1332 OverflowedObjectsScanner::ScanOverflowedObjects(this, &lo_it); 1337 OverflowedObjectsScanner::ScanOverflowedObjects(this, &lo_it);
1333 if (marking_stack_.is_full()) return; 1338 if (marking_stack_.is_full()) return;
1334 1339
1335 marking_stack_.clear_overflowed(); 1340 marking_stack_.clear_overflowed();
1336 } 1341 }
1337 1342
1338 1343
1339 // Mark all objects reachable (transitively) from objects on the marking 1344 // Mark all objects reachable (transitively) from objects on the marking
1340 // stack. Before: the marking stack contains zero or more heap object 1345 // stack. Before: the marking stack contains zero or more heap object
1341 // pointers. After: the marking stack is empty and there are no overflowed 1346 // pointers. After: the marking stack is empty and there are no overflowed
(...skipping 17 matching lines...) Expand all
1359 ProcessMarkingStack(); 1364 ProcessMarkingStack();
1360 } 1365 }
1361 } 1366 }
1362 1367
1363 1368
1364 void MarkCompactCollector::MarkLiveObjects() { 1369 void MarkCompactCollector::MarkLiveObjects() {
1365 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_MARK); 1370 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_MARK);
1366 // The recursive GC marker detects when it is nearing stack overflow, 1371 // The recursive GC marker detects when it is nearing stack overflow,
1367 // and switches to a different marking system. JS interrupts interfere 1372 // and switches to a different marking system. JS interrupts interfere
1368 // with the C stack limit check. 1373 // with the C stack limit check.
1369 PostponeInterruptsScope postpone(heap_->isolate()); 1374 PostponeInterruptsScope postpone(heap()->isolate());
1370 1375
1371 #ifdef DEBUG 1376 #ifdef DEBUG
1372 ASSERT(state_ == PREPARE_GC); 1377 ASSERT(state_ == PREPARE_GC);
1373 state_ = MARK_LIVE_OBJECTS; 1378 state_ = MARK_LIVE_OBJECTS;
1374 #endif 1379 #endif
1375 // The to space contains live objects, the from space is used as a marking 1380 // The to space contains live objects, the from space is used as a marking
1376 // stack. 1381 // stack.
1377 marking_stack_.Initialize(heap_->new_space()->FromSpaceLow(), 1382 marking_stack_.Initialize(heap()->new_space()->FromSpaceLow(),
1378 heap_->new_space()->FromSpaceHigh()); 1383 heap()->new_space()->FromSpaceHigh());
1379 1384
1380 ASSERT(!marking_stack_.overflowed()); 1385 ASSERT(!marking_stack_.overflowed());
1381 1386
1382 PrepareForCodeFlushing(); 1387 PrepareForCodeFlushing();
1383 1388
1384 RootMarkingVisitor root_visitor(heap_); 1389 RootMarkingVisitor root_visitor(heap());
1385 MarkRoots(&root_visitor); 1390 MarkRoots(&root_visitor);
1386 1391
1387 // The objects reachable from the roots are marked, yet unreachable 1392 // The objects reachable from the roots are marked, yet unreachable
1388 // objects are unmarked. Mark objects reachable due to host 1393 // objects are unmarked. Mark objects reachable due to host
1389 // application specific logic. 1394 // application specific logic.
1390 ProcessExternalMarking(); 1395 ProcessExternalMarking();
1391 1396
1392 // The objects reachable from the roots or object groups are marked, 1397 // The objects reachable from the roots or object groups are marked,
1393 // yet unreachable objects are unmarked. Mark objects reachable 1398 // yet unreachable objects are unmarked. Mark objects reachable
1394 // only from weak global handles. 1399 // only from weak global handles.
1395 // 1400 //
1396 // First we identify nonlive weak handles and mark them as pending 1401 // First we identify nonlive weak handles and mark them as pending
1397 // destruction. 1402 // destruction.
1398 heap_->isolate()->global_handles()->IdentifyWeakHandles( 1403 heap()->isolate()->global_handles()->IdentifyWeakHandles(
1399 &IsUnmarkedHeapObject); 1404 &IsUnmarkedHeapObject);
1400 // Then we mark the objects and process the transitive closure. 1405 // Then we mark the objects and process the transitive closure.
1401 heap_->isolate()->global_handles()->IterateWeakRoots(&root_visitor); 1406 heap()->isolate()->global_handles()->IterateWeakRoots(&root_visitor);
1402 while (marking_stack_.overflowed()) { 1407 while (marking_stack_.overflowed()) {
1403 RefillMarkingStack(); 1408 RefillMarkingStack();
1404 EmptyMarkingStack(); 1409 EmptyMarkingStack();
1405 } 1410 }
1406 1411
1407 // Repeat host application specific marking to mark unmarked objects 1412 // Repeat host application specific marking to mark unmarked objects
1408 // reachable from the weak roots. 1413 // reachable from the weak roots.
1409 ProcessExternalMarking(); 1414 ProcessExternalMarking();
1410 1415
1411 // Prune the symbol table removing all symbols only pointed to by the 1416 // Prune the symbol table removing all symbols only pointed to by the
1412 // symbol table. Cannot use symbol_table() here because the symbol 1417 // symbol table. Cannot use symbol_table() here because the symbol
1413 // table is marked. 1418 // table is marked.
1414 SymbolTable* symbol_table = heap_->raw_unchecked_symbol_table(); 1419 SymbolTable* symbol_table = heap()->raw_unchecked_symbol_table();
1415 SymbolTableCleaner v; 1420 SymbolTableCleaner v(heap());
1416 symbol_table->IterateElements(&v); 1421 symbol_table->IterateElements(&v);
1417 symbol_table->ElementsRemoved(v.PointersRemoved()); 1422 symbol_table->ElementsRemoved(v.PointersRemoved());
1418 heap_->external_string_table_.Iterate(&v); 1423 heap()->external_string_table_.Iterate(&v);
1419 heap_->external_string_table_.CleanUp(); 1424 heap()->external_string_table_.CleanUp();
1420 1425
1421 // Process the weak references. 1426 // Process the weak references.
1422 MarkCompactWeakObjectRetainer mark_compact_object_retainer; 1427 MarkCompactWeakObjectRetainer mark_compact_object_retainer;
1423 heap_->ProcessWeakReferences(&mark_compact_object_retainer); 1428 heap()->ProcessWeakReferences(&mark_compact_object_retainer);
1424 1429
1425 // Remove object groups after marking phase. 1430 // Remove object groups after marking phase.
1426 heap_->isolate()->global_handles()->RemoveObjectGroups(); 1431 heap()->isolate()->global_handles()->RemoveObjectGroups();
1427 heap_->isolate()->global_handles()->RemoveImplicitRefGroups(); 1432 heap()->isolate()->global_handles()->RemoveImplicitRefGroups();
1428 1433
1429 // Flush code from collected candidates. 1434 // Flush code from collected candidates.
1430 if (is_code_flushing_enabled()) { 1435 if (is_code_flushing_enabled()) {
1431 code_flusher_->ProcessCandidates(); 1436 code_flusher_->ProcessCandidates();
1432 } 1437 }
1433 1438
1434 // Clean up dead objects from the runtime profiler. 1439 // Clean up dead objects from the runtime profiler.
1435 heap_->isolate()->runtime_profiler()->RemoveDeadSamples(); 1440 heap()->isolate()->runtime_profiler()->RemoveDeadSamples();
1436 } 1441 }
1437 1442
1438 1443
1439 #ifdef DEBUG 1444 #ifdef DEBUG
1440 void MarkCompactCollector::UpdateLiveObjectCount(HeapObject* obj) { 1445 void MarkCompactCollector::UpdateLiveObjectCount(HeapObject* obj) {
1441 live_bytes_ += obj->Size(); 1446 live_bytes_ += obj->Size();
1442 if (HEAP->new_space()->Contains(obj)) { 1447 if (heap()->new_space()->Contains(obj)) {
1443 live_young_objects_size_ += obj->Size(); 1448 live_young_objects_size_ += obj->Size();
1444 } else if (HEAP->map_space()->Contains(obj)) { 1449 } else if (heap()->map_space()->Contains(obj)) {
1445 ASSERT(obj->IsMap()); 1450 ASSERT(obj->IsMap());
1446 live_map_objects_size_ += obj->Size(); 1451 live_map_objects_size_ += obj->Size();
1447 } else if (HEAP->cell_space()->Contains(obj)) { 1452 } else if (heap()->cell_space()->Contains(obj)) {
1448 ASSERT(obj->IsJSGlobalPropertyCell()); 1453 ASSERT(obj->IsJSGlobalPropertyCell());
1449 live_cell_objects_size_ += obj->Size(); 1454 live_cell_objects_size_ += obj->Size();
1450 } else if (HEAP->old_pointer_space()->Contains(obj)) { 1455 } else if (heap()->old_pointer_space()->Contains(obj)) {
1451 live_old_pointer_objects_size_ += obj->Size(); 1456 live_old_pointer_objects_size_ += obj->Size();
1452 } else if (HEAP->old_data_space()->Contains(obj)) { 1457 } else if (heap()->old_data_space()->Contains(obj)) {
1453 live_old_data_objects_size_ += obj->Size(); 1458 live_old_data_objects_size_ += obj->Size();
1454 } else if (HEAP->code_space()->Contains(obj)) { 1459 } else if (heap()->code_space()->Contains(obj)) {
1455 live_code_objects_size_ += obj->Size(); 1460 live_code_objects_size_ += obj->Size();
1456 } else if (HEAP->lo_space()->Contains(obj)) { 1461 } else if (heap()->lo_space()->Contains(obj)) {
1457 live_lo_objects_size_ += obj->Size(); 1462 live_lo_objects_size_ += obj->Size();
1458 } else { 1463 } else {
1459 UNREACHABLE(); 1464 UNREACHABLE();
1460 } 1465 }
1461 } 1466 }
1462 #endif // DEBUG 1467 #endif // DEBUG
1463 1468
1464 1469
1465 void MarkCompactCollector::SweepLargeObjectSpace() { 1470 void MarkCompactCollector::SweepLargeObjectSpace() {
1466 #ifdef DEBUG 1471 #ifdef DEBUG
1467 ASSERT(state_ == MARK_LIVE_OBJECTS); 1472 ASSERT(state_ == MARK_LIVE_OBJECTS);
1468 state_ = 1473 state_ =
1469 compacting_collection_ ? ENCODE_FORWARDING_ADDRESSES : SWEEP_SPACES; 1474 compacting_collection_ ? ENCODE_FORWARDING_ADDRESSES : SWEEP_SPACES;
1470 #endif 1475 #endif
1471 // Deallocate unmarked objects and clear marked bits for marked objects. 1476 // Deallocate unmarked objects and clear marked bits for marked objects.
1472 HEAP->lo_space()->FreeUnmarkedObjects(); 1477 heap()->lo_space()->FreeUnmarkedObjects();
1473 } 1478 }
1474 1479
1475 1480
1476 // Safe to use during marking phase only. 1481 // Safe to use during marking phase only.
1477 bool MarkCompactCollector::SafeIsMap(HeapObject* object) { 1482 bool MarkCompactCollector::SafeIsMap(HeapObject* object) {
1478 MapWord metamap = object->map_word(); 1483 MapWord metamap = object->map_word();
1479 metamap.ClearMark(); 1484 metamap.ClearMark();
1480 return metamap.ToMap()->instance_type() == MAP_TYPE; 1485 return metamap.ToMap()->instance_type() == MAP_TYPE;
1481 } 1486 }
1482 1487
1483 1488
1484 void MarkCompactCollector::ClearNonLiveTransitions() { 1489 void MarkCompactCollector::ClearNonLiveTransitions() {
1485 HeapObjectIterator map_iterator(HEAP->map_space(), &SizeOfMarkedObject); 1490 HeapObjectIterator map_iterator(heap() ->map_space(), &SizeOfMarkedObject);
1486 // Iterate over the map space, setting map transitions that go from 1491 // Iterate over the map space, setting map transitions that go from
1487 // a marked map to an unmarked map to null transitions. At the same time, 1492 // a marked map to an unmarked map to null transitions. At the same time,
1488 // set all the prototype fields of maps back to their original value, 1493 // set all the prototype fields of maps back to their original value,
1489 // dropping the back pointers temporarily stored in the prototype field. 1494 // dropping the back pointers temporarily stored in the prototype field.
1490 // Setting the prototype field requires following the linked list of 1495 // Setting the prototype field requires following the linked list of
1491 // back pointers, reversing them all at once. This allows us to find 1496 // back pointers, reversing them all at once. This allows us to find
1492 // those maps with map transitions that need to be nulled, and only 1497 // those maps with map transitions that need to be nulled, and only
1493 // scan the descriptor arrays of those maps, not all maps. 1498 // scan the descriptor arrays of those maps, not all maps.
1494 // All of these actions are carried out only on maps of JSObjects 1499 // All of these actions are carried out only on maps of JSObjects
1495 // and related subtypes. 1500 // and related subtypes.
(...skipping 29 matching lines...) Expand all
1525 Object* next; 1530 Object* next;
1526 while (SafeIsMap(current)) { 1531 while (SafeIsMap(current)) {
1527 next = current->prototype(); 1532 next = current->prototype();
1528 // There should never be a dead map above a live map. 1533 // There should never be a dead map above a live map.
1529 ASSERT(on_dead_path || current->IsMarked()); 1534 ASSERT(on_dead_path || current->IsMarked());
1530 1535
1531 // A live map above a dead map indicates a dead transition. 1536 // A live map above a dead map indicates a dead transition.
1532 // This test will always be false on the first iteration. 1537 // This test will always be false on the first iteration.
1533 if (on_dead_path && current->IsMarked()) { 1538 if (on_dead_path && current->IsMarked()) {
1534 on_dead_path = false; 1539 on_dead_path = false;
1535 current->ClearNonLiveTransitions(heap_, real_prototype); 1540 current->ClearNonLiveTransitions(heap(), real_prototype);
1536 } 1541 }
1537 *HeapObject::RawField(current, Map::kPrototypeOffset) = 1542 *HeapObject::RawField(current, Map::kPrototypeOffset) =
1538 real_prototype; 1543 real_prototype;
1539 current = reinterpret_cast<Map*>(next); 1544 current = reinterpret_cast<Map*>(next);
1540 } 1545 }
1541 } 1546 }
1542 } 1547 }
1543 1548
1544 // ------------------------------------------------------------------------- 1549 // -------------------------------------------------------------------------
1545 // Phase 2: Encode forwarding addresses. 1550 // Phase 2: Encode forwarding addresses.
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
1760 } 1765 }
1761 1766
1762 1767
1763 // Functions to encode the forwarding pointers in each compactable space. 1768 // Functions to encode the forwarding pointers in each compactable space.
1764 void MarkCompactCollector::EncodeForwardingAddressesInNewSpace() { 1769 void MarkCompactCollector::EncodeForwardingAddressesInNewSpace() {
1765 int ignored; 1770 int ignored;
1766 EncodeForwardingAddressesInRange<MCAllocateFromNewSpace, 1771 EncodeForwardingAddressesInRange<MCAllocateFromNewSpace,
1767 EncodeForwardingAddressInNewSpace, 1772 EncodeForwardingAddressInNewSpace,
1768 IgnoreNonLiveObject>( 1773 IgnoreNonLiveObject>(
1769 this, 1774 this,
1770 heap_->new_space()->bottom(), 1775 heap()->new_space()->bottom(),
1771 heap_->new_space()->top(), 1776 heap()->new_space()->top(),
1772 &ignored); 1777 &ignored);
1773 } 1778 }
1774 1779
1775 1780
1776 template<MarkCompactCollector::AllocationFunction Alloc, 1781 template<MarkCompactCollector::AllocationFunction Alloc,
1777 MarkCompactCollector::ProcessNonLiveFunction ProcessNonLive> 1782 MarkCompactCollector::ProcessNonLiveFunction ProcessNonLive>
1778 void MarkCompactCollector::EncodeForwardingAddressesInPagedSpace( 1783 void MarkCompactCollector::EncodeForwardingAddressesInPagedSpace(
1779 PagedSpace* space) { 1784 PagedSpace* space) {
1780 PageIterator it(space, PageIterator::PAGES_IN_USE); 1785 PageIterator it(space, PageIterator::PAGES_IN_USE);
1781 while (it.has_next()) { 1786 while (it.has_next()) {
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after
2183 space->SetTop(new_allocation_top); 2188 space->SetTop(new_allocation_top);
2184 } 2189 }
2185 } 2190 }
2186 2191
2187 2192
2188 void MarkCompactCollector::EncodeForwardingAddresses() { 2193 void MarkCompactCollector::EncodeForwardingAddresses() {
2189 ASSERT(state_ == ENCODE_FORWARDING_ADDRESSES); 2194 ASSERT(state_ == ENCODE_FORWARDING_ADDRESSES);
2190 // Objects in the active semispace of the young generation may be 2195 // Objects in the active semispace of the young generation may be
2191 // relocated to the inactive semispace (if not promoted). Set the 2196 // relocated to the inactive semispace (if not promoted). Set the
2192 // relocation info to the beginning of the inactive semispace. 2197 // relocation info to the beginning of the inactive semispace.
2193 heap_->new_space()->MCResetRelocationInfo(); 2198 heap()->new_space()->MCResetRelocationInfo();
2194 2199
2195 // Compute the forwarding pointers in each space. 2200 // Compute the forwarding pointers in each space.
2196 EncodeForwardingAddressesInPagedSpace<MCAllocateFromOldPointerSpace, 2201 EncodeForwardingAddressesInPagedSpace<MCAllocateFromOldPointerSpace,
2197 ReportDeleteIfNeeded>( 2202 ReportDeleteIfNeeded>(
2198 heap_->old_pointer_space()); 2203 heap()->old_pointer_space());
2199 2204
2200 EncodeForwardingAddressesInPagedSpace<MCAllocateFromOldDataSpace, 2205 EncodeForwardingAddressesInPagedSpace<MCAllocateFromOldDataSpace,
2201 IgnoreNonLiveObject>( 2206 IgnoreNonLiveObject>(
2202 heap_->old_data_space()); 2207 heap()->old_data_space());
2203 2208
2204 EncodeForwardingAddressesInPagedSpace<MCAllocateFromCodeSpace, 2209 EncodeForwardingAddressesInPagedSpace<MCAllocateFromCodeSpace,
2205 ReportDeleteIfNeeded>( 2210 ReportDeleteIfNeeded>(
2206 heap_->code_space()); 2211 heap()->code_space());
2207 2212
2208 EncodeForwardingAddressesInPagedSpace<MCAllocateFromCellSpace, 2213 EncodeForwardingAddressesInPagedSpace<MCAllocateFromCellSpace,
2209 IgnoreNonLiveObject>( 2214 IgnoreNonLiveObject>(
2210 heap_->cell_space()); 2215 heap()->cell_space());
2211 2216
2212 2217
2213 // Compute new space next to last after the old and code spaces have been 2218 // Compute new space next to last after the old and code spaces have been
2214 // compacted. Objects in new space can be promoted to old or code space. 2219 // compacted. Objects in new space can be promoted to old or code space.
2215 EncodeForwardingAddressesInNewSpace(); 2220 EncodeForwardingAddressesInNewSpace();
2216 2221
2217 // Compute map space last because computing forwarding addresses 2222 // Compute map space last because computing forwarding addresses
2218 // overwrites non-live objects. Objects in the other spaces rely on 2223 // overwrites non-live objects. Objects in the other spaces rely on
2219 // non-live map pointers to get the sizes of non-live objects. 2224 // non-live map pointers to get the sizes of non-live objects.
2220 EncodeForwardingAddressesInPagedSpace<MCAllocateFromMapSpace, 2225 EncodeForwardingAddressesInPagedSpace<MCAllocateFromMapSpace,
2221 IgnoreNonLiveObject>( 2226 IgnoreNonLiveObject>(
2222 heap_->map_space()); 2227 heap()->map_space());
2223 2228
2224 // Write relocation info to the top page, so we can use it later. This is 2229 // Write relocation info to the top page, so we can use it later. This is
2225 // done after promoting objects from the new space so we get the correct 2230 // done after promoting objects from the new space so we get the correct
2226 // allocation top. 2231 // allocation top.
2227 heap_->old_pointer_space()->MCWriteRelocationInfoToPage(); 2232 heap()->old_pointer_space()->MCWriteRelocationInfoToPage();
2228 heap_->old_data_space()->MCWriteRelocationInfoToPage(); 2233 heap()->old_data_space()->MCWriteRelocationInfoToPage();
2229 heap_->code_space()->MCWriteRelocationInfoToPage(); 2234 heap()->code_space()->MCWriteRelocationInfoToPage();
2230 heap_->map_space()->MCWriteRelocationInfoToPage(); 2235 heap()->map_space()->MCWriteRelocationInfoToPage();
2231 heap_->cell_space()->MCWriteRelocationInfoToPage(); 2236 heap()->cell_space()->MCWriteRelocationInfoToPage();
2232 } 2237 }
2233 2238
2234 2239
2235 class MapIterator : public HeapObjectIterator { 2240 class MapIterator : public HeapObjectIterator {
2236 public: 2241 public:
2237 MapIterator() : HeapObjectIterator(HEAP->map_space(), &SizeCallback) { } 2242 explicit MapIterator(Heap* heap)
2243 : HeapObjectIterator(heap->map_space(), &SizeCallback) { }
2238 2244
2239 explicit MapIterator(Address start) 2245 MapIterator(Heap* heap, Address start)
2240 : HeapObjectIterator(HEAP->map_space(), start, &SizeCallback) { } 2246 : HeapObjectIterator(heap->map_space(), start, &SizeCallback) { }
2241 2247
2242 private: 2248 private:
2243 static int SizeCallback(HeapObject* unused) { 2249 static int SizeCallback(HeapObject* unused) {
2244 USE(unused); 2250 USE(unused);
2245 return Map::kSize; 2251 return Map::kSize;
2246 } 2252 }
2247 }; 2253 };
2248 2254
2249 2255
2250 class MapCompact { 2256 class MapCompact {
2251 public: 2257 public:
2252 explicit MapCompact(Heap* heap, int live_maps) 2258 explicit MapCompact(Heap* heap, int live_maps)
2253 : heap_(heap), 2259 : heap_(heap),
2254 live_maps_(live_maps), 2260 live_maps_(live_maps),
2255 to_evacuate_start_(heap->map_space()->TopAfterCompaction(live_maps)), 2261 to_evacuate_start_(heap->map_space()->TopAfterCompaction(live_maps)),
2256 map_to_evacuate_it_(to_evacuate_start_), 2262 vacant_map_it_(heap),
2263 map_to_evacuate_it_(heap, to_evacuate_start_),
2257 first_map_to_evacuate_( 2264 first_map_to_evacuate_(
2258 reinterpret_cast<Map*>(HeapObject::FromAddress(to_evacuate_start_))) { 2265 reinterpret_cast<Map*>(HeapObject::FromAddress(to_evacuate_start_))) {
2259 } 2266 }
2260 2267
2261 void CompactMaps() { 2268 void CompactMaps() {
2262 // As we know the number of maps to evacuate beforehand, 2269 // As we know the number of maps to evacuate beforehand,
2263 // we stop then there is no more vacant maps. 2270 // we stop then there is no more vacant maps.
2264 for (Map* next_vacant_map = NextVacantMap(); 2271 for (Map* next_vacant_map = NextVacantMap();
2265 next_vacant_map; 2272 next_vacant_map;
2266 next_vacant_map = NextVacantMap()) { 2273 next_vacant_map = NextVacantMap()) {
2267 EvacuateMap(next_vacant_map, NextMapToEvacuate()); 2274 EvacuateMap(next_vacant_map, NextMapToEvacuate());
2268 } 2275 }
2269 2276
2270 #ifdef DEBUG 2277 #ifdef DEBUG
2271 CheckNoMapsToEvacuate(); 2278 CheckNoMapsToEvacuate();
2272 #endif 2279 #endif
2273 } 2280 }
2274 2281
2275 void UpdateMapPointersInRoots() { 2282 void UpdateMapPointersInRoots() {
2276 MapUpdatingVisitor map_updating_visitor; 2283 MapUpdatingVisitor map_updating_visitor;
2277 heap_->IterateRoots(&map_updating_visitor, VISIT_ONLY_STRONG); 2284 heap()->IterateRoots(&map_updating_visitor, VISIT_ONLY_STRONG);
2278 heap_->isolate()->global_handles()->IterateWeakRoots(&map_updating_visitor); 2285 heap()->isolate()->global_handles()->IterateWeakRoots(
2286 &map_updating_visitor);
2279 LiveObjectList::IterateElements(&map_updating_visitor); 2287 LiveObjectList::IterateElements(&map_updating_visitor);
2280 } 2288 }
2281 2289
2282 void UpdateMapPointersInPagedSpace(PagedSpace* space) { 2290 void UpdateMapPointersInPagedSpace(PagedSpace* space) {
2283 ASSERT(space != heap_->map_space()); 2291 ASSERT(space != heap()->map_space());
2284 2292
2285 PageIterator it(space, PageIterator::PAGES_IN_USE); 2293 PageIterator it(space, PageIterator::PAGES_IN_USE);
2286 while (it.has_next()) { 2294 while (it.has_next()) {
2287 Page* p = it.next(); 2295 Page* p = it.next();
2288 UpdateMapPointersInRange(heap_, p->ObjectAreaStart(), p->AllocationTop()); 2296 UpdateMapPointersInRange(heap(),
2297 p->ObjectAreaStart(),
2298 p->AllocationTop());
2289 } 2299 }
2290 } 2300 }
2291 2301
2292 void UpdateMapPointersInNewSpace() { 2302 void UpdateMapPointersInNewSpace() {
2293 NewSpace* space = heap_->new_space(); 2303 NewSpace* space = heap()->new_space();
2294 UpdateMapPointersInRange(heap_, space->bottom(), space->top()); 2304 UpdateMapPointersInRange(heap(), space->bottom(), space->top());
2295 } 2305 }
2296 2306
2297 void UpdateMapPointersInLargeObjectSpace() { 2307 void UpdateMapPointersInLargeObjectSpace() {
2298 LargeObjectIterator it(heap_->lo_space()); 2308 LargeObjectIterator it(heap()->lo_space());
2299 for (HeapObject* obj = it.next(); obj != NULL; obj = it.next()) 2309 for (HeapObject* obj = it.next(); obj != NULL; obj = it.next())
2300 UpdateMapPointersInObject(heap_, obj); 2310 UpdateMapPointersInObject(heap(), obj);
2301 } 2311 }
2302 2312
2303 void Finish() { 2313 void Finish() {
2304 heap_->map_space()->FinishCompaction(to_evacuate_start_, live_maps_); 2314 heap()->map_space()->FinishCompaction(to_evacuate_start_, live_maps_);
2305 } 2315 }
2306 2316
2317 inline Heap* heap() const { return heap_; }
2318
2307 private: 2319 private:
2308 Heap* heap_; 2320 Heap* heap_;
2309 int live_maps_; 2321 int live_maps_;
2310 Address to_evacuate_start_; 2322 Address to_evacuate_start_;
2311 MapIterator vacant_map_it_; 2323 MapIterator vacant_map_it_;
2312 MapIterator map_to_evacuate_it_; 2324 MapIterator map_to_evacuate_it_;
2313 Map* first_map_to_evacuate_; 2325 Map* first_map_to_evacuate_;
2314 2326
2315 // Helper class for updating map pointers in HeapObjects. 2327 // Helper class for updating map pointers in HeapObjects.
2316 class MapUpdatingVisitor: public ObjectVisitor { 2328 class MapUpdatingVisitor: public ObjectVisitor {
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
2446 void MarkCompactCollector::SweepSpaces() { 2458 void MarkCompactCollector::SweepSpaces() {
2447 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP); 2459 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP);
2448 2460
2449 ASSERT(state_ == SWEEP_SPACES); 2461 ASSERT(state_ == SWEEP_SPACES);
2450 ASSERT(!IsCompacting()); 2462 ASSERT(!IsCompacting());
2451 // Noncompacting collections simply sweep the spaces to clear the mark 2463 // Noncompacting collections simply sweep the spaces to clear the mark
2452 // bits and free the nonlive blocks (for old and map spaces). We sweep 2464 // bits and free the nonlive blocks (for old and map spaces). We sweep
2453 // the map space last because freeing non-live maps overwrites them and 2465 // the map space last because freeing non-live maps overwrites them and
2454 // the other spaces rely on possibly non-live maps to get the sizes for 2466 // the other spaces rely on possibly non-live maps to get the sizes for
2455 // non-live objects. 2467 // non-live objects.
2456 SweepSpace(heap_, heap_->old_pointer_space()); 2468 SweepSpace(heap(), heap()->old_pointer_space());
2457 SweepSpace(heap_, heap_->old_data_space()); 2469 SweepSpace(heap(), heap()->old_data_space());
2458 SweepSpace(heap_, heap_->code_space()); 2470 SweepSpace(heap(), heap()->code_space());
2459 SweepSpace(heap_, heap_->cell_space()); 2471 SweepSpace(heap(), heap()->cell_space());
2460 { GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP_NEWSPACE); 2472 { GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP_NEWSPACE);
2461 SweepNewSpace(heap_, heap_->new_space()); 2473 SweepNewSpace(heap(), heap()->new_space());
2462 } 2474 }
2463 SweepSpace(heap_, heap_->map_space()); 2475 SweepSpace(heap(), heap()->map_space());
2464 2476
2465 heap_->IterateDirtyRegions(heap_->map_space(), 2477 heap()->IterateDirtyRegions(heap()->map_space(),
2466 &heap_->IteratePointersInDirtyMapsRegion, 2478 &heap()->IteratePointersInDirtyMapsRegion,
2467 &UpdatePointerToNewGen, 2479 &UpdatePointerToNewGen,
2468 heap_->WATERMARK_SHOULD_BE_VALID); 2480 heap()->WATERMARK_SHOULD_BE_VALID);
2469 2481
2470 intptr_t live_maps_size = heap_->map_space()->Size(); 2482 intptr_t live_maps_size = heap()->map_space()->Size();
2471 int live_maps = static_cast<int>(live_maps_size / Map::kSize); 2483 int live_maps = static_cast<int>(live_maps_size / Map::kSize);
2472 ASSERT(live_map_objects_size_ == live_maps_size); 2484 ASSERT(live_map_objects_size_ == live_maps_size);
2473 2485
2474 if (heap_->map_space()->NeedsCompaction(live_maps)) { 2486 if (heap()->map_space()->NeedsCompaction(live_maps)) {
2475 MapCompact map_compact(heap_, live_maps); 2487 MapCompact map_compact(heap(), live_maps);
2476 2488
2477 map_compact.CompactMaps(); 2489 map_compact.CompactMaps();
2478 map_compact.UpdateMapPointersInRoots(); 2490 map_compact.UpdateMapPointersInRoots();
2479 2491
2480 PagedSpaces spaces; 2492 PagedSpaces spaces;
2481 for (PagedSpace* space = spaces.next(); 2493 for (PagedSpace* space = spaces.next();
2482 space != NULL; space = spaces.next()) { 2494 space != NULL; space = spaces.next()) {
2483 if (space == heap_->map_space()) continue; 2495 if (space == heap()->map_space()) continue;
2484 map_compact.UpdateMapPointersInPagedSpace(space); 2496 map_compact.UpdateMapPointersInPagedSpace(space);
2485 } 2497 }
2486 map_compact.UpdateMapPointersInNewSpace(); 2498 map_compact.UpdateMapPointersInNewSpace();
2487 map_compact.UpdateMapPointersInLargeObjectSpace(); 2499 map_compact.UpdateMapPointersInLargeObjectSpace();
2488 2500
2489 map_compact.Finish(); 2501 map_compact.Finish();
2490 } 2502 }
2491 } 2503 }
2492 2504
2493 2505
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
2569 ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) && 2581 ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) &&
2570 rinfo->IsPatchedReturnSequence()) || 2582 rinfo->IsPatchedReturnSequence()) ||
2571 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && 2583 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
2572 rinfo->IsPatchedDebugBreakSlotSequence())); 2584 rinfo->IsPatchedDebugBreakSlotSequence()));
2573 Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address()); 2585 Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address());
2574 VisitPointer(&target); 2586 VisitPointer(&target);
2575 rinfo->set_call_address( 2587 rinfo->set_call_address(
2576 reinterpret_cast<Code*>(target)->instruction_start()); 2588 reinterpret_cast<Code*>(target)->instruction_start());
2577 } 2589 }
2578 2590
2591 inline Heap* heap() const { return heap_; }
2592
2579 private: 2593 private:
2580 void UpdatePointer(Object** p) { 2594 void UpdatePointer(Object** p) {
2581 if (!(*p)->IsHeapObject()) return; 2595 if (!(*p)->IsHeapObject()) return;
2582 2596
2583 HeapObject* obj = HeapObject::cast(*p); 2597 HeapObject* obj = HeapObject::cast(*p);
2584 Address old_addr = obj->address(); 2598 Address old_addr = obj->address();
2585 Address new_addr; 2599 Address new_addr;
2586 ASSERT(!heap_->InFromSpace(obj)); 2600 ASSERT(!heap()->InFromSpace(obj));
2587 2601
2588 if (heap_->new_space()->Contains(obj)) { 2602 if (heap()->new_space()->Contains(obj)) {
2589 Address forwarding_pointer_addr = 2603 Address forwarding_pointer_addr =
2590 heap_->new_space()->FromSpaceLow() + 2604 heap()->new_space()->FromSpaceLow() +
2591 heap_->new_space()->ToSpaceOffsetForAddress(old_addr); 2605 heap()->new_space()->ToSpaceOffsetForAddress(old_addr);
2592 new_addr = Memory::Address_at(forwarding_pointer_addr); 2606 new_addr = Memory::Address_at(forwarding_pointer_addr);
2593 2607
2594 #ifdef DEBUG 2608 #ifdef DEBUG
2595 ASSERT(heap_->old_pointer_space()->Contains(new_addr) || 2609 ASSERT(heap()->old_pointer_space()->Contains(new_addr) ||
2596 heap_->old_data_space()->Contains(new_addr) || 2610 heap()->old_data_space()->Contains(new_addr) ||
2597 heap_->new_space()->FromSpaceContains(new_addr) || 2611 heap()->new_space()->FromSpaceContains(new_addr) ||
2598 heap_->lo_space()->Contains(HeapObject::FromAddress(new_addr))); 2612 heap()->lo_space()->Contains(HeapObject::FromAddress(new_addr)));
2599 2613
2600 if (heap_->new_space()->FromSpaceContains(new_addr)) { 2614 if (heap()->new_space()->FromSpaceContains(new_addr)) {
2601 ASSERT(heap_->new_space()->FromSpaceOffsetForAddress(new_addr) <= 2615 ASSERT(heap()->new_space()->FromSpaceOffsetForAddress(new_addr) <=
2602 heap_->new_space()->ToSpaceOffsetForAddress(old_addr)); 2616 heap()->new_space()->ToSpaceOffsetForAddress(old_addr));
2603 } 2617 }
2604 #endif 2618 #endif
2605 2619
2606 } else if (heap_->lo_space()->Contains(obj)) { 2620 } else if (heap()->lo_space()->Contains(obj)) {
2607 // Don't move objects in the large object space. 2621 // Don't move objects in the large object space.
2608 return; 2622 return;
2609 2623
2610 } else { 2624 } else {
2611 #ifdef DEBUG 2625 #ifdef DEBUG
2612 PagedSpaces spaces; 2626 PagedSpaces spaces;
2613 PagedSpace* original_space = spaces.next(); 2627 PagedSpace* original_space = spaces.next();
2614 while (original_space != NULL) { 2628 while (original_space != NULL) {
2615 if (original_space->Contains(obj)) break; 2629 if (original_space->Contains(obj)) break;
2616 original_space = spaces.next(); 2630 original_space = spaces.next();
(...skipping 18 matching lines...) Expand all
2635 2649
2636 Heap* heap_; 2650 Heap* heap_;
2637 }; 2651 };
2638 2652
2639 2653
2640 void MarkCompactCollector::UpdatePointers() { 2654 void MarkCompactCollector::UpdatePointers() {
2641 #ifdef DEBUG 2655 #ifdef DEBUG
2642 ASSERT(state_ == ENCODE_FORWARDING_ADDRESSES); 2656 ASSERT(state_ == ENCODE_FORWARDING_ADDRESSES);
2643 state_ = UPDATE_POINTERS; 2657 state_ = UPDATE_POINTERS;
2644 #endif 2658 #endif
2645 UpdatingVisitor updating_visitor(heap_); 2659 UpdatingVisitor updating_visitor(heap());
2646 heap_->isolate()->runtime_profiler()->UpdateSamplesAfterCompact( 2660 heap()->isolate()->runtime_profiler()->UpdateSamplesAfterCompact(
2647 &updating_visitor); 2661 &updating_visitor);
2648 heap_->IterateRoots(&updating_visitor, VISIT_ONLY_STRONG); 2662 heap()->IterateRoots(&updating_visitor, VISIT_ONLY_STRONG);
2649 heap_->isolate()->global_handles()->IterateWeakRoots(&updating_visitor); 2663 heap()->isolate()->global_handles()->IterateWeakRoots(&updating_visitor);
2650 2664
2651 // Update the pointer to the head of the weak list of global contexts. 2665 // Update the pointer to the head of the weak list of global contexts.
2652 updating_visitor.VisitPointer(&heap_->global_contexts_list_); 2666 updating_visitor.VisitPointer(&heap()->global_contexts_list_);
2653 2667
2654 LiveObjectList::IterateElements(&updating_visitor); 2668 LiveObjectList::IterateElements(&updating_visitor);
2655 2669
2656 int live_maps_size = IterateLiveObjects( 2670 int live_maps_size = IterateLiveObjects(
2657 heap_->map_space(), &MarkCompactCollector::UpdatePointersInOldObject); 2671 heap()->map_space(), &MarkCompactCollector::UpdatePointersInOldObject);
2658 int live_pointer_olds_size = IterateLiveObjects( 2672 int live_pointer_olds_size = IterateLiveObjects(
2659 heap_->old_pointer_space(), 2673 heap()->old_pointer_space(),
2660 &MarkCompactCollector::UpdatePointersInOldObject); 2674 &MarkCompactCollector::UpdatePointersInOldObject);
2661 int live_data_olds_size = IterateLiveObjects( 2675 int live_data_olds_size = IterateLiveObjects(
2662 heap_->old_data_space(), 2676 heap()->old_data_space(),
2663 &MarkCompactCollector::UpdatePointersInOldObject); 2677 &MarkCompactCollector::UpdatePointersInOldObject);
2664 int live_codes_size = IterateLiveObjects( 2678 int live_codes_size = IterateLiveObjects(
2665 heap_->code_space(), &MarkCompactCollector::UpdatePointersInOldObject); 2679 heap()->code_space(), &MarkCompactCollector::UpdatePointersInOldObject);
2666 int live_cells_size = IterateLiveObjects( 2680 int live_cells_size = IterateLiveObjects(
2667 heap_->cell_space(), &MarkCompactCollector::UpdatePointersInOldObject); 2681 heap()->cell_space(), &MarkCompactCollector::UpdatePointersInOldObject);
2668 int live_news_size = IterateLiveObjects( 2682 int live_news_size = IterateLiveObjects(
2669 heap_->new_space(), &MarkCompactCollector::UpdatePointersInNewObject); 2683 heap()->new_space(), &MarkCompactCollector::UpdatePointersInNewObject);
2670 2684
2671 // Large objects do not move, the map word can be updated directly. 2685 // Large objects do not move, the map word can be updated directly.
2672 LargeObjectIterator it(heap_->lo_space()); 2686 LargeObjectIterator it(heap()->lo_space());
2673 for (HeapObject* obj = it.next(); obj != NULL; obj = it.next()) { 2687 for (HeapObject* obj = it.next(); obj != NULL; obj = it.next()) {
2674 UpdatePointersInNewObject(obj); 2688 UpdatePointersInNewObject(obj);
2675 } 2689 }
2676 2690
2677 USE(live_maps_size); 2691 USE(live_maps_size);
2678 USE(live_pointer_olds_size); 2692 USE(live_pointer_olds_size);
2679 USE(live_data_olds_size); 2693 USE(live_data_olds_size);
2680 USE(live_codes_size); 2694 USE(live_codes_size);
2681 USE(live_cells_size); 2695 USE(live_cells_size);
2682 USE(live_news_size); 2696 USE(live_news_size);
2683 ASSERT(live_maps_size == live_map_objects_size_); 2697 ASSERT(live_maps_size == live_map_objects_size_);
2684 ASSERT(live_data_olds_size == live_old_data_objects_size_); 2698 ASSERT(live_data_olds_size == live_old_data_objects_size_);
2685 ASSERT(live_pointer_olds_size == live_old_pointer_objects_size_); 2699 ASSERT(live_pointer_olds_size == live_old_pointer_objects_size_);
2686 ASSERT(live_codes_size == live_code_objects_size_); 2700 ASSERT(live_codes_size == live_code_objects_size_);
2687 ASSERT(live_cells_size == live_cell_objects_size_); 2701 ASSERT(live_cells_size == live_cell_objects_size_);
2688 ASSERT(live_news_size == live_young_objects_size_); 2702 ASSERT(live_news_size == live_young_objects_size_);
2689 } 2703 }
2690 2704
2691 2705
2692 int MarkCompactCollector::UpdatePointersInNewObject(HeapObject* obj) { 2706 int MarkCompactCollector::UpdatePointersInNewObject(HeapObject* obj) {
2693 // Keep old map pointers 2707 // Keep old map pointers
2694 Map* old_map = obj->map(); 2708 Map* old_map = obj->map();
2695 ASSERT(old_map->IsHeapObject()); 2709 ASSERT(old_map->IsHeapObject());
2696 2710
2697 Address forwarded = GetForwardingAddressInOldSpace(old_map); 2711 Address forwarded = GetForwardingAddressInOldSpace(old_map);
2698 2712
2699 ASSERT(heap_->map_space()->Contains(old_map)); 2713 ASSERT(heap()->map_space()->Contains(old_map));
2700 ASSERT(heap_->map_space()->Contains(forwarded)); 2714 ASSERT(heap()->map_space()->Contains(forwarded));
2701 #ifdef DEBUG 2715 #ifdef DEBUG
2702 if (FLAG_gc_verbose) { 2716 if (FLAG_gc_verbose) {
2703 PrintF("update %p : %p -> %p\n", obj->address(), old_map->address(), 2717 PrintF("update %p : %p -> %p\n", obj->address(), old_map->address(),
2704 forwarded); 2718 forwarded);
2705 } 2719 }
2706 #endif 2720 #endif
2707 // Update the map pointer. 2721 // Update the map pointer.
2708 obj->set_map(reinterpret_cast<Map*>(HeapObject::FromAddress(forwarded))); 2722 obj->set_map(reinterpret_cast<Map*>(HeapObject::FromAddress(forwarded)));
2709 2723
2710 // We have to compute the object size relying on the old map because 2724 // We have to compute the object size relying on the old map because
2711 // map objects are not relocated yet. 2725 // map objects are not relocated yet.
2712 int obj_size = obj->SizeFromMap(old_map); 2726 int obj_size = obj->SizeFromMap(old_map);
2713 2727
2714 // Update pointers in the object body. 2728 // Update pointers in the object body.
2715 UpdatingVisitor updating_visitor(heap_); 2729 UpdatingVisitor updating_visitor(heap());
2716 obj->IterateBody(old_map->instance_type(), obj_size, &updating_visitor); 2730 obj->IterateBody(old_map->instance_type(), obj_size, &updating_visitor);
2717 return obj_size; 2731 return obj_size;
2718 } 2732 }
2719 2733
2720 2734
2721 int MarkCompactCollector::UpdatePointersInOldObject(HeapObject* obj) { 2735 int MarkCompactCollector::UpdatePointersInOldObject(HeapObject* obj) {
2722 // Decode the map pointer. 2736 // Decode the map pointer.
2723 MapWord encoding = obj->map_word(); 2737 MapWord encoding = obj->map_word();
2724 Address map_addr = encoding.DecodeMapAddress(heap_->map_space()); 2738 Address map_addr = encoding.DecodeMapAddress(heap()->map_space());
2725 ASSERT(heap_->map_space()->Contains(HeapObject::FromAddress(map_addr))); 2739 ASSERT(heap()->map_space()->Contains(HeapObject::FromAddress(map_addr)));
2726 2740
2727 // At this point, the first word of map_addr is also encoded, cannot 2741 // At this point, the first word of map_addr is also encoded, cannot
2728 // cast it to Map* using Map::cast. 2742 // cast it to Map* using Map::cast.
2729 Map* map = reinterpret_cast<Map*>(HeapObject::FromAddress(map_addr)); 2743 Map* map = reinterpret_cast<Map*>(HeapObject::FromAddress(map_addr));
2730 int obj_size = obj->SizeFromMap(map); 2744 int obj_size = obj->SizeFromMap(map);
2731 InstanceType type = map->instance_type(); 2745 InstanceType type = map->instance_type();
2732 2746
2733 // Update map pointer. 2747 // Update map pointer.
2734 Address new_map_addr = GetForwardingAddressInOldSpace(map); 2748 Address new_map_addr = GetForwardingAddressInOldSpace(map);
2735 int offset = encoding.DecodeOffset(); 2749 int offset = encoding.DecodeOffset();
2736 obj->set_map_word(MapWord::EncodeAddress(new_map_addr, offset)); 2750 obj->set_map_word(MapWord::EncodeAddress(new_map_addr, offset));
2737 2751
2738 #ifdef DEBUG 2752 #ifdef DEBUG
2739 if (FLAG_gc_verbose) { 2753 if (FLAG_gc_verbose) {
2740 PrintF("update %p : %p -> %p\n", obj->address(), 2754 PrintF("update %p : %p -> %p\n", obj->address(),
2741 map_addr, new_map_addr); 2755 map_addr, new_map_addr);
2742 } 2756 }
2743 #endif 2757 #endif
2744 2758
2745 // Update pointers in the object body. 2759 // Update pointers in the object body.
2746 UpdatingVisitor updating_visitor(heap_); 2760 UpdatingVisitor updating_visitor(heap());
2747 obj->IterateBody(type, obj_size, &updating_visitor); 2761 obj->IterateBody(type, obj_size, &updating_visitor);
2748 return obj_size; 2762 return obj_size;
2749 } 2763 }
2750 2764
2751 2765
2752 Address MarkCompactCollector::GetForwardingAddressInOldSpace(HeapObject* obj) { 2766 Address MarkCompactCollector::GetForwardingAddressInOldSpace(HeapObject* obj) {
2753 // Object should either in old or map space. 2767 // Object should either in old or map space.
2754 MapWord encoding = obj->map_word(); 2768 MapWord encoding = obj->map_word();
2755 2769
2756 // Offset to the first live object's forwarding address. 2770 // Offset to the first live object's forwarding address.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2793 // Phase 4: Relocate objects 2807 // Phase 4: Relocate objects
2794 2808
2795 void MarkCompactCollector::RelocateObjects() { 2809 void MarkCompactCollector::RelocateObjects() {
2796 #ifdef DEBUG 2810 #ifdef DEBUG
2797 ASSERT(state_ == UPDATE_POINTERS); 2811 ASSERT(state_ == UPDATE_POINTERS);
2798 state_ = RELOCATE_OBJECTS; 2812 state_ = RELOCATE_OBJECTS;
2799 #endif 2813 #endif
2800 // Relocates objects, always relocate map objects first. Relocating 2814 // Relocates objects, always relocate map objects first. Relocating
2801 // objects in other space relies on map objects to get object size. 2815 // objects in other space relies on map objects to get object size.
2802 int live_maps_size = IterateLiveObjects( 2816 int live_maps_size = IterateLiveObjects(
2803 heap_->map_space(), &MarkCompactCollector::RelocateMapObject); 2817 heap()->map_space(), &MarkCompactCollector::RelocateMapObject);
2804 int live_pointer_olds_size = IterateLiveObjects( 2818 int live_pointer_olds_size = IterateLiveObjects(
2805 heap_->old_pointer_space(), 2819 heap()->old_pointer_space(),
2806 &MarkCompactCollector::RelocateOldPointerObject); 2820 &MarkCompactCollector::RelocateOldPointerObject);
2807 int live_data_olds_size = IterateLiveObjects( 2821 int live_data_olds_size = IterateLiveObjects(
2808 heap_->old_data_space(), &MarkCompactCollector::RelocateOldDataObject); 2822 heap()->old_data_space(), &MarkCompactCollector::RelocateOldDataObject);
2809 int live_codes_size = IterateLiveObjects( 2823 int live_codes_size = IterateLiveObjects(
2810 heap_->code_space(), &MarkCompactCollector::RelocateCodeObject); 2824 heap()->code_space(), &MarkCompactCollector::RelocateCodeObject);
2811 int live_cells_size = IterateLiveObjects( 2825 int live_cells_size = IterateLiveObjects(
2812 heap_->cell_space(), &MarkCompactCollector::RelocateCellObject); 2826 heap()->cell_space(), &MarkCompactCollector::RelocateCellObject);
2813 int live_news_size = IterateLiveObjects( 2827 int live_news_size = IterateLiveObjects(
2814 heap_->new_space(), &MarkCompactCollector::RelocateNewObject); 2828 heap()->new_space(), &MarkCompactCollector::RelocateNewObject);
2815 2829
2816 USE(live_maps_size); 2830 USE(live_maps_size);
2817 USE(live_pointer_olds_size); 2831 USE(live_pointer_olds_size);
2818 USE(live_data_olds_size); 2832 USE(live_data_olds_size);
2819 USE(live_codes_size); 2833 USE(live_codes_size);
2820 USE(live_cells_size); 2834 USE(live_cells_size);
2821 USE(live_news_size); 2835 USE(live_news_size);
2822 ASSERT(live_maps_size == live_map_objects_size_); 2836 ASSERT(live_maps_size == live_map_objects_size_);
2823 ASSERT(live_data_olds_size == live_old_data_objects_size_); 2837 ASSERT(live_data_olds_size == live_old_data_objects_size_);
2824 ASSERT(live_pointer_olds_size == live_old_pointer_objects_size_); 2838 ASSERT(live_pointer_olds_size == live_old_pointer_objects_size_);
2825 ASSERT(live_codes_size == live_code_objects_size_); 2839 ASSERT(live_codes_size == live_code_objects_size_);
2826 ASSERT(live_cells_size == live_cell_objects_size_); 2840 ASSERT(live_cells_size == live_cell_objects_size_);
2827 ASSERT(live_news_size == live_young_objects_size_); 2841 ASSERT(live_news_size == live_young_objects_size_);
2828 2842
2829 // Flip from and to spaces 2843 // Flip from and to spaces
2830 heap_->new_space()->Flip(); 2844 heap()->new_space()->Flip();
2831 2845
2832 heap_->new_space()->MCCommitRelocationInfo(); 2846 heap()->new_space()->MCCommitRelocationInfo();
2833 2847
2834 // Set age_mark to bottom in to space 2848 // Set age_mark to bottom in to space
2835 Address mark = heap_->new_space()->bottom(); 2849 Address mark = heap()->new_space()->bottom();
2836 heap_->new_space()->set_age_mark(mark); 2850 heap()->new_space()->set_age_mark(mark);
2837 2851
2838 PagedSpaces spaces; 2852 PagedSpaces spaces;
2839 for (PagedSpace* space = spaces.next(); space != NULL; space = spaces.next()) 2853 for (PagedSpace* space = spaces.next(); space != NULL; space = spaces.next())
2840 space->MCCommitRelocationInfo(); 2854 space->MCCommitRelocationInfo();
2841 2855
2842 heap_->CheckNewSpaceExpansionCriteria(); 2856 heap()->CheckNewSpaceExpansionCriteria();
2843 heap_->IncrementYoungSurvivorsCounter(live_news_size); 2857 heap()->IncrementYoungSurvivorsCounter(live_news_size);
2844 } 2858 }
2845 2859
2846 2860
2847 int MarkCompactCollector::RelocateMapObject(HeapObject* obj) { 2861 int MarkCompactCollector::RelocateMapObject(HeapObject* obj) {
2848 // Recover map pointer. 2862 // Recover map pointer.
2849 MapWord encoding = obj->map_word(); 2863 MapWord encoding = obj->map_word();
2850 Address map_addr = encoding.DecodeMapAddress(heap_->map_space()); 2864 Address map_addr = encoding.DecodeMapAddress(heap()->map_space());
2851 ASSERT(heap_->map_space()->Contains(HeapObject::FromAddress(map_addr))); 2865 ASSERT(heap()->map_space()->Contains(HeapObject::FromAddress(map_addr)));
2852 2866
2853 // Get forwarding address before resetting map pointer 2867 // Get forwarding address before resetting map pointer
2854 Address new_addr = GetForwardingAddressInOldSpace(obj); 2868 Address new_addr = GetForwardingAddressInOldSpace(obj);
2855 2869
2856 // Reset map pointer. The meta map object may not be copied yet so 2870 // Reset map pointer. The meta map object may not be copied yet so
2857 // Map::cast does not yet work. 2871 // Map::cast does not yet work.
2858 obj->set_map(reinterpret_cast<Map*>(HeapObject::FromAddress(map_addr))); 2872 obj->set_map(reinterpret_cast<Map*>(HeapObject::FromAddress(map_addr)));
2859 2873
2860 Address old_addr = obj->address(); 2874 Address old_addr = obj->address();
2861 2875
2862 if (new_addr != old_addr) { 2876 if (new_addr != old_addr) {
2863 // Move contents. 2877 // Move contents.
2864 heap_->MoveBlockToOldSpaceAndUpdateRegionMarks(new_addr, 2878 heap()->MoveBlockToOldSpaceAndUpdateRegionMarks(new_addr,
2865 old_addr, 2879 old_addr,
2866 Map::kSize); 2880 Map::kSize);
2867 } 2881 }
2868 2882
2869 #ifdef DEBUG 2883 #ifdef DEBUG
2870 if (FLAG_gc_verbose) { 2884 if (FLAG_gc_verbose) {
2871 PrintF("relocate %p -> %p\n", old_addr, new_addr); 2885 PrintF("relocate %p -> %p\n", old_addr, new_addr);
2872 } 2886 }
2873 #endif 2887 #endif
2874 2888
(...skipping 25 matching lines...) Expand all
2900 #endif 2914 #endif
2901 2915
2902 return obj_size; 2916 return obj_size;
2903 } 2917 }
2904 2918
2905 2919
2906 int MarkCompactCollector::RelocateOldNonCodeObject(HeapObject* obj, 2920 int MarkCompactCollector::RelocateOldNonCodeObject(HeapObject* obj,
2907 PagedSpace* space) { 2921 PagedSpace* space) {
2908 // Recover map pointer. 2922 // Recover map pointer.
2909 MapWord encoding = obj->map_word(); 2923 MapWord encoding = obj->map_word();
2910 Address map_addr = encoding.DecodeMapAddress(heap_->map_space()); 2924 Address map_addr = encoding.DecodeMapAddress(heap()->map_space());
2911 ASSERT(heap_->map_space()->Contains(map_addr)); 2925 ASSERT(heap()->map_space()->Contains(map_addr));
2912 2926
2913 // Get forwarding address before resetting map pointer. 2927 // Get forwarding address before resetting map pointer.
2914 Address new_addr = GetForwardingAddressInOldSpace(obj); 2928 Address new_addr = GetForwardingAddressInOldSpace(obj);
2915 2929
2916 // Reset the map pointer. 2930 // Reset the map pointer.
2917 int obj_size = RestoreMap(obj, space, new_addr, map_addr); 2931 int obj_size = RestoreMap(obj, space, new_addr, map_addr);
2918 2932
2919 Address old_addr = obj->address(); 2933 Address old_addr = obj->address();
2920 2934
2921 if (new_addr != old_addr) { 2935 if (new_addr != old_addr) {
2922 // Move contents. 2936 // Move contents.
2923 if (space == heap_->old_data_space()) { 2937 if (space == heap()->old_data_space()) {
2924 heap_->MoveBlock(new_addr, old_addr, obj_size); 2938 heap()->MoveBlock(new_addr, old_addr, obj_size);
2925 } else { 2939 } else {
2926 heap_->MoveBlockToOldSpaceAndUpdateRegionMarks(new_addr, 2940 heap()->MoveBlockToOldSpaceAndUpdateRegionMarks(new_addr,
2927 old_addr, 2941 old_addr,
2928 obj_size); 2942 obj_size);
2929 } 2943 }
2930 } 2944 }
2931 2945
2932 ASSERT(!HeapObject::FromAddress(new_addr)->IsCode()); 2946 ASSERT(!HeapObject::FromAddress(new_addr)->IsCode());
2933 2947
2934 HeapObject* copied_to = HeapObject::FromAddress(new_addr); 2948 HeapObject* copied_to = HeapObject::FromAddress(new_addr);
2935 if (copied_to->IsSharedFunctionInfo()) { 2949 if (copied_to->IsSharedFunctionInfo()) {
2936 PROFILE(heap_->isolate(), 2950 PROFILE(heap()->isolate(),
2937 SharedFunctionInfoMoveEvent(old_addr, new_addr)); 2951 SharedFunctionInfoMoveEvent(old_addr, new_addr));
2938 } 2952 }
2939 HEAP_PROFILE(heap_, ObjectMoveEvent(old_addr, new_addr)); 2953 HEAP_PROFILE(heap(), ObjectMoveEvent(old_addr, new_addr));
2940 2954
2941 return obj_size; 2955 return obj_size;
2942 } 2956 }
2943 2957
2944 2958
2945 int MarkCompactCollector::RelocateOldPointerObject(HeapObject* obj) { 2959 int MarkCompactCollector::RelocateOldPointerObject(HeapObject* obj) {
2946 return RelocateOldNonCodeObject(obj, heap_->old_pointer_space()); 2960 return RelocateOldNonCodeObject(obj, heap()->old_pointer_space());
2947 } 2961 }
2948 2962
2949 2963
2950 int MarkCompactCollector::RelocateOldDataObject(HeapObject* obj) { 2964 int MarkCompactCollector::RelocateOldDataObject(HeapObject* obj) {
2951 return RelocateOldNonCodeObject(obj, heap_->old_data_space()); 2965 return RelocateOldNonCodeObject(obj, heap()->old_data_space());
2952 } 2966 }
2953 2967
2954 2968
2955 int MarkCompactCollector::RelocateCellObject(HeapObject* obj) { 2969 int MarkCompactCollector::RelocateCellObject(HeapObject* obj) {
2956 return RelocateOldNonCodeObject(obj, heap_->cell_space()); 2970 return RelocateOldNonCodeObject(obj, heap()->cell_space());
2957 } 2971 }
2958 2972
2959 2973
2960 int MarkCompactCollector::RelocateCodeObject(HeapObject* obj) { 2974 int MarkCompactCollector::RelocateCodeObject(HeapObject* obj) {
2961 // Recover map pointer. 2975 // Recover map pointer.
2962 MapWord encoding = obj->map_word(); 2976 MapWord encoding = obj->map_word();
2963 Address map_addr = encoding.DecodeMapAddress(heap_->map_space()); 2977 Address map_addr = encoding.DecodeMapAddress(heap()->map_space());
2964 ASSERT(heap_->map_space()->Contains(HeapObject::FromAddress(map_addr))); 2978 ASSERT(heap()->map_space()->Contains(HeapObject::FromAddress(map_addr)));
2965 2979
2966 // Get forwarding address before resetting map pointer 2980 // Get forwarding address before resetting map pointer
2967 Address new_addr = GetForwardingAddressInOldSpace(obj); 2981 Address new_addr = GetForwardingAddressInOldSpace(obj);
2968 2982
2969 // Reset the map pointer. 2983 // Reset the map pointer.
2970 int obj_size = RestoreMap(obj, heap_->code_space(), new_addr, map_addr); 2984 int obj_size = RestoreMap(obj, heap()->code_space(), new_addr, map_addr);
2971 2985
2972 Address old_addr = obj->address(); 2986 Address old_addr = obj->address();
2973 2987
2974 if (new_addr != old_addr) { 2988 if (new_addr != old_addr) {
2975 // Move contents. 2989 // Move contents.
2976 heap_->MoveBlock(new_addr, old_addr, obj_size); 2990 heap()->MoveBlock(new_addr, old_addr, obj_size);
2977 } 2991 }
2978 2992
2979 HeapObject* copied_to = HeapObject::FromAddress(new_addr); 2993 HeapObject* copied_to = HeapObject::FromAddress(new_addr);
2980 if (copied_to->IsCode()) { 2994 if (copied_to->IsCode()) {
2981 // May also update inline cache target. 2995 // May also update inline cache target.
2982 Code::cast(copied_to)->Relocate(new_addr - old_addr); 2996 Code::cast(copied_to)->Relocate(new_addr - old_addr);
2983 // Notify the logger that compiled code has moved. 2997 // Notify the logger that compiled code has moved.
2984 PROFILE(heap_->isolate(), CodeMoveEvent(old_addr, new_addr)); 2998 PROFILE(heap()->isolate(), CodeMoveEvent(old_addr, new_addr));
2985 } 2999 }
2986 HEAP_PROFILE(heap_, ObjectMoveEvent(old_addr, new_addr)); 3000 HEAP_PROFILE(heap(), ObjectMoveEvent(old_addr, new_addr));
2987 3001
2988 return obj_size; 3002 return obj_size;
2989 } 3003 }
2990 3004
2991 3005
2992 int MarkCompactCollector::RelocateNewObject(HeapObject* obj) { 3006 int MarkCompactCollector::RelocateNewObject(HeapObject* obj) {
2993 int obj_size = obj->Size(); 3007 int obj_size = obj->Size();
2994 3008
2995 // Get forwarding address 3009 // Get forwarding address
2996 Address old_addr = obj->address(); 3010 Address old_addr = obj->address();
2997 int offset = heap_->new_space()->ToSpaceOffsetForAddress(old_addr); 3011 int offset = heap()->new_space()->ToSpaceOffsetForAddress(old_addr);
2998 3012
2999 Address new_addr = 3013 Address new_addr =
3000 Memory::Address_at(heap_->new_space()->FromSpaceLow() + offset); 3014 Memory::Address_at(heap()->new_space()->FromSpaceLow() + offset);
3001 3015
3002 #ifdef DEBUG 3016 #ifdef DEBUG
3003 if (heap_->new_space()->FromSpaceContains(new_addr)) { 3017 if (heap()->new_space()->FromSpaceContains(new_addr)) {
3004 ASSERT(heap_->new_space()->FromSpaceOffsetForAddress(new_addr) <= 3018 ASSERT(heap()->new_space()->FromSpaceOffsetForAddress(new_addr) <=
3005 heap_->new_space()->ToSpaceOffsetForAddress(old_addr)); 3019 heap()->new_space()->ToSpaceOffsetForAddress(old_addr));
3006 } else { 3020 } else {
3007 ASSERT(heap_->TargetSpace(obj) == heap_->old_pointer_space() || 3021 ASSERT(heap()->TargetSpace(obj) == heap()->old_pointer_space() ||
3008 heap_->TargetSpace(obj) == heap_->old_data_space()); 3022 heap()->TargetSpace(obj) == heap()->old_data_space());
3009 } 3023 }
3010 #endif 3024 #endif
3011 3025
3012 // New and old addresses cannot overlap. 3026 // New and old addresses cannot overlap.
3013 if (heap_->InNewSpace(HeapObject::FromAddress(new_addr))) { 3027 if (heap()->InNewSpace(HeapObject::FromAddress(new_addr))) {
3014 heap_->CopyBlock(new_addr, old_addr, obj_size); 3028 heap()->CopyBlock(new_addr, old_addr, obj_size);
3015 } else { 3029 } else {
3016 heap_->CopyBlockToOldSpaceAndUpdateRegionMarks(new_addr, 3030 heap()->CopyBlockToOldSpaceAndUpdateRegionMarks(new_addr,
3017 old_addr, 3031 old_addr,
3018 obj_size); 3032 obj_size);
3019 } 3033 }
3020 3034
3021 #ifdef DEBUG 3035 #ifdef DEBUG
3022 if (FLAG_gc_verbose) { 3036 if (FLAG_gc_verbose) {
3023 PrintF("relocate %p -> %p\n", old_addr, new_addr); 3037 PrintF("relocate %p -> %p\n", old_addr, new_addr);
3024 } 3038 }
3025 #endif 3039 #endif
3026 3040
3027 HeapObject* copied_to = HeapObject::FromAddress(new_addr); 3041 HeapObject* copied_to = HeapObject::FromAddress(new_addr);
3028 if (copied_to->IsSharedFunctionInfo()) { 3042 if (copied_to->IsSharedFunctionInfo()) {
3029 PROFILE(heap_->isolate(), 3043 PROFILE(heap()->isolate(),
3030 SharedFunctionInfoMoveEvent(old_addr, new_addr)); 3044 SharedFunctionInfoMoveEvent(old_addr, new_addr));
3031 } 3045 }
3032 HEAP_PROFILE(heap_, ObjectMoveEvent(old_addr, new_addr)); 3046 HEAP_PROFILE(heap(), ObjectMoveEvent(old_addr, new_addr));
3033 3047
3034 return obj_size; 3048 return obj_size;
3035 } 3049 }
3036 3050
3037 3051
3038 void MarkCompactCollector::EnableCodeFlushing(bool enable) { 3052 void MarkCompactCollector::EnableCodeFlushing(bool enable) {
3039 if (enable) { 3053 if (enable) {
3040 if (code_flusher_ != NULL) return; 3054 if (code_flusher_ != NULL) return;
3041 code_flusher_ = new CodeFlusher(heap_->isolate()); 3055 code_flusher_ = new CodeFlusher(heap()->isolate());
3042 } else { 3056 } else {
3043 if (code_flusher_ == NULL) return; 3057 if (code_flusher_ == NULL) return;
3044 delete code_flusher_; 3058 delete code_flusher_;
3045 code_flusher_ = NULL; 3059 code_flusher_ = NULL;
3046 } 3060 }
3047 } 3061 }
3048 3062
3049 3063
3050 void MarkCompactCollector::ReportDeleteIfNeeded(HeapObject* obj, 3064 void MarkCompactCollector::ReportDeleteIfNeeded(HeapObject* obj,
3051 Isolate* isolate) { 3065 Isolate* isolate) {
(...skipping 17 matching lines...) Expand all
3069 } 3083 }
3070 3084
3071 3085
3072 void MarkCompactCollector::Initialize() { 3086 void MarkCompactCollector::Initialize() {
3073 StaticPointersToNewGenUpdatingVisitor::Initialize(); 3087 StaticPointersToNewGenUpdatingVisitor::Initialize();
3074 StaticMarkingVisitor::Initialize(); 3088 StaticMarkingVisitor::Initialize();
3075 } 3089 }
3076 3090
3077 3091
3078 } } // namespace v8::internal 3092 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/mark-compact.h ('k') | src/mips/frames-mips.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698