| Index: runtime/vm/freelist.cc
|
| ===================================================================
|
| --- runtime/vm/freelist.cc (revision 39806)
|
| +++ runtime/vm/freelist.cc (working copy)
|
| @@ -196,6 +196,7 @@
|
| void FreeList::Reset() {
|
| MutexLocker ml(mutex_);
|
| free_map_.Reset();
|
| + last_free_small_size_ = -1;
|
| for (int i = 0; i < (kNumLists + 1); i++) {
|
| free_lists_[i] = NULL;
|
| }
|
| @@ -206,7 +207,7 @@
|
| ASSERT(size >= kObjectAlignment);
|
| ASSERT(Utils::IsAligned(size, kObjectAlignment));
|
|
|
| - intptr_t index = size / kObjectAlignment;
|
| + intptr_t index = size >> kObjectAlignmentLog2;
|
| if (index >= kNumLists) {
|
| index = kNumLists;
|
| }
|
| @@ -218,6 +219,8 @@
|
| FreeListElement* next = free_lists_[index];
|
| if (next == NULL && index != kNumLists) {
|
| free_map_.Set(index, true);
|
| + last_free_small_size_ = Utils::Maximum(last_free_small_size_,
|
| + index << kObjectAlignmentLog2);
|
| }
|
| element->set_next(next);
|
| free_lists_[index] = element;
|
| @@ -229,6 +232,12 @@
|
| FreeListElement* next = result->next();
|
| if (next == NULL && index != kNumLists) {
|
| free_map_.Set(index, false);
|
| + intptr_t size = index << kObjectAlignmentLog2;
|
| + if (size == last_free_small_size_) {
|
| + // Note: Last() returns -1 if none are set; avoid shift of negative.
|
| + last_free_small_size_ = free_map_.Last() * kObjectAlignment;
|
| + // TODO(koda): Consider adding BitSet::Previous(i).
|
| + }
|
| }
|
| free_lists_[index] = next;
|
| return result;
|
| @@ -344,6 +353,12 @@
|
|
|
| FreeListElement* FreeList::TryAllocateLarge(intptr_t minimum_size) {
|
| MutexLocker ml(mutex_);
|
| + return TryAllocateLargeLocked(minimum_size);
|
| +}
|
| +
|
| +
|
| +FreeListElement* FreeList::TryAllocateLargeLocked(intptr_t minimum_size) {
|
| + DEBUG_ASSERT(mutex_->Owner() == Isolate::Current());
|
| FreeListElement* previous = NULL;
|
| FreeListElement* current = free_lists_[kNumLists];
|
| // TODO(koda): Find largest.
|
| @@ -363,4 +378,25 @@
|
| return NULL;
|
| }
|
|
|
| +
|
| +uword FreeList::TryAllocateSmallLocked(intptr_t size) {
|
| + DEBUG_ASSERT(mutex_->Owner() == Isolate::Current());
|
| + if (size > last_free_small_size_) {
|
| + return 0;
|
| + }
|
| + int index = IndexForSize(size);
|
| + if (index != kNumLists && free_map_.Test(index)) {
|
| + return reinterpret_cast<uword>(DequeueElement(index));
|
| + }
|
| + if ((index + 1) < kNumLists) {
|
| + intptr_t next_index = free_map_.Next(index + 1);
|
| + if (next_index != -1) {
|
| + FreeListElement* element = DequeueElement(next_index);
|
| + SplitElementAfterAndEnqueue(element, size, false);
|
| + return reinterpret_cast<uword>(element);
|
| + }
|
| + }
|
| + return 0;
|
| +}
|
| +
|
| } // namespace dart
|
|
|