OLD | NEW |
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 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
588 } | 588 } |
589 | 589 |
590 Heap* heap_; | 590 Heap* heap_; |
591 PagedSpace* space_; | 591 PagedSpace* space_; |
592 | 592 |
593 DISALLOW_COPY_AND_ASSIGN(SweeperTask); | 593 DISALLOW_COPY_AND_ASSIGN(SweeperTask); |
594 }; | 594 }; |
595 | 595 |
596 | 596 |
597 void MarkCompactCollector::StartSweeperThreads() { | 597 void MarkCompactCollector::StartSweeperThreads() { |
598 // TODO(hpayer): This check is just used for debugging purpose and | 598 ASSERT(free_list_old_pointer_space_.get()->IsEmpty()); |
599 // should be removed or turned into an assert after investigating the | 599 ASSERT(free_list_old_data_space_.get()->IsEmpty()); |
600 // crash in concurrent sweeping. | |
601 CHECK(free_list_old_pointer_space_.get()->IsEmpty()); | |
602 CHECK(free_list_old_data_space_.get()->IsEmpty()); | |
603 sweeping_pending_ = true; | 600 sweeping_pending_ = true; |
604 for (int i = 0; i < isolate()->num_sweeper_threads(); i++) { | 601 for (int i = 0; i < isolate()->num_sweeper_threads(); i++) { |
605 isolate()->sweeper_threads()[i]->StartSweeping(); | 602 isolate()->sweeper_threads()[i]->StartSweeping(); |
606 } | 603 } |
607 if (FLAG_job_based_sweeping) { | 604 if (FLAG_job_based_sweeping) { |
608 V8::GetCurrentPlatform()->CallOnBackgroundThread( | 605 V8::GetCurrentPlatform()->CallOnBackgroundThread( |
609 new SweeperTask(heap(), heap()->old_data_space()), | 606 new SweeperTask(heap(), heap()->old_data_space()), |
610 v8::Platform::kShortRunningTask); | 607 v8::Platform::kShortRunningTask); |
611 V8::GetCurrentPlatform()->CallOnBackgroundThread( | 608 V8::GetCurrentPlatform()->CallOnBackgroundThread( |
612 new SweeperTask(heap(), heap()->old_pointer_space()), | 609 new SweeperTask(heap(), heap()->old_pointer_space()), |
(...skipping 2459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3072 if (map_word.IsForwardingAddress()) { | 3069 if (map_word.IsForwardingAddress()) { |
3073 return String::cast(map_word.ToForwardingAddress()); | 3070 return String::cast(map_word.ToForwardingAddress()); |
3074 } | 3071 } |
3075 | 3072 |
3076 return String::cast(*p); | 3073 return String::cast(*p); |
3077 } | 3074 } |
3078 | 3075 |
3079 | 3076 |
3080 bool MarkCompactCollector::TryPromoteObject(HeapObject* object, | 3077 bool MarkCompactCollector::TryPromoteObject(HeapObject* object, |
3081 int object_size) { | 3078 int object_size) { |
3082 // TODO(hpayer): Replace that check with an assert. | 3079 ASSERT(object_size <= Page::kMaxRegularHeapObjectSize); |
3083 CHECK(object_size <= Page::kMaxRegularHeapObjectSize); | |
3084 | 3080 |
3085 OldSpace* target_space = heap()->TargetSpace(object); | 3081 OldSpace* target_space = heap()->TargetSpace(object); |
3086 | 3082 |
3087 ASSERT(target_space == heap()->old_pointer_space() || | 3083 ASSERT(target_space == heap()->old_pointer_space() || |
3088 target_space == heap()->old_data_space()); | 3084 target_space == heap()->old_data_space()); |
3089 Object* result; | 3085 Object* result; |
3090 MaybeObject* maybe_result = target_space->AllocateRaw(object_size); | 3086 MaybeObject* maybe_result = target_space->AllocateRaw(object_size); |
3091 if (maybe_result->ToObject(&result)) { | 3087 if (maybe_result->ToObject(&result)) { |
3092 HeapObject* target = HeapObject::cast(result); | 3088 HeapObject* target = HeapObject::cast(result); |
3093 MigrateObject(target, | 3089 MigrateObject(target, |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3180 *cell = 0; | 3176 *cell = 0; |
3181 } | 3177 } |
3182 p->ResetLiveBytes(); | 3178 p->ResetLiveBytes(); |
3183 } | 3179 } |
3184 | 3180 |
3185 | 3181 |
3186 void MarkCompactCollector::EvacuatePages() { | 3182 void MarkCompactCollector::EvacuatePages() { |
3187 int npages = evacuation_candidates_.length(); | 3183 int npages = evacuation_candidates_.length(); |
3188 for (int i = 0; i < npages; i++) { | 3184 for (int i = 0; i < npages; i++) { |
3189 Page* p = evacuation_candidates_[i]; | 3185 Page* p = evacuation_candidates_[i]; |
3190 // TODO(hpayer): This check is just used for debugging purpose and | 3186 ASSERT(p->IsEvacuationCandidate() || |
3191 // should be removed or turned into an assert after investigating the | 3187 p->IsFlagSet(Page::RESCAN_ON_EVACUATION)); |
3192 // crash in concurrent sweeping. | 3188 ASSERT(static_cast<int>(p->parallel_sweeping()) == |
3193 CHECK(p->IsEvacuationCandidate() || | 3189 MemoryChunk::PARALLEL_SWEEPING_DONE); |
3194 p->IsFlagSet(Page::RESCAN_ON_EVACUATION)); | |
3195 CHECK_EQ(static_cast<int>(p->parallel_sweeping()), 0); | |
3196 if (p->IsEvacuationCandidate()) { | 3190 if (p->IsEvacuationCandidate()) { |
3197 // During compaction we might have to request a new page. | 3191 // During compaction we might have to request a new page. |
3198 // Check that space still have room for that. | 3192 // Check that space still have room for that. |
3199 if (static_cast<PagedSpace*>(p->owner())->CanExpand()) { | 3193 if (static_cast<PagedSpace*>(p->owner())->CanExpand()) { |
3200 EvacuateLiveObjectsFromPage(p); | 3194 EvacuateLiveObjectsFromPage(p); |
3201 } else { | 3195 } else { |
3202 // Without room for expansion evacuation is not guaranteed to succeed. | 3196 // Without room for expansion evacuation is not guaranteed to succeed. |
3203 // Pessimistically abandon unevacuated pages. | 3197 // Pessimistically abandon unevacuated pages. |
3204 for (int j = i; j < npages; j++) { | 3198 for (int j = i; j < npages; j++) { |
3205 Page* page = evacuation_candidates_[j]; | 3199 Page* page = evacuation_candidates_[j]; |
(...skipping 828 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4034 // spaces have been put on the free list and the smaller ones have been | 4028 // spaces have been put on the free list and the smaller ones have been |
4035 // ignored and left untouched. A free space is always either ignored or put | 4029 // ignored and left untouched. A free space is always either ignored or put |
4036 // on the free list, never split up into two parts. This is important | 4030 // on the free list, never split up into two parts. This is important |
4037 // because it means that any FreeSpace maps left actually describe a region of | 4031 // because it means that any FreeSpace maps left actually describe a region of |
4038 // memory that can be ignored when scanning. Dead objects other than free | 4032 // memory that can be ignored when scanning. Dead objects other than free |
4039 // spaces will not contain the free space map. | 4033 // spaces will not contain the free space map. |
4040 template<MarkCompactCollector::SweepingParallelism mode> | 4034 template<MarkCompactCollector::SweepingParallelism mode> |
4041 intptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space, | 4035 intptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space, |
4042 FreeList* free_list, | 4036 FreeList* free_list, |
4043 Page* p) { | 4037 Page* p) { |
4044 // TODO(hpayer): This check is just used for debugging purpose and | 4038 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept()); |
4045 // should be removed or turned into an assert after investigating the | |
4046 // crash in concurrent sweeping. | |
4047 CHECK(!p->IsEvacuationCandidate() && !p->WasSwept()); | |
4048 ASSERT((mode == MarkCompactCollector::SWEEP_IN_PARALLEL && | 4039 ASSERT((mode == MarkCompactCollector::SWEEP_IN_PARALLEL && |
4049 free_list != NULL) || | 4040 free_list != NULL) || |
4050 (mode == MarkCompactCollector::SWEEP_SEQUENTIALLY && | 4041 (mode == MarkCompactCollector::SWEEP_SEQUENTIALLY && |
4051 free_list == NULL)); | 4042 free_list == NULL)); |
4052 | 4043 |
4053 // When parallel sweeping is active, the page will be marked after | 4044 // When parallel sweeping is active, the page will be marked after |
4054 // sweeping by the main thread. | 4045 // sweeping by the main thread. |
4055 if (mode != MarkCompactCollector::SWEEP_IN_PARALLEL) { | 4046 if (mode != MarkCompactCollector::SWEEP_IN_PARALLEL) { |
4056 p->MarkSweptConservatively(); | 4047 p->MarkSweptConservatively(); |
4057 } | 4048 } |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4281 // the other spaces rely on possibly non-live maps to get the sizes for | 4272 // the other spaces rely on possibly non-live maps to get the sizes for |
4282 // non-live objects. | 4273 // non-live objects. |
4283 { GCTracer::Scope sweep_scope(tracer_, GCTracer::Scope::MC_SWEEP_OLDSPACE); | 4274 { GCTracer::Scope sweep_scope(tracer_, GCTracer::Scope::MC_SWEEP_OLDSPACE); |
4284 { SequentialSweepingScope scope(this); | 4275 { SequentialSweepingScope scope(this); |
4285 SweepSpace(heap()->old_pointer_space(), how_to_sweep); | 4276 SweepSpace(heap()->old_pointer_space(), how_to_sweep); |
4286 SweepSpace(heap()->old_data_space(), how_to_sweep); | 4277 SweepSpace(heap()->old_data_space(), how_to_sweep); |
4287 } | 4278 } |
4288 | 4279 |
4289 if (how_to_sweep == PARALLEL_CONSERVATIVE || | 4280 if (how_to_sweep == PARALLEL_CONSERVATIVE || |
4290 how_to_sweep == CONCURRENT_CONSERVATIVE) { | 4281 how_to_sweep == CONCURRENT_CONSERVATIVE) { |
4291 // TODO(hpayer): fix race with concurrent sweeper | |
4292 StartSweeperThreads(); | 4282 StartSweeperThreads(); |
4293 } | 4283 } |
4294 | 4284 |
4295 if (how_to_sweep == PARALLEL_CONSERVATIVE) { | 4285 if (how_to_sweep == PARALLEL_CONSERVATIVE) { |
4296 WaitUntilSweepingCompleted(); | 4286 WaitUntilSweepingCompleted(); |
4297 } | 4287 } |
4298 } | 4288 } |
4299 RemoveDeadInvalidatedCode(); | 4289 RemoveDeadInvalidatedCode(); |
4300 SweepSpace(heap()->code_space(), PRECISE); | 4290 SweepSpace(heap()->code_space(), PRECISE); |
4301 | 4291 |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4554 while (buffer != NULL) { | 4544 while (buffer != NULL) { |
4555 SlotsBuffer* next_buffer = buffer->next(); | 4545 SlotsBuffer* next_buffer = buffer->next(); |
4556 DeallocateBuffer(buffer); | 4546 DeallocateBuffer(buffer); |
4557 buffer = next_buffer; | 4547 buffer = next_buffer; |
4558 } | 4548 } |
4559 *buffer_address = NULL; | 4549 *buffer_address = NULL; |
4560 } | 4550 } |
4561 | 4551 |
4562 | 4552 |
4563 } } // namespace v8::internal | 4553 } } // namespace v8::internal |
OLD | NEW |