| OLD | NEW |
| 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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 live_code_objects_size_(0), | 61 live_code_objects_size_(0), |
| 62 live_map_objects_size_(0), | 62 live_map_objects_size_(0), |
| 63 live_cell_objects_size_(0), | 63 live_cell_objects_size_(0), |
| 64 live_lo_objects_size_(0), | 64 live_lo_objects_size_(0), |
| 65 live_bytes_(0), | 65 live_bytes_(0), |
| 66 #endif | 66 #endif |
| 67 heap_(NULL), | 67 heap_(NULL), |
| 68 code_flusher_(NULL) { } | 68 code_flusher_(NULL) { } |
| 69 | 69 |
| 70 | 70 |
| 71 bool Marking::Setup() { | |
| 72 if (new_space_bitmap_ == NULL) { | |
| 73 // TODO(gc) ISOLATES | |
| 74 int markbits_per_newspace = | |
| 75 (2*HEAP->ReservedSemiSpaceSize()) >> kPointerSizeLog2; | |
| 76 | |
| 77 new_space_bitmap_ = | |
| 78 BitmapStorageDescriptor::Allocate( | |
| 79 NewSpaceMarkbitsBitmap::CellsForLength(markbits_per_newspace)); | |
| 80 } | |
| 81 return new_space_bitmap_ != NULL; | |
| 82 } | |
| 83 | |
| 84 | |
| 85 void Marking::TearDown() { | |
| 86 if (new_space_bitmap_ != NULL) { | |
| 87 BitmapStorageDescriptor::Free(new_space_bitmap_); | |
| 88 new_space_bitmap_ = NULL; | |
| 89 } | |
| 90 } | |
| 91 | |
| 92 | |
| 93 #ifdef DEBUG | 71 #ifdef DEBUG |
| 94 class VerifyMarkingVisitor: public ObjectVisitor { | 72 class VerifyMarkingVisitor: public ObjectVisitor { |
| 95 public: | 73 public: |
| 96 void VisitPointers(Object** start, Object** end) { | 74 void VisitPointers(Object** start, Object** end) { |
| 97 for (Object** current = start; current < end; current++) { | 75 for (Object** current = start; current < end; current++) { |
| 98 if ((*current)->IsHeapObject()) { | 76 if ((*current)->IsHeapObject()) { |
| 99 HeapObject* object = HeapObject::cast(*current); | 77 HeapObject* object = HeapObject::cast(*current); |
| 100 ASSERT(HEAP->mark_compact_collector()->IsMarked(object)); | 78 ASSERT(HEAP->mark_compact_collector()->IsMarked(object)); |
| 101 } | 79 } |
| 102 } | 80 } |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 ASSERT(p->markbits()->IsClean()); | 183 ASSERT(p->markbits()->IsClean()); |
| 206 } | 184 } |
| 207 } | 185 } |
| 208 | 186 |
| 209 static void VerifyMarkbitsAreClean() { | 187 static void VerifyMarkbitsAreClean() { |
| 210 VerifyMarkbitsAreClean(HEAP->old_pointer_space()); | 188 VerifyMarkbitsAreClean(HEAP->old_pointer_space()); |
| 211 VerifyMarkbitsAreClean(HEAP->old_data_space()); | 189 VerifyMarkbitsAreClean(HEAP->old_data_space()); |
| 212 VerifyMarkbitsAreClean(HEAP->code_space()); | 190 VerifyMarkbitsAreClean(HEAP->code_space()); |
| 213 VerifyMarkbitsAreClean(HEAP->cell_space()); | 191 VerifyMarkbitsAreClean(HEAP->cell_space()); |
| 214 VerifyMarkbitsAreClean(HEAP->map_space()); | 192 VerifyMarkbitsAreClean(HEAP->map_space()); |
| 193 ASSERT(HEAP->new_space()->ActivePage()->markbits()->IsClean()); |
| 215 } | 194 } |
| 216 #endif | 195 #endif |
| 217 | 196 |
| 218 | 197 |
| 219 static void ClearMarkbits(PagedSpace* space) { | 198 static void ClearMarkbits(PagedSpace* space) { |
| 220 PageIterator it(space); | 199 PageIterator it(space); |
| 221 | 200 |
| 222 while (it.has_next()) { | 201 while (it.has_next()) { |
| 223 Page* p = it.next(); | 202 Page* p = it.next(); |
| 224 p->markbits()->Clear(); | 203 p->markbits()->Clear(); |
| 225 } | 204 } |
| 226 } | 205 } |
| 227 | 206 |
| 228 | 207 |
| 229 static void ClearMarkbits() { | 208 static void ClearMarkbits() { |
| 230 // TODO(gc): Clean the mark bits while sweeping. | 209 // TODO(gc): Clean the mark bits while sweeping. |
| 231 ClearMarkbits(HEAP->code_space()); | 210 ClearMarkbits(HEAP->code_space()); |
| 232 ClearMarkbits(HEAP->map_space()); | 211 ClearMarkbits(HEAP->map_space()); |
| 233 ClearMarkbits(HEAP->old_pointer_space()); | 212 ClearMarkbits(HEAP->old_pointer_space()); |
| 234 ClearMarkbits(HEAP->old_data_space()); | 213 ClearMarkbits(HEAP->old_data_space()); |
| 235 ClearMarkbits(HEAP->cell_space()); | 214 ClearMarkbits(HEAP->cell_space()); |
| 215 HEAP->new_space()->ActivePage()->markbits()->Clear(); |
| 236 } | 216 } |
| 237 | 217 |
| 238 | 218 |
| 239 void Marking::TransferMark(Address old_start, Address new_start) { | 219 void Marking::TransferMark(Address old_start, Address new_start) { |
| 240 if (old_start == new_start) return; | 220 if (old_start == new_start) return; |
| 241 | 221 |
| 242 MarkBit new_mark_bit = MarkBitFrom(new_start); | 222 MarkBit new_mark_bit = MarkBitFrom(new_start); |
| 243 | 223 |
| 244 if (heap_->incremental_marking()->IsMarking()) { | 224 if (heap_->incremental_marking()->IsMarking()) { |
| 245 MarkBit old_mark_bit = MarkBitFrom(old_start); | 225 MarkBit old_mark_bit = MarkBitFrom(old_start); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 } | 285 } |
| 306 #endif | 286 #endif |
| 307 | 287 |
| 308 PagedSpaces spaces; | 288 PagedSpaces spaces; |
| 309 for (PagedSpace* space = spaces.next(); | 289 for (PagedSpace* space = spaces.next(); |
| 310 space != NULL; space = spaces.next()) { | 290 space != NULL; space = spaces.next()) { |
| 311 space->PrepareForMarkCompact(compacting_collection_); | 291 space->PrepareForMarkCompact(compacting_collection_); |
| 312 } | 292 } |
| 313 | 293 |
| 314 if (!heap()->incremental_marking()->IsMarking()) { | 294 if (!heap()->incremental_marking()->IsMarking()) { |
| 315 Address new_space_bottom = heap()->new_space()->bottom(); | |
| 316 uintptr_t new_space_size = | |
| 317 RoundUp(heap()->new_space()->top() - new_space_bottom, | |
| 318 32 * kPointerSize); | |
| 319 | |
| 320 heap()->marking()->ClearRange(new_space_bottom, new_space_size); | |
| 321 | |
| 322 ClearMarkbits(); | 295 ClearMarkbits(); |
| 323 #ifdef DEBUG | 296 #ifdef DEBUG |
| 324 VerifyMarkbitsAreClean(); | 297 VerifyMarkbitsAreClean(); |
| 325 #endif | 298 #endif |
| 326 } | 299 } |
| 327 | 300 |
| 328 #ifdef DEBUG | 301 #ifdef DEBUG |
| 329 live_bytes_ = 0; | 302 live_bytes_ = 0; |
| 330 live_young_objects_size_ = 0; | 303 live_young_objects_size_ = 0; |
| 331 live_old_pointer_objects_size_ = 0; | 304 live_old_pointer_objects_size_ = 0; |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 436 Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kLazyCompile); | 409 Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kLazyCompile); |
| 437 | 410 |
| 438 JSFunction* candidate = jsfunction_candidates_head_; | 411 JSFunction* candidate = jsfunction_candidates_head_; |
| 439 JSFunction* next_candidate; | 412 JSFunction* next_candidate; |
| 440 while (candidate != NULL) { | 413 while (candidate != NULL) { |
| 441 next_candidate = GetNextCandidate(candidate); | 414 next_candidate = GetNextCandidate(candidate); |
| 442 | 415 |
| 443 SharedFunctionInfo* shared = candidate->unchecked_shared(); | 416 SharedFunctionInfo* shared = candidate->unchecked_shared(); |
| 444 | 417 |
| 445 Code* code = shared->unchecked_code(); | 418 Code* code = shared->unchecked_code(); |
| 446 MarkBit code_mark = Marking::MarkBitFromOldSpace(code); | 419 MarkBit code_mark = Marking::MarkBitFrom(code); |
| 447 if (!code_mark.Get()) { | 420 if (!code_mark.Get()) { |
| 448 shared->set_code(lazy_compile); | 421 shared->set_code(lazy_compile); |
| 449 candidate->set_code(lazy_compile); | 422 candidate->set_code(lazy_compile); |
| 450 } else { | 423 } else { |
| 451 candidate->set_code(shared->unchecked_code()); | 424 candidate->set_code(shared->unchecked_code()); |
| 452 } | 425 } |
| 453 | 426 |
| 454 candidate = next_candidate; | 427 candidate = next_candidate; |
| 455 } | 428 } |
| 456 | 429 |
| 457 jsfunction_candidates_head_ = NULL; | 430 jsfunction_candidates_head_ = NULL; |
| 458 } | 431 } |
| 459 | 432 |
| 460 | 433 |
| 461 void ProcessSharedFunctionInfoCandidates() { | 434 void ProcessSharedFunctionInfoCandidates() { |
| 462 Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kLazyCompile); | 435 Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kLazyCompile); |
| 463 | 436 |
| 464 SharedFunctionInfo* candidate = shared_function_info_candidates_head_; | 437 SharedFunctionInfo* candidate = shared_function_info_candidates_head_; |
| 465 SharedFunctionInfo* next_candidate; | 438 SharedFunctionInfo* next_candidate; |
| 466 while (candidate != NULL) { | 439 while (candidate != NULL) { |
| 467 next_candidate = GetNextCandidate(candidate); | 440 next_candidate = GetNextCandidate(candidate); |
| 468 SetNextCandidate(candidate, NULL); | 441 SetNextCandidate(candidate, NULL); |
| 469 | 442 |
| 470 Code* code = candidate->unchecked_code(); | 443 Code* code = candidate->unchecked_code(); |
| 471 MarkBit code_mark = Marking::MarkBitFromOldSpace(code); | 444 MarkBit code_mark = Marking::MarkBitFrom(code); |
| 472 if (!code_mark.Get()) { | 445 if (!code_mark.Get()) { |
| 473 candidate->set_code(lazy_compile); | 446 candidate->set_code(lazy_compile); |
| 474 } | 447 } |
| 475 | 448 |
| 476 candidate = next_candidate; | 449 candidate = next_candidate; |
| 477 } | 450 } |
| 478 | 451 |
| 479 shared_function_info_candidates_head_ = NULL; | 452 shared_function_info_candidates_head_ = NULL; |
| 480 } | 453 } |
| 481 | 454 |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 646 } | 619 } |
| 647 | 620 |
| 648 static inline void VisitCodeTarget(Heap* heap, RelocInfo* rinfo) { | 621 static inline void VisitCodeTarget(Heap* heap, RelocInfo* rinfo) { |
| 649 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); | 622 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); |
| 650 Code* code = Code::GetCodeFromTargetAddress(rinfo->target_address()); | 623 Code* code = Code::GetCodeFromTargetAddress(rinfo->target_address()); |
| 651 if (FLAG_cleanup_ics_at_gc && code->is_inline_cache_stub()) { | 624 if (FLAG_cleanup_ics_at_gc && code->is_inline_cache_stub()) { |
| 652 IC::Clear(rinfo->pc()); | 625 IC::Clear(rinfo->pc()); |
| 653 // Please note targets for cleared inline cached do not have to be | 626 // Please note targets for cleared inline cached do not have to be |
| 654 // marked since they are contained in HEAP->non_monomorphic_cache(). | 627 // marked since they are contained in HEAP->non_monomorphic_cache(). |
| 655 } else { | 628 } else { |
| 656 MarkBit code_mark = Marking::MarkBitFromOldSpace(code); | 629 MarkBit code_mark = Marking::MarkBitFrom(code); |
| 657 heap->mark_compact_collector()->MarkObject(code, code_mark); | 630 heap->mark_compact_collector()->MarkObject(code, code_mark); |
| 658 } | 631 } |
| 659 } | 632 } |
| 660 | 633 |
| 661 static void VisitGlobalPropertyCell(Heap* heap, RelocInfo* rinfo) { | 634 static void VisitGlobalPropertyCell(Heap* heap, RelocInfo* rinfo) { |
| 662 ASSERT(rinfo->rmode() == RelocInfo::GLOBAL_PROPERTY_CELL); | 635 ASSERT(rinfo->rmode() == RelocInfo::GLOBAL_PROPERTY_CELL); |
| 663 Object* cell = rinfo->target_cell(); | 636 Object* cell = rinfo->target_cell(); |
| 664 Object* old_cell = cell; | 637 Object* old_cell = cell; |
| 665 VisitPointer(heap, &cell); | 638 VisitPointer(heap, &cell); |
| 666 if (cell != old_cell) { | 639 if (cell != old_cell) { |
| 667 rinfo->set_target_cell(reinterpret_cast<JSGlobalPropertyCell*>(cell), | 640 rinfo->set_target_cell(reinterpret_cast<JSGlobalPropertyCell*>(cell), |
| 668 NULL); | 641 NULL); |
| 669 } | 642 } |
| 670 } | 643 } |
| 671 | 644 |
| 672 static inline void VisitDebugTarget(Heap* heap, RelocInfo* rinfo) { | 645 static inline void VisitDebugTarget(Heap* heap, RelocInfo* rinfo) { |
| 673 ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) && | 646 ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) && |
| 674 rinfo->IsPatchedReturnSequence()) || | 647 rinfo->IsPatchedReturnSequence()) || |
| 675 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && | 648 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && |
| 676 rinfo->IsPatchedDebugBreakSlotSequence())); | 649 rinfo->IsPatchedDebugBreakSlotSequence())); |
| 677 HeapObject* code = Code::GetCodeFromTargetAddress(rinfo->call_address()); | 650 HeapObject* code = Code::GetCodeFromTargetAddress(rinfo->call_address()); |
| 678 MarkBit code_mark = Marking::MarkBitFromOldSpace(code); | 651 MarkBit code_mark = Marking::MarkBitFrom(code); |
| 679 heap->mark_compact_collector()->MarkObject(code, code_mark); | 652 heap->mark_compact_collector()->MarkObject(code, code_mark); |
| 680 } | 653 } |
| 681 | 654 |
| 682 // Mark object pointed to by p. | 655 // Mark object pointed to by p. |
| 683 INLINE(static void MarkObjectByPointer(Heap* heap, Object** p)) { | 656 INLINE(static void MarkObjectByPointer(Heap* heap, Object** p)) { |
| 684 if (!(*p)->IsHeapObject()) return; | 657 if (!(*p)->IsHeapObject()) return; |
| 685 HeapObject* object = ShortCircuitConsString(p); | 658 HeapObject* object = ShortCircuitConsString(p); |
| 686 MarkBit mark = heap->marking()->MarkBitFrom(object); | 659 MarkBit mark = heap->marking()->MarkBitFrom(object); |
| 687 heap->mark_compact_collector()->MarkObject(object, mark); | 660 heap->mark_compact_collector()->MarkObject(object, mark); |
| 688 } | 661 } |
| 689 | 662 |
| 690 | 663 |
| 691 // Visit an unmarked object. | 664 // Visit an unmarked object. |
| 692 INLINE(static void VisitUnmarkedObject(MarkCompactCollector* collector, | 665 INLINE(static void VisitUnmarkedObject(MarkCompactCollector* collector, |
| 693 HeapObject* obj)) { | 666 HeapObject* obj)) { |
| 694 #ifdef DEBUG | 667 #ifdef DEBUG |
| 695 ASSERT(Isolate::Current()->heap()->Contains(obj)); | 668 ASSERT(Isolate::Current()->heap()->Contains(obj)); |
| 696 ASSERT(!HEAP->mark_compact_collector()->IsMarked(obj)); | 669 ASSERT(!HEAP->mark_compact_collector()->IsMarked(obj)); |
| 697 #endif | 670 #endif |
| 698 Map* map = obj->map(); | 671 Map* map = obj->map(); |
| 699 Heap* heap = obj->GetHeap(); | 672 Heap* heap = obj->GetHeap(); |
| 700 // TODO(gc) ISOLATES MERGE | 673 // TODO(gc) ISOLATES MERGE |
| 701 MarkBit mark = heap->marking()->MarkBitFrom(obj); | 674 MarkBit mark = heap->marking()->MarkBitFrom(obj); |
| 702 heap->mark_compact_collector()->SetMark(obj, mark); | 675 heap->mark_compact_collector()->SetMark(obj, mark); |
| 703 // Mark the map pointer and the body. | 676 // Mark the map pointer and the body. |
| 704 MarkBit map_mark = Marking::MarkBitFromOldSpace(map); | 677 MarkBit map_mark = Marking::MarkBitFrom(map); |
| 705 heap->mark_compact_collector()->MarkObject(map, map_mark); | 678 heap->mark_compact_collector()->MarkObject(map, map_mark); |
| 706 IterateBody(map, obj); | 679 IterateBody(map, obj); |
| 707 } | 680 } |
| 708 | 681 |
| 709 // Visit all unmarked objects pointed to by [start, end). | 682 // Visit all unmarked objects pointed to by [start, end). |
| 710 // Returns false if the operation fails (lack of stack space). | 683 // Returns false if the operation fails (lack of stack space). |
| 711 static inline bool VisitUnmarkedObjects(Heap* heap, | 684 static inline bool VisitUnmarkedObjects(Heap* heap, |
| 712 Object** start, | 685 Object** start, |
| 713 Object** end) { | 686 Object** end) { |
| 714 // Return false is we are close to the stack limit. | 687 // Return false is we are close to the stack limit. |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 777 return function->unchecked_code() != | 750 return function->unchecked_code() != |
| 778 function->GetIsolate()->builtins()->builtin(Builtins::kLazyCompile); | 751 function->GetIsolate()->builtins()->builtin(Builtins::kLazyCompile); |
| 779 } | 752 } |
| 780 | 753 |
| 781 inline static bool IsFlushable(Heap* heap, JSFunction* function) { | 754 inline static bool IsFlushable(Heap* heap, JSFunction* function) { |
| 782 SharedFunctionInfo* shared_info = function->unchecked_shared(); | 755 SharedFunctionInfo* shared_info = function->unchecked_shared(); |
| 783 | 756 |
| 784 // Code is either on stack, in compilation cache or referenced | 757 // Code is either on stack, in compilation cache or referenced |
| 785 // by optimized version of function. | 758 // by optimized version of function. |
| 786 MarkBit code_mark = | 759 MarkBit code_mark = |
| 787 Marking::MarkBitFromOldSpace(function->unchecked_code()); | 760 Marking::MarkBitFrom(function->unchecked_code()); |
| 788 if (code_mark.Get()) { | 761 if (code_mark.Get()) { |
| 789 shared_info->set_code_age(0); | 762 shared_info->set_code_age(0); |
| 790 return false; | 763 return false; |
| 791 } | 764 } |
| 792 | 765 |
| 793 // We do not flush code for optimized functions. | 766 // We do not flush code for optimized functions. |
| 794 if (function->code() != shared_info->unchecked_code()) { | 767 if (function->code() != shared_info->unchecked_code()) { |
| 795 return false; | 768 return false; |
| 796 } | 769 } |
| 797 | 770 |
| 798 return IsFlushable(heap, shared_info); | 771 return IsFlushable(heap, shared_info); |
| 799 } | 772 } |
| 800 | 773 |
| 801 inline static bool IsFlushable(Heap* heap, SharedFunctionInfo* shared_info) { | 774 inline static bool IsFlushable(Heap* heap, SharedFunctionInfo* shared_info) { |
| 802 // Code is either on stack, in compilation cache or referenced | 775 // Code is either on stack, in compilation cache or referenced |
| 803 // by optimized version of function. | 776 // by optimized version of function. |
| 804 MarkBit code_mark = | 777 MarkBit code_mark = |
| 805 Marking::MarkBitFromOldSpace(shared_info->unchecked_code()); | 778 Marking::MarkBitFrom(shared_info->unchecked_code()); |
| 806 if (code_mark.Get()) { | 779 if (code_mark.Get()) { |
| 807 shared_info->set_code_age(0); | 780 shared_info->set_code_age(0); |
| 808 return false; | 781 return false; |
| 809 } | 782 } |
| 810 | 783 |
| 811 // The function must be compiled and have the source code available, | 784 // The function must be compiled and have the source code available, |
| 812 // to be able to recompile it in case we need the function again. | 785 // to be able to recompile it in case we need the function again. |
| 813 if (!(shared_info->is_compiled() && HasSourceCode(heap, shared_info))) { | 786 if (!(shared_info->is_compiled() && HasSourceCode(heap, shared_info))) { |
| 814 return false; | 787 return false; |
| 815 } | 788 } |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 947 | 920 |
| 948 JSFunction* jsfunction = reinterpret_cast<JSFunction*>(object); | 921 JSFunction* jsfunction = reinterpret_cast<JSFunction*>(object); |
| 949 // The function must have a valid context and not be a builtin. | 922 // The function must have a valid context and not be a builtin. |
| 950 bool flush_code_candidate = false; | 923 bool flush_code_candidate = false; |
| 951 if (IsValidNotBuiltinContext(jsfunction->unchecked_context())) { | 924 if (IsValidNotBuiltinContext(jsfunction->unchecked_context())) { |
| 952 flush_code_candidate = FlushCodeForFunction(heap, jsfunction); | 925 flush_code_candidate = FlushCodeForFunction(heap, jsfunction); |
| 953 } | 926 } |
| 954 | 927 |
| 955 if (!flush_code_candidate) { | 928 if (!flush_code_candidate) { |
| 956 Code* code = jsfunction->unchecked_shared()->unchecked_code(); | 929 Code* code = jsfunction->unchecked_shared()->unchecked_code(); |
| 957 MarkBit code_mark = Marking::MarkBitFromOldSpace(code); | 930 MarkBit code_mark = Marking::MarkBitFrom(code); |
| 958 HEAP->mark_compact_collector()->MarkObject(code, code_mark); | 931 HEAP->mark_compact_collector()->MarkObject(code, code_mark); |
| 959 | 932 |
| 960 if (jsfunction->unchecked_code()->kind() == Code::OPTIMIZED_FUNCTION) { | 933 if (jsfunction->unchecked_code()->kind() == Code::OPTIMIZED_FUNCTION) { |
| 961 // For optimized functions we should retain both non-optimized version | 934 // For optimized functions we should retain both non-optimized version |
| 962 // of it's code and non-optimized version of all inlined functions. | 935 // of it's code and non-optimized version of all inlined functions. |
| 963 // This is required to support bailing out from inlined code. | 936 // This is required to support bailing out from inlined code. |
| 964 DeoptimizationInputData* data = | 937 DeoptimizationInputData* data = |
| 965 reinterpret_cast<DeoptimizationInputData*>( | 938 reinterpret_cast<DeoptimizationInputData*>( |
| 966 jsfunction->unchecked_code()->unchecked_deoptimization_data()); | 939 jsfunction->unchecked_code()->unchecked_deoptimization_data()); |
| 967 | 940 |
| 968 FixedArray* literals = data->UncheckedLiteralArray(); | 941 FixedArray* literals = data->UncheckedLiteralArray(); |
| 969 | 942 |
| 970 for (int i = 0, count = data->InlinedFunctionCount()->value(); | 943 for (int i = 0, count = data->InlinedFunctionCount()->value(); |
| 971 i < count; | 944 i < count; |
| 972 i++) { | 945 i++) { |
| 973 JSFunction* inlined = reinterpret_cast<JSFunction*>(literals->get(i)); | 946 JSFunction* inlined = reinterpret_cast<JSFunction*>(literals->get(i)); |
| 974 Code* inlined_code = inlined->unchecked_shared()->unchecked_code(); | 947 Code* inlined_code = inlined->unchecked_shared()->unchecked_code(); |
| 975 MarkBit inlined_code_mark = | 948 MarkBit inlined_code_mark = |
| 976 Marking::MarkBitFromOldSpace(inlined_code); | 949 Marking::MarkBitFrom(inlined_code); |
| 977 HEAP->mark_compact_collector()->MarkObject( | 950 HEAP->mark_compact_collector()->MarkObject( |
| 978 inlined_code, inlined_code_mark); | 951 inlined_code, inlined_code_mark); |
| 979 } | 952 } |
| 980 } | 953 } |
| 981 } | 954 } |
| 982 | 955 |
| 983 VisitJSFunctionFields(map, | 956 VisitJSFunctionFields(map, |
| 984 reinterpret_cast<JSFunction*>(object), | 957 reinterpret_cast<JSFunction*>(object), |
| 985 flush_code_candidate); | 958 flush_code_candidate); |
| 986 } | 959 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1011 } else { | 984 } else { |
| 1012 // Don't visit code object. | 985 // Don't visit code object. |
| 1013 | 986 |
| 1014 // Visit shared function info to avoid double checking of it's | 987 // Visit shared function info to avoid double checking of it's |
| 1015 // flushability. | 988 // flushability. |
| 1016 SharedFunctionInfo* shared_info = object->unchecked_shared(); | 989 SharedFunctionInfo* shared_info = object->unchecked_shared(); |
| 1017 MarkBit shared_info_mark = heap->marking()->MarkBitFrom(shared_info); | 990 MarkBit shared_info_mark = heap->marking()->MarkBitFrom(shared_info); |
| 1018 if (!shared_info_mark.Get()) { | 991 if (!shared_info_mark.Get()) { |
| 1019 Map* shared_info_map = shared_info->map(); | 992 Map* shared_info_map = shared_info->map(); |
| 1020 MarkBit shared_info_map_mark = | 993 MarkBit shared_info_map_mark = |
| 1021 Marking::MarkBitFromOldSpace(shared_info_map); | 994 Marking::MarkBitFrom(shared_info_map); |
| 1022 HEAP->mark_compact_collector()->SetMark(shared_info, shared_info_mark); | 995 HEAP->mark_compact_collector()->SetMark(shared_info, shared_info_mark); |
| 1023 HEAP->mark_compact_collector()->MarkObject(shared_info_map, | 996 HEAP->mark_compact_collector()->MarkObject(shared_info_map, |
| 1024 shared_info_map_mark); | 997 shared_info_map_mark); |
| 1025 VisitSharedFunctionInfoAndFlushCodeGeneric(shared_info_map, | 998 VisitSharedFunctionInfoAndFlushCodeGeneric(shared_info_map, |
| 1026 shared_info, | 999 shared_info, |
| 1027 true); | 1000 true); |
| 1028 } | 1001 } |
| 1029 } | 1002 } |
| 1030 | 1003 |
| 1031 VisitPointers(heap, | 1004 VisitPointers(heap, |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1093 | 1066 |
| 1094 | 1067 |
| 1095 class CodeMarkingVisitor : public ThreadVisitor { | 1068 class CodeMarkingVisitor : public ThreadVisitor { |
| 1096 public: | 1069 public: |
| 1097 explicit CodeMarkingVisitor(MarkCompactCollector* collector) | 1070 explicit CodeMarkingVisitor(MarkCompactCollector* collector) |
| 1098 : collector_(collector) {} | 1071 : collector_(collector) {} |
| 1099 | 1072 |
| 1100 void VisitThread(Isolate* isolate, ThreadLocalTop* top) { | 1073 void VisitThread(Isolate* isolate, ThreadLocalTop* top) { |
| 1101 for (StackFrameIterator it(isolate, top); !it.done(); it.Advance()) { | 1074 for (StackFrameIterator it(isolate, top); !it.done(); it.Advance()) { |
| 1102 Code* code = it.frame()->unchecked_code(); | 1075 Code* code = it.frame()->unchecked_code(); |
| 1103 MarkBit code_bit = Marking::MarkBitFromOldSpace(code); | 1076 MarkBit code_bit = Marking::MarkBitFrom(code); |
| 1104 HEAP->mark_compact_collector()->MarkObject( | 1077 HEAP->mark_compact_collector()->MarkObject( |
| 1105 it.frame()->unchecked_code(), code_bit); | 1078 it.frame()->unchecked_code(), code_bit); |
| 1106 } | 1079 } |
| 1107 } | 1080 } |
| 1108 | 1081 |
| 1109 private: | 1082 private: |
| 1110 MarkCompactCollector* collector_; | 1083 MarkCompactCollector* collector_; |
| 1111 }; | 1084 }; |
| 1112 | 1085 |
| 1113 | 1086 |
| 1114 class SharedFunctionInfoMarkingVisitor : public ObjectVisitor { | 1087 class SharedFunctionInfoMarkingVisitor : public ObjectVisitor { |
| 1115 public: | 1088 public: |
| 1116 explicit SharedFunctionInfoMarkingVisitor(MarkCompactCollector* collector) | 1089 explicit SharedFunctionInfoMarkingVisitor(MarkCompactCollector* collector) |
| 1117 : collector_(collector) {} | 1090 : collector_(collector) {} |
| 1118 | 1091 |
| 1119 void VisitPointers(Object** start, Object** end) { | 1092 void VisitPointers(Object** start, Object** end) { |
| 1120 for (Object** p = start; p < end; p++) VisitPointer(p); | 1093 for (Object** p = start; p < end; p++) VisitPointer(p); |
| 1121 } | 1094 } |
| 1122 | 1095 |
| 1123 void VisitPointer(Object** slot) { | 1096 void VisitPointer(Object** slot) { |
| 1124 Object* obj = *slot; | 1097 Object* obj = *slot; |
| 1125 if (obj->IsSharedFunctionInfo()) { | 1098 if (obj->IsSharedFunctionInfo()) { |
| 1126 SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(obj); | 1099 SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(obj); |
| 1127 // TODO(gc) ISOLATES MERGE | 1100 // TODO(gc) ISOLATES MERGE |
| 1128 MarkBit shared_mark = HEAP->marking()->MarkBitFrom(shared); | 1101 MarkBit shared_mark = HEAP->marking()->MarkBitFrom(shared); |
| 1129 MarkBit code_mark = | 1102 MarkBit code_mark = |
| 1130 HEAP->marking()->MarkBitFromOldSpace(shared->unchecked_code()); | 1103 HEAP->marking()->MarkBitFrom(shared->unchecked_code()); |
| 1131 HEAP->mark_compact_collector()->MarkObject(shared->unchecked_code(), | 1104 HEAP->mark_compact_collector()->MarkObject(shared->unchecked_code(), |
| 1132 code_mark); | 1105 code_mark); |
| 1133 HEAP->mark_compact_collector()->MarkObject(shared, shared_mark); | 1106 HEAP->mark_compact_collector()->MarkObject(shared, shared_mark); |
| 1134 } | 1107 } |
| 1135 } | 1108 } |
| 1136 | 1109 |
| 1137 private: | 1110 private: |
| 1138 MarkCompactCollector* collector_; | 1111 MarkCompactCollector* collector_; |
| 1139 }; | 1112 }; |
| 1140 | 1113 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1161 HeapObject* descriptor_array = heap()->raw_unchecked_empty_descriptor_array(); | 1134 HeapObject* descriptor_array = heap()->raw_unchecked_empty_descriptor_array(); |
| 1162 // TODO(gc) ISOLATES MERGE | 1135 // TODO(gc) ISOLATES MERGE |
| 1163 MarkBit descriptor_array_mark = | 1136 MarkBit descriptor_array_mark = |
| 1164 heap()->marking()->MarkBitFrom(descriptor_array); | 1137 heap()->marking()->MarkBitFrom(descriptor_array); |
| 1165 MarkObject(descriptor_array, descriptor_array_mark); | 1138 MarkObject(descriptor_array, descriptor_array_mark); |
| 1166 | 1139 |
| 1167 // Make sure we are not referencing the code from the stack. | 1140 // Make sure we are not referencing the code from the stack. |
| 1168 ASSERT(this == heap()->mark_compact_collector()); | 1141 ASSERT(this == heap()->mark_compact_collector()); |
| 1169 for (StackFrameIterator it; !it.done(); it.Advance()) { | 1142 for (StackFrameIterator it; !it.done(); it.Advance()) { |
| 1170 Code* code = it.frame()->unchecked_code(); | 1143 Code* code = it.frame()->unchecked_code(); |
| 1171 MarkBit code_mark = Marking::MarkBitFromOldSpace(code); | 1144 MarkBit code_mark = Marking::MarkBitFrom(code); |
| 1172 MarkObject(code, code_mark); | 1145 MarkObject(code, code_mark); |
| 1173 } | 1146 } |
| 1174 | 1147 |
| 1175 // Iterate the archived stacks in all threads to check if | 1148 // Iterate the archived stacks in all threads to check if |
| 1176 // the code is referenced. | 1149 // the code is referenced. |
| 1177 CodeMarkingVisitor code_marking_visitor(this); | 1150 CodeMarkingVisitor code_marking_visitor(this); |
| 1178 heap()->isolate()->thread_manager()->IterateArchivedThreads( | 1151 heap()->isolate()->thread_manager()->IterateArchivedThreads( |
| 1179 &code_marking_visitor); | 1152 &code_marking_visitor); |
| 1180 | 1153 |
| 1181 SharedFunctionInfoMarkingVisitor visitor(this); | 1154 SharedFunctionInfoMarkingVisitor visitor(this); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1208 HeapObject* object = ShortCircuitConsString(p); | 1181 HeapObject* object = ShortCircuitConsString(p); |
| 1209 // TODO(gc) ISOLATES MERGE | 1182 // TODO(gc) ISOLATES MERGE |
| 1210 MarkBit mark_bit = HEAP->marking()->MarkBitFrom(object); | 1183 MarkBit mark_bit = HEAP->marking()->MarkBitFrom(object); |
| 1211 if (mark_bit.Get()) return; | 1184 if (mark_bit.Get()) return; |
| 1212 | 1185 |
| 1213 Map* map = object->map(); | 1186 Map* map = object->map(); |
| 1214 // Mark the object. | 1187 // Mark the object. |
| 1215 HEAP->mark_compact_collector()->SetMark(object, mark_bit); | 1188 HEAP->mark_compact_collector()->SetMark(object, mark_bit); |
| 1216 | 1189 |
| 1217 // Mark the map pointer and body, and push them on the marking stack. | 1190 // Mark the map pointer and body, and push them on the marking stack. |
| 1218 MarkBit map_mark = Marking::MarkBitFromOldSpace(map); | 1191 MarkBit map_mark = Marking::MarkBitFrom(map); |
| 1219 HEAP->mark_compact_collector()->MarkObject(map, map_mark); | 1192 HEAP->mark_compact_collector()->MarkObject(map, map_mark); |
| 1220 StaticMarkingVisitor::IterateBody(map, object); | 1193 StaticMarkingVisitor::IterateBody(map, object); |
| 1221 | 1194 |
| 1222 // Mark all the objects reachable from the map and body. May leave | 1195 // Mark all the objects reachable from the map and body. May leave |
| 1223 // overflowed objects in the heap. | 1196 // overflowed objects in the heap. |
| 1224 collector_->EmptyMarkingDeque(); | 1197 collector_->EmptyMarkingDeque(); |
| 1225 } | 1198 } |
| 1226 | 1199 |
| 1227 MarkCompactCollector* collector_; | 1200 MarkCompactCollector* collector_; |
| 1228 }; | 1201 }; |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1544 // marking stack have been marked, or are overflowed in the heap. | 1517 // marking stack have been marked, or are overflowed in the heap. |
| 1545 void MarkCompactCollector::EmptyMarkingDeque() { | 1518 void MarkCompactCollector::EmptyMarkingDeque() { |
| 1546 while (!marking_deque_.IsEmpty()) { | 1519 while (!marking_deque_.IsEmpty()) { |
| 1547 HeapObject* object = marking_deque_.Pop(); | 1520 HeapObject* object = marking_deque_.Pop(); |
| 1548 ASSERT(object->IsHeapObject()); | 1521 ASSERT(object->IsHeapObject()); |
| 1549 ASSERT(heap()->Contains(object)); | 1522 ASSERT(heap()->Contains(object)); |
| 1550 ASSERT(IsMarked(object)); | 1523 ASSERT(IsMarked(object)); |
| 1551 ASSERT(!object->IsOverflowed()); | 1524 ASSERT(!object->IsOverflowed()); |
| 1552 | 1525 |
| 1553 Map* map = object->map(); | 1526 Map* map = object->map(); |
| 1554 MarkBit map_mark = Marking::MarkBitFromOldSpace(map); | 1527 MarkBit map_mark = Marking::MarkBitFrom(map); |
| 1555 MarkObject(map, map_mark); | 1528 MarkObject(map, map_mark); |
| 1556 | 1529 |
| 1557 StaticMarkingVisitor::IterateBody(map, object); | 1530 StaticMarkingVisitor::IterateBody(map, object); |
| 1558 } | 1531 } |
| 1559 } | 1532 } |
| 1560 | 1533 |
| 1561 | 1534 |
| 1562 // Sweep the heap for overflowed objects, clear their overflow bits, and | 1535 // Sweep the heap for overflowed objects, clear their overflow bits, and |
| 1563 // push them on the marking stack. Stop early if the marking stack fills | 1536 // push them on the marking stack. Stop early if the marking stack fills |
| 1564 // before sweeping completes. If sweeping completes, there are no remaining | 1537 // before sweeping completes. If sweeping completes, there are no remaining |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1749 // dropping the back pointers temporarily stored in the prototype field. | 1722 // dropping the back pointers temporarily stored in the prototype field. |
| 1750 // Setting the prototype field requires following the linked list of | 1723 // Setting the prototype field requires following the linked list of |
| 1751 // back pointers, reversing them all at once. This allows us to find | 1724 // back pointers, reversing them all at once. This allows us to find |
| 1752 // those maps with map transitions that need to be nulled, and only | 1725 // those maps with map transitions that need to be nulled, and only |
| 1753 // scan the descriptor arrays of those maps, not all maps. | 1726 // scan the descriptor arrays of those maps, not all maps. |
| 1754 // All of these actions are carried out only on maps of JSObjects | 1727 // All of these actions are carried out only on maps of JSObjects |
| 1755 // and related subtypes. | 1728 // and related subtypes. |
| 1756 for (HeapObject* obj = map_iterator.Next(); | 1729 for (HeapObject* obj = map_iterator.Next(); |
| 1757 obj != NULL; obj = map_iterator.Next()) { | 1730 obj != NULL; obj = map_iterator.Next()) { |
| 1758 Map* map = reinterpret_cast<Map*>(obj); | 1731 Map* map = reinterpret_cast<Map*>(obj); |
| 1759 MarkBit map_mark = Marking::MarkBitFromOldSpace(map); | 1732 MarkBit map_mark = Marking::MarkBitFrom(map); |
| 1760 if (map->IsFreeSpace()) continue; | 1733 if (map->IsFreeSpace()) continue; |
| 1761 | 1734 |
| 1762 ASSERT(SafeIsMap(map)); | 1735 ASSERT(SafeIsMap(map)); |
| 1763 // Only JSObject and subtypes have map transitions and back pointers. | 1736 // Only JSObject and subtypes have map transitions and back pointers. |
| 1764 if (map->instance_type() < FIRST_JS_OBJECT_TYPE) continue; | 1737 if (map->instance_type() < FIRST_JS_OBJECT_TYPE) continue; |
| 1765 if (map->instance_type() > JS_FUNCTION_TYPE) continue; | 1738 if (map->instance_type() > JS_FUNCTION_TYPE) continue; |
| 1766 | 1739 |
| 1767 if (map_mark.Get() && | 1740 if (map_mark.Get() && |
| 1768 map->attached_to_shared_function_info()) { | 1741 map->attached_to_shared_function_info()) { |
| 1769 // This map is used for inobject slack tracking and has been detached | 1742 // This map is used for inobject slack tracking and has been detached |
| 1770 // from SharedFunctionInfo during the mark phase. | 1743 // from SharedFunctionInfo during the mark phase. |
| 1771 // Since it survived the GC, reattach it now. | 1744 // Since it survived the GC, reattach it now. |
| 1772 map->unchecked_constructor()->unchecked_shared()->AttachInitialMap(map); | 1745 map->unchecked_constructor()->unchecked_shared()->AttachInitialMap(map); |
| 1773 } | 1746 } |
| 1774 | 1747 |
| 1775 // Clear dead prototype transitions. | 1748 // Clear dead prototype transitions. |
| 1776 FixedArray* prototype_transitions = map->unchecked_prototype_transitions(); | 1749 FixedArray* prototype_transitions = map->unchecked_prototype_transitions(); |
| 1777 if (prototype_transitions->length() > 0) { | 1750 if (prototype_transitions->length() > 0) { |
| 1778 int finger = Smi::cast(prototype_transitions->get(0))->value(); | 1751 int finger = Smi::cast(prototype_transitions->get(0))->value(); |
| 1779 int new_finger = 1; | 1752 int new_finger = 1; |
| 1780 for (int i = 1; i < finger; i += 2) { | 1753 for (int i = 1; i < finger; i += 2) { |
| 1781 HeapObject* prototype = HeapObject::cast(prototype_transitions->get(i)); | 1754 HeapObject* prototype = HeapObject::cast(prototype_transitions->get(i)); |
| 1782 Map* cached_map = Map::cast(prototype_transitions->get(i + 1)); | 1755 Map* cached_map = Map::cast(prototype_transitions->get(i + 1)); |
| 1783 MarkBit prototype_mark = heap()->marking()->MarkBitFrom(prototype); | 1756 MarkBit prototype_mark = heap()->marking()->MarkBitFrom(prototype); |
| 1784 MarkBit cached_map_mark = Marking::MarkBitFromOldSpace(cached_map); | 1757 MarkBit cached_map_mark = Marking::MarkBitFrom(cached_map); |
| 1785 if (prototype_mark.Get() && cached_map_mark.Get()) { | 1758 if (prototype_mark.Get() && cached_map_mark.Get()) { |
| 1786 if (new_finger != i) { | 1759 if (new_finger != i) { |
| 1787 prototype_transitions->set_unchecked(heap_, | 1760 prototype_transitions->set_unchecked(heap_, |
| 1788 new_finger, | 1761 new_finger, |
| 1789 prototype, | 1762 prototype, |
| 1790 UPDATE_WRITE_BARRIER); | 1763 UPDATE_WRITE_BARRIER); |
| 1791 prototype_transitions->set_unchecked(heap_, | 1764 prototype_transitions->set_unchecked(heap_, |
| 1792 new_finger + 1, | 1765 new_finger + 1, |
| 1793 cached_map, | 1766 cached_map, |
| 1794 SKIP_WRITE_BARRIER); | 1767 SKIP_WRITE_BARRIER); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1817 Object* real_prototype = current; | 1790 Object* real_prototype = current; |
| 1818 | 1791 |
| 1819 // Follow back pointers, setting them to prototype, | 1792 // Follow back pointers, setting them to prototype, |
| 1820 // clearing map transitions when necessary. | 1793 // clearing map transitions when necessary. |
| 1821 current = map; | 1794 current = map; |
| 1822 bool on_dead_path = !map_mark.Get(); | 1795 bool on_dead_path = !map_mark.Get(); |
| 1823 Object* next; | 1796 Object* next; |
| 1824 while (SafeIsMap(current)) { | 1797 while (SafeIsMap(current)) { |
| 1825 next = current->prototype(); | 1798 next = current->prototype(); |
| 1826 // There should never be a dead map above a live map. | 1799 // There should never be a dead map above a live map. |
| 1827 MarkBit current_mark = Marking::MarkBitFromOldSpace(current); | 1800 MarkBit current_mark = Marking::MarkBitFrom(current); |
| 1828 ASSERT(on_dead_path || current_mark.Get()); | 1801 ASSERT(on_dead_path || current_mark.Get()); |
| 1829 | 1802 |
| 1830 // A live map above a dead map indicates a dead transition. | 1803 // A live map above a dead map indicates a dead transition. |
| 1831 // This test will always be false on the first iteration. | 1804 // This test will always be false on the first iteration. |
| 1832 if (on_dead_path && current_mark.Get()) { | 1805 if (on_dead_path && current_mark.Get()) { |
| 1833 on_dead_path = false; | 1806 on_dead_path = false; |
| 1834 current->ClearNonLiveTransitions(heap(), real_prototype); | 1807 current->ClearNonLiveTransitions(heap(), real_prototype); |
| 1835 } | 1808 } |
| 1836 *HeapObject::RawField(current, Map::kPrototypeOffset) = | 1809 *HeapObject::RawField(current, Map::kPrototypeOffset) = |
| 1837 real_prototype; | 1810 real_prototype; |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2010 int survivors_size = 0; | 1983 int survivors_size = 0; |
| 2011 | 1984 |
| 2012 // First pass: traverse all objects in inactive semispace, remove marks, | 1985 // First pass: traverse all objects in inactive semispace, remove marks, |
| 2013 // migrate live objects and write forwarding addresses. This stage puts | 1986 // migrate live objects and write forwarding addresses. This stage puts |
| 2014 // new entries in the store buffer and may cause some pages to be marked | 1987 // new entries in the store buffer and may cause some pages to be marked |
| 2015 // scan-on-scavenge. | 1988 // scan-on-scavenge. |
| 2016 for (Address current = from_bottom; current < from_top; current += size) { | 1989 for (Address current = from_bottom; current < from_top; current += size) { |
| 2017 HeapObject* object = HeapObject::FromAddress(current); | 1990 HeapObject* object = HeapObject::FromAddress(current); |
| 2018 | 1991 |
| 2019 | 1992 |
| 2020 MarkBit mark_bit = heap_->marking()->MarkBitFromNewSpace(object); | 1993 MarkBit mark_bit = heap_->marking()->MarkBitFrom(object); |
| 2021 if (mark_bit.Get()) { | 1994 if (mark_bit.Get()) { |
| 2022 mark_bit.Clear(); | 1995 mark_bit.Clear(); |
| 2023 heap_->mark_compact_collector()->tracer()->decrement_marked_count(); | 1996 heap_->mark_compact_collector()->tracer()->decrement_marked_count(); |
| 2024 | 1997 |
| 2025 size = object->Size(); | 1998 size = object->Size(); |
| 2026 survivors_size += size; | 1999 survivors_size += size; |
| 2027 | 2000 |
| 2028 // Aggressively promote young survivors to the old space. | 2001 // Aggressively promote young survivors to the old space. |
| 2029 if (TryPromoteObject(heap_, object, size)) { | 2002 if (TryPromoteObject(heap_, object, size)) { |
| 2030 continue; | 2003 continue; |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2106 uint32_t free_start, | 2079 uint32_t free_start, |
| 2107 uint32_t region_end, | 2080 uint32_t region_end, |
| 2108 uint32_t* cells)); | 2081 uint32_t* cells)); |
| 2109 | 2082 |
| 2110 | 2083 |
| 2111 static uint32_t SweepFree(PagedSpace* space, | 2084 static uint32_t SweepFree(PagedSpace* space, |
| 2112 Page* p, | 2085 Page* p, |
| 2113 uint32_t free_start, | 2086 uint32_t free_start, |
| 2114 uint32_t region_end, | 2087 uint32_t region_end, |
| 2115 uint32_t* cells) { | 2088 uint32_t* cells) { |
| 2116 uint32_t free_cell_index = Page::MarkbitsBitmap::IndexToCell(free_start); | 2089 uint32_t free_cell_index = Bitmap::IndexToCell(free_start); |
| 2117 ASSERT(cells[free_cell_index] == 0); | 2090 ASSERT(cells[free_cell_index] == 0); |
| 2118 while (free_cell_index < region_end && cells[free_cell_index] == 0) { | 2091 while (free_cell_index < region_end && cells[free_cell_index] == 0) { |
| 2119 free_cell_index++; | 2092 free_cell_index++; |
| 2120 } | 2093 } |
| 2121 | 2094 |
| 2122 if (free_cell_index >= region_end) { | 2095 if (free_cell_index >= region_end) { |
| 2123 return free_cell_index; | 2096 return free_cell_index; |
| 2124 } | 2097 } |
| 2125 | 2098 |
| 2126 uint32_t free_end = Page::MarkbitsBitmap::CellToIndex(free_cell_index); | 2099 uint32_t free_end = Bitmap::CellToIndex(free_cell_index); |
| 2127 space->Free(p->MarkbitIndexToAddress(free_start), | 2100 space->Free(p->MarkbitIndexToAddress(free_start), |
| 2128 (free_end - free_start) << kPointerSizeLog2); | 2101 (free_end - free_start) << kPointerSizeLog2); |
| 2129 | 2102 |
| 2130 return free_cell_index; | 2103 return free_cell_index; |
| 2131 } | 2104 } |
| 2132 | 2105 |
| 2133 | 2106 |
| 2134 INLINE(static uint32_t NextCandidate(uint32_t cell_index, | 2107 INLINE(static uint32_t NextCandidate(uint32_t cell_index, |
| 2135 uint32_t last_cell_index, | 2108 uint32_t last_cell_index, |
| 2136 uint32_t* cells)); | 2109 uint32_t* cells)); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2154 static int SizeOfPreviousObject(Page* p, | 2127 static int SizeOfPreviousObject(Page* p, |
| 2155 uint32_t cell_index, | 2128 uint32_t cell_index, |
| 2156 uint32_t* cells) { | 2129 uint32_t* cells) { |
| 2157 ASSERT(cells[cell_index] == 0); | 2130 ASSERT(cells[cell_index] == 0); |
| 2158 if (cells[cell_index - 1] == 0) return 0; | 2131 if (cells[cell_index - 1] == 0) return 0; |
| 2159 | 2132 |
| 2160 int leading_zeroes = | 2133 int leading_zeroes = |
| 2161 CompilerIntrinsics::CountLeadingZeros(cells[cell_index - 1]) + 1; | 2134 CompilerIntrinsics::CountLeadingZeros(cells[cell_index - 1]) + 1; |
| 2162 Address addr = | 2135 Address addr = |
| 2163 p->MarkbitIndexToAddress( | 2136 p->MarkbitIndexToAddress( |
| 2164 Page::MarkbitsBitmap::CellToIndex(cell_index) - leading_zeroes); | 2137 Bitmap::CellToIndex(cell_index) - leading_zeroes); |
| 2165 HeapObject* obj = HeapObject::FromAddress(addr); | 2138 HeapObject* obj = HeapObject::FromAddress(addr); |
| 2166 ASSERT(obj->map()->IsMap()); | 2139 ASSERT(obj->map()->IsMap()); |
| 2167 return (obj->Size() >> kPointerSizeLog2) - leading_zeroes; | 2140 return (obj->Size() >> kPointerSizeLog2) - leading_zeroes; |
| 2168 } | 2141 } |
| 2169 | 2142 |
| 2170 | 2143 |
| 2171 static const int kStartTableEntriesPerLine = 5; | 2144 static const int kStartTableEntriesPerLine = 5; |
| 2172 static const int kStartTableLines = 171; | 2145 static const int kStartTableLines = 171; |
| 2173 static const int kStartTableInvalidLine = 127; | 2146 static const int kStartTableInvalidLine = 127; |
| 2174 static const int kStartTableUnusedEntry = 126; | 2147 static const int kStartTableUnusedEntry = 126; |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2449 int freed_bytes = 0; | 2422 int freed_bytes = 0; |
| 2450 | 2423 |
| 2451 MarkBit::CellType* cells = p->markbits()->cells(); | 2424 MarkBit::CellType* cells = p->markbits()->cells(); |
| 2452 | 2425 |
| 2453 p->SetFlag(MemoryChunk::WAS_SWEPT_CONSERVATIVELY); | 2426 p->SetFlag(MemoryChunk::WAS_SWEPT_CONSERVATIVELY); |
| 2454 | 2427 |
| 2455 // This is the start of the 32 word block that we are currently looking at. | 2428 // This is the start of the 32 word block that we are currently looking at. |
| 2456 Address block_address = p->ObjectAreaStart(); | 2429 Address block_address = p->ObjectAreaStart(); |
| 2457 | 2430 |
| 2458 int last_cell_index = | 2431 int last_cell_index = |
| 2459 Page::MarkbitsBitmap::IndexToCell( | 2432 Bitmap::IndexToCell( |
| 2460 Page::MarkbitsBitmap::CellAlignIndex( | 2433 Bitmap::CellAlignIndex( |
| 2461 p->AddressToMarkbitIndex(p->ObjectAreaEnd()))); | 2434 p->AddressToMarkbitIndex(p->ObjectAreaEnd()))); |
| 2462 | 2435 |
| 2463 int cell_index = Page::kFirstUsedCell; | 2436 int cell_index = Page::kFirstUsedCell; |
| 2464 | 2437 |
| 2465 // Skip over all the dead objects at the start of the page and mark them free. | 2438 // Skip over all the dead objects at the start of the page and mark them free. |
| 2466 for (cell_index = Page::kFirstUsedCell; | 2439 for (cell_index = Page::kFirstUsedCell; |
| 2467 cell_index < last_cell_index; | 2440 cell_index < last_cell_index; |
| 2468 cell_index++, block_address += 32 * kPointerSize) { | 2441 cell_index++, block_address += 32 * kPointerSize) { |
| 2469 if (cells[cell_index] != 0) break; | 2442 if (cells[cell_index] != 0) break; |
| 2470 } | 2443 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2485 // started. Unless we find a large free space in the bitmap we will not | 2458 // started. Unless we find a large free space in the bitmap we will not |
| 2486 // digest this pair into a real address. We start the iteration here at the | 2459 // digest this pair into a real address. We start the iteration here at the |
| 2487 // first word in the marking bit map that indicates a live object. | 2460 // first word in the marking bit map that indicates a live object. |
| 2488 Address free_start = block_address; | 2461 Address free_start = block_address; |
| 2489 uint32_t free_start_cell = cells[cell_index]; | 2462 uint32_t free_start_cell = cells[cell_index]; |
| 2490 | 2463 |
| 2491 for ( ; | 2464 for ( ; |
| 2492 cell_index < last_cell_index; | 2465 cell_index < last_cell_index; |
| 2493 cell_index++, block_address += 32 * kPointerSize) { | 2466 cell_index++, block_address += 32 * kPointerSize) { |
| 2494 ASSERT((unsigned)cell_index == | 2467 ASSERT((unsigned)cell_index == |
| 2495 Page::MarkbitsBitmap::IndexToCell( | 2468 Bitmap::IndexToCell( |
| 2496 Page::MarkbitsBitmap::CellAlignIndex( | 2469 Bitmap::CellAlignIndex( |
| 2497 p->AddressToMarkbitIndex(block_address)))); | 2470 p->AddressToMarkbitIndex(block_address)))); |
| 2498 uint32_t cell = cells[cell_index]; | 2471 uint32_t cell = cells[cell_index]; |
| 2499 if (cell != 0) { | 2472 if (cell != 0) { |
| 2500 // We have a live object. Check approximately whether it is more than 32 | 2473 // We have a live object. Check approximately whether it is more than 32 |
| 2501 // words since the last live object. | 2474 // words since the last live object. |
| 2502 if (block_address - free_start > 32 * kPointerSize) { | 2475 if (block_address - free_start > 32 * kPointerSize) { |
| 2503 free_start = DigestFreeStart(free_start, free_start_cell); | 2476 free_start = DigestFreeStart(free_start, free_start_cell); |
| 2504 if (block_address - free_start > 32 * kPointerSize) { | 2477 if (block_address - free_start > 32 * kPointerSize) { |
| 2505 // Now that we know the exact start of the free space it still looks | 2478 // Now that we know the exact start of the free space it still looks |
| 2506 // like we have a large enough free space to be worth bothering with. | 2479 // like we have a large enough free space to be worth bothering with. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2530 // be iterated precisely, hitting only the live objects. Code space | 2503 // be iterated precisely, hitting only the live objects. Code space |
| 2531 // is always swept precisely because we want to be able to iterate | 2504 // is always swept precisely because we want to be able to iterate |
| 2532 // over it. Map space is swept precisely, because it is not compacted. | 2505 // over it. Map space is swept precisely, because it is not compacted. |
| 2533 static void SweepPrecisely(PagedSpace* space, | 2506 static void SweepPrecisely(PagedSpace* space, |
| 2534 Page* p) { | 2507 Page* p) { |
| 2535 MarkBit::CellType* cells = p->markbits()->cells(); | 2508 MarkBit::CellType* cells = p->markbits()->cells(); |
| 2536 | 2509 |
| 2537 p->ClearFlag(MemoryChunk::WAS_SWEPT_CONSERVATIVELY); | 2510 p->ClearFlag(MemoryChunk::WAS_SWEPT_CONSERVATIVELY); |
| 2538 | 2511 |
| 2539 int last_cell_index = | 2512 int last_cell_index = |
| 2540 Page::MarkbitsBitmap::IndexToCell( | 2513 Bitmap::IndexToCell( |
| 2541 Page::MarkbitsBitmap::CellAlignIndex( | 2514 Bitmap::CellAlignIndex( |
| 2542 p->AddressToMarkbitIndex(p->ObjectAreaEnd()))); | 2515 p->AddressToMarkbitIndex(p->ObjectAreaEnd()))); |
| 2543 | 2516 |
| 2544 int cell_index = Page::kFirstUsedCell; | 2517 int cell_index = Page::kFirstUsedCell; |
| 2545 Address free_start = p->ObjectAreaStart(); | 2518 Address free_start = p->ObjectAreaStart(); |
| 2546 ASSERT(reinterpret_cast<uint32_t>(free_start) % (32 * kPointerSize) == 0); | 2519 ASSERT(reinterpret_cast<uint32_t>(free_start) % (32 * kPointerSize) == 0); |
| 2547 Address object_address = p->ObjectAreaStart(); | 2520 Address object_address = p->ObjectAreaStart(); |
| 2548 int offsets[16]; | 2521 int offsets[16]; |
| 2549 | 2522 |
| 2550 for (cell_index = Page::kFirstUsedCell; | 2523 for (cell_index = Page::kFirstUsedCell; |
| 2551 cell_index < last_cell_index; | 2524 cell_index < last_cell_index; |
| 2552 cell_index++, object_address += 32 * kPointerSize) { | 2525 cell_index++, object_address += 32 * kPointerSize) { |
| 2553 ASSERT((unsigned)cell_index == | 2526 ASSERT((unsigned)cell_index == |
| 2554 Page::MarkbitsBitmap::IndexToCell( | 2527 Bitmap::IndexToCell( |
| 2555 Page::MarkbitsBitmap::CellAlignIndex( | 2528 Bitmap::CellAlignIndex( |
| 2556 p->AddressToMarkbitIndex(object_address)))); | 2529 p->AddressToMarkbitIndex(object_address)))); |
| 2557 int live_objects = MarkWordToObjectStarts(cells[cell_index], offsets); | 2530 int live_objects = MarkWordToObjectStarts(cells[cell_index], offsets); |
| 2558 int live_index = 0; | 2531 int live_index = 0; |
| 2559 for ( ; live_objects != 0; live_objects--) { | 2532 for ( ; live_objects != 0; live_objects--) { |
| 2560 Address free_end = object_address + offsets[live_index++] * kPointerSize; | 2533 Address free_end = object_address + offsets[live_index++] * kPointerSize; |
| 2561 if (free_end != free_start) { | 2534 if (free_end != free_start) { |
| 2562 space->Free(free_start, free_end - free_start); | 2535 space->Free(free_start, free_end - free_start); |
| 2563 } | 2536 } |
| 2564 HeapObject* live_object = HeapObject::FromAddress(free_end); | 2537 HeapObject* live_object = HeapObject::FromAddress(free_end); |
| 2565 free_start = free_end + live_object->Size(); | 2538 free_start = free_end + live_object->Size(); |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2726 } | 2699 } |
| 2727 | 2700 |
| 2728 | 2701 |
| 2729 void MarkCompactCollector::Initialize() { | 2702 void MarkCompactCollector::Initialize() { |
| 2730 StaticPointersToNewGenUpdatingVisitor::Initialize(); | 2703 StaticPointersToNewGenUpdatingVisitor::Initialize(); |
| 2731 StaticMarkingVisitor::Initialize(); | 2704 StaticMarkingVisitor::Initialize(); |
| 2732 } | 2705 } |
| 2733 | 2706 |
| 2734 | 2707 |
| 2735 } } // namespace v8::internal | 2708 } } // namespace v8::internal |
| OLD | NEW |