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

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

Issue 143633007: A64: Synchronize with r18764. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « src/mark-compact.h ('k') | src/messages.js » ('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 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 49
50 const char* Marking::kWhiteBitPattern = "00"; 50 const char* Marking::kWhiteBitPattern = "00";
51 const char* Marking::kBlackBitPattern = "10"; 51 const char* Marking::kBlackBitPattern = "10";
52 const char* Marking::kGreyBitPattern = "11"; 52 const char* Marking::kGreyBitPattern = "11";
53 const char* Marking::kImpossibleBitPattern = "01"; 53 const char* Marking::kImpossibleBitPattern = "01";
54 54
55 55
56 // ------------------------------------------------------------------------- 56 // -------------------------------------------------------------------------
57 // MarkCompactCollector 57 // MarkCompactCollector
58 58
59 MarkCompactCollector::MarkCompactCollector() : // NOLINT 59 MarkCompactCollector::MarkCompactCollector(Heap* heap) : // NOLINT
60 #ifdef DEBUG 60 #ifdef DEBUG
61 state_(IDLE), 61 state_(IDLE),
62 #endif 62 #endif
63 sweep_precisely_(false), 63 sweep_precisely_(false),
64 reduce_memory_footprint_(false), 64 reduce_memory_footprint_(false),
65 abort_incremental_marking_(false), 65 abort_incremental_marking_(false),
66 marking_parity_(ODD_MARKING_PARITY), 66 marking_parity_(ODD_MARKING_PARITY),
67 compacting_(false), 67 compacting_(false),
68 was_marked_incrementally_(false), 68 was_marked_incrementally_(false),
69 sweeping_pending_(false), 69 sweeping_pending_(false),
70 sequential_sweeping_(false), 70 sequential_sweeping_(false),
71 tracer_(NULL), 71 tracer_(NULL),
72 migration_slots_buffer_(NULL), 72 migration_slots_buffer_(NULL),
73 heap_(NULL), 73 heap_(heap),
74 code_flusher_(NULL), 74 code_flusher_(NULL),
75 encountered_weak_collections_(NULL), 75 encountered_weak_collections_(NULL),
76 have_code_to_deoptimize_(false) { } 76 have_code_to_deoptimize_(false) { }
77 77
78 #ifdef VERIFY_HEAP 78 #ifdef VERIFY_HEAP
79 class VerifyMarkingVisitor: public ObjectVisitor { 79 class VerifyMarkingVisitor: public ObjectVisitor {
80 public: 80 public:
81 explicit VerifyMarkingVisitor(Heap* heap) : heap_(heap) {} 81 explicit VerifyMarkingVisitor(Heap* heap) : heap_(heap) {}
82 82
83 void VisitPointers(Object** start, Object** end) { 83 void VisitPointers(Object** start, Object** end) {
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 HeapObjectIterator it(heap->code_space()); 341 HeapObjectIterator it(heap->code_space());
342 342
343 for (Object* object = it.Next(); object != NULL; object = it.Next()) { 343 for (Object* object = it.Next(); object != NULL; object = it.Next()) {
344 VerifyNativeContextSeparationVisitor visitor; 344 VerifyNativeContextSeparationVisitor visitor;
345 Code::cast(object)->CodeIterateBody(&visitor); 345 Code::cast(object)->CodeIterateBody(&visitor);
346 } 346 }
347 } 347 }
348 #endif 348 #endif
349 349
350 350
351 void MarkCompactCollector::SetUp() {
352 free_list_old_data_space_.Reset(new FreeList(heap_->old_data_space()));
353 free_list_old_pointer_space_.Reset(new FreeList(heap_->old_pointer_space()));
354 }
355
356
351 void MarkCompactCollector::TearDown() { 357 void MarkCompactCollector::TearDown() {
352 AbortCompaction(); 358 AbortCompaction();
353 } 359 }
354 360
355 361
356 void MarkCompactCollector::AddEvacuationCandidate(Page* p) { 362 void MarkCompactCollector::AddEvacuationCandidate(Page* p) {
357 p->MarkEvacuationCandidate(); 363 p->MarkEvacuationCandidate();
358 evacuation_candidates_.Add(p); 364 evacuation_candidates_.Add(p);
359 } 365 }
360 366
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 MarkBit mark_bit = Marking::MarkBitFrom(obj); 563 MarkBit mark_bit = Marking::MarkBitFrom(obj);
558 mark_bit.Clear(); 564 mark_bit.Clear();
559 mark_bit.Next().Clear(); 565 mark_bit.Next().Clear();
560 Page::FromAddress(obj->address())->ResetProgressBar(); 566 Page::FromAddress(obj->address())->ResetProgressBar();
561 Page::FromAddress(obj->address())->ResetLiveBytes(); 567 Page::FromAddress(obj->address())->ResetLiveBytes();
562 } 568 }
563 } 569 }
564 570
565 571
566 void MarkCompactCollector::StartSweeperThreads() { 572 void MarkCompactCollector::StartSweeperThreads() {
573 // TODO(hpayer): This check is just used for debugging purpose and
574 // should be removed or turned into an assert after investigating the
575 // crash in concurrent sweeping.
576 CHECK(free_list_old_pointer_space_.get()->IsEmpty());
577 CHECK(free_list_old_data_space_.get()->IsEmpty());
567 sweeping_pending_ = true; 578 sweeping_pending_ = true;
568 for (int i = 0; i < isolate()->num_sweeper_threads(); i++) { 579 for (int i = 0; i < isolate()->num_sweeper_threads(); i++) {
569 isolate()->sweeper_threads()[i]->StartSweeping(); 580 isolate()->sweeper_threads()[i]->StartSweeping();
570 } 581 }
571 } 582 }
572 583
573 584
574 void MarkCompactCollector::WaitUntilSweepingCompleted() { 585 void MarkCompactCollector::WaitUntilSweepingCompleted() {
575 ASSERT(sweeping_pending_ == true); 586 ASSERT(sweeping_pending_ == true);
576 for (int i = 0; i < isolate()->num_sweeper_threads(); i++) { 587 for (int i = 0; i < isolate()->num_sweeper_threads(); i++) {
577 isolate()->sweeper_threads()[i]->WaitForSweeperThread(); 588 isolate()->sweeper_threads()[i]->WaitForSweeperThread();
578 } 589 }
579 sweeping_pending_ = false; 590 sweeping_pending_ = false;
580 StealMemoryFromSweeperThreads(heap()->paged_space(OLD_DATA_SPACE)); 591 RefillFreeLists(heap()->paged_space(OLD_DATA_SPACE));
581 StealMemoryFromSweeperThreads(heap()->paged_space(OLD_POINTER_SPACE)); 592 RefillFreeLists(heap()->paged_space(OLD_POINTER_SPACE));
582 heap()->paged_space(OLD_DATA_SPACE)->ResetUnsweptFreeBytes(); 593 heap()->paged_space(OLD_DATA_SPACE)->ResetUnsweptFreeBytes();
583 heap()->paged_space(OLD_POINTER_SPACE)->ResetUnsweptFreeBytes(); 594 heap()->paged_space(OLD_POINTER_SPACE)->ResetUnsweptFreeBytes();
584 } 595 }
585 596
586 597
587 intptr_t MarkCompactCollector:: 598 intptr_t MarkCompactCollector::RefillFreeLists(PagedSpace* space) {
588 StealMemoryFromSweeperThreads(PagedSpace* space) { 599 FreeList* free_list;
589 intptr_t freed_bytes = 0; 600
590 for (int i = 0; i < isolate()->num_sweeper_threads(); i++) { 601 if (space == heap()->old_pointer_space()) {
591 freed_bytes += isolate()->sweeper_threads()[i]->StealMemory(space); 602 free_list = free_list_old_pointer_space_.get();
603 } else if (space == heap()->old_data_space()) {
604 free_list = free_list_old_data_space_.get();
605 } else {
606 // Any PagedSpace might invoke RefillFreeLists, so we need to make sure
607 // to only refill them for old data and pointer spaces.
608 return 0;
592 } 609 }
610
611 intptr_t freed_bytes = space->free_list()->Concatenate(free_list);
593 space->AddToAccountingStats(freed_bytes); 612 space->AddToAccountingStats(freed_bytes);
594 space->DecrementUnsweptFreeBytes(freed_bytes); 613 space->DecrementUnsweptFreeBytes(freed_bytes);
595 return freed_bytes; 614 return freed_bytes;
596 } 615 }
597 616
598 617
599 bool MarkCompactCollector::AreSweeperThreadsActivated() { 618 bool MarkCompactCollector::AreSweeperThreadsActivated() {
600 return isolate()->sweeper_threads() != NULL; 619 return isolate()->sweeper_threads() != NULL;
601 } 620 }
602 621
(...skipping 2444 matching lines...) Expand 10 before | Expand all | Expand 10 after
3047 *cell = 0; 3066 *cell = 0;
3048 } 3067 }
3049 p->ResetLiveBytes(); 3068 p->ResetLiveBytes();
3050 } 3069 }
3051 3070
3052 3071
3053 void MarkCompactCollector::EvacuatePages() { 3072 void MarkCompactCollector::EvacuatePages() {
3054 int npages = evacuation_candidates_.length(); 3073 int npages = evacuation_candidates_.length();
3055 for (int i = 0; i < npages; i++) { 3074 for (int i = 0; i < npages; i++) {
3056 Page* p = evacuation_candidates_[i]; 3075 Page* p = evacuation_candidates_[i];
3057 ASSERT(p->IsEvacuationCandidate() || 3076 // TODO(hpayer): This check is just used for debugging purpose and
3058 p->IsFlagSet(Page::RESCAN_ON_EVACUATION)); 3077 // should be removed or turned into an assert after investigating the
3078 // crash in concurrent sweeping.
3079 CHECK(p->IsEvacuationCandidate() ||
3080 p->IsFlagSet(Page::RESCAN_ON_EVACUATION));
3081 CHECK_EQ(static_cast<int>(p->parallel_sweeping()), 0);
3059 if (p->IsEvacuationCandidate()) { 3082 if (p->IsEvacuationCandidate()) {
3060 // During compaction we might have to request a new page. 3083 // During compaction we might have to request a new page.
3061 // Check that space still have room for that. 3084 // Check that space still have room for that.
3062 if (static_cast<PagedSpace*>(p->owner())->CanExpand()) { 3085 if (static_cast<PagedSpace*>(p->owner())->CanExpand()) {
3063 EvacuateLiveObjectsFromPage(p); 3086 EvacuateLiveObjectsFromPage(p);
3064 } else { 3087 } else {
3065 // Without room for expansion evacuation is not guaranteed to succeed. 3088 // Without room for expansion evacuation is not guaranteed to succeed.
3066 // Pessimistically abandon unevacuated pages. 3089 // Pessimistically abandon unevacuated pages.
3067 for (int j = i; j < npages; j++) { 3090 for (int j = i; j < npages; j++) {
3068 Page* page = evacuation_candidates_[j]; 3091 Page* page = evacuation_candidates_[j];
(...skipping 810 matching lines...) Expand 10 before | Expand all | Expand 10 after
3879 // spaces have been put on the free list and the smaller ones have been 3902 // spaces have been put on the free list and the smaller ones have been
3880 // ignored and left untouched. A free space is always either ignored or put 3903 // ignored and left untouched. A free space is always either ignored or put
3881 // on the free list, never split up into two parts. This is important 3904 // on the free list, never split up into two parts. This is important
3882 // because it means that any FreeSpace maps left actually describe a region of 3905 // because it means that any FreeSpace maps left actually describe a region of
3883 // memory that can be ignored when scanning. Dead objects other than free 3906 // memory that can be ignored when scanning. Dead objects other than free
3884 // spaces will not contain the free space map. 3907 // spaces will not contain the free space map.
3885 template<MarkCompactCollector::SweepingParallelism mode> 3908 template<MarkCompactCollector::SweepingParallelism mode>
3886 intptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space, 3909 intptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space,
3887 FreeList* free_list, 3910 FreeList* free_list,
3888 Page* p) { 3911 Page* p) {
3889 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept()); 3912 // TODO(hpayer): This check is just used for debugging purpose and
3913 // should be removed or turned into an assert after investigating the
3914 // crash in concurrent sweeping.
3915 CHECK(!p->IsEvacuationCandidate() && !p->WasSwept());
3890 ASSERT((mode == MarkCompactCollector::SWEEP_IN_PARALLEL && 3916 ASSERT((mode == MarkCompactCollector::SWEEP_IN_PARALLEL &&
3891 free_list != NULL) || 3917 free_list != NULL) ||
3892 (mode == MarkCompactCollector::SWEEP_SEQUENTIALLY && 3918 (mode == MarkCompactCollector::SWEEP_SEQUENTIALLY &&
3893 free_list == NULL)); 3919 free_list == NULL));
3894 3920
3895 p->MarkSweptConservatively(); 3921 p->MarkSweptConservatively();
3896 3922
3897 intptr_t freed_bytes = 0; 3923 intptr_t freed_bytes = 0;
3898 size_t size = 0; 3924 size_t size = 0;
3899 3925
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
3963 free_start = DigestFreeStart(free_start, free_start_cell); 3989 free_start = DigestFreeStart(free_start, free_start_cell);
3964 freed_bytes += Free<mode>(space, free_list, free_start, 3990 freed_bytes += Free<mode>(space, free_list, free_start,
3965 static_cast<int>(p->area_end() - free_start)); 3991 static_cast<int>(p->area_end() - free_start));
3966 } 3992 }
3967 3993
3968 p->ResetLiveBytes(); 3994 p->ResetLiveBytes();
3969 return freed_bytes; 3995 return freed_bytes;
3970 } 3996 }
3971 3997
3972 3998
3973 void MarkCompactCollector::SweepInParallel(PagedSpace* space, 3999 void MarkCompactCollector::SweepInParallel(PagedSpace* space) {
3974 FreeList* private_free_list,
3975 FreeList* free_list) {
3976 PageIterator it(space); 4000 PageIterator it(space);
4001 FreeList* free_list = space == heap()->old_pointer_space()
4002 ? free_list_old_pointer_space_.get()
4003 : free_list_old_data_space_.get();
4004 FreeList private_free_list(space);
3977 while (it.has_next()) { 4005 while (it.has_next()) {
3978 Page* p = it.next(); 4006 Page* p = it.next();
3979 4007
3980 if (p->TryParallelSweeping()) { 4008 if (p->TryParallelSweeping()) {
3981 SweepConservatively<SWEEP_IN_PARALLEL>(space, private_free_list, p); 4009 SweepConservatively<SWEEP_IN_PARALLEL>(space, &private_free_list, p);
3982 free_list->Concatenate(private_free_list); 4010 free_list->Concatenate(&private_free_list);
3983 } 4011 }
3984 } 4012 }
3985 } 4013 }
3986 4014
3987 4015
3988 void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) { 4016 void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) {
3989 space->set_was_swept_conservatively(sweeper == CONSERVATIVE || 4017 space->set_was_swept_conservatively(sweeper == CONSERVATIVE ||
3990 sweeper == LAZY_CONSERVATIVE || 4018 sweeper == LAZY_CONSERVATIVE ||
3991 sweeper == PARALLEL_CONSERVATIVE || 4019 sweeper == PARALLEL_CONSERVATIVE ||
3992 sweeper == CONCURRENT_CONSERVATIVE); 4020 sweeper == CONCURRENT_CONSERVATIVE);
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
4114 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP); 4142 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP);
4115 #ifdef DEBUG 4143 #ifdef DEBUG
4116 state_ = SWEEP_SPACES; 4144 state_ = SWEEP_SPACES;
4117 #endif 4145 #endif
4118 SweeperType how_to_sweep = 4146 SweeperType how_to_sweep =
4119 FLAG_lazy_sweeping ? LAZY_CONSERVATIVE : CONSERVATIVE; 4147 FLAG_lazy_sweeping ? LAZY_CONSERVATIVE : CONSERVATIVE;
4120 if (isolate()->num_sweeper_threads() > 0) { 4148 if (isolate()->num_sweeper_threads() > 0) {
4121 if (FLAG_parallel_sweeping) how_to_sweep = PARALLEL_CONSERVATIVE; 4149 if (FLAG_parallel_sweeping) how_to_sweep = PARALLEL_CONSERVATIVE;
4122 if (FLAG_concurrent_sweeping) how_to_sweep = CONCURRENT_CONSERVATIVE; 4150 if (FLAG_concurrent_sweeping) how_to_sweep = CONCURRENT_CONSERVATIVE;
4123 } 4151 }
4124 if (FLAG_expose_gc) how_to_sweep = CONSERVATIVE;
4125 if (sweep_precisely_) how_to_sweep = PRECISE; 4152 if (sweep_precisely_) how_to_sweep = PRECISE;
4126 4153
4127 // Unlink evacuation candidates before sweeper threads access the list of 4154 // Unlink evacuation candidates before sweeper threads access the list of
4128 // pages to avoid race condition. 4155 // pages to avoid race condition.
4129 UnlinkEvacuationCandidates(); 4156 UnlinkEvacuationCandidates();
4130 4157
4131 // Noncompacting collections simply sweep the spaces to clear the mark 4158 // Noncompacting collections simply sweep the spaces to clear the mark
4132 // bits and free the nonlive blocks (for old and map spaces). We sweep 4159 // bits and free the nonlive blocks (for old and map spaces). We sweep
4133 // the map space last because freeing non-live maps overwrites them and 4160 // the map space last because freeing non-live maps overwrites them and
4134 // the other spaces rely on possibly non-live maps to get the sizes for 4161 // the other spaces rely on possibly non-live maps to get the sizes for
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
4369 while (buffer != NULL) { 4396 while (buffer != NULL) {
4370 SlotsBuffer* next_buffer = buffer->next(); 4397 SlotsBuffer* next_buffer = buffer->next();
4371 DeallocateBuffer(buffer); 4398 DeallocateBuffer(buffer);
4372 buffer = next_buffer; 4399 buffer = next_buffer;
4373 } 4400 }
4374 *buffer_address = NULL; 4401 *buffer_address = NULL;
4375 } 4402 }
4376 4403
4377 4404
4378 } } // namespace v8::internal 4405 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/mark-compact.h ('k') | src/messages.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698