| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/freelist.h" | 5 #include "vm/freelist.h" |
| 6 | 6 |
| 7 #include "vm/bit_set.h" |
| 7 #include "vm/object.h" | 8 #include "vm/object.h" |
| 8 #include "vm/raw_object.h" | 9 #include "vm/raw_object.h" |
| 9 | 10 |
| 10 namespace dart { | 11 namespace dart { |
| 11 | 12 |
| 12 | 13 |
| 13 FreeListElement* FreeListElement::AsElement(uword addr, intptr_t size) { | 14 FreeListElement* FreeListElement::AsElement(uword addr, intptr_t size) { |
| 14 ASSERT(size >= kObjectAlignment); | 15 ASSERT(size >= kObjectAlignment); |
| 15 ASSERT(Utils::IsAligned(size, kObjectAlignment)); | 16 ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
| 16 | 17 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 42 } | 43 } |
| 43 | 44 |
| 44 | 45 |
| 45 FreeList::~FreeList() { | 46 FreeList::~FreeList() { |
| 46 // Nothing to release. | 47 // Nothing to release. |
| 47 } | 48 } |
| 48 | 49 |
| 49 | 50 |
| 50 uword FreeList::TryAllocate(intptr_t size) { | 51 uword FreeList::TryAllocate(intptr_t size) { |
| 51 int index = IndexForSize(size); | 52 int index = IndexForSize(size); |
| 52 if ((index != kNumLists) && (free_lists_[index] != NULL)) { | 53 if ((index != kNumLists) && free_map_.Test(index)) { |
| 53 return reinterpret_cast<uword>(DequeueElement(index)); | 54 return reinterpret_cast<uword>(DequeueElement(index)); |
| 54 } | 55 } |
| 55 | 56 |
| 56 if (index < kNumLists) { | 57 if (index < kNumLists) { |
| 57 index++; | 58 index++; |
| 58 while (index < kNumLists) { | 59 while (index < kNumLists) { |
| 59 if (free_lists_[index] != NULL) { | 60 if (free_map_.Test(index)) { |
| 60 // Dequeue an element from the list, split and enqueue the remainder in | 61 // Dequeue an element from the list, split and enqueue the remainder in |
| 61 // the appropriate list. | 62 // the appropriate list. |
| 62 FreeListElement* element = DequeueElement(index); | 63 FreeListElement* element = DequeueElement(index); |
| 63 SplitElementAfterAndEnqueue(element, size); | 64 SplitElementAfterAndEnqueue(element, size); |
| 64 return reinterpret_cast<uword>(element); | 65 return reinterpret_cast<uword>(element); |
| 65 } | 66 } |
| 66 index++; | 67 index++; |
| 67 } | 68 } |
| 68 } | 69 } |
| 69 | 70 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 89 | 90 |
| 90 | 91 |
| 91 void FreeList::Free(uword addr, intptr_t size) { | 92 void FreeList::Free(uword addr, intptr_t size) { |
| 92 intptr_t index = IndexForSize(size); | 93 intptr_t index = IndexForSize(size); |
| 93 FreeListElement* element = FreeListElement::AsElement(addr, size); | 94 FreeListElement* element = FreeListElement::AsElement(addr, size); |
| 94 EnqueueElement(element, index); | 95 EnqueueElement(element, index); |
| 95 } | 96 } |
| 96 | 97 |
| 97 | 98 |
| 98 void FreeList::Reset() { | 99 void FreeList::Reset() { |
| 100 free_map_.Reset(); |
| 99 for (int i = 0; i < (kNumLists + 1); i++) { | 101 for (int i = 0; i < (kNumLists + 1); i++) { |
| 100 free_lists_[i] = NULL; | 102 free_lists_[i] = NULL; |
| 101 } | 103 } |
| 102 } | 104 } |
| 103 | 105 |
| 106 |
| 104 intptr_t FreeList::IndexForSize(intptr_t size) { | 107 intptr_t FreeList::IndexForSize(intptr_t size) { |
| 105 ASSERT(size >= kObjectAlignment); | 108 ASSERT(size >= kObjectAlignment); |
| 106 ASSERT(Utils::IsAligned(size, kObjectAlignment)); | 109 ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
| 107 | 110 |
| 108 intptr_t index = size / kObjectAlignment; | 111 intptr_t index = size / kObjectAlignment; |
| 109 if (index >= kNumLists) { | 112 if (index >= kNumLists) { |
| 110 index = kNumLists; | 113 index = kNumLists; |
| 111 } | 114 } |
| 112 return index; | 115 return index; |
| 113 } | 116 } |
| 114 | 117 |
| 115 | 118 |
| 116 void FreeList::EnqueueElement(FreeListElement* element, intptr_t index) { | 119 void FreeList::EnqueueElement(FreeListElement* element, intptr_t index) { |
| 117 element->set_next(free_lists_[index]); | 120 FreeListElement* next = free_lists_[index]; |
| 121 if (next == NULL) { |
| 122 free_map_.Set(index, true); |
| 123 } |
| 124 element->set_next(next); |
| 118 free_lists_[index] = element; | 125 free_lists_[index] = element; |
| 119 } | 126 } |
| 120 | 127 |
| 121 | 128 |
| 122 FreeListElement* FreeList::DequeueElement(intptr_t index) { | 129 FreeListElement* FreeList::DequeueElement(intptr_t index) { |
| 123 FreeListElement* result = free_lists_[index]; | 130 FreeListElement* result = free_lists_[index]; |
| 124 free_lists_[index] = result->next(); | 131 FreeListElement* next = result->next(); |
| 132 if (next == NULL) { |
| 133 free_map_.Set(index, false); |
| 134 } |
| 135 free_lists_[index] = next; |
| 125 return result; | 136 return result; |
| 126 } | 137 } |
| 127 | 138 |
| 128 | 139 |
| 140 intptr_t FreeList::Length(int index) const { |
| 141 ASSERT(index >= 0); |
| 142 ASSERT(index < kNumLists); |
| 143 intptr_t result = 0; |
| 144 FreeListElement* element = free_lists_[index]; |
| 145 while (element != NULL) { |
| 146 ++result; |
| 147 element = element->next(); |
| 148 } |
| 149 return result; |
| 150 } |
| 151 |
| 152 |
| 153 void FreeList::Print() const { |
| 154 OS::Print("%*s %*s %*s\n", 10, "Class", 10, "Length", 10, "Size"); |
| 155 OS::Print("--------------------------------\n"); |
| 156 int total_index = 0; |
| 157 int total_length = 0; |
| 158 int total_size = 0; |
| 159 for (int i = 0; i < kNumLists; ++i) { |
| 160 if (free_lists_[i] == NULL) { |
| 161 continue; |
| 162 } |
| 163 total_index += 1; |
| 164 intptr_t length = Length(i); |
| 165 total_length += length; |
| 166 intptr_t size = length * i * kObjectAlignment; |
| 167 total_size += size; |
| 168 OS::Print("%*d %*d %*d\n", 10, i * kObjectAlignment, 10, length, 10, size); |
| 169 } |
| 170 OS::Print("--------------------------------\n"); |
| 171 OS::Print("%*d %*d %*d\n", 10, total_index, 10, total_length, 10, total_size); |
| 172 } |
| 173 |
| 174 |
| 129 void FreeList::SplitElementAfterAndEnqueue(FreeListElement* element, | 175 void FreeList::SplitElementAfterAndEnqueue(FreeListElement* element, |
| 130 intptr_t size) { | 176 intptr_t size) { |
| 131 intptr_t remainder_size = element->Size() - size; | 177 intptr_t remainder_size = element->Size() - size; |
| 132 if (remainder_size == 0) return; | 178 if (remainder_size == 0) return; |
| 133 | 179 |
| 134 element = FreeListElement::AsElement(reinterpret_cast<uword>(element) + size, | 180 element = FreeListElement::AsElement(reinterpret_cast<uword>(element) + size, |
| 135 remainder_size); | 181 remainder_size); |
| 136 intptr_t remainder_index = IndexForSize(remainder_size); | 182 intptr_t remainder_index = IndexForSize(remainder_size); |
| 137 EnqueueElement(element, remainder_index); | 183 EnqueueElement(element, remainder_index); |
| 138 } | 184 } |
| 139 | 185 |
| 140 } // namespace dart | 186 } // namespace dart |
| OLD | NEW |