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 3186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3197 SWEEP_AND_VISIT_LIVE_OBJECTS | 3197 SWEEP_AND_VISIT_LIVE_OBJECTS |
3198 }; | 3198 }; |
3199 | 3199 |
3200 | 3200 |
3201 enum SkipListRebuildingMode { | 3201 enum SkipListRebuildingMode { |
3202 REBUILD_SKIP_LIST, | 3202 REBUILD_SKIP_LIST, |
3203 IGNORE_SKIP_LIST | 3203 IGNORE_SKIP_LIST |
3204 }; | 3204 }; |
3205 | 3205 |
3206 | 3206 |
| 3207 enum FreeSpaceTreatmentMode { |
| 3208 IGNORE_FREE_SPACE, |
| 3209 ZAP_FREE_SPACE |
| 3210 }; |
| 3211 |
| 3212 |
3207 // Sweep a space precisely. After this has been done the space can | 3213 // Sweep a space precisely. After this has been done the space can |
3208 // be iterated precisely, hitting only the live objects. Code space | 3214 // be iterated precisely, hitting only the live objects. Code space |
3209 // is always swept precisely because we want to be able to iterate | 3215 // is always swept precisely because we want to be able to iterate |
3210 // over it. Map space is swept precisely, because it is not compacted. | 3216 // over it. Map space is swept precisely, because it is not compacted. |
3211 // Slots in live objects pointing into evacuation candidates are updated | 3217 // Slots in live objects pointing into evacuation candidates are updated |
3212 // if requested. | 3218 // if requested. |
3213 template<SweepingMode sweeping_mode, SkipListRebuildingMode skip_list_mode> | 3219 template<SweepingMode sweeping_mode, |
| 3220 SkipListRebuildingMode skip_list_mode, |
| 3221 FreeSpaceTreatmentMode free_space_mode> |
3214 static void SweepPrecisely(PagedSpace* space, | 3222 static void SweepPrecisely(PagedSpace* space, |
3215 Page* p, | 3223 Page* p, |
3216 ObjectVisitor* v) { | 3224 ObjectVisitor* v) { |
3217 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept()); | 3225 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept()); |
3218 ASSERT_EQ(skip_list_mode == REBUILD_SKIP_LIST, | 3226 ASSERT_EQ(skip_list_mode == REBUILD_SKIP_LIST, |
3219 space->identity() == CODE_SPACE); | 3227 space->identity() == CODE_SPACE); |
3220 ASSERT((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST)); | 3228 ASSERT((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST)); |
3221 | 3229 |
3222 double start_time = 0.0; | 3230 double start_time = 0.0; |
3223 if (FLAG_print_cumulative_gc_stat) { | 3231 if (FLAG_print_cumulative_gc_stat) { |
(...skipping 13 matching lines...) Expand all Loading... |
3237 } | 3245 } |
3238 | 3246 |
3239 for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) { | 3247 for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) { |
3240 Address cell_base = it.CurrentCellBase(); | 3248 Address cell_base = it.CurrentCellBase(); |
3241 MarkBit::CellType* cell = it.CurrentCell(); | 3249 MarkBit::CellType* cell = it.CurrentCell(); |
3242 int live_objects = MarkWordToObjectStarts(*cell, offsets); | 3250 int live_objects = MarkWordToObjectStarts(*cell, offsets); |
3243 int live_index = 0; | 3251 int live_index = 0; |
3244 for ( ; live_objects != 0; live_objects--) { | 3252 for ( ; live_objects != 0; live_objects--) { |
3245 Address free_end = cell_base + offsets[live_index++] * kPointerSize; | 3253 Address free_end = cell_base + offsets[live_index++] * kPointerSize; |
3246 if (free_end != free_start) { | 3254 if (free_end != free_start) { |
| 3255 if (free_space_mode == ZAP_FREE_SPACE) { |
| 3256 memset(free_start, 0xcc, static_cast<int>(free_end - free_start)); |
| 3257 } |
3247 space->Free(free_start, static_cast<int>(free_end - free_start)); | 3258 space->Free(free_start, static_cast<int>(free_end - free_start)); |
3248 #ifdef ENABLE_GDB_JIT_INTERFACE | 3259 #ifdef ENABLE_GDB_JIT_INTERFACE |
3249 if (FLAG_gdbjit && space->identity() == CODE_SPACE) { | 3260 if (FLAG_gdbjit && space->identity() == CODE_SPACE) { |
3250 GDBJITInterface::RemoveCodeRange(free_start, free_end); | 3261 GDBJITInterface::RemoveCodeRange(free_start, free_end); |
3251 } | 3262 } |
3252 #endif | 3263 #endif |
3253 } | 3264 } |
3254 HeapObject* live_object = HeapObject::FromAddress(free_end); | 3265 HeapObject* live_object = HeapObject::FromAddress(free_end); |
3255 ASSERT(Marking::IsBlack(Marking::MarkBitFrom(live_object))); | 3266 ASSERT(Marking::IsBlack(Marking::MarkBitFrom(live_object))); |
3256 Map* map = live_object->map(); | 3267 Map* map = live_object->map(); |
(...skipping 11 matching lines...) Expand all Loading... |
3268 skip_list->AddObject(free_end, size); | 3279 skip_list->AddObject(free_end, size); |
3269 curr_region = new_region_end; | 3280 curr_region = new_region_end; |
3270 } | 3281 } |
3271 } | 3282 } |
3272 free_start = free_end + size; | 3283 free_start = free_end + size; |
3273 } | 3284 } |
3274 // Clear marking bits for current cell. | 3285 // Clear marking bits for current cell. |
3275 *cell = 0; | 3286 *cell = 0; |
3276 } | 3287 } |
3277 if (free_start != p->area_end()) { | 3288 if (free_start != p->area_end()) { |
| 3289 if (free_space_mode == ZAP_FREE_SPACE) { |
| 3290 memset(free_start, 0xcc, static_cast<int>(p->area_end() - free_start)); |
| 3291 } |
3278 space->Free(free_start, static_cast<int>(p->area_end() - free_start)); | 3292 space->Free(free_start, static_cast<int>(p->area_end() - free_start)); |
3279 #ifdef ENABLE_GDB_JIT_INTERFACE | 3293 #ifdef ENABLE_GDB_JIT_INTERFACE |
3280 if (FLAG_gdbjit && space->identity() == CODE_SPACE) { | 3294 if (FLAG_gdbjit && space->identity() == CODE_SPACE) { |
3281 GDBJITInterface::RemoveCodeRange(free_start, p->area_end()); | 3295 GDBJITInterface::RemoveCodeRange(free_start, p->area_end()); |
3282 } | 3296 } |
3283 #endif | 3297 #endif |
3284 } | 3298 } |
3285 p->ResetLiveBytes(); | 3299 p->ResetLiveBytes(); |
3286 if (FLAG_print_cumulative_gc_stat) { | 3300 if (FLAG_print_cumulative_gc_stat) { |
3287 space->heap()->AddSweepingTime(OS::TimeCurrentMillis() - start_time); | 3301 space->heap()->AddSweepingTime(OS::TimeCurrentMillis() - start_time); |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3513 reinterpret_cast<intptr_t>(p)); | 3527 reinterpret_cast<intptr_t>(p)); |
3514 } | 3528 } |
3515 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); | 3529 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); |
3516 p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION); | 3530 p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION); |
3517 | 3531 |
3518 switch (space->identity()) { | 3532 switch (space->identity()) { |
3519 case OLD_DATA_SPACE: | 3533 case OLD_DATA_SPACE: |
3520 SweepConservatively<SWEEP_SEQUENTIALLY>(space, NULL, p); | 3534 SweepConservatively<SWEEP_SEQUENTIALLY>(space, NULL, p); |
3521 break; | 3535 break; |
3522 case OLD_POINTER_SPACE: | 3536 case OLD_POINTER_SPACE: |
3523 SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS, IGNORE_SKIP_LIST>( | 3537 SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS, |
| 3538 IGNORE_SKIP_LIST, |
| 3539 IGNORE_FREE_SPACE>( |
3524 space, p, &updating_visitor); | 3540 space, p, &updating_visitor); |
3525 break; | 3541 break; |
3526 case CODE_SPACE: | 3542 case CODE_SPACE: |
3527 SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS, REBUILD_SKIP_LIST>( | 3543 if (FLAG_zap_code_space) { |
3528 space, p, &updating_visitor); | 3544 SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS, |
| 3545 REBUILD_SKIP_LIST, |
| 3546 ZAP_FREE_SPACE>( |
| 3547 space, p, &updating_visitor); |
| 3548 } else { |
| 3549 SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS, |
| 3550 REBUILD_SKIP_LIST, |
| 3551 IGNORE_FREE_SPACE>( |
| 3552 space, p, &updating_visitor); |
| 3553 } |
3529 break; | 3554 break; |
3530 default: | 3555 default: |
3531 UNREACHABLE(); | 3556 UNREACHABLE(); |
3532 break; | 3557 break; |
3533 } | 3558 } |
3534 } | 3559 } |
3535 } | 3560 } |
3536 } | 3561 } |
3537 | 3562 |
3538 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_UPDATE_MISC_POINTERS); | 3563 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_UPDATE_MISC_POINTERS); |
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4138 p->set_parallel_sweeping(MemoryChunk::PARALLEL_SWEEPING_PENDING); | 4163 p->set_parallel_sweeping(MemoryChunk::PARALLEL_SWEEPING_PENDING); |
4139 space->IncreaseUnsweptFreeBytes(p); | 4164 space->IncreaseUnsweptFreeBytes(p); |
4140 } | 4165 } |
4141 break; | 4166 break; |
4142 } | 4167 } |
4143 case PRECISE: { | 4168 case PRECISE: { |
4144 if (FLAG_gc_verbose) { | 4169 if (FLAG_gc_verbose) { |
4145 PrintF("Sweeping 0x%" V8PRIxPTR " precisely.\n", | 4170 PrintF("Sweeping 0x%" V8PRIxPTR " precisely.\n", |
4146 reinterpret_cast<intptr_t>(p)); | 4171 reinterpret_cast<intptr_t>(p)); |
4147 } | 4172 } |
4148 if (space->identity() == CODE_SPACE) { | 4173 if (space->identity() == CODE_SPACE && FLAG_zap_code_space) { |
4149 SweepPrecisely<SWEEP_ONLY, REBUILD_SKIP_LIST>(space, p, NULL); | 4174 SweepPrecisely<SWEEP_ONLY, REBUILD_SKIP_LIST, ZAP_FREE_SPACE>( |
| 4175 space, p, NULL); |
| 4176 } else if (space->identity() == CODE_SPACE) { |
| 4177 SweepPrecisely<SWEEP_ONLY, REBUILD_SKIP_LIST, IGNORE_FREE_SPACE>( |
| 4178 space, p, NULL); |
4150 } else { | 4179 } else { |
4151 SweepPrecisely<SWEEP_ONLY, IGNORE_SKIP_LIST>(space, p, NULL); | 4180 SweepPrecisely<SWEEP_ONLY, IGNORE_SKIP_LIST, IGNORE_FREE_SPACE>( |
| 4181 space, p, NULL); |
4152 } | 4182 } |
4153 pages_swept++; | 4183 pages_swept++; |
4154 break; | 4184 break; |
4155 } | 4185 } |
4156 default: { | 4186 default: { |
4157 UNREACHABLE(); | 4187 UNREACHABLE(); |
4158 } | 4188 } |
4159 } | 4189 } |
4160 } | 4190 } |
4161 | 4191 |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4446 while (buffer != NULL) { | 4476 while (buffer != NULL) { |
4447 SlotsBuffer* next_buffer = buffer->next(); | 4477 SlotsBuffer* next_buffer = buffer->next(); |
4448 DeallocateBuffer(buffer); | 4478 DeallocateBuffer(buffer); |
4449 buffer = next_buffer; | 4479 buffer = next_buffer; |
4450 } | 4480 } |
4451 *buffer_address = NULL; | 4481 *buffer_address = NULL; |
4452 } | 4482 } |
4453 | 4483 |
4454 | 4484 |
4455 } } // namespace v8::internal | 4485 } } // namespace v8::internal |
OLD | NEW |