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

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

Issue 10538022: Do not reuse tags_ field to store next_ pointer of FreeListElement. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 6 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 12
13 // Allocate a fake class to be used as the class for elements of the free list.
14 // These raw classes are only used to identify free list elements in the heap.
15 // These classes cannot be allocated in the heap as the elements of the free
16 // list are not live objects and their class references would not be updated
17 // during a moving collection. In the general case these classes are also used
18 // to implement RawObject::Size() to allow other code to safely traverse
19 // the heap without any knowledge of the embedded free list elements.
20 RawClass* AllocateFakeClass() {
21 RawClass* result =
22 reinterpret_cast<RawClass*>(calloc(1, Class::InstanceSize()));
23 result->instance_kind_ = kFreeListElement;
24 return reinterpret_cast<RawClass*>(RawObject::FromAddr(
25 reinterpret_cast<uword>(result)));
26 }
27
28
29 RawClass* FreeListElement::element_class_ = NULL;
30
31
13 FreeListElement* FreeListElement::AsElement(uword addr, intptr_t size) { 32 FreeListElement* FreeListElement::AsElement(uword addr, intptr_t size) {
14 ASSERT(size >= kObjectAlignment); 33 ASSERT(size >= kObjectAlignment);
15 ASSERT(Utils::IsAligned(size, kObjectAlignment)); 34 ASSERT(Utils::IsAligned(size, kObjectAlignment));
16 35
17 FreeListElement* result = reinterpret_cast<FreeListElement*>(addr); 36 FreeListElement* result = reinterpret_cast<FreeListElement*>(addr);
18 result->size_ = size; 37
38 uword tags = 0;
39 tags = RawObject::FreeBit::update(true, tags);
40 tags = RawObject::SizeTag::update(size, tags);
41 tags = RawObject::ClassIdTag::update(kFreeListElement, tags);
42
43 result->tags_ = tags;
44 if (size > RawObject::SizeTag::kMaxSizeTag) {
45 *result->SizeAddress() = size;
46 }
19 result->set_next(NULL); 47 result->set_next(NULL);
48
20 return result; 49 return result;
21 } 50 }
22 51
23 52
24 void FreeListElement::InitOnce() { 53 void FreeListElement::InitOnce() {
25 ASSERT(sizeof(FreeListElement) == kObjectAlignment); 54 ASSERT(sizeof(FreeListElement) == kObjectAlignment);
26 ASSERT(OFFSET_OF(FreeListElement, next_) == Object::tags_offset()); 55 ASSERT(OFFSET_OF(FreeListElement, tags_) == Object::tags_offset());
56 element_class_ = AllocateFakeClass();
27 } 57 }
28 58
29 59
30 FreeList::FreeList() { 60 FreeList::FreeList() {
31 Reset(); 61 Reset();
32 } 62 }
33 63
34 64
35 FreeList::~FreeList() { 65 FreeList::~FreeList() {
36 // Nothing to release. 66 // Nothing to release.
(...skipping 16 matching lines...) Expand all
53 SplitElementAfterAndEnqueue(element, size); 83 SplitElementAfterAndEnqueue(element, size);
54 return reinterpret_cast<uword>(element); 84 return reinterpret_cast<uword>(element);
55 } 85 }
56 index++; 86 index++;
57 } 87 }
58 } 88 }
59 89
60 FreeListElement* previous = NULL; 90 FreeListElement* previous = NULL;
61 FreeListElement* current = free_lists_[kNumLists]; 91 FreeListElement* current = free_lists_[kNumLists];
62 while (current != NULL) { 92 while (current != NULL) {
63 if (current->size() >= size) { 93 if (current->Size() >= size) {
64 // Found an element large enough to hold the requested size. Dequeue, 94 // Found an element large enough to hold the requested size. Dequeue,
65 // split and enqueue the remainder. 95 // split and enqueue the remainder.
66 if (previous == NULL) { 96 if (previous == NULL) {
67 free_lists_[kNumLists] = current->next(); 97 free_lists_[kNumLists] = current->next();
68 } else { 98 } else {
69 previous->set_next(current->next()); 99 previous->set_next(current->next());
70 } 100 }
71 SplitElementAfterAndEnqueue(current, size); 101 SplitElementAfterAndEnqueue(current, size);
72 return reinterpret_cast<uword>(current); 102 return reinterpret_cast<uword>(current);
73 } 103 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 141
112 FreeListElement* FreeList::DequeueElement(intptr_t index) { 142 FreeListElement* FreeList::DequeueElement(intptr_t index) {
113 FreeListElement* result = free_lists_[index]; 143 FreeListElement* result = free_lists_[index];
114 free_lists_[index] = result->next(); 144 free_lists_[index] = result->next();
115 return result; 145 return result;
116 } 146 }
117 147
118 148
119 void FreeList::SplitElementAfterAndEnqueue(FreeListElement* element, 149 void FreeList::SplitElementAfterAndEnqueue(FreeListElement* element,
120 intptr_t size) { 150 intptr_t size) {
121 intptr_t remainder_size = element->size() - size; 151 intptr_t remainder_size = element->Size() - size;
122 if (remainder_size == 0) return; 152 if (remainder_size == 0) return;
123 153
124 element = FreeListElement::AsElement(reinterpret_cast<uword>(element) + size, 154 element = FreeListElement::AsElement(reinterpret_cast<uword>(element) + size,
125 remainder_size); 155 remainder_size);
126 intptr_t remainder_index = IndexForSize(remainder_size); 156 intptr_t remainder_index = IndexForSize(remainder_size);
127 EnqueueElement(element, remainder_index); 157 EnqueueElement(element, remainder_index);
128 } 158 }
129 159
130 } // namespace dart 160 } // namespace dart
OLDNEW
« runtime/vm/freelist.h ('K') | « runtime/vm/freelist.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698