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