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

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

Issue 6713075: Create an abstraction (MarkBit) object to hold the location of the... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: '' Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 } 91 }
92 92
93 93
94 #ifdef DEBUG 94 #ifdef DEBUG
95 class VerifyMarkingVisitor: public ObjectVisitor { 95 class VerifyMarkingVisitor: public ObjectVisitor {
96 public: 96 public:
97 void VisitPointers(Object** start, Object** end) { 97 void VisitPointers(Object** start, Object** end) {
98 for (Object** current = start; current < end; current++) { 98 for (Object** current = start; current < end; current++) {
99 if ((*current)->IsHeapObject()) { 99 if ((*current)->IsHeapObject()) {
100 HeapObject* object = HeapObject::cast(*current); 100 HeapObject* object = HeapObject::cast(*current);
101 ASSERT(Marking::IsMarked(object)); 101 ASSERT(MarkCompactCollector::IsMarked(object));
102 } 102 }
103 } 103 }
104 } 104 }
105 }; 105 };
106 106
107 107
108 static void VerifyMarking(Address bottom, Address top) { 108 static void VerifyMarking(Address bottom, Address top) {
109 VerifyMarkingVisitor visitor; 109 VerifyMarkingVisitor visitor;
110 HeapObject* object; 110 HeapObject* object;
111 Address next_object_must_be_here_or_later = bottom; 111 Address next_object_must_be_here_or_later = bottom;
112 112
113 for (Address current = bottom; 113 for (Address current = bottom;
114 current < top; 114 current < top;
115 current += kPointerSize) { 115 current += kPointerSize) {
116 object = HeapObject::FromAddress(current); 116 object = HeapObject::FromAddress(current);
117 if (Marking::IsMarked(object)) { 117 if (MarkCompactCollector::IsMarked(object)) {
118 ASSERT(current >= next_object_must_be_here_or_later); 118 ASSERT(current >= next_object_must_be_here_or_later);
119 object->Iterate(&visitor); 119 object->Iterate(&visitor);
120 next_object_must_be_here_or_later = current + object->Size(); 120 next_object_must_be_here_or_later = current + object->Size();
121 } 121 }
122 } 122 }
123 } 123 }
124 124
125 125
126 static void VerifyMarking(Page* p) { 126 static void VerifyMarking(Page* p) {
127 VerifyMarking(p->ObjectAreaStart(), p->ObjectAreaEnd()); 127 VerifyMarking(p->ObjectAreaStart(), p->ObjectAreaEnd());
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 ClearMarkbits(Heap::map_space()); 231 ClearMarkbits(Heap::map_space());
232 ClearMarkbits(Heap::old_pointer_space()); 232 ClearMarkbits(Heap::old_pointer_space());
233 ClearMarkbits(Heap::old_data_space()); 233 ClearMarkbits(Heap::old_data_space());
234 ClearMarkbits(Heap::cell_space()); 234 ClearMarkbits(Heap::cell_space());
235 } 235 }
236 236
237 237
238 void Marking::TransferMark(Address old_start, Address new_start) { 238 void Marking::TransferMark(Address old_start, Address new_start) {
239 if (old_start == new_start) return; 239 if (old_start == new_start) return;
240 240
241 MarkBit new_mark_bit = Marking::MarkBitFrom(new_start);
242
241 if (!IncrementalMarking::IsStopped()) { 243 if (!IncrementalMarking::IsStopped()) {
242 if (IncrementalMarking::IsBlack(HeapObject::FromAddress(old_start))) { 244 MarkBit old_mark_bit = Marking::MarkBitFrom(old_start);
243 IncrementalMarking::MarkBlack(HeapObject::FromAddress(new_start)); 245 if (IncrementalMarking::IsBlack(old_mark_bit)) {
244 ClearMark(old_start); 246 IncrementalMarking::MarkBlack(old_mark_bit);
Vyacheslav Egorov (Chromium) 2011/03/21 17:16:30 new_mark_bit
Erik Corry 2011/03/21 20:48:53 Good catch.
245 } else if (IncrementalMarking::IsGrey(HeapObject::FromAddress(old_start))) { 247 old_mark_bit.Clear();
246 ClearMark(old_start + kPointerSize); 248 } else if (IncrementalMarking::IsGrey(old_mark_bit)) {
247 IncrementalMarking::WhiteToGrey(HeapObject::FromAddress(new_start)); 249 old_mark_bit.Next().Clear();
250 IncrementalMarking::WhiteToGrey(HeapObject::FromAddress(new_start),
251 new_mark_bit);
248 IncrementalMarking::RestartIfNotMarking(); 252 IncrementalMarking::RestartIfNotMarking();
249 // TODO(gc): if we shift huge array in the loop we might end up pushing 253 // TODO(gc): if we shift huge array in the loop we might end up pushing
250 // to much to marking stack. maybe we should check one or two elements 254 // to much to marking stack. maybe we should check one or two elements
251 // on top of it to see whether they are equal to old_start. 255 // on top of it to see whether they are equal to old_start.
252 } 256 }
253 } else { 257 } else {
254 if (Heap::InNewSpace(old_start) || !IsMarked(old_start)) { 258 ASSERT(IncrementalMarking::IsStopped());
259 if (Heap::InNewSpace(old_start)) {
255 return; 260 return;
261 } else {
262 MarkBit old_mark_bit = Marking::MarkBitFrom(old_start);
263 if (!old_mark_bit.Get()) {
264 return;
265 }
256 } 266 }
257 SetMark(new_start); 267 new_mark_bit.Set();
258 } 268 }
259 } 269 }
260 270
261 271
262 void MarkCompactCollector::Prepare(GCTracer* tracer) { 272 void MarkCompactCollector::Prepare(GCTracer* tracer) {
263 FLAG_flush_code = false; 273 FLAG_flush_code = false;
264 FLAG_always_compact = false; 274 FLAG_always_compact = false;
265 FLAG_never_compact = true; 275 FLAG_never_compact = true;
266 276
267 // Disable collection of maps if incremental marking is enabled. 277 // Disable collection of maps if incremental marking is enabled.
(...skipping 27 matching lines...) Expand all
295 } 305 }
296 #endif 306 #endif
297 307
298 PagedSpaces spaces; 308 PagedSpaces spaces;
299 for (PagedSpace* space = spaces.next(); 309 for (PagedSpace* space = spaces.next();
300 space != NULL; space = spaces.next()) { 310 space != NULL; space = spaces.next()) {
301 space->PrepareForMarkCompact(compacting_collection_); 311 space->PrepareForMarkCompact(compacting_collection_);
302 } 312 }
303 313
304 if (IncrementalMarking::state() == IncrementalMarking::STOPPED) { 314 if (IncrementalMarking::state() == IncrementalMarking::STOPPED) {
305 Address new_space_top = Heap::new_space()->top();
306 Address new_space_bottom = Heap::new_space()->bottom(); 315 Address new_space_bottom = Heap::new_space()->bottom();
316 uintptr_t new_space_size =
317 RoundUp(Heap::new_space()->top() - new_space_bottom, 32 * kPointerSize);
307 318
308 Marking::ClearRange(new_space_bottom, 319 Marking::ClearRange(new_space_bottom, new_space_size);
309 static_cast<int>(new_space_top - new_space_bottom));
310 320
311 ClearMarkbits(); 321 ClearMarkbits();
312 #ifdef DEBUG 322 #ifdef DEBUG
313 VerifyMarkbitsAreClean(); 323 VerifyMarkbitsAreClean();
314 #endif 324 #endif
315 } 325 }
316 326
317 #ifdef DEBUG 327 #ifdef DEBUG
318 live_bytes_ = 0; 328 live_bytes_ = 0;
319 live_young_objects_size_ = 0; 329 live_young_objects_size_ = 0;
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 Code* lazy_compile = Builtins::builtin(Builtins::LazyCompile); 434 Code* lazy_compile = Builtins::builtin(Builtins::LazyCompile);
425 435
426 JSFunction* candidate = jsfunction_candidates_head_; 436 JSFunction* candidate = jsfunction_candidates_head_;
427 JSFunction* next_candidate; 437 JSFunction* next_candidate;
428 while (candidate != NULL) { 438 while (candidate != NULL) {
429 next_candidate = GetNextCandidate(candidate); 439 next_candidate = GetNextCandidate(candidate);
430 440
431 SharedFunctionInfo* shared = candidate->unchecked_shared(); 441 SharedFunctionInfo* shared = candidate->unchecked_shared();
432 442
433 Code* code = shared->unchecked_code(); 443 Code* code = shared->unchecked_code();
434 if (!Marking::IsMarked(code->address())) { 444 MarkBit code_mark = Marking::MarkBitFrom(code);
445 if (!code_mark.Get()) {
435 shared->set_code(lazy_compile); 446 shared->set_code(lazy_compile);
436 candidate->set_code(lazy_compile); 447 candidate->set_code(lazy_compile);
437 } else { 448 } else {
438 candidate->set_code(shared->unchecked_code()); 449 candidate->set_code(shared->unchecked_code());
439 } 450 }
440 451
441 candidate = next_candidate; 452 candidate = next_candidate;
442 } 453 }
443 454
444 jsfunction_candidates_head_ = NULL; 455 jsfunction_candidates_head_ = NULL;
445 } 456 }
446 457
447 458
448 static void ProcessSharedFunctionInfoCandidates() { 459 static void ProcessSharedFunctionInfoCandidates() {
449 Code* lazy_compile = Builtins::builtin(Builtins::LazyCompile); 460 Code* lazy_compile = Builtins::builtin(Builtins::LazyCompile);
450 461
451 SharedFunctionInfo* candidate = shared_function_info_candidates_head_; 462 SharedFunctionInfo* candidate = shared_function_info_candidates_head_;
452 SharedFunctionInfo* next_candidate; 463 SharedFunctionInfo* next_candidate;
453 while (candidate != NULL) { 464 while (candidate != NULL) {
454 next_candidate = GetNextCandidate(candidate); 465 next_candidate = GetNextCandidate(candidate);
455 SetNextCandidate(candidate, NULL); 466 SetNextCandidate(candidate, NULL);
456 467
457 Code* code = candidate->unchecked_code(); 468 Code* code = candidate->unchecked_code();
458 if (!Marking::IsMarked(code->address())) { 469 MarkBit code_mark = Marking::MarkBitFrom(code);
470 if (!code_mark.Get()) {
459 candidate->set_code(lazy_compile); 471 candidate->set_code(lazy_compile);
460 } 472 }
461 473
462 candidate = next_candidate; 474 candidate = next_candidate;
463 } 475 }
464 476
465 shared_function_info_candidates_head_ = NULL; 477 shared_function_info_candidates_head_ = NULL;
466 } 478 }
467 479
468 480
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 } 655 }
644 656
645 static inline void VisitCodeTarget(RelocInfo* rinfo) { 657 static inline void VisitCodeTarget(RelocInfo* rinfo) {
646 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); 658 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
647 Code* code = Code::GetCodeFromTargetAddress(rinfo->target_address()); 659 Code* code = Code::GetCodeFromTargetAddress(rinfo->target_address());
648 if (FLAG_cleanup_ics_at_gc && code->is_inline_cache_stub()) { 660 if (FLAG_cleanup_ics_at_gc && code->is_inline_cache_stub()) {
649 IC::Clear(rinfo->pc()); 661 IC::Clear(rinfo->pc());
650 // Please note targets for cleared inline cached do not have to be 662 // Please note targets for cleared inline cached do not have to be
651 // marked since they are contained in Heap::non_monomorphic_cache(). 663 // marked since they are contained in Heap::non_monomorphic_cache().
652 } else { 664 } else {
653 MarkCompactCollector::MarkObject(code); 665 MarkBit code_mark = Marking::MarkBitFrom(code);
666 MarkCompactCollector::MarkObject(code, code_mark);
654 } 667 }
655 } 668 }
656 669
657 static void VisitGlobalPropertyCell(RelocInfo* rinfo) { 670 static void VisitGlobalPropertyCell(RelocInfo* rinfo) {
658 ASSERT(rinfo->rmode() == RelocInfo::GLOBAL_PROPERTY_CELL); 671 ASSERT(rinfo->rmode() == RelocInfo::GLOBAL_PROPERTY_CELL);
659 Object* cell = rinfo->target_cell(); 672 Object* cell = rinfo->target_cell();
660 Object* old_cell = cell; 673 Object* old_cell = cell;
661 VisitPointer(&cell); 674 VisitPointer(&cell);
662 if (cell != old_cell) { 675 if (cell != old_cell) {
663 rinfo->set_target_cell(reinterpret_cast<JSGlobalPropertyCell*>(cell), 676 rinfo->set_target_cell(reinterpret_cast<JSGlobalPropertyCell*>(cell),
664 NULL); 677 NULL);
665 } 678 }
666 } 679 }
667 680
668 static inline void VisitDebugTarget(RelocInfo* rinfo) { 681 static inline void VisitDebugTarget(RelocInfo* rinfo) {
669 ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) && 682 ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) &&
670 rinfo->IsPatchedReturnSequence()) || 683 rinfo->IsPatchedReturnSequence()) ||
671 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && 684 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
672 rinfo->IsPatchedDebugBreakSlotSequence())); 685 rinfo->IsPatchedDebugBreakSlotSequence()));
673 HeapObject* code = Code::GetCodeFromTargetAddress(rinfo->call_address()); 686 HeapObject* code = Code::GetCodeFromTargetAddress(rinfo->call_address());
674 MarkCompactCollector::MarkObject(code); 687 MarkBit code_mark = Marking::MarkBitFrom(code);
688 MarkCompactCollector::MarkObject(code, code_mark);
675 } 689 }
676 690
677 // Mark object pointed to by p. 691 // Mark object pointed to by p.
678 INLINE(static void MarkObjectByPointer(Object** p)) { 692 INLINE(static void MarkObjectByPointer(Object** p)) {
679 if (!(*p)->IsHeapObject()) return; 693 if (!(*p)->IsHeapObject()) return;
680 HeapObject* object = ShortCircuitConsString(p); 694 HeapObject* object = ShortCircuitConsString(p);
681 MarkCompactCollector::MarkObject(object); 695 MarkBit mark = Marking::MarkBitFrom(object);
696 MarkCompactCollector::MarkObject(object, mark);
682 } 697 }
683 698
684 // Visit an unmarked object. 699 // Visit an unmarked object.
685 static inline void VisitUnmarkedObject(HeapObject* obj) { 700 static inline void VisitUnmarkedObject(HeapObject* obj) {
686 #ifdef DEBUG 701 #ifdef DEBUG
687 ASSERT(Heap::Contains(obj)); 702 ASSERT(Heap::Contains(obj));
688 ASSERT(!Marking::IsMarked(obj->address())); 703 ASSERT(!MarkCompactCollector::IsMarked(obj));
689 #endif 704 #endif
690 Map* map = obj->map(); 705 Map* map = obj->map();
691 MarkCompactCollector::SetMark(obj); 706 MarkBit mark = Marking::MarkBitFrom(obj);
707 MarkCompactCollector::SetMark(obj, mark);
692 // Mark the map pointer and the body. 708 // Mark the map pointer and the body.
693 MarkCompactCollector::MarkObject(map); 709 MarkBit map_mark = Marking::MarkBitFrom(map);
710 MarkCompactCollector::MarkObject(map, map_mark);
694 IterateBody(map, obj); 711 IterateBody(map, obj);
695 } 712 }
696 713
697 // Visit all unmarked objects pointed to by [start, end). 714 // Visit all unmarked objects pointed to by [start, end).
698 // Returns false if the operation fails (lack of stack space). 715 // Returns false if the operation fails (lack of stack space).
699 static inline bool VisitUnmarkedObjects(Object** start, Object** end) { 716 static inline bool VisitUnmarkedObjects(Object** start, Object** end) {
700 // Return false is we are close to the stack limit. 717 // Return false is we are close to the stack limit.
701 StackLimitCheck check; 718 StackLimitCheck check;
702 if (check.HasOverflowed()) return false; 719 if (check.HasOverflowed()) return false;
703 720
704 // Visit the unmarked objects. 721 // Visit the unmarked objects.
705 for (Object** p = start; p < end; p++) { 722 for (Object** p = start; p < end; p++) {
706 if (!(*p)->IsHeapObject()) continue; 723 Object* o = *p;
707 HeapObject* obj = HeapObject::cast(*p); 724 if (!o->IsHeapObject()) continue;
708 if (Marking::IsMarked(obj)) continue; 725 HeapObject* obj = HeapObject::cast(o);
726 MarkBit mark = Marking::MarkBitFrom(obj);
727 if (mark.Get()) continue;
709 VisitUnmarkedObject(obj); 728 VisitUnmarkedObject(obj);
710 } 729 }
711 return true; 730 return true;
712 } 731 }
713 732
714 static inline void VisitExternalReference(Address* p) { } 733 static inline void VisitExternalReference(Address* p) { }
715 static inline void VisitRuntimeEntry(RelocInfo* rinfo) { } 734 static inline void VisitRuntimeEntry(RelocInfo* rinfo) { }
716 735
717 private: 736 private:
718 class DataObjectVisitor { 737 class DataObjectVisitor {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
759 inline static bool IsCompiled(SharedFunctionInfo* function) { 778 inline static bool IsCompiled(SharedFunctionInfo* function) {
760 return 779 return
761 function->unchecked_code() != Builtins::builtin(Builtins::LazyCompile); 780 function->unchecked_code() != Builtins::builtin(Builtins::LazyCompile);
762 } 781 }
763 782
764 inline static bool IsFlushable(JSFunction* function) { 783 inline static bool IsFlushable(JSFunction* function) {
765 SharedFunctionInfo* shared_info = function->unchecked_shared(); 784 SharedFunctionInfo* shared_info = function->unchecked_shared();
766 785
767 // Code is either on stack, in compilation cache or referenced 786 // Code is either on stack, in compilation cache or referenced
768 // by optimized version of function. 787 // by optimized version of function.
769 if (Marking::IsMarked(function->unchecked_code())) { 788 MarkBit code_mark = Marking::MarkBitFrom(function->unchecked_code());
789 if (code_mark.Get()) {
770 shared_info->set_code_age(0); 790 shared_info->set_code_age(0);
771 return false; 791 return false;
772 } 792 }
773 793
774 // We do not flush code for optimized functions. 794 // We do not flush code for optimized functions.
775 if (function->code() != shared_info->unchecked_code()) { 795 if (function->code() != shared_info->unchecked_code()) {
776 return false; 796 return false;
777 } 797 }
778 798
779 return IsFlushable(shared_info); 799 return IsFlushable(shared_info);
780 } 800 }
781 801
782 inline static bool IsFlushable(SharedFunctionInfo* shared_info) { 802 inline static bool IsFlushable(SharedFunctionInfo* shared_info) {
783 // Code is either on stack, in compilation cache or referenced 803 // Code is either on stack, in compilation cache or referenced
784 // by optimized version of function. 804 // by optimized version of function.
785 if (Marking::IsMarked(shared_info->unchecked_code())) { 805 MarkBit code_mark = Marking::MarkBitFrom(shared_info->unchecked_code());
806 if (code_mark.Get()) {
786 shared_info->set_code_age(0); 807 shared_info->set_code_age(0);
787 return false; 808 return false;
788 } 809 }
789 810
790 // The function must be compiled and have the source code available, 811 // The function must be compiled and have the source code available,
791 // to be able to recompile it in case we need the function again. 812 // to be able to recompile it in case we need the function again.
792 if (!(shared_info->is_compiled() && HasSourceCode(shared_info))) { 813 if (!(shared_info->is_compiled() && HasSourceCode(shared_info))) {
793 return false; 814 return false;
794 } 815 }
795 816
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
909 930
910 static void VisitJSFunctionAndFlushCode(Map* map, HeapObject* object) { 931 static void VisitJSFunctionAndFlushCode(Map* map, HeapObject* object) {
911 JSFunction* jsfunction = reinterpret_cast<JSFunction*>(object); 932 JSFunction* jsfunction = reinterpret_cast<JSFunction*>(object);
912 // The function must have a valid context and not be a builtin. 933 // The function must have a valid context and not be a builtin.
913 bool flush_code_candidate = false; 934 bool flush_code_candidate = false;
914 if (IsValidNotBuiltinContext(jsfunction->unchecked_context())) { 935 if (IsValidNotBuiltinContext(jsfunction->unchecked_context())) {
915 flush_code_candidate = FlushCodeForFunction(jsfunction); 936 flush_code_candidate = FlushCodeForFunction(jsfunction);
916 } 937 }
917 938
918 if (!flush_code_candidate) { 939 if (!flush_code_candidate) {
919 MarkCompactCollector::MarkObject( 940 Code* code = jsfunction->unchecked_shared()->unchecked_code();
920 jsfunction->unchecked_shared()->unchecked_code()); 941 MarkBit code_mark = Marking::MarkBitFrom(code);
942 MarkCompactCollector::MarkObject(code, code_mark);
921 943
922 if (jsfunction->unchecked_code()->kind() == Code::OPTIMIZED_FUNCTION) { 944 if (jsfunction->unchecked_code()->kind() == Code::OPTIMIZED_FUNCTION) {
923 // For optimized functions we should retain both non-optimized version 945 // For optimized functions we should retain both non-optimized version
924 // of it's code and non-optimized version of all inlined functions. 946 // of it's code and non-optimized version of all inlined functions.
925 // This is required to support bailing out from inlined code. 947 // This is required to support bailing out from inlined code.
926 DeoptimizationInputData* data = 948 DeoptimizationInputData* data =
927 reinterpret_cast<DeoptimizationInputData*>( 949 reinterpret_cast<DeoptimizationInputData*>(
928 jsfunction->unchecked_code()->unchecked_deoptimization_data()); 950 jsfunction->unchecked_code()->unchecked_deoptimization_data());
929 951
930 FixedArray* literals = data->UncheckedLiteralArray(); 952 FixedArray* literals = data->UncheckedLiteralArray();
931 953
932 for (int i = 0, count = data->InlinedFunctionCount()->value(); 954 for (int i = 0, count = data->InlinedFunctionCount()->value();
933 i < count; 955 i < count;
934 i++) { 956 i++) {
935 JSFunction* inlined = reinterpret_cast<JSFunction*>(literals->get(i)); 957 JSFunction* inlined = reinterpret_cast<JSFunction*>(literals->get(i));
936 MarkCompactCollector::MarkObject( 958 Code* inlined_code = inlined->unchecked_shared()->unchecked_code();
Vyacheslav Egorov (Chromium) 2011/03/21 17:16:30 I think we will need to kill all unchecked_* gette
Erik Corry 2011/03/21 20:48:53 Done.
937 inlined->unchecked_shared()->unchecked_code()); 959 MarkBit inlined_code_mark = Marking::MarkBitFrom(inlined_code);
960 MarkCompactCollector::MarkObject(inlined_code, inlined_code_mark);
938 } 961 }
939 } 962 }
940 } 963 }
941 964
942 VisitJSFunctionFields(map, 965 VisitJSFunctionFields(map,
943 reinterpret_cast<JSFunction*>(object), 966 reinterpret_cast<JSFunction*>(object),
944 flush_code_candidate); 967 flush_code_candidate);
945 } 968 }
946 969
947 970
(...skipping 15 matching lines...) Expand all
963 SLOT_ADDR(object, JSFunction::kCodeEntryOffset)); 986 SLOT_ADDR(object, JSFunction::kCodeEntryOffset));
964 987
965 if (!flush_code_candidate) { 988 if (!flush_code_candidate) {
966 VisitCodeEntry(object->address() + JSFunction::kCodeEntryOffset); 989 VisitCodeEntry(object->address() + JSFunction::kCodeEntryOffset);
967 } else { 990 } else {
968 // Don't visit code object. 991 // Don't visit code object.
969 992
970 // Visit shared function info to avoid double checking of it's 993 // Visit shared function info to avoid double checking of it's
971 // flushability. 994 // flushability.
972 SharedFunctionInfo* shared_info = object->unchecked_shared(); 995 SharedFunctionInfo* shared_info = object->unchecked_shared();
973 if (!Marking::IsMarked(shared_info)) { 996 MarkBit shared_info_mark = Marking::MarkBitFrom(shared_info);
997 if (!shared_info_mark.Get()) {
974 Map* shared_info_map = shared_info->map(); 998 Map* shared_info_map = shared_info->map();
975 MarkCompactCollector::SetMark(shared_info); 999 MarkBit shared_info_map_mark = Marking::MarkBitFrom(shared_info_map);
976 MarkCompactCollector::MarkObject(shared_info_map); 1000 MarkCompactCollector::SetMark(shared_info, shared_info_mark);
1001 MarkCompactCollector::MarkObject(shared_info_map, shared_info_map_mark);
977 VisitSharedFunctionInfoAndFlushCodeGeneric(shared_info_map, 1002 VisitSharedFunctionInfoAndFlushCodeGeneric(shared_info_map,
978 shared_info, 1003 shared_info,
979 true); 1004 true);
980 } 1005 }
981 } 1006 }
982 1007
983 VisitPointers(SLOT_ADDR(object, 1008 VisitPointers(SLOT_ADDR(object,
984 JSFunction::kCodeEntryOffset + kPointerSize), 1009 JSFunction::kCodeEntryOffset + kPointerSize),
985 SLOT_ADDR(object, JSFunction::kNonWeakFieldsEndOffset)); 1010 SLOT_ADDR(object, JSFunction::kNonWeakFieldsEndOffset));
986 1011
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1033 void VisitDebugTarget(RelocInfo* rinfo) { 1058 void VisitDebugTarget(RelocInfo* rinfo) {
1034 StaticMarkingVisitor::VisitDebugTarget(rinfo); 1059 StaticMarkingVisitor::VisitDebugTarget(rinfo);
1035 } 1060 }
1036 }; 1061 };
1037 1062
1038 1063
1039 class CodeMarkingVisitor : public ThreadVisitor { 1064 class CodeMarkingVisitor : public ThreadVisitor {
1040 public: 1065 public:
1041 void VisitThread(ThreadLocalTop* top) { 1066 void VisitThread(ThreadLocalTop* top) {
1042 for (StackFrameIterator it(top); !it.done(); it.Advance()) { 1067 for (StackFrameIterator it(top); !it.done(); it.Advance()) {
1043 MarkCompactCollector::MarkObject(it.frame()->unchecked_code()); 1068 Code* code = it.frame()->unchecked_code();
1069 MarkBit code_bit = Marking::MarkBitFrom(code);
1070 MarkCompactCollector::MarkObject(it.frame()->unchecked_code(), code_bit);
1044 } 1071 }
1045 } 1072 }
1046 }; 1073 };
1047 1074
1048 1075
1049 class SharedFunctionInfoMarkingVisitor : public ObjectVisitor { 1076 class SharedFunctionInfoMarkingVisitor : public ObjectVisitor {
1050 public: 1077 public:
1051 void VisitPointers(Object** start, Object** end) { 1078 void VisitPointers(Object** start, Object** end) {
1052 for (Object** p = start; p < end; p++) VisitPointer(p); 1079 for (Object** p = start; p < end; p++) VisitPointer(p);
1053 } 1080 }
1054 1081
1055 void VisitPointer(Object** slot) { 1082 void VisitPointer(Object** slot) {
1056 Object* obj = *slot; 1083 Object* obj = *slot;
1057 if (obj->IsSharedFunctionInfo()) { 1084 if (obj->IsSharedFunctionInfo()) {
1058 SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(obj); 1085 SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(obj);
1059 MarkCompactCollector::MarkObject(shared->unchecked_code()); 1086 MarkBit shared_mark = Marking::MarkBitFrom(shared);
1060 MarkCompactCollector::MarkObject(shared); 1087 MarkBit code_mark = Marking::MarkBitFrom(shared->unchecked_code());
1088 MarkCompactCollector::MarkObject(shared->unchecked_code(), code_mark);
1089 MarkCompactCollector::MarkObject(shared, shared_mark);
1061 } 1090 }
1062 } 1091 }
1063 }; 1092 };
1064 1093
1065 1094
1066 void MarkCompactCollector::PrepareForCodeFlushing() { 1095 void MarkCompactCollector::PrepareForCodeFlushing() {
1067 if (!FLAG_flush_code) { 1096 if (!FLAG_flush_code) {
1068 StaticMarkingVisitor::EnableCodeFlushing(false); 1097 StaticMarkingVisitor::EnableCodeFlushing(false);
1069 return; 1098 return;
1070 } 1099 }
1071 1100
1072 #ifdef ENABLE_DEBUGGER_SUPPORT 1101 #ifdef ENABLE_DEBUGGER_SUPPORT
1073 if (Debug::IsLoaded() || Debug::has_break_points()) { 1102 if (Debug::IsLoaded() || Debug::has_break_points()) {
1074 StaticMarkingVisitor::EnableCodeFlushing(false); 1103 StaticMarkingVisitor::EnableCodeFlushing(false);
1075 return; 1104 return;
1076 } 1105 }
1077 #endif 1106 #endif
1078 StaticMarkingVisitor::EnableCodeFlushing(true); 1107 StaticMarkingVisitor::EnableCodeFlushing(true);
1079 1108
1080 // Ensure that empty descriptor array is marked. Method MarkDescriptorArray 1109 // Ensure that empty descriptor array is marked. Method MarkDescriptorArray
1081 // relies on it being marked before any other descriptor array. 1110 // relies on it being marked before any other descriptor array.
1082 MarkObject(Heap::raw_unchecked_empty_descriptor_array()); 1111 HeapObject* descriptor_array = Heap::raw_unchecked_empty_descriptor_array();
1112 MarkBit descriptor_array_mark = Marking::MarkBitFrom(descriptor_array);
1113 MarkObject(descriptor_array, descriptor_array_mark);
1083 1114
1084 // Make sure we are not referencing the code from the stack. 1115 // Make sure we are not referencing the code from the stack.
1085 for (StackFrameIterator it; !it.done(); it.Advance()) { 1116 for (StackFrameIterator it; !it.done(); it.Advance()) {
1086 MarkObject(it.frame()->unchecked_code()); 1117 Code* code = it.frame()->unchecked_code();
1118 MarkBit code_mark = Marking::MarkBitFrom(code);
1119 MarkObject(code, code_mark);
1087 } 1120 }
1088 1121
1089 // Iterate the archived stacks in all threads to check if 1122 // Iterate the archived stacks in all threads to check if
1090 // the code is referenced. 1123 // the code is referenced.
1091 CodeMarkingVisitor code_marking_visitor; 1124 CodeMarkingVisitor code_marking_visitor;
1092 ThreadManager::IterateArchivedThreads(&code_marking_visitor); 1125 ThreadManager::IterateArchivedThreads(&code_marking_visitor);
1093 1126
1094 SharedFunctionInfoMarkingVisitor visitor; 1127 SharedFunctionInfoMarkingVisitor visitor;
1095 CompilationCache::IterateFunctions(&visitor); 1128 CompilationCache::IterateFunctions(&visitor);
1096 HandleScopeImplementer::Iterate(&visitor); 1129 HandleScopeImplementer::Iterate(&visitor);
(...skipping 12 matching lines...) Expand all
1109 void VisitPointers(Object** start, Object** end) { 1142 void VisitPointers(Object** start, Object** end) {
1110 for (Object** p = start; p < end; p++) MarkObjectByPointer(p); 1143 for (Object** p = start; p < end; p++) MarkObjectByPointer(p);
1111 } 1144 }
1112 1145
1113 private: 1146 private:
1114 void MarkObjectByPointer(Object** p) { 1147 void MarkObjectByPointer(Object** p) {
1115 if (!(*p)->IsHeapObject()) return; 1148 if (!(*p)->IsHeapObject()) return;
1116 1149
1117 // Replace flat cons strings in place. 1150 // Replace flat cons strings in place.
1118 HeapObject* object = ShortCircuitConsString(p); 1151 HeapObject* object = ShortCircuitConsString(p);
1119 if (Marking::IsMarked(object)) return; 1152 MarkBit mark_bit = Marking::MarkBitFrom(object);
1153 if (mark_bit.Get()) return;
1120 1154
1121 Map* map = object->map(); 1155 Map* map = object->map();
1122 // Mark the object. 1156 // Mark the object.
1123 MarkCompactCollector::SetMark(object); 1157 MarkCompactCollector::SetMark(object, mark_bit);
1124 1158
1125 // Mark the map pointer and body, and push them on the marking stack. 1159 // Mark the map pointer and body, and push them on the marking stack.
1126 MarkCompactCollector::MarkObject(map); 1160 MarkBit map_mark = Marking::MarkBitFrom(map);
1161 MarkCompactCollector::MarkObject(map, map_mark);
1127 StaticMarkingVisitor::IterateBody(map, object); 1162 StaticMarkingVisitor::IterateBody(map, object);
1128 1163
1129 // Mark all the objects reachable from the map and body. May leave 1164 // Mark all the objects reachable from the map and body. May leave
1130 // overflowed objects in the heap. 1165 // overflowed objects in the heap.
1131 MarkCompactCollector::EmptyMarkingStack(); 1166 MarkCompactCollector::EmptyMarkingStack();
1132 } 1167 }
1133 }; 1168 };
1134 1169
1135 1170
1136 // Helper class for pruning the symbol table. 1171 // Helper class for pruning the symbol table.
1137 class SymbolTableCleaner : public ObjectVisitor { 1172 class SymbolTableCleaner : public ObjectVisitor {
1138 public: 1173 public:
1139 SymbolTableCleaner() : pointers_removed_(0) { } 1174 SymbolTableCleaner() : pointers_removed_(0) { }
1140 1175
1141 virtual void VisitPointers(Object** start, Object** end) { 1176 virtual void VisitPointers(Object** start, Object** end) {
1142 // Visit all HeapObject pointers in [start, end). 1177 // Visit all HeapObject pointers in [start, end).
1143 for (Object** p = start; p < end; p++) { 1178 for (Object** p = start; p < end; p++) {
1144 if ((*p)->IsHeapObject() && 1179 Object* o = *p;
1145 !Marking::IsMarked(HeapObject::cast(*p))) { 1180 if (o->IsHeapObject() &&
1181 !Marking::MarkBitFrom(HeapObject::cast(o)).Get()) {
1146 // Check if the symbol being pruned is an external symbol. We need to 1182 // Check if the symbol being pruned is an external symbol. We need to
1147 // delete the associated external data as this symbol is going away. 1183 // delete the associated external data as this symbol is going away.
1148 1184
1149 // Since no objects have yet been moved we can safely access the map of 1185 // Since no objects have yet been moved we can safely access the map of
1150 // the object. 1186 // the object.
1151 if ((*p)->IsExternalString()) { 1187 if (o->IsExternalString()) {
1152 Heap::FinalizeExternalString(String::cast(*p)); 1188 Heap::FinalizeExternalString(String::cast(o));
1153 } 1189 }
1154 // Set the entry to null_value (as deleted). 1190 // Set the entry to null_value (as deleted).
1155 *p = Heap::raw_unchecked_null_value(); 1191 *p = Heap::raw_unchecked_null_value();
1156 pointers_removed_++; 1192 pointers_removed_++;
1157 } 1193 }
1158 } 1194 }
1159 } 1195 }
1160 1196
1161 int PointersRemoved() { 1197 int PointersRemoved() {
1162 return pointers_removed_; 1198 return pointers_removed_;
1163 } 1199 }
1164 private: 1200 private:
1165 int pointers_removed_; 1201 int pointers_removed_;
1166 }; 1202 };
1167 1203
1168 1204
1169 // Implementation of WeakObjectRetainer for mark compact GCs. All marked objects 1205 // Implementation of WeakObjectRetainer for mark compact GCs. All marked objects
1170 // are retained. 1206 // are retained.
1171 class MarkCompactWeakObjectRetainer : public WeakObjectRetainer { 1207 class MarkCompactWeakObjectRetainer : public WeakObjectRetainer {
1172 public: 1208 public:
1173 virtual Object* RetainAs(Object* object) { 1209 virtual Object* RetainAs(Object* object) {
1174 if (Marking::IsMarked(HeapObject::cast(object))) { 1210 if (Marking::MarkBitFrom(HeapObject::cast(object)).Get()) {
1175 return object; 1211 return object;
1176 } else { 1212 } else {
1177 return NULL; 1213 return NULL;
1178 } 1214 }
1179 } 1215 }
1180 }; 1216 };
1181 1217
1182 1218
1183 void MarkCompactCollector::ProcessNewlyMarkedObject(HeapObject* object) { 1219 void MarkCompactCollector::ProcessNewlyMarkedObject(HeapObject* object) {
1184 ASSERT(Marking::IsMarked(object)); 1220 ASSERT(IsMarked(object));
1185 ASSERT(Heap::Contains(object)); 1221 ASSERT(Heap::Contains(object));
1186 if (object->IsMap()) { 1222 if (object->IsMap()) {
1187 Map* map = Map::cast(object); 1223 Map* map = Map::cast(object);
1188 if (FLAG_cleanup_caches_in_maps_at_gc) { 1224 if (FLAG_cleanup_caches_in_maps_at_gc) {
1189 map->ClearCodeCache(); 1225 map->ClearCodeCache();
1190 } 1226 }
1191 if (FLAG_collect_maps && 1227 if (FLAG_collect_maps &&
1192 map->instance_type() >= FIRST_JS_OBJECT_TYPE && 1228 map->instance_type() >= FIRST_JS_OBJECT_TYPE &&
1193 map->instance_type() <= JS_FUNCTION_TYPE) { 1229 map->instance_type() <= JS_FUNCTION_TYPE) {
1194 MarkMapContents(map); 1230 MarkMapContents(map);
(...skipping 17 matching lines...) Expand all
1212 Map::kPointerFieldsBeginOffset); 1248 Map::kPointerFieldsBeginOffset);
1213 1249
1214 Object** end_slot = HeapObject::RawField(map, Map::kPointerFieldsEndOffset); 1250 Object** end_slot = HeapObject::RawField(map, Map::kPointerFieldsEndOffset);
1215 1251
1216 StaticMarkingVisitor::VisitPointers(start_slot, end_slot); 1252 StaticMarkingVisitor::VisitPointers(start_slot, end_slot);
1217 } 1253 }
1218 1254
1219 1255
1220 void MarkCompactCollector::MarkDescriptorArray( 1256 void MarkCompactCollector::MarkDescriptorArray(
1221 DescriptorArray* descriptors) { 1257 DescriptorArray* descriptors) {
1222 if (Marking::IsMarked(descriptors)) return; 1258 MarkBit descriptors_mark = Marking::MarkBitFrom(descriptors);
1259 if (descriptors_mark.Get()) return;
1223 // Empty descriptor array is marked as a root before any maps are marked. 1260 // Empty descriptor array is marked as a root before any maps are marked.
1224 ASSERT(descriptors != Heap::raw_unchecked_empty_descriptor_array()); 1261 ASSERT(descriptors != Heap::raw_unchecked_empty_descriptor_array());
1225 SetMark(descriptors); 1262 SetMark(descriptors, descriptors_mark);
1226 1263
1227 FixedArray* contents = reinterpret_cast<FixedArray*>( 1264 FixedArray* contents = reinterpret_cast<FixedArray*>(
1228 descriptors->get(DescriptorArray::kContentArrayIndex)); 1265 descriptors->get(DescriptorArray::kContentArrayIndex));
1229 ASSERT(contents->IsHeapObject()); 1266 ASSERT(contents->IsHeapObject());
1230 ASSERT(!Marking::IsMarked(contents)); 1267 ASSERT(!IsMarked(contents));
1231 ASSERT(contents->IsFixedArray()); 1268 ASSERT(contents->IsFixedArray());
1232 ASSERT(contents->length() >= 2); 1269 ASSERT(contents->length() >= 2);
1233 SetMark(contents); 1270 MarkBit contents_mark = Marking::MarkBitFrom(contents);
1271 SetMark(contents, contents_mark);
1234 // Contents contains (value, details) pairs. If the details say that 1272 // Contents contains (value, details) pairs. If the details say that
1235 // the type of descriptor is MAP_TRANSITION, CONSTANT_TRANSITION, or 1273 // the type of descriptor is MAP_TRANSITION, CONSTANT_TRANSITION, or
1236 // NULL_DESCRIPTOR, we don't mark the value as live. Only for 1274 // NULL_DESCRIPTOR, we don't mark the value as live. Only for
1237 // MAP_TRANSITION and CONSTANT_TRANSITION is the value an Object* (a 1275 // MAP_TRANSITION and CONSTANT_TRANSITION is the value an Object* (a
1238 // Map*). 1276 // Map*).
1239 for (int i = 0; i < contents->length(); i += 2) { 1277 for (int i = 0; i < contents->length(); i += 2) {
1240 // If the pair (value, details) at index i, i+1 is not 1278 // If the pair (value, details) at index i, i+1 is not
1241 // a transition or null descriptor, mark the value. 1279 // a transition or null descriptor, mark the value.
1242 PropertyDetails details(Smi::cast(contents->get(i + 1))); 1280 PropertyDetails details(Smi::cast(contents->get(i + 1)));
1243 if (details.type() < FIRST_PHANTOM_PROPERTY_TYPE) { 1281 if (details.type() < FIRST_PHANTOM_PROPERTY_TYPE) {
1244 HeapObject* object = reinterpret_cast<HeapObject*>(contents->get(i)); 1282 HeapObject* object = reinterpret_cast<HeapObject*>(contents->get(i));
1245 if (object->IsHeapObject() && !Marking::IsMarked(object)) { 1283 if (object->IsHeapObject()) {
1246 SetMark(object); 1284 MarkBit mark = Marking::MarkBitFrom(HeapObject::cast(object));
1247 marking_stack.Push(object); 1285 if (!mark.Get()) {
1286 SetMark(HeapObject::cast(object), mark);
1287 marking_stack.Push(object);
1288 }
1248 } 1289 }
1249 } 1290 }
1250 } 1291 }
1251 // The DescriptorArray descriptors contains a pointer to its contents array, 1292 // The DescriptorArray descriptors contains a pointer to its contents array,
1252 // but the contents array is already marked. 1293 // but the contents array is already marked.
1253 marking_stack.Push(descriptors); 1294 marking_stack.Push(descriptors);
1254 } 1295 }
1255 1296
1256 1297
1257 void MarkCompactCollector::CreateBackPointers() { 1298 void MarkCompactCollector::CreateBackPointers() {
(...skipping 26 matching lines...) Expand all
1284 template<class T> 1325 template<class T>
1285 static void ScanOverflowedObjects(T* it) { 1326 static void ScanOverflowedObjects(T* it) {
1286 #if 0 1327 #if 0
1287 // The caller should ensure that the marking stack is initially not full, 1328 // The caller should ensure that the marking stack is initially not full,
1288 // so that we don't waste effort pointlessly scanning for objects. 1329 // so that we don't waste effort pointlessly scanning for objects.
1289 ASSERT(!marking_stack.is_full()); 1330 ASSERT(!marking_stack.is_full());
1290 1331
1291 for (HeapObject* object = it->next(); object != NULL; object = it->next()) { 1332 for (HeapObject* object = it->next(); object != NULL; object = it->next()) {
1292 if (object->IsOverflowed()) { 1333 if (object->IsOverflowed()) {
1293 object->ClearOverflow(); 1334 object->ClearOverflow();
1294 ASSERT(Marking::IsMarked(object)); 1335 ASSERT(MarkCompactCollector::IsMarked(object));
1295 ASSERT(Heap::Contains(object)); 1336 ASSERT(Heap::Contains(object));
1296 marking_stack.Push(object); 1337 marking_stack.Push(object);
1297 if (marking_stack.is_full()) return; 1338 if (marking_stack.is_full()) return;
1298 } 1339 }
1299 } 1340 }
1300 #endif 1341 #endif
1301 UNREACHABLE(); 1342 UNREACHABLE();
1302 } 1343 }
1303 1344
1304 1345
1305 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) { 1346 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) {
1306 return (*p)->IsHeapObject() && 1347 Object* o = *p;
1307 !Marking::IsMarked(HeapObject::cast(*p)); 1348 if (!o->IsHeapObject()) return false;
1349 HeapObject* heap_object = HeapObject::cast(o);
1350 MarkBit mark = Marking::MarkBitFrom(heap_object);
1351 return !mark.Get();
1308 } 1352 }
1309 1353
1310 1354
1311 void MarkCompactCollector::MarkSymbolTable() { 1355 void MarkCompactCollector::MarkSymbolTable() {
1312 SymbolTable* symbol_table = Heap::raw_unchecked_symbol_table(); 1356 SymbolTable* symbol_table = Heap::raw_unchecked_symbol_table();
1313 // Mark the symbol table itself. 1357 // Mark the symbol table itself.
1314 SetMark(symbol_table); 1358 MarkBit symbol_table_mark = Marking::MarkBitFrom(symbol_table);
1359 SetMark(symbol_table, symbol_table_mark);
1315 // Explicitly mark the prefix. 1360 // Explicitly mark the prefix.
1316 MarkingVisitor marker; 1361 MarkingVisitor marker;
1317 symbol_table->IteratePrefix(&marker); 1362 symbol_table->IteratePrefix(&marker);
1318 ProcessMarkingStack(); 1363 ProcessMarkingStack();
1319 } 1364 }
1320 1365
1321 1366
1322 void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) { 1367 void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) {
1323 // Mark the heap roots including global variables, stack variables, 1368 // Mark the heap roots including global variables, stack variables,
1324 // etc., and all objects reachable from them. 1369 // etc., and all objects reachable from them.
(...skipping 14 matching lines...) Expand all
1339 List<ObjectGroup*>* object_groups = GlobalHandles::ObjectGroups(); 1384 List<ObjectGroup*>* object_groups = GlobalHandles::ObjectGroups();
1340 1385
1341 for (int i = 0; i < object_groups->length(); i++) { 1386 for (int i = 0; i < object_groups->length(); i++) {
1342 ObjectGroup* entry = object_groups->at(i); 1387 ObjectGroup* entry = object_groups->at(i);
1343 if (entry == NULL) continue; 1388 if (entry == NULL) continue;
1344 1389
1345 List<Object**>& objects = entry->objects_; 1390 List<Object**>& objects = entry->objects_;
1346 bool group_marked = false; 1391 bool group_marked = false;
1347 for (int j = 0; j < objects.length(); j++) { 1392 for (int j = 0; j < objects.length(); j++) {
1348 Object* object = *objects[j]; 1393 Object* object = *objects[j];
1349 if (object->IsHeapObject() 1394 if (object->IsHeapObject()) {
1350 && Marking::IsMarked(HeapObject::cast(object))) { 1395 HeapObject* heap_object = HeapObject::cast(object);
1351 group_marked = true; 1396 MarkBit mark = Marking::MarkBitFrom(heap_object);
1352 break; 1397 if (mark.Get()) {
1398 group_marked = true;
1399 break;
1400 }
1353 } 1401 }
1354 } 1402 }
1355 1403
1356 if (!group_marked) continue; 1404 if (!group_marked) continue;
1357 1405
1358 // An object in the group is marked, so mark as gray all white heap 1406 // An object in the group is marked, so mark as grey all white heap
1359 // objects in the group. 1407 // objects in the group.
1360 for (int j = 0; j < objects.length(); ++j) { 1408 for (int j = 0; j < objects.length(); ++j) {
1361 if ((*objects[j])->IsHeapObject()) { 1409 Object* object = *objects[j];
1362 MarkObject(HeapObject::cast(*objects[j])); 1410 if (object->IsHeapObject()) {
1411 HeapObject* heap_object = HeapObject::cast(object);
1412 MarkBit mark = Marking::MarkBitFrom(heap_object);
1413 MarkObject(heap_object, mark);
1363 } 1414 }
1364 } 1415 }
1365 // Once the entire group has been colored gray, set the object group 1416 // Once the entire group has been colored grey, set the object group
1366 // to NULL so it won't be processed again. 1417 // to NULL so it won't be processed again.
1367 delete object_groups->at(i); 1418 delete object_groups->at(i);
1368 object_groups->at(i) = NULL; 1419 object_groups->at(i) = NULL;
1369 } 1420 }
1370 } 1421 }
1371 1422
1372 1423
1373 // Mark all objects reachable from the objects on the marking stack. 1424 // Mark all objects reachable from the objects on the marking stack.
1374 // Before: the marking stack contains zero or more heap object pointers. 1425 // Before: the marking stack contains zero or more heap object pointers.
1375 // After: the marking stack is empty, and all objects reachable from the 1426 // After: the marking stack is empty, and all objects reachable from the
1376 // marking stack have been marked, or are overflowed in the heap. 1427 // marking stack have been marked, or are overflowed in the heap.
1377 void MarkCompactCollector::EmptyMarkingStack() { 1428 void MarkCompactCollector::EmptyMarkingStack() {
1378 while (!marking_stack.is_empty()) { 1429 while (!marking_stack.is_empty()) {
1379 HeapObject* object = marking_stack.Pop(); 1430 HeapObject* object = marking_stack.Pop();
1380 ASSERT(object->IsHeapObject()); 1431 ASSERT(object->IsHeapObject());
1381 ASSERT(Heap::Contains(object)); 1432 ASSERT(Heap::Contains(object));
1382 ASSERT(Marking::IsMarked(object)); 1433 ASSERT(IsMarked(object));
1383 ASSERT(!object->IsOverflowed()); 1434 ASSERT(!object->IsOverflowed());
1384 1435
1385 // Because the object is marked, we have to recover the original map
1386 // pointer and use it to mark the object's body.
1387 Map* map = object->map(); 1436 Map* map = object->map();
1388 MarkObject(map); 1437 MarkBit map_mark = Marking::MarkBitFrom(map);
1438 MarkObject(map, map_mark);
1389 1439
1390 StaticMarkingVisitor::IterateBody(map, object); 1440 StaticMarkingVisitor::IterateBody(map, object);
1391 } 1441 }
1392 } 1442 }
1393 1443
1394 1444
1395 // Sweep the heap for overflowed objects, clear their overflow bits, and 1445 // Sweep the heap for overflowed objects, clear their overflow bits, and
1396 // push them on the marking stack. Stop early if the marking stack fills 1446 // push them on the marking stack. Stop early if the marking stack fills
1397 // before sweeping completes. If sweeping completes, there are no remaining 1447 // before sweeping completes. If sweeping completes, there are no remaining
1398 // overflowed objects in the heap so the overflow flag on the markings stack 1448 // overflowed objects in the heap so the overflow flag on the markings stack
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
1576 // dropping the back pointers temporarily stored in the prototype field. 1626 // dropping the back pointers temporarily stored in the prototype field.
1577 // Setting the prototype field requires following the linked list of 1627 // Setting the prototype field requires following the linked list of
1578 // back pointers, reversing them all at once. This allows us to find 1628 // back pointers, reversing them all at once. This allows us to find
1579 // those maps with map transitions that need to be nulled, and only 1629 // those maps with map transitions that need to be nulled, and only
1580 // scan the descriptor arrays of those maps, not all maps. 1630 // scan the descriptor arrays of those maps, not all maps.
1581 // All of these actions are carried out only on maps of JSObjects 1631 // All of these actions are carried out only on maps of JSObjects
1582 // and related subtypes. 1632 // and related subtypes.
1583 for (HeapObject* obj = map_iterator.Next(); 1633 for (HeapObject* obj = map_iterator.Next();
1584 obj != NULL; obj = map_iterator.Next()) { 1634 obj != NULL; obj = map_iterator.Next()) {
1585 Map* map = reinterpret_cast<Map*>(obj); 1635 Map* map = reinterpret_cast<Map*>(obj);
1586 if (!Marking::IsMarked(map) && map->IsFreeSpace()) continue; 1636 MarkBit map_mark = Marking::MarkBitFrom(map);
1637 if (!map_mark.Get() && map->IsFreeSpace()) continue;
1587 1638
1588 ASSERT(SafeIsMap(map)); 1639 ASSERT(SafeIsMap(map));
1589 // Only JSObject and subtypes have map transitions and back pointers. 1640 // Only JSObject and subtypes have map transitions and back pointers.
1590 if (map->instance_type() < FIRST_JS_OBJECT_TYPE) continue; 1641 if (map->instance_type() < FIRST_JS_OBJECT_TYPE) continue;
1591 if (map->instance_type() > JS_FUNCTION_TYPE) continue; 1642 if (map->instance_type() > JS_FUNCTION_TYPE) continue;
1592 1643
1593 if (Marking::IsMarked(map) && 1644 if (map_mark.Get() &&
1594 map->attached_to_shared_function_info()) { 1645 map->attached_to_shared_function_info()) {
1595 // This map is used for inobject slack tracking and has been detached 1646 // This map is used for inobject slack tracking and has been detached
1596 // from SharedFunctionInfo during the mark phase. 1647 // from SharedFunctionInfo during the mark phase.
1597 // Since it survived the GC, reattach it now. 1648 // Since it survived the GC, reattach it now.
1598 map->unchecked_constructor()->unchecked_shared()->AttachInitialMap(map); 1649 map->unchecked_constructor()->unchecked_shared()->AttachInitialMap(map);
1599 } 1650 }
1600 1651
1601 // Follow the chain of back pointers to find the prototype. 1652 // Follow the chain of back pointers to find the prototype.
1602 Map* current = map; 1653 Map* current = map;
1603 while (SafeIsMap(current)) { 1654 while (SafeIsMap(current)) {
1604 current = reinterpret_cast<Map*>(current->prototype()); 1655 current = reinterpret_cast<Map*>(current->prototype());
1605 ASSERT(current->IsHeapObject()); 1656 ASSERT(current->IsHeapObject());
1606 } 1657 }
1607 Object* real_prototype = current; 1658 Object* real_prototype = current;
1608 1659
1609 // Follow back pointers, setting them to prototype, 1660 // Follow back pointers, setting them to prototype,
1610 // clearing map transitions when necessary. 1661 // clearing map transitions when necessary.
1611 current = map; 1662 bool on_dead_path = !map_mark.Get();
1612 bool on_dead_path = !Marking::IsMarked(current);
1613 Object* next; 1663 Object* next;
1614 while (SafeIsMap(current)) { 1664 while (SafeIsMap(current)) {
1615 next = current->prototype(); 1665 next = current->prototype();
1616 // There should never be a dead map above a live map. 1666 // There should never be a dead map above a live map.
1617 ASSERT(on_dead_path || Marking::IsMarked(current)); 1667 MarkBit current_mark = Marking::MarkBitFrom(current);
1668 ASSERT(on_dead_path || current_mark.Get());
1618 1669
1619 // A live map above a dead map indicates a dead transition. 1670 // A live map above a dead map indicates a dead transition.
1620 // This test will always be false on the first iteration. 1671 // This test will always be false on the first iteration.
1621 if (on_dead_path && Marking::IsMarked(current)) { 1672 if (on_dead_path && current_mark.Get()) {
1622 on_dead_path = false; 1673 on_dead_path = false;
1623 current->ClearNonLiveTransitions(real_prototype); 1674 current->ClearNonLiveTransitions(real_prototype);
1624 } 1675 }
1625 *HeapObject::RawField(current, Map::kPrototypeOffset) = 1676 *HeapObject::RawField(current, Map::kPrototypeOffset) =
1626 real_prototype; 1677 real_prototype;
1627 current = reinterpret_cast<Map*>(next); 1678 current = reinterpret_cast<Map*>(next);
1628 } 1679 }
1629 } 1680 }
1630 } 1681 }
1631 1682
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
1786 space->ResetAllocationInfo(); 1837 space->ResetAllocationInfo();
1787 1838
1788 int size = 0; 1839 int size = 0;
1789 int survivors_size = 0; 1840 int survivors_size = 0;
1790 1841
1791 // First pass: traverse all objects in inactive semispace, remove marks, 1842 // First pass: traverse all objects in inactive semispace, remove marks,
1792 // migrate live objects and write forwarding addresses. 1843 // migrate live objects and write forwarding addresses.
1793 for (Address current = from_bottom; current < from_top; current += size) { 1844 for (Address current = from_bottom; current < from_top; current += size) {
1794 HeapObject* object = HeapObject::FromAddress(current); 1845 HeapObject* object = HeapObject::FromAddress(current);
1795 1846
1796 if (Marking::IsMarked(object)) { 1847
1797 Marking::ClearMark(object); 1848 MarkBit mark_bit = Marking::MarkBitFromNewSpace(object);
1849 if (mark_bit.Get()) {
1850 mark_bit.Clear();
1798 MarkCompactCollector::tracer()->decrement_marked_count(); 1851 MarkCompactCollector::tracer()->decrement_marked_count();
1799 1852
1800 size = object->Size(); 1853 size = object->Size();
1801 survivors_size += size; 1854 survivors_size += size;
1802 1855
1803 // Aggressively promote young survivors to the old space. 1856 // Aggressively promote young survivors to the old space.
1804 if (TryPromoteObject(object, size)) { 1857 if (TryPromoteObject(object, size)) {
1805 continue; 1858 continue;
1806 } 1859 }
1807 1860
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
2212 2265
2213 // Sweeps a space conservatively. After this has been done the larger free 2266 // Sweeps a space conservatively. After this has been done the larger free
2214 // spaces have been put on the free list and the smaller ones have been 2267 // spaces have been put on the free list and the smaller ones have been
2215 // ignored and left untouched. A free space is always either ignored or put 2268 // ignored and left untouched. A free space is always either ignored or put
2216 // on the free list, never split up into two parts. This is important 2269 // on the free list, never split up into two parts. This is important
2217 // because it means that any FreeSpace maps left actually describe a region of 2270 // because it means that any FreeSpace maps left actually describe a region of
2218 // memory that can be ignored when scanning. Dead objects other than free 2271 // memory that can be ignored when scanning. Dead objects other than free
2219 // spaces will not contain the free space map. 2272 // spaces will not contain the free space map.
2220 static void SweepConservatively(PagedSpace* space, 2273 static void SweepConservatively(PagedSpace* space,
2221 Page* p) { 2274 Page* p) {
2222 Page::MarkbitsBitmap* markbits = p->markbits(); 2275 MarkBit::CellType* cells = p->markbits()->cells();
2223 Page::MarkbitsBitmap::CellType* cells = markbits->cells();
2224 2276
2225 p->SetFlag(MemoryChunk::WAS_SWEPT_CONSERVATIVELY); 2277 p->SetFlag(MemoryChunk::WAS_SWEPT_CONSERVATIVELY);
2226 2278
2227 // This is the start of the 32 word block that we are currently looking at. 2279 // This is the start of the 32 word block that we are currently looking at.
2228 Address block_address = p->ObjectAreaStart(); 2280 Address block_address = p->ObjectAreaStart();
2229 2281
2230 int last_cell_index = 2282 int last_cell_index =
2231 Page::MarkbitsBitmap::IndexToCell( 2283 Page::MarkbitsBitmap::IndexToCell(
2232 Page::MarkbitsBitmap::CellAlignIndex( 2284 Page::MarkbitsBitmap::CellAlignIndex(
2233 p->AddressToMarkbitIndex(p->ObjectAreaEnd()))); 2285 p->AddressToMarkbitIndex(p->ObjectAreaEnd())));
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
2295 } 2347 }
2296 } 2348 }
2297 2349
2298 2350
2299 // Sweep a space precisely. After this has been done the space can 2351 // Sweep a space precisely. After this has been done the space can
2300 // be iterated precisely, hitting only the live objects. Code space 2352 // be iterated precisely, hitting only the live objects. Code space
2301 // is always swept precisely because we want to be able to iterate 2353 // is always swept precisely because we want to be able to iterate
2302 // over it. Map space is swept precisely, because it is not compacted. 2354 // over it. Map space is swept precisely, because it is not compacted.
2303 static void SweepPrecisely(PagedSpace* space, 2355 static void SweepPrecisely(PagedSpace* space,
2304 Page* p) { 2356 Page* p) {
2305 Page::MarkbitsBitmap* markbits = p->markbits(); 2357 MarkBit::CellType* cells = p->markbits()->cells();
2306 Page::MarkbitsBitmap::CellType* cells = markbits->cells();
2307 2358
2308 p->ClearFlag(MemoryChunk::WAS_SWEPT_CONSERVATIVELY); 2359 p->ClearFlag(MemoryChunk::WAS_SWEPT_CONSERVATIVELY);
2309 2360
2310 int last_cell_index = 2361 int last_cell_index =
2311 Page::MarkbitsBitmap::IndexToCell( 2362 Page::MarkbitsBitmap::IndexToCell(
2312 Page::MarkbitsBitmap::CellAlignIndex( 2363 Page::MarkbitsBitmap::CellAlignIndex(
2313 p->AddressToMarkbitIndex(p->ObjectAreaEnd()))); 2364 p->AddressToMarkbitIndex(p->ObjectAreaEnd())));
2314 2365
2315 int cell_index = Page::kFirstUsedCell; 2366 int cell_index = Page::kFirstUsedCell;
2316 Address free_start = p->ObjectAreaStart(); 2367 Address free_start = p->ObjectAreaStart();
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
2476 } 2527 }
2477 2528
2478 2529
2479 void MarkCompactCollector::Initialize() { 2530 void MarkCompactCollector::Initialize() {
2480 StaticPointersToNewGenUpdatingVisitor::Initialize(); 2531 StaticPointersToNewGenUpdatingVisitor::Initialize();
2481 StaticMarkingVisitor::Initialize(); 2532 StaticMarkingVisitor::Initialize();
2482 } 2533 }
2483 2534
2484 2535
2485 } } // namespace v8::internal 2536 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698