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

Unified Diff: runtime/vm/scavenger.cc

Issue 2001713002: - Removed the kWatchedBit and the associated weak property handling (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 side-by-side diff with in-line comments
Download patch
Index: runtime/vm/scavenger.cc
diff --git a/runtime/vm/scavenger.cc b/runtime/vm/scavenger.cc
index bcbb79fed277ad6b27f8bd696e31a73892e22447..7921e36e4f1f022120252edd1132039442d67161 100644
--- a/runtime/vm/scavenger.cc
+++ b/runtime/vm/scavenger.cc
@@ -4,10 +4,6 @@
#include "vm/scavenger.h"
-#include <algorithm>
-#include <map>
-#include <utility>
-
#include "vm/dart.h"
#include "vm/dart_api_state.h"
#include "vm/isolate.h"
@@ -63,21 +59,6 @@ static inline void ForwardTo(uword original, uword target) {
}
-class BoolScope : public ValueObject {
- public:
- BoolScope(bool* addr, bool value) : _addr(addr), _value(*addr) {
- *_addr = value;
- }
- ~BoolScope() {
- *_addr = _value;
- }
-
- private:
- bool* _addr;
- bool _value;
-};
-
-
class ScavengerVisitor : public ObjectPointerVisitor {
public:
explicit ScavengerVisitor(Isolate* isolate,
@@ -90,45 +71,23 @@ class ScavengerVisitor : public ObjectPointerVisitor {
heap_(scavenger->heap_),
vm_heap_(Dart::vm_isolate()->heap()),
page_space_(scavenger->heap_->old_space()),
- delayed_weak_stack_(),
bytes_promoted_(0),
- visiting_old_object_(NULL),
- in_scavenge_pointer_(false) { }
+ visiting_old_object_(NULL) { }
void VisitPointers(RawObject** first, RawObject** last) {
+ ASSERT((visiting_old_object_ != NULL) ||
+ scavenger_->Contains(reinterpret_cast<uword>(first)) ||
+ !heap_->Contains(reinterpret_cast<uword>(first)));
for (RawObject** current = first; current <= last; current++) {
ScavengePointer(current);
}
}
- GrowableArray<RawObject*>* DelayedWeakStack() {
- return &delayed_weak_stack_;
- }
-
void VisitingOldObject(RawObject* obj) {
ASSERT((obj == NULL) || obj->IsOldObject());
visiting_old_object_ = obj;
}
- void DelayWeakProperty(RawWeakProperty* raw_weak) {
- RawObject* raw_key = raw_weak->ptr()->key_;
- DelaySet::iterator it = delay_set_.find(raw_key);
- if (it != delay_set_.end()) {
- ASSERT(raw_key->IsWatched());
- } else {
- ASSERT(!raw_key->IsWatched());
- raw_key->SetWatchedBitUnsynchronized();
- }
- delay_set_.insert(std::make_pair(raw_key, raw_weak));
- }
-
- void Finalize() {
- DelaySet::iterator it = delay_set_.begin();
- for (; it != delay_set_.end(); ++it) {
- WeakProperty::Clear(it->second);
- }
- }
-
intptr_t bytes_promoted() const { return bytes_promoted_; }
private:
@@ -148,11 +107,6 @@ class ScavengerVisitor : public ObjectPointerVisitor {
void ScavengePointer(RawObject** p) {
// ScavengePointer cannot be called recursively.
-#ifdef DEBUG
- ASSERT(!in_scavenge_pointer_);
- BoolScope bs(&in_scavenge_pointer_, true);
-#endif
-
RawObject* raw_obj = *p;
if (raw_obj->IsSmiOrOldObject()) {
@@ -170,20 +124,6 @@ class ScavengerVisitor : public ObjectPointerVisitor {
// Get the new location of the object.
new_addr = ForwardedAddr(header);
} else {
- if (raw_obj->IsWatched()) {
- raw_obj->ClearWatchedBitUnsynchronized();
- std::pair<DelaySet::iterator, DelaySet::iterator> ret;
- // Visit all elements with a key equal to this raw_obj.
- ret = delay_set_.equal_range(raw_obj);
- for (DelaySet::iterator it = ret.first; it != ret.second; ++it) {
- // Remember the delayed WeakProperty. These objects have been
- // forwarded, but have not been scavenged because their key was not
- // known to be reachable. Now that the key object is known to be
- // reachable, we need to visit its key and value pointers.
- delayed_weak_stack_.Add(it->second);
- }
- delay_set_.erase(ret.first, ret.second);
- }
intptr_t size = raw_obj->Size();
intptr_t cid = raw_obj->GetClassId();
ClassTable* class_table = isolate()->class_table();
@@ -241,14 +181,11 @@ class ScavengerVisitor : public ObjectPointerVisitor {
Heap* heap_;
Heap* vm_heap_;
PageSpace* page_space_;
- typedef std::multimap<RawObject*, RawWeakProperty*> DelaySet;
- DelaySet delay_set_;
- GrowableArray<RawObject*> delayed_weak_stack_;
- // TODO(cshapiro): use this value to compute survival statistics for
- // new space growth policy.
+ RawWeakProperty* delayed_weak_properties_;
intptr_t bytes_promoted_;
RawObject* visiting_old_object_;
- bool in_scavenge_pointer_;
+
+ friend class Scavenger;
DISALLOW_COPY_AND_ASSIGN(ScavengerVisitor);
};
@@ -397,6 +334,7 @@ Scavenger::Scavenger(Heap* heap,
max_semi_capacity_in_words_(max_semi_capacity_in_words),
object_alignment_(object_alignment),
scavenging_(false),
+ delayed_weak_properties_(NULL),
gc_time_micros_(0),
collections_(0),
external_size_(0) {
@@ -601,12 +539,9 @@ void Scavenger::IterateWeakRoots(Isolate* isolate, HandleVisitor* visitor) {
void Scavenger::ProcessToSpace(ScavengerVisitor* visitor) {
- GrowableArray<RawObject*>* delayed_weak_stack = visitor->DelayedWeakStack();
-
// Iterate until all work has been drained.
while ((resolved_top_ < top_) ||
- PromotedStackHasMore() ||
- !delayed_weak_stack->is_empty()) {
+ PromotedStackHasMore()) {
while (resolved_top_ < top_) {
RawObject* raw_obj = RawObject::FromAddr(resolved_top_);
intptr_t class_id = raw_obj->GetClassId();
@@ -618,6 +553,8 @@ void Scavenger::ProcessToSpace(ScavengerVisitor* visitor) {
}
}
{
+ // Visit all the promoted objects and update/scavenge their internal
+ // pointers. Potentially this adds more objects to the to space.
while (PromotedStackHasMore()) {
RawObject* raw_object = RawObject::FromAddr(PopFromPromotedStack());
// Resolve or copy all objects referred to by the current object. This
@@ -629,10 +566,36 @@ void Scavenger::ProcessToSpace(ScavengerVisitor* visitor) {
}
visitor->VisitingOldObject(NULL);
}
- while (!delayed_weak_stack->is_empty()) {
- // Pop the delayed weak object from the stack and visit its pointers.
- RawObject* weak_property = delayed_weak_stack->RemoveLast();
- weak_property->VisitPointers(visitor);
+ {
+ // Finished this round of scavenging. Process the pending weak properties
+ // for which the keys have become reachable. Potentially this adds more
+ // objects to the to space.
+ RawWeakProperty* cur_weak = delayed_weak_properties_;
+ delayed_weak_properties_ = NULL;
+ while (cur_weak != NULL) {
+ uword next_weak = cur_weak->ptr()->next_;
+ // Promoted weak properties are not enqueued. So we can guarantee that
+ // we do not need to think about store barriers here.
+ ASSERT(cur_weak->IsNewObject());
+ RawObject* raw_key = cur_weak->ptr()->key_;
+ ASSERT(raw_key->IsHeapObject());
+ // Key still points into from space even if the object has been
+ // promoted to old space by now. The key will be updated accordingly
+ // below when VisitPointers is run.
+ ASSERT(raw_key->IsNewObject());
+ uword raw_addr = RawObject::ToAddr(raw_key);
+ ASSERT(visitor->from_->Contains(raw_addr));
+ uword header = *reinterpret_cast<uword*>(raw_addr);
+ // Reset the next pointer in the weak property.
+ cur_weak->ptr()->next_ = 0;
+ if (IsForwarding(header)) {
+ cur_weak->VisitPointers(visitor);
+ } else {
+ EnqueueWeakProperty(cur_weak);
+ }
+ // Advance to next weak property in the queue.
+ cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak);
+ }
}
}
}
@@ -665,6 +628,21 @@ void Scavenger::UpdateMaxHeapUsage() {
}
+void Scavenger::EnqueueWeakProperty(RawWeakProperty* raw_weak) {
+ ASSERT(raw_weak->IsHeapObject());
+ ASSERT(raw_weak->IsNewObject());
+ ASSERT(raw_weak->IsWeakProperty());
+ DEBUG_ONLY(
+ uword raw_addr = RawObject::ToAddr(raw_weak);
+ uword header = *reinterpret_cast<uword*>(raw_addr);
+ ASSERT(!IsForwarding(header));
+ )
+ ASSERT(raw_weak->ptr()->next_ == 0);
+ raw_weak->ptr()->next_ = reinterpret_cast<uword>(delayed_weak_properties_);
+ delayed_weak_properties_ = raw_weak;
+}
+
+
uword Scavenger::ProcessWeakProperty(RawWeakProperty* raw_weak,
ScavengerVisitor* visitor) {
// The fate of the weak property is determined by its key.
@@ -673,8 +651,8 @@ uword Scavenger::ProcessWeakProperty(RawWeakProperty* raw_weak,
uword raw_addr = RawObject::ToAddr(raw_key);
uword header = *reinterpret_cast<uword*>(raw_addr);
if (!IsForwarding(header)) {
- // Key is white. Delay the weak property.
- visitor->DelayWeakProperty(raw_weak);
+ // Key is white. Enqueue the weak property.
+ EnqueueWeakProperty(raw_weak);
return raw_weak->Size();
}
}
@@ -683,7 +661,8 @@ uword Scavenger::ProcessWeakProperty(RawWeakProperty* raw_weak,
}
-void Scavenger::ProcessWeakTables() {
+void Scavenger::ProcessWeakReferences() {
+ // Rehash the weak tables now that we know which objects survive this cycle.
for (int sel = 0;
sel < Heap::kNumWeakSelectors;
sel++) {
@@ -713,6 +692,32 @@ void Scavenger::ProcessWeakTables() {
// table above.
delete table;
}
+
+ // The queued weak properties at this point do not refer to reachable keys,
+ // so we clear their key and value fields.
+ {
+ RawWeakProperty* cur_weak = delayed_weak_properties_;
+ delayed_weak_properties_ = NULL;
+ while (cur_weak != NULL) {
+ uword next_weak = cur_weak->ptr()->next_;
+ // Reset the next pointer in the weak property.
+ cur_weak->ptr()->next_ = 0;
+
+ DEBUG_ONLY(
+ RawObject* raw_key = cur_weak->ptr()->key_;
+ uword raw_addr = RawObject::ToAddr(raw_key);
+ uword header = *reinterpret_cast<uword*>(raw_addr);
+ ASSERT(!IsForwarding(header));
+ ASSERT(raw_key->IsHeapObject());
+ ASSERT(raw_key->IsNewObject()); // Key still points into from space.
+ )
+
+ WeakProperty::Clear(cur_weak);
+
+ // Advance to next weak property in the queue.
+ cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak);
+ }
+ }
}
@@ -801,8 +806,7 @@ void Scavenger::Scavenge(bool invoke_api_callbacks) {
int64_t middle = OS::GetCurrentTimeMicros();
ScavengerWeakVisitor weak_visitor(this);
IterateWeakRoots(isolate, &weak_visitor);
- visitor.Finalize();
- ProcessWeakTables();
+ ProcessWeakReferences();
page_space->ReleaseDataLock();
// Scavenge finished. Run accounting.
« runtime/vm/raw_object.h ('K') | « runtime/vm/scavenger.h ('k') | runtime/vm/snapshot.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698