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

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

Powered by Google App Engine
This is Rietveld 408576698