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

Unified Diff: runtime/vm/dart_api_state.h

Issue 9148051: Provide API support for weak handles and post-mortem finalization. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: address review comments Created 8 years, 11 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/dart_api_impl_test.cc ('k') | runtime/vm/dart_api_state.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/dart_api_state.h
diff --git a/runtime/vm/dart_api_state.h b/runtime/vm/dart_api_state.h
index aea8010c62e19d3bf00aa362ecc6ca1c6c52fbe6..9badcc4fb9447228d1ad0ca6c148d081686b6f06 100644
--- a/runtime/vm/dart_api_state.h
+++ b/runtime/vm/dart_api_state.h
@@ -81,78 +81,89 @@ void ProtectedHandleCallback(void* peer);
// dart API.
class PersistentHandle {
public:
- enum Kind {
- StrongReference = 0,
- WeakReference,
- };
-
- // Adaptor for visiting handles with matching reference kind.
- class Visitor : public HandleVisitor {
- public:
- Visitor(ObjectPointerVisitor* visitor, Kind kind) {
- ASSERT(visitor != NULL);
- kind_ = kind;
- object_pointer_visitor_ = visitor;
- }
+ // Accessors.
+ RawObject* raw() const { return raw_; }
+ void set_raw(RawObject* ref) { raw_ = ref; }
+ void set_raw(const LocalHandle& ref) { raw_ = ref.raw(); }
+ void set_raw(const Object& object) { raw_ = object.raw(); }
+ static intptr_t raw_offset() { return OFFSET_OF(PersistentHandle, raw_); }
- void Visit(uword* addr) {
- PersistentHandle* handle = reinterpret_cast<PersistentHandle*>(addr);
- if (handle->kind() == kind_) {
- object_pointer_visitor_->VisitPointer(&handle->raw_);
- }
- }
+ private:
+ friend class PersistentHandles;
+
+ PersistentHandle() { }
+ ~PersistentHandle() { }
- ~Visitor() {}
+ // Overload the raw_ field as a next pointer when adding freed
+ // handles to the free list.
+ PersistentHandle* Next() {
+ return reinterpret_cast<PersistentHandle*>(raw_);
+ }
+ void SetNext(PersistentHandle* free_list) {
+ raw_ = reinterpret_cast<RawObject*>(free_list);
+ }
+ void FreeHandle(PersistentHandle* free_list) {
+ SetNext(free_list);
+ }
- private:
- Kind kind_;
- ObjectPointerVisitor* object_pointer_visitor_;
+ RawObject* raw_;
+ DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods.
+ DISALLOW_COPY_AND_ASSIGN(PersistentHandle);
+};
- DISALLOW_COPY_AND_ASSIGN(Visitor);
- };
+// Implementation of persistent handles which are handed out through the
+// dart API.
+class WeakPersistentHandle {
+ public:
// Accessors.
RawObject* raw() const { return raw_; }
+ void set_raw(RawObject* raw) { raw_ = raw; }
void set_raw(const LocalHandle& ref) { raw_ = ref.raw(); }
void set_raw(const Object& object) { raw_ = object.raw(); }
- static intptr_t raw_offset() { return OFFSET_OF(PersistentHandle, raw_); }
- Kind kind() const { return kind_; }
- void set_kind(Kind kind) { kind_ = kind; }
+ static intptr_t raw_offset() { return OFFSET_OF(WeakPersistentHandle, raw_); }
void* peer() const { return peer_; }
void set_peer(void* peer) { peer_ = peer; }
Dart_PeerFinalizer callback() const { return callback_; }
void set_callback(Dart_PeerFinalizer callback) { callback_ = callback; }
- // Some handles are protected from being freed via the external dart api.
- bool IsProtected() {
- return callback() == ProtectedHandleCallback;
+ void Finalize() {
+ if (callback_ != NULL) {
+ (*callback_)(peer_);
+ }
+ Clear();
}
private:
- friend class PersistentHandles;
+ friend class WeakPersistentHandles;
- PersistentHandle() : kind_(StrongReference), peer_(NULL), callback_(NULL) { }
- ~PersistentHandle() { }
+ WeakPersistentHandle() : raw_(NULL), peer_(NULL), callback_(NULL) { }
+ ~WeakPersistentHandle() { }
// Overload the callback_ field as a next pointer when adding freed
// handles to the free list.
- PersistentHandle* Next() {
- return reinterpret_cast<PersistentHandle*>(callback_);
+ WeakPersistentHandle* Next() {
+ return reinterpret_cast<WeakPersistentHandle*>(callback_);
}
- void SetNext(PersistentHandle* free_list) {
+ void SetNext(WeakPersistentHandle* free_list) {
callback_ = reinterpret_cast<Dart_PeerFinalizer>(free_list);
}
- void FreeHandle(PersistentHandle* free_list) {
+ void FreeHandle(WeakPersistentHandle* free_list) {
raw_ = NULL;
SetNext(free_list);
}
+ void Clear() {
+ raw_ = Object::null();
+ peer_ = NULL;
+ callback_ = NULL;
+ }
+
RawObject* raw_;
- Kind kind_;
void* peer_;
Dart_PeerFinalizer callback_;
DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods.
- DISALLOW_COPY_AND_ASSIGN(PersistentHandle);
+ DISALLOW_COPY_AND_ASSIGN(WeakPersistentHandle);
};
@@ -227,24 +238,6 @@ 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() {
@@ -255,8 +248,7 @@ class PersistentHandles : Handles<kPersistentHandleSizeInWords,
} else {
handle = reinterpret_cast<PersistentHandle*>(AllocateScopedHandle());
}
- handle->set_callback(NULL);
- handle->set_kind(PersistentHandle::StrongReference);
+ handle->set_raw(NULL);
return handle;
}
@@ -281,6 +273,69 @@ class PersistentHandles : Handles<kPersistentHandleSizeInWords,
};
+// Weak persistent handles repository structure.
+static const int kWeakPersistentHandleSizeInWords =
+ sizeof(WeakPersistentHandle) / kWordSize;
+static const int kWeakPersistentHandlesPerChunk = 64;
+static const int kOffsetOfRawPtrInWeakPersistentHandle = 0;
+class WeakPersistentHandles : Handles<kWeakPersistentHandleSizeInWords,
+ kWeakPersistentHandlesPerChunk,
+ kOffsetOfRawPtrInWeakPersistentHandle> {
+ public:
+ WeakPersistentHandles() : Handles<kWeakPersistentHandleSizeInWords,
+ kWeakPersistentHandlesPerChunk,
+ kOffsetOfRawPtrInWeakPersistentHandle>(),
+ free_list_(NULL) { }
+ ~WeakPersistentHandles() {
+ free_list_ = NULL;
+ }
+
+ // Accessors.
+ WeakPersistentHandle* free_list() const { return free_list_; }
+ void set_free_list(WeakPersistentHandle* value) { free_list_ = value; }
+
+ // Visit all handles stored in the various handle blocks.
+ void VisitWeakPersistentHandles(HandleVisitor* visitor) {
+ Handles<kWeakPersistentHandleSizeInWords,
+ kWeakPersistentHandlesPerChunk,
+ kOffsetOfRawPtrInWeakPersistentHandle>::Visit(visitor);
+ }
+
+ // Allocates a persistent handle, these have to be destroyed explicitly
+ // by calling FreeHandle.
+ WeakPersistentHandle* AllocateHandle() {
+ WeakPersistentHandle* handle;
+ if (free_list_ != NULL) {
+ handle = free_list_;
+ free_list_ = handle->Next();
+ } else {
+ handle = reinterpret_cast<WeakPersistentHandle*>(AllocateScopedHandle());
+ }
+ handle->set_callback(NULL);
+ return handle;
+ }
+
+ void FreeHandle(WeakPersistentHandle* handle) {
+ handle->FreeHandle(free_list());
+ set_free_list(handle);
+ }
+
+ // Validate if passed in handle is a Persistent Handle.
+ bool IsValidHandle(Dart_Handle object) const {
+ return IsValidScopedHandle(reinterpret_cast<uword>(object));
+ }
+
+ // Returns a count of active handles (used for testing purposes).
+ int CountHandles() const {
+ return CountScopedHandles();
+ }
+
+ private:
+ WeakPersistentHandle* free_list_;
+ DISALLOW_COPY_AND_ASSIGN(WeakPersistentHandles);
+};
+
+
// Structure used for the implementation of local scopes used in dart_api.
// These local scopes manage handles and memory allocated in the scope.
class ApiLocalScope {
@@ -338,6 +393,9 @@ class ApiState {
ApiLocalScope* top_scope() const { return top_scope_; }
void set_top_scope(ApiLocalScope* value) { top_scope_ = value; }
PersistentHandles& persistent_handles() { return persistent_handles_; }
+ WeakPersistentHandles& weak_persistent_handles() {
+ return weak_persistent_handles_;
+ }
void UnwindScopes(uword sp) {
while (top_scope_ != NULL && top_scope_->stack_marker() < sp) {
@@ -347,23 +405,17 @@ class ApiState {
}
}
- void VisitStrongObjectPointers(ObjectPointerVisitor* visitor) {
+ void VisitObjectPointers(ObjectPointerVisitor* visitor) {
ApiLocalScope* scope = top_scope_;
while (scope != NULL) {
scope->local_handles()->VisitObjectPointers(visitor);
scope = scope->previous();
}
-
- persistent_handles().VisitStrongObjectPointers(visitor);
+ persistent_handles().VisitObjectPointers(visitor);
}
- void VisitWeakObjectPointers(ObjectPointerVisitor* visitor) {
- persistent_handles().VisitWeakObjectPointers(visitor);
- }
-
- void VisitObjectPointers(ObjectPointerVisitor* visitor) {
- VisitStrongObjectPointers(visitor);
- VisitWeakObjectPointers(visitor);
+ void VisitWeakHandles(HandleVisitor* visitor) {
+ weak_persistent_handles().VisitWeakPersistentHandles(visitor);
}
bool IsValidLocalHandle(Dart_Handle object) const {
@@ -376,10 +428,20 @@ class ApiState {
}
return false;
}
+
bool IsValidPersistentHandle(Dart_Handle object) const {
return persistent_handles_.IsValidHandle(object);
}
+ bool IsValidWeakPersistentHandle(Dart_Handle object) const {
+ return weak_persistent_handles_.IsValidHandle(object);
+ }
+
+ bool IsProtectedHandle(PersistentHandle* object) const {
+ if (object == NULL) return false;
+ return object == null_ || object == true_ || object == false_;
+ }
+
int CountLocalHandles() const {
int total = 0;
ApiLocalScope* scope = top_scope_;
@@ -408,7 +470,6 @@ class ApiState {
Object& null_object = Object::Handle();
null_ = persistent_handles().AllocateHandle();
null_->set_raw(null_object);
- null_->set_callback(ProtectedHandleCallback);
}
return null_;
}
@@ -419,7 +480,6 @@ class ApiState {
const Object& true_object = Object::Handle(Bool::True());
true_ = persistent_handles().AllocateHandle();
true_->set_raw(true_object);
- true_->set_callback(ProtectedHandleCallback);
}
return true_;
}
@@ -430,13 +490,13 @@ class ApiState {
const Object& false_object = Object::Handle(Bool::False());
false_ = persistent_handles().AllocateHandle();
false_->set_raw(false_object);
- false_->set_callback(ProtectedHandleCallback);
}
return false_;
}
private:
PersistentHandles persistent_handles_;
+ WeakPersistentHandles weak_persistent_handles_;
ApiLocalScope* top_scope_;
// Persistent handles to important objects.
« no previous file with comments | « runtime/vm/dart_api_impl_test.cc ('k') | runtime/vm/dart_api_state.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698