Chromium Code Reviews| 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 |