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

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.cc » ('j') | src/spaces.cc » ('J')
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<SWEEP_IN_PARALLEL>(
563 space_, 0);
563 heap_->mark_compact_collector()->pending_sweeper_jobs_semaphore_.Signal(); 564 heap_->mark_compact_collector()->pending_sweeper_jobs_semaphore_.Signal();
564 } 565 }
565 566
566 Heap* heap_; 567 Heap* heap_;
567 PagedSpace* space_; 568 PagedSpace* space_;
568 569
569 DISALLOW_COPY_AND_ASSIGN(SweeperTask); 570 DISALLOW_COPY_AND_ASSIGN(SweeperTask);
570 }; 571 };
571 572
572 573
(...skipping 2964 matching lines...) Expand 10 before | Expand all | Expand 10 after
3537 } else { 3538 } else {
3538 if (FLAG_gc_verbose) { 3539 if (FLAG_gc_verbose) {
3539 PrintF("Sweeping 0x%" V8PRIxPTR " during evacuation.\n", 3540 PrintF("Sweeping 0x%" V8PRIxPTR " during evacuation.\n",
3540 reinterpret_cast<intptr_t>(p)); 3541 reinterpret_cast<intptr_t>(p));
3541 } 3542 }
3542 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); 3543 PagedSpace* space = static_cast<PagedSpace*>(p->owner());
3543 p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION); 3544 p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION);
3544 3545
3545 switch (space->identity()) { 3546 switch (space->identity()) {
3546 case OLD_DATA_SPACE: 3547 case OLD_DATA_SPACE:
3547 SweepConservatively<SWEEP_SEQUENTIALLY>(space, NULL, p); 3548 SweepConservatively<SWEEP_ON_MAIN_THREAD>(space, NULL, p);
3548 break; 3549 break;
3549 case OLD_POINTER_SPACE: 3550 case OLD_POINTER_SPACE:
3550 SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS, 3551 SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS,
3551 IGNORE_SKIP_LIST, 3552 IGNORE_SKIP_LIST,
3552 IGNORE_FREE_SPACE>( 3553 IGNORE_FREE_SPACE>(
3553 space, p, &updating_visitor); 3554 space, p, &updating_visitor);
3554 break; 3555 break;
3555 case CODE_SPACE: 3556 case CODE_SPACE:
3556 if (FLAG_zap_code_space) { 3557 if (FLAG_zap_code_space) {
3557 SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS, 3558 SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS,
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after
3932 USE(live_objects); 3933 USE(live_objects);
3933 return block_address + offsets[0] * kPointerSize; 3934 return block_address + offsets[0] * kPointerSize;
3934 } 3935 }
3935 3936
3936 3937
3937 template<MarkCompactCollector::SweepingParallelism mode> 3938 template<MarkCompactCollector::SweepingParallelism mode>
3938 static intptr_t Free(PagedSpace* space, 3939 static intptr_t Free(PagedSpace* space,
3939 FreeList* free_list, 3940 FreeList* free_list,
3940 Address start, 3941 Address start,
3941 int size) { 3942 int size) {
3942 if (mode == MarkCompactCollector::SWEEP_SEQUENTIALLY) { 3943 if (mode == MarkCompactCollector::SWEEP_ON_MAIN_THREAD) {
3943 return space->Free(start, size); 3944 return space->Free(start, size);
3944 } else { 3945 } else {
3945 return size - free_list->Free(start, size); 3946 return size - free_list->Free(start, size);
3946 } 3947 }
3947 } 3948 }
3948 3949
3949 3950
3950 // Force instantiation of templatized SweepConservatively method for 3951 // Force instantiation of templatized SweepConservatively method for
3951 // SWEEP_SEQUENTIALLY mode. 3952 // SWEEP_ON_MAIN_THREAD mode.
3952 template intptr_t MarkCompactCollector:: 3953 template intptr_t MarkCompactCollector::
3953 SweepConservatively<MarkCompactCollector::SWEEP_SEQUENTIALLY>( 3954 SweepConservatively<MarkCompactCollector::SWEEP_ON_MAIN_THREAD>(
3954 PagedSpace*, FreeList*, Page*); 3955 PagedSpace*, FreeList*, Page*);
3955 3956
3956 3957
3957 // Force instantiation of templatized SweepConservatively method for 3958 // Force instantiation of templatized SweepConservatively method for
3958 // SWEEP_IN_PARALLEL mode. 3959 // SWEEP_IN_PARALLEL mode.
3959 template intptr_t MarkCompactCollector:: 3960 template intptr_t MarkCompactCollector::
3960 SweepConservatively<MarkCompactCollector::SWEEP_IN_PARALLEL>( 3961 SweepConservatively<MarkCompactCollector::SWEEP_IN_PARALLEL>(
3961 PagedSpace*, FreeList*, Page*); 3962 PagedSpace*, FreeList*, Page*);
3962 3963
3963 3964
3964 // Sweeps a space conservatively. After this has been done the larger free 3965 // 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 3966 // 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 3967 // 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 3968 // 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 3969 // 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 3970 // memory that can be ignored when scanning. Dead objects other than free
3970 // spaces will not contain the free space map. 3971 // spaces will not contain the free space map.
3971 template<MarkCompactCollector::SweepingParallelism mode> 3972 template<MarkCompactCollector::SweepingParallelism mode>
3972 intptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space, 3973 intptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space,
3973 FreeList* free_list, 3974 FreeList* free_list,
3974 Page* p) { 3975 Page* p) {
3975 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept()); 3976 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept());
3976 ASSERT((mode == MarkCompactCollector::SWEEP_IN_PARALLEL && 3977 ASSERT((mode == MarkCompactCollector::SWEEP_IN_PARALLEL &&
3977 free_list != NULL) || 3978 free_list != NULL) ||
3978 (mode == MarkCompactCollector::SWEEP_SEQUENTIALLY && 3979 (mode == MarkCompactCollector::SWEEP_ON_MAIN_THREAD &&
3979 free_list == NULL)); 3980 free_list == NULL));
3980 3981
3981 // When parallel sweeping is active, the page will be marked after 3982 // When parallel sweeping is active, the page will be marked after
3982 // sweeping by the main thread. 3983 // sweeping by the main thread.
3983 if (mode != MarkCompactCollector::SWEEP_IN_PARALLEL) { 3984 if (mode != MarkCompactCollector::SWEEP_IN_PARALLEL) {
3984 p->MarkSweptConservatively(); 3985 p->MarkSweptConservatively();
3985 } 3986 }
3986 3987
3987 intptr_t freed_bytes = 0; 3988 intptr_t freed_bytes = 0;
3989 intptr_t max_freed_bytes = 0;
3988 size_t size = 0; 3990 size_t size = 0;
3989 3991
3990 // Skip over all the dead objects at the start of the page and mark them free. 3992 // Skip over all the dead objects at the start of the page and mark them free.
3991 Address cell_base = 0; 3993 Address cell_base = 0;
3992 MarkBit::CellType* cell = NULL; 3994 MarkBit::CellType* cell = NULL;
3993 MarkBitCellIterator it(p); 3995 MarkBitCellIterator it(p);
3994 for (; !it.Done(); it.Advance()) { 3996 for (; !it.Done(); it.Advance()) {
3995 cell_base = it.CurrentCellBase(); 3997 cell_base = it.CurrentCellBase();
3996 cell = it.CurrentCell(); 3998 cell = it.CurrentCell();
3997 if (*cell != 0) break; 3999 if (*cell != 0) break;
3998 } 4000 }
3999 4001
4000 if (it.Done()) { 4002 if (it.Done()) {
4001 size = p->area_end() - p->area_start(); 4003 size = p->area_end() - p->area_start();
4002 freed_bytes += Free<mode>(space, free_list, p->area_start(), 4004 freed_bytes = Free<mode>(space, free_list, p->area_start(),
4003 static_cast<int>(size)); 4005 static_cast<int>(size));
4006 max_freed_bytes = Max(freed_bytes, max_freed_bytes);
4004 ASSERT_EQ(0, p->LiveBytes()); 4007 ASSERT_EQ(0, p->LiveBytes());
4005 return freed_bytes; 4008 return freed_bytes;
4006 } 4009 }
4007 4010
4008 // Grow the size of the start-of-page free space a little to get up to the 4011 // Grow the size of the start-of-page free space a little to get up to the
4009 // first live object. 4012 // first live object.
4010 Address free_end = StartOfLiveObject(cell_base, *cell); 4013 Address free_end = StartOfLiveObject(cell_base, *cell);
4011 // Free the first free space. 4014 // Free the first free space.
4012 size = free_end - p->area_start(); 4015 size = free_end - p->area_start();
4013 freed_bytes += Free<mode>(space, free_list, p->area_start(), 4016 freed_bytes = Free<mode>(space, free_list, p->area_start(),
4014 static_cast<int>(size)); 4017 static_cast<int>(size));
4018 max_freed_bytes = Max(freed_bytes, max_freed_bytes);
4015 4019
4016 // The start of the current free area is represented in undigested form by 4020 // 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 4021 // 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 4022 // 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 4023 // 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 4024 // 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. 4025 // first word in the marking bit map that indicates a live object.
4022 Address free_start = cell_base; 4026 Address free_start = cell_base;
4023 MarkBit::CellType free_start_cell = *cell; 4027 MarkBit::CellType free_start_cell = *cell;
4024 4028
4025 for (; !it.Done(); it.Advance()) { 4029 for (; !it.Done(); it.Advance()) {
4026 cell_base = it.CurrentCellBase(); 4030 cell_base = it.CurrentCellBase();
4027 cell = it.CurrentCell(); 4031 cell = it.CurrentCell();
4028 if (*cell != 0) { 4032 if (*cell != 0) {
4029 // We have a live object. Check approximately whether it is more than 32 4033 // We have a live object. Check approximately whether it is more than 32
4030 // words since the last live object. 4034 // words since the last live object.
4031 if (cell_base - free_start > 32 * kPointerSize) { 4035 if (cell_base - free_start > 32 * kPointerSize) {
4032 free_start = DigestFreeStart(free_start, free_start_cell); 4036 free_start = DigestFreeStart(free_start, free_start_cell);
4033 if (cell_base - free_start > 32 * kPointerSize) { 4037 if (cell_base - free_start > 32 * kPointerSize) {
4034 // Now that we know the exact start of the free space it still looks 4038 // 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. 4039 // 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 4040 // so now we need to find the start of the first live object at the
4037 // end of the free space. 4041 // end of the free space.
4038 free_end = StartOfLiveObject(cell_base, *cell); 4042 free_end = StartOfLiveObject(cell_base, *cell);
4039 freed_bytes += Free<mode>(space, free_list, free_start, 4043 freed_bytes = Free<mode>(space, free_list, free_start,
4040 static_cast<int>(free_end - free_start)); 4044 static_cast<int>(free_end - free_start));
4045 max_freed_bytes = Max(freed_bytes, max_freed_bytes);
4041 } 4046 }
4042 } 4047 }
4043 // Update our undigested record of where the current free area started. 4048 // Update our undigested record of where the current free area started.
4044 free_start = cell_base; 4049 free_start = cell_base;
4045 free_start_cell = *cell; 4050 free_start_cell = *cell;
4046 // Clear marking bits for current cell. 4051 // Clear marking bits for current cell.
4047 *cell = 0; 4052 *cell = 0;
4048 } 4053 }
4049 } 4054 }
4050 4055
4051 // Handle the free space at the end of the page. 4056 // Handle the free space at the end of the page.
4052 if (cell_base - free_start > 32 * kPointerSize) { 4057 if (cell_base - free_start > 32 * kPointerSize) {
4053 free_start = DigestFreeStart(free_start, free_start_cell); 4058 free_start = DigestFreeStart(free_start, free_start_cell);
4054 freed_bytes += Free<mode>(space, free_list, free_start, 4059 freed_bytes = Free<mode>(space, free_list, free_start,
4055 static_cast<int>(p->area_end() - free_start)); 4060 static_cast<int>(p->area_end() - free_start));
4061 max_freed_bytes = Max(freed_bytes, max_freed_bytes);
4056 } 4062 }
4057 4063
4058 p->ResetLiveBytes(); 4064 p->ResetLiveBytes();
4059 return freed_bytes; 4065 return max_freed_bytes;
4060 } 4066 }
4061 4067
4062 4068
4063 void MarkCompactCollector::SweepInParallel(PagedSpace* space) { 4069 // Force instantiation of templatized SweepInParallel method for
Jarin 2014/07/09 11:02:02 Is the templatization of SweepInParallel really ne
Hannes Payer (out of office) 2014/07/10 12:03:45 Done. It would make sense to remove the template
4070 // SWEEP_ON_MAIN_THREAD mode.
4071 template int MarkCompactCollector::
4072 SweepInParallel<MarkCompactCollector::SWEEP_ON_MAIN_THREAD>(
4073 PagedSpace*, int);
4074
4075
4076 // Force instantiation of templatized SweepInParallel method for
4077 // SWEEP_IN_PARALLEL mode.
4078 template int MarkCompactCollector::
4079 SweepInParallel<MarkCompactCollector::SWEEP_IN_PARALLEL>(
4080 PagedSpace*, int);
4081
4082
4083 template<MarkCompactCollector::SweepingParallelism type>
4084 int MarkCompactCollector::SweepInParallel(PagedSpace* space,
4085 int required_freed_bytes) {
4064 PageIterator it(space); 4086 PageIterator it(space);
4065 FreeList* free_list = space == heap()->old_pointer_space() 4087 FreeList* free_list = space == heap()->old_pointer_space()
4066 ? free_list_old_pointer_space_.get() 4088 ? free_list_old_pointer_space_.get()
4067 : free_list_old_data_space_.get(); 4089 : free_list_old_data_space_.get();
4068 FreeList private_free_list(space); 4090 FreeList private_free_list(space);
4091 int max_freed = 0;
4069 while (it.has_next()) { 4092 while (it.has_next()) {
4070 Page* p = it.next(); 4093 Page* p = it.next();
4071 4094
4072 if (p->TryParallelSweeping()) { 4095 if (p->TryParallelSweeping()) {
4073 SweepConservatively<SWEEP_IN_PARALLEL>(space, &private_free_list, p); 4096 if (type == SWEEP_IN_PARALLEL) {
4074 free_list->Concatenate(&private_free_list); 4097 max_freed = SweepConservatively<SWEEP_IN_PARALLEL>(
4098 space, &private_free_list, p);
4099 free_list->Concatenate(&private_free_list);
4100 } else {
4101 max_freed = SweepConservatively<SWEEP_ON_MAIN_THREAD>(space, NULL, p);
4102 }
4075 p->set_parallel_sweeping(MemoryChunk::PARALLEL_SWEEPING_FINALIZE); 4103 p->set_parallel_sweeping(MemoryChunk::PARALLEL_SWEEPING_FINALIZE);
4104 if (required_freed_bytes > 0 && max_freed >= required_freed_bytes) {
4105 return max_freed;
4106 }
4076 } 4107 }
4077 if (p == space->end_of_unswept_pages()) break; 4108 if (p == space->end_of_unswept_pages()) break;
4078 } 4109 }
4110 return max_freed;
Jarin 2014/07/09 11:02:02 For consistency, should not this return the maximu
Hannes Payer (out of office) 2014/07/10 12:03:45 Done.
4079 } 4111 }
4080 4112
4081 4113
4082 void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) { 4114 void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) {
4083 space->set_is_iterable(sweeper == PRECISE); 4115 space->set_is_iterable(sweeper == PRECISE);
4084 space->set_is_swept_concurrently(sweeper == CONCURRENT_CONSERVATIVE); 4116 space->set_is_swept_concurrently(sweeper == CONCURRENT_CONSERVATIVE);
4085 space->ClearStats(); 4117 space->ClearStats();
4086 4118
4087 // We defensively initialize end_of_unswept_pages_ here with the first page 4119 // We defensively initialize end_of_unswept_pages_ here with the first page
4088 // of the pages list. 4120 // of the pages list.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
4124 } 4156 }
4125 unused_page_present = true; 4157 unused_page_present = true;
4126 } 4158 }
4127 4159
4128 switch (sweeper) { 4160 switch (sweeper) {
4129 case CONSERVATIVE: { 4161 case CONSERVATIVE: {
4130 if (FLAG_gc_verbose) { 4162 if (FLAG_gc_verbose) {
4131 PrintF("Sweeping 0x%" V8PRIxPTR " conservatively.\n", 4163 PrintF("Sweeping 0x%" V8PRIxPTR " conservatively.\n",
4132 reinterpret_cast<intptr_t>(p)); 4164 reinterpret_cast<intptr_t>(p));
4133 } 4165 }
4134 SweepConservatively<SWEEP_SEQUENTIALLY>(space, NULL, p); 4166 SweepConservatively<SWEEP_ON_MAIN_THREAD>(space, NULL, p);
4135 pages_swept++; 4167 pages_swept++;
4136 break; 4168 break;
4137 } 4169 }
4138 case CONCURRENT_CONSERVATIVE: 4170 case CONCURRENT_CONSERVATIVE:
4139 case PARALLEL_CONSERVATIVE: { 4171 case PARALLEL_CONSERVATIVE: {
4140 if (!parallel_sweeping_active) { 4172 if (!parallel_sweeping_active) {
4141 if (FLAG_gc_verbose) { 4173 if (FLAG_gc_verbose) {
4142 PrintF("Sweeping 0x%" V8PRIxPTR " conservatively.\n", 4174 PrintF("Sweeping 0x%" V8PRIxPTR " conservatively.\n",
4143 reinterpret_cast<intptr_t>(p)); 4175 reinterpret_cast<intptr_t>(p));
4144 } 4176 }
4145 SweepConservatively<SWEEP_SEQUENTIALLY>(space, NULL, p); 4177 SweepConservatively<SWEEP_ON_MAIN_THREAD>(space, NULL, p);
4146 pages_swept++; 4178 pages_swept++;
4147 parallel_sweeping_active = true; 4179 parallel_sweeping_active = true;
4148 } else { 4180 } else {
4149 if (p->scan_on_scavenge()) { 4181 if (p->scan_on_scavenge()) {
4150 SweepPrecisely<SWEEP_ONLY, IGNORE_SKIP_LIST, IGNORE_FREE_SPACE>( 4182 SweepPrecisely<SWEEP_ONLY, IGNORE_SKIP_LIST, IGNORE_FREE_SPACE>(
4151 space, p, NULL); 4183 space, p, NULL);
4152 pages_swept++; 4184 pages_swept++;
4153 if (FLAG_gc_verbose) { 4185 if (FLAG_gc_verbose) {
4154 PrintF("Sweeping 0x%" V8PRIxPTR 4186 PrintF("Sweeping 0x%" V8PRIxPTR
4155 " scan on scavenge page precisely.\n", 4187 " scan on scavenge page precisely.\n",
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
4501 while (buffer != NULL) { 4533 while (buffer != NULL) {
4502 SlotsBuffer* next_buffer = buffer->next(); 4534 SlotsBuffer* next_buffer = buffer->next();
4503 DeallocateBuffer(buffer); 4535 DeallocateBuffer(buffer);
4504 buffer = next_buffer; 4536 buffer = next_buffer;
4505 } 4537 }
4506 *buffer_address = NULL; 4538 *buffer_address = NULL;
4507 } 4539 }
4508 4540
4509 4541
4510 } } // namespace v8::internal 4542 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/mark-compact.h ('k') | src/spaces.cc » ('j') | src/spaces.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698