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

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

Issue 474913004: - Account for number of pending tasks in old-space collections. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 4 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
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 #include <utility>
9 8
10 #include "vm/bit_set.h" 9 #include "vm/bit_set.h"
10 #include "vm/lockers.h"
11 #include "vm/object.h" 11 #include "vm/object.h"
12 #include "vm/raw_object.h" 12 #include "vm/raw_object.h"
13 #include "vm/thread.h"
13 14
14 namespace dart { 15 namespace dart {
15 16
16 17
17 FreeListElement* FreeListElement::AsElement(uword addr, intptr_t size) { 18 FreeListElement* FreeListElement::AsElement(uword addr, intptr_t size) {
18 // Precondition: the (page containing the) header of the element is 19 // Precondition: the (page containing the) header of the element is
19 // writable. 20 // writable.
20 ASSERT(size >= kObjectAlignment); 21 ASSERT(size >= kObjectAlignment);
21 ASSERT(Utils::IsAligned(size, kObjectAlignment)); 22 ASSERT(Utils::IsAligned(size, kObjectAlignment));
22 23
(...skipping 19 matching lines...) Expand all
42 ASSERT(OFFSET_OF(FreeListElement, tags_) == Object::tags_offset()); 43 ASSERT(OFFSET_OF(FreeListElement, tags_) == Object::tags_offset());
43 } 44 }
44 45
45 46
46 intptr_t FreeListElement::HeaderSizeFor(intptr_t size) { 47 intptr_t FreeListElement::HeaderSizeFor(intptr_t size) {
47 if (size == 0) return 0; 48 if (size == 0) return 0;
48 return ((size > RawObject::SizeTag::kMaxSizeTag) ? 3 : 2) * kWordSize; 49 return ((size > RawObject::SizeTag::kMaxSizeTag) ? 3 : 2) * kWordSize;
49 } 50 }
50 51
51 52
52 FreeList::FreeList() { 53 FreeList::FreeList() : mutex_(new Mutex()) {
53 Reset(); 54 Reset();
54 } 55 }
55 56
56 57
57 FreeList::~FreeList() { 58 FreeList::~FreeList() {
58 // Nothing to release. 59 delete mutex_;
59 } 60 }
60 61
61 62
62 uword FreeList::TryAllocate(intptr_t size, bool is_protected) { 63 uword FreeList::TryAllocate(intptr_t size, bool is_protected) {
64 MutexLocker ml(mutex_);
65 return TryAllocateLocked(size, is_protected);
66 }
67
68
69 uword FreeList::TryAllocateLocked(intptr_t size, bool is_protected) {
70 DEBUG_ASSERT(mutex_->Owner() == Isolate::Current());
63 // Precondition: is_protected is false or else all free list elements are 71 // Precondition: is_protected is false or else all free list elements are
64 // in non-writable pages. 72 // in non-writable pages.
65 73
66 // Postcondition: if allocation succeeds, the allocated block is writable. 74 // Postcondition: if allocation succeeds, the allocated block is writable.
67 int index = IndexForSize(size); 75 int index = IndexForSize(size);
68 if ((index != kNumLists) && free_map_.Test(index)) { 76 if ((index != kNumLists) && free_map_.Test(index)) {
69 FreeListElement* element = DequeueElement(index); 77 FreeListElement* element = DequeueElement(index);
70 if (is_protected) { 78 if (is_protected) {
71 bool status = 79 bool status =
72 VirtualMemory::Protect(reinterpret_cast<void*>(element), 80 VirtualMemory::Protect(reinterpret_cast<void*>(element),
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 return reinterpret_cast<uword>(current); 167 return reinterpret_cast<uword>(current);
160 } 168 }
161 previous = current; 169 previous = current;
162 current = current->next(); 170 current = current->next();
163 } 171 }
164 return 0; 172 return 0;
165 } 173 }
166 174
167 175
168 void FreeList::Free(uword addr, intptr_t size) { 176 void FreeList::Free(uword addr, intptr_t size) {
177 MutexLocker ml(mutex_);
178 FreeLocked(addr, size);
179 }
180
181
182 void FreeList::FreeLocked(uword addr, intptr_t size) {
koda 2014/08/20 00:10:21 Assert that it's actually locked.
Ivan Posva 2014/08/20 03:50:53 Done.
169 // Precondition required by AsElement and EnqueueElement: the (page 183 // Precondition required by AsElement and EnqueueElement: the (page
170 // containing the) header of the freed block should be writable. This is 184 // containing the) header of the freed block should be writable. This is
171 // the case when called for newly allocated pages because they are 185 // the case when called for newly allocated pages because they are
172 // allocated as writable. It is the case when called during GC sweeping 186 // allocated as writable. It is the case when called during GC sweeping
173 // because the entire heap is writable. 187 // because the entire heap is writable.
174 intptr_t index = IndexForSize(size); 188 intptr_t index = IndexForSize(size);
175 FreeListElement* element = FreeListElement::AsElement(addr, size); 189 FreeListElement* element = FreeListElement::AsElement(addr, size);
176 EnqueueElement(element, index); 190 EnqueueElement(element, index);
177 // Postcondition: the (page containing the) header is left writable. 191 // Postcondition: the (page containing the) header is left writable.
178 } 192 }
179 193
180 194
181 void FreeList::Reset() { 195 void FreeList::Reset() {
196 MutexLocker ml(mutex_);
182 free_map_.Reset(); 197 free_map_.Reset();
183 for (int i = 0; i < (kNumLists + 1); i++) { 198 for (int i = 0; i < (kNumLists + 1); i++) {
184 free_lists_[i] = NULL; 199 free_lists_[i] = NULL;
185 } 200 }
186 } 201 }
187 202
188 203
189 intptr_t FreeList::IndexForSize(intptr_t size) { 204 intptr_t FreeList::IndexForSize(intptr_t size) {
190 ASSERT(size >= kObjectAlignment); 205 ASSERT(size >= kObjectAlignment);
191 ASSERT(Utils::IsAligned(size, kObjectAlignment)); 206 ASSERT(Utils::IsAligned(size, kObjectAlignment));
(...skipping 21 matching lines...) Expand all
213 FreeListElement* next = result->next(); 228 FreeListElement* next = result->next();
214 if (next == NULL && index != kNumLists) { 229 if (next == NULL && index != kNumLists) {
215 free_map_.Set(index, false); 230 free_map_.Set(index, false);
216 } 231 }
217 free_lists_[index] = next; 232 free_lists_[index] = next;
218 return result; 233 return result;
219 } 234 }
220 235
221 236
222 intptr_t FreeList::Length(int index) const { 237 intptr_t FreeList::Length(int index) const {
238 MutexLocker ml(mutex_);
223 ASSERT(index >= 0); 239 ASSERT(index >= 0);
224 ASSERT(index < kNumLists); 240 ASSERT(index < kNumLists);
225 intptr_t result = 0; 241 intptr_t result = 0;
226 FreeListElement* element = free_lists_[index]; 242 FreeListElement* element = free_lists_[index];
227 while (element != NULL) { 243 while (element != NULL) {
228 ++result; 244 ++result;
229 element = element->next(); 245 element = element->next();
230 } 246 }
231 return result; 247 return result;
232 } 248 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 size / kObjectAlignment, 299 size / kObjectAlignment,
284 size, 300 size,
285 list_length, 301 list_length,
286 list_bytes / static_cast<double>(KB), 302 list_bytes / static_cast<double>(KB),
287 large_bytes / static_cast<double>(KB)); 303 large_bytes / static_cast<double>(KB));
288 } 304 }
289 } 305 }
290 306
291 307
292 void FreeList::Print() const { 308 void FreeList::Print() const {
309 MutexLocker ml(mutex_);
293 PrintSmall(); 310 PrintSmall();
294 PrintLarge(); 311 PrintLarge();
295 } 312 }
296 313
297 314
298 void FreeList::SplitElementAfterAndEnqueue(FreeListElement* element, 315 void FreeList::SplitElementAfterAndEnqueue(FreeListElement* element,
299 intptr_t size, 316 intptr_t size,
300 bool is_protected) { 317 bool is_protected) {
301 // Precondition required by AsElement and EnqueueElement: either 318 // Precondition required by AsElement and EnqueueElement: either
302 // element->Size() == size, or else the (page containing the) header of 319 // element->Size() == size, or else the (page containing the) header of
(...skipping 14 matching lines...) Expand all
317 !VirtualMemory::InSamePage(remainder_address - 1, remainder_address)) { 334 !VirtualMemory::InSamePage(remainder_address - 1, remainder_address)) {
318 bool status = 335 bool status =
319 VirtualMemory::Protect(reinterpret_cast<void*>(remainder_address), 336 VirtualMemory::Protect(reinterpret_cast<void*>(remainder_address),
320 remainder_size, 337 remainder_size,
321 VirtualMemory::kReadExecute); 338 VirtualMemory::kReadExecute);
322 ASSERT(status); 339 ASSERT(status);
323 } 340 }
324 } 341 }
325 342
326 } // namespace dart 343 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/freelist.h ('k') | runtime/vm/heap.h » ('j') | runtime/vm/pages.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698