OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/heap/mark-compact.h" | 5 #include "src/heap/mark-compact.h" |
6 | 6 |
7 #include "src/base/atomicops.h" | 7 #include "src/base/atomicops.h" |
8 #include "src/base/bits.h" | 8 #include "src/base/bits.h" |
9 #include "src/base/sys-info.h" | 9 #include "src/base/sys-info.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 2793 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2804 Object** p) { | 2804 Object** p) { |
2805 MapWord map_word = HeapObject::cast(*p)->map_word(); | 2805 MapWord map_word = HeapObject::cast(*p)->map_word(); |
2806 | 2806 |
2807 if (map_word.IsForwardingAddress()) { | 2807 if (map_word.IsForwardingAddress()) { |
2808 return String::cast(map_word.ToForwardingAddress()); | 2808 return String::cast(map_word.ToForwardingAddress()); |
2809 } | 2809 } |
2810 | 2810 |
2811 return String::cast(*p); | 2811 return String::cast(*p); |
2812 } | 2812 } |
2813 | 2813 |
2814 | 2814 bool MarkCompactCollector::IsSlotInBlackObject(MemoryChunk* p, Address slot) { |
2815 bool MarkCompactCollector::IsSlotInBlackObject(Page* p, Address slot, | |
2816 HeapObject** out_object) { | |
2817 Space* owner = p->owner(); | 2815 Space* owner = p->owner(); |
2818 if (owner == heap_->lo_space() || owner == NULL) { | 2816 DCHECK(owner != heap_->lo_space() && owner != nullptr); |
2819 Object* large_object = heap_->lo_space()->FindObject(slot); | 2817 USE(owner); |
2820 // This object has to exist, otherwise we would not have recorded a slot | |
2821 // for it. | |
2822 CHECK(large_object->IsHeapObject()); | |
2823 HeapObject* large_heap_object = HeapObject::cast(large_object); | |
2824 if (IsMarked(large_heap_object)) { | |
2825 *out_object = large_heap_object; | |
2826 return true; | |
2827 } | |
2828 return false; | |
2829 } | |
2830 | 2818 |
2831 // If we are on a black page, we cannot find the actual object start | 2819 // If we are on a black page, we cannot find the actual object start |
2832 // easiliy. We just return true but do not set the out_object. | 2820 // easiliy. We just return true but do not set the out_object. |
2833 if (p->IsFlagSet(Page::BLACK_PAGE)) { | 2821 if (p->IsFlagSet(Page::BLACK_PAGE)) { |
2834 return true; | 2822 return true; |
2835 } | 2823 } |
2836 | 2824 |
2837 uint32_t mark_bit_index = p->AddressToMarkbitIndex(slot); | 2825 uint32_t mark_bit_index = p->AddressToMarkbitIndex(slot); |
2838 unsigned int cell_index = mark_bit_index >> Bitmap::kBitsPerCellLog2; | 2826 unsigned int cell_index = mark_bit_index >> Bitmap::kBitsPerCellLog2; |
2839 MarkBit::CellType index_mask = 1u << Bitmap::IndexInCell(mark_bit_index); | 2827 MarkBit::CellType index_mask = 1u << Bitmap::IndexInCell(mark_bit_index); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2899 Address address = base_address + offset * kPointerSize; | 2887 Address address = base_address + offset * kPointerSize; |
2900 HeapObject* object = HeapObject::FromAddress(address); | 2888 HeapObject* object = HeapObject::FromAddress(address); |
2901 CHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); | 2889 CHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); |
2902 CHECK(object->address() < reinterpret_cast<Address>(slot)); | 2890 CHECK(object->address() < reinterpret_cast<Address>(slot)); |
2903 if ((object->address() + kPointerSize) <= slot && | 2891 if ((object->address() + kPointerSize) <= slot && |
2904 (object->address() + object->Size()) > slot) { | 2892 (object->address() + object->Size()) > slot) { |
2905 // If the slot is within the last found object in the cell, the slot is | 2893 // If the slot is within the last found object in the cell, the slot is |
2906 // in a live object. | 2894 // in a live object. |
2907 // Slots pointing to the first word of an object are invalid and removed. | 2895 // Slots pointing to the first word of an object are invalid and removed. |
2908 // This can happen when we move the object header while left trimming. | 2896 // This can happen when we move the object header while left trimming. |
2909 *out_object = object; | |
2910 return true; | 2897 return true; |
2911 } | 2898 } |
2912 return false; | 2899 return false; |
2913 } | 2900 } |
2914 | 2901 |
2915 HeapObject* MarkCompactCollector::FindBlackObjectBySlotSlow(Address slot) { | 2902 HeapObject* MarkCompactCollector::FindBlackObjectBySlotSlow(Address slot) { |
2916 Page* p = Page::FromAddress(slot); | 2903 Page* p = Page::FromAddress(slot); |
2917 Space* owner = p->owner(); | 2904 Space* owner = p->owner(); |
2918 if (owner == heap_->lo_space() || owner == nullptr) { | 2905 if (owner == heap_->lo_space() || owner == nullptr) { |
2919 Object* large_object = heap_->lo_space()->FindObject(slot); | 2906 Object* large_object = heap_->lo_space()->FindObject(slot); |
(...skipping 26 matching lines...) Expand all Loading... |
2946 if (object->address() > slot) return nullptr; | 2933 if (object->address() > slot) return nullptr; |
2947 if (object->address() <= slot && slot < (object->address() + size)) { | 2934 if (object->address() <= slot && slot < (object->address() + size)) { |
2948 return object; | 2935 return object; |
2949 } | 2936 } |
2950 } | 2937 } |
2951 } | 2938 } |
2952 return nullptr; | 2939 return nullptr; |
2953 } | 2940 } |
2954 | 2941 |
2955 | 2942 |
2956 bool MarkCompactCollector::IsSlotInLiveObject(Address slot) { | |
2957 // The target object is black but we don't know if the source slot is black. | |
2958 // The source object could have died and the slot could be part of a free | |
2959 // space. Find out based on mark bits if the slot is part of a live object. | |
2960 Page* page = Page::FromAddress(slot); | |
2961 HeapObject* object = NULL; | |
2962 if (!IsSlotInBlackObject(page, slot, &object)) { | |
2963 return false; | |
2964 } | |
2965 | |
2966 // If the slot is on a black page, the object will be live. | |
2967 DCHECK(object != NULL || page->IsFlagSet(Page::BLACK_PAGE)); | |
2968 if (page->IsFlagSet(Page::BLACK_PAGE)) { | |
2969 return true; | |
2970 } | |
2971 | |
2972 int offset = static_cast<int>(slot - object->address()); | |
2973 return object->IsValidSlot(offset); | |
2974 } | |
2975 | |
2976 | |
2977 void MarkCompactCollector::EvacuateNewSpacePrologue() { | 2943 void MarkCompactCollector::EvacuateNewSpacePrologue() { |
2978 NewSpace* new_space = heap()->new_space(); | 2944 NewSpace* new_space = heap()->new_space(); |
2979 NewSpacePageIterator it(new_space->bottom(), new_space->top()); | 2945 NewSpacePageIterator it(new_space->bottom(), new_space->top()); |
2980 // Append the list of new space pages to be processed. | 2946 // Append the list of new space pages to be processed. |
2981 while (it.has_next()) { | 2947 while (it.has_next()) { |
2982 newspace_evacuation_candidates_.Add(it.next()); | 2948 newspace_evacuation_candidates_.Add(it.next()); |
2983 } | 2949 } |
2984 new_space->Flip(); | 2950 new_space->Flip(); |
2985 new_space->ResetAllocationInfo(); | 2951 new_space->ResetAllocationInfo(); |
2986 } | 2952 } |
(...skipping 876 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3863 MarkBit mark_bit = Marking::MarkBitFrom(host); | 3829 MarkBit mark_bit = Marking::MarkBitFrom(host); |
3864 if (Marking::IsBlack(mark_bit)) { | 3830 if (Marking::IsBlack(mark_bit)) { |
3865 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); | 3831 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); |
3866 RecordRelocSlot(host, &rinfo, target); | 3832 RecordRelocSlot(host, &rinfo, target); |
3867 } | 3833 } |
3868 } | 3834 } |
3869 } | 3835 } |
3870 | 3836 |
3871 } // namespace internal | 3837 } // namespace internal |
3872 } // namespace v8 | 3838 } // namespace v8 |
OLD | NEW |