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 3042 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3053 heap()->IncrementPromotedObjectsSize(object_size); | 3053 heap()->IncrementPromotedObjectsSize(object_size); |
3054 return true; | 3054 return true; |
3055 } | 3055 } |
3056 | 3056 |
3057 return false; | 3057 return false; |
3058 } | 3058 } |
3059 | 3059 |
3060 | 3060 |
3061 bool MarkCompactCollector::IsSlotInBlackObject(Page* p, Address slot, | 3061 bool MarkCompactCollector::IsSlotInBlackObject(Page* p, Address slot, |
3062 HeapObject** out_object) { | 3062 HeapObject** out_object) { |
3063 // This function does not support large objects right now. | |
3064 Space* owner = p->owner(); | 3063 Space* owner = p->owner(); |
3065 if (owner == heap_->lo_space() || owner == NULL) { | 3064 if (owner == heap_->lo_space() || owner == NULL) { |
3066 *out_object = NULL; | 3065 Object* large_object = heap_->lo_space()->FindObject(slot); |
3067 return true; | 3066 // This object has to exist, otherwise we would not have recorded a slot |
| 3067 // for it. |
| 3068 CHECK(large_object->IsHeapObject()); |
| 3069 HeapObject* large_heap_object = HeapObject::cast(large_object); |
| 3070 if (IsMarked(large_heap_object)) { |
| 3071 *out_object = large_heap_object; |
| 3072 return true; |
| 3073 } |
| 3074 return false; |
3068 } | 3075 } |
3069 | 3076 |
3070 uint32_t mark_bit_index = p->AddressToMarkbitIndex(slot); | 3077 uint32_t mark_bit_index = p->AddressToMarkbitIndex(slot); |
3071 unsigned int start_index = mark_bit_index >> Bitmap::kBitsPerCellLog2; | 3078 unsigned int start_index = mark_bit_index >> Bitmap::kBitsPerCellLog2; |
3072 MarkBit::CellType index_in_cell = 1U | 3079 MarkBit::CellType index_in_cell = 1U |
3073 << (mark_bit_index & Bitmap::kBitIndexMask); | 3080 << (mark_bit_index & Bitmap::kBitIndexMask); |
3074 MarkBit::CellType* cells = p->markbits()->cells(); | 3081 MarkBit::CellType* cells = p->markbits()->cells(); |
3075 Address cell_base = p->area_start(); | 3082 Address cell_base = p->area_start(); |
3076 unsigned int cell_base_start_index = Bitmap::IndexToCell( | 3083 unsigned int cell_base_start_index = Bitmap::IndexToCell( |
3077 Bitmap::CellAlignIndex(p->AddressToMarkbitIndex(cell_base))); | 3084 Bitmap::CellAlignIndex(p->AddressToMarkbitIndex(cell_base))); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3174 | 3181 |
3175 bool MarkCompactCollector::IsSlotInLiveObject(Address slot) { | 3182 bool MarkCompactCollector::IsSlotInLiveObject(Address slot) { |
3176 HeapObject* object = NULL; | 3183 HeapObject* object = NULL; |
3177 // The target object is black but we don't know if the source slot is black. | 3184 // The target object is black but we don't know if the source slot is black. |
3178 // The source object could have died and the slot could be part of a free | 3185 // The source object could have died and the slot could be part of a free |
3179 // space. Find out based on mark bits if the slot is part of a live object. | 3186 // space. Find out based on mark bits if the slot is part of a live object. |
3180 if (!IsSlotInBlackObject(Page::FromAddress(slot), slot, &object)) { | 3187 if (!IsSlotInBlackObject(Page::FromAddress(slot), slot, &object)) { |
3181 return false; | 3188 return false; |
3182 } | 3189 } |
3183 | 3190 |
3184 // |object| is NULL only when the slot belongs to large object space. | 3191 DCHECK(object != NULL); |
3185 DCHECK(object != NULL || | 3192 |
3186 Page::FromAnyPointerAddress(heap_, slot)->owner() == | |
3187 heap_->lo_space()); | |
3188 // We don't need to check large objects' layout descriptor since it can't | |
3189 // contain in-object fields anyway. | |
3190 if (object != NULL) { | |
3191 switch (object->ContentType()) { | 3193 switch (object->ContentType()) { |
3192 case HeapObjectContents::kTaggedValues: | 3194 case HeapObjectContents::kTaggedValues: |
3193 return true; | 3195 return true; |
3194 | 3196 |
3195 case HeapObjectContents::kRawValues: { | 3197 case HeapObjectContents::kRawValues: { |
3196 InstanceType type = object->map()->instance_type(); | 3198 InstanceType type = object->map()->instance_type(); |
3197 // Slots in maps and code can't be invalid because they are never | 3199 // Slots in maps and code can't be invalid because they are never |
3198 // shrunk. | 3200 // shrunk. |
3199 if (type == MAP_TYPE || type == CODE_TYPE) return true; | 3201 if (type == MAP_TYPE || type == CODE_TYPE) return true; |
3200 | 3202 |
3201 // Consider slots in objects that contain ONLY raw data as invalid. | 3203 // Consider slots in objects that contain ONLY raw data as invalid. |
3202 return false; | 3204 return false; |
3203 } | 3205 } |
3204 | 3206 |
3205 case HeapObjectContents::kMixedValues: { | 3207 case HeapObjectContents::kMixedValues: { |
3206 if (object->IsFixedTypedArrayBase()) { | 3208 if (object->IsFixedTypedArrayBase()) { |
3207 return static_cast<int>(slot - object->address()) == | 3209 return static_cast<int>(slot - object->address()) == |
3208 FixedTypedArrayBase::kBasePointerOffset; | 3210 FixedTypedArrayBase::kBasePointerOffset; |
3209 } else if (FLAG_unbox_double_fields) { | 3211 } else if (FLAG_unbox_double_fields) { |
3210 // Filter out slots that happen to point to unboxed double fields. | 3212 // Filter out slots that happen to point to unboxed double fields. |
3211 LayoutDescriptorHelper helper(object->map()); | 3213 LayoutDescriptorHelper helper(object->map()); |
3212 DCHECK(!helper.all_fields_tagged()); | 3214 DCHECK(!helper.all_fields_tagged()); |
3213 return helper.IsTagged(static_cast<int>(slot - object->address())); | 3215 return helper.IsTagged(static_cast<int>(slot - object->address())); |
3214 } | 3216 } |
3215 break; | 3217 break; |
3216 } | 3218 } |
3217 } | 3219 } |
3218 UNREACHABLE(); | 3220 UNREACHABLE(); |
3219 } | 3221 return true; |
3220 | |
3221 return true; | |
3222 } | 3222 } |
3223 | 3223 |
3224 | 3224 |
3225 void MarkCompactCollector::VerifyIsSlotInLiveObject(Address slot, | 3225 void MarkCompactCollector::VerifyIsSlotInLiveObject(Address slot, |
3226 HeapObject* object) { | 3226 HeapObject* object) { |
3227 // The target object has to be black. | 3227 // The target object has to be black. |
3228 CHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); | 3228 CHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); |
3229 | 3229 |
3230 // The target object is black but we don't know if the source slot is black. | 3230 // The target object is black but we don't know if the source slot is black. |
3231 // The source object could have died and the slot could be part of a free | 3231 // The source object could have died and the slot could be part of a free |
(...skipping 1517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4749 SlotsBuffer* buffer = *buffer_address; | 4749 SlotsBuffer* buffer = *buffer_address; |
4750 while (buffer != NULL) { | 4750 while (buffer != NULL) { |
4751 SlotsBuffer* next_buffer = buffer->next(); | 4751 SlotsBuffer* next_buffer = buffer->next(); |
4752 DeallocateBuffer(buffer); | 4752 DeallocateBuffer(buffer); |
4753 buffer = next_buffer; | 4753 buffer = next_buffer; |
4754 } | 4754 } |
4755 *buffer_address = NULL; | 4755 *buffer_address = NULL; |
4756 } | 4756 } |
4757 } // namespace internal | 4757 } // namespace internal |
4758 } // namespace v8 | 4758 } // namespace v8 |
OLD | NEW |