| 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/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 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 219 VerifyEvacuation(heap->new_space()); | 219 VerifyEvacuation(heap->new_space()); |
| 220 | 220 |
| 221 VerifyEvacuationVisitor visitor; | 221 VerifyEvacuationVisitor visitor; |
| 222 heap->IterateStrongRoots(&visitor, VISIT_ALL); | 222 heap->IterateStrongRoots(&visitor, VISIT_ALL); |
| 223 } | 223 } |
| 224 #endif // VERIFY_HEAP | 224 #endif // VERIFY_HEAP |
| 225 | 225 |
| 226 | 226 |
| 227 void MarkCompactCollector::SetUp() { | 227 void MarkCompactCollector::SetUp() { |
| 228 free_list_old_space_.Reset(new FreeList(heap_->old_space())); | 228 free_list_old_space_.Reset(new FreeList(heap_->old_space())); |
| 229 free_list_code_space_.Reset(new FreeList(heap_->code_space())); | |
| 230 EnsureMarkingDequeIsReserved(); | 229 EnsureMarkingDequeIsReserved(); |
| 231 EnsureMarkingDequeIsCommitted(kMinMarkingDequeSize); | 230 EnsureMarkingDequeIsCommitted(kMinMarkingDequeSize); |
| 232 } | 231 } |
| 233 | 232 |
| 234 | 233 |
| 235 void MarkCompactCollector::TearDown() { | 234 void MarkCompactCollector::TearDown() { |
| 236 AbortCompaction(); | 235 AbortCompaction(); |
| 237 delete marking_deque_memory_; | 236 delete marking_deque_memory_; |
| 238 } | 237 } |
| 239 | 238 |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 ClearInvalidStoreAndSlotsBufferEntries(); | 361 ClearInvalidStoreAndSlotsBufferEntries(); |
| 363 | 362 |
| 364 #ifdef VERIFY_HEAP | 363 #ifdef VERIFY_HEAP |
| 365 if (FLAG_verify_heap) { | 364 if (FLAG_verify_heap) { |
| 366 VerifyValidStoreAndSlotsBufferEntries(heap_); | 365 VerifyValidStoreAndSlotsBufferEntries(heap_); |
| 367 } | 366 } |
| 368 #endif | 367 #endif |
| 369 | 368 |
| 370 SweepSpaces(); | 369 SweepSpaces(); |
| 371 | 370 |
| 371 #ifdef VERIFY_HEAP |
| 372 VerifyWeakEmbeddedObjectsInCode(); |
| 373 if (FLAG_omit_map_checks_for_leaf_maps) { |
| 374 VerifyOmittedMapChecks(); |
| 375 } |
| 376 #endif |
| 377 |
| 372 Finish(); | 378 Finish(); |
| 373 | 379 |
| 374 if (marking_parity_ == EVEN_MARKING_PARITY) { | 380 if (marking_parity_ == EVEN_MARKING_PARITY) { |
| 375 marking_parity_ = ODD_MARKING_PARITY; | 381 marking_parity_ = ODD_MARKING_PARITY; |
| 376 } else { | 382 } else { |
| 377 DCHECK(marking_parity_ == ODD_MARKING_PARITY); | 383 DCHECK(marking_parity_ == ODD_MARKING_PARITY); |
| 378 marking_parity_ = EVEN_MARKING_PARITY; | 384 marking_parity_ = EVEN_MARKING_PARITY; |
| 379 } | 385 } |
| 380 } | 386 } |
| 381 | 387 |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 488 | 494 |
| 489 Heap* heap_; | 495 Heap* heap_; |
| 490 PagedSpace* space_; | 496 PagedSpace* space_; |
| 491 | 497 |
| 492 DISALLOW_COPY_AND_ASSIGN(SweeperTask); | 498 DISALLOW_COPY_AND_ASSIGN(SweeperTask); |
| 493 }; | 499 }; |
| 494 | 500 |
| 495 | 501 |
| 496 void MarkCompactCollector::StartSweeperThreads() { | 502 void MarkCompactCollector::StartSweeperThreads() { |
| 497 DCHECK(free_list_old_space_.get()->IsEmpty()); | 503 DCHECK(free_list_old_space_.get()->IsEmpty()); |
| 498 DCHECK(free_list_code_space_.get()->IsEmpty()); | |
| 499 V8::GetCurrentPlatform()->CallOnBackgroundThread( | 504 V8::GetCurrentPlatform()->CallOnBackgroundThread( |
| 500 new SweeperTask(heap(), heap()->old_space()), | 505 new SweeperTask(heap(), heap()->old_space()), |
| 501 v8::Platform::kShortRunningTask); | 506 v8::Platform::kShortRunningTask); |
| 502 V8::GetCurrentPlatform()->CallOnBackgroundThread( | |
| 503 new SweeperTask(heap(), heap()->code_space()), | |
| 504 v8::Platform::kShortRunningTask); | |
| 505 } | 507 } |
| 506 | 508 |
| 507 | 509 |
| 508 void MarkCompactCollector::SweepOrWaitUntilSweepingCompleted(Page* page) { | |
| 509 PagedSpace* owner = reinterpret_cast<PagedSpace*>(page->owner()); | |
| 510 if (!page->SweepingCompleted()) { | |
| 511 SweepInParallel(page, owner); | |
| 512 if (!page->SweepingCompleted()) { | |
| 513 // We were not able to sweep that page, i.e., a concurrent | |
| 514 // sweeper thread currently owns this page. Wait for the sweeper | |
| 515 // thread to be done with this page. | |
| 516 page->WaitUntilSweepingCompleted(); | |
| 517 } | |
| 518 } | |
| 519 } | |
| 520 | |
| 521 | |
| 522 void MarkCompactCollector::EnsureSweepingCompleted() { | 510 void MarkCompactCollector::EnsureSweepingCompleted() { |
| 523 DCHECK(sweeping_in_progress_ == true); | 511 DCHECK(sweeping_in_progress_ == true); |
| 524 | 512 |
| 525 // If sweeping is not completed or not running at all, we try to complete it | 513 // If sweeping is not completed or not running at all, we try to complete it |
| 526 // here. | 514 // here. |
| 527 if (!heap()->concurrent_sweeping_enabled() || !IsSweepingCompleted()) { | 515 if (!heap()->concurrent_sweeping_enabled() || !IsSweepingCompleted()) { |
| 528 SweepInParallel(heap()->paged_space(OLD_SPACE), 0); | 516 SweepInParallel(heap()->paged_space(OLD_SPACE), 0); |
| 529 SweepInParallel(heap()->paged_space(CODE_SPACE), 0); | |
| 530 } | 517 } |
| 531 // Wait twice for both jobs. | 518 // Wait twice for both jobs. |
| 532 if (heap()->concurrent_sweeping_enabled()) { | 519 if (heap()->concurrent_sweeping_enabled()) { |
| 533 pending_sweeper_jobs_semaphore_.Wait(); | 520 pending_sweeper_jobs_semaphore_.Wait(); |
| 534 pending_sweeper_jobs_semaphore_.Wait(); | |
| 535 } | 521 } |
| 536 ParallelSweepSpacesComplete(); | 522 ParallelSweepSpacesComplete(); |
| 537 sweeping_in_progress_ = false; | 523 sweeping_in_progress_ = false; |
| 538 RefillFreeList(heap()->paged_space(OLD_SPACE)); | 524 RefillFreeList(heap()->paged_space(OLD_SPACE)); |
| 539 RefillFreeList(heap()->paged_space(CODE_SPACE)); | |
| 540 heap()->paged_space(OLD_SPACE)->ResetUnsweptFreeBytes(); | 525 heap()->paged_space(OLD_SPACE)->ResetUnsweptFreeBytes(); |
| 541 heap()->paged_space(CODE_SPACE)->ResetUnsweptFreeBytes(); | |
| 542 | 526 |
| 543 #ifdef VERIFY_HEAP | 527 #ifdef VERIFY_HEAP |
| 544 if (FLAG_verify_heap && !evacuation()) { | 528 if (FLAG_verify_heap && !evacuation()) { |
| 545 VerifyEvacuation(heap_); | 529 VerifyEvacuation(heap_); |
| 546 } | 530 } |
| 547 #endif | 531 #endif |
| 548 } | 532 } |
| 549 | 533 |
| 550 | 534 |
| 551 bool MarkCompactCollector::IsSweepingCompleted() { | 535 bool MarkCompactCollector::IsSweepingCompleted() { |
| 552 if (!pending_sweeper_jobs_semaphore_.WaitFor( | 536 if (!pending_sweeper_jobs_semaphore_.WaitFor( |
| 553 base::TimeDelta::FromSeconds(0))) { | 537 base::TimeDelta::FromSeconds(0))) { |
| 554 return false; | 538 return false; |
| 555 } | 539 } |
| 556 pending_sweeper_jobs_semaphore_.Signal(); | 540 pending_sweeper_jobs_semaphore_.Signal(); |
| 557 return true; | 541 return true; |
| 558 } | 542 } |
| 559 | 543 |
| 560 | 544 |
| 561 void MarkCompactCollector::RefillFreeList(PagedSpace* space) { | 545 void MarkCompactCollector::RefillFreeList(PagedSpace* space) { |
| 562 FreeList* free_list; | 546 FreeList* free_list; |
| 563 | 547 |
| 564 if (space == heap()->old_space()) { | 548 if (space == heap()->old_space()) { |
| 565 free_list = free_list_old_space_.get(); | 549 free_list = free_list_old_space_.get(); |
| 566 } else if (space == heap()->code_space()) { | |
| 567 free_list = free_list_code_space_.get(); | |
| 568 } else { | 550 } else { |
| 569 // Any PagedSpace might invoke RefillFreeLists, so we need to make sure | 551 // Any PagedSpace might invoke RefillFreeLists, so we need to make sure |
| 570 // to only refill them for the old space. | 552 // to only refill them for the old space. |
| 571 return; | 553 return; |
| 572 } | 554 } |
| 573 | 555 |
| 574 intptr_t freed_bytes = space->free_list()->Concatenate(free_list); | 556 intptr_t freed_bytes = space->free_list()->Concatenate(free_list); |
| 575 space->AddToAccountingStats(freed_bytes); | 557 space->AddToAccountingStats(freed_bytes); |
| 576 space->DecrementUnsweptFreeBytes(freed_bytes); | 558 space->DecrementUnsweptFreeBytes(freed_bytes); |
| 577 } | 559 } |
| (...skipping 2912 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3490 DCHECK_EQ(skip_list_mode == REBUILD_SKIP_LIST, | 3472 DCHECK_EQ(skip_list_mode == REBUILD_SKIP_LIST, |
| 3491 space->identity() == CODE_SPACE); | 3473 space->identity() == CODE_SPACE); |
| 3492 DCHECK((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST)); | 3474 DCHECK((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST)); |
| 3493 DCHECK(parallelism == MarkCompactCollector::SWEEP_ON_MAIN_THREAD || | 3475 DCHECK(parallelism == MarkCompactCollector::SWEEP_ON_MAIN_THREAD || |
| 3494 sweeping_mode == SWEEP_ONLY); | 3476 sweeping_mode == SWEEP_ONLY); |
| 3495 | 3477 |
| 3496 Address free_start = p->area_start(); | 3478 Address free_start = p->area_start(); |
| 3497 DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); | 3479 DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); |
| 3498 int offsets[16]; | 3480 int offsets[16]; |
| 3499 | 3481 |
| 3500 // If we use the skip list for code space pages, we have to lock the skip | |
| 3501 // list because it could be accessed concurrently by the runtime or the | |
| 3502 // deoptimizer. | |
| 3503 SkipList* skip_list = p->skip_list(); | 3482 SkipList* skip_list = p->skip_list(); |
| 3483 int curr_region = -1; |
| 3504 if ((skip_list_mode == REBUILD_SKIP_LIST) && skip_list) { | 3484 if ((skip_list_mode == REBUILD_SKIP_LIST) && skip_list) { |
| 3505 skip_list->Clear(); | 3485 skip_list->Clear(); |
| 3506 } | 3486 } |
| 3507 | 3487 |
| 3508 intptr_t freed_bytes = 0; | 3488 intptr_t freed_bytes = 0; |
| 3509 intptr_t max_freed_bytes = 0; | 3489 intptr_t max_freed_bytes = 0; |
| 3510 int curr_region = -1; | |
| 3511 | 3490 |
| 3512 for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) { | 3491 for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) { |
| 3513 Address cell_base = it.CurrentCellBase(); | 3492 Address cell_base = it.CurrentCellBase(); |
| 3514 MarkBit::CellType* cell = it.CurrentCell(); | 3493 MarkBit::CellType* cell = it.CurrentCell(); |
| 3515 int live_objects = MarkWordToObjectStarts(*cell, offsets); | 3494 int live_objects = MarkWordToObjectStarts(*cell, offsets); |
| 3516 int live_index = 0; | 3495 int live_index = 0; |
| 3517 for (; live_objects != 0; live_objects--) { | 3496 for (; live_objects != 0; live_objects--) { |
| 3518 Address free_end = cell_base + offsets[live_index++] * kPointerSize; | 3497 Address free_end = cell_base + offsets[live_index++] * kPointerSize; |
| 3519 if (free_end != free_start) { | 3498 if (free_end != free_start) { |
| 3520 int size = static_cast<int>(free_end - free_start); | 3499 int size = static_cast<int>(free_end - free_start); |
| (...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4259 | 4238 |
| 4260 int MarkCompactCollector::SweepInParallel(Page* page, PagedSpace* space) { | 4239 int MarkCompactCollector::SweepInParallel(Page* page, PagedSpace* space) { |
| 4261 int max_freed = 0; | 4240 int max_freed = 0; |
| 4262 if (page->TryLock()) { | 4241 if (page->TryLock()) { |
| 4263 // If this page was already swept in the meantime, we can return here. | 4242 // If this page was already swept in the meantime, we can return here. |
| 4264 if (page->parallel_sweeping() != MemoryChunk::SWEEPING_PENDING) { | 4243 if (page->parallel_sweeping() != MemoryChunk::SWEEPING_PENDING) { |
| 4265 page->mutex()->Unlock(); | 4244 page->mutex()->Unlock(); |
| 4266 return 0; | 4245 return 0; |
| 4267 } | 4246 } |
| 4268 page->set_parallel_sweeping(MemoryChunk::SWEEPING_IN_PROGRESS); | 4247 page->set_parallel_sweeping(MemoryChunk::SWEEPING_IN_PROGRESS); |
| 4269 FreeList* free_list; | 4248 FreeList* free_list = free_list_old_space_.get(); |
| 4270 FreeList private_free_list(space); | 4249 FreeList private_free_list(space); |
| 4271 if (space->identity() == CODE_SPACE) { | 4250 max_freed = Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, IGNORE_SKIP_LIST, |
| 4272 free_list = free_list_code_space_.get(); | 4251 IGNORE_FREE_SPACE>(space, &private_free_list, page, NULL); |
| 4273 max_freed = | |
| 4274 Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, REBUILD_SKIP_LIST, | |
| 4275 IGNORE_FREE_SPACE>(space, &private_free_list, page, NULL); | |
| 4276 } else { | |
| 4277 free_list = free_list_old_space_.get(); | |
| 4278 max_freed = | |
| 4279 Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, IGNORE_SKIP_LIST, | |
| 4280 IGNORE_FREE_SPACE>(space, &private_free_list, page, NULL); | |
| 4281 } | |
| 4282 free_list->Concatenate(&private_free_list); | 4252 free_list->Concatenate(&private_free_list); |
| 4283 page->mutex()->Unlock(); | 4253 page->mutex()->Unlock(); |
| 4284 } | 4254 } |
| 4285 return max_freed; | 4255 return max_freed; |
| 4286 } | 4256 } |
| 4287 | 4257 |
| 4288 | 4258 |
| 4289 void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) { | 4259 void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) { |
| 4290 space->ClearStats(); | 4260 space->ClearStats(); |
| 4291 | 4261 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4329 unused_page_present = true; | 4299 unused_page_present = true; |
| 4330 } | 4300 } |
| 4331 | 4301 |
| 4332 switch (sweeper) { | 4302 switch (sweeper) { |
| 4333 case CONCURRENT_SWEEPING: | 4303 case CONCURRENT_SWEEPING: |
| 4334 if (!parallel_sweeping_active) { | 4304 if (!parallel_sweeping_active) { |
| 4335 if (FLAG_gc_verbose) { | 4305 if (FLAG_gc_verbose) { |
| 4336 PrintF("Sweeping 0x%" V8PRIxPTR ".\n", | 4306 PrintF("Sweeping 0x%" V8PRIxPTR ".\n", |
| 4337 reinterpret_cast<intptr_t>(p)); | 4307 reinterpret_cast<intptr_t>(p)); |
| 4338 } | 4308 } |
| 4339 if (space->identity() == CODE_SPACE) { | 4309 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, IGNORE_SKIP_LIST, |
| 4340 if (FLAG_zap_code_space) { | 4310 IGNORE_FREE_SPACE>(space, NULL, p, NULL); |
| 4341 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST, | |
| 4342 ZAP_FREE_SPACE>(space, NULL, p, NULL); | |
| 4343 } else { | |
| 4344 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST, | |
| 4345 IGNORE_FREE_SPACE>(space, NULL, p, NULL); | |
| 4346 } | |
| 4347 } else { | |
| 4348 DCHECK(space->identity() == OLD_SPACE); | |
| 4349 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, IGNORE_SKIP_LIST, | |
| 4350 IGNORE_FREE_SPACE>(space, NULL, p, NULL); | |
| 4351 } | |
| 4352 pages_swept++; | 4311 pages_swept++; |
| 4353 parallel_sweeping_active = true; | 4312 parallel_sweeping_active = true; |
| 4354 } else { | 4313 } else { |
| 4355 if (FLAG_gc_verbose) { | 4314 if (FLAG_gc_verbose) { |
| 4356 PrintF("Sweeping 0x%" V8PRIxPTR " in parallel.\n", | 4315 PrintF("Sweeping 0x%" V8PRIxPTR " in parallel.\n", |
| 4357 reinterpret_cast<intptr_t>(p)); | 4316 reinterpret_cast<intptr_t>(p)); |
| 4358 } | 4317 } |
| 4359 p->set_parallel_sweeping(MemoryChunk::SWEEPING_PENDING); | 4318 p->set_parallel_sweeping(MemoryChunk::SWEEPING_PENDING); |
| 4360 space->IncreaseUnsweptFreeBytes(p); | 4319 space->IncreaseUnsweptFreeBytes(p); |
| 4361 } | 4320 } |
| 4362 space->set_end_of_unswept_pages(p); | 4321 space->set_end_of_unswept_pages(p); |
| 4363 break; | 4322 break; |
| 4364 case SEQUENTIAL_SWEEPING: { | 4323 case SEQUENTIAL_SWEEPING: { |
| 4365 if (FLAG_gc_verbose) { | 4324 if (FLAG_gc_verbose) { |
| 4366 PrintF("Sweeping 0x%" V8PRIxPTR ".\n", reinterpret_cast<intptr_t>(p)); | 4325 PrintF("Sweeping 0x%" V8PRIxPTR ".\n", reinterpret_cast<intptr_t>(p)); |
| 4367 } | 4326 } |
| 4368 if (space->identity() == CODE_SPACE) { | 4327 if (space->identity() == CODE_SPACE && FLAG_zap_code_space) { |
| 4369 if (FLAG_zap_code_space) { | 4328 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST, |
| 4370 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST, | 4329 ZAP_FREE_SPACE>(space, NULL, p, NULL); |
| 4371 ZAP_FREE_SPACE>(space, NULL, p, NULL); | 4330 } else if (space->identity() == CODE_SPACE) { |
| 4372 } else { | 4331 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST, |
| 4373 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST, | 4332 IGNORE_FREE_SPACE>(space, NULL, p, NULL); |
| 4374 IGNORE_FREE_SPACE>(space, NULL, p, NULL); | |
| 4375 } | |
| 4376 } else { | 4333 } else { |
| 4377 DCHECK(space->identity() == OLD_SPACE || | |
| 4378 space->identity() == MAP_SPACE); | |
| 4379 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, IGNORE_SKIP_LIST, | 4334 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, IGNORE_SKIP_LIST, |
| 4380 IGNORE_FREE_SPACE>(space, NULL, p, NULL); | 4335 IGNORE_FREE_SPACE>(space, NULL, p, NULL); |
| 4381 } | 4336 } |
| 4382 pages_swept++; | 4337 pages_swept++; |
| 4383 break; | 4338 break; |
| 4384 } | 4339 } |
| 4385 default: { UNREACHABLE(); } | 4340 default: { UNREACHABLE(); } |
| 4386 } | 4341 } |
| 4387 } | 4342 } |
| 4388 | 4343 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 4408 #endif | 4363 #endif |
| 4409 | 4364 |
| 4410 MoveEvacuationCandidatesToEndOfPagesList(); | 4365 MoveEvacuationCandidatesToEndOfPagesList(); |
| 4411 | 4366 |
| 4412 // Noncompacting collections simply sweep the spaces to clear the mark | 4367 // Noncompacting collections simply sweep the spaces to clear the mark |
| 4413 // bits and free the nonlive blocks (for old and map spaces). We sweep | 4368 // bits and free the nonlive blocks (for old and map spaces). We sweep |
| 4414 // the map space last because freeing non-live maps overwrites them and | 4369 // the map space last because freeing non-live maps overwrites them and |
| 4415 // the other spaces rely on possibly non-live maps to get the sizes for | 4370 // the other spaces rely on possibly non-live maps to get the sizes for |
| 4416 // non-live objects. | 4371 // non-live objects. |
| 4417 { | 4372 { |
| 4418 { | 4373 GCTracer::Scope sweep_scope(heap()->tracer(), |
| 4419 GCTracer::Scope sweep_scope(heap()->tracer(), | 4374 GCTracer::Scope::MC_SWEEP_OLDSPACE); |
| 4420 GCTracer::Scope::MC_SWEEP_OLDSPACE); | 4375 { SweepSpace(heap()->old_space(), CONCURRENT_SWEEPING); } |
| 4421 SweepSpace(heap()->old_space(), CONCURRENT_SWEEPING); | |
| 4422 } | |
| 4423 { | |
| 4424 GCTracer::Scope sweep_scope(heap()->tracer(), | |
| 4425 GCTracer::Scope::MC_SWEEP_CODE); | |
| 4426 SweepSpace(heap()->code_space(), CONCURRENT_SWEEPING); | |
| 4427 } | |
| 4428 | |
| 4429 sweeping_in_progress_ = true; | 4376 sweeping_in_progress_ = true; |
| 4430 if (heap()->concurrent_sweeping_enabled()) { | 4377 if (heap()->concurrent_sweeping_enabled()) { |
| 4431 StartSweeperThreads(); | 4378 StartSweeperThreads(); |
| 4432 } | 4379 } |
| 4433 } | 4380 } |
| 4381 RemoveDeadInvalidatedCode(); |
| 4434 | 4382 |
| 4435 RemoveDeadInvalidatedCode(); | 4383 { |
| 4384 GCTracer::Scope sweep_scope(heap()->tracer(), |
| 4385 GCTracer::Scope::MC_SWEEP_CODE); |
| 4386 SweepSpace(heap()->code_space(), SEQUENTIAL_SWEEPING); |
| 4387 } |
| 4436 | 4388 |
| 4437 EvacuateNewSpaceAndCandidates(); | 4389 EvacuateNewSpaceAndCandidates(); |
| 4438 | 4390 |
| 4439 heap()->FreeDeadArrayBuffers(false); | 4391 heap()->FreeDeadArrayBuffers(false); |
| 4440 | 4392 |
| 4441 // ClearNonLiveReferences depends on precise sweeping of map space to | 4393 // ClearNonLiveReferences depends on precise sweeping of map space to |
| 4442 // detect whether unmarked map became dead in this collection or in one | 4394 // detect whether unmarked map became dead in this collection or in one |
| 4443 // of the previous ones. | 4395 // of the previous ones. |
| 4444 { | 4396 { |
| 4445 GCTracer::Scope sweep_scope(heap()->tracer(), | 4397 GCTracer::Scope sweep_scope(heap()->tracer(), |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4478 p->set_parallel_sweeping(MemoryChunk::SWEEPING_DONE); | 4430 p->set_parallel_sweeping(MemoryChunk::SWEEPING_DONE); |
| 4479 p->SetWasSwept(); | 4431 p->SetWasSwept(); |
| 4480 } | 4432 } |
| 4481 DCHECK(p->parallel_sweeping() == MemoryChunk::SWEEPING_DONE); | 4433 DCHECK(p->parallel_sweeping() == MemoryChunk::SWEEPING_DONE); |
| 4482 } | 4434 } |
| 4483 } | 4435 } |
| 4484 | 4436 |
| 4485 | 4437 |
| 4486 void MarkCompactCollector::ParallelSweepSpacesComplete() { | 4438 void MarkCompactCollector::ParallelSweepSpacesComplete() { |
| 4487 ParallelSweepSpaceComplete(heap()->old_space()); | 4439 ParallelSweepSpaceComplete(heap()->old_space()); |
| 4488 ParallelSweepSpaceComplete(heap()->code_space()); | |
| 4489 } | 4440 } |
| 4490 | 4441 |
| 4491 | 4442 |
| 4492 void MarkCompactCollector::EnableCodeFlushing(bool enable) { | 4443 void MarkCompactCollector::EnableCodeFlushing(bool enable) { |
| 4493 if (isolate()->debug()->is_active()) enable = false; | 4444 if (isolate()->debug()->is_active()) enable = false; |
| 4494 | 4445 |
| 4495 if (enable) { | 4446 if (enable) { |
| 4496 if (code_flusher_ != NULL) return; | 4447 if (code_flusher_ != NULL) return; |
| 4497 code_flusher_ = new CodeFlusher(isolate()); | 4448 code_flusher_ = new CodeFlusher(isolate()); |
| 4498 } else { | 4449 } else { |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4797 SlotsBuffer* buffer = *buffer_address; | 4748 SlotsBuffer* buffer = *buffer_address; |
| 4798 while (buffer != NULL) { | 4749 while (buffer != NULL) { |
| 4799 SlotsBuffer* next_buffer = buffer->next(); | 4750 SlotsBuffer* next_buffer = buffer->next(); |
| 4800 DeallocateBuffer(buffer); | 4751 DeallocateBuffer(buffer); |
| 4801 buffer = next_buffer; | 4752 buffer = next_buffer; |
| 4802 } | 4753 } |
| 4803 *buffer_address = NULL; | 4754 *buffer_address = NULL; |
| 4804 } | 4755 } |
| 4805 } // namespace internal | 4756 } // namespace internal |
| 4806 } // namespace v8 | 4757 } // namespace v8 |
| OLD | NEW |