Index: runtime/vm/scavenger.cc |
diff --git a/runtime/vm/scavenger.cc b/runtime/vm/scavenger.cc |
index a9bd583e127b457963cfff8719f8cdbb9addb4e8..814252b1155017fff16d6b5bdd24d56fe7fcf90d 100644 |
--- a/runtime/vm/scavenger.cc |
+++ b/runtime/vm/scavenger.cc |
@@ -13,6 +13,33 @@ |
namespace dart { |
+enum { |
+ kForwardingMask = 3, |
+ kNotForwarded = 1, // Tagged pointer. |
+ kForwarded = 3, // Tagged pointer and forwarding bit set. |
+}; |
+ |
+ |
+static inline bool IsForwarding(uword header) { |
+ uword bits = header & kForwardingMask; |
+ ASSERT((bits == kNotForwarded) || (bits == kForwarded)); |
+ return bits == kForwarded; |
+} |
+ |
+ |
+static inline uword ForwardedAddr(uword header) { |
+ ASSERT(IsForwarding(header)); |
+ return header & ~kForwardingMask; |
+} |
+ |
+ |
+static inline void ForwardTo(uword orignal, uword target) { |
+ // Make sure forwarding can be encoded. |
+ ASSERT((target & kForwardingMask) == 0); |
+ *reinterpret_cast<uword*>(orignal) = target | kForwarded; |
+} |
+ |
+ |
class ScavengerVisitor : public ObjectPointerVisitor { |
public: |
explicit ScavengerVisitor(Scavenger* scavenger) |
@@ -27,29 +54,6 @@ class ScavengerVisitor : public ObjectPointerVisitor { |
} |
private: |
- enum { |
- kForwardingMask = 3, |
- kNotForwarded = 1, // Tagged pointer. |
- kForwarded = 3, // Tagged pointer and forwarding bit set. |
- }; |
- |
- static inline bool IsForwarding(uword header) { |
- uword bits = header & kForwardingMask; |
- ASSERT((bits == kNotForwarded) || (bits == kForwarded)); |
- return bits == kForwarded; |
- } |
- |
- static inline uword ForwardedAddr(uword header) { |
- ASSERT(IsForwarding(header)); |
- return header & ~kForwardingMask; |
- } |
- |
- static inline void ForwardTo(uword orignal, uword target) { |
- // Make sure forwarding can be encoded. |
- ASSERT((target & kForwardingMask) == 0); |
- *reinterpret_cast<uword*>(orignal) = target | kForwarded; |
- } |
- |
void UpdateStoreBuffer(RawObject** p, RawObject* obj) { |
// TODO(iposva): Implement store buffers. |
} |
@@ -105,6 +109,36 @@ class ScavengerVisitor : public ObjectPointerVisitor { |
Scavenger* scavenger_; |
Heap* heap_; |
Heap* vm_heap_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ScavengerVisitor); |
+}; |
+ |
+ |
+class ScavengerWeakVisitor : public ObjectPointerVisitor { |
+ public: |
+ explicit ScavengerWeakVisitor(Scavenger* scavenger) : scavenger_(scavenger) { |
+ } |
+ |
+ void VisitPointers(RawObject** first, RawObject** last) { |
+ for (RawObject** current = first; current <= last; current++) { |
+ RawObject* raw_obj = *current; |
+ ASSERT(raw_obj->IsHeapObject()); |
+ uword raw_addr = RawObject::ToAddr(raw_obj); |
+ if (scavenger_->from_->Contains(raw_addr)) { |
+ uword header = *reinterpret_cast<uword*>(raw_addr); |
+ if (IsForwarding(header)) { |
+ *current = RawObject::FromAddr(ForwardedAddr(header)); |
+ } else { |
+ *current = Object::null(); |
+ } |
+ } |
+ } |
+ } |
+ |
+ private: |
+ Scavenger* scavenger_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ScavengerWeakVisitor); |
}; |
@@ -167,12 +201,18 @@ void Scavenger::Epilogue() { |
void Scavenger::IterateRoots(Isolate* isolate, ObjectPointerVisitor* visitor) { |
- isolate->VisitObjectPointers(visitor, |
- StackFrameIterator::kDontValidateFrames); |
+ isolate->VisitStrongObjectPointers(visitor, |
+ StackFrameIterator::kDontValidateFrames); |
heap_->IterateOldPointers(visitor); |
} |
+void Scavenger::IterateWeakRoots(Isolate* isolate, |
+ ObjectPointerVisitor* visitor) { |
+ isolate->VisitWeakObjectPointers(visitor); |
+} |
+ |
+ |
void Scavenger::ProcessToSpace(ObjectPointerVisitor* visitor) { |
uword resolved_top = FirstObjectStart(); |
// Iterate until all work has been drained. |
@@ -206,6 +246,8 @@ void Scavenger::Scavenge() { |
Prologue(); |
IterateRoots(isolate, &visitor); |
ProcessToSpace(&visitor); |
+ ScavengerWeakVisitor weak_visitor(this); |
+ IterateWeakRoots(isolate, &weak_visitor); |
Epilogue(); |
timer.Stop(); |
if (FLAG_verbose_gc) { |