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/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/compilation-cache.h" | 9 #include "src/compilation-cache.h" |
10 #include "src/cpu-profiler.h" | 10 #include "src/cpu-profiler.h" |
(...skipping 3088 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3099 for (int i = 0; i < live_objects; i++) { | 3099 for (int i = 0; i < live_objects; i++) { |
3100 Address object_addr = cell_base + offsets[i] * kPointerSize; | 3100 Address object_addr = cell_base + offsets[i] * kPointerSize; |
3101 HeapObject* object = HeapObject::FromAddress(object_addr); | 3101 HeapObject* object = HeapObject::FromAddress(object_addr); |
3102 ASSERT(Marking::IsBlack(Marking::MarkBitFrom(object))); | 3102 ASSERT(Marking::IsBlack(Marking::MarkBitFrom(object))); |
3103 | 3103 |
3104 int size = object->Size(); | 3104 int size = object->Size(); |
3105 | 3105 |
3106 HeapObject* target_object; | 3106 HeapObject* target_object; |
3107 AllocationResult allocation = space->AllocateRaw(size); | 3107 AllocationResult allocation = space->AllocateRaw(size); |
3108 if (!allocation.To(&target_object)) { | 3108 if (!allocation.To(&target_object)) { |
| 3109 // If allocation failed, use emergency memory and re-try allocation. |
| 3110 CHECK(space->HasEmergencyMemory()); |
| 3111 space->UseEmergencyMemory(); |
| 3112 allocation = space->AllocateRaw(size); |
| 3113 } |
| 3114 if (!allocation.To(&target_object)) { |
3109 // OS refused to give us memory. | 3115 // OS refused to give us memory. |
3110 V8::FatalProcessOutOfMemory("Evacuation"); | 3116 V8::FatalProcessOutOfMemory("Evacuation"); |
3111 return; | 3117 return; |
3112 } | 3118 } |
3113 | 3119 |
3114 MigrateObject(target_object, object, size, space->identity()); | 3120 MigrateObject(target_object, object, size, space->identity()); |
3115 ASSERT(object->map_word().IsForwardingAddress()); | 3121 ASSERT(object->map_word().IsForwardingAddress()); |
3116 } | 3122 } |
3117 | 3123 |
3118 // Clear marking bits for current cell. | 3124 // Clear marking bits for current cell. |
3119 *cell = 0; | 3125 *cell = 0; |
3120 } | 3126 } |
3121 p->ResetLiveBytes(); | 3127 p->ResetLiveBytes(); |
3122 } | 3128 } |
3123 | 3129 |
3124 | 3130 |
3125 void MarkCompactCollector::EvacuatePages() { | 3131 void MarkCompactCollector::EvacuatePages() { |
3126 int npages = evacuation_candidates_.length(); | 3132 int npages = evacuation_candidates_.length(); |
3127 for (int i = 0; i < npages; i++) { | 3133 for (int i = 0; i < npages; i++) { |
3128 Page* p = evacuation_candidates_[i]; | 3134 Page* p = evacuation_candidates_[i]; |
3129 ASSERT(p->IsEvacuationCandidate() || | 3135 ASSERT(p->IsEvacuationCandidate() || |
3130 p->IsFlagSet(Page::RESCAN_ON_EVACUATION)); | 3136 p->IsFlagSet(Page::RESCAN_ON_EVACUATION)); |
3131 ASSERT(static_cast<int>(p->parallel_sweeping()) == | 3137 ASSERT(static_cast<int>(p->parallel_sweeping()) == |
3132 MemoryChunk::SWEEPING_DONE); | 3138 MemoryChunk::SWEEPING_DONE); |
| 3139 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); |
| 3140 // Allocate emergency memory for the case when compaction fails due to out |
| 3141 // of memory. |
| 3142 if (!space->HasEmergencyMemory()) { |
| 3143 space->CreateEmergencyMemory(); |
| 3144 } |
3133 if (p->IsEvacuationCandidate()) { | 3145 if (p->IsEvacuationCandidate()) { |
3134 // During compaction we might have to request a new page. | 3146 // During compaction we might have to request a new page. Check that we |
3135 // Check that space still have room for that. | 3147 // have an emergency page and the space still has room for that. |
3136 if (static_cast<PagedSpace*>(p->owner())->CanExpand()) { | 3148 if (space->HasEmergencyMemory() && space->CanExpand()) { |
3137 EvacuateLiveObjectsFromPage(p); | 3149 EvacuateLiveObjectsFromPage(p); |
3138 } else { | 3150 } else { |
3139 // Without room for expansion evacuation is not guaranteed to succeed. | 3151 // Without room for expansion evacuation is not guaranteed to succeed. |
3140 // Pessimistically abandon unevacuated pages. | 3152 // Pessimistically abandon unevacuated pages. |
3141 for (int j = i; j < npages; j++) { | 3153 for (int j = i; j < npages; j++) { |
3142 Page* page = evacuation_candidates_[j]; | 3154 Page* page = evacuation_candidates_[j]; |
3143 slots_buffer_allocator_.DeallocateChain(page->slots_buffer_address()); | 3155 slots_buffer_allocator_.DeallocateChain(page->slots_buffer_address()); |
3144 page->ClearEvacuationCandidate(); | 3156 page->ClearEvacuationCandidate(); |
3145 page->SetFlag(Page::RESCAN_ON_EVACUATION); | 3157 page->SetFlag(Page::RESCAN_ON_EVACUATION); |
3146 } | 3158 } |
3147 return; | 3159 break; |
3148 } | 3160 } |
3149 } | 3161 } |
3150 } | 3162 } |
| 3163 if (npages > 0) { |
| 3164 // Release emergency memory. |
| 3165 PagedSpaces spaces(heap()); |
| 3166 for (PagedSpace* space = spaces.next(); space != NULL; |
| 3167 space = spaces.next()) { |
| 3168 if (space->HasEmergencyMemory()) { |
| 3169 space->FreeEmergencyMemory(); |
| 3170 } |
| 3171 } |
| 3172 } |
3151 } | 3173 } |
3152 | 3174 |
3153 | 3175 |
3154 class EvacuationWeakObjectRetainer : public WeakObjectRetainer { | 3176 class EvacuationWeakObjectRetainer : public WeakObjectRetainer { |
3155 public: | 3177 public: |
3156 virtual Object* RetainAs(Object* object) { | 3178 virtual Object* RetainAs(Object* object) { |
3157 if (object->IsHeapObject()) { | 3179 if (object->IsHeapObject()) { |
3158 HeapObject* heap_object = HeapObject::cast(object); | 3180 HeapObject* heap_object = HeapObject::cast(object); |
3159 MapWord map_word = heap_object->map_word(); | 3181 MapWord map_word = heap_object->map_word(); |
3160 if (map_word.IsForwardingAddress()) { | 3182 if (map_word.IsForwardingAddress()) { |
(...skipping 1428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4589 while (buffer != NULL) { | 4611 while (buffer != NULL) { |
4590 SlotsBuffer* next_buffer = buffer->next(); | 4612 SlotsBuffer* next_buffer = buffer->next(); |
4591 DeallocateBuffer(buffer); | 4613 DeallocateBuffer(buffer); |
4592 buffer = next_buffer; | 4614 buffer = next_buffer; |
4593 } | 4615 } |
4594 *buffer_address = NULL; | 4616 *buffer_address = NULL; |
4595 } | 4617 } |
4596 | 4618 |
4597 | 4619 |
4598 } } // namespace v8::internal | 4620 } } // namespace v8::internal |
OLD | NEW |