Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(291)

Side by Side Diff: src/mark-compact.cc

Issue 7712026: Clear mark bits while sweeping and not explicitly. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/gc
Patch Set: Correctly handle incremental marking as well. Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/mark-compact.h ('k') | src/spaces.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 273
274 heap_->isolate()->pc_to_code_cache()->Flush(); 274 heap_->isolate()->pc_to_code_cache()->Flush();
275 275
276 Finish(); 276 Finish();
277 277
278 tracer_ = NULL; 278 tracer_ = NULL;
279 } 279 }
280 280
281 281
282 #ifdef DEBUG 282 #ifdef DEBUG
283 static void VerifyMarkbitsAreClean(PagedSpace* space) { 283 void MarkCompactCollector::VerifyMarkbitsAreClean(PagedSpace* space) {
284 PageIterator it(space); 284 PageIterator it(space);
285 285
286 while (it.has_next()) { 286 while (it.has_next()) {
287 Page* p = it.next(); 287 Page* p = it.next();
288 ASSERT(p->markbits()->IsClean()); 288 ASSERT(p->markbits()->IsClean());
289 } 289 }
290 } 290 }
291 291
292 static void VerifyMarkbitsAreClean(NewSpace* space) { 292 void MarkCompactCollector::VerifyMarkbitsAreClean(NewSpace* space) {
293 NewSpacePageIterator it(space->bottom(), space->top()); 293 NewSpacePageIterator it(space->bottom(), space->top());
294 294
295 while (it.has_next()) { 295 while (it.has_next()) {
296 NewSpacePage* p = it.next(); 296 NewSpacePage* p = it.next();
297 ASSERT(p->markbits()->IsClean()); 297 ASSERT(p->markbits()->IsClean());
298 } 298 }
299 } 299 }
300 300
301 static void VerifyMarkbitsAreClean(Heap* heap) { 301 void MarkCompactCollector::VerifyMarkbitsAreClean() {
302 VerifyMarkbitsAreClean(heap->old_pointer_space()); 302 VerifyMarkbitsAreClean(heap_->old_pointer_space());
303 VerifyMarkbitsAreClean(heap->old_data_space()); 303 VerifyMarkbitsAreClean(heap_->old_data_space());
304 VerifyMarkbitsAreClean(heap->code_space()); 304 VerifyMarkbitsAreClean(heap_->code_space());
305 VerifyMarkbitsAreClean(heap->cell_space()); 305 VerifyMarkbitsAreClean(heap_->cell_space());
306 VerifyMarkbitsAreClean(heap->map_space()); 306 VerifyMarkbitsAreClean(heap_->map_space());
307 VerifyMarkbitsAreClean(heap->new_space()); 307 VerifyMarkbitsAreClean(heap_->new_space());
308 } 308 }
309 #endif 309 #endif
310 310
311 311
312 static void ClearMarkbits(PagedSpace* space) { 312 static void ClearMarkbits(PagedSpace* space) {
313 PageIterator it(space); 313 PageIterator it(space);
314 314
315 while (it.has_next()) { 315 while (it.has_next()) {
316 Bitmap::Clear(it.next()); 316 Bitmap::Clear(it.next());
317 } 317 }
318 } 318 }
319 319
320 320
321 static void ClearMarkbits(NewSpace* space) { 321 static void ClearMarkbits(NewSpace* space) {
322 NewSpacePageIterator it(space->ToSpaceStart(), space->ToSpaceEnd()); 322 NewSpacePageIterator it(space->ToSpaceStart(), space->ToSpaceEnd());
323 323
324 while (it.has_next()) { 324 while (it.has_next()) {
325 Bitmap::Clear(it.next()); 325 Bitmap::Clear(it.next());
326 } 326 }
327 } 327 }
328 328
329 329
330 static void ClearMarkbits(Heap* heap) { 330 static void ClearMarkbits(Heap* heap) {
331 // TODO(gc): Clean the mark bits while sweeping.
332 ClearMarkbits(heap->code_space()); 331 ClearMarkbits(heap->code_space());
333 ClearMarkbits(heap->map_space()); 332 ClearMarkbits(heap->map_space());
334 ClearMarkbits(heap->old_pointer_space()); 333 ClearMarkbits(heap->old_pointer_space());
335 ClearMarkbits(heap->old_data_space()); 334 ClearMarkbits(heap->old_data_space());
336 ClearMarkbits(heap->cell_space()); 335 ClearMarkbits(heap->cell_space());
337 ClearMarkbits(heap->new_space()); 336 ClearMarkbits(heap->new_space());
338 } 337 }
339 338
340 339
341 bool Marking::TransferMark(Address old_start, Address new_start) { 340 bool Marking::TransferMark(Address old_start, Address new_start) {
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 ASSERT(!FLAG_always_compact || !FLAG_never_compact); 424 ASSERT(!FLAG_always_compact || !FLAG_never_compact);
426 425
427 if (collect_maps_) CreateBackPointers(); 426 if (collect_maps_) CreateBackPointers();
428 #ifdef ENABLE_GDB_JIT_INTERFACE 427 #ifdef ENABLE_GDB_JIT_INTERFACE
429 if (FLAG_gdbjit) { 428 if (FLAG_gdbjit) {
430 // If GDBJIT interface is active disable compaction. 429 // If GDBJIT interface is active disable compaction.
431 compacting_collection_ = false; 430 compacting_collection_ = false;
432 } 431 }
433 #endif 432 #endif
434 433
434 // Clear marking bits for precise sweeping to collect all garbage.
435 if (heap()->incremental_marking()->IsMarking() && PreciseSweepingRequired()) { 435 if (heap()->incremental_marking()->IsMarking() && PreciseSweepingRequired()) {
436 heap()->incremental_marking()->Abort(); 436 heap()->incremental_marking()->Abort();
437 ClearMarkbits(heap_);
437 } 438 }
438 439
439 if (!FLAG_never_compact) StartCompaction(); 440 if (!FLAG_never_compact) StartCompaction();
440 441
441 PagedSpaces spaces; 442 PagedSpaces spaces;
442 for (PagedSpace* space = spaces.next(); 443 for (PagedSpace* space = spaces.next();
443 space != NULL; 444 space != NULL;
444 space = spaces.next()) { 445 space = spaces.next()) {
445 space->PrepareForMarkCompact(); 446 space->PrepareForMarkCompact();
446 } 447 }
447 448
449 #ifdef DEBUG
448 if (!heap()->incremental_marking()->IsMarking()) { 450 if (!heap()->incremental_marking()->IsMarking()) {
449 ClearMarkbits(heap_); 451 VerifyMarkbitsAreClean();
450 #ifdef DEBUG 452 }
451 VerifyMarkbitsAreClean(heap_);
452 #endif 453 #endif
453 }
454 454
455 #ifdef DEBUG 455 #ifdef DEBUG
456 live_bytes_ = 0; 456 live_bytes_ = 0;
457 live_young_objects_size_ = 0; 457 live_young_objects_size_ = 0;
458 live_old_pointer_objects_size_ = 0; 458 live_old_pointer_objects_size_ = 0;
459 live_old_data_objects_size_ = 0; 459 live_old_data_objects_size_ = 0;
460 live_code_objects_size_ = 0; 460 live_code_objects_size_ = 0;
461 live_map_objects_size_ = 0; 461 live_map_objects_size_ = 0;
462 live_cell_objects_size_ = 0; 462 live_cell_objects_size_ = 0;
463 live_lo_objects_size_ = 0; 463 live_lo_objects_size_ = 0;
(...skipping 2153 matching lines...) Expand 10 before | Expand all | Expand 10 after
2617 2617
2618 2618
2619 // Sweep a space precisely. After this has been done the space can 2619 // Sweep a space precisely. After this has been done the space can
2620 // be iterated precisely, hitting only the live objects. Code space 2620 // be iterated precisely, hitting only the live objects. Code space
2621 // is always swept precisely because we want to be able to iterate 2621 // is always swept precisely because we want to be able to iterate
2622 // over it. Map space is swept precisely, because it is not compacted. 2622 // over it. Map space is swept precisely, because it is not compacted.
2623 // Slots in live objects pointing into evacuation candidates are updated 2623 // Slots in live objects pointing into evacuation candidates are updated
2624 // if requested. 2624 // if requested.
2625 static void SweepPrecisely(PagedSpace* space, Page* p, SweepingMode mode) { 2625 static void SweepPrecisely(PagedSpace* space, Page* p, SweepingMode mode) {
2626 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept()); 2626 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept());
2627 ASSERT(!p->IsFlagSet(MemoryChunk::WAS_SWEPT_CONSERVATIVELY));
2627 MarkBit::CellType* cells = p->markbits()->cells(); 2628 MarkBit::CellType* cells = p->markbits()->cells();
2628
2629 p->ClearFlag(MemoryChunk::WAS_SWEPT_CONSERVATIVELY);
2630 p->MarkSwept(); 2629 p->MarkSwept();
2631 2630
2632 int last_cell_index = 2631 int last_cell_index =
2633 Bitmap::IndexToCell( 2632 Bitmap::IndexToCell(
2634 Bitmap::CellAlignIndex( 2633 Bitmap::CellAlignIndex(
2635 p->AddressToMarkbitIndex(p->ObjectAreaEnd()))); 2634 p->AddressToMarkbitIndex(p->ObjectAreaEnd())));
2636 2635
2637 int cell_index = Page::kFirstUsedCell; 2636 int cell_index = Page::kFirstUsedCell;
2638 Address free_start = p->ObjectAreaStart(); 2637 Address free_start = p->ObjectAreaStart();
2639 ASSERT(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); 2638 ASSERT(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0);
(...skipping 16 matching lines...) Expand all
2656 } 2655 }
2657 HeapObject* live_object = HeapObject::FromAddress(free_end); 2656 HeapObject* live_object = HeapObject::FromAddress(free_end);
2658 ASSERT(Marking::IsBlack(Marking::MarkBitFrom(live_object))); 2657 ASSERT(Marking::IsBlack(Marking::MarkBitFrom(live_object)));
2659 int size = live_object->Size(); 2658 int size = live_object->Size();
2660 if (mode == SWEEP_AND_UPDATE_SLOTS) { 2659 if (mode == SWEEP_AND_UPDATE_SLOTS) {
2661 UpdateSlotsInRange(HeapObject::RawField(live_object, kPointerSize), 2660 UpdateSlotsInRange(HeapObject::RawField(live_object, kPointerSize),
2662 HeapObject::RawField(live_object, size)); 2661 HeapObject::RawField(live_object, size));
2663 } 2662 }
2664 free_start = free_end + size; 2663 free_start = free_end + size;
2665 } 2664 }
2665 // Clear marking bits for current cell.
2666 cells[cell_index] = 0;
2666 } 2667 }
2667 if (free_start != p->ObjectAreaEnd()) { 2668 if (free_start != p->ObjectAreaEnd()) {
2668 space->Free(free_start, static_cast<int>(p->ObjectAreaEnd() - free_start)); 2669 space->Free(free_start, static_cast<int>(p->ObjectAreaEnd() - free_start));
2669 } 2670 }
2670 } 2671 }
2671 2672
2672 2673
2673 void MarkCompactCollector::EvacuateNewSpaceAndCandidates() { 2674 void MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
2674 EvacuateNewSpace(); 2675 EvacuateNewSpace();
2675 EvacuatePages(); 2676 EvacuatePages();
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
3096 3097
3097 // Sweeps a space conservatively. After this has been done the larger free 3098 // Sweeps a space conservatively. After this has been done the larger free
3098 // spaces have been put on the free list and the smaller ones have been 3099 // spaces have been put on the free list and the smaller ones have been
3099 // ignored and left untouched. A free space is always either ignored or put 3100 // ignored and left untouched. A free space is always either ignored or put
3100 // on the free list, never split up into two parts. This is important 3101 // on the free list, never split up into two parts. This is important
3101 // because it means that any FreeSpace maps left actually describe a region of 3102 // because it means that any FreeSpace maps left actually describe a region of
3102 // memory that can be ignored when scanning. Dead objects other than free 3103 // memory that can be ignored when scanning. Dead objects other than free
3103 // spaces will not contain the free space map. 3104 // spaces will not contain the free space map.
3104 intptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space, Page* p) { 3105 intptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space, Page* p) {
3105 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept()); 3106 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept());
3106
3107 intptr_t freed_bytes = 0;
3108
3109 MarkBit::CellType* cells = p->markbits()->cells(); 3107 MarkBit::CellType* cells = p->markbits()->cells();
3110
3111 p->SetFlag(MemoryChunk::WAS_SWEPT_CONSERVATIVELY); 3108 p->SetFlag(MemoryChunk::WAS_SWEPT_CONSERVATIVELY);
3112 3109
3113 // This is the start of the 32 word block that we are currently looking at.
3114 Address block_address = p->ObjectAreaStart();
3115
3116 int last_cell_index = 3110 int last_cell_index =
3117 Bitmap::IndexToCell( 3111 Bitmap::IndexToCell(
3118 Bitmap::CellAlignIndex( 3112 Bitmap::CellAlignIndex(
3119 p->AddressToMarkbitIndex(p->ObjectAreaEnd()))); 3113 p->AddressToMarkbitIndex(p->ObjectAreaEnd())));
3120 3114
3121 int cell_index = Page::kFirstUsedCell; 3115 int cell_index = Page::kFirstUsedCell;
3116 intptr_t freed_bytes = 0;
3117
3118 // This is the start of the 32 word block that we are currently looking at.
3119 Address block_address = p->ObjectAreaStart();
3122 3120
3123 // Skip over all the dead objects at the start of the page and mark them free. 3121 // Skip over all the dead objects at the start of the page and mark them free.
3124 for (cell_index = Page::kFirstUsedCell; 3122 for (cell_index = Page::kFirstUsedCell;
3125 cell_index < last_cell_index; 3123 cell_index < last_cell_index;
3126 cell_index++, block_address += 32 * kPointerSize) { 3124 cell_index++, block_address += 32 * kPointerSize) {
3127 if (cells[cell_index] != 0) break; 3125 if (cells[cell_index] != 0) break;
3128 } 3126 }
3129 size_t size = block_address - p->ObjectAreaStart(); 3127 size_t size = block_address - p->ObjectAreaStart();
3130 if (cell_index == last_cell_index) { 3128 if (cell_index == last_cell_index) {
3131 freed_bytes += static_cast<int>(space->Free(p->ObjectAreaStart(), 3129 freed_bytes += static_cast<int>(space->Free(p->ObjectAreaStart(),
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3167 // so now we need to find the start of the first live object at the 3165 // so now we need to find the start of the first live object at the
3168 // end of the free space. 3166 // end of the free space.
3169 free_end = StartOfLiveObject(block_address, cell); 3167 free_end = StartOfLiveObject(block_address, cell);
3170 freed_bytes += space->Free(free_start, 3168 freed_bytes += space->Free(free_start,
3171 static_cast<int>(free_end - free_start)); 3169 static_cast<int>(free_end - free_start));
3172 } 3170 }
3173 } 3171 }
3174 // Update our undigested record of where the current free area started. 3172 // Update our undigested record of where the current free area started.
3175 free_start = block_address; 3173 free_start = block_address;
3176 free_start_cell = cell; 3174 free_start_cell = cell;
3175 // Clear marking bits for current cell.
3176 cells[cell_index] = 0;
3177 } 3177 }
3178 } 3178 }
3179 3179
3180 // Handle the free space at the end of the page. 3180 // Handle the free space at the end of the page.
3181 if (block_address - free_start > 32 * kPointerSize) { 3181 if (block_address - free_start > 32 * kPointerSize) {
3182 free_start = DigestFreeStart(free_start, free_start_cell); 3182 free_start = DigestFreeStart(free_start, free_start_cell);
3183 freed_bytes += space->Free(free_start, 3183 freed_bytes += space->Free(free_start,
3184 static_cast<int>(block_address - free_start)); 3184 static_cast<int>(block_address - free_start));
3185 } 3185 }
3186 3186
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
3394 while (buffer != NULL) { 3394 while (buffer != NULL) {
3395 SlotsBuffer* next_buffer = buffer->next(); 3395 SlotsBuffer* next_buffer = buffer->next();
3396 DeallocateBuffer(buffer); 3396 DeallocateBuffer(buffer);
3397 buffer = next_buffer; 3397 buffer = next_buffer;
3398 } 3398 }
3399 *buffer_address = NULL; 3399 *buffer_address = NULL;
3400 } 3400 }
3401 3401
3402 3402
3403 } } // namespace v8::internal 3403 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/mark-compact.h ('k') | src/spaces.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698