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

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

Issue 380653003: Allow main thread to contribute to the sweeping phase. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 5 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/spaces.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/code-stubs.h" 8 #include "src/code-stubs.h"
9 #include "src/compilation-cache.h" 9 #include "src/compilation-cache.h"
10 #include "src/cpu-profiler.h" 10 #include "src/cpu-profiler.h"
(...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 class MarkCompactCollector::SweeperTask : public v8::Task { 552 class MarkCompactCollector::SweeperTask : public v8::Task {
553 public: 553 public:
554 SweeperTask(Heap* heap, PagedSpace* space) 554 SweeperTask(Heap* heap, PagedSpace* space)
555 : heap_(heap), space_(space) {} 555 : heap_(heap), space_(space) {}
556 556
557 virtual ~SweeperTask() {} 557 virtual ~SweeperTask() {}
558 558
559 private: 559 private:
560 // v8::Task overrides. 560 // v8::Task overrides.
561 virtual void Run() V8_OVERRIDE { 561 virtual void Run() V8_OVERRIDE {
562 heap_->mark_compact_collector()->SweepInParallel(space_); 562 heap_->mark_compact_collector()->SweepInParallel(space_, 0);
563 heap_->mark_compact_collector()->pending_sweeper_jobs_semaphore_.Signal(); 563 heap_->mark_compact_collector()->pending_sweeper_jobs_semaphore_.Signal();
564 } 564 }
565 565
566 Heap* heap_; 566 Heap* heap_;
567 PagedSpace* space_; 567 PagedSpace* space_;
568 568
569 DISALLOW_COPY_AND_ASSIGN(SweeperTask); 569 DISALLOW_COPY_AND_ASSIGN(SweeperTask);
570 }; 570 };
571 571
572 572
(...skipping 2964 matching lines...) Expand 10 before | Expand all | Expand 10 after
3537 } else { 3537 } else {
3538 if (FLAG_gc_verbose) { 3538 if (FLAG_gc_verbose) {
3539 PrintF("Sweeping 0x%" V8PRIxPTR " during evacuation.\n", 3539 PrintF("Sweeping 0x%" V8PRIxPTR " during evacuation.\n",
3540 reinterpret_cast<intptr_t>(p)); 3540 reinterpret_cast<intptr_t>(p));
3541 } 3541 }
3542 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); 3542 PagedSpace* space = static_cast<PagedSpace*>(p->owner());
3543 p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION); 3543 p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION);
3544 3544
3545 switch (space->identity()) { 3545 switch (space->identity()) {
3546 case OLD_DATA_SPACE: 3546 case OLD_DATA_SPACE:
3547 SweepConservatively<SWEEP_SEQUENTIALLY>(space, NULL, p); 3547 SweepConservatively<SWEEP_ON_MAIN_THREAD>(space, NULL, p);
3548 break; 3548 break;
3549 case OLD_POINTER_SPACE: 3549 case OLD_POINTER_SPACE:
3550 SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS, 3550 SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS,
3551 IGNORE_SKIP_LIST, 3551 IGNORE_SKIP_LIST,
3552 IGNORE_FREE_SPACE>( 3552 IGNORE_FREE_SPACE>(
3553 space, p, &updating_visitor); 3553 space, p, &updating_visitor);
3554 break; 3554 break;
3555 case CODE_SPACE: 3555 case CODE_SPACE:
3556 if (FLAG_zap_code_space) { 3556 if (FLAG_zap_code_space) {
3557 SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS, 3557 SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS,
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after
3932 USE(live_objects); 3932 USE(live_objects);
3933 return block_address + offsets[0] * kPointerSize; 3933 return block_address + offsets[0] * kPointerSize;
3934 } 3934 }
3935 3935
3936 3936
3937 template<MarkCompactCollector::SweepingParallelism mode> 3937 template<MarkCompactCollector::SweepingParallelism mode>
3938 static intptr_t Free(PagedSpace* space, 3938 static intptr_t Free(PagedSpace* space,
3939 FreeList* free_list, 3939 FreeList* free_list,
3940 Address start, 3940 Address start,
3941 int size) { 3941 int size) {
3942 if (mode == MarkCompactCollector::SWEEP_SEQUENTIALLY) { 3942 if (mode == MarkCompactCollector::SWEEP_ON_MAIN_THREAD) {
3943 return space->Free(start, size); 3943 return space->Free(start, size);
3944 } else { 3944 } else {
3945 return size - free_list->Free(start, size); 3945 return size - free_list->Free(start, size);
3946 } 3946 }
3947 } 3947 }
3948 3948
3949 3949
3950 // Force instantiation of templatized SweepConservatively method for 3950 // Force instantiation of templatized SweepConservatively method for
3951 // SWEEP_SEQUENTIALLY mode. 3951 // SWEEP_ON_MAIN_THREAD mode.
3952 template intptr_t MarkCompactCollector:: 3952 template intptr_t MarkCompactCollector::
3953 SweepConservatively<MarkCompactCollector::SWEEP_SEQUENTIALLY>( 3953 SweepConservatively<MarkCompactCollector::SWEEP_ON_MAIN_THREAD>(
3954 PagedSpace*, FreeList*, Page*); 3954 PagedSpace*, FreeList*, Page*);
3955 3955
3956 3956
3957 // Force instantiation of templatized SweepConservatively method for 3957 // Force instantiation of templatized SweepConservatively method for
3958 // SWEEP_IN_PARALLEL mode. 3958 // SWEEP_IN_PARALLEL mode.
3959 template intptr_t MarkCompactCollector:: 3959 template intptr_t MarkCompactCollector::
3960 SweepConservatively<MarkCompactCollector::SWEEP_IN_PARALLEL>( 3960 SweepConservatively<MarkCompactCollector::SWEEP_IN_PARALLEL>(
3961 PagedSpace*, FreeList*, Page*); 3961 PagedSpace*, FreeList*, Page*);
3962 3962
3963 3963
3964 // Sweeps a space conservatively. After this has been done the larger free 3964 // Sweeps a space conservatively. After this has been done the larger free
3965 // spaces have been put on the free list and the smaller ones have been 3965 // spaces have been put on the free list and the smaller ones have been
3966 // ignored and left untouched. A free space is always either ignored or put 3966 // ignored and left untouched. A free space is always either ignored or put
3967 // on the free list, never split up into two parts. This is important 3967 // on the free list, never split up into two parts. This is important
3968 // because it means that any FreeSpace maps left actually describe a region of 3968 // because it means that any FreeSpace maps left actually describe a region of
3969 // memory that can be ignored when scanning. Dead objects other than free 3969 // memory that can be ignored when scanning. Dead objects other than free
3970 // spaces will not contain the free space map. 3970 // spaces will not contain the free space map.
3971 template<MarkCompactCollector::SweepingParallelism mode> 3971 template<MarkCompactCollector::SweepingParallelism mode>
3972 intptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space, 3972 intptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space,
3973 FreeList* free_list, 3973 FreeList* free_list,
3974 Page* p) { 3974 Page* p) {
3975 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept()); 3975 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept());
3976 ASSERT((mode == MarkCompactCollector::SWEEP_IN_PARALLEL && 3976 ASSERT((mode == MarkCompactCollector::SWEEP_IN_PARALLEL &&
3977 free_list != NULL) || 3977 free_list != NULL) ||
3978 (mode == MarkCompactCollector::SWEEP_SEQUENTIALLY && 3978 (mode == MarkCompactCollector::SWEEP_ON_MAIN_THREAD &&
3979 free_list == NULL)); 3979 free_list == NULL));
3980 3980
3981 // When parallel sweeping is active, the page will be marked after 3981 // When parallel sweeping is active, the page will be marked after
3982 // sweeping by the main thread. 3982 // sweeping by the main thread.
3983 if (mode != MarkCompactCollector::SWEEP_IN_PARALLEL) { 3983 if (mode == MarkCompactCollector::SWEEP_IN_PARALLEL) {
3984 p->set_parallel_sweeping(MemoryChunk::PARALLEL_SWEEPING_FINALIZE);
3985 } else {
3984 p->MarkSweptConservatively(); 3986 p->MarkSweptConservatively();
3985 } 3987 }
3986 3988
3987 intptr_t freed_bytes = 0; 3989 intptr_t freed_bytes = 0;
3990 intptr_t max_freed_bytes = 0;
3988 size_t size = 0; 3991 size_t size = 0;
3989 3992
3990 // Skip over all the dead objects at the start of the page and mark them free. 3993 // Skip over all the dead objects at the start of the page and mark them free.
3991 Address cell_base = 0; 3994 Address cell_base = 0;
3992 MarkBit::CellType* cell = NULL; 3995 MarkBit::CellType* cell = NULL;
3993 MarkBitCellIterator it(p); 3996 MarkBitCellIterator it(p);
3994 for (; !it.Done(); it.Advance()) { 3997 for (; !it.Done(); it.Advance()) {
3995 cell_base = it.CurrentCellBase(); 3998 cell_base = it.CurrentCellBase();
3996 cell = it.CurrentCell(); 3999 cell = it.CurrentCell();
3997 if (*cell != 0) break; 4000 if (*cell != 0) break;
3998 } 4001 }
3999 4002
4000 if (it.Done()) { 4003 if (it.Done()) {
4001 size = p->area_end() - p->area_start(); 4004 size = p->area_end() - p->area_start();
4002 freed_bytes += Free<mode>(space, free_list, p->area_start(), 4005 freed_bytes = Free<mode>(space, free_list, p->area_start(),
4003 static_cast<int>(size)); 4006 static_cast<int>(size));
4007 max_freed_bytes = Max(freed_bytes, max_freed_bytes);
4004 ASSERT_EQ(0, p->LiveBytes()); 4008 ASSERT_EQ(0, p->LiveBytes());
4005 return freed_bytes; 4009 return freed_bytes;
4006 } 4010 }
4007 4011
4008 // Grow the size of the start-of-page free space a little to get up to the 4012 // Grow the size of the start-of-page free space a little to get up to the
4009 // first live object. 4013 // first live object.
4010 Address free_end = StartOfLiveObject(cell_base, *cell); 4014 Address free_end = StartOfLiveObject(cell_base, *cell);
4011 // Free the first free space. 4015 // Free the first free space.
4012 size = free_end - p->area_start(); 4016 size = free_end - p->area_start();
4013 freed_bytes += Free<mode>(space, free_list, p->area_start(), 4017 freed_bytes = Free<mode>(space, free_list, p->area_start(),
4014 static_cast<int>(size)); 4018 static_cast<int>(size));
4019 max_freed_bytes = Max(freed_bytes, max_freed_bytes);
4015 4020
4016 // The start of the current free area is represented in undigested form by 4021 // The start of the current free area is represented in undigested form by
4017 // the address of the last 32-word section that contained a live object and 4022 // the address of the last 32-word section that contained a live object and
4018 // the marking bitmap for that cell, which describes where the live object 4023 // the marking bitmap for that cell, which describes where the live object
4019 // started. Unless we find a large free space in the bitmap we will not 4024 // started. Unless we find a large free space in the bitmap we will not
4020 // digest this pair into a real address. We start the iteration here at the 4025 // digest this pair into a real address. We start the iteration here at the
4021 // first word in the marking bit map that indicates a live object. 4026 // first word in the marking bit map that indicates a live object.
4022 Address free_start = cell_base; 4027 Address free_start = cell_base;
4023 MarkBit::CellType free_start_cell = *cell; 4028 MarkBit::CellType free_start_cell = *cell;
4024 4029
4025 for (; !it.Done(); it.Advance()) { 4030 for (; !it.Done(); it.Advance()) {
4026 cell_base = it.CurrentCellBase(); 4031 cell_base = it.CurrentCellBase();
4027 cell = it.CurrentCell(); 4032 cell = it.CurrentCell();
4028 if (*cell != 0) { 4033 if (*cell != 0) {
4029 // We have a live object. Check approximately whether it is more than 32 4034 // We have a live object. Check approximately whether it is more than 32
4030 // words since the last live object. 4035 // words since the last live object.
4031 if (cell_base - free_start > 32 * kPointerSize) { 4036 if (cell_base - free_start > 32 * kPointerSize) {
4032 free_start = DigestFreeStart(free_start, free_start_cell); 4037 free_start = DigestFreeStart(free_start, free_start_cell);
4033 if (cell_base - free_start > 32 * kPointerSize) { 4038 if (cell_base - free_start > 32 * kPointerSize) {
4034 // Now that we know the exact start of the free space it still looks 4039 // Now that we know the exact start of the free space it still looks
4035 // like we have a large enough free space to be worth bothering with. 4040 // like we have a large enough free space to be worth bothering with.
4036 // so now we need to find the start of the first live object at the 4041 // so now we need to find the start of the first live object at the
4037 // end of the free space. 4042 // end of the free space.
4038 free_end = StartOfLiveObject(cell_base, *cell); 4043 free_end = StartOfLiveObject(cell_base, *cell);
4039 freed_bytes += Free<mode>(space, free_list, free_start, 4044 freed_bytes = Free<mode>(space, free_list, free_start,
4040 static_cast<int>(free_end - free_start)); 4045 static_cast<int>(free_end - free_start));
4046 max_freed_bytes = Max(freed_bytes, max_freed_bytes);
4041 } 4047 }
4042 } 4048 }
4043 // Update our undigested record of where the current free area started. 4049 // Update our undigested record of where the current free area started.
4044 free_start = cell_base; 4050 free_start = cell_base;
4045 free_start_cell = *cell; 4051 free_start_cell = *cell;
4046 // Clear marking bits for current cell. 4052 // Clear marking bits for current cell.
4047 *cell = 0; 4053 *cell = 0;
4048 } 4054 }
4049 } 4055 }
4050 4056
4051 // Handle the free space at the end of the page. 4057 // Handle the free space at the end of the page.
4052 if (cell_base - free_start > 32 * kPointerSize) { 4058 if (cell_base - free_start > 32 * kPointerSize) {
4053 free_start = DigestFreeStart(free_start, free_start_cell); 4059 free_start = DigestFreeStart(free_start, free_start_cell);
4054 freed_bytes += Free<mode>(space, free_list, free_start, 4060 freed_bytes = Free<mode>(space, free_list, free_start,
4055 static_cast<int>(p->area_end() - free_start)); 4061 static_cast<int>(p->area_end() - free_start));
4062 max_freed_bytes = Max(freed_bytes, max_freed_bytes);
4056 } 4063 }
4057 4064
4058 p->ResetLiveBytes(); 4065 p->ResetLiveBytes();
4059 return freed_bytes; 4066 return max_freed_bytes;
4060 } 4067 }
4061 4068
4062 4069
4063 void MarkCompactCollector::SweepInParallel(PagedSpace* space) { 4070 int MarkCompactCollector::SweepInParallel(PagedSpace* space,
4071 int required_freed_bytes) {
4064 PageIterator it(space); 4072 PageIterator it(space);
4065 FreeList* free_list = space == heap()->old_pointer_space() 4073 FreeList* free_list = space == heap()->old_pointer_space()
4066 ? free_list_old_pointer_space_.get() 4074 ? free_list_old_pointer_space_.get()
4067 : free_list_old_data_space_.get(); 4075 : free_list_old_data_space_.get();
4068 FreeList private_free_list(space); 4076 FreeList private_free_list(space);
4077 int max_freed = 0;
Jarin 2014/07/10 12:12:20 Nit: you could remove this line and declare the in
4078 int max_freed_overall = 0;
4069 while (it.has_next()) { 4079 while (it.has_next()) {
4070 Page* p = it.next(); 4080 Page* p = it.next();
4071 4081
4072 if (p->TryParallelSweeping()) { 4082 if (p->TryParallelSweeping()) {
4073 SweepConservatively<SWEEP_IN_PARALLEL>(space, &private_free_list, p); 4083 max_freed = SweepConservatively<SWEEP_IN_PARALLEL>(
4084 space, &private_free_list, p);
4074 free_list->Concatenate(&private_free_list); 4085 free_list->Concatenate(&private_free_list);
4075 p->set_parallel_sweeping(MemoryChunk::PARALLEL_SWEEPING_FINALIZE); 4086 if (required_freed_bytes > 0 && max_freed >= required_freed_bytes) {
4087 return max_freed;
4088 }
4089 max_freed_overall = Max(max_freed, max_freed_overall);
4076 } 4090 }
4077 if (p == space->end_of_unswept_pages()) break; 4091 if (p == space->end_of_unswept_pages()) break;
4078 } 4092 }
4093 return max_freed_overall;
4079 } 4094 }
4080 4095
4081 4096
4082 void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) { 4097 void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) {
4083 space->set_is_iterable(sweeper == PRECISE); 4098 space->set_is_iterable(sweeper == PRECISE);
4084 space->set_is_swept_concurrently(sweeper == CONCURRENT_CONSERVATIVE); 4099 space->set_is_swept_concurrently(sweeper == CONCURRENT_CONSERVATIVE);
4085 space->ClearStats(); 4100 space->ClearStats();
4086 4101
4087 // We defensively initialize end_of_unswept_pages_ here with the first page 4102 // We defensively initialize end_of_unswept_pages_ here with the first page
4088 // of the pages list. 4103 // of the pages list.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
4124 } 4139 }
4125 unused_page_present = true; 4140 unused_page_present = true;
4126 } 4141 }
4127 4142
4128 switch (sweeper) { 4143 switch (sweeper) {
4129 case CONSERVATIVE: { 4144 case CONSERVATIVE: {
4130 if (FLAG_gc_verbose) { 4145 if (FLAG_gc_verbose) {
4131 PrintF("Sweeping 0x%" V8PRIxPTR " conservatively.\n", 4146 PrintF("Sweeping 0x%" V8PRIxPTR " conservatively.\n",
4132 reinterpret_cast<intptr_t>(p)); 4147 reinterpret_cast<intptr_t>(p));
4133 } 4148 }
4134 SweepConservatively<SWEEP_SEQUENTIALLY>(space, NULL, p); 4149 SweepConservatively<SWEEP_ON_MAIN_THREAD>(space, NULL, p);
4135 pages_swept++; 4150 pages_swept++;
4136 break; 4151 break;
4137 } 4152 }
4138 case CONCURRENT_CONSERVATIVE: 4153 case CONCURRENT_CONSERVATIVE:
4139 case PARALLEL_CONSERVATIVE: { 4154 case PARALLEL_CONSERVATIVE: {
4140 if (!parallel_sweeping_active) { 4155 if (!parallel_sweeping_active) {
4141 if (FLAG_gc_verbose) { 4156 if (FLAG_gc_verbose) {
4142 PrintF("Sweeping 0x%" V8PRIxPTR " conservatively.\n", 4157 PrintF("Sweeping 0x%" V8PRIxPTR " conservatively.\n",
4143 reinterpret_cast<intptr_t>(p)); 4158 reinterpret_cast<intptr_t>(p));
4144 } 4159 }
4145 SweepConservatively<SWEEP_SEQUENTIALLY>(space, NULL, p); 4160 SweepConservatively<SWEEP_ON_MAIN_THREAD>(space, NULL, p);
4146 pages_swept++; 4161 pages_swept++;
4147 parallel_sweeping_active = true; 4162 parallel_sweeping_active = true;
4148 } else { 4163 } else {
4149 if (p->scan_on_scavenge()) { 4164 if (p->scan_on_scavenge()) {
4150 SweepPrecisely<SWEEP_ONLY, IGNORE_SKIP_LIST, IGNORE_FREE_SPACE>( 4165 SweepPrecisely<SWEEP_ONLY, IGNORE_SKIP_LIST, IGNORE_FREE_SPACE>(
4151 space, p, NULL); 4166 space, p, NULL);
4152 pages_swept++; 4167 pages_swept++;
4153 if (FLAG_gc_verbose) { 4168 if (FLAG_gc_verbose) {
4154 PrintF("Sweeping 0x%" V8PRIxPTR 4169 PrintF("Sweeping 0x%" V8PRIxPTR
4155 " scan on scavenge page precisely.\n", 4170 " scan on scavenge page precisely.\n",
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
4501 while (buffer != NULL) { 4516 while (buffer != NULL) {
4502 SlotsBuffer* next_buffer = buffer->next(); 4517 SlotsBuffer* next_buffer = buffer->next();
4503 DeallocateBuffer(buffer); 4518 DeallocateBuffer(buffer);
4504 buffer = next_buffer; 4519 buffer = next_buffer;
4505 } 4520 }
4506 *buffer_address = NULL; 4521 *buffer_address = NULL;
4507 } 4522 }
4508 4523
4509 4524
4510 } } // namespace v8::internal 4525 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/mark-compact.h ('k') | src/spaces.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698