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