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

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

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