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

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

Issue 10450014: Request for comments on overall approach. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fix scavenger and freelist handling Created 8 years, 7 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 "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 {
11 11
12 // Allocate a fake class to be used as the class for elements of the free list. 12 // Allocate a fake class to be used as the class for elements of the free list.
13 // These raw classes are only used to identify free list elements in the heap. 13 // These raw classes are only used to identify free list elements in the heap.
14 // These classes cannot be allocated in the heap as the elements of the free 14 // These classes cannot be allocated in the heap as the elements of the free
15 // list are not live objects and their class references would not be updated 15 // list are not live objects and their class references would not be updated
16 // during a moving collection. In the general case these classes are also used 16 // during a moving collection. In the general case these classes are also used
17 // to implement RawObject::Size() to allow other code to safely traverse 17 // to implement RawObject::Size() to allow other code to safely traverse
18 // the heap without any knowledge of the embedded free list elements. 18 // the heap without any knowledge of the embedded free list elements.
19 RawClass* AllocateFakeClass() { 19 RawClass* AllocateFakeClass() {
20 RawClass* result = 20 RawClass* result =
21 reinterpret_cast<RawClass*>(calloc(1, Class::InstanceSize())); 21 reinterpret_cast<RawClass*>(calloc(1, Class::InstanceSize()));
22 result->instance_kind_ = kFreeListElement; 22 result->instance_kind_ = kFreeListElement;
23 return reinterpret_cast<RawClass*>(RawObject::FromAddr( 23 return reinterpret_cast<RawClass*>(RawObject::FromAddr(
24 reinterpret_cast<uword>(result))); 24 reinterpret_cast<uword>(result)));
25 } 25 }
26 26
27 27
28 RawClass* FreeListElement::minimal_element_class_ = NULL; 28 RawClass* FreeListElement::freelist_class_ = NULL;
29 RawClass* FreeListElement::element_class_ = NULL;
30
31 29
32 FreeListElement* FreeListElement::AsElement(uword addr, intptr_t size) { 30 FreeListElement* FreeListElement::AsElement(uword addr, intptr_t size) {
33 ASSERT(size >= kObjectAlignment); 31 ASSERT(size >= kObjectAlignment);
34 ASSERT(Utils::IsAligned(size, kObjectAlignment)); 32 ASSERT(Utils::IsAligned(size, kObjectAlignment));
35 33
36 FreeListElement* result = reinterpret_cast<FreeListElement*>(addr); 34 FreeListElement* result = reinterpret_cast<FreeListElement*>(addr);
37 if (size == kObjectAlignment) {
38 result->class_ = minimal_element_class_;
39 } else {
40 result->class_ = element_class_;
41 *result->SizeAddress() = size;
42 }
43 result->set_next(NULL); 35 result->set_next(NULL);
44 ASSERT(result->Size() == size); 36 result->set_size(size);
45 return result; 37 return result;
46 } 38 }
47 39
48 40
49 void FreeListElement::InitOnce() { 41 void FreeListElement::InitOnce() {
50 ASSERT(sizeof(FreeListElement) == kObjectAlignment); 42 ASSERT(sizeof(FreeListElement) == kObjectAlignment);
51 ASSERT(minimal_element_class_ == NULL); 43 ASSERT(OFFSET_OF(FreeListElement, next_) == Object::tags_offset());
52 ASSERT(element_class_ == NULL); 44 freelist_class_ = AllocateFakeClass();
53 minimal_element_class_ = AllocateFakeClass();
54 element_class_ = AllocateFakeClass();
55 } 45 }
56 46
57 47
58 FreeList::FreeList() { 48 FreeList::FreeList() {
59 Reset(); 49 Reset();
60 } 50 }
61 51
62 52
63 FreeList::~FreeList() { 53 FreeList::~FreeList() {
64 // Nothing to release. 54 // Nothing to release.
(...skipping 16 matching lines...) Expand all
81 SplitElementAfterAndEnqueue(element, size); 71 SplitElementAfterAndEnqueue(element, size);
82 return reinterpret_cast<uword>(element); 72 return reinterpret_cast<uword>(element);
83 } 73 }
84 index++; 74 index++;
85 } 75 }
86 } 76 }
87 77
88 FreeListElement* previous = NULL; 78 FreeListElement* previous = NULL;
89 FreeListElement* current = free_lists_[kNumLists]; 79 FreeListElement* current = free_lists_[kNumLists];
90 while (current != NULL) { 80 while (current != NULL) {
91 if (current->Size() >= size) { 81 if (current->size() >= size) {
92 // Found an element large enough to hold the requested size. Dequeue, 82 // Found an element large enough to hold the requested size. Dequeue,
93 // split and enqueue the remainder. 83 // split and enqueue the remainder.
94 if (previous == NULL) { 84 if (previous == NULL) {
95 free_lists_[kNumLists] = current->next(); 85 free_lists_[kNumLists] = current->next();
96 } else { 86 } else {
97 previous->set_next(current->next()); 87 previous->set_next(current->next());
98 } 88 }
99 SplitElementAfterAndEnqueue(current, size); 89 SplitElementAfterAndEnqueue(current, size);
100 return reinterpret_cast<uword>(current); 90 return reinterpret_cast<uword>(current);
101 } 91 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 129
140 FreeListElement* FreeList::DequeueElement(intptr_t index) { 130 FreeListElement* FreeList::DequeueElement(intptr_t index) {
141 FreeListElement* result = free_lists_[index]; 131 FreeListElement* result = free_lists_[index];
142 free_lists_[index] = result->next(); 132 free_lists_[index] = result->next();
143 return result; 133 return result;
144 } 134 }
145 135
146 136
147 void FreeList::SplitElementAfterAndEnqueue(FreeListElement* element, 137 void FreeList::SplitElementAfterAndEnqueue(FreeListElement* element,
148 intptr_t size) { 138 intptr_t size) {
149 intptr_t remainder_size = element->Size() - size; 139 intptr_t remainder_size = element->size() - size;
150 if (remainder_size == 0) return; 140 if (remainder_size == 0) return;
151 141
152 element = FreeListElement::AsElement(reinterpret_cast<uword>(element) + size, 142 element = FreeListElement::AsElement(reinterpret_cast<uword>(element) + size,
153 remainder_size); 143 remainder_size);
154 intptr_t remainder_index = IndexForSize(remainder_size); 144 intptr_t remainder_index = IndexForSize(remainder_size);
155 EnqueueElement(element, remainder_index); 145 EnqueueElement(element, remainder_index);
156 } 146 }
157 147
158 } // namespace dart 148 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698