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

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

Issue 2026643004: Don't overload FreeListElement for become. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 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
« no previous file with comments | « runtime/vm/become.h ('k') | runtime/vm/class_table.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) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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/become.h" 5 #include "vm/become.h"
6 6
7 #include "platform/assert.h" 7 #include "platform/assert.h"
8 #include "platform/utils.h" 8 #include "platform/utils.h"
9 9
10 #include "vm/dart_api_state.h" 10 #include "vm/dart_api_state.h"
11 #include "vm/freelist.h"
12 #include "vm/isolate_reload.h" 11 #include "vm/isolate_reload.h"
13 #include "vm/object.h" 12 #include "vm/object.h"
14 #include "vm/raw_object.h" 13 #include "vm/raw_object.h"
15 #include "vm/safepoint.h" 14 #include "vm/safepoint.h"
16 #include "vm/timeline.h" 15 #include "vm/timeline.h"
17 #include "vm/visitor.h" 16 #include "vm/visitor.h"
18 17
19 namespace dart { 18 namespace dart {
20 19
21 DECLARE_FLAG(bool, trace_reload); 20 DECLARE_FLAG(bool, trace_reload);
22 21
22
23 ForwardingCorpse* ForwardingCorpse::AsForwarder(uword addr, intptr_t size) {
24 ASSERT(size >= kObjectAlignment);
25 ASSERT(Utils::IsAligned(size, kObjectAlignment));
26
27 ForwardingCorpse* result = reinterpret_cast<ForwardingCorpse*>(addr);
28
29 uword tags = 0;
30 tags = RawObject::SizeTag::update(size, tags);
31 tags = RawObject::ClassIdTag::update(kForwardingCorpse, tags);
32
33 result->tags_ = tags;
34 if (size > RawObject::SizeTag::kMaxSizeTag) {
35 *result->SizeAddress() = size;
36 }
37 result->set_target(Object::null());
38 return result;
39 }
40
41
42 void ForwardingCorpse::InitOnce() {
43 ASSERT(sizeof(ForwardingCorpse) == kObjectAlignment);
44 ASSERT(OFFSET_OF(ForwardingCorpse, tags_) == Object::tags_offset());
45 }
46
47
23 // Free list elements are used as a marker for forwarding objects. This is 48 // Free list elements are used as a marker for forwarding objects. This is
24 // safe because we cannot reach free list elements from live objects. Ideally 49 // safe because we cannot reach free list elements from live objects. Ideally
25 // forwarding objects would have their own class id. See TODO below. 50 // forwarding objects would have their own class id. See TODO below.
26 static bool IsForwardingObject(RawObject* object) { 51 static bool IsForwardingObject(RawObject* object) {
27 return object->IsHeapObject() && object->IsFreeListElement(); 52 return object->IsHeapObject() && object->IsForwardingCorpse();
28 } 53 }
29 54
30 55
31 static RawObject* GetForwardedObject(RawObject* object) { 56 static RawObject* GetForwardedObject(RawObject* object) {
32 ASSERT(IsForwardingObject(object)); 57 ASSERT(IsForwardingObject(object));
33 uword addr = reinterpret_cast<uword>(object) - kHeapObjectTag; 58 uword addr = reinterpret_cast<uword>(object) - kHeapObjectTag;
34 FreeListElement* forwarder = reinterpret_cast<FreeListElement*>(addr); 59 ForwardingCorpse* forwarder = reinterpret_cast<ForwardingCorpse*>(addr);
35 RawObject* new_target = reinterpret_cast<RawObject*>(forwarder->next()); 60 return forwarder->target();
36 return new_target;
37 } 61 }
38 62
39 63
40 static void ForwardObjectTo(RawObject* before_obj, RawObject* after_obj) { 64 static void ForwardObjectTo(RawObject* before_obj, RawObject* after_obj) {
41 const intptr_t size_before = before_obj->Size(); 65 const intptr_t size_before = before_obj->Size();
42 66
43 // TODO(rmacnak): We should use different cids for forwarding corpses and
44 // free list elements.
45 uword corpse_addr = reinterpret_cast<uword>(before_obj) - kHeapObjectTag; 67 uword corpse_addr = reinterpret_cast<uword>(before_obj) - kHeapObjectTag;
46 FreeListElement* forwarder = FreeListElement::AsElement(corpse_addr, 68 ForwardingCorpse* forwarder = ForwardingCorpse::AsForwarder(corpse_addr,
47 size_before); 69 size_before);
48 forwarder->set_next(reinterpret_cast<FreeListElement*>(after_obj)); 70 forwarder->set_target(after_obj);
49 if (!IsForwardingObject(before_obj)) { 71 if (!IsForwardingObject(before_obj)) {
50 FATAL("become: ForwardObjectTo failure."); 72 FATAL("become: ForwardObjectTo failure.");
51 } 73 }
52 // Still need to be able to iterate over the forwarding corpse. 74 // Still need to be able to iterate over the forwarding corpse.
53 const intptr_t size_after = before_obj->Size(); 75 const intptr_t size_after = before_obj->Size();
54 if (size_before != size_after) { 76 if (size_before != size_after) {
55 FATAL("become: Before and after sizes do not match."); 77 FATAL("become: Before and after sizes do not match.");
56 } 78 }
57 } 79 }
58 80
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 intptr_t count() const { return count_; } 145 intptr_t count() const { return count_; }
124 146
125 private: 147 private:
126 int count_; 148 int count_;
127 149
128 DISALLOW_COPY_AND_ASSIGN(ForwardHeapPointersHandleVisitor); 150 DISALLOW_COPY_AND_ASSIGN(ForwardHeapPointersHandleVisitor);
129 }; 151 };
130 152
131 153
132 #if defined(DEBUG) 154 #if defined(DEBUG)
133 class NoFreeListTargetsVisitor : public ObjectPointerVisitor { 155 class NoForwardingCorpseTargetsVisitor : public ObjectPointerVisitor {
134 public: 156 public:
135 explicit NoFreeListTargetsVisitor(Isolate* isolate) 157 explicit NoForwardingCorpseTargetsVisitor(Isolate* isolate)
136 : ObjectPointerVisitor(isolate) { } 158 : ObjectPointerVisitor(isolate) { }
137 159
138 virtual void VisitPointers(RawObject** first, RawObject** last) { 160 virtual void VisitPointers(RawObject** first, RawObject** last) {
139 for (RawObject** p = first; p <= last; p++) { 161 for (RawObject** p = first; p <= last; p++) {
140 RawObject* target = *p; 162 RawObject* target = *p;
141 if (target->IsHeapObject()) { 163 if (target->IsHeapObject()) {
142 ASSERT(!target->IsFreeListElement()); 164 ASSERT(!target->IsForwardingCorpse());
143 } 165 }
144 } 166 }
145 } 167 }
146 168
147 private: 169 private:
148 DISALLOW_COPY_AND_ASSIGN(NoFreeListTargetsVisitor); 170 DISALLOW_COPY_AND_ASSIGN(NoForwardingCorpseTargetsVisitor);
149 }; 171 };
150 #endif 172 #endif
151 173
152 174
153 void Become::ElementsForwardIdentity(const Array& before, const Array& after) { 175 void Become::ElementsForwardIdentity(const Array& before, const Array& after) {
154 Thread* thread = Thread::Current(); 176 Thread* thread = Thread::Current();
155 Isolate* isolate = thread->isolate(); 177 Isolate* isolate = thread->isolate();
156 Heap* heap = isolate->heap(); 178 Heap* heap = isolate->heap();
157 179
158 { 180 {
159 // TODO(rmacnak): Investigate why this is necessary. 181 // TODO(rmacnak): Investigate why this is necessary.
160 heap->CollectGarbage(Heap::kNew); 182 heap->CollectGarbage(Heap::kNew);
161 } 183 }
162 184
163 TIMELINE_FUNCTION_GC_DURATION(thread, "Become::ElementsForwardIdentity"); 185 TIMELINE_FUNCTION_GC_DURATION(thread, "Become::ElementsForwardIdentity");
164 HeapIterationScope his; 186 HeapIterationScope his;
165 187
166 #if defined(DEBUG) 188 #if defined(DEBUG)
167 { 189 {
168 // There should be no pointers to free list elements / forwarding corpses. 190 // There should be no pointers to free list elements / forwarding corpses.
169 NoFreeListTargetsVisitor visitor(isolate); 191 NoForwardingCorpseTargetsVisitor visitor(isolate);
170 isolate->VisitObjectPointers(&visitor, true); 192 isolate->VisitObjectPointers(&visitor, true);
171 heap->VisitObjectPointers(&visitor); 193 heap->VisitObjectPointers(&visitor);
172 } 194 }
173 #endif 195 #endif
174 196
175 // Setup forwarding pointers. 197 // Setup forwarding pointers.
176 ASSERT(before.Length() == after.Length()); 198 ASSERT(before.Length() == after.Length());
177 for (intptr_t i = 0; i < before.Length(); i++) { 199 for (intptr_t i = 0; i < before.Length(); i++) {
178 RawObject* before_obj = before.At(i); 200 RawObject* before_obj = before.At(i);
179 RawObject* after_obj = after.At(i); 201 RawObject* after_obj = after.At(i);
180 202
181 if (before_obj == after_obj) { 203 if (before_obj == after_obj) {
182 FATAL("become: Cannot self-forward"); 204 FATAL("become: Cannot self-forward");
183 } 205 }
184 if (!before_obj->IsHeapObject()) { 206 if (!before_obj->IsHeapObject()) {
185 FATAL("become: Cannot forward immediates"); 207 FATAL("become: Cannot forward immediates");
186 } 208 }
187 if (!after_obj->IsHeapObject()) { 209 if (!after_obj->IsHeapObject()) {
188 FATAL("become: Cannot become an immediates"); 210 FATAL("become: Cannot become an immediates");
189 } 211 }
190 if (before_obj->IsVMHeapObject()) { 212 if (before_obj->IsVMHeapObject()) {
191 FATAL("become: Cannot forward VM heap objects"); 213 FATAL("become: Cannot forward VM heap objects");
192 } 214 }
193 if (after_obj->IsFreeListElement()) { 215 if (before_obj->IsForwardingCorpse()) {
216 FATAL("become: Cannot forward to multiple targets");
217 }
218 if (after_obj->IsForwardingCorpse()) {
194 // The Smalltalk become does allow this, and for very special cases 219 // The Smalltalk become does allow this, and for very special cases
195 // it is important (shape changes to Class or Mixin), but as these 220 // it is important (shape changes to Class or Mixin), but as these
196 // cases do not arise in Dart, better to prohibit it. 221 // cases do not arise in Dart, better to prohibit it.
197 FATAL("become: No indirect chains of forwarding"); 222 FATAL("become: No indirect chains of forwarding");
198 } 223 }
199 224
200 ForwardObjectTo(before_obj, after_obj); 225 ForwardObjectTo(before_obj, after_obj);
201 } 226 }
202 227
203 { 228 {
(...skipping 17 matching lines...) Expand all
221 handle_visitor.count()); 246 handle_visitor.count());
222 } 247 }
223 248
224 #if defined(DEBUG) 249 #if defined(DEBUG)
225 for (intptr_t i = 0; i < before.Length(); i++) { 250 for (intptr_t i = 0; i < before.Length(); i++) {
226 ASSERT(before.At(i) == after.At(i)); 251 ASSERT(before.At(i) == after.At(i));
227 } 252 }
228 253
229 { 254 {
230 // There should be no pointers to forwarding corpses. 255 // There should be no pointers to forwarding corpses.
231 NoFreeListTargetsVisitor visitor(isolate); 256 NoForwardingCorpseTargetsVisitor visitor(isolate);
232 isolate->VisitObjectPointers(&visitor, true); 257 isolate->VisitObjectPointers(&visitor, true);
233 heap->VisitObjectPointers(&visitor); 258 heap->VisitObjectPointers(&visitor);
234 } 259 }
235 #endif 260 #endif
236 } 261 }
237 262
238 } // namespace dart 263 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/become.h ('k') | runtime/vm/class_table.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698