Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(163)

Side by Side Diff: src/heap/mark-compact.cc

Issue 1051233002: Reland "Merge old data and pointer space." (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/heap/mark-compact-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 PageIterator it(space); 128 PageIterator it(space);
129 129
130 while (it.has_next()) { 130 while (it.has_next()) {
131 Page* p = it.next(); 131 Page* p = it.next();
132 VerifyMarking(space->heap(), p->area_start(), p->area_end()); 132 VerifyMarking(space->heap(), p->area_start(), p->area_end());
133 } 133 }
134 } 134 }
135 135
136 136
137 static void VerifyMarking(Heap* heap) { 137 static void VerifyMarking(Heap* heap) {
138 VerifyMarking(heap->old_pointer_space()); 138 VerifyMarking(heap->old_space());
139 VerifyMarking(heap->old_data_space());
140 VerifyMarking(heap->code_space()); 139 VerifyMarking(heap->code_space());
141 VerifyMarking(heap->cell_space()); 140 VerifyMarking(heap->cell_space());
142 VerifyMarking(heap->map_space()); 141 VerifyMarking(heap->map_space());
143 VerifyMarking(heap->new_space()); 142 VerifyMarking(heap->new_space());
144 143
145 VerifyMarkingVisitor visitor(heap); 144 VerifyMarkingVisitor visitor(heap);
146 145
147 LargeObjectIterator it(heap->lo_space()); 146 LargeObjectIterator it(heap->lo_space());
148 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { 147 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) {
149 if (MarkCompactCollector::IsMarked(obj)) { 148 if (MarkCompactCollector::IsMarked(obj)) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 while (current < limit) { 192 while (current < limit) {
194 HeapObject* object = HeapObject::FromAddress(current); 193 HeapObject* object = HeapObject::FromAddress(current);
195 object->Iterate(&visitor); 194 object->Iterate(&visitor);
196 current += object->Size(); 195 current += object->Size();
197 } 196 }
198 } 197 }
199 } 198 }
200 199
201 200
202 static void VerifyEvacuation(Heap* heap, PagedSpace* space) { 201 static void VerifyEvacuation(Heap* heap, PagedSpace* space) {
203 if (FLAG_use_allocation_folding && 202 if (FLAG_use_allocation_folding && (space == heap->old_space())) {
204 (space == heap->old_pointer_space() || space == heap->old_data_space())) {
205 return; 203 return;
206 } 204 }
207 PageIterator it(space); 205 PageIterator it(space);
208 206
209 while (it.has_next()) { 207 while (it.has_next()) {
210 Page* p = it.next(); 208 Page* p = it.next();
211 if (p->IsEvacuationCandidate()) continue; 209 if (p->IsEvacuationCandidate()) continue;
212 VerifyEvacuation(p); 210 VerifyEvacuation(p);
213 } 211 }
214 } 212 }
215 213
216 214
217 static void VerifyEvacuation(Heap* heap) { 215 static void VerifyEvacuation(Heap* heap) {
218 VerifyEvacuation(heap, heap->old_pointer_space()); 216 VerifyEvacuation(heap, heap->old_space());
219 VerifyEvacuation(heap, heap->old_data_space());
220 VerifyEvacuation(heap, heap->code_space()); 217 VerifyEvacuation(heap, heap->code_space());
221 VerifyEvacuation(heap, heap->cell_space()); 218 VerifyEvacuation(heap, heap->cell_space());
222 VerifyEvacuation(heap, heap->map_space()); 219 VerifyEvacuation(heap, heap->map_space());
223 VerifyEvacuation(heap->new_space()); 220 VerifyEvacuation(heap->new_space());
224 221
225 VerifyEvacuationVisitor visitor; 222 VerifyEvacuationVisitor visitor;
226 heap->IterateStrongRoots(&visitor, VISIT_ALL); 223 heap->IterateStrongRoots(&visitor, VISIT_ALL);
227 } 224 }
228 #endif // VERIFY_HEAP 225 #endif // VERIFY_HEAP
229 226
230 227
231 void MarkCompactCollector::SetUp() { 228 void MarkCompactCollector::SetUp() {
232 free_list_old_data_space_.Reset(new FreeList(heap_->old_data_space())); 229 free_list_old_space_.Reset(new FreeList(heap_->old_space()));
233 free_list_old_pointer_space_.Reset(new FreeList(heap_->old_pointer_space()));
234 } 230 }
235 231
236 232
237 void MarkCompactCollector::TearDown() { 233 void MarkCompactCollector::TearDown() {
238 AbortCompaction(); 234 AbortCompaction();
239 delete marking_deque_memory_; 235 delete marking_deque_memory_;
240 } 236 }
241 237
242 238
243 void MarkCompactCollector::AddEvacuationCandidate(Page* p) { 239 void MarkCompactCollector::AddEvacuationCandidate(Page* p) {
(...skipping 10 matching lines...) Expand all
254 PrintF("[%s]: %d pages, %d (%.1f%%) free\n", 250 PrintF("[%s]: %d pages, %d (%.1f%%) free\n",
255 AllocationSpaceName(space->identity()), number_of_pages, 251 AllocationSpaceName(space->identity()), number_of_pages,
256 static_cast<int>(free), static_cast<double>(free) * 100 / reserved); 252 static_cast<int>(free), static_cast<double>(free) * 100 / reserved);
257 } 253 }
258 254
259 255
260 bool MarkCompactCollector::StartCompaction(CompactionMode mode) { 256 bool MarkCompactCollector::StartCompaction(CompactionMode mode) {
261 if (!compacting_) { 257 if (!compacting_) {
262 DCHECK(evacuation_candidates_.length() == 0); 258 DCHECK(evacuation_candidates_.length() == 0);
263 259
264 CollectEvacuationCandidates(heap()->old_pointer_space()); 260 CollectEvacuationCandidates(heap()->old_space());
265 CollectEvacuationCandidates(heap()->old_data_space());
266 261
267 if (FLAG_compact_code_space && (mode == NON_INCREMENTAL_COMPACTION || 262 if (FLAG_compact_code_space && (mode == NON_INCREMENTAL_COMPACTION ||
268 FLAG_incremental_code_compaction)) { 263 FLAG_incremental_code_compaction)) {
269 CollectEvacuationCandidates(heap()->code_space()); 264 CollectEvacuationCandidates(heap()->code_space());
270 } else if (FLAG_trace_fragmentation) { 265 } else if (FLAG_trace_fragmentation) {
271 TraceFragmentation(heap()->code_space()); 266 TraceFragmentation(heap()->code_space());
272 } 267 }
273 268
274 if (FLAG_trace_fragmentation) { 269 if (FLAG_trace_fragmentation) {
275 TraceFragmentation(heap()->map_space()); 270 TraceFragmentation(heap()->map_space());
276 TraceFragmentation(heap()->cell_space()); 271 TraceFragmentation(heap()->cell_space());
277 } 272 }
278 273
279 heap()->old_pointer_space()->EvictEvacuationCandidatesFromFreeLists(); 274 heap()->old_space()->EvictEvacuationCandidatesFromFreeLists();
280 heap()->old_data_space()->EvictEvacuationCandidatesFromFreeLists();
281 heap()->code_space()->EvictEvacuationCandidatesFromFreeLists(); 275 heap()->code_space()->EvictEvacuationCandidatesFromFreeLists();
282 276
283 compacting_ = evacuation_candidates_.length() > 0; 277 compacting_ = evacuation_candidates_.length() > 0;
284 } 278 }
285 279
286 return compacting_; 280 return compacting_;
287 } 281 }
288 282
289 283
290 void MarkCompactCollector::ClearInvalidSlotsBufferEntries(PagedSpace* space) { 284 void MarkCompactCollector::ClearInvalidSlotsBufferEntries(PagedSpace* space) {
291 PageIterator it(space); 285 PageIterator it(space);
292 while (it.has_next()) { 286 while (it.has_next()) {
293 Page* p = it.next(); 287 Page* p = it.next();
294 SlotsBuffer::RemoveInvalidSlots(heap_, p->slots_buffer()); 288 SlotsBuffer::RemoveInvalidSlots(heap_, p->slots_buffer());
295 } 289 }
296 } 290 }
297 291
298 292
299 void MarkCompactCollector::ClearInvalidStoreAndSlotsBufferEntries() { 293 void MarkCompactCollector::ClearInvalidStoreAndSlotsBufferEntries() {
300 heap_->store_buffer()->ClearInvalidStoreBufferEntries(); 294 heap_->store_buffer()->ClearInvalidStoreBufferEntries();
301 295
302 ClearInvalidSlotsBufferEntries(heap_->old_pointer_space()); 296 ClearInvalidSlotsBufferEntries(heap_->old_space());
303 ClearInvalidSlotsBufferEntries(heap_->old_data_space());
304 ClearInvalidSlotsBufferEntries(heap_->code_space()); 297 ClearInvalidSlotsBufferEntries(heap_->code_space());
305 ClearInvalidSlotsBufferEntries(heap_->cell_space()); 298 ClearInvalidSlotsBufferEntries(heap_->cell_space());
306 ClearInvalidSlotsBufferEntries(heap_->map_space()); 299 ClearInvalidSlotsBufferEntries(heap_->map_space());
307 300
308 LargeObjectIterator it(heap_->lo_space()); 301 LargeObjectIterator it(heap_->lo_space());
309 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) { 302 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) {
310 MemoryChunk* chunk = MemoryChunk::FromAddress(object->address()); 303 MemoryChunk* chunk = MemoryChunk::FromAddress(object->address());
311 SlotsBuffer::RemoveInvalidSlots(heap_, chunk->slots_buffer()); 304 SlotsBuffer::RemoveInvalidSlots(heap_, chunk->slots_buffer());
312 } 305 }
313 } 306 }
314 307
315 308
316 #ifdef VERIFY_HEAP 309 #ifdef VERIFY_HEAP
317 static void VerifyValidSlotsBufferEntries(Heap* heap, PagedSpace* space) { 310 static void VerifyValidSlotsBufferEntries(Heap* heap, PagedSpace* space) {
318 PageIterator it(space); 311 PageIterator it(space);
319 while (it.has_next()) { 312 while (it.has_next()) {
320 Page* p = it.next(); 313 Page* p = it.next();
321 SlotsBuffer::VerifySlots(heap, p->slots_buffer()); 314 SlotsBuffer::VerifySlots(heap, p->slots_buffer());
322 } 315 }
323 } 316 }
324 317
325 318
326 static void VerifyValidStoreAndSlotsBufferEntries(Heap* heap) { 319 static void VerifyValidStoreAndSlotsBufferEntries(Heap* heap) {
327 heap->store_buffer()->VerifyValidStoreBufferEntries(); 320 heap->store_buffer()->VerifyValidStoreBufferEntries();
328 321
329 VerifyValidSlotsBufferEntries(heap, heap->old_pointer_space()); 322 VerifyValidSlotsBufferEntries(heap, heap->old_space());
330 VerifyValidSlotsBufferEntries(heap, heap->old_data_space());
331 VerifyValidSlotsBufferEntries(heap, heap->code_space()); 323 VerifyValidSlotsBufferEntries(heap, heap->code_space());
332 VerifyValidSlotsBufferEntries(heap, heap->cell_space()); 324 VerifyValidSlotsBufferEntries(heap, heap->cell_space());
333 VerifyValidSlotsBufferEntries(heap, heap->map_space()); 325 VerifyValidSlotsBufferEntries(heap, heap->map_space());
334 326
335 LargeObjectIterator it(heap->lo_space()); 327 LargeObjectIterator it(heap->lo_space());
336 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) { 328 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) {
337 MemoryChunk* chunk = MemoryChunk::FromAddress(object->address()); 329 MemoryChunk* chunk = MemoryChunk::FromAddress(object->address());
338 SlotsBuffer::VerifySlots(heap, chunk->slots_buffer()); 330 SlotsBuffer::VerifySlots(heap, chunk->slots_buffer());
339 } 331 }
340 } 332 }
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 403
412 while (it.has_next()) { 404 while (it.has_next()) {
413 NewSpacePage* p = it.next(); 405 NewSpacePage* p = it.next();
414 CHECK(p->markbits()->IsClean()); 406 CHECK(p->markbits()->IsClean());
415 CHECK_EQ(0, p->LiveBytes()); 407 CHECK_EQ(0, p->LiveBytes());
416 } 408 }
417 } 409 }
418 410
419 411
420 void MarkCompactCollector::VerifyMarkbitsAreClean() { 412 void MarkCompactCollector::VerifyMarkbitsAreClean() {
421 VerifyMarkbitsAreClean(heap_->old_pointer_space()); 413 VerifyMarkbitsAreClean(heap_->old_space());
422 VerifyMarkbitsAreClean(heap_->old_data_space());
423 VerifyMarkbitsAreClean(heap_->code_space()); 414 VerifyMarkbitsAreClean(heap_->code_space());
424 VerifyMarkbitsAreClean(heap_->cell_space()); 415 VerifyMarkbitsAreClean(heap_->cell_space());
425 VerifyMarkbitsAreClean(heap_->map_space()); 416 VerifyMarkbitsAreClean(heap_->map_space());
426 VerifyMarkbitsAreClean(heap_->new_space()); 417 VerifyMarkbitsAreClean(heap_->new_space());
427 418
428 LargeObjectIterator it(heap_->lo_space()); 419 LargeObjectIterator it(heap_->lo_space());
429 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { 420 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) {
430 MarkBit mark_bit = Marking::MarkBitFrom(obj); 421 MarkBit mark_bit = Marking::MarkBitFrom(obj);
431 CHECK(Marking::IsWhite(mark_bit)); 422 CHECK(Marking::IsWhite(mark_bit));
432 CHECK_EQ(0, Page::FromAddress(obj->address())->LiveBytes()); 423 CHECK_EQ(0, Page::FromAddress(obj->address())->LiveBytes());
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 461
471 while (it.has_next()) { 462 while (it.has_next()) {
472 Bitmap::Clear(it.next()); 463 Bitmap::Clear(it.next());
473 } 464 }
474 } 465 }
475 466
476 467
477 void MarkCompactCollector::ClearMarkbits() { 468 void MarkCompactCollector::ClearMarkbits() {
478 ClearMarkbitsInPagedSpace(heap_->code_space()); 469 ClearMarkbitsInPagedSpace(heap_->code_space());
479 ClearMarkbitsInPagedSpace(heap_->map_space()); 470 ClearMarkbitsInPagedSpace(heap_->map_space());
480 ClearMarkbitsInPagedSpace(heap_->old_pointer_space()); 471 ClearMarkbitsInPagedSpace(heap_->old_space());
481 ClearMarkbitsInPagedSpace(heap_->old_data_space());
482 ClearMarkbitsInPagedSpace(heap_->cell_space()); 472 ClearMarkbitsInPagedSpace(heap_->cell_space());
483 ClearMarkbitsInNewSpace(heap_->new_space()); 473 ClearMarkbitsInNewSpace(heap_->new_space());
484 474
485 LargeObjectIterator it(heap_->lo_space()); 475 LargeObjectIterator it(heap_->lo_space());
486 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { 476 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) {
487 MarkBit mark_bit = Marking::MarkBitFrom(obj); 477 MarkBit mark_bit = Marking::MarkBitFrom(obj);
488 mark_bit.Clear(); 478 mark_bit.Clear();
489 mark_bit.Next().Clear(); 479 mark_bit.Next().Clear();
490 Page::FromAddress(obj->address())->ResetProgressBar(); 480 Page::FromAddress(obj->address())->ResetProgressBar();
491 Page::FromAddress(obj->address())->ResetLiveBytes(); 481 Page::FromAddress(obj->address())->ResetLiveBytes();
(...skipping 15 matching lines...) Expand all
507 } 497 }
508 498
509 Heap* heap_; 499 Heap* heap_;
510 PagedSpace* space_; 500 PagedSpace* space_;
511 501
512 DISALLOW_COPY_AND_ASSIGN(SweeperTask); 502 DISALLOW_COPY_AND_ASSIGN(SweeperTask);
513 }; 503 };
514 504
515 505
516 void MarkCompactCollector::StartSweeperThreads() { 506 void MarkCompactCollector::StartSweeperThreads() {
517 DCHECK(free_list_old_pointer_space_.get()->IsEmpty()); 507 DCHECK(free_list_old_space_.get()->IsEmpty());
518 DCHECK(free_list_old_data_space_.get()->IsEmpty());
519 V8::GetCurrentPlatform()->CallOnBackgroundThread( 508 V8::GetCurrentPlatform()->CallOnBackgroundThread(
520 new SweeperTask(heap(), heap()->old_data_space()), 509 new SweeperTask(heap(), heap()->old_space()),
521 v8::Platform::kShortRunningTask);
522 V8::GetCurrentPlatform()->CallOnBackgroundThread(
523 new SweeperTask(heap(), heap()->old_pointer_space()),
524 v8::Platform::kShortRunningTask); 510 v8::Platform::kShortRunningTask);
525 } 511 }
526 512
527 513
528 void MarkCompactCollector::EnsureSweepingCompleted() { 514 void MarkCompactCollector::EnsureSweepingCompleted() {
529 DCHECK(sweeping_in_progress_ == true); 515 DCHECK(sweeping_in_progress_ == true);
530 516
531 // If sweeping is not completed or not running at all, we try to complete it 517 // If sweeping is not completed or not running at all, we try to complete it
532 // here. 518 // here.
533 if (!heap()->concurrent_sweeping_enabled() || !IsSweepingCompleted()) { 519 if (!heap()->concurrent_sweeping_enabled() || !IsSweepingCompleted()) {
534 SweepInParallel(heap()->paged_space(OLD_DATA_SPACE), 0); 520 SweepInParallel(heap()->paged_space(OLD_SPACE), 0);
535 SweepInParallel(heap()->paged_space(OLD_POINTER_SPACE), 0);
536 } 521 }
537 // Wait twice for both jobs. 522 // Wait twice for both jobs.
538 if (heap()->concurrent_sweeping_enabled()) { 523 if (heap()->concurrent_sweeping_enabled()) {
539 pending_sweeper_jobs_semaphore_.Wait(); 524 pending_sweeper_jobs_semaphore_.Wait();
540 pending_sweeper_jobs_semaphore_.Wait();
541 } 525 }
542 ParallelSweepSpacesComplete(); 526 ParallelSweepSpacesComplete();
543 sweeping_in_progress_ = false; 527 sweeping_in_progress_ = false;
544 RefillFreeList(heap()->paged_space(OLD_DATA_SPACE)); 528 RefillFreeList(heap()->paged_space(OLD_SPACE));
545 RefillFreeList(heap()->paged_space(OLD_POINTER_SPACE)); 529 heap()->paged_space(OLD_SPACE)->ResetUnsweptFreeBytes();
546 heap()->paged_space(OLD_DATA_SPACE)->ResetUnsweptFreeBytes();
547 heap()->paged_space(OLD_POINTER_SPACE)->ResetUnsweptFreeBytes();
548 530
549 #ifdef VERIFY_HEAP 531 #ifdef VERIFY_HEAP
550 if (FLAG_verify_heap && !evacuation()) { 532 if (FLAG_verify_heap && !evacuation()) {
551 VerifyEvacuation(heap_); 533 VerifyEvacuation(heap_);
552 } 534 }
553 #endif 535 #endif
554 } 536 }
555 537
556 538
557 bool MarkCompactCollector::IsSweepingCompleted() { 539 bool MarkCompactCollector::IsSweepingCompleted() {
558 if (!pending_sweeper_jobs_semaphore_.WaitFor( 540 if (!pending_sweeper_jobs_semaphore_.WaitFor(
559 base::TimeDelta::FromSeconds(0))) { 541 base::TimeDelta::FromSeconds(0))) {
560 return false; 542 return false;
561 } 543 }
562 pending_sweeper_jobs_semaphore_.Signal(); 544 pending_sweeper_jobs_semaphore_.Signal();
563 return true; 545 return true;
564 } 546 }
565 547
566 548
567 void MarkCompactCollector::RefillFreeList(PagedSpace* space) { 549 void MarkCompactCollector::RefillFreeList(PagedSpace* space) {
568 FreeList* free_list; 550 FreeList* free_list;
569 551
570 if (space == heap()->old_pointer_space()) { 552 if (space == heap()->old_space()) {
571 free_list = free_list_old_pointer_space_.get(); 553 free_list = free_list_old_space_.get();
572 } else if (space == heap()->old_data_space()) {
573 free_list = free_list_old_data_space_.get();
574 } else { 554 } else {
575 // Any PagedSpace might invoke RefillFreeLists, so we need to make sure 555 // Any PagedSpace might invoke RefillFreeLists, so we need to make sure
576 // to only refill them for old data and pointer spaces. 556 // to only refill them for the old space.
577 return; 557 return;
578 } 558 }
579 559
580 intptr_t freed_bytes = space->free_list()->Concatenate(free_list); 560 intptr_t freed_bytes = space->free_list()->Concatenate(free_list);
581 space->AddToAccountingStats(freed_bytes); 561 space->AddToAccountingStats(freed_bytes);
582 space->DecrementUnsweptFreeBytes(freed_bytes); 562 space->DecrementUnsweptFreeBytes(freed_bytes);
583 } 563 }
584 564
585 565
586 void Marking::TransferMark(Address old_start, Address new_start) { 566 void Marking::TransferMark(Address old_start, Address new_start) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 ObjectColor new_color = Color(new_mark_bit); 600 ObjectColor new_color = Color(new_mark_bit);
621 DCHECK(new_color == old_color); 601 DCHECK(new_color == old_color);
622 #endif 602 #endif
623 } 603 }
624 604
625 605
626 const char* AllocationSpaceName(AllocationSpace space) { 606 const char* AllocationSpaceName(AllocationSpace space) {
627 switch (space) { 607 switch (space) {
628 case NEW_SPACE: 608 case NEW_SPACE:
629 return "NEW_SPACE"; 609 return "NEW_SPACE";
630 case OLD_POINTER_SPACE: 610 case OLD_SPACE:
631 return "OLD_POINTER_SPACE"; 611 return "OLD_SPACE";
632 case OLD_DATA_SPACE:
633 return "OLD_DATA_SPACE";
634 case CODE_SPACE: 612 case CODE_SPACE:
635 return "CODE_SPACE"; 613 return "CODE_SPACE";
636 case MAP_SPACE: 614 case MAP_SPACE:
637 return "MAP_SPACE"; 615 return "MAP_SPACE";
638 case CELL_SPACE: 616 case CELL_SPACE:
639 return "CELL_SPACE"; 617 return "CELL_SPACE";
640 case LO_SPACE: 618 case LO_SPACE:
641 return "LO_SPACE"; 619 return "LO_SPACE";
642 default: 620 default:
643 UNREACHABLE(); 621 UNREACHABLE();
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 return 1; 670 return 1;
693 } 671 }
694 672
695 if (ratio <= ratio_threshold) return 0; // Not fragmented. 673 if (ratio <= ratio_threshold) return 0; // Not fragmented.
696 674
697 return static_cast<int>(ratio - ratio_threshold); 675 return static_cast<int>(ratio - ratio_threshold);
698 } 676 }
699 677
700 678
701 void MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) { 679 void MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) {
702 DCHECK(space->identity() == OLD_POINTER_SPACE || 680 DCHECK(space->identity() == OLD_SPACE || space->identity() == CODE_SPACE);
703 space->identity() == OLD_DATA_SPACE ||
704 space->identity() == CODE_SPACE);
705 681
706 static const int kMaxMaxEvacuationCandidates = 1000; 682 static const int kMaxMaxEvacuationCandidates = 1000;
707 int number_of_pages = space->CountTotalPages(); 683 int number_of_pages = space->CountTotalPages();
708 int max_evacuation_candidates = 684 int max_evacuation_candidates =
709 static_cast<int>(std::sqrt(number_of_pages / 2.0) + 1); 685 static_cast<int>(std::sqrt(number_of_pages / 2.0) + 1);
710 686
711 if (FLAG_stress_compaction || FLAG_always_compact) { 687 if (FLAG_stress_compaction || FLAG_always_compact) {
712 max_evacuation_candidates = kMaxMaxEvacuationCandidates; 688 max_evacuation_candidates = kMaxMaxEvacuationCandidates;
713 } 689 }
714 690
(...skipping 1162 matching lines...) Expand 10 before | Expand all | Expand 10 after
1877 (next_cell << (Bitmap::kBitsPerCell - 1))); 1853 (next_cell << (Bitmap::kBitsPerCell - 1)));
1878 } else { 1854 } else {
1879 grey_objects = current_cell & (current_cell >> 1); 1855 grey_objects = current_cell & (current_cell >> 1);
1880 } 1856 }
1881 1857
1882 int offset = 0; 1858 int offset = 0;
1883 while (grey_objects != 0) { 1859 while (grey_objects != 0) {
1884 int trailing_zeros = base::bits::CountTrailingZeros32(grey_objects); 1860 int trailing_zeros = base::bits::CountTrailingZeros32(grey_objects);
1885 grey_objects >>= trailing_zeros; 1861 grey_objects >>= trailing_zeros;
1886 offset += trailing_zeros; 1862 offset += trailing_zeros;
1887 MarkBit markbit(cell, 1 << offset, false); 1863 MarkBit markbit(cell, 1 << offset);
1888 DCHECK(Marking::IsGrey(markbit)); 1864 DCHECK(Marking::IsGrey(markbit));
1889 Marking::GreyToBlack(markbit); 1865 Marking::GreyToBlack(markbit);
1890 Address addr = cell_base + offset * kPointerSize; 1866 Address addr = cell_base + offset * kPointerSize;
1891 HeapObject* object = HeapObject::FromAddress(addr); 1867 HeapObject* object = HeapObject::FromAddress(addr);
1892 MemoryChunk::IncrementLiveBytesFromGC(object->address(), object->Size()); 1868 MemoryChunk::IncrementLiveBytesFromGC(object->address(), object->Size());
1893 marking_deque->PushBlack(object); 1869 marking_deque->PushBlack(object);
1894 if (marking_deque->IsFull()) return; 1870 if (marking_deque->IsFull()) return;
1895 offset += 2; 1871 offset += 2;
1896 grey_objects >>= 2; 1872 grey_objects >>= 2;
1897 } 1873 }
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
2101 // before sweeping completes. If sweeping completes, there are no remaining 2077 // before sweeping completes. If sweeping completes, there are no remaining
2102 // overflowed objects in the heap so the overflow flag on the markings stack 2078 // overflowed objects in the heap so the overflow flag on the markings stack
2103 // is cleared. 2079 // is cleared.
2104 void MarkCompactCollector::RefillMarkingDeque() { 2080 void MarkCompactCollector::RefillMarkingDeque() {
2105 isolate()->CountUsage(v8::Isolate::UseCounterFeature::kMarkDequeOverflow); 2081 isolate()->CountUsage(v8::Isolate::UseCounterFeature::kMarkDequeOverflow);
2106 DCHECK(marking_deque_.overflowed()); 2082 DCHECK(marking_deque_.overflowed());
2107 2083
2108 DiscoverGreyObjectsInNewSpace(heap(), &marking_deque_); 2084 DiscoverGreyObjectsInNewSpace(heap(), &marking_deque_);
2109 if (marking_deque_.IsFull()) return; 2085 if (marking_deque_.IsFull()) return;
2110 2086
2111 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, 2087 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->old_space());
2112 heap()->old_pointer_space());
2113 if (marking_deque_.IsFull()) return;
2114
2115 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->old_data_space());
2116 if (marking_deque_.IsFull()) return; 2088 if (marking_deque_.IsFull()) return;
2117 2089
2118 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->code_space()); 2090 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->code_space());
2119 if (marking_deque_.IsFull()) return; 2091 if (marking_deque_.IsFull()) return;
2120 2092
2121 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->map_space()); 2093 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->map_space());
2122 if (marking_deque_.IsFull()) return; 2094 if (marking_deque_.IsFull()) return;
2123 2095
2124 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->cell_space()); 2096 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->cell_space());
2125 if (marking_deque_.IsFull()) return; 2097 if (marking_deque_.IsFull()) return;
(...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after
2784 // to new space. We should clear them to avoid encountering them during next 2756 // to new space. We should clear them to avoid encountering them during next
2785 // pointer iteration. This is an issue if the store buffer overflows and we 2757 // pointer iteration. This is an issue if the store buffer overflows and we
2786 // have to scan the entire old space, including dead objects, looking for 2758 // have to scan the entire old space, including dead objects, looking for
2787 // pointers to new space. 2759 // pointers to new space.
2788 void MarkCompactCollector::MigrateObject(HeapObject* dst, HeapObject* src, 2760 void MarkCompactCollector::MigrateObject(HeapObject* dst, HeapObject* src,
2789 int size, AllocationSpace dest) { 2761 int size, AllocationSpace dest) {
2790 Address dst_addr = dst->address(); 2762 Address dst_addr = dst->address();
2791 Address src_addr = src->address(); 2763 Address src_addr = src->address();
2792 DCHECK(heap()->AllowedToBeMigrated(src, dest)); 2764 DCHECK(heap()->AllowedToBeMigrated(src, dest));
2793 DCHECK(dest != LO_SPACE && size <= Page::kMaxRegularHeapObjectSize); 2765 DCHECK(dest != LO_SPACE && size <= Page::kMaxRegularHeapObjectSize);
2794 if (dest == OLD_POINTER_SPACE) { 2766 if (dest == OLD_SPACE) {
2795 Address src_slot = src_addr; 2767 Address src_slot = src_addr;
2796 Address dst_slot = dst_addr; 2768 Address dst_slot = dst_addr;
2797 DCHECK(IsAligned(size, kPointerSize)); 2769 DCHECK(IsAligned(size, kPointerSize));
2798 2770
2799 bool may_contain_raw_values = src->MayContainRawValues(); 2771 bool may_contain_raw_values = src->MayContainRawValues();
2800 #if V8_DOUBLE_FIELDS_UNBOXING 2772 #if V8_DOUBLE_FIELDS_UNBOXING
2801 LayoutDescriptorHelper helper(src->map()); 2773 LayoutDescriptorHelper helper(src->map());
2802 bool has_only_tagged_fields = helper.all_fields_tagged(); 2774 bool has_only_tagged_fields = helper.all_fields_tagged();
2803 #endif 2775 #endif
2804 for (int remaining = size / kPointerSize; remaining > 0; remaining--) { 2776 for (int remaining = size / kPointerSize; remaining > 0; remaining--) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2856 } 2828 }
2857 } 2829 }
2858 } else if (dest == CODE_SPACE) { 2830 } else if (dest == CODE_SPACE) {
2859 PROFILE(isolate(), CodeMoveEvent(src_addr, dst_addr)); 2831 PROFILE(isolate(), CodeMoveEvent(src_addr, dst_addr));
2860 heap()->MoveBlock(dst_addr, src_addr, size); 2832 heap()->MoveBlock(dst_addr, src_addr, size);
2861 SlotsBuffer::AddTo(&slots_buffer_allocator_, &migration_slots_buffer_, 2833 SlotsBuffer::AddTo(&slots_buffer_allocator_, &migration_slots_buffer_,
2862 SlotsBuffer::RELOCATED_CODE_OBJECT, dst_addr, 2834 SlotsBuffer::RELOCATED_CODE_OBJECT, dst_addr,
2863 SlotsBuffer::IGNORE_OVERFLOW); 2835 SlotsBuffer::IGNORE_OVERFLOW);
2864 Code::cast(dst)->Relocate(dst_addr - src_addr); 2836 Code::cast(dst)->Relocate(dst_addr - src_addr);
2865 } else { 2837 } else {
2866 DCHECK(dest == OLD_DATA_SPACE || dest == NEW_SPACE); 2838 DCHECK(dest == NEW_SPACE);
2867 heap()->MoveBlock(dst_addr, src_addr, size); 2839 heap()->MoveBlock(dst_addr, src_addr, size);
2868 } 2840 }
2869 heap()->OnMoveEvent(dst, src, size); 2841 heap()->OnMoveEvent(dst, src, size);
2870 Memory::Address_at(src_addr) = dst_addr; 2842 Memory::Address_at(src_addr) = dst_addr;
2871 } 2843 }
2872 2844
2873 2845
2874 // Visitor for updating pointers from live objects in old spaces to new space. 2846 // Visitor for updating pointers from live objects in old spaces to new space.
2875 // It does not expect to encounter pointers to dead objects. 2847 // It does not expect to encounter pointers to dead objects.
2876 class PointersUpdatingVisitor : public ObjectVisitor { 2848 class PointersUpdatingVisitor : public ObjectVisitor {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
2978 data[index++] = reinterpret_cast<uintptr_t>(slot); 2950 data[index++] = reinterpret_cast<uintptr_t>(slot);
2979 data[index++] = 0x15aaaaaaaaUL; 2951 data[index++] = 0x15aaaaaaaaUL;
2980 2952
2981 Address slot_address = reinterpret_cast<Address>(slot); 2953 Address slot_address = reinterpret_cast<Address>(slot);
2982 2954
2983 uintptr_t space_owner_id = 0xb001; 2955 uintptr_t space_owner_id = 0xb001;
2984 if (heap->new_space()->ToSpaceContains(slot_address)) { 2956 if (heap->new_space()->ToSpaceContains(slot_address)) {
2985 space_owner_id = 1; 2957 space_owner_id = 1;
2986 } else if (heap->new_space()->FromSpaceContains(slot_address)) { 2958 } else if (heap->new_space()->FromSpaceContains(slot_address)) {
2987 space_owner_id = 2; 2959 space_owner_id = 2;
2988 } else if (heap->old_pointer_space()->ContainsSafe(slot_address)) { 2960 } else if (heap->old_space()->ContainsSafe(slot_address)) {
2989 space_owner_id = 3; 2961 space_owner_id = 3;
2990 } else if (heap->old_data_space()->ContainsSafe(slot_address)) { 2962 } else if (heap->code_space()->ContainsSafe(slot_address)) {
2991 space_owner_id = 4; 2963 space_owner_id = 4;
2992 } else if (heap->code_space()->ContainsSafe(slot_address)) { 2964 } else if (heap->map_space()->ContainsSafe(slot_address)) {
2993 space_owner_id = 5; 2965 space_owner_id = 5;
2994 } else if (heap->map_space()->ContainsSafe(slot_address)) { 2966 } else if (heap->cell_space()->ContainsSafe(slot_address)) {
2995 space_owner_id = 6; 2967 space_owner_id = 6;
2996 } else if (heap->cell_space()->ContainsSafe(slot_address)) {
2997 space_owner_id = 7;
2998 } else { 2968 } else {
2999 // Lo space or other. 2969 // Lo space or other.
3000 space_owner_id = 8; 2970 space_owner_id = 7;
3001 } 2971 }
3002 data[index++] = space_owner_id; 2972 data[index++] = space_owner_id;
3003 data[index++] = 0x20aaaaaaaaUL; 2973 data[index++] = 0x20aaaaaaaaUL;
3004 2974
3005 // Find map word lying near before the slot address (usually the map word is 2975 // Find map word lying near before the slot address (usually the map word is
3006 // at -3 words from the slot but just in case we look up further. 2976 // at -3 words from the slot but just in case we look up further.
3007 Object** map_slot = slot; 2977 Object** map_slot = slot;
3008 bool found = false; 2978 bool found = false;
3009 const int kMaxDistanceToMap = 64; 2979 const int kMaxDistanceToMap = 64;
3010 for (int i = 0; i < kMaxDistanceToMap; i++, map_slot--) { 2980 for (int i = 0; i < kMaxDistanceToMap; i++, map_slot--) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
3081 } 3051 }
3082 3052
3083 return String::cast(*p); 3053 return String::cast(*p);
3084 } 3054 }
3085 3055
3086 3056
3087 bool MarkCompactCollector::TryPromoteObject(HeapObject* object, 3057 bool MarkCompactCollector::TryPromoteObject(HeapObject* object,
3088 int object_size) { 3058 int object_size) {
3089 DCHECK(object_size <= Page::kMaxRegularHeapObjectSize); 3059 DCHECK(object_size <= Page::kMaxRegularHeapObjectSize);
3090 3060
3091 OldSpace* target_space = heap()->TargetSpace(object); 3061 OldSpace* old_space = heap()->old_space();
3092 3062
3093 DCHECK(target_space == heap()->old_pointer_space() ||
3094 target_space == heap()->old_data_space());
3095 HeapObject* target; 3063 HeapObject* target;
3096 AllocationResult allocation = target_space->AllocateRaw(object_size); 3064 AllocationResult allocation = old_space->AllocateRaw(object_size);
3097 if (allocation.To(&target)) { 3065 if (allocation.To(&target)) {
3098 MigrateObject(target, object, object_size, target_space->identity()); 3066 MigrateObject(target, object, object_size, old_space->identity());
3099 heap()->IncrementPromotedObjectsSize(object_size); 3067 heap()->IncrementPromotedObjectsSize(object_size);
3100 return true; 3068 return true;
3101 } 3069 }
3102 3070
3103 return false; 3071 return false;
3104 } 3072 }
3105 3073
3106 3074
3107 bool MarkCompactCollector::IsSlotInBlackObject(Page* p, Address slot, 3075 bool MarkCompactCollector::IsSlotInBlackObject(Page* p, Address slot,
3108 HeapObject** out_object) { 3076 HeapObject** out_object) {
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after
3599 3567
3600 return true; 3568 return true;
3601 } 3569 }
3602 3570
3603 3571
3604 static bool IsOnInvalidatedCodeObject(Address addr) { 3572 static bool IsOnInvalidatedCodeObject(Address addr) {
3605 // We did not record any slots in large objects thus 3573 // We did not record any slots in large objects thus
3606 // we can safely go to the page from the slot address. 3574 // we can safely go to the page from the slot address.
3607 Page* p = Page::FromAddress(addr); 3575 Page* p = Page::FromAddress(addr);
3608 3576
3609 // First check owner's identity because old pointer and old data spaces 3577 // First check owner's identity because old space is swept concurrently or
3610 // are swept lazily and might still have non-zero mark-bits on some 3578 // lazily and might still have non-zero mark-bits on some pages.
3611 // pages.
3612 if (p->owner()->identity() != CODE_SPACE) return false; 3579 if (p->owner()->identity() != CODE_SPACE) return false;
3613 3580
3614 // In code space only bits on evacuation candidates (but we don't record 3581 // In code space only bits on evacuation candidates (but we don't record
3615 // any slots on them) and under invalidated code objects are non-zero. 3582 // any slots on them) and under invalidated code objects are non-zero.
3616 MarkBit mark_bit = 3583 MarkBit mark_bit =
3617 p->markbits()->MarkBitFromIndex(Page::FastAddressToMarkbitIndex(addr)); 3584 p->markbits()->MarkBitFromIndex(Page::FastAddressToMarkbitIndex(addr));
3618 3585
3619 return mark_bit.Get(); 3586 return mark_bit.Get();
3620 } 3587 }
3621 3588
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
3780 if (list != NULL) list->Clear(); 3747 if (list != NULL) list->Clear();
3781 } else { 3748 } else {
3782 if (FLAG_gc_verbose) { 3749 if (FLAG_gc_verbose) {
3783 PrintF("Sweeping 0x%" V8PRIxPTR " during evacuation.\n", 3750 PrintF("Sweeping 0x%" V8PRIxPTR " during evacuation.\n",
3784 reinterpret_cast<intptr_t>(p)); 3751 reinterpret_cast<intptr_t>(p));
3785 } 3752 }
3786 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); 3753 PagedSpace* space = static_cast<PagedSpace*>(p->owner());
3787 p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION); 3754 p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION);
3788 3755
3789 switch (space->identity()) { 3756 switch (space->identity()) {
3790 case OLD_DATA_SPACE: 3757 case OLD_SPACE:
3791 Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD, 3758 Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD,
3792 IGNORE_SKIP_LIST, IGNORE_FREE_SPACE>(space, NULL, p, 3759 IGNORE_SKIP_LIST, IGNORE_FREE_SPACE>(space, NULL, p,
3793 &updating_visitor); 3760 &updating_visitor);
3794 break;
3795 case OLD_POINTER_SPACE:
3796 Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD,
3797 IGNORE_SKIP_LIST, IGNORE_FREE_SPACE>(space, NULL, p,
3798 &updating_visitor);
3799 break; 3761 break;
3800 case CODE_SPACE: 3762 case CODE_SPACE:
3801 if (FLAG_zap_code_space) { 3763 if (FLAG_zap_code_space) {
3802 Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD, 3764 Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD,
3803 REBUILD_SKIP_LIST, ZAP_FREE_SPACE>(space, NULL, p, 3765 REBUILD_SKIP_LIST, ZAP_FREE_SPACE>(space, NULL, p,
3804 &updating_visitor); 3766 &updating_visitor);
3805 } else { 3767 } else {
3806 Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD, 3768 Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD,
3807 REBUILD_SKIP_LIST, IGNORE_FREE_SPACE>(space, NULL, p, 3769 REBUILD_SKIP_LIST, IGNORE_FREE_SPACE>(space, NULL, p,
3808 &updating_visitor); 3770 &updating_visitor);
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after
4296 max_freed_overall = Max(max_freed, max_freed_overall); 4258 max_freed_overall = Max(max_freed, max_freed_overall);
4297 if (p == space->end_of_unswept_pages()) break; 4259 if (p == space->end_of_unswept_pages()) break;
4298 } 4260 }
4299 return max_freed_overall; 4261 return max_freed_overall;
4300 } 4262 }
4301 4263
4302 4264
4303 int MarkCompactCollector::SweepInParallel(Page* page, PagedSpace* space) { 4265 int MarkCompactCollector::SweepInParallel(Page* page, PagedSpace* space) {
4304 int max_freed = 0; 4266 int max_freed = 0;
4305 if (page->TryParallelSweeping()) { 4267 if (page->TryParallelSweeping()) {
4306 FreeList* free_list = space == heap()->old_pointer_space() 4268 FreeList* free_list = free_list_old_space_.get();
4307 ? free_list_old_pointer_space_.get()
4308 : free_list_old_data_space_.get();
4309 FreeList private_free_list(space); 4269 FreeList private_free_list(space);
4310 max_freed = Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, IGNORE_SKIP_LIST, 4270 max_freed = Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, IGNORE_SKIP_LIST,
4311 IGNORE_FREE_SPACE>(space, &private_free_list, page, NULL); 4271 IGNORE_FREE_SPACE>(space, &private_free_list, page, NULL);
4312 free_list->Concatenate(&private_free_list); 4272 free_list->Concatenate(&private_free_list);
4313 } 4273 }
4314 return max_freed; 4274 return max_freed;
4315 } 4275 }
4316 4276
4317 4277
4318 void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) { 4278 void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) {
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
4423 MoveEvacuationCandidatesToEndOfPagesList(); 4383 MoveEvacuationCandidatesToEndOfPagesList();
4424 4384
4425 // Noncompacting collections simply sweep the spaces to clear the mark 4385 // Noncompacting collections simply sweep the spaces to clear the mark
4426 // bits and free the nonlive blocks (for old and map spaces). We sweep 4386 // bits and free the nonlive blocks (for old and map spaces). We sweep
4427 // the map space last because freeing non-live maps overwrites them and 4387 // the map space last because freeing non-live maps overwrites them and
4428 // the other spaces rely on possibly non-live maps to get the sizes for 4388 // the other spaces rely on possibly non-live maps to get the sizes for
4429 // non-live objects. 4389 // non-live objects.
4430 { 4390 {
4431 GCTracer::Scope sweep_scope(heap()->tracer(), 4391 GCTracer::Scope sweep_scope(heap()->tracer(),
4432 GCTracer::Scope::MC_SWEEP_OLDSPACE); 4392 GCTracer::Scope::MC_SWEEP_OLDSPACE);
4433 { 4393 { SweepSpace(heap()->old_space(), CONCURRENT_SWEEPING); }
4434 SweepSpace(heap()->old_pointer_space(), CONCURRENT_SWEEPING);
4435 SweepSpace(heap()->old_data_space(), CONCURRENT_SWEEPING);
4436 }
4437 sweeping_in_progress_ = true; 4394 sweeping_in_progress_ = true;
4438 if (heap()->concurrent_sweeping_enabled()) { 4395 if (heap()->concurrent_sweeping_enabled()) {
4439 StartSweeperThreads(); 4396 StartSweeperThreads();
4440 } 4397 }
4441 } 4398 }
4442 RemoveDeadInvalidatedCode(); 4399 RemoveDeadInvalidatedCode();
4443 4400
4444 { 4401 {
4445 GCTracer::Scope sweep_scope(heap()->tracer(), 4402 GCTracer::Scope sweep_scope(heap()->tracer(),
4446 GCTracer::Scope::MC_SWEEP_CODE); 4403 GCTracer::Scope::MC_SWEEP_CODE);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
4494 if (p->parallel_sweeping() == MemoryChunk::SWEEPING_FINALIZE) { 4451 if (p->parallel_sweeping() == MemoryChunk::SWEEPING_FINALIZE) {
4495 p->set_parallel_sweeping(MemoryChunk::SWEEPING_DONE); 4452 p->set_parallel_sweeping(MemoryChunk::SWEEPING_DONE);
4496 p->SetWasSwept(); 4453 p->SetWasSwept();
4497 } 4454 }
4498 DCHECK(p->parallel_sweeping() == MemoryChunk::SWEEPING_DONE); 4455 DCHECK(p->parallel_sweeping() == MemoryChunk::SWEEPING_DONE);
4499 } 4456 }
4500 } 4457 }
4501 4458
4502 4459
4503 void MarkCompactCollector::ParallelSweepSpacesComplete() { 4460 void MarkCompactCollector::ParallelSweepSpacesComplete() {
4504 ParallelSweepSpaceComplete(heap()->old_pointer_space()); 4461 ParallelSweepSpaceComplete(heap()->old_space());
4505 ParallelSweepSpaceComplete(heap()->old_data_space());
4506 } 4462 }
4507 4463
4508 4464
4509 void MarkCompactCollector::EnableCodeFlushing(bool enable) { 4465 void MarkCompactCollector::EnableCodeFlushing(bool enable) {
4510 if (isolate()->debug()->is_loaded() || 4466 if (isolate()->debug()->is_loaded() ||
4511 isolate()->debug()->has_break_points()) { 4467 isolate()->debug()->has_break_points()) {
4512 enable = false; 4468 enable = false;
4513 } 4469 }
4514 4470
4515 if (enable) { 4471 if (enable) {
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
4684 isolate()->CountUsage(v8::Isolate::UseCounterFeature::kSlotsBufferOverflow); 4640 isolate()->CountUsage(v8::Isolate::UseCounterFeature::kSlotsBufferOverflow);
4685 4641
4686 // TODO(gc) If all evacuation candidates are too popular we 4642 // TODO(gc) If all evacuation candidates are too popular we
4687 // should stop slots recording entirely. 4643 // should stop slots recording entirely.
4688 page->ClearEvacuationCandidate(); 4644 page->ClearEvacuationCandidate();
4689 4645
4690 // We were not collecting slots on this page that point 4646 // We were not collecting slots on this page that point
4691 // to other evacuation candidates thus we have to 4647 // to other evacuation candidates thus we have to
4692 // rescan the page after evacuation to discover and update all 4648 // rescan the page after evacuation to discover and update all
4693 // pointers to evacuated objects. 4649 // pointers to evacuated objects.
4694 if (page->owner()->identity() == OLD_DATA_SPACE) { 4650 page->SetFlag(Page::RESCAN_ON_EVACUATION);
4695 evacuation_candidates_.RemoveElement(page);
4696 } else {
4697 page->SetFlag(Page::RESCAN_ON_EVACUATION);
4698 }
4699 } 4651 }
4700 4652
4701 4653
4702 void MarkCompactCollector::RecordCodeEntrySlot(Address slot, Code* target) { 4654 void MarkCompactCollector::RecordCodeEntrySlot(Address slot, Code* target) {
4703 Page* target_page = Page::FromAddress(reinterpret_cast<Address>(target)); 4655 Page* target_page = Page::FromAddress(reinterpret_cast<Address>(target));
4704 if (target_page->IsEvacuationCandidate() && 4656 if (target_page->IsEvacuationCandidate() &&
4705 !ShouldSkipEvacuationSlotRecording(reinterpret_cast<Object**>(slot))) { 4657 !ShouldSkipEvacuationSlotRecording(reinterpret_cast<Object**>(slot))) {
4706 if (!SlotsBuffer::AddTo(&slots_buffer_allocator_, 4658 if (!SlotsBuffer::AddTo(&slots_buffer_allocator_,
4707 target_page->slots_buffer_address(), 4659 target_page->slots_buffer_address(),
4708 SlotsBuffer::CODE_ENTRY_SLOT, slot, 4660 SlotsBuffer::CODE_ENTRY_SLOT, slot,
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
4787 SlotsBuffer* buffer = *buffer_address; 4739 SlotsBuffer* buffer = *buffer_address;
4788 while (buffer != NULL) { 4740 while (buffer != NULL) {
4789 SlotsBuffer* next_buffer = buffer->next(); 4741 SlotsBuffer* next_buffer = buffer->next();
4790 DeallocateBuffer(buffer); 4742 DeallocateBuffer(buffer);
4791 buffer = next_buffer; 4743 buffer = next_buffer;
4792 } 4744 }
4793 *buffer_address = NULL; 4745 *buffer_address = NULL;
4794 } 4746 }
4795 } 4747 }
4796 } // namespace v8::internal 4748 } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/heap/mark-compact-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698