OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 2058 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2069 // Shouldn't happen. We are sweeping linearly, and to-space | 2069 // Shouldn't happen. We are sweeping linearly, and to-space |
2070 // has the same number of pages as from-space, so there is | 2070 // has the same number of pages as from-space, so there is |
2071 // always room. | 2071 // always room. |
2072 UNREACHABLE(); | 2072 UNREACHABLE(); |
2073 } | 2073 } |
2074 allocation = new_space->AllocateRaw(size); | 2074 allocation = new_space->AllocateRaw(size); |
2075 ASSERT(!allocation->IsFailure()); | 2075 ASSERT(!allocation->IsFailure()); |
2076 } | 2076 } |
2077 Object* target = allocation->ToObjectUnchecked(); | 2077 Object* target = allocation->ToObjectUnchecked(); |
2078 | 2078 |
2079 MigrateObject(HeapObject::cast(target)->address(), | 2079 MigrateObject(HeapObject::cast(target), |
2080 object->address(), | 2080 object, |
2081 size, | 2081 size, |
2082 NEW_SPACE); | 2082 NEW_SPACE); |
2083 } | 2083 } |
2084 *cells = 0; | 2084 *cells = 0; |
2085 } | 2085 } |
2086 return survivors_size; | 2086 return survivors_size; |
2087 } | 2087 } |
2088 | 2088 |
2089 | 2089 |
2090 static void DiscoverGreyObjectsInSpace(Heap* heap, | 2090 static void DiscoverGreyObjectsInSpace(Heap* heap, |
(...skipping 721 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2812 // promotes them to old space. Forwarding address is written directly into | 2812 // promotes them to old space. Forwarding address is written directly into |
2813 // first word of object without any encoding. If object is dead we write | 2813 // first word of object without any encoding. If object is dead we write |
2814 // NULL as a forwarding address. | 2814 // NULL as a forwarding address. |
2815 // | 2815 // |
2816 // The second pass updates pointers to new space in all spaces. It is possible | 2816 // The second pass updates pointers to new space in all spaces. It is possible |
2817 // to encounter pointers to dead new space objects during traversal of pointers | 2817 // to encounter pointers to dead new space objects during traversal of pointers |
2818 // to new space. We should clear them to avoid encountering them during next | 2818 // to new space. We should clear them to avoid encountering them during next |
2819 // pointer iteration. This is an issue if the store buffer overflows and we | 2819 // pointer iteration. This is an issue if the store buffer overflows and we |
2820 // have to scan the entire old space, including dead objects, looking for | 2820 // have to scan the entire old space, including dead objects, looking for |
2821 // pointers to new space. | 2821 // pointers to new space. |
2822 void MarkCompactCollector::MigrateObject(Address dst, | 2822 void MarkCompactCollector::MigrateObject(HeapObject* dst, |
2823 Address src, | 2823 HeapObject* src, |
2824 int size, | 2824 int size, |
2825 AllocationSpace dest) { | 2825 AllocationSpace dest) { |
| 2826 Address dst_addr = dst->address(); |
| 2827 Address src_addr = src->address(); |
2826 HeapProfiler* heap_profiler = heap()->isolate()->heap_profiler(); | 2828 HeapProfiler* heap_profiler = heap()->isolate()->heap_profiler(); |
2827 if (heap_profiler->is_tracking_object_moves()) { | 2829 if (heap_profiler->is_tracking_object_moves()) { |
2828 heap_profiler->ObjectMoveEvent(src, dst, size); | 2830 heap_profiler->ObjectMoveEvent(src_addr, dst_addr, size); |
2829 } | 2831 } |
2830 ASSERT(heap()->AllowedToBeMigrated(HeapObject::FromAddress(src), dest)); | 2832 ASSERT(heap()->AllowedToBeMigrated(src, dest)); |
2831 ASSERT(dest != LO_SPACE && size <= Page::kMaxRegularHeapObjectSize); | 2833 ASSERT(dest != LO_SPACE && size <= Page::kMaxRegularHeapObjectSize); |
2832 if (dest == OLD_POINTER_SPACE) { | 2834 if (dest == OLD_POINTER_SPACE) { |
2833 Address src_slot = src; | 2835 Address src_slot = src_addr; |
2834 Address dst_slot = dst; | 2836 Address dst_slot = dst_addr; |
2835 ASSERT(IsAligned(size, kPointerSize)); | 2837 ASSERT(IsAligned(size, kPointerSize)); |
2836 | 2838 |
2837 for (int remaining = size / kPointerSize; remaining > 0; remaining--) { | 2839 for (int remaining = size / kPointerSize; remaining > 0; remaining--) { |
2838 Object* value = Memory::Object_at(src_slot); | 2840 Object* value = Memory::Object_at(src_slot); |
2839 | 2841 |
2840 Memory::Object_at(dst_slot) = value; | 2842 Memory::Object_at(dst_slot) = value; |
2841 | 2843 |
2842 if (heap_->InNewSpace(value)) { | 2844 if (heap_->InNewSpace(value)) { |
2843 heap_->store_buffer()->Mark(dst_slot); | 2845 heap_->store_buffer()->Mark(dst_slot); |
2844 } else if (value->IsHeapObject() && IsOnEvacuationCandidate(value)) { | 2846 } else if (value->IsHeapObject() && IsOnEvacuationCandidate(value)) { |
2845 SlotsBuffer::AddTo(&slots_buffer_allocator_, | 2847 SlotsBuffer::AddTo(&slots_buffer_allocator_, |
2846 &migration_slots_buffer_, | 2848 &migration_slots_buffer_, |
2847 reinterpret_cast<Object**>(dst_slot), | 2849 reinterpret_cast<Object**>(dst_slot), |
2848 SlotsBuffer::IGNORE_OVERFLOW); | 2850 SlotsBuffer::IGNORE_OVERFLOW); |
2849 } | 2851 } |
2850 | 2852 |
2851 src_slot += kPointerSize; | 2853 src_slot += kPointerSize; |
2852 dst_slot += kPointerSize; | 2854 dst_slot += kPointerSize; |
2853 } | 2855 } |
2854 | 2856 |
2855 if (compacting_ && HeapObject::FromAddress(dst)->IsJSFunction()) { | 2857 if (compacting_ && dst->IsJSFunction()) { |
2856 Address code_entry_slot = dst + JSFunction::kCodeEntryOffset; | 2858 Address code_entry_slot = dst_addr + JSFunction::kCodeEntryOffset; |
2857 Address code_entry = Memory::Address_at(code_entry_slot); | 2859 Address code_entry = Memory::Address_at(code_entry_slot); |
2858 | 2860 |
2859 if (Page::FromAddress(code_entry)->IsEvacuationCandidate()) { | 2861 if (Page::FromAddress(code_entry)->IsEvacuationCandidate()) { |
2860 SlotsBuffer::AddTo(&slots_buffer_allocator_, | 2862 SlotsBuffer::AddTo(&slots_buffer_allocator_, |
2861 &migration_slots_buffer_, | 2863 &migration_slots_buffer_, |
2862 SlotsBuffer::CODE_ENTRY_SLOT, | 2864 SlotsBuffer::CODE_ENTRY_SLOT, |
2863 code_entry_slot, | 2865 code_entry_slot, |
2864 SlotsBuffer::IGNORE_OVERFLOW); | 2866 SlotsBuffer::IGNORE_OVERFLOW); |
2865 } | 2867 } |
| 2868 } else if (compacting_ && dst->IsConstantPoolArray()) { |
| 2869 ConstantPoolArray* constant_pool = ConstantPoolArray::cast(dst); |
| 2870 for (int i = 0; i < constant_pool->count_of_code_ptr_entries(); i++) { |
| 2871 Address code_entry_slot = |
| 2872 dst_addr + constant_pool->OffsetOfElementAt(i); |
| 2873 Address code_entry = Memory::Address_at(code_entry_slot); |
| 2874 |
| 2875 if (Page::FromAddress(code_entry)->IsEvacuationCandidate()) { |
| 2876 SlotsBuffer::AddTo(&slots_buffer_allocator_, |
| 2877 &migration_slots_buffer_, |
| 2878 SlotsBuffer::CODE_ENTRY_SLOT, |
| 2879 code_entry_slot, |
| 2880 SlotsBuffer::IGNORE_OVERFLOW); |
| 2881 } |
| 2882 } |
2866 } | 2883 } |
2867 } else if (dest == CODE_SPACE) { | 2884 } else if (dest == CODE_SPACE) { |
2868 PROFILE(isolate(), CodeMoveEvent(src, dst)); | 2885 PROFILE(isolate(), CodeMoveEvent(src_addr, dst_addr)); |
2869 heap()->MoveBlock(dst, src, size); | 2886 heap()->MoveBlock(dst_addr, src_addr, size); |
2870 SlotsBuffer::AddTo(&slots_buffer_allocator_, | 2887 SlotsBuffer::AddTo(&slots_buffer_allocator_, |
2871 &migration_slots_buffer_, | 2888 &migration_slots_buffer_, |
2872 SlotsBuffer::RELOCATED_CODE_OBJECT, | 2889 SlotsBuffer::RELOCATED_CODE_OBJECT, |
2873 dst, | 2890 dst_addr, |
2874 SlotsBuffer::IGNORE_OVERFLOW); | 2891 SlotsBuffer::IGNORE_OVERFLOW); |
2875 Code::cast(HeapObject::FromAddress(dst))->Relocate(dst - src); | 2892 Code::cast(dst)->Relocate(dst_addr - src_addr); |
2876 } else { | 2893 } else { |
2877 ASSERT(dest == OLD_DATA_SPACE || dest == NEW_SPACE); | 2894 ASSERT(dest == OLD_DATA_SPACE || dest == NEW_SPACE); |
2878 heap()->MoveBlock(dst, src, size); | 2895 heap()->MoveBlock(dst_addr, src_addr, size); |
2879 } | 2896 } |
2880 Memory::Address_at(src) = dst; | 2897 Memory::Address_at(src_addr) = dst_addr; |
2881 } | 2898 } |
2882 | 2899 |
2883 | 2900 |
2884 // Visitor for updating pointers from live objects in old spaces to new space. | 2901 // Visitor for updating pointers from live objects in old spaces to new space. |
2885 // It does not expect to encounter pointers to dead objects. | 2902 // It does not expect to encounter pointers to dead objects. |
2886 class PointersUpdatingVisitor: public ObjectVisitor { | 2903 class PointersUpdatingVisitor: public ObjectVisitor { |
2887 public: | 2904 public: |
2888 explicit PointersUpdatingVisitor(Heap* heap) : heap_(heap) { } | 2905 explicit PointersUpdatingVisitor(Heap* heap) : heap_(heap) { } |
2889 | 2906 |
2890 void VisitPointer(Object** p) { | 2907 void VisitPointer(Object** p) { |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3005 CHECK(object_size <= Page::kMaxRegularHeapObjectSize); | 3022 CHECK(object_size <= Page::kMaxRegularHeapObjectSize); |
3006 | 3023 |
3007 OldSpace* target_space = heap()->TargetSpace(object); | 3024 OldSpace* target_space = heap()->TargetSpace(object); |
3008 | 3025 |
3009 ASSERT(target_space == heap()->old_pointer_space() || | 3026 ASSERT(target_space == heap()->old_pointer_space() || |
3010 target_space == heap()->old_data_space()); | 3027 target_space == heap()->old_data_space()); |
3011 Object* result; | 3028 Object* result; |
3012 MaybeObject* maybe_result = target_space->AllocateRaw(object_size); | 3029 MaybeObject* maybe_result = target_space->AllocateRaw(object_size); |
3013 if (maybe_result->ToObject(&result)) { | 3030 if (maybe_result->ToObject(&result)) { |
3014 HeapObject* target = HeapObject::cast(result); | 3031 HeapObject* target = HeapObject::cast(result); |
3015 MigrateObject(target->address(), | 3032 MigrateObject(target, |
3016 object->address(), | 3033 object, |
3017 object_size, | 3034 object_size, |
3018 target_space->identity()); | 3035 target_space->identity()); |
3019 heap()->mark_compact_collector()->tracer()-> | 3036 heap()->mark_compact_collector()->tracer()-> |
3020 increment_promoted_objects_size(object_size); | 3037 increment_promoted_objects_size(object_size); |
3021 return true; | 3038 return true; |
3022 } | 3039 } |
3023 | 3040 |
3024 return false; | 3041 return false; |
3025 } | 3042 } |
3026 | 3043 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3084 | 3101 |
3085 MaybeObject* target = space->AllocateRaw(size); | 3102 MaybeObject* target = space->AllocateRaw(size); |
3086 if (target->IsFailure()) { | 3103 if (target->IsFailure()) { |
3087 // OS refused to give us memory. | 3104 // OS refused to give us memory. |
3088 V8::FatalProcessOutOfMemory("Evacuation"); | 3105 V8::FatalProcessOutOfMemory("Evacuation"); |
3089 return; | 3106 return; |
3090 } | 3107 } |
3091 | 3108 |
3092 Object* target_object = target->ToObjectUnchecked(); | 3109 Object* target_object = target->ToObjectUnchecked(); |
3093 | 3110 |
3094 MigrateObject(HeapObject::cast(target_object)->address(), | 3111 MigrateObject(HeapObject::cast(target_object), |
3095 object_addr, | 3112 object, |
3096 size, | 3113 size, |
3097 space->identity()); | 3114 space->identity()); |
3098 ASSERT(object->map_word().IsForwardingAddress()); | 3115 ASSERT(object->map_word().IsForwardingAddress()); |
3099 } | 3116 } |
3100 | 3117 |
3101 // Clear marking bits for current cell. | 3118 // Clear marking bits for current cell. |
3102 *cell = 0; | 3119 *cell = 0; |
3103 } | 3120 } |
3104 p->ResetLiveBytes(); | 3121 p->ResetLiveBytes(); |
3105 } | 3122 } |
(...skipping 1371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4477 while (buffer != NULL) { | 4494 while (buffer != NULL) { |
4478 SlotsBuffer* next_buffer = buffer->next(); | 4495 SlotsBuffer* next_buffer = buffer->next(); |
4479 DeallocateBuffer(buffer); | 4496 DeallocateBuffer(buffer); |
4480 buffer = next_buffer; | 4497 buffer = next_buffer; |
4481 } | 4498 } |
4482 *buffer_address = NULL; | 4499 *buffer_address = NULL; |
4483 } | 4500 } |
4484 | 4501 |
4485 | 4502 |
4486 } } // namespace v8::internal | 4503 } } // namespace v8::internal |
OLD | NEW |