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

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

Issue 958543003: Avoid stale store buffer entries after full GC by promoting objects referenced by the store buffer. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 9 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/store-buffer.cc » ('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 1839 matching lines...) Expand 10 before | Expand all | Expand 10 after
1850 if (current_cell == 0) continue; 1850 if (current_cell == 0) continue;
1851 1851
1852 int offset = 0; 1852 int offset = 0;
1853 while (current_cell != 0) { 1853 while (current_cell != 0) {
1854 int trailing_zeros = base::bits::CountTrailingZeros32(current_cell); 1854 int trailing_zeros = base::bits::CountTrailingZeros32(current_cell);
1855 current_cell >>= trailing_zeros; 1855 current_cell >>= trailing_zeros;
1856 offset += trailing_zeros; 1856 offset += trailing_zeros;
1857 Address address = cell_base + offset * kPointerSize; 1857 Address address = cell_base + offset * kPointerSize;
1858 HeapObject* object = HeapObject::FromAddress(address); 1858 HeapObject* object = HeapObject::FromAddress(address);
1859 1859
1860 offset++;
1861 current_cell >>= 1;
1862
1863 MapWord map_word = object->map_word();
1864 if (map_word.IsForwardingAddress()) {
1865 printf("forwarded object found %p\n", address);
1866 continue;
1867 }
1868
1860 int size = object->Size(); 1869 int size = object->Size();
1861 survivors_size += size; 1870 survivors_size += size;
1862 1871
1863 Heap::UpdateAllocationSiteFeedback(object, Heap::RECORD_SCRATCHPAD_SLOT); 1872 Heap::UpdateAllocationSiteFeedback(object, Heap::RECORD_SCRATCHPAD_SLOT);
1864 1873
1865 offset++;
1866 current_cell >>= 1;
1867
1868 // TODO(hpayer): Refactor EvacuateObject and call this function instead. 1874 // TODO(hpayer): Refactor EvacuateObject and call this function instead.
1869 if (heap()->ShouldBePromoted(object->address(), size) && 1875 if (heap()->ShouldBePromoted(object->address(), size) &&
1870 TryPromoteObject(object, size)) { 1876 TryPromoteObject(object, size)) {
1871 continue; 1877 continue;
1872 } 1878 }
1873 1879
1874 AllocationResult allocation = new_space->AllocateRaw(size); 1880 AllocationResult allocation = new_space->AllocateRaw(size);
1875 if (allocation.IsRetry()) { 1881 if (allocation.IsRetry()) {
1876 if (!new_space->AddFreshPage()) { 1882 if (!new_space->AddFreshPage()) {
1877 // Shouldn't happen. We are sweeping linearly, and to-space 1883 // Shouldn't happen. We are sweeping linearly, and to-space
(...skipping 1055 matching lines...) Expand 10 before | Expand all | Expand 10 after
2933 // update garbage memory which was concurrently accessed by the sweeper. 2939 // update garbage memory which was concurrently accessed by the sweeper.
2934 if (new_addr != NULL) { 2940 if (new_addr != NULL) {
2935 base::NoBarrier_CompareAndSwap( 2941 base::NoBarrier_CompareAndSwap(
2936 reinterpret_cast<base::AtomicWord*>(address), 2942 reinterpret_cast<base::AtomicWord*>(address),
2937 reinterpret_cast<base::AtomicWord>(object), 2943 reinterpret_cast<base::AtomicWord>(object),
2938 reinterpret_cast<base::AtomicWord>(HeapObject::FromAddress(new_addr))); 2944 reinterpret_cast<base::AtomicWord>(HeapObject::FromAddress(new_addr)));
2939 } 2945 }
2940 } 2946 }
2941 2947
2942 2948
2949 static void PromoteObjectReferencedFromStoreBuffer(HeapObject** address,
2950 HeapObject* object) {
2951 Heap* heap = object->GetIsolate()->heap();
2952 DCHECK(heap->InFromSpace(object));
2953
2954 // We use the first word (where the map pointer usually is) of a heap
2955 // object to record the forwarding pointer. A forwarding pointer can
2956 // point to an old space, the code space, or the to space of the new
2957 // generation.
2958 MapWord first_word = object->map_word();
2959
2960 // If the first word is a forwarding address, the object has already been
2961 // promoted to the old generation. There must have been a duplicate store
2962 // buffer entry.
2963 if (first_word.IsForwardingAddress()) {
2964 DCHECK(!heap->InNewSpace(first_word.ToForwardingAddress()));
2965 return;
2966 }
2967
2968 if (!heap->mark_compact_collector()->TryPromoteObject(object,
2969 object->Size())) {
2970 V8::FatalProcessOutOfMemory("Store buffer promotion");
2971 }
2972 }
2973
2974
2943 static String* UpdateReferenceInExternalStringTableEntry(Heap* heap, 2975 static String* UpdateReferenceInExternalStringTableEntry(Heap* heap,
2944 Object** p) { 2976 Object** p) {
2945 MapWord map_word = HeapObject::cast(*p)->map_word(); 2977 MapWord map_word = HeapObject::cast(*p)->map_word();
2946 2978
2947 if (map_word.IsForwardingAddress()) { 2979 if (map_word.IsForwardingAddress()) {
2948 return String::cast(map_word.ToForwardingAddress()); 2980 return String::cast(map_word.ToForwardingAddress());
2949 } 2981 }
2950 2982
2951 return String::cast(*p); 2983 return String::cast(*p);
2952 } 2984 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2984 Address from_bottom = new_space->bottom(); 3016 Address from_bottom = new_space->bottom();
2985 Address from_top = new_space->top(); 3017 Address from_top = new_space->top();
2986 3018
2987 // Flip the semispaces. After flipping, to space is empty, from space has 3019 // Flip the semispaces. After flipping, to space is empty, from space has
2988 // live objects. 3020 // live objects.
2989 new_space->Flip(); 3021 new_space->Flip();
2990 new_space->ResetAllocationInfo(); 3022 new_space->ResetAllocationInfo();
2991 3023
2992 int survivors_size = 0; 3024 int survivors_size = 0;
2993 3025
3026 {
3027 StoreBufferRebuildScope scope(heap_, heap_->store_buffer(),
3028 &Heap::ScavengeStoreBufferCallback);
3029 heap_->store_buffer()->IteratePointersToNewSpace(
3030 &PromoteObjectReferencedFromStoreBuffer);
3031 }
3032
2994 // First pass: traverse all objects in inactive semispace, remove marks, 3033 // First pass: traverse all objects in inactive semispace, remove marks,
2995 // migrate live objects and write forwarding addresses. This stage puts 3034 // migrate live objects and write forwarding addresses. This stage puts
2996 // new entries in the store buffer and may cause some pages to be marked 3035 // new entries in the store buffer and may cause some pages to be marked
2997 // scan-on-scavenge. 3036 // scan-on-scavenge.
2998 NewSpacePageIterator it(from_bottom, from_top); 3037 NewSpacePageIterator it(from_bottom, from_top);
2999 while (it.has_next()) { 3038 while (it.has_next()) {
3000 NewSpacePage* p = it.next(); 3039 NewSpacePage* p = it.next();
3001 survivors_size += DiscoverAndEvacuateBlackObjectsOnPage(new_space, p); 3040 survivors_size += DiscoverAndEvacuateBlackObjectsOnPage(new_space, p);
3002 } 3041 }
3003 3042
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
3394 } 3433 }
3395 } 3434 }
3396 invalidated_code_.Rewind(0); 3435 invalidated_code_.Rewind(0);
3397 } 3436 }
3398 3437
3399 3438
3400 void MarkCompactCollector::EvacuateNewSpaceAndCandidates() { 3439 void MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
3401 Heap::RelocationLock relocation_lock(heap()); 3440 Heap::RelocationLock relocation_lock(heap());
3402 3441
3403 bool code_slots_filtering_required; 3442 bool code_slots_filtering_required;
3443
3404 { 3444 {
3405 GCTracer::Scope gc_scope(heap()->tracer(), 3445 GCTracer::Scope gc_scope(heap()->tracer(),
3406 GCTracer::Scope::MC_SWEEP_NEWSPACE); 3446 GCTracer::Scope::MC_SWEEP_NEWSPACE);
3407 code_slots_filtering_required = MarkInvalidatedCode(); 3447 code_slots_filtering_required = MarkInvalidatedCode();
3408 EvacuateNewSpace(); 3448 EvacuateNewSpace();
3409 } 3449 }
3410 3450
3411 { 3451 {
3412 GCTracer::Scope gc_scope(heap()->tracer(), 3452 GCTracer::Scope gc_scope(heap()->tracer(),
3413 GCTracer::Scope::MC_EVACUATE_PAGES); 3453 GCTracer::Scope::MC_EVACUATE_PAGES);
(...skipping 1016 matching lines...) Expand 10 before | Expand all | Expand 10 after
4430 SlotsBuffer* buffer = *buffer_address; 4470 SlotsBuffer* buffer = *buffer_address;
4431 while (buffer != NULL) { 4471 while (buffer != NULL) {
4432 SlotsBuffer* next_buffer = buffer->next(); 4472 SlotsBuffer* next_buffer = buffer->next();
4433 DeallocateBuffer(buffer); 4473 DeallocateBuffer(buffer);
4434 buffer = next_buffer; 4474 buffer = next_buffer;
4435 } 4475 }
4436 *buffer_address = NULL; 4476 *buffer_address = NULL;
4437 } 4477 }
4438 } 4478 }
4439 } // namespace v8::internal 4479 } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/heap/store-buffer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698