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 2775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2786 if (heap_->InNewSpace(value)) { | 2786 if (heap_->InNewSpace(value)) { |
2787 heap_->store_buffer()->Mark(slot); | 2787 heap_->store_buffer()->Mark(slot); |
2788 } else if (value->IsHeapObject() && IsOnEvacuationCandidate(value)) { | 2788 } else if (value->IsHeapObject() && IsOnEvacuationCandidate(value)) { |
2789 SlotsBuffer::AddTo(&slots_buffer_allocator_, &migration_slots_buffer_, | 2789 SlotsBuffer::AddTo(&slots_buffer_allocator_, &migration_slots_buffer_, |
2790 reinterpret_cast<Object**>(slot), | 2790 reinterpret_cast<Object**>(slot), |
2791 SlotsBuffer::IGNORE_OVERFLOW); | 2791 SlotsBuffer::IGNORE_OVERFLOW); |
2792 } | 2792 } |
2793 } | 2793 } |
2794 | 2794 |
2795 | 2795 |
2796 void MarkCompactCollector::MigrateMixedObjectEpilog(HeapObject* dst) { | |
2797 DCHECK(dst->MayContainMixedValues()); | |
2798 Address dst_addr = dst->address(); | |
2799 if (compacting_ && dst->IsJSFunction()) { | |
2800 Address code_entry_slot = dst_addr + JSFunction::kCodeEntryOffset; | |
2801 Address code_entry = Memory::Address_at(code_entry_slot); | |
2802 | |
2803 if (Page::FromAddress(code_entry)->IsEvacuationCandidate()) { | |
2804 SlotsBuffer::AddTo(&slots_buffer_allocator_, &migration_slots_buffer_, | |
2805 SlotsBuffer::CODE_ENTRY_SLOT, code_entry_slot, | |
2806 SlotsBuffer::IGNORE_OVERFLOW); | |
2807 } | |
2808 } else if (dst->IsConstantPoolArray()) { | |
2809 // We special case ConstantPoolArrays since they could contain integers | |
2810 // value entries which look like tagged pointers. | |
2811 // TODO(mstarzinger): restructure this code to avoid this special-casing. | |
2812 ConstantPoolArray* array = ConstantPoolArray::cast(dst); | |
2813 ConstantPoolArray::Iterator code_iter(array, ConstantPoolArray::CODE_PTR); | |
2814 while (!code_iter.is_finished()) { | |
2815 Address code_entry_slot = | |
2816 dst_addr + array->OffsetOfElementAt(code_iter.next_index()); | |
2817 Address code_entry = Memory::Address_at(code_entry_slot); | |
2818 | |
2819 if (Page::FromAddress(code_entry)->IsEvacuationCandidate()) { | |
2820 SlotsBuffer::AddTo(&slots_buffer_allocator_, &migration_slots_buffer_, | |
2821 SlotsBuffer::CODE_ENTRY_SLOT, code_entry_slot, | |
2822 SlotsBuffer::IGNORE_OVERFLOW); | |
2823 } | |
2824 } | |
2825 ConstantPoolArray::Iterator heap_iter(array, ConstantPoolArray::HEAP_PTR); | |
2826 while (!heap_iter.is_finished()) { | |
2827 Address heap_slot = | |
2828 dst_addr + array->OffsetOfElementAt(heap_iter.next_index()); | |
2829 Object* value = Memory::Object_at(heap_slot); | |
2830 RecordMigratedSlot(value, heap_slot); | |
2831 } | |
2832 } | |
2833 } | |
2834 | |
2835 | |
2796 // We scavenge new space simultaneously with sweeping. This is done in two | 2836 // We scavenge new space simultaneously with sweeping. This is done in two |
2797 // passes. | 2837 // passes. |
2798 // | 2838 // |
2799 // The first pass migrates all alive objects from one semispace to another or | 2839 // The first pass migrates all alive objects from one semispace to another or |
2800 // promotes them to old space. Forwarding address is written directly into | 2840 // promotes them to old space. Forwarding address is written directly into |
2801 // first word of object without any encoding. If object is dead we write | 2841 // first word of object without any encoding. If object is dead we write |
2802 // NULL as a forwarding address. | 2842 // NULL as a forwarding address. |
2803 // | 2843 // |
2804 // The second pass updates pointers to new space in all spaces. It is possible | 2844 // The second pass updates pointers to new space in all spaces. It is possible |
2805 // to encounter pointers to dead new space objects during traversal of pointers | 2845 // to encounter pointers to dead new space objects during traversal of pointers |
(...skipping 15 matching lines...) Expand all Loading... | |
2821 bool may_contain_raw_values = src->MayContainRawValues(); | 2861 bool may_contain_raw_values = src->MayContainRawValues(); |
2822 #if V8_DOUBLE_FIELDS_UNBOXING | 2862 #if V8_DOUBLE_FIELDS_UNBOXING |
2823 LayoutDescriptorHelper helper(src->map()); | 2863 LayoutDescriptorHelper helper(src->map()); |
2824 bool has_only_tagged_fields = helper.all_fields_tagged(); | 2864 bool has_only_tagged_fields = helper.all_fields_tagged(); |
2825 #endif | 2865 #endif |
2826 for (int remaining = size / kPointerSize; remaining > 0; remaining--) { | 2866 for (int remaining = size / kPointerSize; remaining > 0; remaining--) { |
2827 Object* value = Memory::Object_at(src_slot); | 2867 Object* value = Memory::Object_at(src_slot); |
2828 | 2868 |
2829 Memory::Object_at(dst_slot) = value; | 2869 Memory::Object_at(dst_slot) = value; |
2830 | 2870 |
2831 #if V8_DOUBLE_FIELDS_UNBOXING | 2871 #if V8_DOUBLE_FIELDS_UNBOXING |
Hannes Payer (out of office)
2015/05/13 06:47:38
Double unboxing would also be part of mixed object
jochen (gone - plz use gerrit)
2015/05/13 06:51:45
yeah, but this isn't really an epilogue but the ac
Hannes Payer (out of office)
2015/05/13 12:12:36
Maybe it not really an Epilog, but more a HandleMi
Igor Sheludko
2015/05/13 12:22:59
yeah, we could have three versions of this moving
| |
2832 if (!may_contain_raw_values && | 2872 if (!may_contain_raw_values && |
2833 (has_only_tagged_fields || | 2873 (has_only_tagged_fields || |
2834 helper.IsTagged(static_cast<int>(src_slot - src_addr)))) | 2874 helper.IsTagged(static_cast<int>(src_slot - src_addr)))) |
2835 #else | 2875 #else |
2836 if (!may_contain_raw_values) | 2876 if (!may_contain_raw_values) |
2837 #endif | 2877 #endif |
2838 { | 2878 { |
2839 RecordMigratedSlot(value, dst_slot); | 2879 RecordMigratedSlot(value, dst_slot); |
2840 } | 2880 } |
2841 | 2881 |
2842 src_slot += kPointerSize; | 2882 src_slot += kPointerSize; |
2843 dst_slot += kPointerSize; | 2883 dst_slot += kPointerSize; |
2844 } | 2884 } |
2845 | 2885 if (dst->MayContainMixedValues()) MigrateMixedObjectEpilog(dst); |
Igor Sheludko
2015/05/13 12:22:59
Do we need MayContainMixedValues() at all given th
| |
2846 if (compacting_ && dst->IsJSFunction()) { | |
2847 Address code_entry_slot = dst_addr + JSFunction::kCodeEntryOffset; | |
2848 Address code_entry = Memory::Address_at(code_entry_slot); | |
2849 | |
2850 if (Page::FromAddress(code_entry)->IsEvacuationCandidate()) { | |
2851 SlotsBuffer::AddTo(&slots_buffer_allocator_, &migration_slots_buffer_, | |
2852 SlotsBuffer::CODE_ENTRY_SLOT, code_entry_slot, | |
2853 SlotsBuffer::IGNORE_OVERFLOW); | |
2854 } | |
2855 } else if (dst->IsConstantPoolArray()) { | |
2856 // We special case ConstantPoolArrays since they could contain integers | |
2857 // value entries which look like tagged pointers. | |
2858 // TODO(mstarzinger): restructure this code to avoid this special-casing. | |
2859 ConstantPoolArray* array = ConstantPoolArray::cast(dst); | |
2860 ConstantPoolArray::Iterator code_iter(array, ConstantPoolArray::CODE_PTR); | |
2861 while (!code_iter.is_finished()) { | |
2862 Address code_entry_slot = | |
2863 dst_addr + array->OffsetOfElementAt(code_iter.next_index()); | |
2864 Address code_entry = Memory::Address_at(code_entry_slot); | |
2865 | |
2866 if (Page::FromAddress(code_entry)->IsEvacuationCandidate()) { | |
2867 SlotsBuffer::AddTo(&slots_buffer_allocator_, &migration_slots_buffer_, | |
2868 SlotsBuffer::CODE_ENTRY_SLOT, code_entry_slot, | |
2869 SlotsBuffer::IGNORE_OVERFLOW); | |
2870 } | |
2871 } | |
2872 ConstantPoolArray::Iterator heap_iter(array, ConstantPoolArray::HEAP_PTR); | |
2873 while (!heap_iter.is_finished()) { | |
2874 Address heap_slot = | |
2875 dst_addr + array->OffsetOfElementAt(heap_iter.next_index()); | |
2876 Object* value = Memory::Object_at(heap_slot); | |
2877 RecordMigratedSlot(value, heap_slot); | |
2878 } | |
2879 } | |
2880 } else if (dest == CODE_SPACE) { | 2886 } else if (dest == CODE_SPACE) { |
2881 PROFILE(isolate(), CodeMoveEvent(src_addr, dst_addr)); | 2887 PROFILE(isolate(), CodeMoveEvent(src_addr, dst_addr)); |
2882 heap()->MoveBlock(dst_addr, src_addr, size); | 2888 heap()->MoveBlock(dst_addr, src_addr, size); |
2883 SlotsBuffer::AddTo(&slots_buffer_allocator_, &migration_slots_buffer_, | 2889 SlotsBuffer::AddTo(&slots_buffer_allocator_, &migration_slots_buffer_, |
2884 SlotsBuffer::RELOCATED_CODE_OBJECT, dst_addr, | 2890 SlotsBuffer::RELOCATED_CODE_OBJECT, dst_addr, |
2885 SlotsBuffer::IGNORE_OVERFLOW); | 2891 SlotsBuffer::IGNORE_OVERFLOW); |
2886 Code::cast(dst)->Relocate(dst_addr - src_addr); | 2892 Code::cast(dst)->Relocate(dst_addr - src_addr); |
2887 } else { | 2893 } else { |
2888 DCHECK(dest == NEW_SPACE); | 2894 DCHECK(dest == NEW_SPACE); |
2889 heap()->MoveBlock(dst_addr, src_addr, size); | 2895 heap()->MoveBlock(dst_addr, src_addr, size); |
2896 if (dst->MayContainMixedValues()) { | |
2897 heap()->MigrateMixedObjectInNewSpaceEpilog(dst); | |
2898 } | |
2890 } | 2899 } |
2891 heap()->OnMoveEvent(dst, src, size); | 2900 heap()->OnMoveEvent(dst, src, size); |
2892 Memory::Address_at(src_addr) = dst_addr; | 2901 Memory::Address_at(src_addr) = dst_addr; |
2893 } | 2902 } |
2894 | 2903 |
2895 | 2904 |
2896 // Visitor for updating pointers from live objects in old spaces to new space. | 2905 // Visitor for updating pointers from live objects in old spaces to new space. |
2897 // It does not expect to encounter pointers to dead objects. | 2906 // It does not expect to encounter pointers to dead objects. |
2898 class PointersUpdatingVisitor : public ObjectVisitor { | 2907 class PointersUpdatingVisitor : public ObjectVisitor { |
2899 public: | 2908 public: |
(...skipping 1882 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4782 SlotsBuffer* buffer = *buffer_address; | 4791 SlotsBuffer* buffer = *buffer_address; |
4783 while (buffer != NULL) { | 4792 while (buffer != NULL) { |
4784 SlotsBuffer* next_buffer = buffer->next(); | 4793 SlotsBuffer* next_buffer = buffer->next(); |
4785 DeallocateBuffer(buffer); | 4794 DeallocateBuffer(buffer); |
4786 buffer = next_buffer; | 4795 buffer = next_buffer; |
4787 } | 4796 } |
4788 *buffer_address = NULL; | 4797 *buffer_address = NULL; |
4789 } | 4798 } |
4790 } | 4799 } |
4791 } // namespace v8::internal | 4800 } // namespace v8::internal |
OLD | NEW |