| 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 |