Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(432)

Side by Side Diff: src/heap/mark-compact.cc

Issue 930243002: Put extra information to the stack when crbug/454297 happens. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressed comments Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/heap/spaces.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « no previous file | src/heap/spaces.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698