| 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_map_[index]) { | 52 if ((index != kNumLists) && (free_lists_[index] != NULL)) { |
| 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_map_[index]) { | 59 if (free_lists_[index] != NULL) { |
| 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(); | |
| 100 for (int i = 0; i < (kNumLists + 1); i++) { | 99 for (int i = 0; i < (kNumLists + 1); i++) { |
| 101 free_lists_[i] = NULL; | 100 free_lists_[i] = NULL; |
| 102 } | 101 } |
| 103 } | 102 } |
| 104 | 103 |
| 105 | |
| 106 intptr_t FreeList::IndexForSize(intptr_t size) { | 104 intptr_t FreeList::IndexForSize(intptr_t size) { |
| 107 ASSERT(size >= kObjectAlignment); | 105 ASSERT(size >= kObjectAlignment); |
| 108 ASSERT(Utils::IsAligned(size, kObjectAlignment)); | 106 ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
| 109 | 107 |
| 110 intptr_t index = size / kObjectAlignment; | 108 intptr_t index = size / kObjectAlignment; |
| 111 if (index >= kNumLists) { | 109 if (index >= kNumLists) { |
| 112 index = kNumLists; | 110 index = kNumLists; |
| 113 } | 111 } |
| 114 return index; | 112 return index; |
| 115 } | 113 } |
| 116 | 114 |
| 117 | 115 |
| 118 void FreeList::EnqueueElement(FreeListElement* element, intptr_t index) { | 116 void FreeList::EnqueueElement(FreeListElement* element, intptr_t index) { |
| 119 FreeListElement* next = free_lists_[index]; | 117 element->set_next(free_lists_[index]); |
| 120 if (next == NULL) { | |
| 121 free_map_[index] = true; | |
| 122 } | |
| 123 element->set_next(next); | |
| 124 free_lists_[index] = element; | 118 free_lists_[index] = element; |
| 125 } | 119 } |
| 126 | 120 |
| 127 | 121 |
| 128 FreeListElement* FreeList::DequeueElement(intptr_t index) { | 122 FreeListElement* FreeList::DequeueElement(intptr_t index) { |
| 129 FreeListElement* result = free_lists_[index]; | 123 FreeListElement* result = free_lists_[index]; |
| 130 FreeListElement* next = result->next(); | 124 free_lists_[index] = result->next(); |
| 131 if (next == NULL) { | |
| 132 free_map_[index] = false; | |
| 133 } | |
| 134 free_lists_[index] = next; | |
| 135 return result; | 125 return result; |
| 136 } | 126 } |
| 137 | 127 |
| 138 | 128 |
| 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 | |
| 174 void FreeList::SplitElementAfterAndEnqueue(FreeListElement* element, | 129 void FreeList::SplitElementAfterAndEnqueue(FreeListElement* element, |
| 175 intptr_t size) { | 130 intptr_t size) { |
| 176 intptr_t remainder_size = element->Size() - size; | 131 intptr_t remainder_size = element->Size() - size; |
| 177 if (remainder_size == 0) return; | 132 if (remainder_size == 0) return; |
| 178 | 133 |
| 179 element = FreeListElement::AsElement(reinterpret_cast<uword>(element) + size, | 134 element = FreeListElement::AsElement(reinterpret_cast<uword>(element) + size, |
| 180 remainder_size); | 135 remainder_size); |
| 181 intptr_t remainder_index = IndexForSize(remainder_size); | 136 intptr_t remainder_index = IndexForSize(remainder_size); |
| 182 EnqueueElement(element, remainder_index); | 137 EnqueueElement(element, remainder_index); |
| 183 } | 138 } |
| 184 | 139 |
| 185 } // namespace dart | 140 } // namespace dart |
| OLD | NEW |