Chromium Code Reviews| 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 2988 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2999 } | 2999 } |
| 3000 | 3000 |
| 3001 | 3001 |
| 3002 // Sweeps a space conservatively. After this has been done the larger free | 3002 // Sweeps a space conservatively. After this has been done the larger free |
| 3003 // spaces have been put on the free list and the smaller ones have been | 3003 // spaces have been put on the free list and the smaller ones have been |
| 3004 // ignored and left untouched. A free space is always either ignored or put | 3004 // ignored and left untouched. A free space is always either ignored or put |
| 3005 // on the free list, never split up into two parts. This is important | 3005 // on the free list, never split up into two parts. This is important |
| 3006 // because it means that any FreeSpace maps left actually describe a region of | 3006 // because it means that any FreeSpace maps left actually describe a region of |
| 3007 // memory that can be ignored when scanning. Dead objects other than free | 3007 // memory that can be ignored when scanning. Dead objects other than free |
| 3008 // spaces will not contain the free space map. | 3008 // spaces will not contain the free space map. |
| 3009 int MarkCompactCollector::SweepConservatively(PagedSpace* space, Page* p) { | 3009 int MarkCompactCollector::SweepConservatively(PagedSpace* space, Page* p) { |
|
Erik Corry
2011/07/15 21:37:33
Perhas this should return intptr_t?
Lasse Reichstein
2011/08/01 12:40:33
Should probably be size_t, but intptr_t will do (t
| |
| 3010 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept()); | 3010 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept()); |
| 3011 | 3011 |
| 3012 int freed_bytes = 0; | 3012 int freed_bytes = 0; |
| 3013 | 3013 |
| 3014 MarkBit::CellType* cells = p->markbits()->cells(); | 3014 MarkBit::CellType* cells = p->markbits()->cells(); |
| 3015 | 3015 |
| 3016 p->SetFlag(MemoryChunk::WAS_SWEPT_CONSERVATIVELY); | 3016 p->SetFlag(MemoryChunk::WAS_SWEPT_CONSERVATIVELY); |
| 3017 | 3017 |
| 3018 // This is the start of the 32 word block that we are currently looking at. | 3018 // This is the start of the 32 word block that we are currently looking at. |
| 3019 Address block_address = p->ObjectAreaStart(); | 3019 Address block_address = p->ObjectAreaStart(); |
| 3020 | 3020 |
| 3021 int last_cell_index = | 3021 int last_cell_index = |
| 3022 Bitmap::IndexToCell( | 3022 Bitmap::IndexToCell( |
| 3023 Bitmap::CellAlignIndex( | 3023 Bitmap::CellAlignIndex( |
| 3024 p->AddressToMarkbitIndex(p->ObjectAreaEnd()))); | 3024 p->AddressToMarkbitIndex(p->ObjectAreaEnd()))); |
| 3025 | 3025 |
| 3026 int cell_index = Page::kFirstUsedCell; | 3026 int cell_index = Page::kFirstUsedCell; |
| 3027 | 3027 |
| 3028 // Skip over all the dead objects at the start of the page and mark them free. | 3028 // Skip over all the dead objects at the start of the page and mark them free. |
| 3029 for (cell_index = Page::kFirstUsedCell; | 3029 for (cell_index = Page::kFirstUsedCell; |
| 3030 cell_index < last_cell_index; | 3030 cell_index < last_cell_index; |
| 3031 cell_index++, block_address += 32 * kPointerSize) { | 3031 cell_index++, block_address += 32 * kPointerSize) { |
| 3032 if (cells[cell_index] != 0) break; | 3032 if (cells[cell_index] != 0) break; |
| 3033 } | 3033 } |
| 3034 int size = block_address - p->ObjectAreaStart(); | 3034 size_t size = block_address - p->ObjectAreaStart(); |
| 3035 if (cell_index == last_cell_index) { | 3035 if (cell_index == last_cell_index) { |
| 3036 freed_bytes += space->Free(p->ObjectAreaStart(), size); | 3036 freed_bytes += static_cast<int>(space->Free(p->ObjectAreaStart(), |
| 3037 static_cast<int>(size))); | |
| 3037 return freed_bytes; | 3038 return freed_bytes; |
| 3038 } | 3039 } |
| 3039 // Grow the size of the start-of-page free space a little to get up to the | 3040 // Grow the size of the start-of-page free space a little to get up to the |
| 3040 // first live object. | 3041 // first live object. |
| 3041 Address free_end = StartOfLiveObject(block_address, cells[cell_index]); | 3042 Address free_end = StartOfLiveObject(block_address, cells[cell_index]); |
| 3042 // Free the first free space. | 3043 // Free the first free space. |
| 3043 size = free_end - p->ObjectAreaStart(); | 3044 size = free_end - p->ObjectAreaStart(); |
| 3044 freed_bytes += space->Free(p->ObjectAreaStart(), size); | 3045 freed_bytes += space->Free(p->ObjectAreaStart(), |
| 3046 static_cast<int>(size)); | |
| 3045 // The start of the current free area is represented in undigested form by | 3047 // The start of the current free area is represented in undigested form by |
| 3046 // the address of the last 32-word section that contained a live object and | 3048 // the address of the last 32-word section that contained a live object and |
| 3047 // the marking bitmap for that cell, which describes where the live object | 3049 // the marking bitmap for that cell, which describes where the live object |
| 3048 // started. Unless we find a large free space in the bitmap we will not | 3050 // started. Unless we find a large free space in the bitmap we will not |
| 3049 // digest this pair into a real address. We start the iteration here at the | 3051 // digest this pair into a real address. We start the iteration here at the |
| 3050 // first word in the marking bit map that indicates a live object. | 3052 // first word in the marking bit map that indicates a live object. |
| 3051 Address free_start = block_address; | 3053 Address free_start = block_address; |
| 3052 uint32_t free_start_cell = cells[cell_index]; | 3054 uint32_t free_start_cell = cells[cell_index]; |
| 3053 | 3055 |
| 3054 for ( ; | 3056 for ( ; |
| 3055 cell_index < last_cell_index; | 3057 cell_index < last_cell_index; |
| 3056 cell_index++, block_address += 32 * kPointerSize) { | 3058 cell_index++, block_address += 32 * kPointerSize) { |
| 3057 ASSERT((unsigned)cell_index == | 3059 ASSERT((unsigned)cell_index == |
| 3058 Bitmap::IndexToCell( | 3060 Bitmap::IndexToCell( |
| 3059 Bitmap::CellAlignIndex( | 3061 Bitmap::CellAlignIndex( |
| 3060 p->AddressToMarkbitIndex(block_address)))); | 3062 p->AddressToMarkbitIndex(block_address)))); |
| 3061 uint32_t cell = cells[cell_index]; | 3063 uint32_t cell = cells[cell_index]; |
| 3062 if (cell != 0) { | 3064 if (cell != 0) { |
| 3063 // We have a live object. Check approximately whether it is more than 32 | 3065 // We have a live object. Check approximately whether it is more than 32 |
| 3064 // words since the last live object. | 3066 // words since the last live object. |
| 3065 if (block_address - free_start > 32 * kPointerSize) { | 3067 if (block_address - free_start > 32 * kPointerSize) { |
| 3066 free_start = DigestFreeStart(free_start, free_start_cell); | 3068 free_start = DigestFreeStart(free_start, free_start_cell); |
| 3067 if (block_address - free_start > 32 * kPointerSize) { | 3069 if (block_address - free_start > 32 * kPointerSize) { |
| 3068 // Now that we know the exact start of the free space it still looks | 3070 // Now that we know the exact start of the free space it still looks |
| 3069 // like we have a large enough free space to be worth bothering with. | 3071 // like we have a large enough free space to be worth bothering with. |
| 3070 // so now we need to find the start of the first live object at the | 3072 // so now we need to find the start of the first live object at the |
| 3071 // end of the free space. | 3073 // end of the free space. |
| 3072 free_end = StartOfLiveObject(block_address, cell); | 3074 free_end = StartOfLiveObject(block_address, cell); |
| 3073 freed_bytes += space->Free(free_start, free_end - free_start); | 3075 freed_bytes += space->Free(free_start, |
| 3076 static_cast<int>(free_end - free_start)); | |
| 3074 } | 3077 } |
| 3075 } | 3078 } |
| 3076 // Update our undigested record of where the current free area started. | 3079 // Update our undigested record of where the current free area started. |
| 3077 free_start = block_address; | 3080 free_start = block_address; |
| 3078 free_start_cell = cell; | 3081 free_start_cell = cell; |
| 3079 } | 3082 } |
| 3080 } | 3083 } |
| 3081 | 3084 |
| 3082 // Handle the free space at the end of the page. | 3085 // Handle the free space at the end of the page. |
| 3083 if (block_address - free_start > 32 * kPointerSize) { | 3086 if (block_address - free_start > 32 * kPointerSize) { |
| 3084 free_start = DigestFreeStart(free_start, free_start_cell); | 3087 free_start = DigestFreeStart(free_start, free_start_cell); |
| 3085 freed_bytes += space->Free(free_start, block_address - free_start); | 3088 freed_bytes += space->Free(free_start, |
| 3089 static_cast<int>(block_address - free_start)); | |
| 3086 } | 3090 } |
| 3087 | 3091 |
| 3088 return freed_bytes; | 3092 return freed_bytes; |
| 3089 } | 3093 } |
| 3090 | 3094 |
| 3091 | 3095 |
| 3092 // Sweep a space precisely. After this has been done the space can | 3096 // Sweep a space precisely. After this has been done the space can |
| 3093 // be iterated precisely, hitting only the live objects. Code space | 3097 // be iterated precisely, hitting only the live objects. Code space |
| 3094 // is always swept precisely because we want to be able to iterate | 3098 // is always swept precisely because we want to be able to iterate |
| 3095 // over it. Map space is swept precisely, because it is not compacted. | 3099 // over it. Map space is swept precisely, because it is not compacted. |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 3116 cell_index++, object_address += 32 * kPointerSize) { | 3120 cell_index++, object_address += 32 * kPointerSize) { |
| 3117 ASSERT((unsigned)cell_index == | 3121 ASSERT((unsigned)cell_index == |
| 3118 Bitmap::IndexToCell( | 3122 Bitmap::IndexToCell( |
| 3119 Bitmap::CellAlignIndex( | 3123 Bitmap::CellAlignIndex( |
| 3120 p->AddressToMarkbitIndex(object_address)))); | 3124 p->AddressToMarkbitIndex(object_address)))); |
| 3121 int live_objects = MarkWordToObjectStarts(cells[cell_index], offsets); | 3125 int live_objects = MarkWordToObjectStarts(cells[cell_index], offsets); |
| 3122 int live_index = 0; | 3126 int live_index = 0; |
| 3123 for ( ; live_objects != 0; live_objects--) { | 3127 for ( ; live_objects != 0; live_objects--) { |
| 3124 Address free_end = object_address + offsets[live_index++] * kPointerSize; | 3128 Address free_end = object_address + offsets[live_index++] * kPointerSize; |
| 3125 if (free_end != free_start) { | 3129 if (free_end != free_start) { |
| 3126 space->Free(free_start, free_end - free_start); | 3130 space->Free(free_start, static_cast<int>(free_end - free_start)); |
| 3127 } | 3131 } |
| 3128 HeapObject* live_object = HeapObject::FromAddress(free_end); | 3132 HeapObject* live_object = HeapObject::FromAddress(free_end); |
| 3129 ASSERT(Marking::IsBlack(Marking::MarkBitFrom(live_object))); | 3133 ASSERT(Marking::IsBlack(Marking::MarkBitFrom(live_object))); |
| 3130 free_start = free_end + live_object->Size(); | 3134 free_start = free_end + live_object->Size(); |
| 3131 } | 3135 } |
| 3132 } | 3136 } |
| 3133 if (free_start != p->ObjectAreaEnd()) { | 3137 if (free_start != p->ObjectAreaEnd()) { |
| 3134 space->Free(free_start, p->ObjectAreaEnd() - free_start); | 3138 space->Free(free_start, static_cast<int>(p->ObjectAreaEnd() - free_start)); |
| 3135 } | 3139 } |
| 3136 } | 3140 } |
| 3137 | 3141 |
| 3138 | 3142 |
| 3139 void MarkCompactCollector::SweepSpace(PagedSpace* space, | 3143 void MarkCompactCollector::SweepSpace(PagedSpace* space, |
| 3140 SweeperType sweeper) { | 3144 SweeperType sweeper) { |
| 3141 space->set_was_swept_conservatively(sweeper == CONSERVATIVE || | 3145 space->set_was_swept_conservatively(sweeper == CONSERVATIVE || |
| 3142 sweeper == LAZY_CONSERVATIVE); | 3146 sweeper == LAZY_CONSERVATIVE); |
| 3143 | 3147 |
| 3144 space->ClearStats(); | 3148 space->ClearStats(); |
| 3145 | 3149 |
| 3146 PageIterator it(space); | 3150 PageIterator it(space); |
| 3147 | 3151 |
| 3148 int freed_bytes = 0; | 3152 int freed_bytes = 0; |
| 3149 int newspace_size = space->heap()->new_space()->Size(); | 3153 int newspace_size = static_cast<int>(space->heap()->new_space()->Size()); |
| 3150 | 3154 |
| 3151 while (it.has_next()) { | 3155 while (it.has_next()) { |
| 3152 Page* p = it.next(); | 3156 Page* p = it.next(); |
| 3153 | 3157 |
| 3154 if (p->IsEvacuationCandidate()) { | 3158 if (p->IsEvacuationCandidate()) { |
| 3155 ASSERT(evacuation_candidates_.length() > 0); | 3159 ASSERT(evacuation_candidates_.length() > 0); |
| 3156 continue; | 3160 continue; |
| 3157 } | 3161 } |
| 3158 | 3162 |
| 3159 if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) { | 3163 if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) { |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3344 while (buffer != NULL) { | 3348 while (buffer != NULL) { |
| 3345 SlotsBuffer* next_buffer = buffer->next(); | 3349 SlotsBuffer* next_buffer = buffer->next(); |
| 3346 DeallocateBuffer(buffer); | 3350 DeallocateBuffer(buffer); |
| 3347 buffer = next_buffer; | 3351 buffer = next_buffer; |
| 3348 } | 3352 } |
| 3349 *buffer_address = NULL; | 3353 *buffer_address = NULL; |
| 3350 } | 3354 } |
| 3351 | 3355 |
| 3352 | 3356 |
| 3353 } } // namespace v8::internal | 3357 } } // namespace v8::internal |
| OLD | NEW |