Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(292)

Side by Side Diff: runtime/vm/freelist.cc

Issue 534653002: Bump allocation for promotion (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/freelist.h ('k') | runtime/vm/pages.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <map> 7 #include <map>
8 8
9 #include "vm/bit_set.h" 9 #include "vm/bit_set.h"
10 #include "vm/lockers.h" 10 #include "vm/lockers.h"
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 intptr_t index = IndexForSize(size); 189 intptr_t index = IndexForSize(size);
190 FreeListElement* element = FreeListElement::AsElement(addr, size); 190 FreeListElement* element = FreeListElement::AsElement(addr, size);
191 EnqueueElement(element, index); 191 EnqueueElement(element, index);
192 // Postcondition: the (page containing the) header is left writable. 192 // Postcondition: the (page containing the) header is left writable.
193 } 193 }
194 194
195 195
196 void FreeList::Reset() { 196 void FreeList::Reset() {
197 MutexLocker ml(mutex_); 197 MutexLocker ml(mutex_);
198 free_map_.Reset(); 198 free_map_.Reset();
199 last_free_small_size_ = -1;
199 for (int i = 0; i < (kNumLists + 1); i++) { 200 for (int i = 0; i < (kNumLists + 1); i++) {
200 free_lists_[i] = NULL; 201 free_lists_[i] = NULL;
201 } 202 }
202 } 203 }
203 204
204 205
205 intptr_t FreeList::IndexForSize(intptr_t size) { 206 intptr_t FreeList::IndexForSize(intptr_t size) {
206 ASSERT(size >= kObjectAlignment); 207 ASSERT(size >= kObjectAlignment);
207 ASSERT(Utils::IsAligned(size, kObjectAlignment)); 208 ASSERT(Utils::IsAligned(size, kObjectAlignment));
208 209
209 intptr_t index = size / kObjectAlignment; 210 intptr_t index = size >> kObjectAlignmentLog2;
210 if (index >= kNumLists) { 211 if (index >= kNumLists) {
211 index = kNumLists; 212 index = kNumLists;
212 } 213 }
213 return index; 214 return index;
214 } 215 }
215 216
216 217
217 void FreeList::EnqueueElement(FreeListElement* element, intptr_t index) { 218 void FreeList::EnqueueElement(FreeListElement* element, intptr_t index) {
218 FreeListElement* next = free_lists_[index]; 219 FreeListElement* next = free_lists_[index];
219 if (next == NULL && index != kNumLists) { 220 if (next == NULL && index != kNumLists) {
220 free_map_.Set(index, true); 221 free_map_.Set(index, true);
222 last_free_small_size_ = Utils::Maximum(last_free_small_size_,
223 index << kObjectAlignmentLog2);
221 } 224 }
222 element->set_next(next); 225 element->set_next(next);
223 free_lists_[index] = element; 226 free_lists_[index] = element;
224 } 227 }
225 228
226 229
227 FreeListElement* FreeList::DequeueElement(intptr_t index) { 230 FreeListElement* FreeList::DequeueElement(intptr_t index) {
228 FreeListElement* result = free_lists_[index]; 231 FreeListElement* result = free_lists_[index];
229 FreeListElement* next = result->next(); 232 FreeListElement* next = result->next();
230 if (next == NULL && index != kNumLists) { 233 if (next == NULL && index != kNumLists) {
231 free_map_.Set(index, false); 234 free_map_.Set(index, false);
235 intptr_t size = index << kObjectAlignmentLog2;
236 if (size == last_free_small_size_) {
237 // Note: Last() returns -1 if none are set; avoid shift of negative.
238 last_free_small_size_ = free_map_.Last() * kObjectAlignment;
239 // TODO(koda): Consider adding BitSet::Previous(i).
240 }
232 } 241 }
233 free_lists_[index] = next; 242 free_lists_[index] = next;
234 return result; 243 return result;
235 } 244 }
236 245
237 246
238 intptr_t FreeList::LengthLocked(int index) const { 247 intptr_t FreeList::LengthLocked(int index) const {
239 DEBUG_ASSERT(mutex_->Owner() == Isolate::Current()); 248 DEBUG_ASSERT(mutex_->Owner() == Isolate::Current());
240 ASSERT(index >= 0); 249 ASSERT(index >= 0);
241 ASSERT(index < kNumLists); 250 ASSERT(index < kNumLists);
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 VirtualMemory::Protect(reinterpret_cast<void*>(remainder_address), 346 VirtualMemory::Protect(reinterpret_cast<void*>(remainder_address),
338 remainder_size, 347 remainder_size,
339 VirtualMemory::kReadExecute); 348 VirtualMemory::kReadExecute);
340 ASSERT(status); 349 ASSERT(status);
341 } 350 }
342 } 351 }
343 352
344 353
345 FreeListElement* FreeList::TryAllocateLarge(intptr_t minimum_size) { 354 FreeListElement* FreeList::TryAllocateLarge(intptr_t minimum_size) {
346 MutexLocker ml(mutex_); 355 MutexLocker ml(mutex_);
356 return TryAllocateLargeLocked(minimum_size);
357 }
358
359
360 FreeListElement* FreeList::TryAllocateLargeLocked(intptr_t minimum_size) {
361 DEBUG_ASSERT(mutex_->Owner() == Isolate::Current());
347 FreeListElement* previous = NULL; 362 FreeListElement* previous = NULL;
348 FreeListElement* current = free_lists_[kNumLists]; 363 FreeListElement* current = free_lists_[kNumLists];
349 // TODO(koda): Find largest. 364 // TODO(koda): Find largest.
350 while (current != NULL) { 365 while (current != NULL) {
351 FreeListElement* next = current->next(); 366 FreeListElement* next = current->next();
352 if (current->Size() >= minimum_size) { 367 if (current->Size() >= minimum_size) {
353 if (previous == NULL) { 368 if (previous == NULL) {
354 free_lists_[kNumLists] = next; 369 free_lists_[kNumLists] = next;
355 } else { 370 } else {
356 previous->set_next(next); 371 previous->set_next(next);
357 } 372 }
358 return current; 373 return current;
359 } 374 }
360 previous = current; 375 previous = current;
361 current = next; 376 current = next;
362 } 377 }
363 return NULL; 378 return NULL;
364 } 379 }
365 380
381
382 uword FreeList::TryAllocateSmallLocked(intptr_t size) {
383 DEBUG_ASSERT(mutex_->Owner() == Isolate::Current());
384 if (size > last_free_small_size_) {
385 return 0;
386 }
387 int index = IndexForSize(size);
388 if (index != kNumLists && free_map_.Test(index)) {
389 return reinterpret_cast<uword>(DequeueElement(index));
390 }
391 if ((index + 1) < kNumLists) {
392 intptr_t next_index = free_map_.Next(index + 1);
393 if (next_index != -1) {
394 FreeListElement* element = DequeueElement(next_index);
395 SplitElementAfterAndEnqueue(element, size, false);
396 return reinterpret_cast<uword>(element);
397 }
398 }
399 return 0;
400 }
401
366 } // namespace dart 402 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/freelist.h ('k') | runtime/vm/pages.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698