| 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 3249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3260 space->identity() == CODE_SPACE); | 3260 space->identity() == CODE_SPACE); |
| 3261 ASSERT((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST)); | 3261 ASSERT((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST)); |
| 3262 ASSERT(parallelism == MarkCompactCollector::SWEEP_ON_MAIN_THREAD || | 3262 ASSERT(parallelism == MarkCompactCollector::SWEEP_ON_MAIN_THREAD || |
| 3263 sweeping_mode == SWEEP_ONLY); | 3263 sweeping_mode == SWEEP_ONLY); |
| 3264 | 3264 |
| 3265 double start_time = 0.0; | 3265 double start_time = 0.0; |
| 3266 if (FLAG_print_cumulative_gc_stat) { | 3266 if (FLAG_print_cumulative_gc_stat) { |
| 3267 start_time = base::OS::TimeCurrentMillis(); | 3267 start_time = base::OS::TimeCurrentMillis(); |
| 3268 } | 3268 } |
| 3269 | 3269 |
| 3270 if (parallelism == MarkCompactCollector::SWEEP_IN_PARALLEL) { |
| 3271 p->set_parallel_sweeping(MemoryChunk::SWEEPING_FINALIZE); |
| 3272 } else { |
| 3273 p->MarkSweptPrecisely(); |
| 3274 } |
| 3275 |
| 3270 Address free_start = p->area_start(); | 3276 Address free_start = p->area_start(); |
| 3271 ASSERT(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); | 3277 ASSERT(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); |
| 3272 int offsets[16]; | 3278 int offsets[16]; |
| 3273 | 3279 |
| 3274 SkipList* skip_list = p->skip_list(); | 3280 SkipList* skip_list = p->skip_list(); |
| 3275 int curr_region = -1; | 3281 int curr_region = -1; |
| 3276 if ((skip_list_mode == REBUILD_SKIP_LIST) && skip_list) { | 3282 if ((skip_list_mode == REBUILD_SKIP_LIST) && skip_list) { |
| 3277 skip_list->Clear(); | 3283 skip_list->Clear(); |
| 3278 } | 3284 } |
| 3279 | 3285 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3333 #ifdef ENABLE_GDB_JIT_INTERFACE | 3339 #ifdef ENABLE_GDB_JIT_INTERFACE |
| 3334 if (FLAG_gdbjit && space->identity() == CODE_SPACE) { | 3340 if (FLAG_gdbjit && space->identity() == CODE_SPACE) { |
| 3335 GDBJITInterface::RemoveCodeRange(free_start, p->area_end()); | 3341 GDBJITInterface::RemoveCodeRange(free_start, p->area_end()); |
| 3336 } | 3342 } |
| 3337 #endif | 3343 #endif |
| 3338 } | 3344 } |
| 3339 p->ResetLiveBytes(); | 3345 p->ResetLiveBytes(); |
| 3340 if (FLAG_print_cumulative_gc_stat) { | 3346 if (FLAG_print_cumulative_gc_stat) { |
| 3341 space->heap()->AddSweepingTime(base::OS::TimeCurrentMillis() - start_time); | 3347 space->heap()->AddSweepingTime(base::OS::TimeCurrentMillis() - start_time); |
| 3342 } | 3348 } |
| 3343 | |
| 3344 if (parallelism == MarkCompactCollector::SWEEP_IN_PARALLEL) { | |
| 3345 // When concurrent sweeping is active, the page will be marked after | |
| 3346 // sweeping by the main thread. | |
| 3347 p->set_parallel_sweeping(MemoryChunk::SWEEPING_FINALIZE); | |
| 3348 } else { | |
| 3349 p->MarkSweptPrecisely(); | |
| 3350 } | |
| 3351 return FreeList::GuaranteedAllocatable(static_cast<int>(max_freed_bytes)); | 3349 return FreeList::GuaranteedAllocatable(static_cast<int>(max_freed_bytes)); |
| 3352 } | 3350 } |
| 3353 | 3351 |
| 3354 | 3352 |
| 3355 static bool SetMarkBitsUnderInvalidatedCode(Code* code, bool value) { | 3353 static bool SetMarkBitsUnderInvalidatedCode(Code* code, bool value) { |
| 3356 Page* p = Page::FromAddress(code->address()); | 3354 Page* p = Page::FromAddress(code->address()); |
| 3357 | 3355 |
| 3358 if (p->IsEvacuationCandidate() || | 3356 if (p->IsEvacuationCandidate() || |
| 3359 p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) { | 3357 p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) { |
| 3360 return false; | 3358 return false; |
| (...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3994 template<MarkCompactCollector::SweepingParallelism mode> | 3992 template<MarkCompactCollector::SweepingParallelism mode> |
| 3995 int MarkCompactCollector::SweepConservatively(PagedSpace* space, | 3993 int MarkCompactCollector::SweepConservatively(PagedSpace* space, |
| 3996 FreeList* free_list, | 3994 FreeList* free_list, |
| 3997 Page* p) { | 3995 Page* p) { |
| 3998 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept()); | 3996 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept()); |
| 3999 ASSERT((mode == MarkCompactCollector::SWEEP_IN_PARALLEL && | 3997 ASSERT((mode == MarkCompactCollector::SWEEP_IN_PARALLEL && |
| 4000 free_list != NULL) || | 3998 free_list != NULL) || |
| 4001 (mode == MarkCompactCollector::SWEEP_ON_MAIN_THREAD && | 3999 (mode == MarkCompactCollector::SWEEP_ON_MAIN_THREAD && |
| 4002 free_list == NULL)); | 4000 free_list == NULL)); |
| 4003 | 4001 |
| 4002 // When parallel sweeping is active, the page will be marked after |
| 4003 // sweeping by the main thread. |
| 4004 if (mode == MarkCompactCollector::SWEEP_IN_PARALLEL) { |
| 4005 p->set_parallel_sweeping(MemoryChunk::SWEEPING_FINALIZE); |
| 4006 } else { |
| 4007 p->MarkSweptConservatively(); |
| 4008 } |
| 4009 |
| 4004 intptr_t freed_bytes = 0; | 4010 intptr_t freed_bytes = 0; |
| 4005 intptr_t max_freed_bytes = 0; | 4011 intptr_t max_freed_bytes = 0; |
| 4006 size_t size = 0; | 4012 size_t size = 0; |
| 4007 | 4013 |
| 4008 // Skip over all the dead objects at the start of the page and mark them free. | 4014 // Skip over all the dead objects at the start of the page and mark them free. |
| 4009 Address cell_base = 0; | 4015 Address cell_base = 0; |
| 4010 MarkBit::CellType* cell = NULL; | 4016 MarkBit::CellType* cell = NULL; |
| 4011 MarkBitCellIterator it(p); | 4017 MarkBitCellIterator it(p); |
| 4012 for (; !it.Done(); it.Advance()) { | 4018 for (; !it.Done(); it.Advance()) { |
| 4013 cell_base = it.CurrentCellBase(); | 4019 cell_base = it.CurrentCellBase(); |
| 4014 cell = it.CurrentCell(); | 4020 cell = it.CurrentCell(); |
| 4015 if (*cell != 0) break; | 4021 if (*cell != 0) break; |
| 4016 } | 4022 } |
| 4017 | 4023 |
| 4018 if (it.Done()) { | 4024 if (it.Done()) { |
| 4019 size = p->area_end() - p->area_start(); | 4025 size = p->area_end() - p->area_start(); |
| 4020 freed_bytes = Free<mode>(space, free_list, p->area_start(), | 4026 freed_bytes = Free<mode>(space, free_list, p->area_start(), |
| 4021 static_cast<int>(size)); | 4027 static_cast<int>(size)); |
| 4022 max_freed_bytes = Max(freed_bytes, max_freed_bytes); | 4028 max_freed_bytes = Max(freed_bytes, max_freed_bytes); |
| 4023 ASSERT_EQ(0, p->LiveBytes()); | 4029 ASSERT_EQ(0, p->LiveBytes()); |
| 4024 if (mode == MarkCompactCollector::SWEEP_IN_PARALLEL) { | |
| 4025 // When concurrent sweeping is active, the page will be marked after | |
| 4026 // sweeping by the main thread. | |
| 4027 p->set_parallel_sweeping(MemoryChunk::SWEEPING_FINALIZE); | |
| 4028 } else { | |
| 4029 p->MarkSweptConservatively(); | |
| 4030 } | |
| 4031 return FreeList::GuaranteedAllocatable(static_cast<int>(max_freed_bytes)); | 4030 return FreeList::GuaranteedAllocatable(static_cast<int>(max_freed_bytes)); |
| 4032 } | 4031 } |
| 4033 | 4032 |
| 4034 // Grow the size of the start-of-page free space a little to get up to the | 4033 // Grow the size of the start-of-page free space a little to get up to the |
| 4035 // first live object. | 4034 // first live object. |
| 4036 Address free_end = StartOfLiveObject(cell_base, *cell); | 4035 Address free_end = StartOfLiveObject(cell_base, *cell); |
| 4037 // Free the first free space. | 4036 // Free the first free space. |
| 4038 size = free_end - p->area_start(); | 4037 size = free_end - p->area_start(); |
| 4039 freed_bytes = Free<mode>(space, free_list, p->area_start(), | 4038 freed_bytes = Free<mode>(space, free_list, p->area_start(), |
| 4040 static_cast<int>(size)); | 4039 static_cast<int>(size)); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4078 | 4077 |
| 4079 // Handle the free space at the end of the page. | 4078 // Handle the free space at the end of the page. |
| 4080 if (cell_base - free_start > 32 * kPointerSize) { | 4079 if (cell_base - free_start > 32 * kPointerSize) { |
| 4081 free_start = DigestFreeStart(free_start, free_start_cell); | 4080 free_start = DigestFreeStart(free_start, free_start_cell); |
| 4082 freed_bytes = Free<mode>(space, free_list, free_start, | 4081 freed_bytes = Free<mode>(space, free_list, free_start, |
| 4083 static_cast<int>(p->area_end() - free_start)); | 4082 static_cast<int>(p->area_end() - free_start)); |
| 4084 max_freed_bytes = Max(freed_bytes, max_freed_bytes); | 4083 max_freed_bytes = Max(freed_bytes, max_freed_bytes); |
| 4085 } | 4084 } |
| 4086 | 4085 |
| 4087 p->ResetLiveBytes(); | 4086 p->ResetLiveBytes(); |
| 4088 if (mode == MarkCompactCollector::SWEEP_IN_PARALLEL) { | |
| 4089 // When concurrent sweeping is active, the page will be marked after | |
| 4090 // sweeping by the main thread. | |
| 4091 p->set_parallel_sweeping(MemoryChunk::SWEEPING_FINALIZE); | |
| 4092 } else { | |
| 4093 p->MarkSweptConservatively(); | |
| 4094 } | |
| 4095 return FreeList::GuaranteedAllocatable(static_cast<int>(max_freed_bytes)); | 4087 return FreeList::GuaranteedAllocatable(static_cast<int>(max_freed_bytes)); |
| 4096 } | 4088 } |
| 4097 | 4089 |
| 4098 | 4090 |
| 4099 int MarkCompactCollector::SweepInParallel(PagedSpace* space, | 4091 int MarkCompactCollector::SweepInParallel(PagedSpace* space, |
| 4100 int required_freed_bytes) { | 4092 int required_freed_bytes) { |
| 4101 PageIterator it(space); | 4093 PageIterator it(space); |
| 4102 FreeList* free_list = space == heap()->old_pointer_space() | 4094 FreeList* free_list = space == heap()->old_pointer_space() |
| 4103 ? free_list_old_pointer_space_.get() | 4095 ? free_list_old_pointer_space_.get() |
| 4104 : free_list_old_data_space_.get(); | 4096 : free_list_old_data_space_.get(); |
| (...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4584 while (buffer != NULL) { | 4576 while (buffer != NULL) { |
| 4585 SlotsBuffer* next_buffer = buffer->next(); | 4577 SlotsBuffer* next_buffer = buffer->next(); |
| 4586 DeallocateBuffer(buffer); | 4578 DeallocateBuffer(buffer); |
| 4587 buffer = next_buffer; | 4579 buffer = next_buffer; |
| 4588 } | 4580 } |
| 4589 *buffer_address = NULL; | 4581 *buffer_address = NULL; |
| 4590 } | 4582 } |
| 4591 | 4583 |
| 4592 | 4584 |
| 4593 } } // namespace v8::internal | 4585 } } // namespace v8::internal |
| OLD | NEW |