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 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |