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

Side by Side Diff: vm/freelist.cc

Issue 8787012: - Add free list to be used for sweep phase of mark-sweep collector. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: '' Created 9 years 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
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 #include "vm/freelist.h"
6
7 #include "vm/object.h"
8 #include "vm/raw_object.h"
9
10 namespace dart {
11
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.
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
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
18 // the heap without any knowledge of the embedded free list elements.
19 RawClass* AllocateFakeClass() {
20 RawClass* result =
21 reinterpret_cast<RawClass*>(calloc(1, Class::InstanceSize()));
antonm 2011/12/15 10:00:25 maybe should check the alignment of allocated data
Ivan Posva 2011/12/16 23:22:14 If calloc does not allocate on word boundaries I t
Anton Muhin 2011/12/19 15:31:27 I am more concerned with the case when objects may
22 result->instance_kind_ = kFreeListElement;
23 return reinterpret_cast<RawClass*>(RawObject::FromAddr(
24 reinterpret_cast<uword>(result)));
25 }
26
27
28 RawClass* FreeListElement::minimal_element_class_ = NULL;
29 RawClass* FreeListElement::element_class_ = NULL;
30
31
32 FreeListElement* FreeListElement::AsElement(uword addr, intptr_t size) {
33 ASSERT(size >= kObjectAlignment);
34 ASSERT(Utils::IsAligned(size, kObjectAlignment));
35
36 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);
44 ASSERT(result->Size() == size);
45 return result;
46 }
47
48
49 void FreeListElement::InitOnce() {
50 ASSERT(sizeof(FreeListElement) == kObjectAlignment);
51 ASSERT(minimal_element_class_ == NULL);
52 ASSERT(element_class_ == NULL);
53 minimal_element_class_ = AllocateFakeClass();
54 element_class_ = AllocateFakeClass();
55 }
56
57
58 FreeList::FreeList() {
59 Reset();
60 }
61
62
63 FreeList::~FreeList() {
64 // Nothing to release.
65 }
66
67
68 uword FreeList::TryAllocate(intptr_t size) {
69 int index = IndexForSize(size);
70 if ((index != kNumLists) && (free_lists_[index] != NULL)) {
71 return reinterpret_cast<uword>(DequeueElement(index));
72 }
73
74 if (index < kNumLists) {
75 index++;
76 while (index < kNumLists) {
77 if (free_lists_[index] != NULL) {
78 // Dequeue an element from the list, split and enqueue the remainder in
79 // the appropriate list.
80 FreeListElement* element = DequeueElement(index);
81 SplitElementAfterAndEnqueue(element, size);
82 return reinterpret_cast<uword>(element);
83 }
84 index++;
85 }
86 }
87
88 FreeListElement* previous = NULL;
89 FreeListElement* current = free_lists_[kNumLists];
90 while (current != NULL) {
91 if (current->Size() >= size) {
92 // Found an element large enough to hold the requested size. Dequeue,
93 // split and enqueue the remainder.
94 if (previous == NULL) {
95 free_lists_[kNumLists] = current->next();
96 } else {
97 previous->set_next(current->next());
98 }
99 SplitElementAfterAndEnqueue(current, size);
100 return reinterpret_cast<uword>(current);
101 }
102 previous = current;
103 current = current->next();
104 }
105 return 0;
106 }
107
108
109 void FreeList::Free(uword addr, intptr_t size) {
110 intptr_t index = IndexForSize(size);
111 FreeListElement* element = FreeListElement::AsElement(addr, size);
112 EnqueueElement(element, index);
113 }
114
115
116 void FreeList::Reset() {
117 for (int i = 0; i < (kNumLists + 1); i++) {
118 free_lists_[i] = NULL;
119 }
120 }
121
122 intptr_t FreeList::IndexForSize(intptr_t size) {
123 ASSERT(size >= kObjectAlignment);
124 ASSERT(Utils::IsAligned(size, kObjectAlignment));
125
126 intptr_t index = size / kObjectAlignment;
127 if (index >= kNumLists) {
128 index = kNumLists;
129 }
130 return index;
131 }
132
133
134 void FreeList::EnqueueElement(FreeListElement* element, intptr_t index) {
135 element->set_next(free_lists_[index]);
136 free_lists_[index] = element;
137 }
138
139
140 FreeListElement* FreeList::DequeueElement(intptr_t index) {
141 FreeListElement* result = free_lists_[index];
142 free_lists_[index] = result->next();
143 return result;
144 }
145
146
147 void FreeList::SplitElementAfterAndEnqueue(FreeListElement* element,
148 intptr_t size) {
149 intptr_t remainder_size = element->Size() - size;
150 if (remainder_size == 0) return;
151
152 element = FreeListElement::AsElement(reinterpret_cast<uword>(element) + size,
153 remainder_size);
154 intptr_t remainder_index = IndexForSize(remainder_size);
155 EnqueueElement(element, remainder_index);
156 }
157
158 } // namespace dart
OLDNEW
« vm/dart.cc ('K') | « vm/freelist.h ('k') | vm/freelist_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698