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 |