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

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

Issue 6088012: Separate markbits from heap object map words into bitmaps. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/gc
Patch Set: profiler related code reenabled Created 9 years, 11 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
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 28 matching lines...) Expand all
39 namespace v8 { 39 namespace v8 {
40 namespace internal { 40 namespace internal {
41 41
42 // ------------------------------------------------------------------------- 42 // -------------------------------------------------------------------------
43 // MarkCompactCollector 43 // MarkCompactCollector
44 44
45 bool MarkCompactCollector::force_compaction_ = false; 45 bool MarkCompactCollector::force_compaction_ = false;
46 bool MarkCompactCollector::compacting_collection_ = false; 46 bool MarkCompactCollector::compacting_collection_ = false;
47 bool MarkCompactCollector::compact_on_next_gc_ = false; 47 bool MarkCompactCollector::compact_on_next_gc_ = false;
48 48
49 int MarkCompactCollector::previous_marked_count_ = 0;
50 GCTracer* MarkCompactCollector::tracer_ = NULL; 49 GCTracer* MarkCompactCollector::tracer_ = NULL;
51 50
52
53 #ifdef DEBUG 51 #ifdef DEBUG
54 MarkCompactCollector::CollectorState MarkCompactCollector::state_ = IDLE; 52 MarkCompactCollector::CollectorState MarkCompactCollector::state_ = IDLE;
55 53
56 // Counters used for debugging the marking phase of mark-compact or mark-sweep 54 // Counters used for debugging the marking phase of mark-compact or mark-sweep
57 // collection. 55 // collection.
58 int MarkCompactCollector::live_bytes_ = 0; 56 int MarkCompactCollector::live_bytes_ = 0;
59 int MarkCompactCollector::live_young_objects_size_ = 0; 57 int MarkCompactCollector::live_young_objects_size_ = 0;
60 int MarkCompactCollector::live_old_data_objects_size_ = 0; 58 int MarkCompactCollector::live_old_data_objects_size_ = 0;
61 int MarkCompactCollector::live_old_pointer_objects_size_ = 0; 59 int MarkCompactCollector::live_old_pointer_objects_size_ = 0;
62 int MarkCompactCollector::live_code_objects_size_ = 0; 60 int MarkCompactCollector::live_code_objects_size_ = 0;
63 int MarkCompactCollector::live_map_objects_size_ = 0; 61 int MarkCompactCollector::live_map_objects_size_ = 0;
64 int MarkCompactCollector::live_cell_objects_size_ = 0; 62 int MarkCompactCollector::live_cell_objects_size_ = 0;
65 int MarkCompactCollector::live_lo_objects_size_ = 0; 63 int MarkCompactCollector::live_lo_objects_size_ = 0;
66 #endif 64 #endif
67 65
68 66
67 Marking::NewSpaceMarkbitsBitmap* Marking::new_space_bitmap_ = NULL;
68
69
70 bool Marking::Setup() {
71 if (new_space_bitmap_ == NULL) {
72 int markbits_per_newspace =
73 (2*Heap::MaxSemiSpaceSize()) >> kPointerSizeLog2;
74
75 new_space_bitmap_ =
76 BitmapStorageDescriptor::Allocate(
77 NewSpaceMarkbitsBitmap::CellsForLength(markbits_per_newspace));
78 }
79 return new_space_bitmap_ != NULL;
80 }
81
82
83 void Marking::TearDown() {
84 if (new_space_bitmap_ != NULL) {
85 BitmapStorageDescriptor::Free(new_space_bitmap_);
86 new_space_bitmap_ = NULL;
87 }
88 }
89
90
69 void MarkCompactCollector::CollectGarbage() { 91 void MarkCompactCollector::CollectGarbage() {
70 // Make sure that Prepare() has been called. The individual steps below will 92 // Make sure that Prepare() has been called. The individual steps below will
71 // update the state as they proceed. 93 // update the state as they proceed.
72 ASSERT(state_ == PREPARE_GC); 94 ASSERT(state_ == PREPARE_GC);
73 95
74 // Prepare has selected whether to compact the old generation or not. 96 // Prepare has selected whether to compact the old generation or not.
75 // Tell the tracer. 97 // Tell the tracer.
76 if (IsCompacting()) tracer_->set_is_compacting(); 98 if (IsCompacting()) tracer_->set_is_compacting();
77 99
78 MarkLiveObjects(); 100 MarkLiveObjects();
79 101
80 if (FLAG_collect_maps) ClearNonLiveTransitions(); 102 if (FLAG_collect_maps) ClearNonLiveTransitions();
81 103
82 SweepLargeObjectSpace(); 104 SweepLargeObjectSpace();
83 105
84 SweepSpaces(); 106 SweepSpaces();
85 PcToCodeCache::FlushPcToCodeCache(); 107 PcToCodeCache::FlushPcToCodeCache();
86 108
87 Finish(); 109 Finish();
88 110
89 // Save the count of marked objects remaining after the collection and 111 // Check that swept all marked objects and
Erik Corry 2011/01/07 12:13:21 that swept -> that we swept Also formatting is off
90 // null out the GC tracer. 112 // null out the GC tracer.
91 previous_marked_count_ = tracer_->marked_count(); 113 ASSERT(tracer_->marked_count() == 0);
92 ASSERT(previous_marked_count_ == 0);
93 tracer_ = NULL; 114 tracer_ = NULL;
94 } 115 }
95 116
96 117
118 #ifdef DEBUG
119 static void VerifyMarkbitsAreClean(PagedSpace* space) {
120 PageIterator it(space, PageIterator::PAGES_IN_USE);
121
122 while (it.has_next()) {
123 Page* p = it.next();
124 ASSERT(p->markbits()->IsClean());
125 }
126 }
127
128 static void VerifyMarkbitsAreClean() {
129 VerifyMarkbitsAreClean(Heap::old_pointer_space());
130 VerifyMarkbitsAreClean(Heap::old_data_space());
131 VerifyMarkbitsAreClean(Heap::code_space());
132 VerifyMarkbitsAreClean(Heap::cell_space());
133 VerifyMarkbitsAreClean(Heap::map_space());
134 }
135 #endif
136
137
97 void MarkCompactCollector::Prepare(GCTracer* tracer) { 138 void MarkCompactCollector::Prepare(GCTracer* tracer) {
98 FLAG_flush_code = false; 139 FLAG_flush_code = false;
99 FLAG_always_compact = false; 140 FLAG_always_compact = false;
100 FLAG_never_compact = true; 141 FLAG_never_compact = true;
101 142
102 // Rather than passing the tracer around we stash it in a static member 143 // Rather than passing the tracer around we stash it in a static member
103 // variable. 144 // variable.
104 tracer_ = tracer; 145 tracer_ = tracer;
105 146
106 #ifdef DEBUG 147 #ifdef DEBUG
(...skipping 10 matching lines...) Expand all
117 if (!Heap::map_space()->MapPointersEncodable()) 158 if (!Heap::map_space()->MapPointersEncodable())
118 compacting_collection_ = false; 159 compacting_collection_ = false;
119 if (FLAG_collect_maps) CreateBackPointers(); 160 if (FLAG_collect_maps) CreateBackPointers();
120 161
121 PagedSpaces spaces; 162 PagedSpaces spaces;
122 for (PagedSpace* space = spaces.next(); 163 for (PagedSpace* space = spaces.next();
123 space != NULL; space = spaces.next()) { 164 space != NULL; space = spaces.next()) {
124 space->PrepareForMarkCompact(compacting_collection_); 165 space->PrepareForMarkCompact(compacting_collection_);
125 } 166 }
126 167
168 Address new_space_top = Heap::new_space()->top();
169 Address new_space_bottom = Heap::new_space()->bottom();
170 Marking::ClearRange(new_space_bottom,
171 static_cast<int>(new_space_top - new_space_bottom));
172
127 #ifdef DEBUG 173 #ifdef DEBUG
174 VerifyMarkbitsAreClean();
175
128 live_bytes_ = 0; 176 live_bytes_ = 0;
129 live_young_objects_size_ = 0; 177 live_young_objects_size_ = 0;
130 live_old_pointer_objects_size_ = 0; 178 live_old_pointer_objects_size_ = 0;
131 live_old_data_objects_size_ = 0; 179 live_old_data_objects_size_ = 0;
132 live_code_objects_size_ = 0; 180 live_code_objects_size_ = 0;
133 live_map_objects_size_ = 0; 181 live_map_objects_size_ = 0;
134 live_cell_objects_size_ = 0; 182 live_cell_objects_size_ = 0;
135 live_lo_objects_size_ = 0; 183 live_lo_objects_size_ = 0;
136 #endif 184 #endif
137 } 185 }
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 Code* lazy_compile = Builtins::builtin(Builtins::LazyCompile); 282 Code* lazy_compile = Builtins::builtin(Builtins::LazyCompile);
235 283
236 JSFunction* candidate = jsfunction_candidates_head_; 284 JSFunction* candidate = jsfunction_candidates_head_;
237 JSFunction* next_candidate; 285 JSFunction* next_candidate;
238 while (candidate != NULL) { 286 while (candidate != NULL) {
239 next_candidate = GetNextCandidate(candidate); 287 next_candidate = GetNextCandidate(candidate);
240 288
241 SharedFunctionInfo* shared = candidate->unchecked_shared(); 289 SharedFunctionInfo* shared = candidate->unchecked_shared();
242 290
243 Code* code = shared->unchecked_code(); 291 Code* code = shared->unchecked_code();
244 if (!code->IsMarked()) { 292 if (!Marking::IsMarked(code->address())) {
245 shared->set_code(lazy_compile); 293 shared->set_code(lazy_compile);
246 candidate->set_code(lazy_compile); 294 candidate->set_code(lazy_compile);
247 } else { 295 } else {
248 candidate->set_code(shared->unchecked_code()); 296 candidate->set_code(shared->unchecked_code());
249 } 297 }
250 298
251 candidate = next_candidate; 299 candidate = next_candidate;
252 } 300 }
253 301
254 jsfunction_candidates_head_ = NULL; 302 jsfunction_candidates_head_ = NULL;
255 } 303 }
256 304
257 305
258 static void ProcessSharedFunctionInfoCandidates() { 306 static void ProcessSharedFunctionInfoCandidates() {
259 Code* lazy_compile = Builtins::builtin(Builtins::LazyCompile); 307 Code* lazy_compile = Builtins::builtin(Builtins::LazyCompile);
260 308
261 SharedFunctionInfo* candidate = shared_function_info_candidates_head_; 309 SharedFunctionInfo* candidate = shared_function_info_candidates_head_;
262 SharedFunctionInfo* next_candidate; 310 SharedFunctionInfo* next_candidate;
263 while (candidate != NULL) { 311 while (candidate != NULL) {
264 next_candidate = GetNextCandidate(candidate); 312 next_candidate = GetNextCandidate(candidate);
265 SetNextCandidate(candidate, NULL); 313 SetNextCandidate(candidate, NULL);
266 314
267 Code* code = candidate->unchecked_code(); 315 Code* code = candidate->unchecked_code();
268 if (!code->IsMarked()) { 316 if (!Marking::IsMarked(code->address())) {
269 candidate->set_code(lazy_compile); 317 candidate->set_code(lazy_compile);
270 } 318 }
271 319
272 candidate = next_candidate; 320 candidate = next_candidate;
273 } 321 }
274 322
275 shared_function_info_candidates_head_ = NULL; 323 shared_function_info_candidates_head_ = NULL;
276 } 324 }
277 325
278 326
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 // 378 //
331 // Here we assume that if we change *p, we replace it with a heap object 379 // Here we assume that if we change *p, we replace it with a heap object
332 // (ie, the left substring of a cons string is always a heap object). 380 // (ie, the left substring of a cons string is always a heap object).
333 // 381 //
334 // The check performed is: 382 // The check performed is:
335 // object->IsConsString() && !object->IsSymbol() && 383 // object->IsConsString() && !object->IsSymbol() &&
336 // (ConsString::cast(object)->second() == Heap::empty_string()) 384 // (ConsString::cast(object)->second() == Heap::empty_string())
337 // except the maps for the object and its possible substrings might be 385 // except the maps for the object and its possible substrings might be
338 // marked. 386 // marked.
339 HeapObject* object = HeapObject::cast(*p); 387 HeapObject* object = HeapObject::cast(*p);
340 MapWord map_word = object->map_word(); 388 InstanceType type = object->map()->instance_type();
341 map_word.ClearMark();
342 InstanceType type = map_word.ToMap()->instance_type();
343 if ((type & kShortcutTypeMask) != kShortcutTypeTag) return object; 389 if ((type & kShortcutTypeMask) != kShortcutTypeTag) return object;
344 390
345 Object* second = reinterpret_cast<ConsString*>(object)->unchecked_second(); 391 Object* second = reinterpret_cast<ConsString*>(object)->unchecked_second();
346 if (second != Heap::raw_unchecked_empty_string()) { 392 if (second != Heap::raw_unchecked_empty_string()) {
347 return object; 393 return object;
348 } 394 }
349 395
350 // Since we don't have the object's start, it is impossible to update the 396 // Since we don't have the object's start, it is impossible to update the
351 // page dirty marks. Therefore, we only replace the string with its left 397 // page dirty marks. Therefore, we only replace the string with its left
352 // substring when page dirty marks do not change. 398 // substring when page dirty marks do not change.
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 INLINE(static void MarkObjectByPointer(Object** p)) { 533 INLINE(static void MarkObjectByPointer(Object** p)) {
488 if (!(*p)->IsHeapObject()) return; 534 if (!(*p)->IsHeapObject()) return;
489 HeapObject* object = ShortCircuitConsString(p); 535 HeapObject* object = ShortCircuitConsString(p);
490 MarkCompactCollector::MarkObject(object); 536 MarkCompactCollector::MarkObject(object);
491 } 537 }
492 538
493 // Visit an unmarked object. 539 // Visit an unmarked object.
494 static inline void VisitUnmarkedObject(HeapObject* obj) { 540 static inline void VisitUnmarkedObject(HeapObject* obj) {
495 #ifdef DEBUG 541 #ifdef DEBUG
496 ASSERT(Heap::Contains(obj)); 542 ASSERT(Heap::Contains(obj));
497 ASSERT(!obj->IsMarked()); 543 ASSERT(!Marking::IsMarked(obj->address()));
Erik Corry 2011/01/07 12:13:21 I wonder whether the compiler can work out that th
498 #endif 544 #endif
499 Map* map = obj->map(); 545 Map* map = obj->map();
500 MarkCompactCollector::SetMark(obj); 546 MarkCompactCollector::SetMark(obj);
501 // Mark the map pointer and the body. 547 // Mark the map pointer and the body.
502 MarkCompactCollector::MarkObject(map); 548 MarkCompactCollector::MarkObject(map);
503 IterateBody(map, obj); 549 IterateBody(map, obj);
504 } 550 }
505 551
506 // Visit all unmarked objects pointed to by [start, end). 552 // Visit all unmarked objects pointed to by [start, end).
507 // Returns false if the operation fails (lack of stack space). 553 // Returns false if the operation fails (lack of stack space).
508 static inline bool VisitUnmarkedObjects(Object** start, Object** end) { 554 static inline bool VisitUnmarkedObjects(Object** start, Object** end) {
Erik Corry 2011/01/07 12:13:21 It would be nice to disassemble this function to s
509 // Return false is we are close to the stack limit. 555 // Return false is we are close to the stack limit.
510 StackLimitCheck check; 556 StackLimitCheck check;
511 if (check.HasOverflowed()) return false; 557 if (check.HasOverflowed()) return false;
512 558
513 // Visit the unmarked objects. 559 // Visit the unmarked objects.
514 for (Object** p = start; p < end; p++) { 560 for (Object** p = start; p < end; p++) {
515 if (!(*p)->IsHeapObject()) continue; 561 if (!(*p)->IsHeapObject()) continue;
516 HeapObject* obj = HeapObject::cast(*p); 562 HeapObject* obj = HeapObject::cast(*p);
517 if (obj->IsMarked()) continue; 563 if (Marking::IsMarked(obj)) continue;
518 VisitUnmarkedObject(obj); 564 VisitUnmarkedObject(obj);
519 } 565 }
520 return true; 566 return true;
521 } 567 }
522 568
523 static inline void VisitExternalReference(Address* p) { } 569 static inline void VisitExternalReference(Address* p) { }
524 static inline void VisitRuntimeEntry(RelocInfo* rinfo) { } 570 static inline void VisitRuntimeEntry(RelocInfo* rinfo) { }
525 571
526 private: 572 private:
527 class DataObjectVisitor { 573 class DataObjectVisitor {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 inline static bool IsCompiled(SharedFunctionInfo* function) { 614 inline static bool IsCompiled(SharedFunctionInfo* function) {
569 return 615 return
570 function->unchecked_code() != Builtins::builtin(Builtins::LazyCompile); 616 function->unchecked_code() != Builtins::builtin(Builtins::LazyCompile);
571 } 617 }
572 618
573 inline static bool IsFlushable(JSFunction* function) { 619 inline static bool IsFlushable(JSFunction* function) {
574 SharedFunctionInfo* shared_info = function->unchecked_shared(); 620 SharedFunctionInfo* shared_info = function->unchecked_shared();
575 621
576 // Code is either on stack, in compilation cache or referenced 622 // Code is either on stack, in compilation cache or referenced
577 // by optimized version of function. 623 // by optimized version of function.
578 if (function->unchecked_code()->IsMarked()) { 624 if (Marking::IsMarked(function->unchecked_code())) {
579 shared_info->set_code_age(0); 625 shared_info->set_code_age(0);
580 return false; 626 return false;
581 } 627 }
582 628
583 // We do not flush code for optimized functions. 629 // We do not flush code for optimized functions.
584 if (function->code() != shared_info->unchecked_code()) { 630 if (function->code() != shared_info->unchecked_code()) {
585 return false; 631 return false;
586 } 632 }
587 633
588 return IsFlushable(shared_info); 634 return IsFlushable(shared_info);
589 } 635 }
590 636
591 inline static bool IsFlushable(SharedFunctionInfo* shared_info) { 637 inline static bool IsFlushable(SharedFunctionInfo* shared_info) {
592 // Code is either on stack, in compilation cache or referenced 638 // Code is either on stack, in compilation cache or referenced
593 // by optimized version of function. 639 // by optimized version of function.
594 if (shared_info->unchecked_code()->IsMarked()) { 640 if (Marking::IsMarked(shared_info->unchecked_code())) {
595 shared_info->set_code_age(0); 641 shared_info->set_code_age(0);
596 return false; 642 return false;
597 } 643 }
598 644
599 // The function must be compiled and have the source code available, 645 // The function must be compiled and have the source code available,
600 // to be able to recompile it in case we need the function again. 646 // to be able to recompile it in case we need the function again.
601 if (!(shared_info->is_compiled() && HasSourceCode(shared_info))) { 647 if (!(shared_info->is_compiled() && HasSourceCode(shared_info))) {
602 return false; 648 return false;
603 } 649 }
604 650
(...skipping 30 matching lines...) Expand all
635 // This function's code looks flushable. But we have to postpone the 681 // This function's code looks flushable. But we have to postpone the
636 // decision until we see all functions that point to the same 682 // decision until we see all functions that point to the same
637 // SharedFunctionInfo because some of them might be optimized. 683 // SharedFunctionInfo because some of them might be optimized.
638 // That would make the nonoptimized version of the code nonflushable, 684 // That would make the nonoptimized version of the code nonflushable,
639 // because it is required for bailing out from optimized code. 685 // because it is required for bailing out from optimized code.
640 FlushCode::AddCandidate(function); 686 FlushCode::AddCandidate(function);
641 return true; 687 return true;
642 } 688 }
643 689
644 690
645 static inline Map* SafeMap(Object* obj) { 691 static inline Map* SafeMap(Object* obj) {
Erik Corry 2011/01/07 12:13:21 Get rid of this function?
646 MapWord map_word = HeapObject::cast(obj)->map_word(); 692 return HeapObject::cast(obj)->map();
647 map_word.ClearMark();
648 map_word.ClearOverflow();
649 return map_word.ToMap();
650 } 693 }
651 694
652 695
653 static inline bool IsJSBuiltinsObject(Object* obj) { 696 static inline bool IsJSBuiltinsObject(Object* obj) {
654 return obj->IsHeapObject() && 697 return obj->IsHeapObject() &&
655 (SafeMap(obj)->instance_type() == JS_BUILTINS_OBJECT_TYPE); 698 (SafeMap(obj)->instance_type() == JS_BUILTINS_OBJECT_TYPE);
656 } 699 }
657 700
658 701
659 static inline bool IsValidNotBuiltinContext(Object* ctx) { 702 static inline bool IsValidNotBuiltinContext(Object* ctx) {
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
775 SLOT_ADDR(object, JSFunction::kCodeEntryOffset)); 818 SLOT_ADDR(object, JSFunction::kCodeEntryOffset));
776 819
777 if (!flush_code_candidate) { 820 if (!flush_code_candidate) {
778 VisitCodeEntry(object->address() + JSFunction::kCodeEntryOffset); 821 VisitCodeEntry(object->address() + JSFunction::kCodeEntryOffset);
779 } else { 822 } else {
780 // Don't visit code object. 823 // Don't visit code object.
781 824
782 // Visit shared function info to avoid double checking of it's 825 // Visit shared function info to avoid double checking of it's
783 // flushability. 826 // flushability.
784 SharedFunctionInfo* shared_info = object->unchecked_shared(); 827 SharedFunctionInfo* shared_info = object->unchecked_shared();
785 if (!shared_info->IsMarked()) { 828 if (!Marking::IsMarked(shared_info)) {
786 Map* shared_info_map = shared_info->map(); 829 Map* shared_info_map = shared_info->map();
787 MarkCompactCollector::SetMark(shared_info); 830 MarkCompactCollector::SetMark(shared_info);
788 MarkCompactCollector::MarkObject(shared_info_map); 831 MarkCompactCollector::MarkObject(shared_info_map);
789 VisitSharedFunctionInfoAndFlushCodeGeneric(shared_info_map, 832 VisitSharedFunctionInfoAndFlushCodeGeneric(shared_info_map,
790 shared_info, 833 shared_info,
791 true); 834 true);
792 } 835 }
793 } 836 }
794 837
795 VisitPointers(SLOT_ADDR(object, 838 VisitPointers(SLOT_ADDR(object,
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
921 void VisitPointers(Object** start, Object** end) { 964 void VisitPointers(Object** start, Object** end) {
922 for (Object** p = start; p < end; p++) MarkObjectByPointer(p); 965 for (Object** p = start; p < end; p++) MarkObjectByPointer(p);
923 } 966 }
924 967
925 private: 968 private:
926 void MarkObjectByPointer(Object** p) { 969 void MarkObjectByPointer(Object** p) {
927 if (!(*p)->IsHeapObject()) return; 970 if (!(*p)->IsHeapObject()) return;
928 971
929 // Replace flat cons strings in place. 972 // Replace flat cons strings in place.
930 HeapObject* object = ShortCircuitConsString(p); 973 HeapObject* object = ShortCircuitConsString(p);
931 if (object->IsMarked()) return; 974 if (Marking::IsMarked(object)) return;
932 975
933 Map* map = object->map(); 976 Map* map = object->map();
934 // Mark the object. 977 // Mark the object.
935 MarkCompactCollector::SetMark(object); 978 MarkCompactCollector::SetMark(object);
936 979
937 // Mark the map pointer and body, and push them on the marking stack. 980 // Mark the map pointer and body, and push them on the marking stack.
938 MarkCompactCollector::MarkObject(map); 981 MarkCompactCollector::MarkObject(map);
939 StaticMarkingVisitor::IterateBody(map, object); 982 StaticMarkingVisitor::IterateBody(map, object);
940 983
941 // Mark all the objects reachable from the map and body. May leave 984 // Mark all the objects reachable from the map and body. May leave
942 // overflowed objects in the heap. 985 // overflowed objects in the heap.
943 MarkCompactCollector::EmptyMarkingStack(); 986 MarkCompactCollector::EmptyMarkingStack();
944 } 987 }
945 }; 988 };
946 989
947 990
948 // Helper class for pruning the symbol table. 991 // Helper class for pruning the symbol table.
949 class SymbolTableCleaner : public ObjectVisitor { 992 class SymbolTableCleaner : public ObjectVisitor {
950 public: 993 public:
951 SymbolTableCleaner() : pointers_removed_(0) { } 994 SymbolTableCleaner() : pointers_removed_(0) { }
952 995
953 virtual void VisitPointers(Object** start, Object** end) { 996 virtual void VisitPointers(Object** start, Object** end) {
954 // Visit all HeapObject pointers in [start, end). 997 // Visit all HeapObject pointers in [start, end).
955 for (Object** p = start; p < end; p++) { 998 for (Object** p = start; p < end; p++) {
956 if ((*p)->IsHeapObject() && !HeapObject::cast(*p)->IsMarked()) { 999 if ((*p)->IsHeapObject() &&
1000 !Marking::IsMarked(HeapObject::cast(*p))) {
957 // Check if the symbol being pruned is an external symbol. We need to 1001 // Check if the symbol being pruned is an external symbol. We need to
958 // delete the associated external data as this symbol is going away. 1002 // delete the associated external data as this symbol is going away.
959 1003
960 // Since no objects have yet been moved we can safely access the map of 1004 // Since no objects have yet been moved we can safely access the map of
961 // the object. 1005 // the object.
962 if ((*p)->IsExternalString()) { 1006 if ((*p)->IsExternalString()) {
963 Heap::FinalizeExternalString(String::cast(*p)); 1007 Heap::FinalizeExternalString(String::cast(*p));
964 } 1008 }
965 // Set the entry to null_value (as deleted). 1009 // Set the entry to null_value (as deleted).
966 *p = Heap::raw_unchecked_null_value(); 1010 *p = Heap::raw_unchecked_null_value();
967 pointers_removed_++; 1011 pointers_removed_++;
968 } 1012 }
969 } 1013 }
970 } 1014 }
971 1015
972 int PointersRemoved() { 1016 int PointersRemoved() {
973 return pointers_removed_; 1017 return pointers_removed_;
974 } 1018 }
975 private: 1019 private:
976 int pointers_removed_; 1020 int pointers_removed_;
977 }; 1021 };
978 1022
979 1023
980 // Implementation of WeakObjectRetainer for mark compact GCs. All marked objects 1024 // Implementation of WeakObjectRetainer for mark compact GCs. All marked objects
981 // are retained. 1025 // are retained.
982 class MarkCompactWeakObjectRetainer : public WeakObjectRetainer { 1026 class MarkCompactWeakObjectRetainer : public WeakObjectRetainer {
983 public: 1027 public:
984 virtual Object* RetainAs(Object* object) { 1028 virtual Object* RetainAs(Object* object) {
985 MapWord first_word = HeapObject::cast(object)->map_word(); 1029 if (Marking::IsMarked(HeapObject::cast(object))) {
986 if (first_word.IsMarked()) {
987 return object; 1030 return object;
988 } else { 1031 } else {
989 return NULL; 1032 return NULL;
990 } 1033 }
991 } 1034 }
992 }; 1035 };
993 1036
994 1037
995 void MarkCompactCollector::MarkUnmarkedObject(HeapObject* object) { 1038 void MarkCompactCollector::ProcessNewlyMarkedObject(HeapObject* object) {
996 ASSERT(!object->IsMarked()); 1039 ASSERT(Marking::IsMarked(object));
997 ASSERT(Heap::Contains(object)); 1040 ASSERT(Heap::Contains(object));
998 if (object->IsMap()) { 1041 if (object->IsMap()) {
999 Map* map = Map::cast(object); 1042 Map* map = Map::cast(object);
1000 if (FLAG_cleanup_caches_in_maps_at_gc) { 1043 if (FLAG_cleanup_caches_in_maps_at_gc) {
1001 map->ClearCodeCache(); 1044 map->ClearCodeCache();
1002 } 1045 }
1003 SetMark(map);
1004 if (FLAG_collect_maps && 1046 if (FLAG_collect_maps &&
1005 map->instance_type() >= FIRST_JS_OBJECT_TYPE && 1047 map->instance_type() >= FIRST_JS_OBJECT_TYPE &&
1006 map->instance_type() <= JS_FUNCTION_TYPE) { 1048 map->instance_type() <= JS_FUNCTION_TYPE) {
1007 MarkMapContents(map); 1049 MarkMapContents(map);
1008 } else { 1050 } else {
1009 marking_stack.Push(map); 1051 marking_stack.Push(map);
1010 } 1052 }
1011 } else { 1053 } else {
1012 SetMark(object);
1013 marking_stack.Push(object); 1054 marking_stack.Push(object);
1014 } 1055 }
1015 } 1056 }
1016 1057
1017 1058
1018 void MarkCompactCollector::MarkMapContents(Map* map) { 1059 void MarkCompactCollector::MarkMapContents(Map* map) {
1019 MarkDescriptorArray(reinterpret_cast<DescriptorArray*>( 1060 MarkDescriptorArray(reinterpret_cast<DescriptorArray*>(
1020 *HeapObject::RawField(map, Map::kInstanceDescriptorsOffset))); 1061 *HeapObject::RawField(map, Map::kInstanceDescriptorsOffset)));
1021 1062
1022 // Mark the Object* fields of the Map. 1063 // Mark the Object* fields of the Map.
1023 // Since the descriptor array has been marked already, it is fine 1064 // Since the descriptor array has been marked already, it is fine
1024 // that one of these fields contains a pointer to it. 1065 // that one of these fields contains a pointer to it.
1025 Object** start_slot = HeapObject::RawField(map, 1066 Object** start_slot = HeapObject::RawField(map,
1026 Map::kPointerFieldsBeginOffset); 1067 Map::kPointerFieldsBeginOffset);
1027 1068
1028 Object** end_slot = HeapObject::RawField(map, Map::kPointerFieldsEndOffset); 1069 Object** end_slot = HeapObject::RawField(map, Map::kPointerFieldsEndOffset);
1029 1070
1030 StaticMarkingVisitor::VisitPointers(start_slot, end_slot); 1071 StaticMarkingVisitor::VisitPointers(start_slot, end_slot);
1031 } 1072 }
1032 1073
1033 1074
1034 void MarkCompactCollector::MarkDescriptorArray( 1075 void MarkCompactCollector::MarkDescriptorArray(
1035 DescriptorArray* descriptors) { 1076 DescriptorArray* descriptors) {
1036 if (descriptors->IsMarked()) return; 1077 if (Marking::IsMarked(descriptors)) return;
1037 // Empty descriptor array is marked as a root before any maps are marked. 1078 // Empty descriptor array is marked as a root before any maps are marked.
1038 ASSERT(descriptors != Heap::raw_unchecked_empty_descriptor_array()); 1079 ASSERT(descriptors != Heap::raw_unchecked_empty_descriptor_array());
1039 SetMark(descriptors); 1080 SetMark(descriptors);
1040 1081
1041 FixedArray* contents = reinterpret_cast<FixedArray*>( 1082 FixedArray* contents = reinterpret_cast<FixedArray*>(
1042 descriptors->get(DescriptorArray::kContentArrayIndex)); 1083 descriptors->get(DescriptorArray::kContentArrayIndex));
1043 ASSERT(contents->IsHeapObject()); 1084 ASSERT(contents->IsHeapObject());
1044 ASSERT(!contents->IsMarked()); 1085 ASSERT(!Marking::IsMarked(contents));
1045 ASSERT(contents->IsFixedArray()); 1086 ASSERT(contents->IsFixedArray());
1046 ASSERT(contents->length() >= 2); 1087 ASSERT(contents->length() >= 2);
1047 SetMark(contents); 1088 SetMark(contents);
1048 // Contents contains (value, details) pairs. If the details say that 1089 // Contents contains (value, details) pairs. If the details say that
1049 // the type of descriptor is MAP_TRANSITION, CONSTANT_TRANSITION, or 1090 // the type of descriptor is MAP_TRANSITION, CONSTANT_TRANSITION, or
1050 // NULL_DESCRIPTOR, we don't mark the value as live. Only for 1091 // NULL_DESCRIPTOR, we don't mark the value as live. Only for
1051 // MAP_TRANSITION and CONSTANT_TRANSITION is the value an Object* (a 1092 // MAP_TRANSITION and CONSTANT_TRANSITION is the value an Object* (a
1052 // Map*). 1093 // Map*).
1053 for (int i = 0; i < contents->length(); i += 2) { 1094 for (int i = 0; i < contents->length(); i += 2) {
1054 // If the pair (value, details) at index i, i+1 is not 1095 // If the pair (value, details) at index i, i+1 is not
1055 // a transition or null descriptor, mark the value. 1096 // a transition or null descriptor, mark the value.
1056 PropertyDetails details(Smi::cast(contents->get(i + 1))); 1097 PropertyDetails details(Smi::cast(contents->get(i + 1)));
1057 if (details.type() < FIRST_PHANTOM_PROPERTY_TYPE) { 1098 if (details.type() < FIRST_PHANTOM_PROPERTY_TYPE) {
1058 HeapObject* object = reinterpret_cast<HeapObject*>(contents->get(i)); 1099 HeapObject* object = reinterpret_cast<HeapObject*>(contents->get(i));
1059 if (object->IsHeapObject() && !object->IsMarked()) { 1100 if (object->IsHeapObject() && !Marking::IsMarked(object)) {
1060 SetMark(object); 1101 SetMark(object);
1061 marking_stack.Push(object); 1102 marking_stack.Push(object);
1062 } 1103 }
1063 } 1104 }
1064 } 1105 }
1065 // The DescriptorArray descriptors contains a pointer to its contents array, 1106 // The DescriptorArray descriptors contains a pointer to its contents array,
1066 // but the contents array is already marked. 1107 // but the contents array is already marked.
1067 marking_stack.Push(descriptors); 1108 marking_stack.Push(descriptors);
1068 } 1109 }
1069 1110
(...skipping 11 matching lines...) Expand all
1081 ASSERT(map->instance_descriptors() == Heap::empty_descriptor_array()); 1122 ASSERT(map->instance_descriptors() == Heap::empty_descriptor_array());
1082 } 1123 }
1083 } 1124 }
1084 } 1125 }
1085 } 1126 }
1086 1127
1087 1128
1088 static int OverflowObjectSize(HeapObject* obj) { 1129 static int OverflowObjectSize(HeapObject* obj) {
1089 // Recover the normal map pointer, it might be marked as live and 1130 // Recover the normal map pointer, it might be marked as live and
1090 // overflowed. 1131 // overflowed.
1091 MapWord map_word = obj->map_word(); 1132 return obj->Size();
1092 map_word.ClearMark();
1093 map_word.ClearOverflow();
1094 return obj->SizeFromMap(map_word.ToMap());
1095 } 1133 }
1096 1134
1097 1135
1098 // Fill the marking stack with overflowed objects returned by the given 1136 // Fill the marking stack with overflowed objects returned by the given
1099 // iterator. Stop when the marking stack is filled or the end of the space 1137 // iterator. Stop when the marking stack is filled or the end of the space
1100 // is reached, whichever comes first. 1138 // is reached, whichever comes first.
1101 template<class T> 1139 template<class T>
1102 static void ScanOverflowedObjects(T* it) { 1140 static void ScanOverflowedObjects(T* it) {
1141 #if 0
1103 // The caller should ensure that the marking stack is initially not full, 1142 // The caller should ensure that the marking stack is initially not full,
1104 // so that we don't waste effort pointlessly scanning for objects. 1143 // so that we don't waste effort pointlessly scanning for objects.
1105 ASSERT(!marking_stack.is_full()); 1144 ASSERT(!marking_stack.is_full());
1106 1145
1107 for (HeapObject* object = it->next(); object != NULL; object = it->next()) { 1146 for (HeapObject* object = it->next(); object != NULL; object = it->next()) {
1108 if (object->IsOverflowed()) { 1147 if (object->IsOverflowed()) {
1109 object->ClearOverflow(); 1148 object->ClearOverflow();
1110 ASSERT(object->IsMarked()); 1149 ASSERT(Marking::IsMarked(object));
1111 ASSERT(Heap::Contains(object)); 1150 ASSERT(Heap::Contains(object));
1112 marking_stack.Push(object); 1151 marking_stack.Push(object);
1113 if (marking_stack.is_full()) return; 1152 if (marking_stack.is_full()) return;
1114 } 1153 }
1115 } 1154 }
1155 #endif
1156 UNREACHABLE();
1116 } 1157 }
1117 1158
1118 1159
1119 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) { 1160 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) {
1120 return (*p)->IsHeapObject() && !HeapObject::cast(*p)->IsMarked(); 1161 return (*p)->IsHeapObject() &&
1162 !Marking::IsMarked(HeapObject::cast(*p));
1121 } 1163 }
1122 1164
1123 1165
1124 void MarkCompactCollector::MarkSymbolTable() { 1166 void MarkCompactCollector::MarkSymbolTable() {
1125 SymbolTable* symbol_table = Heap::raw_unchecked_symbol_table(); 1167 SymbolTable* symbol_table = Heap::raw_unchecked_symbol_table();
1126 // Mark the symbol table itself. 1168 // Mark the symbol table itself.
1127 SetMark(symbol_table); 1169 SetMark(symbol_table);
1128 // Explicitly mark the prefix. 1170 // Explicitly mark the prefix.
1129 MarkingVisitor marker; 1171 MarkingVisitor marker;
1130 symbol_table->IteratePrefix(&marker); 1172 symbol_table->IteratePrefix(&marker);
(...skipping 21 matching lines...) Expand all
1152 List<ObjectGroup*>* object_groups = GlobalHandles::ObjectGroups(); 1194 List<ObjectGroup*>* object_groups = GlobalHandles::ObjectGroups();
1153 1195
1154 for (int i = 0; i < object_groups->length(); i++) { 1196 for (int i = 0; i < object_groups->length(); i++) {
1155 ObjectGroup* entry = object_groups->at(i); 1197 ObjectGroup* entry = object_groups->at(i);
1156 if (entry == NULL) continue; 1198 if (entry == NULL) continue;
1157 1199
1158 List<Object**>& objects = entry->objects_; 1200 List<Object**>& objects = entry->objects_;
1159 bool group_marked = false; 1201 bool group_marked = false;
1160 for (int j = 0; j < objects.length(); j++) { 1202 for (int j = 0; j < objects.length(); j++) {
1161 Object* object = *objects[j]; 1203 Object* object = *objects[j];
1162 if (object->IsHeapObject() && HeapObject::cast(object)->IsMarked()) { 1204 if (object->IsHeapObject() && Marking::IsMarked(HeapObject::cast(object))) {
1163 group_marked = true; 1205 group_marked = true;
1164 break; 1206 break;
1165 } 1207 }
1166 } 1208 }
1167 1209
1168 if (!group_marked) continue; 1210 if (!group_marked) continue;
1169 1211
1170 // An object in the group is marked, so mark as gray all white heap 1212 // An object in the group is marked, so mark as gray all white heap
1171 // objects in the group. 1213 // objects in the group.
1172 for (int j = 0; j < objects.length(); ++j) { 1214 for (int j = 0; j < objects.length(); ++j) {
(...skipping 11 matching lines...) Expand all
1184 1226
1185 // Mark all objects reachable from the objects on the marking stack. 1227 // Mark all objects reachable from the objects on the marking stack.
1186 // Before: the marking stack contains zero or more heap object pointers. 1228 // Before: the marking stack contains zero or more heap object pointers.
1187 // After: the marking stack is empty, and all objects reachable from the 1229 // After: the marking stack is empty, and all objects reachable from the
1188 // marking stack have been marked, or are overflowed in the heap. 1230 // marking stack have been marked, or are overflowed in the heap.
1189 void MarkCompactCollector::EmptyMarkingStack() { 1231 void MarkCompactCollector::EmptyMarkingStack() {
1190 while (!marking_stack.is_empty()) { 1232 while (!marking_stack.is_empty()) {
1191 HeapObject* object = marking_stack.Pop(); 1233 HeapObject* object = marking_stack.Pop();
1192 ASSERT(object->IsHeapObject()); 1234 ASSERT(object->IsHeapObject());
1193 ASSERT(Heap::Contains(object)); 1235 ASSERT(Heap::Contains(object));
1194 ASSERT(object->IsMarked()); 1236 ASSERT(Marking::IsMarked(object));
1195 ASSERT(!object->IsOverflowed()); 1237 ASSERT(!object->IsOverflowed());
1196 1238
1197 // Because the object is marked, we have to recover the original map 1239 // Because the object is marked, we have to recover the original map
Erik Corry 2011/01/07 12:13:21 comment out of date
1198 // pointer and use it to mark the object's body. 1240 // pointer and use it to mark the object's body.
1199 MapWord map_word = object->map_word(); 1241 Map* map = object->map();
1200 map_word.ClearMark();
1201 Map* map = map_word.ToMap();
1202 MarkObject(map); 1242 MarkObject(map);
1203 1243
1204 StaticMarkingVisitor::IterateBody(map, object); 1244 StaticMarkingVisitor::IterateBody(map, object);
1205 } 1245 }
1206 } 1246 }
1207 1247
1208 1248
1209 // Sweep the heap for overflowed objects, clear their overflow bits, and 1249 // Sweep the heap for overflowed objects, clear their overflow bits, and
1210 // push them on the marking stack. Stop early if the marking stack fills 1250 // push them on the marking stack. Stop early if the marking stack fills
1211 // before sweeping completes. If sweeping completes, there are no remaining 1251 // before sweeping completes. If sweeping completes, there are no remaining
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1371 ASSERT(state_ == MARK_LIVE_OBJECTS); 1411 ASSERT(state_ == MARK_LIVE_OBJECTS);
1372 state_ = 1412 state_ =
1373 compacting_collection_ ? ENCODE_FORWARDING_ADDRESSES : SWEEP_SPACES; 1413 compacting_collection_ ? ENCODE_FORWARDING_ADDRESSES : SWEEP_SPACES;
1374 #endif 1414 #endif
1375 // Deallocate unmarked objects and clear marked bits for marked objects. 1415 // Deallocate unmarked objects and clear marked bits for marked objects.
1376 Heap::lo_space()->FreeUnmarkedObjects(); 1416 Heap::lo_space()->FreeUnmarkedObjects();
1377 } 1417 }
1378 1418
1379 1419
1380 // Safe to use during marking phase only. 1420 // Safe to use during marking phase only.
1381 bool MarkCompactCollector::SafeIsMap(HeapObject* object) { 1421 bool MarkCompactCollector::SafeIsMap(HeapObject* object) {
Erik Corry 2011/01/07 12:13:21 Remove or rename?
1382 MapWord metamap = object->map_word(); 1422 return object->map()->instance_type() == MAP_TYPE;
1383 metamap.ClearMark();
1384 return metamap.ToMap()->instance_type() == MAP_TYPE;
1385 } 1423 }
1386 1424
1387 1425
1388 void MarkCompactCollector::ClearNonLiveTransitions() { 1426 void MarkCompactCollector::ClearNonLiveTransitions() {
1389 HeapObjectIterator map_iterator(Heap::map_space(), &SizeOfMarkedObject); 1427 HeapObjectIterator map_iterator(Heap::map_space(), &SizeOfMarkedObject);
1390 // Iterate over the map space, setting map transitions that go from 1428 // Iterate over the map space, setting map transitions that go from
1391 // a marked map to an unmarked map to null transitions. At the same time, 1429 // a marked map to an unmarked map to null transitions. At the same time,
1392 // set all the prototype fields of maps back to their original value, 1430 // set all the prototype fields of maps back to their original value,
1393 // dropping the back pointers temporarily stored in the prototype field. 1431 // dropping the back pointers temporarily stored in the prototype field.
1394 // Setting the prototype field requires following the linked list of 1432 // Setting the prototype field requires following the linked list of
1395 // back pointers, reversing them all at once. This allows us to find 1433 // back pointers, reversing them all at once. This allows us to find
1396 // those maps with map transitions that need to be nulled, and only 1434 // those maps with map transitions that need to be nulled, and only
1397 // scan the descriptor arrays of those maps, not all maps. 1435 // scan the descriptor arrays of those maps, not all maps.
1398 // All of these actions are carried out only on maps of JSObjects 1436 // All of these actions are carried out only on maps of JSObjects
1399 // and related subtypes. 1437 // and related subtypes.
1400 for (HeapObject* obj = map_iterator.next(); 1438 for (HeapObject* obj = map_iterator.next();
1401 obj != NULL; obj = map_iterator.next()) { 1439 obj != NULL; obj = map_iterator.next()) {
1402 Map* map = reinterpret_cast<Map*>(obj); 1440 Map* map = reinterpret_cast<Map*>(obj);
1403 if (!map->IsMarked() && map->IsByteArray()) continue; 1441 if (!Marking::IsMarked(map) && map->IsByteArray()) continue;
1404 1442
1405 ASSERT(SafeIsMap(map)); 1443 ASSERT(SafeIsMap(map));
1406 // Only JSObject and subtypes have map transitions and back pointers. 1444 // Only JSObject and subtypes have map transitions and back pointers.
1407 if (map->instance_type() < FIRST_JS_OBJECT_TYPE) continue; 1445 if (map->instance_type() < FIRST_JS_OBJECT_TYPE) continue;
1408 if (map->instance_type() > JS_FUNCTION_TYPE) continue; 1446 if (map->instance_type() > JS_FUNCTION_TYPE) continue;
1409 1447
1410 if (map->IsMarked() && map->attached_to_shared_function_info()) { 1448 if (Marking::IsMarked(map) &&
1449 map->attached_to_shared_function_info()) {
1411 // This map is used for inobject slack tracking and has been detached 1450 // This map is used for inobject slack tracking and has been detached
1412 // from SharedFunctionInfo during the mark phase. 1451 // from SharedFunctionInfo during the mark phase.
1413 // Since it survived the GC, reattach it now. 1452 // Since it survived the GC, reattach it now.
1414 map->unchecked_constructor()->unchecked_shared()->AttachInitialMap(map); 1453 map->unchecked_constructor()->unchecked_shared()->AttachInitialMap(map);
1415 } 1454 }
1416 1455
1417 // Follow the chain of back pointers to find the prototype. 1456 // Follow the chain of back pointers to find the prototype.
1418 Map* current = map; 1457 Map* current = map;
1419 while (SafeIsMap(current)) { 1458 while (SafeIsMap(current)) {
1420 current = reinterpret_cast<Map*>(current->prototype()); 1459 current = reinterpret_cast<Map*>(current->prototype());
1421 ASSERT(current->IsHeapObject()); 1460 ASSERT(current->IsHeapObject());
1422 } 1461 }
1423 Object* real_prototype = current; 1462 Object* real_prototype = current;
1424 1463
1425 // Follow back pointers, setting them to prototype, 1464 // Follow back pointers, setting them to prototype,
1426 // clearing map transitions when necessary. 1465 // clearing map transitions when necessary.
1427 current = map; 1466 current = map;
1428 bool on_dead_path = !current->IsMarked(); 1467 bool on_dead_path = !Marking::IsMarked(current);
1429 Object* next; 1468 Object* next;
1430 while (SafeIsMap(current)) { 1469 while (SafeIsMap(current)) {
1431 next = current->prototype(); 1470 next = current->prototype();
1432 // There should never be a dead map above a live map. 1471 // There should never be a dead map above a live map.
1433 ASSERT(on_dead_path || current->IsMarked()); 1472 ASSERT(on_dead_path || Marking::IsMarked(current));
1434 1473
1435 // A live map above a dead map indicates a dead transition. 1474 // A live map above a dead map indicates a dead transition.
1436 // This test will always be false on the first iteration. 1475 // This test will always be false on the first iteration.
1437 if (on_dead_path && current->IsMarked()) { 1476 if (on_dead_path && Marking::IsMarked(current)) {
1438 on_dead_path = false; 1477 on_dead_path = false;
1439 current->ClearNonLiveTransitions(real_prototype); 1478 current->ClearNonLiveTransitions(real_prototype);
1440 } 1479 }
1441 *HeapObject::RawField(current, Map::kPrototypeOffset) = 1480 *HeapObject::RawField(current, Map::kPrototypeOffset) =
1442 real_prototype; 1481 real_prototype;
1443 current = reinterpret_cast<Map*>(next); 1482 current = reinterpret_cast<Map*>(next);
1444 } 1483 }
1445 } 1484 }
1446 } 1485 }
1447 1486
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1576 MarkCompactCollector::tracer()-> 1615 MarkCompactCollector::tracer()->
1577 increment_promoted_objects_size(object_size); 1616 increment_promoted_objects_size(object_size);
1578 return true; 1617 return true;
1579 } 1618 }
1580 } 1619 }
1581 1620
1582 return false; 1621 return false;
1583 } 1622 }
1584 1623
1585 1624
1586 static void SweepNewSpace(NewSpace* space) { 1625 void MarkCompactCollector::SweepNewSpace(NewSpace* space) {
1587 Heap::CheckNewSpaceExpansionCriteria(); 1626 Heap::CheckNewSpaceExpansionCriteria();
1588 1627
1589 Address from_bottom = space->bottom(); 1628 Address from_bottom = space->bottom();
1590 Address from_top = space->top(); 1629 Address from_top = space->top();
1591 1630
1592 // Flip the semispaces. After flipping, to space is empty, from space has 1631 // Flip the semispaces. After flipping, to space is empty, from space has
1593 // live objects. 1632 // live objects.
1594 space->Flip(); 1633 space->Flip();
1595 space->ResetAllocationInfo(); 1634 space->ResetAllocationInfo();
1596 1635
1597 int size = 0; 1636 int size = 0;
1598 int survivors_size = 0; 1637 int survivors_size = 0;
1599 1638
1600 // First pass: traverse all objects in inactive semispace, remove marks, 1639 // First pass: traverse all objects in inactive semispace, remove marks,
1601 // migrate live objects and write forwarding addresses. 1640 // migrate live objects and write forwarding addresses.
1602 for (Address current = from_bottom; current < from_top; current += size) { 1641 for (Address current = from_bottom; current < from_top; current += size) {
1603 HeapObject* object = HeapObject::FromAddress(current); 1642 HeapObject* object = HeapObject::FromAddress(current);
1604 1643
1605 if (object->IsMarked()) { 1644 if (Marking::IsMarked(object)) {
1606 object->ClearMark(); 1645 Marking::ClearMark(object);
1607 MarkCompactCollector::tracer()->decrement_marked_count(); 1646 MarkCompactCollector::tracer()->decrement_marked_count();
1608 1647
1609 size = object->Size(); 1648 size = object->Size();
1610 survivors_size += size; 1649 survivors_size += size;
1611 1650
1612 // Aggressively promote young survivors to the old space. 1651 // Aggressively promote young survivors to the old space.
1613 if (TryPromoteObject(object, size)) { 1652 if (TryPromoteObject(object, size)) {
1614 continue; 1653 continue;
1615 } 1654 }
1616 1655
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1670 // Update pointers from external string table. 1709 // Update pointers from external string table.
1671 Heap::UpdateNewSpaceReferencesInExternalStringTable( 1710 Heap::UpdateNewSpaceReferencesInExternalStringTable(
1672 &UpdateNewSpaceReferenceInExternalStringTableEntry); 1711 &UpdateNewSpaceReferenceInExternalStringTableEntry);
1673 1712
1674 // All pointers were updated. Update auxiliary allocation info. 1713 // All pointers were updated. Update auxiliary allocation info.
1675 Heap::IncrementYoungSurvivorsCounter(survivors_size); 1714 Heap::IncrementYoungSurvivorsCounter(survivors_size);
1676 space->set_age_mark(space->top()); 1715 space->set_age_mark(space->top());
1677 } 1716 }
1678 1717
1679 1718
1680 static void SweepSpace(PagedSpace* space) { 1719 void MarkCompactCollector::SweepSpace(PagedSpace* space) {
1681 PageIterator it(space, PageIterator::PAGES_IN_USE); 1720 PageIterator it(space, PageIterator::PAGES_IN_USE);
1682 1721
1683 // During sweeping of paged space we are trying to find longest sequences 1722 // During sweeping of paged space we are trying to find longest sequences
1684 // of pages without live objects and free them (instead of putting them on 1723 // of pages without live objects and free them (instead of putting them on
1685 // the free list). 1724 // the free list).
1686 1725
1687 // Page preceding current. 1726 // Page preceding current.
1688 Page* prev = Page::FromAddress(NULL); 1727 Page* prev = Page::FromAddress(NULL);
1689 1728
1690 // First empty page in a sequence. 1729 // First empty page in a sequence.
(...skipping 15 matching lines...) Expand all
1706 Page* p = it.next(); 1745 Page* p = it.next();
1707 1746
1708 bool is_previous_alive = true; 1747 bool is_previous_alive = true;
1709 Address free_start = NULL; 1748 Address free_start = NULL;
1710 HeapObject* object; 1749 HeapObject* object;
1711 1750
1712 for (Address current = p->ObjectAreaStart(); 1751 for (Address current = p->ObjectAreaStart();
1713 current < p->AllocationTop(); 1752 current < p->AllocationTop();
1714 current += object->Size()) { 1753 current += object->Size()) {
1715 object = HeapObject::FromAddress(current); 1754 object = HeapObject::FromAddress(current);
1716 if (object->IsMarked()) { 1755 if (Marking::IsMarked(object)) {
1717 object->ClearMark(); 1756 Marking::ClearMark(object);
1718 MarkCompactCollector::tracer()->decrement_marked_count(); 1757 MarkCompactCollector::tracer()->decrement_marked_count();
1719 1758
1720 if (!is_previous_alive) { // Transition from free to live. 1759 if (!is_previous_alive) { // Transition from free to live.
1721 space->DeallocateBlock(free_start, 1760 space->DeallocateBlock(free_start,
1722 static_cast<int>(current - free_start), 1761 static_cast<int>(current - free_start),
1723 true); 1762 true);
1724 is_previous_alive = true; 1763 is_previous_alive = true;
1725 } 1764 }
1726 } else { 1765 } else {
1727 MarkCompactCollector::ReportDeleteIfNeeded(object); 1766 MarkCompactCollector::ReportDeleteIfNeeded(object);
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
1899 #ifdef ENABLE_LOGGING_AND_PROFILING 1938 #ifdef ENABLE_LOGGING_AND_PROFILING
1900 if (obj->IsCode()) { 1939 if (obj->IsCode()) {
1901 PROFILE(CodeDeleteEvent(obj->address())); 1940 PROFILE(CodeDeleteEvent(obj->address()));
1902 } else if (obj->IsJSFunction()) { 1941 } else if (obj->IsJSFunction()) {
1903 PROFILE(FunctionDeleteEvent(obj->address())); 1942 PROFILE(FunctionDeleteEvent(obj->address()));
1904 } 1943 }
1905 #endif 1944 #endif
1906 } 1945 }
1907 1946
1908 1947
1909 int MarkCompactCollector::SizeOfMarkedObject(HeapObject* obj) { 1948 int MarkCompactCollector::SizeOfMarkedObject(HeapObject* obj) {
Erik Corry 2011/01/07 12:13:21 This function is not needed
1910 MapWord map_word = obj->map_word(); 1949 return obj->Size();
1911 map_word.ClearMark();
1912 return obj->SizeFromMap(map_word.ToMap());
1913 } 1950 }
1914 1951
1915 1952
1916 void MarkCompactCollector::Initialize() { 1953 void MarkCompactCollector::Initialize() {
1917 StaticPointersToNewGenUpdatingVisitor::Initialize(); 1954 StaticPointersToNewGenUpdatingVisitor::Initialize();
1918 StaticMarkingVisitor::Initialize(); 1955 StaticMarkingVisitor::Initialize();
1919 } 1956 }
1920 1957
1921 1958
1922 } } // namespace v8::internal 1959 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698