| Index: runtime/vm/scavenger.cc
|
| diff --git a/runtime/vm/scavenger.cc b/runtime/vm/scavenger.cc
|
| index a13bcce75a27f8ceee815933cd333ac69f8ebe6e..34810a109fe21f4382c01d7ad88892b38b329592 100644
|
| --- a/runtime/vm/scavenger.cc
|
| +++ b/runtime/vm/scavenger.cc
|
| @@ -157,6 +157,7 @@ class ScavengerVisitor : public ObjectPointerVisitor {
|
| NOT_IN_PRODUCT(class_table->UpdateAllocatedOld(cid, size));
|
| } else {
|
| // Promotion did not succeed. Copy into the to space instead.
|
| + scavenger_->failed_to_promote_ = true;
|
| new_addr = scavenger_->TryAllocate(size);
|
| NOT_IN_PRODUCT(class_table->UpdateLiveNew(cid, size));
|
| }
|
| @@ -338,7 +339,8 @@ Scavenger::Scavenger(Heap* heap,
|
| delayed_weak_properties_(NULL),
|
| gc_time_micros_(0),
|
| collections_(0),
|
| - external_size_(0) {
|
| + external_size_(0),
|
| + failed_to_promote_(false) {
|
| // Verify assumptions about the first word in objects which the scavenger is
|
| // going to use for forwarding pointers.
|
| ASSERT(Object::tags_offset() == 0);
|
| @@ -796,6 +798,8 @@ void Scavenger::Scavenge(bool invoke_api_callbacks) {
|
| ASSERT(!scavenging_);
|
| scavenging_ = true;
|
|
|
| + failed_to_promote_ = false;
|
| +
|
| PageSpace* page_space = heap_->old_space();
|
| NoSafepointScope no_safepoints;
|
|
|
| @@ -905,4 +909,23 @@ void Scavenger::FreeExternal(intptr_t size) {
|
| ASSERT(external_size_ >= 0);
|
| }
|
|
|
| +
|
| +void Scavenger::Evacuate() {
|
| + // We need a safepoint here to prevent allocation right before or right after
|
| + // the scavenge.
|
| + // The former can introduce an object that we might fail to collect.
|
| + // The latter means even if the scavenge promotes every object in the new
|
| + // space, the new allocation means the space is not empty,
|
| + // causing the assertion below to fail.
|
| + SafepointOperationScope scope(Thread::Current());
|
| +
|
| + // Forces the next scavenge to promote all the objects in the new space.
|
| + survivor_end_ = top_;
|
| + Scavenge();
|
| +
|
| + // It is possible for objects to stay in the new space
|
| + // if the VM cannot create more pages for these objects.
|
| + ASSERT((UsedInWords() == 0) || failed_to_promote_);
|
| +}
|
| +
|
| } // namespace dart
|
|
|