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

Unified 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, 9 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
« no previous file with comments | « runtime/vm/scavenger.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/scavenger.cc
diff --git a/runtime/vm/scavenger.cc b/runtime/vm/scavenger.cc
index 29bb59b8aafe037466e61f1d59fbe0317a431172..148134ab269c7b5879b101bf7950ecd2561995d1 100644
--- a/runtime/vm/scavenger.cc
+++ b/runtime/vm/scavenger.cc
@@ -240,6 +240,80 @@ void Scavenger::IterateRoots(Isolate* isolate,
}
+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
+ RawObject* raw_obj = *p;
+ 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
+ return false;
+ }
+ 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
+ return false;
+ }
+ uword raw_addr = RawObject::ToAddr(raw_obj);
+ if (!from_->Contains(raw_addr)) {
+ return false;
+ }
+ uword header = *reinterpret_cast<uword*>(raw_addr);
+ if (IsForwarding(header)) {
+ uword new_addr = ForwardedAddr(header);
+ *p = RawObject::FromAddr(new_addr);
+ return false;
+ }
+ return true;
+}
+
+
+void Scavenger::IterateWeakReferences(Isolate* isolate,
+ ObjectPointerVisitor* visitor) {
+ ApiState* state = isolate->api_state();
+ ASSERT(state != NULL);
+ while (true) {
+ WeakReference* queue = state->delayed_weak_references();
+ if (queue == NULL) {
+ // The delay queue is empty therefore no clean-up is required.
+ return;
+ }
+ state->set_delayed_weak_references(NULL);
+ while (queue != NULL) {
+ WeakReference* reference = WeakReference::Pop(&queue);
+ ASSERT(reference != NULL);
+ bool is_unreachable = true;
+ // Test each key object for reachability. If a key object is
+ // reachable, all value objects should be marked.
+ for (intptr_t k = 0; k < reference->num_keys(); ++k) {
+ if (!IsUnreachable(reference->get_key(k))) {
+ for (intptr_t v = 0; v < reference->num_values(); ++v) {
+ visitor->VisitPointer(reference->get_value(v));
+ }
+ is_unreachable = false;
+ delete reference;
+ break;
+ }
+ }
+ // If all key objects are unreachable put the reference on a
+ // delay queue. This reference will be revisited if another
+ // reference is marked.
+ if (is_unreachable) {
+ state->DelayWeakReference(reference);
+ }
+ }
+ if ((FirstObjectStart() < top_) || PromotedStackHasMore()) {
+ ProcessToSpace(visitor);
+ } else {
+ // Break out of the loop if there has been no forward process.
+ break;
+ }
+ }
+ // Deallocate any unmarked references on the delay queue.
+ if (state->delayed_weak_references() != NULL) {
+ WeakReference* queue = state->delayed_weak_references();
+ state->set_delayed_weak_references(NULL);
+ while (queue != NULL) {
+ delete WeakReference::Pop(&queue);
+ }
+ }
+}
+
+
void Scavenger::IterateWeakRoots(Isolate* isolate,
HandleVisitor* visitor,
bool visit_prologue_weak_persistent_handles) {
@@ -303,6 +377,7 @@ void Scavenger::Scavenge(bool invoke_api_callbacks) {
Prologue(isolate, invoke_api_callbacks);
IterateRoots(isolate, &visitor, !invoke_api_callbacks);
ProcessToSpace(&visitor);
+ IterateWeakReferences(isolate, &visitor);
ScavengerWeakVisitor weak_visitor(this);
IterateWeakRoots(isolate, &weak_visitor, invoke_api_callbacks);
Epilogue(isolate, invoke_api_callbacks);
« 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