Index: runtime/vm/dart_api_state.h |
diff --git a/runtime/vm/dart_api_state.h b/runtime/vm/dart_api_state.h |
index 81f65d9a75e3af2e80269e4aad03ad9491242892..04f34d50c698e11219b96db069ab104fc394a4a1 100644 |
--- a/runtime/vm/dart_api_state.h |
+++ b/runtime/vm/dart_api_state.h |
@@ -81,11 +81,36 @@ void ProtectedHandleCallback(); |
// dart API. |
class PersistentHandle { |
public: |
- enum { |
+ enum Kind { |
StrongReference = 0, |
WeakReference, |
}; |
+ // Adaptor for visiting handles with matching reference kind. |
+ class Visitor : public HandleVisitor { |
+ public: |
+ explicit Visitor(ObjectPointerVisitor* visitor, Kind kind) { |
Ivan Posva
2011/12/19 22:41:36
explicit not needed here.
cshapiro
2011/12/20 00:58:57
Right, done.
|
+ ASSERT(visitor != NULL); |
+ kind_ = kind; |
+ object_pointer_visitor_ = visitor; |
+ } |
+ |
+ void Visit(uword* addr) { |
+ PersistentHandle* handle = reinterpret_cast<PersistentHandle*>(addr); |
+ if (handle->kind() == kind_) { |
+ object_pointer_visitor_->VisitPointer(&handle->raw_); |
+ } |
+ } |
+ |
+ ~Visitor() {} |
+ |
+ private: |
+ Kind kind_; |
+ ObjectPointerVisitor* object_pointer_visitor_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(Visitor); |
+ }; |
+ |
// Accessors. |
RawObject* raw() const { return raw_; } |
void set_raw(const LocalHandle& ref) { raw_ = ref.raw(); } |
@@ -93,8 +118,8 @@ class PersistentHandle { |
static intptr_t raw_offset() { return OFFSET_OF(PersistentHandle, raw_); } |
void* callback() const { return callback_; } |
void set_callback(void* value) { callback_ = value; } |
- intptr_t type() const { return type_; } |
- void set_type(intptr_t value) { type_ = value; } |
+ Kind kind() const { return kind_; } |
+ void set_kind(Kind value) { kind_ = value; } |
// Some handles are protected from being freed via the external dart api. |
bool IsProtected() { |
@@ -122,7 +147,8 @@ class PersistentHandle { |
RawObject* raw_; |
void* callback_; |
- intptr_t type_; |
+ void* peer_; |
+ Kind kind_; |
DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods. |
DISALLOW_COPY_AND_ASSIGN(PersistentHandle); |
}; |
@@ -199,6 +225,24 @@ class PersistentHandles : Handles<kPersistentHandleSizeInWords, |
kOffsetOfRawPtrInPersistentHandle>::VisitObjectPointers(visitor); |
} |
+ // Visits the object pointers in strong persistent handles. |
+ void VisitStrongObjectPointers(ObjectPointerVisitor* visitor) { |
+ PersistentHandle::Visitor strong_visitor(visitor, |
+ PersistentHandle::StrongReference); |
+ Handles<kPersistentHandleSizeInWords, |
+ kPersistentHandlesPerChunk, |
+ kOffsetOfRawPtrInPersistentHandle>::Visit(&strong_visitor); |
+ } |
+ |
+ // Visits the object pointers in weak persistent handles. |
+ void VisitWeakObjectPointers(ObjectPointerVisitor* visitor) { |
+ PersistentHandle::Visitor weak_visitor(visitor, |
+ PersistentHandle::WeakReference); |
+ Handles<kPersistentHandleSizeInWords, |
+ kPersistentHandlesPerChunk, |
+ kOffsetOfRawPtrInPersistentHandle>::Visit(&weak_visitor); |
+ } |
+ |
// Allocates a persistent handle, these have to be destroyed explicitly |
// by calling FreeHandle. |
PersistentHandle* AllocateHandle() { |
@@ -210,7 +254,7 @@ class PersistentHandles : Handles<kPersistentHandleSizeInWords, |
handle = reinterpret_cast<PersistentHandle*>(AllocateScopedHandle()); |
} |
handle->set_callback(NULL); |
- handle->set_type(PersistentHandle::StrongReference); |
+ handle->set_kind(PersistentHandle::StrongReference); |
return handle; |
} |
@@ -301,13 +345,23 @@ class ApiState { |
} |
} |
- void VisitObjectPointers(ObjectPointerVisitor* visitor) { |
+ void VisitStrongObjectPointers(ObjectPointerVisitor* visitor) { |
ApiLocalScope* scope = top_scope_; |
while (scope != NULL) { |
scope->local_handles()->VisitObjectPointers(visitor); |
scope = scope->previous(); |
} |
- persistent_handles().VisitObjectPointers(visitor); |
+ |
+ persistent_handles().VisitStrongObjectPointers(visitor); |
+ } |
+ |
+ void VisitWeakObjectPointers(ObjectPointerVisitor* visitor) { |
+ persistent_handles().VisitWeakObjectPointers(visitor); |
+ } |
+ |
+ void VisitObjectPointers(ObjectPointerVisitor* visitor) { |
+ VisitStrongObjectPointers(visitor); |
+ VisitWeakObjectPointers(visitor); |
} |
bool IsValidLocalHandle(Dart_Handle object) const { |