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

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: 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 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 218
219 void Scavenger::Epilogue(Isolate* isolate, bool invoke_api_callbacks) { 219 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 220 // All objects in the to space have been copied from the from space at this
221 // moment. 221 // moment.
222 survivor_end_ = top_; 222 survivor_end_ = top_;
223 223
224 #if defined(DEBUG) 224 #if defined(DEBUG)
225 memset(from_->pointer(), 0xf3, from_->size()); 225 memset(from_->pointer(), 0xf3, from_->size());
226 #endif // defined(DEBUG) 226 #endif // defined(DEBUG)
227 if (invoke_api_callbacks) { 227 if (invoke_api_callbacks) {
228 isolate->gc_prologue_callbacks().Invoke(); 228 isolate->gc_prologue_callbacks().Invoke();
podivilov 2012/04/06 17:20:10 Please invoke epilogue callbacks here.
cshapiro 2012/04/06 22:24:31 Yes, will do. Also, I will update the tests to ex
229 } 229 }
230 } 230 }
231 231
232 232
233 void Scavenger::IterateRoots(Isolate* isolate, 233 void Scavenger::IterateRoots(Isolate* isolate,
234 ObjectPointerVisitor* visitor, 234 ObjectPointerVisitor* visitor,
235 bool visit_prologue_weak_persistent_handles) { 235 bool visit_prologue_weak_persistent_handles) {
236 isolate->VisitObjectPointers(visitor, 236 isolate->VisitObjectPointers(visitor,
237 visit_prologue_weak_persistent_handles, 237 visit_prologue_weak_persistent_handles,
238 StackFrameIterator::kDontValidateFrames); 238 StackFrameIterator::kDontValidateFrames);
239 heap_->IterateOldPointers(visitor); 239 heap_->IterateOldPointers(visitor);
240 } 240 }
241 241
242 242
243 bool Scavenger::IsUnreachable(RawObject** p) {
Ivan Posva 2012/04/06 21:54:06 Can you change this to Scavenger::IsReachable() to
cshapiro 2012/04/06 22:24:31 Yes, will do.
cshapiro 2012/04/10 02:40:31 While this is very rational adjustment when consid
244 RawObject* raw_obj = *p;
245 if (!raw_obj->IsHeapObject()) {
Ivan Posva 2012/04/06 21:54:06 This is surprising to me to say the least. Having
cshapiro 2012/04/06 22:24:31 I am not sure why this is surprising. Smi instanc
cshapiro 2012/04/10 02:40:31 I thought about this over the weekend. Numbers ar
246 return false;
247 }
248 if (!raw_obj->IsNewObject()) {
siva 2012/04/06 17:12:25 Wouldn't just this check be sufficient, it also im
cshapiro 2012/04/06 22:24:31 Objects that become unreferenced after a new space
249 return false;
250 }
251 uword raw_addr = RawObject::ToAddr(raw_obj);
252 if (!from_->Contains(raw_addr)) {
253 return false;
254 }
255 uword header = *reinterpret_cast<uword*>(raw_addr);
256 if (IsForwarding(header)) {
257 uword new_addr = ForwardedAddr(header);
258 *p = RawObject::FromAddr(new_addr);
259 return false;
260 }
261 return true;
262 }
263
264
265 void Scavenger::IterateWeakReferences(Isolate* isolate,
266 ObjectPointerVisitor* visitor) {
267 ApiState* state = isolate->api_state();
268 ASSERT(state != NULL);
269 while (true) {
270 WeakReference* queue = state->delayed_weak_references();
271 if (queue == NULL) {
272 // The delay queue is empty therefore no clean-up is required.
273 return;
274 }
275 state->set_delayed_weak_references(NULL);
276 while (queue != NULL) {
277 WeakReference* reference = WeakReference::Pop(&queue);
278 ASSERT(reference != NULL);
279 bool is_unreachable = true;
280 // Test each key object for reachability. If a key object is
281 // reachable, all value objects should be marked.
282 for (intptr_t k = 0; k < reference->num_keys(); ++k) {
283 if (!IsUnreachable(reference->get_key(k))) {
284 for (intptr_t v = 0; v < reference->num_values(); ++v) {
285 visitor->VisitPointer(reference->get_value(v));
286 }
287 is_unreachable = false;
288 delete reference;
289 break;
290 }
291 }
292 // If all key objects are unreachable put the reference on a
293 // delay queue. This reference will be revisited if another
294 // reference is marked.
295 if (is_unreachable) {
296 state->DelayWeakReference(reference);
297 }
298 }
299 if ((FirstObjectStart() < top_) || PromotedStackHasMore()) {
300 ProcessToSpace(visitor);
301 } else {
302 // Break out of the loop if there has been no forward process.
303 break;
304 }
305 }
306 // Deallocate any unmarked references on the delay queue.
307 if (state->delayed_weak_references() != NULL) {
308 WeakReference* queue = state->delayed_weak_references();
309 state->set_delayed_weak_references(NULL);
310 while (queue != NULL) {
311 delete WeakReference::Pop(&queue);
312 }
313 }
314 }
315
316
243 void Scavenger::IterateWeakRoots(Isolate* isolate, 317 void Scavenger::IterateWeakRoots(Isolate* isolate,
244 HandleVisitor* visitor, 318 HandleVisitor* visitor,
245 bool visit_prologue_weak_persistent_handles) { 319 bool visit_prologue_weak_persistent_handles) {
246 isolate->VisitWeakPersistentHandles(visitor, 320 isolate->VisitWeakPersistentHandles(visitor,
247 visit_prologue_weak_persistent_handles); 321 visit_prologue_weak_persistent_handles);
248 } 322 }
249 323
250 324
251 void Scavenger::ProcessToSpace(ObjectPointerVisitor* visitor) { 325 void Scavenger::ProcessToSpace(ObjectPointerVisitor* visitor) {
252 uword resolved_top = FirstObjectStart(); 326 uword resolved_top = FirstObjectStart();
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 OS::PrintErr(" done.\n"); 370 OS::PrintErr(" done.\n");
297 } 371 }
298 372
299 Timer timer(FLAG_verbose_gc, "Scavenge"); 373 Timer timer(FLAG_verbose_gc, "Scavenge");
300 timer.Start(); 374 timer.Start();
301 // Setup the visitor and run a scavenge. 375 // Setup the visitor and run a scavenge.
302 ScavengerVisitor visitor(this); 376 ScavengerVisitor visitor(this);
303 Prologue(isolate, invoke_api_callbacks); 377 Prologue(isolate, invoke_api_callbacks);
304 IterateRoots(isolate, &visitor, !invoke_api_callbacks); 378 IterateRoots(isolate, &visitor, !invoke_api_callbacks);
305 ProcessToSpace(&visitor); 379 ProcessToSpace(&visitor);
380 IterateWeakReferences(isolate, &visitor);
306 ScavengerWeakVisitor weak_visitor(this); 381 ScavengerWeakVisitor weak_visitor(this);
307 IterateWeakRoots(isolate, &weak_visitor, invoke_api_callbacks); 382 IterateWeakRoots(isolate, &weak_visitor, invoke_api_callbacks);
308 Epilogue(isolate, invoke_api_callbacks); 383 Epilogue(isolate, invoke_api_callbacks);
309 timer.Stop(); 384 timer.Stop();
310 if (FLAG_verbose_gc) { 385 if (FLAG_verbose_gc) {
311 OS::PrintErr("Scavenge[%d]: %dus\n", count_, timer.TotalElapsedTime()); 386 OS::PrintErr("Scavenge[%d]: %dus\n", count_, timer.TotalElapsedTime());
312 } 387 }
313 388
314 if (FLAG_verify_after_gc) { 389 if (FLAG_verify_after_gc) {
315 OS::PrintErr("Verifying after Scavenge... "); 390 OS::PrintErr("Verifying after Scavenge... ");
316 heap_->Verify(); 391 heap_->Verify();
317 OS::PrintErr(" done.\n"); 392 OS::PrintErr(" done.\n");
318 } 393 }
319 394
320 count_++; 395 count_++;
321 // Done scavenging. Reset the marker. 396 // Done scavenging. Reset the marker.
322 ASSERT(scavenging_); 397 ASSERT(scavenging_);
323 scavenging_ = false; 398 scavenging_ = false;
324 } 399 }
325 400
326 } // namespace dart 401 } // 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