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

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

Issue 985453003: Eliminate invalid pointers in store buffer after marking. (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 | « src/heap/mark-compact.h ('k') | src/heap/store-buffer.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 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 ClearWeakCollections(); 307 ClearWeakCollections();
308 308
309 heap_->set_encountered_weak_cells(Smi::FromInt(0)); 309 heap_->set_encountered_weak_cells(Smi::FromInt(0));
310 310
311 #ifdef VERIFY_HEAP 311 #ifdef VERIFY_HEAP
312 if (FLAG_verify_heap) { 312 if (FLAG_verify_heap) {
313 VerifyMarking(heap_); 313 VerifyMarking(heap_);
314 } 314 }
315 #endif 315 #endif
316 316
317 heap_->store_buffer()->ClearInvalidStoreBufferEntries();
318
319 #ifdef VERIFY_HEAP
320 if (FLAG_verify_heap) {
321 heap_->store_buffer()->VerifyValidStoreBufferEntries();
322 }
323 #endif
324
317 SweepSpaces(); 325 SweepSpaces();
318 326
319 #ifdef VERIFY_HEAP 327 #ifdef VERIFY_HEAP
320 VerifyWeakEmbeddedObjectsInCode(); 328 VerifyWeakEmbeddedObjectsInCode();
321 if (FLAG_collect_maps && FLAG_omit_map_checks_for_leaf_maps) { 329 if (FLAG_collect_maps && FLAG_omit_map_checks_for_leaf_maps) {
322 VerifyOmittedMapChecks(); 330 VerifyOmittedMapChecks();
323 } 331 }
324 #endif 332 #endif
325 333
326 Finish(); 334 Finish();
(...skipping 2714 matching lines...) Expand 10 before | Expand all | Expand 10 after
3041 if (allocation.To(&target)) { 3049 if (allocation.To(&target)) {
3042 MigrateObject(target, object, object_size, target_space->identity()); 3050 MigrateObject(target, object, object_size, target_space->identity());
3043 heap()->IncrementPromotedObjectsSize(object_size); 3051 heap()->IncrementPromotedObjectsSize(object_size);
3044 return true; 3052 return true;
3045 } 3053 }
3046 3054
3047 return false; 3055 return false;
3048 } 3056 }
3049 3057
3050 3058
3059 bool MarkCompactCollector::IsSlotInBlackObject(Page* p, Address slot) {
3060 // This function does not support large objects right now.
3061 if (p->owner() == NULL) return true;
3062
3063 uint32_t mark_bit_index = p->AddressToMarkbitIndex(slot);
3064 unsigned int start_index = mark_bit_index >> Bitmap::kBitsPerCellLog2;
3065 MarkBit::CellType index_in_cell = 1U
3066 << (mark_bit_index & Bitmap::kBitIndexMask);
3067 MarkBit::CellType* cells = p->markbits()->cells();
3068
3069 // First check if the object is in the current cell.
3070 MarkBit::CellType slot_mask;
3071 if ((cells[start_index] == 0) ||
3072 (base::bits::CountTrailingZeros32(cells[start_index]) >
3073 base::bits::CountTrailingZeros32(cells[start_index] | index_in_cell))) {
3074 // If not, find a cell in a preceding cell slot that has a mark bit set.
3075 do {
3076 start_index--;
Erik Corry 2015/03/09 10:39:17 If start_index was zero, it goes negative here, wh
Hannes Payer (out of office) 2015/03/09 11:50:12 start_index will never be zero. It will always be
3077 } while (start_index > 0 && cells[start_index] == 0);
3078
3079 // The slot must be in a dead object if there are no preceding cells that
3080 // have mark bits set.
3081 if (cells[start_index] == 0) {
3082 return false;
3083 }
3084
3085 // The object is in a preceding cell. Set the mask to find any object.
3086 slot_mask = 0xffffffff;
3087 } else {
3088 // We are interested in object mark bits right before the slot.
3089 slot_mask = index_in_cell - 1;
3090 }
3091
3092 MarkBit::CellType current_cell = cells[start_index];
3093 DCHECK(current_cell != 0);
3094
3095 // Find the first live object in the cell.
Erik Corry 2015/03/09 10:46:26 Shouldn't this be the _last_ live object in the ce
Hannes Payer (out of office) 2015/03/09 11:50:12 Done. It depends on your point of view.
3096 unsigned int leading_zeros =
3097 base::bits::CountLeadingZeros32(current_cell & slot_mask);
3098 DCHECK(leading_zeros != 32);
3099 unsigned int offset = Bitmap::kBitIndexMask - leading_zeros;
3100
3101 Address cell_base = p->area_start();
3102 unsigned int cell_base_start_index = Bitmap::IndexToCell(
3103 Bitmap::CellAlignIndex(p->AddressToMarkbitIndex(cell_base)));
3104 cell_base += (start_index - cell_base_start_index) * 32 * kPointerSize;
3105 Address address = cell_base + offset * kPointerSize;
3106 HeapObject* object = HeapObject::FromAddress(address);
3107 DCHECK(object->address() < reinterpret_cast<Address>(slot));
3108 if (object->address() <= slot &&
3109 (object->address() + object->Size()) > slot) {
3110 // If the slot is within the first found object in the cell, the slot is
3111 // in a live object.
3112 return true;
3113 }
3114 return false;
3115 }
3116
3117
3118 bool MarkCompactCollector::IsSlotInBlackObjectSlow(Page* p, Address slot) {
3119 // This function does not support large objects right now.
3120 if (p->owner() == NULL) return true;
3121
3122 for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) {
3123 Address cell_base = it.CurrentCellBase();
3124 MarkBit::CellType* cell = it.CurrentCell();
3125
3126 MarkBit::CellType current_cell = *cell;
3127 if (current_cell == 0) continue;
3128
3129 int offset = 0;
3130 while (current_cell != 0) {
3131 int trailing_zeros = base::bits::CountTrailingZeros32(current_cell);
3132 current_cell >>= trailing_zeros;
3133 offset += trailing_zeros;
3134 Address address = cell_base + offset * kPointerSize;
3135
3136 HeapObject* object = HeapObject::FromAddress(address);
3137 int size = object->Size();
3138
3139 if (object->address() > slot) return false;
3140 if (object->address() <= slot && slot < (object->address() + size)) {
3141 return true;
3142 }
3143
3144 offset++;
3145 current_cell >>= 1;
3146 }
3147 }
3148 return false;
3149 }
3150
3151
3152 bool MarkCompactCollector::IsSlotInLiveObject(HeapObject** address,
3153 HeapObject* object) {
3154 // If the target object is not black, the source slot must be part
3155 // of a non-black (dead) object.
3156 if (!Marking::IsBlack(Marking::MarkBitFrom(object))) {
3157 return false;
3158 }
3159
3160 // The target object is black but we don't know if the source slot is black.
3161 // The source object could have died and the slot could be part of a free
3162 // space. Find out based on mark bits if the slot is part of a live object.
3163 if (!IsSlotInBlackObject(
3164 Page::FromAddress(reinterpret_cast<Address>(address)),
3165 reinterpret_cast<Address>(address))) {
3166 return false;
3167 }
3168
3169 return true;
3170 }
3171
3172
3173 void MarkCompactCollector::VerifyIsSlotInLiveObject(HeapObject** address,
3174 HeapObject* object) {
3175 // The target object has to be black.
3176 CHECK(Marking::IsBlack(Marking::MarkBitFrom(object)));
3177
3178 // The target object is black but we don't know if the source slot is black.
3179 // The source object could have died and the slot could be part of a free
3180 // space. Use the mark bit iterator to find out about liveness of the slot.
3181 CHECK(IsSlotInBlackObjectSlow(
3182 Page::FromAddress(reinterpret_cast<Address>(address)),
3183 reinterpret_cast<Address>(address)));
3184 }
3185
3186
3051 void MarkCompactCollector::EvacuateNewSpace() { 3187 void MarkCompactCollector::EvacuateNewSpace() {
3052 // There are soft limits in the allocation code, designed trigger a mark 3188 // There are soft limits in the allocation code, designed trigger a mark
3053 // sweep collection by failing allocations. But since we are already in 3189 // sweep collection by failing allocations. But since we are already in
3054 // a mark-sweep allocation, there is no sense in trying to trigger one. 3190 // a mark-sweep allocation, there is no sense in trying to trigger one.
3055 AlwaysAllocateScope scope(isolate()); 3191 AlwaysAllocateScope scope(isolate());
3056 3192
3057 NewSpace* new_space = heap()->new_space(); 3193 NewSpace* new_space = heap()->new_space();
3058 3194
3059 // Store allocation range before flipping semispaces. 3195 // Store allocation range before flipping semispaces.
3060 Address from_bottom = new_space->bottom(); 3196 Address from_bottom = new_space->bottom();
(...skipping 1435 matching lines...) Expand 10 before | Expand all | Expand 10 after
4496 SlotsBuffer* buffer = *buffer_address; 4632 SlotsBuffer* buffer = *buffer_address;
4497 while (buffer != NULL) { 4633 while (buffer != NULL) {
4498 SlotsBuffer* next_buffer = buffer->next(); 4634 SlotsBuffer* next_buffer = buffer->next();
4499 DeallocateBuffer(buffer); 4635 DeallocateBuffer(buffer);
4500 buffer = next_buffer; 4636 buffer = next_buffer;
4501 } 4637 }
4502 *buffer_address = NULL; 4638 *buffer_address = NULL;
4503 } 4639 }
4504 } 4640 }
4505 } // namespace v8::internal 4641 } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/heap/store-buffer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698