| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 2643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2654 } | 2654 } |
| 2655 // Clear marking bits for current cell. | 2655 // Clear marking bits for current cell. |
| 2656 cells[cell_index] = 0; | 2656 cells[cell_index] = 0; |
| 2657 } | 2657 } |
| 2658 if (free_start != p->ObjectAreaEnd()) { | 2658 if (free_start != p->ObjectAreaEnd()) { |
| 2659 space->Free(free_start, static_cast<int>(p->ObjectAreaEnd() - free_start)); | 2659 space->Free(free_start, static_cast<int>(p->ObjectAreaEnd() - free_start)); |
| 2660 } | 2660 } |
| 2661 } | 2661 } |
| 2662 | 2662 |
| 2663 | 2663 |
| 2664 // Sweep a page of a space which contains objects of fixed size. This is used |
| 2665 // for map space and cell space, it always sweeps those spaces precisely. |
| 2666 template<int size> |
| 2667 static void SweepSpecialized(PagedSpace* space, Page* p) { |
| 2668 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept()); |
| 2669 MarkBit::CellType* cells = p->markbits()->cells(); |
| 2670 p->MarkSweptPrecisely(); |
| 2671 |
| 2672 int last_cell_index = |
| 2673 Bitmap::IndexToCell( |
| 2674 Bitmap::CellAlignIndex( |
| 2675 p->AddressToMarkbitIndex(p->ObjectAreaEnd()))); |
| 2676 |
| 2677 int cell_index = Page::kFirstUsedCell; |
| 2678 Address free_start = p->ObjectAreaStart(); |
| 2679 Address free_end = p->ObjectAreaStart(); |
| 2680 uint32_t mark_mask = 0; |
| 2681 uint32_t mark_bits; |
| 2682 |
| 2683 ASSERT(size % kPointerSize == 0); |
| 2684 int bits_per_object = size / kPointerSize; |
| 2685 |
| 2686 for (cell_index = Page::kFirstUsedCell; |
| 2687 cell_index < last_cell_index || mark_mask != 0; |
| 2688 free_end += size, mark_mask <<= bits_per_object) { |
| 2689 if (mark_mask == 0) { |
| 2690 mark_mask = 1 << (p->AddressToMarkbitIndex(free_end) % 32); |
| 2691 mark_bits = cells[cell_index]; |
| 2692 cells[cell_index] = 0; |
| 2693 cell_index++; |
| 2694 } |
| 2695 if ((mark_bits & mark_mask) != 0) { |
| 2696 if (free_end != free_start) { |
| 2697 space->Free(free_start, static_cast<int>(free_end - free_start)); |
| 2698 } |
| 2699 free_start = free_end + size; |
| 2700 } |
| 2701 } |
| 2702 if (free_start != p->ObjectAreaEnd()) { |
| 2703 space->Free(free_start, static_cast<int>(p->ObjectAreaEnd() - free_start)); |
| 2704 } |
| 2705 } |
| 2706 |
| 2707 |
| 2664 void MarkCompactCollector::EvacuateNewSpaceAndCandidates() { | 2708 void MarkCompactCollector::EvacuateNewSpaceAndCandidates() { |
| 2665 EvacuateNewSpace(); | 2709 EvacuateNewSpace(); |
| 2666 EvacuatePages(); | 2710 EvacuatePages(); |
| 2667 | 2711 |
| 2668 // Second pass: find pointers to new space and update them. | 2712 // Second pass: find pointers to new space and update them. |
| 2669 PointersUpdatingVisitor updating_visitor(heap()); | 2713 PointersUpdatingVisitor updating_visitor(heap()); |
| 2670 | 2714 |
| 2671 // Update pointers in to space. | 2715 // Update pointers in to space. |
| 2672 SemiSpaceIterator to_it(heap()->new_space()->bottom(), | 2716 SemiSpaceIterator to_it(heap()->new_space()->bottom(), |
| 2673 heap()->new_space()->top()); | 2717 heap()->new_space()->top()); |
| (...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3234 if (freed_bytes >= newspace_size && p != space->LastPage()) { | 3278 if (freed_bytes >= newspace_size && p != space->LastPage()) { |
| 3235 space->SetPagesToSweep(p->next_page(), space->LastPage()); | 3279 space->SetPagesToSweep(p->next_page(), space->LastPage()); |
| 3236 lazy_sweeping_active = true; | 3280 lazy_sweeping_active = true; |
| 3237 } | 3281 } |
| 3238 break; | 3282 break; |
| 3239 } | 3283 } |
| 3240 case PRECISE: { | 3284 case PRECISE: { |
| 3241 SweepPrecisely(space, p, SWEEP_ONLY); | 3285 SweepPrecisely(space, p, SWEEP_ONLY); |
| 3242 break; | 3286 break; |
| 3243 } | 3287 } |
| 3288 case PRECISE_CELLS: { |
| 3289 SweepSpecialized<JSGlobalPropertyCell::kSize>(space, p); |
| 3290 break; |
| 3291 } |
| 3292 case PRECISE_MAPS: { |
| 3293 SweepSpecialized<Map::kSize>(space, p); |
| 3294 break; |
| 3295 } |
| 3244 default: { | 3296 default: { |
| 3245 UNREACHABLE(); | 3297 UNREACHABLE(); |
| 3246 } | 3298 } |
| 3247 } | 3299 } |
| 3248 } | 3300 } |
| 3249 } | 3301 } |
| 3250 | 3302 |
| 3251 | 3303 |
| 3252 void MarkCompactCollector::SweepSpaces() { | 3304 void MarkCompactCollector::SweepSpaces() { |
| 3253 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP); | 3305 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP); |
| 3254 #ifdef DEBUG | 3306 #ifdef DEBUG |
| 3255 state_ = SWEEP_SPACES; | 3307 state_ = SWEEP_SPACES; |
| 3256 #endif | 3308 #endif |
| 3257 SweeperType how_to_sweep = | 3309 SweeperType how_to_sweep = |
| 3258 FLAG_lazy_sweeping ? LAZY_CONSERVATIVE : CONSERVATIVE; | 3310 FLAG_lazy_sweeping ? LAZY_CONSERVATIVE : CONSERVATIVE; |
| 3259 if (sweep_precisely_) how_to_sweep = PRECISE; | 3311 if (sweep_precisely_) how_to_sweep = PRECISE; |
| 3260 // Noncompacting collections simply sweep the spaces to clear the mark | 3312 // Noncompacting collections simply sweep the spaces to clear the mark |
| 3261 // bits and free the nonlive blocks (for old and map spaces). We sweep | 3313 // bits and free the nonlive blocks (for old and map spaces). We sweep |
| 3262 // the map space last because freeing non-live maps overwrites them and | 3314 // the map space last because freeing non-live maps overwrites them and |
| 3263 // the other spaces rely on possibly non-live maps to get the sizes for | 3315 // the other spaces rely on possibly non-live maps to get the sizes for |
| 3264 // non-live objects. | 3316 // non-live objects. |
| 3265 SweepSpace(heap()->old_pointer_space(), how_to_sweep); | 3317 SweepSpace(heap()->old_pointer_space(), how_to_sweep); |
| 3266 SweepSpace(heap()->old_data_space(), how_to_sweep); | 3318 SweepSpace(heap()->old_data_space(), how_to_sweep); |
| 3267 SweepSpace(heap()->code_space(), PRECISE); | 3319 SweepSpace(heap()->code_space(), PRECISE); |
| 3268 SweepSpace(heap()->cell_space(), PRECISE); | 3320 SweepSpace(heap()->cell_space(), PRECISE_CELLS); |
| 3269 { GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP_NEWSPACE); | 3321 { GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP_NEWSPACE); |
| 3270 EvacuateNewSpaceAndCandidates(); | 3322 EvacuateNewSpaceAndCandidates(); |
| 3271 } | 3323 } |
| 3272 // ClearNonLiveTransitions depends on precise sweeping of map space to | 3324 // ClearNonLiveTransitions depends on precise sweeping of map space to |
| 3273 // detect whether unmarked map became dead in this collection or in one | 3325 // detect whether unmarked map became dead in this collection or in one |
| 3274 // of the previous ones. | 3326 // of the previous ones. |
| 3275 SweepSpace(heap()->map_space(), PRECISE); | 3327 SweepSpace(heap()->map_space(), PRECISE_MAPS); |
| 3276 | 3328 |
| 3277 ASSERT(live_map_objects_size_ <= heap()->map_space()->Size()); | 3329 ASSERT(live_map_objects_size_ <= heap()->map_space()->Size()); |
| 3278 | 3330 |
| 3279 // Deallocate unmarked objects and clear marked bits for marked objects. | 3331 // Deallocate unmarked objects and clear marked bits for marked objects. |
| 3280 heap_->lo_space()->FreeUnmarkedObjects(); | 3332 heap_->lo_space()->FreeUnmarkedObjects(); |
| 3281 } | 3333 } |
| 3282 | 3334 |
| 3283 | 3335 |
| 3284 // TODO(1466) ReportDeleteIfNeeded is not called currently. | 3336 // TODO(1466) ReportDeleteIfNeeded is not called currently. |
| 3285 // Our profiling tools do not expect intersections between | 3337 // Our profiling tools do not expect intersections between |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3336 while (buffer != NULL) { | 3388 while (buffer != NULL) { |
| 3337 SlotsBuffer* next_buffer = buffer->next(); | 3389 SlotsBuffer* next_buffer = buffer->next(); |
| 3338 DeallocateBuffer(buffer); | 3390 DeallocateBuffer(buffer); |
| 3339 buffer = next_buffer; | 3391 buffer = next_buffer; |
| 3340 } | 3392 } |
| 3341 *buffer_address = NULL; | 3393 *buffer_address = NULL; |
| 3342 } | 3394 } |
| 3343 | 3395 |
| 3344 | 3396 |
| 3345 } } // namespace v8::internal | 3397 } } // namespace v8::internal |
| OLD | NEW |