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 } | |
2763 } | 2739 } |
2764 } else if (dest == CODE_SPACE) { | 2740 } else if (dest == CODE_SPACE) { |
2765 PROFILE(isolate(), CodeMoveEvent(src_addr, dst_addr)); | 2741 PROFILE(isolate(), CodeMoveEvent(src_addr, dst_addr)); |
2766 heap()->MoveBlock(dst_addr, src_addr, size); | 2742 heap()->MoveBlock(dst_addr, src_addr, size); |
2767 SlotsBuffer::AddTo(&slots_buffer_allocator_, &migration_slots_buffer_, | 2743 SlotsBuffer::AddTo(&slots_buffer_allocator_, &migration_slots_buffer_, |
2768 SlotsBuffer::RELOCATED_CODE_OBJECT, dst_addr, | 2744 SlotsBuffer::RELOCATED_CODE_OBJECT, dst_addr, |
2769 SlotsBuffer::IGNORE_OVERFLOW); | 2745 SlotsBuffer::IGNORE_OVERFLOW); |
2770 Code::cast(dst)->Relocate(dst_addr - src_addr); | 2746 Code::cast(dst)->Relocate(dst_addr - src_addr); |
2771 } else { | 2747 } else { |
2772 DCHECK(dest == NEW_SPACE); | 2748 DCHECK(dest == NEW_SPACE); |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3143 Page::FromAnyPointerAddress(heap_, slot)->owner() == | 3119 Page::FromAnyPointerAddress(heap_, slot)->owner() == |
3144 heap_->lo_space()); | 3120 heap_->lo_space()); |
3145 // We don't need to check large objects' layout descriptor since it can't | 3121 // We don't need to check large objects' layout descriptor since it can't |
3146 // contain in-object fields anyway. | 3122 // contain in-object fields anyway. |
3147 if (object != NULL) { | 3123 if (object != NULL) { |
3148 // TODO(ishell): This is a workaround for crbug/454297. We must not have | 3124 // TODO(ishell): This is a workaround for crbug/454297. We must not have |
3149 // slots in data objects at all. Remove this once we found the root cause. | 3125 // slots in data objects at all. Remove this once we found the root cause. |
3150 InstanceType type = object->map()->instance_type(); | 3126 InstanceType type = object->map()->instance_type(); |
3151 // Slots in maps and code can't be invalid because they are never shrunk. | 3127 // Slots in maps and code can't be invalid because they are never shrunk. |
3152 if (type == MAP_TYPE || type == CODE_TYPE) return true; | 3128 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 } | |
3162 // Consider slots in objects that contain ONLY raw data as invalid. | 3129 // Consider slots in objects that contain ONLY raw data as invalid. |
3163 if (object->MayContainRawValues()) return false; | 3130 if (object->MayContainRawValues()) return false; |
3164 if (FLAG_unbox_double_fields) { | 3131 if (FLAG_unbox_double_fields) { |
3165 // Filter out slots that happen to point to unboxed double fields. | 3132 // Filter out slots that happen to point to unboxed double fields. |
3166 LayoutDescriptorHelper helper(object->map()); | 3133 LayoutDescriptorHelper helper(object->map()); |
3167 bool has_only_tagged_fields = helper.all_fields_tagged(); | 3134 bool has_only_tagged_fields = helper.all_fields_tagged(); |
3168 if (!has_only_tagged_fields && | 3135 if (!has_only_tagged_fields && |
3169 !helper.IsTagged(static_cast<int>(slot - object->address()))) { | 3136 !helper.IsTagged(static_cast<int>(slot - object->address()))) { |
3170 return false; | 3137 return false; |
3171 } | 3138 } |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3377 case SlotsBuffer::JS_RETURN_SLOT: { | 3344 case SlotsBuffer::JS_RETURN_SLOT: { |
3378 RelocInfo rinfo(addr, RelocInfo::JS_RETURN, 0, NULL); | 3345 RelocInfo rinfo(addr, RelocInfo::JS_RETURN, 0, NULL); |
3379 if (rinfo.IsPatchedReturnSequence()) rinfo.Visit(isolate, v); | 3346 if (rinfo.IsPatchedReturnSequence()) rinfo.Visit(isolate, v); |
3380 break; | 3347 break; |
3381 } | 3348 } |
3382 case SlotsBuffer::EMBEDDED_OBJECT_SLOT: { | 3349 case SlotsBuffer::EMBEDDED_OBJECT_SLOT: { |
3383 RelocInfo rinfo(addr, RelocInfo::EMBEDDED_OBJECT, 0, NULL); | 3350 RelocInfo rinfo(addr, RelocInfo::EMBEDDED_OBJECT, 0, NULL); |
3384 rinfo.Visit(isolate, v); | 3351 rinfo.Visit(isolate, v); |
3385 break; | 3352 break; |
3386 } | 3353 } |
| 3354 case SlotsBuffer::OBJECT_SLOT: { |
| 3355 v->VisitPointer(reinterpret_cast<Object**>(addr)); |
| 3356 break; |
| 3357 } |
3387 default: | 3358 default: |
3388 UNREACHABLE(); | 3359 UNREACHABLE(); |
3389 break; | 3360 break; |
3390 } | 3361 } |
3391 } | 3362 } |
3392 | 3363 |
3393 | 3364 |
3394 enum SweepingMode { SWEEP_ONLY, SWEEP_AND_VISIT_LIVE_OBJECTS }; | 3365 enum SweepingMode { SWEEP_ONLY, SWEEP_AND_VISIT_LIVE_OBJECTS }; |
3395 | 3366 |
3396 | 3367 |
(...skipping 1149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4546 return SlotsBuffer::NUMBER_OF_SLOT_TYPES; | 4517 return SlotsBuffer::NUMBER_OF_SLOT_TYPES; |
4547 } | 4518 } |
4548 | 4519 |
4549 | 4520 |
4550 void MarkCompactCollector::RecordRelocSlot(RelocInfo* rinfo, Object* target) { | 4521 void MarkCompactCollector::RecordRelocSlot(RelocInfo* rinfo, Object* target) { |
4551 Page* target_page = Page::FromAddress(reinterpret_cast<Address>(target)); | 4522 Page* target_page = Page::FromAddress(reinterpret_cast<Address>(target)); |
4552 RelocInfo::Mode rmode = rinfo->rmode(); | 4523 RelocInfo::Mode rmode = rinfo->rmode(); |
4553 if (target_page->IsEvacuationCandidate() && | 4524 if (target_page->IsEvacuationCandidate() && |
4554 (rinfo->host() == NULL || | 4525 (rinfo->host() == NULL || |
4555 !ShouldSkipEvacuationSlotRecording(rinfo->host()))) { | 4526 !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 } |
4556 bool success = SlotsBuffer::AddTo( | 4538 bool success = SlotsBuffer::AddTo( |
4557 &slots_buffer_allocator_, target_page->slots_buffer_address(), | 4539 &slots_buffer_allocator_, target_page->slots_buffer_address(), |
4558 SlotTypeForRMode(rmode), rinfo->pc(), SlotsBuffer::FAIL_ON_OVERFLOW); | 4540 slot_type, addr, SlotsBuffer::FAIL_ON_OVERFLOW); |
4559 if (!success) { | 4541 if (!success) { |
4560 EvictPopularEvacuationCandidate(target_page); | 4542 EvictPopularEvacuationCandidate(target_page); |
4561 } | 4543 } |
4562 } | 4544 } |
4563 } | 4545 } |
4564 | 4546 |
4565 | 4547 |
4566 void MarkCompactCollector::EvictPopularEvacuationCandidate(Page* page) { | 4548 void MarkCompactCollector::EvictPopularEvacuationCandidate(Page* page) { |
4567 if (FLAG_trace_fragmentation) { | 4549 if (FLAG_trace_fragmentation) { |
4568 PrintF("Page %p is too popular. Disabling evacuation.\n", | 4550 PrintF("Page %p is too popular. Disabling evacuation.\n", |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4674 SlotsBuffer* buffer = *buffer_address; | 4656 SlotsBuffer* buffer = *buffer_address; |
4675 while (buffer != NULL) { | 4657 while (buffer != NULL) { |
4676 SlotsBuffer* next_buffer = buffer->next(); | 4658 SlotsBuffer* next_buffer = buffer->next(); |
4677 DeallocateBuffer(buffer); | 4659 DeallocateBuffer(buffer); |
4678 buffer = next_buffer; | 4660 buffer = next_buffer; |
4679 } | 4661 } |
4680 *buffer_address = NULL; | 4662 *buffer_address = NULL; |
4681 } | 4663 } |
4682 } // namespace internal | 4664 } // namespace internal |
4683 } // namespace v8 | 4665 } // namespace v8 |
OLD | NEW |