OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 1880 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1891 rem_node->set_next(free_[rem].head_node_); | 1891 rem_node->set_next(free_[rem].head_node_); |
1892 free_[rem].head_node_ = rem_node->address(); | 1892 free_[rem].head_node_ = rem_node->address(); |
1893 if (rem_node->next() == NULL) InsertSize(rem); | 1893 if (rem_node->next() == NULL) InsertSize(rem); |
1894 } | 1894 } |
1895 available_ -= size_in_bytes; | 1895 available_ -= size_in_bytes; |
1896 *wasted_bytes = 0; | 1896 *wasted_bytes = 0; |
1897 return cur_node; | 1897 return cur_node; |
1898 } | 1898 } |
1899 | 1899 |
1900 | 1900 |
| 1901 void OldSpaceFreeList::MarkNodes() { |
| 1902 for (int i = 0; i < kFreeListsLength; i++) { |
| 1903 Address cur_addr = free_[i].head_node_; |
| 1904 while (cur_addr != NULL) { |
| 1905 FreeListNode* cur_node = FreeListNode::FromAddress(cur_addr); |
| 1906 cur_addr = cur_node->next(); |
| 1907 cur_node->SetMark(); |
| 1908 } |
| 1909 } |
| 1910 } |
| 1911 |
| 1912 |
1901 #ifdef DEBUG | 1913 #ifdef DEBUG |
1902 bool OldSpaceFreeList::Contains(FreeListNode* node) { | 1914 bool OldSpaceFreeList::Contains(FreeListNode* node) { |
1903 for (int i = 0; i < kFreeListsLength; i++) { | 1915 for (int i = 0; i < kFreeListsLength; i++) { |
1904 Address cur_addr = free_[i].head_node_; | 1916 Address cur_addr = free_[i].head_node_; |
1905 while (cur_addr != NULL) { | 1917 while (cur_addr != NULL) { |
1906 FreeListNode* cur_node = FreeListNode::FromAddress(cur_addr); | 1918 FreeListNode* cur_node = FreeListNode::FromAddress(cur_addr); |
1907 if (cur_node == node) return true; | 1919 if (cur_node == node) return true; |
1908 cur_addr = cur_node->next(); | 1920 cur_addr = cur_node->next(); |
1909 } | 1921 } |
1910 } | 1922 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1950 } | 1962 } |
1951 | 1963 |
1952 ASSERT(!FLAG_always_compact); // We only use the freelists with mark-sweep. | 1964 ASSERT(!FLAG_always_compact); // We only use the freelists with mark-sweep. |
1953 FreeListNode* node = FreeListNode::FromAddress(head_); | 1965 FreeListNode* node = FreeListNode::FromAddress(head_); |
1954 head_ = node->next(); | 1966 head_ = node->next(); |
1955 available_ -= object_size_; | 1967 available_ -= object_size_; |
1956 return node; | 1968 return node; |
1957 } | 1969 } |
1958 | 1970 |
1959 | 1971 |
| 1972 void FixedSizeFreeList::MarkNodes() { |
| 1973 Address cur_addr = head_; |
| 1974 while (cur_addr != NULL && cur_addr != tail_) { |
| 1975 FreeListNode* cur_node = FreeListNode::FromAddress(cur_addr); |
| 1976 cur_addr = cur_node->next(); |
| 1977 cur_node->SetMark(); |
| 1978 } |
| 1979 } |
| 1980 |
| 1981 |
1960 // ----------------------------------------------------------------------------- | 1982 // ----------------------------------------------------------------------------- |
1961 // OldSpace implementation | 1983 // OldSpace implementation |
1962 | 1984 |
1963 void OldSpace::PrepareForMarkCompact(bool will_compact) { | 1985 void OldSpace::PrepareForMarkCompact(bool will_compact) { |
1964 // Call prepare of the super class. | 1986 // Call prepare of the super class. |
1965 PagedSpace::PrepareForMarkCompact(will_compact); | 1987 PagedSpace::PrepareForMarkCompact(will_compact); |
1966 | 1988 |
1967 if (will_compact) { | 1989 if (will_compact) { |
1968 // Reset relocation info. During a compacting collection, everything in | 1990 // Reset relocation info. During a compacting collection, everything in |
1969 // the space is considered 'available' and we will rediscover live data | 1991 // the space is considered 'available' and we will rediscover live data |
(...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2704 return size_in_bytes + Page::kObjectStartOffset; | 2726 return size_in_bytes + Page::kObjectStartOffset; |
2705 } | 2727 } |
2706 | 2728 |
2707 // ----------------------------------------------------------------------------- | 2729 // ----------------------------------------------------------------------------- |
2708 // LargeObjectSpace | 2730 // LargeObjectSpace |
2709 | 2731 |
2710 LargeObjectSpace::LargeObjectSpace(AllocationSpace id) | 2732 LargeObjectSpace::LargeObjectSpace(AllocationSpace id) |
2711 : Space(id, NOT_EXECUTABLE), // Managed on a per-allocation basis | 2733 : Space(id, NOT_EXECUTABLE), // Managed on a per-allocation basis |
2712 first_chunk_(NULL), | 2734 first_chunk_(NULL), |
2713 size_(0), | 2735 size_(0), |
2714 page_count_(0) {} | 2736 page_count_(0), |
| 2737 objects_size_(0) {} |
2715 | 2738 |
2716 | 2739 |
2717 bool LargeObjectSpace::Setup() { | 2740 bool LargeObjectSpace::Setup() { |
2718 first_chunk_ = NULL; | 2741 first_chunk_ = NULL; |
2719 size_ = 0; | 2742 size_ = 0; |
2720 page_count_ = 0; | 2743 page_count_ = 0; |
| 2744 objects_size_ = 0; |
2721 return true; | 2745 return true; |
2722 } | 2746 } |
2723 | 2747 |
2724 | 2748 |
2725 void LargeObjectSpace::TearDown() { | 2749 void LargeObjectSpace::TearDown() { |
2726 while (first_chunk_ != NULL) { | 2750 while (first_chunk_ != NULL) { |
2727 LargeObjectChunk* chunk = first_chunk_; | 2751 LargeObjectChunk* chunk = first_chunk_; |
2728 first_chunk_ = first_chunk_->next(); | 2752 first_chunk_ = first_chunk_->next(); |
2729 LOG(DeleteEvent("LargeObjectChunk", chunk->address())); | 2753 LOG(DeleteEvent("LargeObjectChunk", chunk->address())); |
2730 Page* page = Page::FromAddress(RoundUp(chunk->address(), Page::kPageSize)); | 2754 Page* page = Page::FromAddress(RoundUp(chunk->address(), Page::kPageSize)); |
2731 Executability executable = | 2755 Executability executable = |
2732 page->IsPageExecutable() ? EXECUTABLE : NOT_EXECUTABLE; | 2756 page->IsPageExecutable() ? EXECUTABLE : NOT_EXECUTABLE; |
2733 ObjectSpace space = kObjectSpaceLoSpace; | 2757 ObjectSpace space = kObjectSpaceLoSpace; |
2734 if (executable == EXECUTABLE) space = kObjectSpaceCodeSpace; | 2758 if (executable == EXECUTABLE) space = kObjectSpaceCodeSpace; |
2735 size_t size = chunk->size(); | 2759 size_t size = chunk->size(); |
2736 MemoryAllocator::FreeRawMemory(chunk->address(), size, executable); | 2760 MemoryAllocator::FreeRawMemory(chunk->address(), size, executable); |
2737 MemoryAllocator::PerformAllocationCallback( | 2761 MemoryAllocator::PerformAllocationCallback( |
2738 space, kAllocationActionFree, size); | 2762 space, kAllocationActionFree, size); |
2739 } | 2763 } |
2740 | 2764 |
2741 size_ = 0; | 2765 size_ = 0; |
2742 page_count_ = 0; | 2766 page_count_ = 0; |
| 2767 objects_size_ = 0; |
2743 } | 2768 } |
2744 | 2769 |
2745 | 2770 |
2746 #ifdef ENABLE_HEAP_PROTECTION | 2771 #ifdef ENABLE_HEAP_PROTECTION |
2747 | 2772 |
2748 void LargeObjectSpace::Protect() { | 2773 void LargeObjectSpace::Protect() { |
2749 LargeObjectChunk* chunk = first_chunk_; | 2774 LargeObjectChunk* chunk = first_chunk_; |
2750 while (chunk != NULL) { | 2775 while (chunk != NULL) { |
2751 MemoryAllocator::Protect(chunk->address(), chunk->size()); | 2776 MemoryAllocator::Protect(chunk->address(), chunk->size()); |
2752 chunk = chunk->next(); | 2777 chunk = chunk->next(); |
(...skipping 26 matching lines...) Expand all Loading... |
2779 } | 2804 } |
2780 | 2805 |
2781 size_t chunk_size; | 2806 size_t chunk_size; |
2782 LargeObjectChunk* chunk = | 2807 LargeObjectChunk* chunk = |
2783 LargeObjectChunk::New(requested_size, &chunk_size, executable); | 2808 LargeObjectChunk::New(requested_size, &chunk_size, executable); |
2784 if (chunk == NULL) { | 2809 if (chunk == NULL) { |
2785 return Failure::RetryAfterGC(identity()); | 2810 return Failure::RetryAfterGC(identity()); |
2786 } | 2811 } |
2787 | 2812 |
2788 size_ += static_cast<int>(chunk_size); | 2813 size_ += static_cast<int>(chunk_size); |
| 2814 objects_size_ += requested_size; |
2789 page_count_++; | 2815 page_count_++; |
2790 chunk->set_next(first_chunk_); | 2816 chunk->set_next(first_chunk_); |
2791 chunk->set_size(chunk_size); | 2817 chunk->set_size(chunk_size); |
2792 first_chunk_ = chunk; | 2818 first_chunk_ = chunk; |
2793 | 2819 |
2794 // Initialize page header. | 2820 // Initialize page header. |
2795 Page* page = Page::FromAddress(RoundUp(chunk->address(), Page::kPageSize)); | 2821 Page* page = Page::FromAddress(RoundUp(chunk->address(), Page::kPageSize)); |
2796 Address object_address = page->ObjectAreaStart(); | 2822 Address object_address = page->ObjectAreaStart(); |
2797 // Clear the low order bit of the second word in the page to flag it as a | 2823 // Clear the low order bit of the second word in the page to flag it as a |
2798 // large object page. If the chunk_size happened to be written there, its | 2824 // large object page. If the chunk_size happened to be written there, its |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2941 current = current->next(); | 2967 current = current->next(); |
2942 if (previous == NULL) { | 2968 if (previous == NULL) { |
2943 first_chunk_ = current; | 2969 first_chunk_ = current; |
2944 } else { | 2970 } else { |
2945 previous->set_next(current); | 2971 previous->set_next(current); |
2946 } | 2972 } |
2947 | 2973 |
2948 // Free the chunk. | 2974 // Free the chunk. |
2949 MarkCompactCollector::ReportDeleteIfNeeded(object); | 2975 MarkCompactCollector::ReportDeleteIfNeeded(object); |
2950 size_ -= static_cast<int>(chunk_size); | 2976 size_ -= static_cast<int>(chunk_size); |
| 2977 objects_size_ -= object->Size(); |
2951 page_count_--; | 2978 page_count_--; |
2952 ObjectSpace space = kObjectSpaceLoSpace; | 2979 ObjectSpace space = kObjectSpaceLoSpace; |
2953 if (executable == EXECUTABLE) space = kObjectSpaceCodeSpace; | 2980 if (executable == EXECUTABLE) space = kObjectSpaceCodeSpace; |
2954 MemoryAllocator::FreeRawMemory(chunk_address, chunk_size, executable); | 2981 MemoryAllocator::FreeRawMemory(chunk_address, chunk_size, executable); |
2955 MemoryAllocator::PerformAllocationCallback(space, kAllocationActionFree, | 2982 MemoryAllocator::PerformAllocationCallback(space, kAllocationActionFree, |
2956 size_); | 2983 size_); |
2957 LOG(DeleteEvent("LargeObjectChunk", chunk_address)); | 2984 LOG(DeleteEvent("LargeObjectChunk", chunk_address)); |
2958 } | 2985 } |
2959 } | 2986 } |
2960 } | 2987 } |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3045 void LargeObjectSpace::ReportStatistics() { | 3072 void LargeObjectSpace::ReportStatistics() { |
3046 PrintF(" size: %" V8_PTR_PREFIX "d\n", size_); | 3073 PrintF(" size: %" V8_PTR_PREFIX "d\n", size_); |
3047 int num_objects = 0; | 3074 int num_objects = 0; |
3048 ClearHistograms(); | 3075 ClearHistograms(); |
3049 LargeObjectIterator it(this); | 3076 LargeObjectIterator it(this); |
3050 for (HeapObject* obj = it.next(); obj != NULL; obj = it.next()) { | 3077 for (HeapObject* obj = it.next(); obj != NULL; obj = it.next()) { |
3051 num_objects++; | 3078 num_objects++; |
3052 CollectHistogramInfo(obj); | 3079 CollectHistogramInfo(obj); |
3053 } | 3080 } |
3054 | 3081 |
3055 PrintF(" number of objects %d\n", num_objects); | 3082 PrintF(" number of objects %d, " |
| 3083 "size of objects %" V8_PTR_PREFIX "d\n", num_objects, objects_size_); |
3056 if (num_objects > 0) ReportHistogram(false); | 3084 if (num_objects > 0) ReportHistogram(false); |
3057 } | 3085 } |
3058 | 3086 |
3059 | 3087 |
3060 void LargeObjectSpace::CollectCodeStatistics() { | 3088 void LargeObjectSpace::CollectCodeStatistics() { |
3061 LargeObjectIterator obj_it(this); | 3089 LargeObjectIterator obj_it(this); |
3062 for (HeapObject* obj = obj_it.next(); obj != NULL; obj = obj_it.next()) { | 3090 for (HeapObject* obj = obj_it.next(); obj != NULL; obj = obj_it.next()) { |
3063 if (obj->IsCode()) { | 3091 if (obj->IsCode()) { |
3064 Code* code = Code::cast(obj); | 3092 Code* code = Code::cast(obj); |
3065 code_kind_statistics[code->kind()] += code->Size(); | 3093 code_kind_statistics[code->kind()] += code->Size(); |
3066 } | 3094 } |
3067 } | 3095 } |
3068 } | 3096 } |
3069 #endif // DEBUG | 3097 #endif // DEBUG |
3070 | 3098 |
3071 } } // namespace v8::internal | 3099 } } // namespace v8::internal |
OLD | NEW |