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

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

Issue 2481873005: clang-format runtime/vm (Closed)
Patch Set: Merge Created 4 years, 1 month 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
« no previous file with comments | « runtime/vm/freelist.h ('k') | runtime/vm/freelist_test.cc » ('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 "vm/bit_set.h" 7 #include "vm/bit_set.h"
8 #include "vm/hash_map.h" 8 #include "vm/hash_map.h"
9 #include "vm/lockers.h" 9 #include "vm/lockers.h"
10 #include "vm/object.h" 10 #include "vm/object.h"
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 uword FreeList::TryAllocateLocked(intptr_t size, bool is_protected) { 70 uword FreeList::TryAllocateLocked(intptr_t size, bool is_protected) {
71 DEBUG_ASSERT(mutex_->IsOwnedByCurrentThread()); 71 DEBUG_ASSERT(mutex_->IsOwnedByCurrentThread());
72 // Precondition: is_protected is false or else all free list elements are 72 // Precondition: is_protected is false or else all free list elements are
73 // in non-writable pages. 73 // in non-writable pages.
74 74
75 // Postcondition: if allocation succeeds, the allocated block is writable. 75 // Postcondition: if allocation succeeds, the allocated block is writable.
76 int index = IndexForSize(size); 76 int index = IndexForSize(size);
77 if ((index != kNumLists) && free_map_.Test(index)) { 77 if ((index != kNumLists) && free_map_.Test(index)) {
78 FreeListElement* element = DequeueElement(index); 78 FreeListElement* element = DequeueElement(index);
79 if (is_protected) { 79 if (is_protected) {
80 bool status = 80 bool status = VirtualMemory::Protect(reinterpret_cast<void*>(element),
81 VirtualMemory::Protect(reinterpret_cast<void*>(element), 81 size, VirtualMemory::kReadWrite);
82 size,
83 VirtualMemory::kReadWrite);
84 ASSERT(status); 82 ASSERT(status);
85 } 83 }
86 return reinterpret_cast<uword>(element); 84 return reinterpret_cast<uword>(element);
87 } 85 }
88 86
89 if ((index + 1) < kNumLists) { 87 if ((index + 1) < kNumLists) {
90 intptr_t next_index = free_map_.Next(index + 1); 88 intptr_t next_index = free_map_.Next(index + 1);
91 if (next_index != -1) { 89 if (next_index != -1) {
92 // Dequeue an element from the list, split and enqueue the remainder in 90 // Dequeue an element from the list, split and enqueue the remainder in
93 // the appropriate list. 91 // the appropriate list.
94 FreeListElement* element = DequeueElement(next_index); 92 FreeListElement* element = DequeueElement(next_index);
95 if (is_protected) { 93 if (is_protected) {
96 // Make the allocated block and the header of the remainder element 94 // Make the allocated block and the header of the remainder element
97 // writable. The remainder will be non-writable if necessary after 95 // writable. The remainder will be non-writable if necessary after
98 // the call to SplitElementAfterAndEnqueue. 96 // the call to SplitElementAfterAndEnqueue.
99 // If the remainder size is zero, only the element itself needs to 97 // If the remainder size is zero, only the element itself needs to
100 // be made writable. 98 // be made writable.
101 intptr_t remainder_size = element->Size() - size; 99 intptr_t remainder_size = element->Size() - size;
102 intptr_t region_size = 100 intptr_t region_size =
103 size + FreeListElement::HeaderSizeFor(remainder_size); 101 size + FreeListElement::HeaderSizeFor(remainder_size);
104 bool status = 102 bool status =
105 VirtualMemory::Protect(reinterpret_cast<void*>(element), 103 VirtualMemory::Protect(reinterpret_cast<void*>(element),
106 region_size, 104 region_size, VirtualMemory::kReadWrite);
107 VirtualMemory::kReadWrite);
108 ASSERT(status); 105 ASSERT(status);
109 } 106 }
110 SplitElementAfterAndEnqueue(element, size, is_protected); 107 SplitElementAfterAndEnqueue(element, size, is_protected);
111 return reinterpret_cast<uword>(element); 108 return reinterpret_cast<uword>(element);
112 } 109 }
113 } 110 }
114 111
115 FreeListElement* previous = NULL; 112 FreeListElement* previous = NULL;
116 FreeListElement* current = free_lists_[kNumLists]; 113 FreeListElement* current = free_lists_[kNumLists];
117 while (current != NULL) { 114 while (current != NULL) {
118 if (current->Size() >= size) { 115 if (current->Size() >= size) {
119 // Found an element large enough to hold the requested size. Dequeue, 116 // Found an element large enough to hold the requested size. Dequeue,
120 // split and enqueue the remainder. 117 // split and enqueue the remainder.
121 intptr_t remainder_size = current->Size() - size; 118 intptr_t remainder_size = current->Size() - size;
122 intptr_t region_size = 119 intptr_t region_size =
123 size + FreeListElement::HeaderSizeFor(remainder_size); 120 size + FreeListElement::HeaderSizeFor(remainder_size);
124 if (is_protected) { 121 if (is_protected) {
125 // Make the allocated block and the header of the remainder element 122 // Make the allocated block and the header of the remainder element
126 // writable. The remainder will be non-writable if necessary after 123 // writable. The remainder will be non-writable if necessary after
127 // the call to SplitElementAfterAndEnqueue. 124 // the call to SplitElementAfterAndEnqueue.
128 bool status = 125 bool status =
129 VirtualMemory::Protect(reinterpret_cast<void*>(current), 126 VirtualMemory::Protect(reinterpret_cast<void*>(current),
130 region_size, 127 region_size, VirtualMemory::kReadWrite);
131 VirtualMemory::kReadWrite);
132 ASSERT(status); 128 ASSERT(status);
133 } 129 }
134 130
135 if (previous == NULL) { 131 if (previous == NULL) {
136 free_lists_[kNumLists] = current->next(); 132 free_lists_[kNumLists] = current->next();
137 } else { 133 } else {
138 // If the previous free list element's next field is protected, it 134 // If the previous free list element's next field is protected, it
139 // needs to be unprotected before storing to it and reprotected 135 // needs to be unprotected before storing to it and reprotected
140 // after. 136 // after.
141 bool target_is_protected = false; 137 bool target_is_protected = false;
142 uword target_address = 0L; 138 uword target_address = 0L;
143 if (is_protected) { 139 if (is_protected) {
144 uword writable_start = reinterpret_cast<uword>(current); 140 uword writable_start = reinterpret_cast<uword>(current);
145 uword writable_end = writable_start + region_size - 1; 141 uword writable_end = writable_start + region_size - 1;
146 target_address = previous->next_address(); 142 target_address = previous->next_address();
147 target_is_protected = 143 target_is_protected =
148 !VirtualMemory::InSamePage(target_address, writable_start) && 144 !VirtualMemory::InSamePage(target_address, writable_start) &&
149 !VirtualMemory::InSamePage(target_address, writable_end); 145 !VirtualMemory::InSamePage(target_address, writable_end);
150 } 146 }
151 if (target_is_protected) { 147 if (target_is_protected) {
152 bool status = 148 bool status =
153 VirtualMemory::Protect(reinterpret_cast<void*>(target_address), 149 VirtualMemory::Protect(reinterpret_cast<void*>(target_address),
154 kWordSize, 150 kWordSize, VirtualMemory::kReadWrite);
155 VirtualMemory::kReadWrite);
156 ASSERT(status); 151 ASSERT(status);
157 } 152 }
158 previous->set_next(current->next()); 153 previous->set_next(current->next());
159 if (target_is_protected) { 154 if (target_is_protected) {
160 bool status = 155 bool status =
161 VirtualMemory::Protect(reinterpret_cast<void*>(target_address), 156 VirtualMemory::Protect(reinterpret_cast<void*>(target_address),
162 kWordSize, 157 kWordSize, VirtualMemory::kReadExecute);
163 VirtualMemory::kReadExecute);
164 ASSERT(status); 158 ASSERT(status);
165 } 159 }
166 } 160 }
167 SplitElementAfterAndEnqueue(current, size, is_protected); 161 SplitElementAfterAndEnqueue(current, size, is_protected);
168 return reinterpret_cast<uword>(current); 162 return reinterpret_cast<uword>(current);
169 } 163 }
170 previous = current; 164 previous = current;
171 current = current->next(); 165 current = current->next();
172 } 166 }
173 return 0; 167 return 0;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 index = kNumLists; 207 index = kNumLists;
214 } 208 }
215 return index; 209 return index;
216 } 210 }
217 211
218 212
219 void FreeList::EnqueueElement(FreeListElement* element, intptr_t index) { 213 void FreeList::EnqueueElement(FreeListElement* element, intptr_t index) {
220 FreeListElement* next = free_lists_[index]; 214 FreeListElement* next = free_lists_[index];
221 if (next == NULL && index != kNumLists) { 215 if (next == NULL && index != kNumLists) {
222 free_map_.Set(index, true); 216 free_map_.Set(index, true);
223 last_free_small_size_ = Utils::Maximum(last_free_small_size_, 217 last_free_small_size_ =
224 index << kObjectAlignmentLog2); 218 Utils::Maximum(last_free_small_size_, index << kObjectAlignmentLog2);
225 } 219 }
226 element->set_next(next); 220 element->set_next(next);
227 free_lists_[index] = element; 221 free_lists_[index] = element;
228 } 222 }
229 223
230 224
231 FreeListElement* FreeList::DequeueElement(intptr_t index) { 225 FreeListElement* FreeList::DequeueElement(intptr_t index) {
232 FreeListElement* result = free_lists_[index]; 226 FreeListElement* result = free_lists_[index];
233 FreeListElement* next = result->next(); 227 FreeListElement* next = result->next();
234 if (next == NULL && index != kNumLists) { 228 if (next == NULL && index != kNumLists) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 intptr_t small_bytes = 0; 260 intptr_t small_bytes = 0;
267 for (int i = 0; i < kNumLists; ++i) { 261 for (int i = 0; i < kNumLists; ++i) {
268 if (free_lists_[i] == NULL) { 262 if (free_lists_[i] == NULL) {
269 continue; 263 continue;
270 } 264 }
271 small_sizes += 1; 265 small_sizes += 1;
272 intptr_t list_length = LengthLocked(i); 266 intptr_t list_length = LengthLocked(i);
273 small_objects += list_length; 267 small_objects += list_length;
274 intptr_t list_bytes = list_length * i * kObjectAlignment; 268 intptr_t list_bytes = list_length * i * kObjectAlignment;
275 small_bytes += list_bytes; 269 small_bytes += list_bytes;
276 OS::Print("small %3d [%8d bytes] : " 270 OS::Print(
277 "%8" Pd " objs; %8.1f KB; %8.1f cum KB\n", 271 "small %3d [%8d bytes] : "
278 i, 272 "%8" Pd " objs; %8.1f KB; %8.1f cum KB\n",
279 i * kObjectAlignment, 273 i, i * kObjectAlignment, list_length,
280 list_length, 274 list_bytes / static_cast<double>(KB),
281 list_bytes / static_cast<double>(KB), 275 small_bytes / static_cast<double>(KB));
282 small_bytes / static_cast<double>(KB));
283 } 276 }
284 } 277 }
285 278
286 279
287 class IntptrPair { 280 class IntptrPair {
288 public: 281 public:
289 IntptrPair() : first_(-1), second_(-1) {} 282 IntptrPair() : first_(-1), second_(-1) {}
290 IntptrPair(intptr_t first, intptr_t second) 283 IntptrPair(intptr_t first, intptr_t second)
291 : first_(first), second_(second) {} 284 : first_(first), second_(second) {}
292 285
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 } 319 }
327 320
328 MallocDirectChainedHashMap<NumbersKeyValueTrait<IntptrPair> >::Iterator it = 321 MallocDirectChainedHashMap<NumbersKeyValueTrait<IntptrPair> >::Iterator it =
329 map.GetIterator(); 322 map.GetIterator();
330 IntptrPair* pair; 323 IntptrPair* pair;
331 while ((pair = it.Next()) != NULL) { 324 while ((pair = it.Next()) != NULL) {
332 intptr_t size = pair->first(); 325 intptr_t size = pair->first();
333 intptr_t list_length = pair->second(); 326 intptr_t list_length = pair->second();
334 intptr_t list_bytes = list_length * size; 327 intptr_t list_bytes = list_length * size;
335 large_bytes += list_bytes; 328 large_bytes += list_bytes;
336 OS::Print("large %3" Pd " [%8" Pd " bytes] : " 329 OS::Print("large %3" Pd " [%8" Pd
330 " bytes] : "
337 "%8" Pd " objs; %8.1f KB; %8.1f cum KB\n", 331 "%8" Pd " objs; %8.1f KB; %8.1f cum KB\n",
338 size / kObjectAlignment, 332 size / kObjectAlignment, size, list_length,
339 size,
340 list_length,
341 list_bytes / static_cast<double>(KB), 333 list_bytes / static_cast<double>(KB),
342 large_bytes / static_cast<double>(KB)); 334 large_bytes / static_cast<double>(KB));
343 } 335 }
344 } 336 }
345 337
346 338
347 void FreeList::Print() const { 339 void FreeList::Print() const {
348 MutexLocker ml(mutex_); 340 MutexLocker ml(mutex_);
349 PrintSmall(); 341 PrintSmall();
350 PrintLarge(); 342 PrintLarge();
(...skipping 15 matching lines...) Expand all
366 EnqueueElement(element, remainder_index); 358 EnqueueElement(element, remainder_index);
367 359
368 // Postcondition: when allocating in a protected page, the remainder 360 // Postcondition: when allocating in a protected page, the remainder
369 // element is no longer writable unless it is in the same page as the 361 // element is no longer writable unless it is in the same page as the
370 // allocated element. (The allocated element is still writable, and the 362 // allocated element. (The allocated element is still writable, and the
371 // remainder element will be protected when the allocated one is). 363 // remainder element will be protected when the allocated one is).
372 if (is_protected && 364 if (is_protected &&
373 !VirtualMemory::InSamePage(remainder_address - 1, remainder_address)) { 365 !VirtualMemory::InSamePage(remainder_address - 1, remainder_address)) {
374 bool status = 366 bool status =
375 VirtualMemory::Protect(reinterpret_cast<void*>(remainder_address), 367 VirtualMemory::Protect(reinterpret_cast<void*>(remainder_address),
376 remainder_size, 368 remainder_size, VirtualMemory::kReadExecute);
377 VirtualMemory::kReadExecute);
378 ASSERT(status); 369 ASSERT(status);
379 } 370 }
380 } 371 }
381 372
382 373
383 FreeListElement* FreeList::TryAllocateLarge(intptr_t minimum_size) { 374 FreeListElement* FreeList::TryAllocateLarge(intptr_t minimum_size) {
384 MutexLocker ml(mutex_); 375 MutexLocker ml(mutex_);
385 return TryAllocateLargeLocked(minimum_size); 376 return TryAllocateLargeLocked(minimum_size);
386 } 377 }
387 378
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 if (next_index != -1) { 413 if (next_index != -1) {
423 FreeListElement* element = DequeueElement(next_index); 414 FreeListElement* element = DequeueElement(next_index);
424 SplitElementAfterAndEnqueue(element, size, false); 415 SplitElementAfterAndEnqueue(element, size, false);
425 return reinterpret_cast<uword>(element); 416 return reinterpret_cast<uword>(element);
426 } 417 }
427 } 418 }
428 return 0; 419 return 0;
429 } 420 }
430 421
431 } // namespace dart 422 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/freelist.h ('k') | runtime/vm/freelist_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698