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

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

Issue 9289047: Reduce boot-up memory use of V8. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 8 years, 11 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
OLDNEW
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 2900 matching lines...) Expand 10 before | Expand all | Expand 10 after
2911 cell_index++, object_address += 32 * kPointerSize) { 2911 cell_index++, object_address += 32 * kPointerSize) {
2912 ASSERT((unsigned)cell_index == 2912 ASSERT((unsigned)cell_index ==
2913 Bitmap::IndexToCell( 2913 Bitmap::IndexToCell(
2914 Bitmap::CellAlignIndex( 2914 Bitmap::CellAlignIndex(
2915 p->AddressToMarkbitIndex(object_address)))); 2915 p->AddressToMarkbitIndex(object_address))));
2916 int live_objects = MarkWordToObjectStarts(cells[cell_index], offsets); 2916 int live_objects = MarkWordToObjectStarts(cells[cell_index], offsets);
2917 int live_index = 0; 2917 int live_index = 0;
2918 for ( ; live_objects != 0; live_objects--) { 2918 for ( ; live_objects != 0; live_objects--) {
2919 Address free_end = object_address + offsets[live_index++] * kPointerSize; 2919 Address free_end = object_address + offsets[live_index++] * kPointerSize;
2920 if (free_end != free_start) { 2920 if (free_end != free_start) {
2921 space->Free(free_start, static_cast<int>(free_end - free_start)); 2921 space->AddToFreeLists(free_start,
2922 static_cast<int>(free_end - free_start));
2922 } 2923 }
2923 HeapObject* live_object = HeapObject::FromAddress(free_end); 2924 HeapObject* live_object = HeapObject::FromAddress(free_end);
2924 ASSERT(Marking::IsBlack(Marking::MarkBitFrom(live_object))); 2925 ASSERT(Marking::IsBlack(Marking::MarkBitFrom(live_object)));
2925 Map* map = live_object->map(); 2926 Map* map = live_object->map();
2926 int size = live_object->SizeFromMap(map); 2927 int size = live_object->SizeFromMap(map);
2927 if (sweeping_mode == SWEEP_AND_VISIT_LIVE_OBJECTS) { 2928 if (sweeping_mode == SWEEP_AND_VISIT_LIVE_OBJECTS) {
2928 live_object->IterateBody(map->instance_type(), size, v); 2929 live_object->IterateBody(map->instance_type(), size, v);
2929 } 2930 }
2930 if ((skip_list_mode == REBUILD_SKIP_LIST) && skip_list != NULL) { 2931 if ((skip_list_mode == REBUILD_SKIP_LIST) && skip_list != NULL) {
2931 int new_region_start = 2932 int new_region_start =
2932 SkipList::RegionNumber(free_end); 2933 SkipList::RegionNumber(free_end);
2933 int new_region_end = 2934 int new_region_end =
2934 SkipList::RegionNumber(free_end + size - kPointerSize); 2935 SkipList::RegionNumber(free_end + size - kPointerSize);
2935 if (new_region_start != curr_region || 2936 if (new_region_start != curr_region ||
2936 new_region_end != curr_region) { 2937 new_region_end != curr_region) {
2937 skip_list->AddObject(free_end, size); 2938 skip_list->AddObject(free_end, size);
2938 curr_region = new_region_end; 2939 curr_region = new_region_end;
2939 } 2940 }
2940 } 2941 }
2941 free_start = free_end + size; 2942 free_start = free_end + size;
2942 } 2943 }
2943 // Clear marking bits for current cell. 2944 // Clear marking bits for current cell.
2944 cells[cell_index] = 0; 2945 cells[cell_index] = 0;
2945 } 2946 }
2946 if (free_start != p->ObjectAreaEnd()) { 2947 if (free_start != p->ObjectAreaEnd()) {
2947 space->Free(free_start, static_cast<int>(p->ObjectAreaEnd() - free_start)); 2948 space->AddToFreeLists(free_start,
2949 static_cast<int>(p->ObjectAreaEnd() - free_start));
2948 } 2950 }
2949 p->ResetLiveBytes(); 2951 p->ResetLiveBytes();
2950 } 2952 }
2951 2953
2952 2954
2953 static bool SetMarkBitsUnderInvalidatedCode(Code* code, bool value) { 2955 static bool SetMarkBitsUnderInvalidatedCode(Code* code, bool value) {
2954 Page* p = Page::FromAddress(code->address()); 2956 Page* p = Page::FromAddress(code->address());
2955 2957
2956 if (p->IsEvacuationCandidate() || 2958 if (p->IsEvacuationCandidate() ||
2957 p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) { 2959 p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) {
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
3230 VerifyEvacuation(heap_); 3232 VerifyEvacuation(heap_);
3231 } 3233 }
3232 #endif 3234 #endif
3233 3235
3234 slots_buffer_allocator_.DeallocateChain(&migration_slots_buffer_); 3236 slots_buffer_allocator_.DeallocateChain(&migration_slots_buffer_);
3235 ASSERT(migration_slots_buffer_ == NULL); 3237 ASSERT(migration_slots_buffer_ == NULL);
3236 for (int i = 0; i < npages; i++) { 3238 for (int i = 0; i < npages; i++) {
3237 Page* p = evacuation_candidates_[i]; 3239 Page* p = evacuation_candidates_[i];
3238 if (!p->IsEvacuationCandidate()) continue; 3240 if (!p->IsEvacuationCandidate()) continue;
3239 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); 3241 PagedSpace* space = static_cast<PagedSpace*>(p->owner());
3240 space->Free(p->ObjectAreaStart(), Page::kObjectAreaSize); 3242 space->AddToFreeLists(
3243 p->ObjectAreaStart(),
3244 static_cast<int>(p->ObjectAreaEnd() - p->ObjectAreaStart()));
3241 p->set_scan_on_scavenge(false); 3245 p->set_scan_on_scavenge(false);
3242 slots_buffer_allocator_.DeallocateChain(p->slots_buffer_address()); 3246 slots_buffer_allocator_.DeallocateChain(p->slots_buffer_address());
3243 p->ClearEvacuationCandidate(); 3247 p->ClearEvacuationCandidate();
3244 } 3248 }
3245 evacuation_candidates_.Rewind(0); 3249 evacuation_candidates_.Rewind(0);
3246 compacting_ = false; 3250 compacting_ = false;
3247 } 3251 }
3248 3252
3249 3253
3250 static const int kStartTableEntriesPerLine = 5; 3254 static const int kStartTableEntriesPerLine = 5;
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
3547 Address block_address = p->ObjectAreaStart(); 3551 Address block_address = p->ObjectAreaStart();
3548 3552
3549 // Skip over all the dead objects at the start of the page and mark them free. 3553 // Skip over all the dead objects at the start of the page and mark them free.
3550 for (cell_index = Page::kFirstUsedCell; 3554 for (cell_index = Page::kFirstUsedCell;
3551 cell_index < last_cell_index; 3555 cell_index < last_cell_index;
3552 cell_index++, block_address += 32 * kPointerSize) { 3556 cell_index++, block_address += 32 * kPointerSize) {
3553 if (cells[cell_index] != 0) break; 3557 if (cells[cell_index] != 0) break;
3554 } 3558 }
3555 size_t size = block_address - p->ObjectAreaStart(); 3559 size_t size = block_address - p->ObjectAreaStart();
3556 if (cell_index == last_cell_index) { 3560 if (cell_index == last_cell_index) {
3557 freed_bytes += static_cast<int>(space->Free(p->ObjectAreaStart(), 3561 freed_bytes += static_cast<int>(space->AddToFreeLists(
3558 static_cast<int>(size))); 3562 p->ObjectAreaStart(), static_cast<int>(size)));
3559 ASSERT_EQ(0, p->LiveBytes()); 3563 ASSERT_EQ(0, p->LiveBytes());
3560 return freed_bytes; 3564 return freed_bytes;
3561 } 3565 }
3562 // Grow the size of the start-of-page free space a little to get up to the 3566 // Grow the size of the start-of-page free space a little to get up to the
3563 // first live object. 3567 // first live object.
3564 Address free_end = StartOfLiveObject(block_address, cells[cell_index]); 3568 Address free_end = StartOfLiveObject(block_address, cells[cell_index]);
3565 // Free the first free space. 3569 // Free the first free space.
3566 size = free_end - p->ObjectAreaStart(); 3570 size = free_end - p->ObjectAreaStart();
3567 freed_bytes += space->Free(p->ObjectAreaStart(), 3571 freed_bytes += space->AddToFreeLists(p->ObjectAreaStart(),
3568 static_cast<int>(size)); 3572 static_cast<int>(size));
3569 // The start of the current free area is represented in undigested form by 3573 // The start of the current free area is represented in undigested form by
3570 // the address of the last 32-word section that contained a live object and 3574 // the address of the last 32-word section that contained a live object and
3571 // the marking bitmap for that cell, which describes where the live object 3575 // the marking bitmap for that cell, which describes where the live object
3572 // started. Unless we find a large free space in the bitmap we will not 3576 // started. Unless we find a large free space in the bitmap we will not
3573 // digest this pair into a real address. We start the iteration here at the 3577 // digest this pair into a real address. We start the iteration here at the
3574 // first word in the marking bit map that indicates a live object. 3578 // first word in the marking bit map that indicates a live object.
3575 Address free_start = block_address; 3579 Address free_start = block_address;
3576 uint32_t free_start_cell = cells[cell_index]; 3580 uint32_t free_start_cell = cells[cell_index];
3577 3581
3578 for ( ; 3582 for ( ;
3579 cell_index < last_cell_index; 3583 cell_index < last_cell_index;
3580 cell_index++, block_address += 32 * kPointerSize) { 3584 cell_index++, block_address += 32 * kPointerSize) {
3581 ASSERT((unsigned)cell_index == 3585 ASSERT((unsigned)cell_index ==
3582 Bitmap::IndexToCell( 3586 Bitmap::IndexToCell(
3583 Bitmap::CellAlignIndex( 3587 Bitmap::CellAlignIndex(
3584 p->AddressToMarkbitIndex(block_address)))); 3588 p->AddressToMarkbitIndex(block_address))));
3585 uint32_t cell = cells[cell_index]; 3589 uint32_t cell = cells[cell_index];
3586 if (cell != 0) { 3590 if (cell != 0) {
3587 // We have a live object. Check approximately whether it is more than 32 3591 // We have a live object. Check approximately whether it is more than 32
3588 // words since the last live object. 3592 // words since the last live object.
3589 if (block_address - free_start > 32 * kPointerSize) { 3593 if (block_address - free_start > 32 * kPointerSize) {
3590 free_start = DigestFreeStart(free_start, free_start_cell); 3594 free_start = DigestFreeStart(free_start, free_start_cell);
3591 if (block_address - free_start > 32 * kPointerSize) { 3595 if (block_address - free_start > 32 * kPointerSize) {
3592 // Now that we know the exact start of the free space it still looks 3596 // Now that we know the exact start of the free space it still looks
3593 // like we have a large enough free space to be worth bothering with. 3597 // like we have a large enough free space to be worth bothering with.
3594 // so now we need to find the start of the first live object at the 3598 // so now we need to find the start of the first live object at the
3595 // end of the free space. 3599 // end of the free space.
3596 free_end = StartOfLiveObject(block_address, cell); 3600 free_end = StartOfLiveObject(block_address, cell);
3597 freed_bytes += space->Free(free_start, 3601 freed_bytes += space->AddToFreeLists(
3598 static_cast<int>(free_end - free_start)); 3602 free_start, static_cast<int>(free_end - free_start));
3599 } 3603 }
3600 } 3604 }
3601 // Update our undigested record of where the current free area started. 3605 // Update our undigested record of where the current free area started.
3602 free_start = block_address; 3606 free_start = block_address;
3603 free_start_cell = cell; 3607 free_start_cell = cell;
3604 // Clear marking bits for current cell. 3608 // Clear marking bits for current cell.
3605 cells[cell_index] = 0; 3609 cells[cell_index] = 0;
3606 } 3610 }
3607 } 3611 }
3608 3612
3609 // Handle the free space at the end of the page. 3613 // Handle the free space at the end of the page.
3610 if (block_address - free_start > 32 * kPointerSize) { 3614 if (block_address - free_start > 32 * kPointerSize) {
3611 free_start = DigestFreeStart(free_start, free_start_cell); 3615 free_start = DigestFreeStart(free_start, free_start_cell);
3612 freed_bytes += space->Free(free_start, 3616 freed_bytes += space->AddToFreeLists(
3613 static_cast<int>(block_address - free_start)); 3617 free_start, static_cast<int>(block_address - free_start));
3614 } 3618 }
3615 3619
3616 p->ResetLiveBytes(); 3620 p->ResetLiveBytes();
3617 return freed_bytes; 3621 return freed_bytes;
3618 } 3622 }
3619 3623
3620 3624
3621 void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) { 3625 void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) {
3622 space->set_was_swept_conservatively(sweeper == CONSERVATIVE || 3626 space->set_was_swept_conservatively(sweeper == CONSERVATIVE ||
3623 sweeper == LAZY_CONSERVATIVE); 3627 sweeper == LAZY_CONSERVATIVE);
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
3938 while (buffer != NULL) { 3942 while (buffer != NULL) {
3939 SlotsBuffer* next_buffer = buffer->next(); 3943 SlotsBuffer* next_buffer = buffer->next();
3940 DeallocateBuffer(buffer); 3944 DeallocateBuffer(buffer);
3941 buffer = next_buffer; 3945 buffer = next_buffer;
3942 } 3946 }
3943 *buffer_address = NULL; 3947 *buffer_address = NULL;
3944 } 3948 }
3945 3949
3946 3950
3947 } } // namespace v8::internal 3951 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698