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/v8.h" | 5 #include "src/v8.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/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/compilation-cache.h" | 10 #include "src/compilation-cache.h" |
(...skipping 2785 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2796 } | 2796 } |
2797 | 2797 |
2798 static inline void UpdateSlot(Heap* heap, Object** slot) { | 2798 static inline void UpdateSlot(Heap* heap, Object** slot) { |
2799 Object* obj = reinterpret_cast<Object*>( | 2799 Object* obj = reinterpret_cast<Object*>( |
2800 base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot))); | 2800 base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot))); |
2801 | 2801 |
2802 if (!obj->IsHeapObject()) return; | 2802 if (!obj->IsHeapObject()) return; |
2803 | 2803 |
2804 HeapObject* heap_obj = HeapObject::cast(obj); | 2804 HeapObject* heap_obj = HeapObject::cast(obj); |
2805 | 2805 |
2806 // TODO(ishell): remove, once crbug/454297 is caught. | |
2807 #if V8_TARGET_ARCH_64_BIT | |
2808 const uintptr_t kBoundary = 1UL << 48; | |
2809 STATIC_ASSERT(kBoundary > 0); | |
2810 if (reinterpret_cast<uintptr_t>(heap_obj->address()) >= kBoundary) { | |
2811 CheckLayoutDescriptorAndDie(heap, slot); | |
2812 } | |
2813 #endif | |
2806 MapWord map_word = heap_obj->map_word(); | 2814 MapWord map_word = heap_obj->map_word(); |
2807 if (map_word.IsForwardingAddress()) { | 2815 if (map_word.IsForwardingAddress()) { |
2808 DCHECK(heap->InFromSpace(heap_obj) || | 2816 DCHECK(heap->InFromSpace(heap_obj) || |
2809 MarkCompactCollector::IsOnEvacuationCandidate(heap_obj)); | 2817 MarkCompactCollector::IsOnEvacuationCandidate(heap_obj)); |
2810 HeapObject* target = map_word.ToForwardingAddress(); | 2818 HeapObject* target = map_word.ToForwardingAddress(); |
2811 base::NoBarrier_CompareAndSwap( | 2819 base::NoBarrier_CompareAndSwap( |
2812 reinterpret_cast<base::AtomicWord*>(slot), | 2820 reinterpret_cast<base::AtomicWord*>(slot), |
2813 reinterpret_cast<base::AtomicWord>(obj), | 2821 reinterpret_cast<base::AtomicWord>(obj), |
2814 reinterpret_cast<base::AtomicWord>(target)); | 2822 reinterpret_cast<base::AtomicWord>(target)); |
2815 DCHECK(!heap->InFromSpace(target) && | 2823 DCHECK(!heap->InFromSpace(target) && |
2816 !MarkCompactCollector::IsOnEvacuationCandidate(target)); | 2824 !MarkCompactCollector::IsOnEvacuationCandidate(target)); |
2817 } | 2825 } |
2818 } | 2826 } |
2819 | 2827 |
2820 private: | 2828 private: |
2821 inline void UpdatePointer(Object** p) { UpdateSlot(heap_, p); } | 2829 inline void UpdatePointer(Object** p) { UpdateSlot(heap_, p); } |
2822 | 2830 |
2831 static void CheckLayoutDescriptorAndDie(Heap* heap, Object** slot); | |
2832 | |
2823 Heap* heap_; | 2833 Heap* heap_; |
2824 }; | 2834 }; |
2825 | 2835 |
2826 | 2836 |
2837 #if V8_TARGET_ARCH_64_BIT | |
2838 // TODO(ishell): remove, once crbug/454297 is caught. | |
2839 void PointersUpdatingVisitor::CheckLayoutDescriptorAndDie(Heap* heap, | |
2840 Object** slot) { | |
2841 const int kDataBufferSize = 1280; | |
2842 uintptr_t data[kDataBufferSize] = {0}; | |
2843 int index = 0; | |
2844 data[index++] = 0x10aaaaaaaaUL; // begin marker | |
2845 Address slot_address = reinterpret_cast<Address>(slot); | |
2846 | |
2847 uintptr_t space_owner_id = 0xb001; | |
2848 if (heap->new_space()->ToSpaceContains(slot_address)) { | |
2849 space_owner_id = 1; | |
2850 } else if (heap->new_space()->FromSpaceContains(slot_address)) { | |
2851 space_owner_id = 2; | |
2852 } else if (heap->old_pointer_space()->ContainsSafe(slot_address)) { | |
2853 space_owner_id = 3; | |
2854 } else if (heap->old_data_space()->ContainsSafe(slot_address)) { | |
2855 space_owner_id = 4; | |
2856 } else if (heap->code_space()->ContainsSafe(slot_address)) { | |
2857 space_owner_id = 5; | |
2858 } else if (heap->map_space()->ContainsSafe(slot_address)) { | |
2859 space_owner_id = 6; | |
2860 } else if (heap->cell_space()->ContainsSafe(slot_address)) { | |
2861 space_owner_id = 7; | |
2862 } else if (heap->property_cell_space()->ContainsSafe(slot_address)) { | |
2863 space_owner_id = 8; | |
2864 } else { | |
2865 // Lo space or other. | |
2866 space_owner_id = 9; | |
2867 } | |
2868 data[index++] = space_owner_id; | |
2869 data[index++] = 0x20aaaaaaaaUL; | |
2870 | |
2871 // Find map word lying near before the slot address (usually the map word is | |
2872 // at -3 words from the slot but just in case we look up further. | |
2873 Object** map_slot = slot; | |
2874 bool found = false; | |
2875 const int kMaxDistanceToMap = 64; | |
2876 for (int i = 0; i < kMaxDistanceToMap; i++, map_slot -= kPointerSize) { | |
2877 Address map_address = reinterpret_cast<Address>(*map_slot); | |
2878 if (heap->map_space()->ContainsSafe(map_address)) { | |
2879 found = true; | |
2880 break; | |
2881 } | |
2882 } | |
2883 data[index++] = found; | |
2884 data[index++] = 0x30aaaaaaaaUL; | |
2885 if (found) { | |
2886 Address obj_address = reinterpret_cast<Address>(map_slot); | |
2887 Address end_of_page = | |
2888 reinterpret_cast<Address>(Page::FromAddress(obj_address)) + | |
2889 Page::kPageSize; | |
2890 Address end_address = | |
2891 Min(obj_address + kPointerSize * kMaxDistanceToMap, end_of_page); | |
2892 int size = end_address - obj_address; | |
2893 data[index++] = size / kPointerSize; | |
2894 data[index++] = 0x40aaaaaaaaUL; | |
2895 memcpy(&data[index], reinterpret_cast<void*>(map_slot), size); | |
2896 index += size / kPointerSize; | |
2897 data[index++] = 0x50aaaaaaaaUL; | |
2898 | |
2899 HeapObject* object = HeapObject::FromAddress(obj_address); | |
2900 data[index++] = reinterpret_cast<uintptr_t>(object); | |
2901 data[index++] = 0x60aaaaaaaaUL; | |
2902 | |
2903 Map* map = object->map(); | |
2904 data[index++] = reinterpret_cast<uintptr_t>(map); | |
2905 data[index++] = 0x70aaaaaaaaUL; | |
2906 | |
2907 LayoutDescriptor* layout_descriptor = map->layout_descriptor(); | |
2908 data[index++] = reinterpret_cast<uintptr_t>(layout_descriptor); | |
2909 data[index++] = 0x80aaaaaaaaUL; | |
2910 | |
2911 memcpy(&data[index], reinterpret_cast<void*>(map->address()), Map::kSize); | |
2912 STATIC_ASSERT(Map::kSize == 10 * kPointerSize); | |
2913 index += 10; | |
Hannes Payer (out of office)
2015/02/17 10:51:11
instead of +10 please use the map size
Igor Sheludko
2015/02/17 10:57:40
Done.
| |
2914 data[index++] = 0x90aaaaaaaaUL; | |
2915 } | |
2916 | |
2917 data[index++] = 0xeeeeeeeeeeUL; | |
2918 DCHECK(index < kDataBufferSize); | |
2919 base::OS::PrintError("Data: %p\n", static_cast<void*>(data)); | |
2920 base::OS::Abort(); | |
2921 } | |
2922 #endif | |
2923 | |
2924 | |
2827 static void UpdatePointer(HeapObject** address, HeapObject* object) { | 2925 static void UpdatePointer(HeapObject** address, HeapObject* object) { |
2828 Address new_addr = Memory::Address_at(object->address()); | 2926 Address new_addr = Memory::Address_at(object->address()); |
2829 | 2927 |
2830 // The new space sweep will overwrite the map word of dead objects | 2928 // The new space sweep will overwrite the map word of dead objects |
2831 // with NULL. In this case we do not need to transfer this entry to | 2929 // with NULL. In this case we do not need to transfer this entry to |
2832 // the store buffer which we are rebuilding. | 2930 // the store buffer which we are rebuilding. |
2833 // We perform the pointer update with a no barrier compare-and-swap. The | 2931 // We perform the pointer update with a no barrier compare-and-swap. The |
2834 // compare and swap may fail in the case where the pointer update tries to | 2932 // compare and swap may fail in the case where the pointer update tries to |
2835 // update garbage memory which was concurrently accessed by the sweeper. | 2933 // update garbage memory which was concurrently accessed by the sweeper. |
2836 if (new_addr != NULL) { | 2934 if (new_addr != NULL) { |
(...skipping 1490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4327 SlotsBuffer* buffer = *buffer_address; | 4425 SlotsBuffer* buffer = *buffer_address; |
4328 while (buffer != NULL) { | 4426 while (buffer != NULL) { |
4329 SlotsBuffer* next_buffer = buffer->next(); | 4427 SlotsBuffer* next_buffer = buffer->next(); |
4330 DeallocateBuffer(buffer); | 4428 DeallocateBuffer(buffer); |
4331 buffer = next_buffer; | 4429 buffer = next_buffer; |
4332 } | 4430 } |
4333 *buffer_address = NULL; | 4431 *buffer_address = NULL; |
4334 } | 4432 } |
4335 } | 4433 } |
4336 } // namespace v8::internal | 4434 } // namespace v8::internal |
OLD | NEW |