| 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 3040 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3051 heap()->IncrementPromotedObjectsSize(object_size); | 3051 heap()->IncrementPromotedObjectsSize(object_size); |
| 3052 return true; | 3052 return true; |
| 3053 } | 3053 } |
| 3054 | 3054 |
| 3055 return false; | 3055 return false; |
| 3056 } | 3056 } |
| 3057 | 3057 |
| 3058 | 3058 |
| 3059 bool MarkCompactCollector::IsSlotInBlackObject(Page* p, Address slot, | 3059 bool MarkCompactCollector::IsSlotInBlackObject(Page* p, Address slot, |
| 3060 HeapObject** out_object) { | 3060 HeapObject** out_object) { |
| 3061 // This function does not support large objects right now. | |
| 3062 Space* owner = p->owner(); | 3061 Space* owner = p->owner(); |
| 3063 if (owner == heap_->lo_space() || owner == NULL) { | 3062 if (owner == heap_->lo_space() || owner == NULL) { |
| 3064 *out_object = NULL; | 3063 Object* large_object = heap_->lo_space()->FindObject(slot); |
| 3065 return true; | 3064 // This object has to exist, otherwise we would not have recorded a slot |
| 3065 // for it. |
| 3066 CHECK(large_object->IsHeapObject()); |
| 3067 HeapObject* large_heap_object = HeapObject::cast(large_object); |
| 3068 if (IsMarked(large_heap_object)) { |
| 3069 *out_object = large_heap_object; |
| 3070 return true; |
| 3071 } |
| 3072 return false; |
| 3066 } | 3073 } |
| 3067 | 3074 |
| 3068 uint32_t mark_bit_index = p->AddressToMarkbitIndex(slot); | 3075 uint32_t mark_bit_index = p->AddressToMarkbitIndex(slot); |
| 3069 unsigned int start_index = mark_bit_index >> Bitmap::kBitsPerCellLog2; | 3076 unsigned int start_index = mark_bit_index >> Bitmap::kBitsPerCellLog2; |
| 3070 MarkBit::CellType index_in_cell = 1U | 3077 MarkBit::CellType index_in_cell = 1U |
| 3071 << (mark_bit_index & Bitmap::kBitIndexMask); | 3078 << (mark_bit_index & Bitmap::kBitIndexMask); |
| 3072 MarkBit::CellType* cells = p->markbits()->cells(); | 3079 MarkBit::CellType* cells = p->markbits()->cells(); |
| 3073 Address cell_base = p->area_start(); | 3080 Address cell_base = p->area_start(); |
| 3074 unsigned int cell_base_start_index = Bitmap::IndexToCell( | 3081 unsigned int cell_base_start_index = Bitmap::IndexToCell( |
| 3075 Bitmap::CellAlignIndex(p->AddressToMarkbitIndex(cell_base))); | 3082 Bitmap::CellAlignIndex(p->AddressToMarkbitIndex(cell_base))); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3172 | 3179 |
| 3173 bool MarkCompactCollector::IsSlotInLiveObject(Address slot) { | 3180 bool MarkCompactCollector::IsSlotInLiveObject(Address slot) { |
| 3174 HeapObject* object = NULL; | 3181 HeapObject* object = NULL; |
| 3175 // The target object is black but we don't know if the source slot is black. | 3182 // The target object is black but we don't know if the source slot is black. |
| 3176 // The source object could have died and the slot could be part of a free | 3183 // The source object could have died and the slot could be part of a free |
| 3177 // space. Find out based on mark bits if the slot is part of a live object. | 3184 // space. Find out based on mark bits if the slot is part of a live object. |
| 3178 if (!IsSlotInBlackObject(Page::FromAddress(slot), slot, &object)) { | 3185 if (!IsSlotInBlackObject(Page::FromAddress(slot), slot, &object)) { |
| 3179 return false; | 3186 return false; |
| 3180 } | 3187 } |
| 3181 | 3188 |
| 3182 // |object| is NULL only when the slot belongs to large object space. | 3189 DCHECK(object != NULL); |
| 3183 DCHECK(object != NULL || | 3190 |
| 3184 Page::FromAnyPointerAddress(heap_, slot)->owner() == | |
| 3185 heap_->lo_space()); | |
| 3186 // We don't need to check large objects' layout descriptor since it can't | |
| 3187 // contain in-object fields anyway. | |
| 3188 if (object != NULL) { | |
| 3189 switch (object->ContentType()) { | 3191 switch (object->ContentType()) { |
| 3190 case HeapObjectContents::kTaggedValues: | 3192 case HeapObjectContents::kTaggedValues: |
| 3191 return true; | 3193 return true; |
| 3192 | 3194 |
| 3193 case HeapObjectContents::kRawValues: { | 3195 case HeapObjectContents::kRawValues: { |
| 3194 InstanceType type = object->map()->instance_type(); | 3196 InstanceType type = object->map()->instance_type(); |
| 3195 // Slots in maps and code can't be invalid because they are never | 3197 // Slots in maps and code can't be invalid because they are never |
| 3196 // shrunk. | 3198 // shrunk. |
| 3197 if (type == MAP_TYPE || type == CODE_TYPE) return true; | 3199 if (type == MAP_TYPE || type == CODE_TYPE) return true; |
| 3198 | 3200 |
| 3199 // Consider slots in objects that contain ONLY raw data as invalid. | 3201 // Consider slots in objects that contain ONLY raw data as invalid. |
| 3200 return false; | 3202 return false; |
| 3201 } | 3203 } |
| 3202 | 3204 |
| 3203 case HeapObjectContents::kMixedValues: { | 3205 case HeapObjectContents::kMixedValues: { |
| 3204 if (object->IsFixedTypedArrayBase()) { | 3206 if (object->IsFixedTypedArrayBase()) { |
| 3205 return static_cast<int>(slot - object->address()) == | 3207 return static_cast<int>(slot - object->address()) == |
| 3206 FixedTypedArrayBase::kBasePointerOffset; | 3208 FixedTypedArrayBase::kBasePointerOffset; |
| 3207 } else if (FLAG_unbox_double_fields) { | 3209 } else if (FLAG_unbox_double_fields) { |
| 3208 // Filter out slots that happen to point to unboxed double fields. | 3210 // Filter out slots that happen to point to unboxed double fields. |
| 3209 LayoutDescriptorHelper helper(object->map()); | 3211 LayoutDescriptorHelper helper(object->map()); |
| 3210 DCHECK(!helper.all_fields_tagged()); | 3212 DCHECK(!helper.all_fields_tagged()); |
| 3211 return helper.IsTagged(static_cast<int>(slot - object->address())); | 3213 return helper.IsTagged(static_cast<int>(slot - object->address())); |
| 3212 } | 3214 } |
| 3213 break; | 3215 break; |
| 3214 } | 3216 } |
| 3215 } | 3217 } |
| 3216 UNREACHABLE(); | 3218 UNREACHABLE(); |
| 3217 } | 3219 return true; |
| 3218 | |
| 3219 return true; | |
| 3220 } | 3220 } |
| 3221 | 3221 |
| 3222 | 3222 |
| 3223 void MarkCompactCollector::VerifyIsSlotInLiveObject(Address slot, | 3223 void MarkCompactCollector::VerifyIsSlotInLiveObject(Address slot, |
| 3224 HeapObject* object) { | 3224 HeapObject* object) { |
| 3225 // The target object has to be black. | 3225 // The target object has to be black. |
| 3226 CHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); | 3226 CHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); |
| 3227 | 3227 |
| 3228 // The target object is black but we don't know if the source slot is black. | 3228 // The target object is black but we don't know if the source slot is black. |
| 3229 // The source object could have died and the slot could be part of a free | 3229 // The source object could have died and the slot could be part of a free |
| (...skipping 1207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4437 ->NeverEvacuate()); | 4437 ->NeverEvacuate()); |
| 4438 | 4438 |
| 4439 while (buffer != NULL) { | 4439 while (buffer != NULL) { |
| 4440 SlotsBuffer::ObjectSlot* slots = buffer->slots_; | 4440 SlotsBuffer::ObjectSlot* slots = buffer->slots_; |
| 4441 intptr_t slots_count = buffer->idx_; | 4441 intptr_t slots_count = buffer->idx_; |
| 4442 | 4442 |
| 4443 for (int slot_idx = 0; slot_idx < slots_count; ++slot_idx) { | 4443 for (int slot_idx = 0; slot_idx < slots_count; ++slot_idx) { |
| 4444 ObjectSlot slot = slots[slot_idx]; | 4444 ObjectSlot slot = slots[slot_idx]; |
| 4445 if (!IsTypedSlot(slot)) { | 4445 if (!IsTypedSlot(slot)) { |
| 4446 Object* object = *slot; | 4446 Object* object = *slot; |
| 4447 if (object->IsHeapObject()) { | 4447 if ((object->IsHeapObject() && heap->InNewSpace(object)) || |
| 4448 if (heap->InNewSpace(object) || | 4448 !heap->mark_compact_collector()->IsSlotInLiveObject( |
| 4449 !heap->mark_compact_collector()->IsSlotInLiveObject( | 4449 reinterpret_cast<Address>(slot))) { |
| 4450 reinterpret_cast<Address>(slot))) { | 4450 slots[slot_idx] = kRemovedEntry; |
| 4451 slots[slot_idx] = kRemovedEntry; | |
| 4452 } | |
| 4453 } | 4451 } |
| 4454 } else { | 4452 } else { |
| 4455 ++slot_idx; | 4453 ++slot_idx; |
| 4456 DCHECK(slot_idx < slots_count); | 4454 DCHECK(slot_idx < slots_count); |
| 4457 } | 4455 } |
| 4458 } | 4456 } |
| 4459 buffer = buffer->next(); | 4457 buffer = buffer->next(); |
| 4460 } | 4458 } |
| 4461 } | 4459 } |
| 4462 | 4460 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4499 void SlotsBuffer::VerifySlots(Heap* heap, SlotsBuffer* buffer) { | 4497 void SlotsBuffer::VerifySlots(Heap* heap, SlotsBuffer* buffer) { |
| 4500 while (buffer != NULL) { | 4498 while (buffer != NULL) { |
| 4501 SlotsBuffer::ObjectSlot* slots = buffer->slots_; | 4499 SlotsBuffer::ObjectSlot* slots = buffer->slots_; |
| 4502 intptr_t slots_count = buffer->idx_; | 4500 intptr_t slots_count = buffer->idx_; |
| 4503 | 4501 |
| 4504 for (int slot_idx = 0; slot_idx < slots_count; ++slot_idx) { | 4502 for (int slot_idx = 0; slot_idx < slots_count; ++slot_idx) { |
| 4505 ObjectSlot slot = slots[slot_idx]; | 4503 ObjectSlot slot = slots[slot_idx]; |
| 4506 if (!IsTypedSlot(slot)) { | 4504 if (!IsTypedSlot(slot)) { |
| 4507 Object* object = *slot; | 4505 Object* object = *slot; |
| 4508 if (object->IsHeapObject()) { | 4506 if (object->IsHeapObject()) { |
| 4507 HeapObject* heap_object = HeapObject::cast(object); |
| 4509 CHECK(!heap->InNewSpace(object)); | 4508 CHECK(!heap->InNewSpace(object)); |
| 4510 CHECK(heap->mark_compact_collector()->IsSlotInLiveObject( | 4509 heap->mark_compact_collector()->VerifyIsSlotInLiveObject( |
| 4511 reinterpret_cast<Address>(slot))); | 4510 reinterpret_cast<Address>(slot), heap_object); |
| 4512 } | 4511 } |
| 4513 } else { | 4512 } else { |
| 4514 ++slot_idx; | 4513 ++slot_idx; |
| 4515 DCHECK(slot_idx < slots_count); | 4514 DCHECK(slot_idx < slots_count); |
| 4516 } | 4515 } |
| 4517 } | 4516 } |
| 4518 buffer = buffer->next(); | 4517 buffer = buffer->next(); |
| 4519 } | 4518 } |
| 4520 } | 4519 } |
| 4521 | 4520 |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4653 SlotsBuffer* buffer = *buffer_address; | 4652 SlotsBuffer* buffer = *buffer_address; |
| 4654 while (buffer != NULL) { | 4653 while (buffer != NULL) { |
| 4655 SlotsBuffer* next_buffer = buffer->next(); | 4654 SlotsBuffer* next_buffer = buffer->next(); |
| 4656 DeallocateBuffer(buffer); | 4655 DeallocateBuffer(buffer); |
| 4657 buffer = next_buffer; | 4656 buffer = next_buffer; |
| 4658 } | 4657 } |
| 4659 *buffer_address = NULL; | 4658 *buffer_address = NULL; |
| 4660 } | 4659 } |
| 4661 } // namespace internal | 4660 } // namespace internal |
| 4662 } // namespace v8 | 4661 } // namespace v8 |
| OLD | NEW |