| 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 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 #endif // DEBUG | 410 #endif // DEBUG |
| 411 | 411 |
| 412 #if defined(DEBUG) | 412 #if defined(DEBUG) |
| 413 ReportStatisticsBeforeGC(); | 413 ReportStatisticsBeforeGC(); |
| 414 #endif // DEBUG | 414 #endif // DEBUG |
| 415 | 415 |
| 416 LiveObjectList::GCPrologue(); | 416 LiveObjectList::GCPrologue(); |
| 417 store_buffer()->GCPrologue(); | 417 store_buffer()->GCPrologue(); |
| 418 } | 418 } |
| 419 | 419 |
| 420 |
| 420 intptr_t Heap::SizeOfObjects() { | 421 intptr_t Heap::SizeOfObjects() { |
| 421 intptr_t total = 0; | 422 intptr_t total = 0; |
| 422 AllSpaces spaces; | 423 AllSpaces spaces; |
| 423 for (Space* space = spaces.next(); space != NULL; space = spaces.next()) { | 424 for (Space* space = spaces.next(); space != NULL; space = spaces.next()) { |
| 424 total += space->SizeOfObjects(); | 425 total += space->SizeOfObjects(); |
| 425 } | 426 } |
| 426 return total; | 427 return total; |
| 427 } | 428 } |
| 428 | 429 |
| 430 |
| 431 void Heap::RepairFreeListsAfterBoot() { |
| 432 PagedSpaces spaces; |
| 433 for (PagedSpace* space = spaces.next(); |
| 434 space != NULL; |
| 435 space = spaces.next()) { |
| 436 space->RepairFreeListsAfterBoot(); |
| 437 } |
| 438 } |
| 439 |
| 440 |
| 429 void Heap::GarbageCollectionEpilogue() { | 441 void Heap::GarbageCollectionEpilogue() { |
| 430 store_buffer()->GCEpilogue(); | 442 store_buffer()->GCEpilogue(); |
| 431 LiveObjectList::GCEpilogue(); | 443 LiveObjectList::GCEpilogue(); |
| 432 #ifdef DEBUG | 444 #ifdef DEBUG |
| 433 allow_allocation(true); | 445 allow_allocation(true); |
| 434 ZapFromSpace(); | 446 ZapFromSpace(); |
| 435 | 447 |
| 436 if (FLAG_verify_heap) { | 448 if (FLAG_verify_heap) { |
| 437 Verify(); | 449 Verify(); |
| 438 } | 450 } |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 661 AllocationSpace space, | 673 AllocationSpace space, |
| 662 const char* gc_reason = NULL) { | 674 const char* gc_reason = NULL) { |
| 663 heap->mark_compact_collector()->SetFlags(Heap::kAbortIncrementalMarkingMask); | 675 heap->mark_compact_collector()->SetFlags(Heap::kAbortIncrementalMarkingMask); |
| 664 bool result = heap->CollectGarbage(space, gc_reason); | 676 bool result = heap->CollectGarbage(space, gc_reason); |
| 665 heap->mark_compact_collector()->SetFlags(Heap::kNoGCFlags); | 677 heap->mark_compact_collector()->SetFlags(Heap::kNoGCFlags); |
| 666 return result; | 678 return result; |
| 667 } | 679 } |
| 668 | 680 |
| 669 | 681 |
| 670 void Heap::ReserveSpace( | 682 void Heap::ReserveSpace( |
| 671 int new_space_size, | 683 intptr_t *sizes, |
| 672 int pointer_space_size, | 684 Address *locations_out) { |
| 673 int data_space_size, | |
| 674 int code_space_size, | |
| 675 int map_space_size, | |
| 676 int cell_space_size, | |
| 677 int large_object_size) { | |
| 678 NewSpace* new_space = Heap::new_space(); | |
| 679 PagedSpace* old_pointer_space = Heap::old_pointer_space(); | |
| 680 PagedSpace* old_data_space = Heap::old_data_space(); | |
| 681 PagedSpace* code_space = Heap::code_space(); | |
| 682 PagedSpace* map_space = Heap::map_space(); | |
| 683 PagedSpace* cell_space = Heap::cell_space(); | |
| 684 LargeObjectSpace* lo_space = Heap::lo_space(); | |
| 685 bool gc_performed = true; | 685 bool gc_performed = true; |
| 686 int counter = 0; | 686 int counter = 0; |
| 687 static const int kThreshold = 20; | 687 static const int kThreshold = 20; |
| 688 while (gc_performed && counter++ < kThreshold) { | 688 while (gc_performed && counter++ < kThreshold) { |
| 689 gc_performed = false; | 689 gc_performed = false; |
| 690 if (!new_space->ReserveSpace(new_space_size)) { | 690 ASSERT(NEW_SPACE == FIRST_PAGED_SPACE - 1); |
| 691 Heap::CollectGarbage(NEW_SPACE, | 691 for (int space = NEW_SPACE; space <= LAST_PAGED_SPACE; space++) { |
| 692 "failed to reserve space in the new space"); | 692 if (sizes[space] != 0) { |
| 693 gc_performed = true; | 693 MaybeObject* allocation; |
| 694 } | 694 if (space == NEW_SPACE) { |
| 695 if (!old_pointer_space->ReserveSpace(pointer_space_size)) { | 695 allocation = new_space()->AllocateRaw(sizes[space]); |
| 696 AbortIncrementalMarkingAndCollectGarbage(this, OLD_POINTER_SPACE, | 696 } else { |
| 697 "failed to reserve space in the old pointer space"); | 697 allocation = paged_space(space)->AllocateRaw(sizes[space]); |
| 698 gc_performed = true; | 698 } |
| 699 } | 699 FreeListNode* node; |
| 700 if (!(old_data_space->ReserveSpace(data_space_size))) { | 700 if (!allocation->To<FreeListNode>(&node)) { |
| 701 AbortIncrementalMarkingAndCollectGarbage(this, OLD_DATA_SPACE, | 701 if (space == NEW_SPACE) { |
| 702 "failed to reserve space in the old data space"); | 702 Heap::CollectGarbage(NEW_SPACE, |
| 703 gc_performed = true; | 703 "failed to reserve space in the new space"); |
| 704 } | 704 } else { |
| 705 if (!(code_space->ReserveSpace(code_space_size))) { | 705 AbortIncrementalMarkingAndCollectGarbage( |
| 706 AbortIncrementalMarkingAndCollectGarbage(this, CODE_SPACE, | 706 this, |
| 707 "failed to reserve space in the code space"); | 707 static_cast<AllocationSpace>(space), |
| 708 gc_performed = true; | 708 "failed to reserve space in paged space"); |
| 709 } | 709 } |
| 710 if (!(map_space->ReserveSpace(map_space_size))) { | 710 gc_performed = true; |
| 711 AbortIncrementalMarkingAndCollectGarbage(this, MAP_SPACE, | 711 break; |
| 712 "failed to reserve space in the map space"); | 712 } else { |
| 713 gc_performed = true; | 713 // Mark with a free list node, in case we have a GC before |
| 714 } | 714 // deserializing. |
| 715 if (!(cell_space->ReserveSpace(cell_space_size))) { | 715 node->set_size(this, sizes[space]); |
| 716 AbortIncrementalMarkingAndCollectGarbage(this, CELL_SPACE, | 716 locations_out[space] = node->address(); |
| 717 "failed to reserve space in the cell space"); | 717 } |
| 718 gc_performed = true; | 718 } |
| 719 } | |
| 720 // We add a slack-factor of 2 in order to have space for a series of | |
| 721 // large-object allocations that are only just larger than the page size. | |
| 722 large_object_size *= 2; | |
| 723 // The ReserveSpace method on the large object space checks how much | |
| 724 // we can expand the old generation. This includes expansion caused by | |
| 725 // allocation in the other spaces. | |
| 726 large_object_size += cell_space_size + map_space_size + code_space_size + | |
| 727 data_space_size + pointer_space_size; | |
| 728 if (!(lo_space->ReserveSpace(large_object_size))) { | |
| 729 AbortIncrementalMarkingAndCollectGarbage(this, LO_SPACE, | |
| 730 "failed to reserve space in the large object space"); | |
| 731 gc_performed = true; | |
| 732 } | 719 } |
| 733 } | 720 } |
| 734 | 721 |
| 735 if (gc_performed) { | 722 if (gc_performed) { |
| 736 // Failed to reserve the space after several attempts. | 723 // Failed to reserve the space after several attempts. |
| 737 V8::FatalProcessOutOfMemory("Heap::ReserveSpace"); | 724 V8::FatalProcessOutOfMemory("Heap::ReserveSpace"); |
| 738 } | 725 } |
| 739 } | 726 } |
| 740 | 727 |
| 741 | 728 |
| (...skipping 2851 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3593 MaybeObject* maybe_reloc_info = AllocateByteArray(desc.reloc_size, TENURED); | 3580 MaybeObject* maybe_reloc_info = AllocateByteArray(desc.reloc_size, TENURED); |
| 3594 if (!maybe_reloc_info->To(&reloc_info)) return maybe_reloc_info; | 3581 if (!maybe_reloc_info->To(&reloc_info)) return maybe_reloc_info; |
| 3595 | 3582 |
| 3596 // Compute size. | 3583 // Compute size. |
| 3597 int body_size = RoundUp(desc.instr_size, kObjectAlignment); | 3584 int body_size = RoundUp(desc.instr_size, kObjectAlignment); |
| 3598 int obj_size = Code::SizeFor(body_size); | 3585 int obj_size = Code::SizeFor(body_size); |
| 3599 ASSERT(IsAligned(static_cast<intptr_t>(obj_size), kCodeAlignment)); | 3586 ASSERT(IsAligned(static_cast<intptr_t>(obj_size), kCodeAlignment)); |
| 3600 MaybeObject* maybe_result; | 3587 MaybeObject* maybe_result; |
| 3601 // Large code objects and code objects which should stay at a fixed address | 3588 // Large code objects and code objects which should stay at a fixed address |
| 3602 // are allocated in large object space. | 3589 // are allocated in large object space. |
| 3603 if (obj_size > code_space()->AreaSize() || immovable) { | 3590 HeapObject* result; |
| 3591 bool force_lo_space = obj_size > code_space()->AreaSize(); |
| 3592 if (force_lo_space) { |
| 3604 maybe_result = lo_space_->AllocateRaw(obj_size, EXECUTABLE); | 3593 maybe_result = lo_space_->AllocateRaw(obj_size, EXECUTABLE); |
| 3605 } else { | 3594 } else { |
| 3606 maybe_result = code_space_->AllocateRaw(obj_size); | 3595 maybe_result = code_space_->AllocateRaw(obj_size); |
| 3607 } | 3596 } |
| 3597 if (!maybe_result->To<HeapObject>(&result)) return maybe_result; |
| 3608 | 3598 |
| 3609 Object* result; | 3599 if (immovable && !force_lo_space && |
| 3610 if (!maybe_result->ToObject(&result)) return maybe_result; | 3600 // Objects on the first page of each space are never moved. |
| 3601 !code_space_->FirstPage()->Contains(result->address())) { |
| 3602 // Discard the first code allocation, which was on a page where it could be |
| 3603 // moved. |
| 3604 CreateFillerObjectAt(result->address(), obj_size); |
| 3605 maybe_result = lo_space_->AllocateRaw(obj_size, EXECUTABLE); |
| 3606 if (!maybe_result->To<HeapObject>(&result)) return maybe_result; |
| 3607 } |
| 3611 | 3608 |
| 3612 // Initialize the object | 3609 // Initialize the object |
| 3613 HeapObject::cast(result)->set_map_no_write_barrier(code_map()); | 3610 result->set_map_no_write_barrier(code_map()); |
| 3614 Code* code = Code::cast(result); | 3611 Code* code = Code::cast(result); |
| 3615 ASSERT(!isolate_->code_range()->exists() || | 3612 ASSERT(!isolate_->code_range()->exists() || |
| 3616 isolate_->code_range()->contains(code->address())); | 3613 isolate_->code_range()->contains(code->address())); |
| 3617 code->set_instruction_size(desc.instr_size); | 3614 code->set_instruction_size(desc.instr_size); |
| 3618 code->set_relocation_info(reloc_info); | 3615 code->set_relocation_info(reloc_info); |
| 3619 code->set_flags(flags); | 3616 code->set_flags(flags); |
| 3620 if (code->is_call_stub() || code->is_keyed_call_stub()) { | 3617 if (code->is_call_stub() || code->is_keyed_call_stub()) { |
| 3621 code->set_check_type(RECEIVER_MAP_CHECK); | 3618 code->set_check_type(RECEIVER_MAP_CHECK); |
| 3622 } | 3619 } |
| 3623 code->set_deoptimization_data(empty_fixed_array(), SKIP_WRITE_BARRIER); | 3620 code->set_deoptimization_data(empty_fixed_array(), SKIP_WRITE_BARRIER); |
| (...skipping 3697 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7321 static_cast<int>(object_sizes_last_time_[index])); | 7318 static_cast<int>(object_sizes_last_time_[index])); |
| 7322 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT) | 7319 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT) |
| 7323 #undef ADJUST_LAST_TIME_OBJECT_COUNT | 7320 #undef ADJUST_LAST_TIME_OBJECT_COUNT |
| 7324 | 7321 |
| 7325 memcpy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); | 7322 memcpy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); |
| 7326 memcpy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); | 7323 memcpy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); |
| 7327 ClearObjectStats(); | 7324 ClearObjectStats(); |
| 7328 } | 7325 } |
| 7329 | 7326 |
| 7330 } } // namespace v8::internal | 7327 } } // namespace v8::internal |
| OLD | NEW |