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

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

Issue 256743004: Don't unlink evacuation candidates before sweeping, move them to the end of their list of pages. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 7 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
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 3188 matching lines...) Expand 10 before | Expand all | Expand 10 after
3199 if (static_cast<PagedSpace*>(p->owner())->CanExpand()) { 3199 if (static_cast<PagedSpace*>(p->owner())->CanExpand()) {
3200 EvacuateLiveObjectsFromPage(p); 3200 EvacuateLiveObjectsFromPage(p);
3201 } else { 3201 } else {
3202 // Without room for expansion evacuation is not guaranteed to succeed. 3202 // Without room for expansion evacuation is not guaranteed to succeed.
3203 // Pessimistically abandon unevacuated pages. 3203 // Pessimistically abandon unevacuated pages.
3204 for (int j = i; j < npages; j++) { 3204 for (int j = i; j < npages; j++) {
3205 Page* page = evacuation_candidates_[j]; 3205 Page* page = evacuation_candidates_[j];
3206 slots_buffer_allocator_.DeallocateChain(page->slots_buffer_address()); 3206 slots_buffer_allocator_.DeallocateChain(page->slots_buffer_address());
3207 page->ClearEvacuationCandidate(); 3207 page->ClearEvacuationCandidate();
3208 page->SetFlag(Page::RESCAN_ON_EVACUATION); 3208 page->SetFlag(Page::RESCAN_ON_EVACUATION);
3209 page->InsertAfter(static_cast<PagedSpace*>(page->owner())->anchor());
3210 } 3209 }
3211 return; 3210 return;
3212 } 3211 }
3213 } 3212 }
3214 } 3213 }
3215 } 3214 }
3216 3215
3217 3216
3218 class EvacuationWeakObjectRetainer : public WeakObjectRetainer { 3217 class EvacuationWeakObjectRetainer : public WeakObjectRetainer {
3219 public: 3218 public:
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after
3690 if (FLAG_verify_heap) { 3689 if (FLAG_verify_heap) {
3691 VerifyEvacuation(heap_); 3690 VerifyEvacuation(heap_);
3692 } 3691 }
3693 #endif 3692 #endif
3694 3693
3695 slots_buffer_allocator_.DeallocateChain(&migration_slots_buffer_); 3694 slots_buffer_allocator_.DeallocateChain(&migration_slots_buffer_);
3696 ASSERT(migration_slots_buffer_ == NULL); 3695 ASSERT(migration_slots_buffer_ == NULL);
3697 } 3696 }
3698 3697
3699 3698
3700 void MarkCompactCollector::UnlinkEvacuationCandidates() { 3699 void MarkCompactCollector::MoveEvacuationCandidatesToEndOfPagesList() {
3701 int npages = evacuation_candidates_.length(); 3700 int npages = evacuation_candidates_.length();
3702 for (int i = 0; i < npages; i++) { 3701 for (int i = 0; i < npages; i++) {
3703 Page* p = evacuation_candidates_[i]; 3702 Page* p = evacuation_candidates_[i];
3704 if (!p->IsEvacuationCandidate()) continue; 3703 if (!p->IsEvacuationCandidate()) continue;
3705 p->Unlink(); 3704 p->Unlink();
3706 p->ClearSweptPrecisely(); 3705 PagedSpace* space = static_cast<PagedSpace*>(p->owner());
3707 p->ClearSweptConservatively(); 3706 p->InsertAfter(space->LastPage());
3708 } 3707 }
3709 } 3708 }
3710 3709
3711 3710
3711
Michael Starzinger 2014/04/29 10:23:57 nit: Two lines of white-space ought'a be enough fo
Hannes Payer (out of office) 2014/04/29 10:59:27 Done.
3712 void MarkCompactCollector::ReleaseEvacuationCandidates() { 3712 void MarkCompactCollector::ReleaseEvacuationCandidates() {
3713 int npages = evacuation_candidates_.length(); 3713 int npages = evacuation_candidates_.length();
3714 for (int i = 0; i < npages; i++) { 3714 for (int i = 0; i < npages; i++) {
3715 Page* p = evacuation_candidates_[i]; 3715 Page* p = evacuation_candidates_[i];
3716 if (!p->IsEvacuationCandidate()) continue; 3716 if (!p->IsEvacuationCandidate()) continue;
3717 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); 3717 PagedSpace* space = static_cast<PagedSpace*>(p->owner());
3718 space->Free(p->area_start(), p->area_size()); 3718 space->Free(p->area_start(), p->area_size());
3719 p->set_scan_on_scavenge(false); 3719 p->set_scan_on_scavenge(false);
3720 slots_buffer_allocator_.DeallocateChain(p->slots_buffer_address()); 3720 slots_buffer_allocator_.DeallocateChain(p->slots_buffer_address());
3721 p->ResetLiveBytes(); 3721 p->ResetLiveBytes();
3722 space->ReleasePage(p, false); 3722 space->ReleasePage(p);
3723 } 3723 }
3724 evacuation_candidates_.Rewind(0); 3724 evacuation_candidates_.Rewind(0);
3725 compacting_ = false; 3725 compacting_ = false;
3726 heap()->FreeQueuedChunks(); 3726 heap()->FreeQueuedChunks();
3727 } 3727 }
3728 3728
3729 3729
3730 static const int kStartTableEntriesPerLine = 5; 3730 static const int kStartTableEntriesPerLine = 5;
3731 static const int kStartTableLines = 171; 3731 static const int kStartTableLines = 171;
3732 static const int kStartTableInvalidLine = 127; 3732 static const int kStartTableInvalidLine = 127;
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
4139 : free_list_old_data_space_.get(); 4139 : free_list_old_data_space_.get();
4140 FreeList private_free_list(space); 4140 FreeList private_free_list(space);
4141 while (it.has_next()) { 4141 while (it.has_next()) {
4142 Page* p = it.next(); 4142 Page* p = it.next();
4143 4143
4144 if (p->TryParallelSweeping()) { 4144 if (p->TryParallelSweeping()) {
4145 SweepConservatively<SWEEP_IN_PARALLEL>(space, &private_free_list, p); 4145 SweepConservatively<SWEEP_IN_PARALLEL>(space, &private_free_list, p);
4146 free_list->Concatenate(&private_free_list); 4146 free_list->Concatenate(&private_free_list);
4147 p->set_parallel_sweeping(MemoryChunk::PARALLEL_SWEEPING_FINALIZE); 4147 p->set_parallel_sweeping(MemoryChunk::PARALLEL_SWEEPING_FINALIZE);
4148 } 4148 }
4149 if (p == space->end_of_unswept_pages()) break;
4149 } 4150 }
4150 } 4151 }
4151 4152
4152 4153
4153 void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) { 4154 void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) {
4154 space->set_was_swept_conservatively(sweeper == CONSERVATIVE || 4155 space->set_was_swept_conservatively(sweeper == CONSERVATIVE ||
4155 sweeper == PARALLEL_CONSERVATIVE || 4156 sweeper == PARALLEL_CONSERVATIVE ||
4156 sweeper == CONCURRENT_CONSERVATIVE); 4157 sweeper == CONCURRENT_CONSERVATIVE);
4157 space->ClearStats(); 4158 space->ClearStats();
4158 4159
4159 PageIterator it(space); 4160 PageIterator it(space);
4160 4161
4161 int pages_swept = 0; 4162 int pages_swept = 0;
4162 bool unused_page_present = false; 4163 bool unused_page_present = false;
4163 bool parallel_sweeping_active = false; 4164 bool parallel_sweeping_active = false;
4164 4165
4165 while (it.has_next()) { 4166 while (it.has_next()) {
4166 Page* p = it.next(); 4167 Page* p = it.next();
4167
4168 ASSERT(p->parallel_sweeping() == MemoryChunk::PARALLEL_SWEEPING_DONE); 4168 ASSERT(p->parallel_sweeping() == MemoryChunk::PARALLEL_SWEEPING_DONE);
4169 ASSERT(!p->IsEvacuationCandidate());
4170 4169
4171 // Clear sweeping flags indicating that marking bits are still intact. 4170 // Clear sweeping flags indicating that marking bits are still intact.
4172 p->ClearSweptPrecisely(); 4171 p->ClearSweptPrecisely();
4173 p->ClearSweptConservatively(); 4172 p->ClearSweptConservatively();
4174 4173
4175 if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) { 4174 if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION) ||
4175 p->IsEvacuationCandidate()) {
4176 // Will be processed in EvacuateNewSpaceAndCandidates. 4176 // Will be processed in EvacuateNewSpaceAndCandidates.
4177 ASSERT(evacuation_candidates_.length() > 0); 4177 ASSERT(evacuation_candidates_.length() > 0);
4178 continue; 4178 continue;
4179 } 4179 }
4180 4180
4181 // One unused page is kept, all further are released before sweeping them. 4181 // One unused page is kept, all further are released before sweeping them.
4182 if (p->LiveBytes() == 0) { 4182 if (p->LiveBytes() == 0) {
4183 if (unused_page_present) { 4183 if (unused_page_present) {
4184 if (FLAG_gc_verbose) { 4184 if (FLAG_gc_verbose) {
4185 PrintF("Sweeping 0x%" V8PRIxPTR " released page.\n", 4185 PrintF("Sweeping 0x%" V8PRIxPTR " released page.\n",
4186 reinterpret_cast<intptr_t>(p)); 4186 reinterpret_cast<intptr_t>(p));
4187 } 4187 }
4188 // Adjust unswept free bytes because releasing a page expects said 4188 // Adjust unswept free bytes because releasing a page expects said
4189 // counter to be accurate for unswept pages. 4189 // counter to be accurate for unswept pages.
4190 space->IncreaseUnsweptFreeBytes(p); 4190 space->IncreaseUnsweptFreeBytes(p);
4191 space->ReleasePage(p, true); 4191 space->ReleasePage(p);
4192 continue; 4192 continue;
4193 } 4193 }
4194 unused_page_present = true; 4194 unused_page_present = true;
4195 } 4195 }
4196 4196
4197 switch (sweeper) { 4197 switch (sweeper) {
4198 case CONSERVATIVE: { 4198 case CONSERVATIVE: {
4199 if (FLAG_gc_verbose) { 4199 if (FLAG_gc_verbose) {
4200 PrintF("Sweeping 0x%" V8PRIxPTR " conservatively.\n", 4200 PrintF("Sweeping 0x%" V8PRIxPTR " conservatively.\n",
4201 reinterpret_cast<intptr_t>(p)); 4201 reinterpret_cast<intptr_t>(p));
(...skipping 13 matching lines...) Expand all
4215 pages_swept++; 4215 pages_swept++;
4216 parallel_sweeping_active = true; 4216 parallel_sweeping_active = true;
4217 } else { 4217 } else {
4218 if (FLAG_gc_verbose) { 4218 if (FLAG_gc_verbose) {
4219 PrintF("Sweeping 0x%" V8PRIxPTR " conservatively in parallel.\n", 4219 PrintF("Sweeping 0x%" V8PRIxPTR " conservatively in parallel.\n",
4220 reinterpret_cast<intptr_t>(p)); 4220 reinterpret_cast<intptr_t>(p));
4221 } 4221 }
4222 p->set_parallel_sweeping(MemoryChunk::PARALLEL_SWEEPING_PENDING); 4222 p->set_parallel_sweeping(MemoryChunk::PARALLEL_SWEEPING_PENDING);
4223 space->IncreaseUnsweptFreeBytes(p); 4223 space->IncreaseUnsweptFreeBytes(p);
4224 } 4224 }
4225 space->set_end_of_unswept_pages(p);
4225 break; 4226 break;
4226 } 4227 }
4227 case PRECISE: { 4228 case PRECISE: {
4228 if (FLAG_gc_verbose) { 4229 if (FLAG_gc_verbose) {
4229 PrintF("Sweeping 0x%" V8PRIxPTR " precisely.\n", 4230 PrintF("Sweeping 0x%" V8PRIxPTR " precisely.\n",
4230 reinterpret_cast<intptr_t>(p)); 4231 reinterpret_cast<intptr_t>(p));
4231 } 4232 }
4232 if (space->identity() == CODE_SPACE && FLAG_zap_code_space) { 4233 if (space->identity() == CODE_SPACE && FLAG_zap_code_space) {
4233 SweepPrecisely<SWEEP_ONLY, REBUILD_SKIP_LIST, ZAP_FREE_SPACE>( 4234 SweepPrecisely<SWEEP_ONLY, REBUILD_SKIP_LIST, ZAP_FREE_SPACE>(
4234 space, p, NULL); 4235 space, p, NULL);
(...skipping 29 matching lines...) Expand all
4264 #ifdef DEBUG 4265 #ifdef DEBUG
4265 state_ = SWEEP_SPACES; 4266 state_ = SWEEP_SPACES;
4266 #endif 4267 #endif
4267 SweeperType how_to_sweep = CONSERVATIVE; 4268 SweeperType how_to_sweep = CONSERVATIVE;
4268 if (AreSweeperThreadsActivated()) { 4269 if (AreSweeperThreadsActivated()) {
4269 if (FLAG_parallel_sweeping) how_to_sweep = PARALLEL_CONSERVATIVE; 4270 if (FLAG_parallel_sweeping) how_to_sweep = PARALLEL_CONSERVATIVE;
4270 if (FLAG_concurrent_sweeping) how_to_sweep = CONCURRENT_CONSERVATIVE; 4271 if (FLAG_concurrent_sweeping) how_to_sweep = CONCURRENT_CONSERVATIVE;
4271 } 4272 }
4272 if (sweep_precisely_) how_to_sweep = PRECISE; 4273 if (sweep_precisely_) how_to_sweep = PRECISE;
4273 4274
4274 // Unlink evacuation candidates before sweeper threads access the list of 4275 // Moves the evacuation candidates to the ends of their corresponding pages
4275 // pages to avoid race condition. 4276 // list.
4276 UnlinkEvacuationCandidates(); 4277 MoveEvacuationCandidatesToEndOfPagesList();
4277 4278
4278 // Noncompacting collections simply sweep the spaces to clear the mark 4279 // Noncompacting collections simply sweep the spaces to clear the mark
4279 // bits and free the nonlive blocks (for old and map spaces). We sweep 4280 // bits and free the nonlive blocks (for old and map spaces). We sweep
4280 // the map space last because freeing non-live maps overwrites them and 4281 // the map space last because freeing non-live maps overwrites them and
4281 // the other spaces rely on possibly non-live maps to get the sizes for 4282 // the other spaces rely on possibly non-live maps to get the sizes for
4282 // non-live objects. 4283 // non-live objects.
4283 { GCTracer::Scope sweep_scope(tracer_, GCTracer::Scope::MC_SWEEP_OLDSPACE); 4284 { GCTracer::Scope sweep_scope(tracer_, GCTracer::Scope::MC_SWEEP_OLDSPACE);
4284 { SequentialSweepingScope scope(this); 4285 { SequentialSweepingScope scope(this);
4285 SweepSpace(heap()->old_pointer_space(), how_to_sweep); 4286 SweepSpace(heap()->old_pointer_space(), how_to_sweep);
4286 SweepSpace(heap()->old_data_space(), how_to_sweep); 4287 SweepSpace(heap()->old_data_space(), how_to_sweep);
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
4554 while (buffer != NULL) { 4555 while (buffer != NULL) {
4555 SlotsBuffer* next_buffer = buffer->next(); 4556 SlotsBuffer* next_buffer = buffer->next();
4556 DeallocateBuffer(buffer); 4557 DeallocateBuffer(buffer);
4557 buffer = next_buffer; 4558 buffer = next_buffer;
4558 } 4559 }
4559 *buffer_address = NULL; 4560 *buffer_address = NULL;
4560 } 4561 }
4561 4562
4562 4563
4563 } } // namespace v8::internal 4564 } } // namespace v8::internal
OLDNEW
« src/mark-compact.h ('K') | « src/mark-compact.h ('k') | src/spaces.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698