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

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

Issue 1965823002: Initial isolate reload support (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 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
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 #include "vm/become.h"
6
7 #include "platform/assert.h"
8 #include "platform/utils.h"
9
10 #include "vm/dart_api_state.h"
11 #include "vm/freelist.h"
12 #include "vm/isolate_reload.h"
13 #include "vm/object.h"
14 #include "vm/raw_object.h"
15 #include "vm/safepoint.h"
16 #include "vm/timeline.h"
17 #include "vm/visitor.h"
18
19 namespace dart {
20
21 DECLARE_FLAG(bool, trace_reload);
22
23 static bool IsForwardingObject(RawObject* object) {
24 return object->IsHeapObject() && object->IsFreeListElement();
25 }
26
27
28 static RawObject* GetForwardedObject(RawObject* object) {
29 ASSERT(IsForwardingObject(object));
30 uword addr = reinterpret_cast<uword>(object) - kHeapObjectTag;
31 FreeListElement* forwarder = reinterpret_cast<FreeListElement*>(addr);
32 RawObject* new_target = reinterpret_cast<RawObject*>(forwarder->next());
33 return new_target;
34 }
35
36
37 static void ForwardObjectTo(RawObject* before_obj, RawObject* after_obj) {
38 const intptr_t size_before = before_obj->Size();
39
40 // TODO(rmacnak): We should use different cids for forwarding corpses and
41 // free list elements.
42 uword corpse_addr = reinterpret_cast<uword>(before_obj) - kHeapObjectTag;
43 FreeListElement* forwarder = FreeListElement::AsElement(corpse_addr,
44 size_before);
45 forwarder->set_next(reinterpret_cast<FreeListElement*>(after_obj));
46 if (!IsForwardingObject(before_obj)) {
47 FATAL("become: ForwardObjectTo failure.");
48 }
49 // Still need to be able to iterate over the forwarding corpse.
50 const intptr_t size_after = before_obj->Size();
51 if (size_before != size_after) {
52 FATAL("become: Before and after sizes do not match.");
53 }
54 ASSERT(size_before == size_after);
55 }
56
57
58 class ForwardPointersVisitor : public ObjectPointerVisitor {
59 public:
60 explicit ForwardPointersVisitor(Isolate* isolate)
61 : ObjectPointerVisitor(isolate), visiting_object_(NULL), count_(0) { }
62
63 virtual void VisitPointers(RawObject** first, RawObject** last) {
64 for (RawObject** p = first; p <= last; p++) {
65 RawObject* old_target = *p;
66 if (IsForwardingObject(old_target)) {
67 RawObject* new_target = GetForwardedObject(old_target);
68 if (visiting_object_ == NULL) {
69 *p = new_target;
70 } else {
71 visiting_object_->StorePointer(p, new_target);
72 }
73 count_++;
74 }
75 }
76 }
77
78 void VisitingObject(RawObject* obj) { visiting_object_ = obj; }
79
80 intptr_t count() const { return count_; }
81
82 private:
83 RawObject* visiting_object_;
84 intptr_t count_;
85
86 DISALLOW_COPY_AND_ASSIGN(ForwardPointersVisitor);
87 };
88
89
90 class ForwardHeapPointersVisitor : public ObjectVisitor {
91 public:
92 explicit ForwardHeapPointersVisitor(ForwardPointersVisitor* pointer_visitor)
93 : pointer_visitor_(pointer_visitor) { }
94
95 virtual void VisitObject(RawObject* obj) {
96 pointer_visitor_->VisitingObject(obj);
97 obj->VisitPointers(pointer_visitor_);
98 }
99
100 private:
101 ForwardPointersVisitor* pointer_visitor_;
102
103 DISALLOW_COPY_AND_ASSIGN(ForwardHeapPointersVisitor);
104 };
105
106
107 class ForwardHeapPointersHandleVisitor : public HandleVisitor {
108 public:
109 ForwardHeapPointersHandleVisitor()
110 : HandleVisitor(Thread::Current()), count_(0) { }
111
112 virtual void VisitHandle(uword addr) {
113 FinalizablePersistentHandle* handle =
114 reinterpret_cast<FinalizablePersistentHandle*>(addr);
115 if (IsForwardingObject(handle->raw())) {
116 *handle->raw_addr() = GetForwardedObject(handle->raw());
117 count_++;
118 }
119 }
120
121 intptr_t count() const { return count_; }
122
123 private:
124 int count_;
125
126 DISALLOW_COPY_AND_ASSIGN(ForwardHeapPointersHandleVisitor);
127 };
128
129
130 #if defined(DEBUG)
131 class NoFreeListTargetsVisitor : public ObjectPointerVisitor {
132 public:
133 explicit NoFreeListTargetsVisitor(Isolate* isolate)
134 : ObjectPointerVisitor(isolate) { }
135
136 virtual void VisitPointers(RawObject** first, RawObject** last) {
137 for (RawObject** p = first; p <= last; p++) {
138 RawObject* target = *p;
139 if (target->IsHeapObject()) {
140 ASSERT(!target->IsFreeListElement());
141 }
142 }
143 }
144
145 private:
146 DISALLOW_COPY_AND_ASSIGN(NoFreeListTargetsVisitor);
147 };
148 #endif
149
150
151 void Become::ElementsForwardIdentity(const Array& before, const Array& after) {
152 Thread* thread = Thread::Current();
153 Isolate* isolate = thread->isolate();
154 Heap* heap = isolate->heap();
155
156 {
157 // TODO(rmacnak): Investigate why this is necessary.
158 heap->CollectGarbage(Heap::kNew);
159 }
160
161 TIMELINE_FUNCTION_GC_DURATION(thread, "Become::ElementsForwardIdentity");
162 HeapIterationScope his;
163
164 #if defined(DEBUG)
165 {
166 // There should be no pointers to free list elements / forwarding corpses.
167 NoFreeListTargetsVisitor visitor(isolate);
168 isolate->VisitObjectPointers(&visitor, true);
169 heap->VisitObjectPointers(&visitor);
170 }
171 #endif
172
173 // Setup forwarding pointers.
174 ASSERT(before.Length() == after.Length());
175 for (intptr_t i = 0; i < before.Length(); i++) {
176 RawObject* before_obj = before.At(i);
177 RawObject* after_obj = after.At(i);
178
179 if (before_obj == after_obj) {
180 FATAL("become: Cannot self-forward");
181 }
182 if (!before_obj->IsHeapObject()) {
183 FATAL("become: Cannot forward immediates");
184 }
185 if (!after_obj->IsHeapObject()) {
186 FATAL("become: Cannot become an immediates");
187 }
188 if (before_obj->IsVMHeapObject()) {
189 FATAL("become: Cannot forward VM heap objects");
190 }
191 if (before_obj->IsFreeListElement()) {
192 FATAL("become: Cannot forward to multiple objects");
193 }
194 if (after_obj->IsFreeListElement()) {
195 // The Smalltalk become does allow this, and for very special cases
196 // it is important (shape changes to Class or Mixin), but as these
197 // cases do not arise in Dart, better to prohibit it.
198 FATAL("become: No indirect chains of forwarding");
199 }
200
201 ForwardObjectTo(before_obj, after_obj);
202 }
203
204 {
205 // Follow forwarding pointers.
206
207 // C++ pointers
208 ForwardPointersVisitor pointer_visitor(isolate);
209 isolate->VisitObjectPointers(&pointer_visitor, true);
210
211 // Weak persistent handles.
212 ForwardHeapPointersHandleVisitor handle_visitor;
213 isolate->VisitWeakPersistentHandles(&handle_visitor);
214
215 // Heap pointers (may require updating the remembered set)
216 ForwardHeapPointersVisitor object_visitor(&pointer_visitor);
217 heap->VisitObjects(&object_visitor);
218 pointer_visitor.VisitingObject(NULL);
219
220 TIR_Print("Performed %" Pd " heap and %" Pd " handle replacements\n",
221 pointer_visitor.count(),
222 handle_visitor.count());
223 }
224
225 #if defined(DEBUG)
226 for (intptr_t i = 0; i < before.Length(); i++) {
227 ASSERT(before.At(i) == after.At(i));
228 }
229
230 {
231 // There should be no pointers to forwarding corpses.
232 NoFreeListTargetsVisitor visitor(isolate);
233 isolate->VisitObjectPointers(&visitor, true);
234 heap->VisitObjectPointers(&visitor);
235 }
236 #endif
237 }
238
239 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698