| 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 |