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

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

Issue 9956138: Process weak reference sets when a scavenge invokes the API callbacks. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: rebase Created 8 years, 8 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
« no previous file with comments | « runtime/vm/scavenger.h ('k') | no next file » | 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) 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/scavenger.h" 5 #include "vm/scavenger.h"
6 6
7 #include "vm/dart.h" 7 #include "vm/dart.h"
8 #include "vm/dart_api_state.h" 8 #include "vm/dart_api_state.h"
9 #include "vm/isolate.h" 9 #include "vm/isolate.h"
10 #include "vm/object.h" 10 #include "vm/object.h"
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 132
133 133
134 class ScavengerWeakVisitor : public HandleVisitor { 134 class ScavengerWeakVisitor : public HandleVisitor {
135 public: 135 public:
136 explicit ScavengerWeakVisitor(Scavenger* scavenger) : scavenger_(scavenger) { 136 explicit ScavengerWeakVisitor(Scavenger* scavenger) : scavenger_(scavenger) {
137 } 137 }
138 138
139 void VisitHandle(uword addr) { 139 void VisitHandle(uword addr) {
140 FinalizablePersistentHandle* handle = 140 FinalizablePersistentHandle* handle =
141 reinterpret_cast<FinalizablePersistentHandle*>(addr); 141 reinterpret_cast<FinalizablePersistentHandle*>(addr);
142 RawObject* raw_obj = handle->raw(); 142 RawObject** p = reinterpret_cast<RawObject**>(handle);
143 if (!raw_obj->IsHeapObject()) return; 143 if (scavenger_->IsUnreachable(p)) {
144 uword raw_addr = RawObject::ToAddr(raw_obj); 144 FinalizablePersistentHandle::Finalize(handle);
145 if (scavenger_->from_->Contains(raw_addr)) {
146 uword header = *reinterpret_cast<uword*>(raw_addr);
147 if (IsForwarding(header)) {
148 handle->set_raw(RawObject::FromAddr(ForwardedAddr(header)));
149 } else {
150 FinalizablePersistentHandle::Finalize(handle);
151 }
152 } 145 }
153 } 146 }
154 147
155 private: 148 private:
156 Scavenger* scavenger_; 149 Scavenger* scavenger_;
157 150
158 DISALLOW_COPY_AND_ASSIGN(ScavengerWeakVisitor); 151 DISALLOW_COPY_AND_ASSIGN(ScavengerWeakVisitor);
159 }; 152 };
160 153
161 154
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 211
219 void Scavenger::Epilogue(Isolate* isolate, bool invoke_api_callbacks) { 212 void Scavenger::Epilogue(Isolate* isolate, bool invoke_api_callbacks) {
220 // All objects in the to space have been copied from the from space at this 213 // All objects in the to space have been copied from the from space at this
221 // moment. 214 // moment.
222 survivor_end_ = top_; 215 survivor_end_ = top_;
223 216
224 #if defined(DEBUG) 217 #if defined(DEBUG)
225 memset(from_->pointer(), 0xf3, from_->size()); 218 memset(from_->pointer(), 0xf3, from_->size());
226 #endif // defined(DEBUG) 219 #endif // defined(DEBUG)
227 if (invoke_api_callbacks) { 220 if (invoke_api_callbacks) {
228 isolate->gc_prologue_callbacks().Invoke(); 221 isolate->gc_epilogue_callbacks().Invoke();
229 } 222 }
230 } 223 }
231 224
232 225
233 void Scavenger::IterateRoots(Isolate* isolate, 226 void Scavenger::IterateRoots(Isolate* isolate,
234 ObjectPointerVisitor* visitor, 227 ObjectPointerVisitor* visitor,
235 bool visit_prologue_weak_persistent_handles) { 228 bool visit_prologue_weak_persistent_handles) {
236 isolate->VisitObjectPointers(visitor, 229 isolate->VisitObjectPointers(visitor,
237 visit_prologue_weak_persistent_handles, 230 visit_prologue_weak_persistent_handles,
238 StackFrameIterator::kDontValidateFrames); 231 StackFrameIterator::kDontValidateFrames);
239 heap_->IterateOldPointers(visitor); 232 heap_->IterateOldPointers(visitor);
240 } 233 }
241 234
242 235
236 bool Scavenger::IsUnreachable(RawObject** p) {
237 RawObject* raw_obj = *p;
238 if (!raw_obj->IsHeapObject()) {
239 return false;
240 }
241 if (!raw_obj->IsNewObject()) {
242 return false;
243 }
244 uword raw_addr = RawObject::ToAddr(raw_obj);
245 if (!from_->Contains(raw_addr)) {
246 return false;
247 }
248 uword header = *reinterpret_cast<uword*>(raw_addr);
249 if (IsForwarding(header)) {
250 uword new_addr = ForwardedAddr(header);
251 *p = RawObject::FromAddr(new_addr);
252 return false;
253 }
254 return true;
255 }
256
257
258 void Scavenger::IterateWeakReferences(Isolate* isolate,
259 ObjectPointerVisitor* visitor) {
260 ApiState* state = isolate->api_state();
261 ASSERT(state != NULL);
262 while (true) {
263 WeakReference* queue = state->delayed_weak_references();
264 if (queue == NULL) {
265 // The delay queue is empty therefore no clean-up is required.
266 return;
267 }
268 state->set_delayed_weak_references(NULL);
269 while (queue != NULL) {
270 WeakReference* reference = WeakReference::Pop(&queue);
271 ASSERT(reference != NULL);
272 bool is_unreachable = true;
273 // Test each key object for reachability. If a key object is
274 // reachable, all value objects should be scavenged.
275 for (intptr_t k = 0; k < reference->num_keys(); ++k) {
276 if (!IsUnreachable(reference->get_key(k))) {
277 for (intptr_t v = 0; v < reference->num_values(); ++v) {
278 visitor->VisitPointer(reference->get_value(v));
279 }
280 is_unreachable = false;
281 delete reference;
282 break;
283 }
284 }
285 // If all key objects are unreachable put the reference on a
286 // delay queue. This reference will be revisited if another
287 // reference is scavenged.
288 if (is_unreachable) {
289 state->DelayWeakReference(reference);
290 }
291 }
292 if ((FirstObjectStart() < top_) || PromotedStackHasMore()) {
293 ProcessToSpace(visitor);
294 } else {
295 // Break out of the loop if there has been no forward process.
296 break;
297 }
298 }
299 // Deallocate any unreachable references on the delay queue.
300 if (state->delayed_weak_references() != NULL) {
301 WeakReference* queue = state->delayed_weak_references();
302 state->set_delayed_weak_references(NULL);
303 while (queue != NULL) {
304 delete WeakReference::Pop(&queue);
305 }
306 }
307 }
308
309
243 void Scavenger::IterateWeakRoots(Isolate* isolate, 310 void Scavenger::IterateWeakRoots(Isolate* isolate,
244 HandleVisitor* visitor, 311 HandleVisitor* visitor,
245 bool visit_prologue_weak_persistent_handles) { 312 bool visit_prologue_weak_persistent_handles) {
246 isolate->VisitWeakPersistentHandles(visitor, 313 isolate->VisitWeakPersistentHandles(visitor,
247 visit_prologue_weak_persistent_handles); 314 visit_prologue_weak_persistent_handles);
248 } 315 }
249 316
250 317
251 void Scavenger::ProcessToSpace(ObjectPointerVisitor* visitor) { 318 void Scavenger::ProcessToSpace(ObjectPointerVisitor* visitor) {
252 uword resolved_top = FirstObjectStart(); 319 uword resolved_top = FirstObjectStart();
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 OS::PrintErr(" done.\n"); 363 OS::PrintErr(" done.\n");
297 } 364 }
298 365
299 Timer timer(FLAG_verbose_gc, "Scavenge"); 366 Timer timer(FLAG_verbose_gc, "Scavenge");
300 timer.Start(); 367 timer.Start();
301 // Setup the visitor and run a scavenge. 368 // Setup the visitor and run a scavenge.
302 ScavengerVisitor visitor(this); 369 ScavengerVisitor visitor(this);
303 Prologue(isolate, invoke_api_callbacks); 370 Prologue(isolate, invoke_api_callbacks);
304 IterateRoots(isolate, &visitor, !invoke_api_callbacks); 371 IterateRoots(isolate, &visitor, !invoke_api_callbacks);
305 ProcessToSpace(&visitor); 372 ProcessToSpace(&visitor);
373 IterateWeakReferences(isolate, &visitor);
306 ScavengerWeakVisitor weak_visitor(this); 374 ScavengerWeakVisitor weak_visitor(this);
307 IterateWeakRoots(isolate, &weak_visitor, invoke_api_callbacks); 375 IterateWeakRoots(isolate, &weak_visitor, invoke_api_callbacks);
308 Epilogue(isolate, invoke_api_callbacks); 376 Epilogue(isolate, invoke_api_callbacks);
309 timer.Stop(); 377 timer.Stop();
310 if (FLAG_verbose_gc) { 378 if (FLAG_verbose_gc) {
311 OS::PrintErr("Scavenge[%d]: %dus\n", count_, timer.TotalElapsedTime()); 379 OS::PrintErr("Scavenge[%d]: %dus\n", count_, timer.TotalElapsedTime());
312 } 380 }
313 381
314 if (FLAG_verify_after_gc) { 382 if (FLAG_verify_after_gc) {
315 OS::PrintErr("Verifying after Scavenge... "); 383 OS::PrintErr("Verifying after Scavenge... ");
316 heap_->Verify(); 384 heap_->Verify();
317 OS::PrintErr(" done.\n"); 385 OS::PrintErr(" done.\n");
318 } 386 }
319 387
320 count_++; 388 count_++;
321 // Done scavenging. Reset the marker. 389 // Done scavenging. Reset the marker.
322 ASSERT(scavenging_); 390 ASSERT(scavenging_);
323 scavenging_ = false; 391 scavenging_ = false;
324 } 392 }
325 393
326 } // namespace dart 394 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/scavenger.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698