| 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 |