Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |