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/heap/mark-compact.h" | 5 #include "src/heap/mark-compact.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 3158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3169 while (it.has_next()) { | 3169 while (it.has_next()) { |
3170 NewSpacePage* p = it.next(); | 3170 NewSpacePage* p = it.next(); |
3171 survivors_size += DiscoverAndEvacuateBlackObjectsOnPage(new_space, p); | 3171 survivors_size += DiscoverAndEvacuateBlackObjectsOnPage(new_space, p); |
3172 } | 3172 } |
3173 | 3173 |
3174 heap_->IncrementYoungSurvivorsCounter(survivors_size); | 3174 heap_->IncrementYoungSurvivorsCounter(survivors_size); |
3175 new_space->set_age_mark(new_space->top()); | 3175 new_space->set_age_mark(new_space->top()); |
3176 } | 3176 } |
3177 | 3177 |
3178 | 3178 |
3179 void MarkCompactCollector::EvacuateLiveObjectsFromPage(Page* p) { | 3179 void MarkCompactCollector::EvacuateLiveObjectsFromPage( |
| 3180 Page* p, PagedSpace* target_space) { |
3180 AlwaysAllocateScope always_allocate(isolate()); | 3181 AlwaysAllocateScope always_allocate(isolate()); |
3181 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); | |
3182 DCHECK(p->IsEvacuationCandidate() && !p->WasSwept()); | 3182 DCHECK(p->IsEvacuationCandidate() && !p->WasSwept()); |
3183 p->SetWasSwept(); | 3183 p->SetWasSwept(); |
3184 | 3184 |
3185 int offsets[16]; | 3185 int offsets[16]; |
3186 | 3186 |
3187 for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) { | 3187 for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) { |
3188 Address cell_base = it.CurrentCellBase(); | 3188 Address cell_base = it.CurrentCellBase(); |
3189 MarkBit::CellType* cell = it.CurrentCell(); | 3189 MarkBit::CellType* cell = it.CurrentCell(); |
3190 | 3190 |
3191 if (*cell == 0) continue; | 3191 if (*cell == 0) continue; |
3192 | 3192 |
3193 int live_objects = MarkWordToObjectStarts(*cell, offsets); | 3193 int live_objects = MarkWordToObjectStarts(*cell, offsets); |
3194 for (int i = 0; i < live_objects; i++) { | 3194 for (int i = 0; i < live_objects; i++) { |
3195 Address object_addr = cell_base + offsets[i] * kPointerSize; | 3195 Address object_addr = cell_base + offsets[i] * kPointerSize; |
3196 HeapObject* object = HeapObject::FromAddress(object_addr); | 3196 HeapObject* object = HeapObject::FromAddress(object_addr); |
3197 DCHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); | 3197 DCHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); |
3198 | 3198 |
3199 int size = object->Size(); | 3199 int size = object->Size(); |
3200 AllocationAlignment alignment = object->RequiredAlignment(); | 3200 AllocationAlignment alignment = object->RequiredAlignment(); |
3201 HeapObject* target_object = nullptr; | 3201 HeapObject* target_object = nullptr; |
3202 AllocationResult allocation = space->AllocateRaw(size, alignment); | 3202 AllocationResult allocation = target_space->AllocateRaw(size, alignment); |
3203 if (!allocation.To(&target_object)) { | 3203 if (!allocation.To(&target_object)) { |
3204 // If allocation failed, use emergency memory and re-try allocation. | 3204 // If allocation failed, use emergency memory and re-try allocation. |
3205 CHECK(space->HasEmergencyMemory()); | 3205 CHECK(target_space->HasEmergencyMemory()); |
3206 space->UseEmergencyMemory(); | 3206 target_space->UseEmergencyMemory(); |
3207 allocation = space->AllocateRaw(size, alignment); | 3207 allocation = target_space->AllocateRaw(size, alignment); |
3208 } | 3208 } |
3209 if (!allocation.To(&target_object)) { | 3209 if (!allocation.To(&target_object)) { |
3210 // OS refused to give us memory. | 3210 // OS refused to give us memory. |
3211 V8::FatalProcessOutOfMemory("Evacuation"); | 3211 V8::FatalProcessOutOfMemory("Evacuation"); |
3212 return; | 3212 return; |
3213 } | 3213 } |
3214 | 3214 |
3215 MigrateObject(target_object, object, size, space->identity()); | 3215 MigrateObject(target_object, object, size, target_space->identity()); |
3216 DCHECK(object->map_word().IsForwardingAddress()); | 3216 DCHECK(object->map_word().IsForwardingAddress()); |
3217 } | 3217 } |
3218 | 3218 |
3219 // Clear marking bits for current cell. | 3219 // Clear marking bits for current cell. |
3220 *cell = 0; | 3220 *cell = 0; |
3221 } | 3221 } |
3222 p->ResetLiveBytes(); | 3222 p->ResetLiveBytes(); |
3223 } | 3223 } |
3224 | 3224 |
3225 | 3225 |
(...skipping 23 matching lines...) Expand all Loading... |
3249 // Allocate emergency memory for the case when compaction fails due to out | 3249 // Allocate emergency memory for the case when compaction fails due to out |
3250 // of memory. | 3250 // of memory. |
3251 if (!space->HasEmergencyMemory()) { | 3251 if (!space->HasEmergencyMemory()) { |
3252 space->CreateEmergencyMemory(); // If the OS lets us. | 3252 space->CreateEmergencyMemory(); // If the OS lets us. |
3253 } | 3253 } |
3254 if (p->IsEvacuationCandidate()) { | 3254 if (p->IsEvacuationCandidate()) { |
3255 // During compaction we might have to request a new page in order to free | 3255 // During compaction we might have to request a new page in order to free |
3256 // up a page. Check that we actually got an emergency page above so we | 3256 // up a page. Check that we actually got an emergency page above so we |
3257 // can guarantee that this succeeds. | 3257 // can guarantee that this succeeds. |
3258 if (space->HasEmergencyMemory()) { | 3258 if (space->HasEmergencyMemory()) { |
3259 EvacuateLiveObjectsFromPage(p); | 3259 EvacuateLiveObjectsFromPage(p, static_cast<PagedSpace*>(p->owner())); |
3260 // Unlink the page from the list of pages here. We must not iterate | 3260 // Unlink the page from the list of pages here. We must not iterate |
3261 // over that page later (e.g. when scan on scavenge pages are | 3261 // over that page later (e.g. when scan on scavenge pages are |
3262 // processed). The page itself will be freed later and is still | 3262 // processed). The page itself will be freed later and is still |
3263 // reachable from the evacuation candidates list. | 3263 // reachable from the evacuation candidates list. |
3264 p->Unlink(); | 3264 p->Unlink(); |
3265 } else { | 3265 } else { |
3266 // Without room for expansion evacuation is not guaranteed to succeed. | 3266 // Without room for expansion evacuation is not guaranteed to succeed. |
3267 // Pessimistically abandon unevacuated pages. | 3267 // Pessimistically abandon unevacuated pages. |
3268 for (int j = i; j < npages; j++) { | 3268 for (int j = i; j < npages; j++) { |
3269 Page* page = evacuation_candidates_[j]; | 3269 Page* page = evacuation_candidates_[j]; |
(...skipping 1401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4671 SlotsBuffer* buffer = *buffer_address; | 4671 SlotsBuffer* buffer = *buffer_address; |
4672 while (buffer != NULL) { | 4672 while (buffer != NULL) { |
4673 SlotsBuffer* next_buffer = buffer->next(); | 4673 SlotsBuffer* next_buffer = buffer->next(); |
4674 DeallocateBuffer(buffer); | 4674 DeallocateBuffer(buffer); |
4675 buffer = next_buffer; | 4675 buffer = next_buffer; |
4676 } | 4676 } |
4677 *buffer_address = NULL; | 4677 *buffer_address = NULL; |
4678 } | 4678 } |
4679 } // namespace internal | 4679 } // namespace internal |
4680 } // namespace v8 | 4680 } // namespace v8 |
OLD | NEW |