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 2718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2729 | 2729 |
2730 if (compacting_ && dst->IsJSFunction()) { | 2730 if (compacting_ && dst->IsJSFunction()) { |
2731 Address code_entry_slot = dst_addr + JSFunction::kCodeEntryOffset; | 2731 Address code_entry_slot = dst_addr + JSFunction::kCodeEntryOffset; |
2732 Address code_entry = Memory::Address_at(code_entry_slot); | 2732 Address code_entry = Memory::Address_at(code_entry_slot); |
2733 | 2733 |
2734 if (Page::FromAddress(code_entry)->IsEvacuationCandidate()) { | 2734 if (Page::FromAddress(code_entry)->IsEvacuationCandidate()) { |
2735 SlotsBuffer::AddTo(&slots_buffer_allocator_, &migration_slots_buffer_, | 2735 SlotsBuffer::AddTo(&slots_buffer_allocator_, &migration_slots_buffer_, |
2736 SlotsBuffer::CODE_ENTRY_SLOT, code_entry_slot, | 2736 SlotsBuffer::CODE_ENTRY_SLOT, code_entry_slot, |
2737 SlotsBuffer::IGNORE_OVERFLOW); | 2737 SlotsBuffer::IGNORE_OVERFLOW); |
2738 } | 2738 } |
| 2739 } else if (dst->IsConstantPoolArray()) { |
| 2740 // We special case ConstantPoolArrays since they could contain integers |
| 2741 // value entries which look like tagged pointers. |
| 2742 // TODO(mstarzinger): restructure this code to avoid this special-casing. |
| 2743 ConstantPoolArray* array = ConstantPoolArray::cast(dst); |
| 2744 ConstantPoolArray::Iterator code_iter(array, ConstantPoolArray::CODE_PTR); |
| 2745 while (!code_iter.is_finished()) { |
| 2746 Address code_entry_slot = |
| 2747 dst_addr + array->OffsetOfElementAt(code_iter.next_index()); |
| 2748 Address code_entry = Memory::Address_at(code_entry_slot); |
| 2749 |
| 2750 if (Page::FromAddress(code_entry)->IsEvacuationCandidate()) { |
| 2751 SlotsBuffer::AddTo(&slots_buffer_allocator_, &migration_slots_buffer_, |
| 2752 SlotsBuffer::CODE_ENTRY_SLOT, code_entry_slot, |
| 2753 SlotsBuffer::IGNORE_OVERFLOW); |
| 2754 } |
| 2755 } |
| 2756 ConstantPoolArray::Iterator heap_iter(array, ConstantPoolArray::HEAP_PTR); |
| 2757 while (!heap_iter.is_finished()) { |
| 2758 Address heap_slot = |
| 2759 dst_addr + array->OffsetOfElementAt(heap_iter.next_index()); |
| 2760 Object* value = Memory::Object_at(heap_slot); |
| 2761 RecordMigratedSlot(value, heap_slot); |
| 2762 } |
2739 } | 2763 } |
2740 } else if (dest == CODE_SPACE) { | 2764 } else if (dest == CODE_SPACE) { |
2741 PROFILE(isolate(), CodeMoveEvent(src_addr, dst_addr)); | 2765 PROFILE(isolate(), CodeMoveEvent(src_addr, dst_addr)); |
2742 heap()->MoveBlock(dst_addr, src_addr, size); | 2766 heap()->MoveBlock(dst_addr, src_addr, size); |
2743 SlotsBuffer::AddTo(&slots_buffer_allocator_, &migration_slots_buffer_, | 2767 SlotsBuffer::AddTo(&slots_buffer_allocator_, &migration_slots_buffer_, |
2744 SlotsBuffer::RELOCATED_CODE_OBJECT, dst_addr, | 2768 SlotsBuffer::RELOCATED_CODE_OBJECT, dst_addr, |
2745 SlotsBuffer::IGNORE_OVERFLOW); | 2769 SlotsBuffer::IGNORE_OVERFLOW); |
2746 Code::cast(dst)->Relocate(dst_addr - src_addr); | 2770 Code::cast(dst)->Relocate(dst_addr - src_addr); |
2747 } else { | 2771 } else { |
2748 DCHECK(dest == NEW_SPACE); | 2772 DCHECK(dest == NEW_SPACE); |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3119 Page::FromAnyPointerAddress(heap_, slot)->owner() == | 3143 Page::FromAnyPointerAddress(heap_, slot)->owner() == |
3120 heap_->lo_space()); | 3144 heap_->lo_space()); |
3121 // We don't need to check large objects' layout descriptor since it can't | 3145 // We don't need to check large objects' layout descriptor since it can't |
3122 // contain in-object fields anyway. | 3146 // contain in-object fields anyway. |
3123 if (object != NULL) { | 3147 if (object != NULL) { |
3124 // TODO(ishell): This is a workaround for crbug/454297. We must not have | 3148 // TODO(ishell): This is a workaround for crbug/454297. We must not have |
3125 // slots in data objects at all. Remove this once we found the root cause. | 3149 // slots in data objects at all. Remove this once we found the root cause. |
3126 InstanceType type = object->map()->instance_type(); | 3150 InstanceType type = object->map()->instance_type(); |
3127 // Slots in maps and code can't be invalid because they are never shrunk. | 3151 // Slots in maps and code can't be invalid because they are never shrunk. |
3128 if (type == MAP_TYPE || type == CODE_TYPE) return true; | 3152 if (type == MAP_TYPE || type == CODE_TYPE) return true; |
| 3153 if (type == CONSTANT_POOL_ARRAY_TYPE) { |
| 3154 if (FLAG_enable_ool_constant_pool) { |
| 3155 // TODO(ishell): implement constant pool support if we ever enable it. |
| 3156 UNIMPLEMENTED(); |
| 3157 } else { |
| 3158 // This is left here just to make constant pool unit tests work. |
| 3159 return true; |
| 3160 } |
| 3161 } |
3129 // Consider slots in objects that contain ONLY raw data as invalid. | 3162 // Consider slots in objects that contain ONLY raw data as invalid. |
3130 if (object->MayContainRawValues()) return false; | 3163 if (object->MayContainRawValues()) return false; |
3131 if (FLAG_unbox_double_fields) { | 3164 if (FLAG_unbox_double_fields) { |
3132 // Filter out slots that happen to point to unboxed double fields. | 3165 // Filter out slots that happen to point to unboxed double fields. |
3133 LayoutDescriptorHelper helper(object->map()); | 3166 LayoutDescriptorHelper helper(object->map()); |
3134 bool has_only_tagged_fields = helper.all_fields_tagged(); | 3167 bool has_only_tagged_fields = helper.all_fields_tagged(); |
3135 if (!has_only_tagged_fields && | 3168 if (!has_only_tagged_fields && |
3136 !helper.IsTagged(static_cast<int>(slot - object->address()))) { | 3169 !helper.IsTagged(static_cast<int>(slot - object->address()))) { |
3137 return false; | 3170 return false; |
3138 } | 3171 } |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3344 case SlotsBuffer::JS_RETURN_SLOT: { | 3377 case SlotsBuffer::JS_RETURN_SLOT: { |
3345 RelocInfo rinfo(addr, RelocInfo::JS_RETURN, 0, NULL); | 3378 RelocInfo rinfo(addr, RelocInfo::JS_RETURN, 0, NULL); |
3346 if (rinfo.IsPatchedReturnSequence()) rinfo.Visit(isolate, v); | 3379 if (rinfo.IsPatchedReturnSequence()) rinfo.Visit(isolate, v); |
3347 break; | 3380 break; |
3348 } | 3381 } |
3349 case SlotsBuffer::EMBEDDED_OBJECT_SLOT: { | 3382 case SlotsBuffer::EMBEDDED_OBJECT_SLOT: { |
3350 RelocInfo rinfo(addr, RelocInfo::EMBEDDED_OBJECT, 0, NULL); | 3383 RelocInfo rinfo(addr, RelocInfo::EMBEDDED_OBJECT, 0, NULL); |
3351 rinfo.Visit(isolate, v); | 3384 rinfo.Visit(isolate, v); |
3352 break; | 3385 break; |
3353 } | 3386 } |
3354 case SlotsBuffer::OBJECT_SLOT: { | |
3355 v->VisitPointer(reinterpret_cast<Object**>(addr)); | |
3356 break; | |
3357 } | |
3358 default: | 3387 default: |
3359 UNREACHABLE(); | 3388 UNREACHABLE(); |
3360 break; | 3389 break; |
3361 } | 3390 } |
3362 } | 3391 } |
3363 | 3392 |
3364 | 3393 |
3365 enum SweepingMode { SWEEP_ONLY, SWEEP_AND_VISIT_LIVE_OBJECTS }; | 3394 enum SweepingMode { SWEEP_ONLY, SWEEP_AND_VISIT_LIVE_OBJECTS }; |
3366 | 3395 |
3367 | 3396 |
(...skipping 1149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4517 return SlotsBuffer::NUMBER_OF_SLOT_TYPES; | 4546 return SlotsBuffer::NUMBER_OF_SLOT_TYPES; |
4518 } | 4547 } |
4519 | 4548 |
4520 | 4549 |
4521 void MarkCompactCollector::RecordRelocSlot(RelocInfo* rinfo, Object* target) { | 4550 void MarkCompactCollector::RecordRelocSlot(RelocInfo* rinfo, Object* target) { |
4522 Page* target_page = Page::FromAddress(reinterpret_cast<Address>(target)); | 4551 Page* target_page = Page::FromAddress(reinterpret_cast<Address>(target)); |
4523 RelocInfo::Mode rmode = rinfo->rmode(); | 4552 RelocInfo::Mode rmode = rinfo->rmode(); |
4524 if (target_page->IsEvacuationCandidate() && | 4553 if (target_page->IsEvacuationCandidate() && |
4525 (rinfo->host() == NULL || | 4554 (rinfo->host() == NULL || |
4526 !ShouldSkipEvacuationSlotRecording(rinfo->host()))) { | 4555 !ShouldSkipEvacuationSlotRecording(rinfo->host()))) { |
4527 Address addr = rinfo->pc(); | |
4528 SlotsBuffer::SlotType slot_type = SlotTypeForRMode(rmode); | |
4529 if (rinfo->IsInConstantPool()) { | |
4530 addr = rinfo->constant_pool_entry_address(); | |
4531 if (RelocInfo::IsCodeTarget(rmode)) { | |
4532 slot_type = SlotsBuffer::CODE_ENTRY_SLOT; | |
4533 } else { | |
4534 DCHECK(RelocInfo::IsEmbeddedObject(rmode)); | |
4535 slot_type = SlotsBuffer::OBJECT_SLOT; | |
4536 } | |
4537 } | |
4538 bool success = SlotsBuffer::AddTo( | 4556 bool success = SlotsBuffer::AddTo( |
4539 &slots_buffer_allocator_, target_page->slots_buffer_address(), | 4557 &slots_buffer_allocator_, target_page->slots_buffer_address(), |
4540 slot_type, addr, SlotsBuffer::FAIL_ON_OVERFLOW); | 4558 SlotTypeForRMode(rmode), rinfo->pc(), SlotsBuffer::FAIL_ON_OVERFLOW); |
4541 if (!success) { | 4559 if (!success) { |
4542 EvictPopularEvacuationCandidate(target_page); | 4560 EvictPopularEvacuationCandidate(target_page); |
4543 } | 4561 } |
4544 } | 4562 } |
4545 } | 4563 } |
4546 | 4564 |
4547 | 4565 |
4548 void MarkCompactCollector::EvictPopularEvacuationCandidate(Page* page) { | 4566 void MarkCompactCollector::EvictPopularEvacuationCandidate(Page* page) { |
4549 if (FLAG_trace_fragmentation) { | 4567 if (FLAG_trace_fragmentation) { |
4550 PrintF("Page %p is too popular. Disabling evacuation.\n", | 4568 PrintF("Page %p is too popular. Disabling evacuation.\n", |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4656 SlotsBuffer* buffer = *buffer_address; | 4674 SlotsBuffer* buffer = *buffer_address; |
4657 while (buffer != NULL) { | 4675 while (buffer != NULL) { |
4658 SlotsBuffer* next_buffer = buffer->next(); | 4676 SlotsBuffer* next_buffer = buffer->next(); |
4659 DeallocateBuffer(buffer); | 4677 DeallocateBuffer(buffer); |
4660 buffer = next_buffer; | 4678 buffer = next_buffer; |
4661 } | 4679 } |
4662 *buffer_address = NULL; | 4680 *buffer_address = NULL; |
4663 } | 4681 } |
4664 } // namespace internal | 4682 } // namespace internal |
4665 } // namespace v8 | 4683 } // namespace v8 |
OLD | NEW |