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 2904 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2915 } | 2915 } |
2916 | 2916 |
2917 static inline void UpdateSlot(Heap* heap, Object** slot) { | 2917 static inline void UpdateSlot(Heap* heap, Object** slot) { |
2918 Object* obj = reinterpret_cast<Object*>( | 2918 Object* obj = reinterpret_cast<Object*>( |
2919 base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot))); | 2919 base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot))); |
2920 | 2920 |
2921 if (!obj->IsHeapObject()) return; | 2921 if (!obj->IsHeapObject()) return; |
2922 | 2922 |
2923 HeapObject* heap_obj = HeapObject::cast(obj); | 2923 HeapObject* heap_obj = HeapObject::cast(obj); |
2924 | 2924 |
2925 // TODO(ishell): remove, once crbug/454297 is caught. | |
2926 #if V8_TARGET_ARCH_64_BIT | |
2927 #ifndef V8_OS_AIX // no point checking on AIX as full 64 range is supported | |
2928 const uintptr_t kBoundary = V8_UINT64_C(1) << 48; | |
2929 STATIC_ASSERT(kBoundary > 0); | |
2930 if (reinterpret_cast<uintptr_t>(heap_obj->address()) >= kBoundary) { | |
2931 CheckLayoutDescriptorAndDie(heap, slot); | |
2932 } | |
2933 #endif | |
2934 #endif | |
2935 MapWord map_word = heap_obj->map_word(); | 2925 MapWord map_word = heap_obj->map_word(); |
2936 if (map_word.IsForwardingAddress()) { | 2926 if (map_word.IsForwardingAddress()) { |
2937 DCHECK(heap->InFromSpace(heap_obj) || | 2927 DCHECK(heap->InFromSpace(heap_obj) || |
2938 MarkCompactCollector::IsOnEvacuationCandidate(heap_obj)); | 2928 MarkCompactCollector::IsOnEvacuationCandidate(heap_obj)); |
2939 HeapObject* target = map_word.ToForwardingAddress(); | 2929 HeapObject* target = map_word.ToForwardingAddress(); |
2940 base::NoBarrier_CompareAndSwap( | 2930 base::NoBarrier_CompareAndSwap( |
2941 reinterpret_cast<base::AtomicWord*>(slot), | 2931 reinterpret_cast<base::AtomicWord*>(slot), |
2942 reinterpret_cast<base::AtomicWord>(obj), | 2932 reinterpret_cast<base::AtomicWord>(obj), |
2943 reinterpret_cast<base::AtomicWord>(target)); | 2933 reinterpret_cast<base::AtomicWord>(target)); |
2944 DCHECK(!heap->InFromSpace(target) && | 2934 DCHECK(!heap->InFromSpace(target) && |
2945 !MarkCompactCollector::IsOnEvacuationCandidate(target)); | 2935 !MarkCompactCollector::IsOnEvacuationCandidate(target)); |
2946 } | 2936 } |
2947 } | 2937 } |
2948 | 2938 |
2949 private: | 2939 private: |
2950 inline void UpdatePointer(Object** p) { UpdateSlot(heap_, p); } | 2940 inline void UpdatePointer(Object** p) { UpdateSlot(heap_, p); } |
2951 | 2941 |
2952 static void CheckLayoutDescriptorAndDie(Heap* heap, Object** slot); | |
2953 | |
2954 Heap* heap_; | 2942 Heap* heap_; |
2955 }; | 2943 }; |
2956 | 2944 |
2957 | 2945 |
2958 #if V8_TARGET_ARCH_64_BIT | |
2959 // TODO(ishell): remove, once crbug/454297 is caught. | |
2960 void PointersUpdatingVisitor::CheckLayoutDescriptorAndDie(Heap* heap, | |
2961 Object** slot) { | |
2962 const int kDataBufferSize = 128; | |
2963 uintptr_t data[kDataBufferSize] = {0}; | |
2964 int index = 0; | |
2965 data[index++] = 0x10aaaaaaaaUL; // begin marker | |
2966 | |
2967 data[index++] = reinterpret_cast<uintptr_t>(slot); | |
2968 data[index++] = 0x15aaaaaaaaUL; | |
2969 | |
2970 Address slot_address = reinterpret_cast<Address>(slot); | |
2971 | |
2972 uintptr_t space_owner_id = 0xb001; | |
2973 if (heap->new_space()->ToSpaceContains(slot_address)) { | |
2974 space_owner_id = 1; | |
2975 } else if (heap->new_space()->FromSpaceContains(slot_address)) { | |
2976 space_owner_id = 2; | |
2977 } else if (heap->old_space()->ContainsSafe(slot_address)) { | |
2978 space_owner_id = 3; | |
2979 } else if (heap->code_space()->ContainsSafe(slot_address)) { | |
2980 space_owner_id = 4; | |
2981 } else if (heap->map_space()->ContainsSafe(slot_address)) { | |
2982 space_owner_id = 5; | |
2983 } else { | |
2984 // Lo space or other. | |
2985 space_owner_id = 6; | |
2986 } | |
2987 data[index++] = space_owner_id; | |
2988 data[index++] = 0x20aaaaaaaaUL; | |
2989 | |
2990 // Find map word lying near before the slot address (usually the map word is | |
2991 // at -3 words from the slot but just in case we look up further. | |
2992 Object** map_slot = slot; | |
2993 bool found = false; | |
2994 const int kMaxDistanceToMap = 64; | |
2995 for (int i = 0; i < kMaxDistanceToMap; i++, map_slot--) { | |
2996 Address map_address = reinterpret_cast<Address>(*map_slot); | |
2997 if (heap->map_space()->ContainsSafe(map_address)) { | |
2998 found = true; | |
2999 break; | |
3000 } | |
3001 } | |
3002 data[index++] = found; | |
3003 data[index++] = 0x30aaaaaaaaUL; | |
3004 data[index++] = reinterpret_cast<uintptr_t>(map_slot); | |
3005 data[index++] = 0x35aaaaaaaaUL; | |
3006 | |
3007 if (found) { | |
3008 Address obj_address = reinterpret_cast<Address>(map_slot); | |
3009 Address end_of_page = | |
3010 reinterpret_cast<Address>(Page::FromAddress(obj_address)) + | |
3011 Page::kPageSize; | |
3012 Address end_address = | |
3013 Min(obj_address + kPointerSize * kMaxDistanceToMap, end_of_page); | |
3014 int size = static_cast<int>(end_address - obj_address); | |
3015 data[index++] = size / kPointerSize; | |
3016 data[index++] = 0x40aaaaaaaaUL; | |
3017 memcpy(&data[index], reinterpret_cast<void*>(map_slot), size); | |
3018 index += size / kPointerSize; | |
3019 data[index++] = 0x50aaaaaaaaUL; | |
3020 | |
3021 HeapObject* object = HeapObject::FromAddress(obj_address); | |
3022 data[index++] = reinterpret_cast<uintptr_t>(object); | |
3023 data[index++] = 0x60aaaaaaaaUL; | |
3024 | |
3025 Map* map = object->map(); | |
3026 data[index++] = reinterpret_cast<uintptr_t>(map); | |
3027 data[index++] = 0x70aaaaaaaaUL; | |
3028 | |
3029 LayoutDescriptor* layout_descriptor = map->layout_descriptor(); | |
3030 data[index++] = reinterpret_cast<uintptr_t>(layout_descriptor); | |
3031 data[index++] = 0x80aaaaaaaaUL; | |
3032 | |
3033 memcpy(&data[index], reinterpret_cast<void*>(map->address()), Map::kSize); | |
3034 index += Map::kSize / kPointerSize; | |
3035 data[index++] = 0x90aaaaaaaaUL; | |
3036 } | |
3037 | |
3038 data[index++] = 0xeeeeeeeeeeUL; | |
3039 DCHECK(index < kDataBufferSize); | |
3040 base::OS::PrintError("Data: %p\n", static_cast<void*>(data)); | |
3041 base::OS::Abort(); | |
3042 } | |
3043 #endif | |
3044 | |
3045 | |
3046 void MarkCompactCollector::UpdateSlots(SlotsBuffer* buffer) { | 2946 void MarkCompactCollector::UpdateSlots(SlotsBuffer* buffer) { |
3047 PointersUpdatingVisitor v(heap_); | 2947 PointersUpdatingVisitor v(heap_); |
3048 size_t buffer_size = buffer->Size(); | 2948 size_t buffer_size = buffer->Size(); |
3049 | 2949 |
3050 for (size_t slot_idx = 0; slot_idx < buffer_size; ++slot_idx) { | 2950 for (size_t slot_idx = 0; slot_idx < buffer_size; ++slot_idx) { |
3051 SlotsBuffer::ObjectSlot slot = buffer->Get(slot_idx); | 2951 SlotsBuffer::ObjectSlot slot = buffer->Get(slot_idx); |
3052 if (!SlotsBuffer::IsTypedSlot(slot)) { | 2952 if (!SlotsBuffer::IsTypedSlot(slot)) { |
3053 PointersUpdatingVisitor::UpdateSlot(heap_, slot); | 2953 PointersUpdatingVisitor::UpdateSlot(heap_, slot); |
3054 } else { | 2954 } else { |
3055 ++slot_idx; | 2955 ++slot_idx; |
(...skipping 1556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4612 MarkBit mark_bit = Marking::MarkBitFrom(host); | 4512 MarkBit mark_bit = Marking::MarkBitFrom(host); |
4613 if (Marking::IsBlack(mark_bit)) { | 4513 if (Marking::IsBlack(mark_bit)) { |
4614 RelocInfo rinfo(pc, RelocInfo::CODE_TARGET, 0, host); | 4514 RelocInfo rinfo(pc, RelocInfo::CODE_TARGET, 0, host); |
4615 RecordRelocSlot(&rinfo, target); | 4515 RecordRelocSlot(&rinfo, target); |
4616 } | 4516 } |
4617 } | 4517 } |
4618 } | 4518 } |
4619 | 4519 |
4620 } // namespace internal | 4520 } // namespace internal |
4621 } // namespace v8 | 4521 } // namespace v8 |
OLD | NEW |