Index: runtime/vm/dart_api_state.h |
=================================================================== |
--- runtime/vm/dart_api_state.h (revision 33249) |
+++ runtime/vm/dart_api_state.h (working copy) |
@@ -151,8 +151,14 @@ |
void set_raw(const LocalHandle& ref) { raw_ = ref.raw(); } |
void set_raw(const Object& object) { raw_ = object.raw(); } |
RawObject** raw_addr() { return &raw_; } |
+ Dart_PersistentHandle apiHandle() { |
+ return reinterpret_cast<Dart_PersistentHandle>(this); |
+ } |
+ |
static intptr_t raw_offset() { return OFFSET_OF(PersistentHandle, raw_); } |
+ static PersistentHandle* Cast(Dart_PersistentHandle handle); |
+ |
private: |
friend class PersistentHandles; |
@@ -197,19 +203,43 @@ |
void set_callback(Dart_WeakPersistentHandleFinalizer callback) { |
callback_ = callback; |
} |
+ Dart_WeakPersistentHandle apiPrologueHandle() { |
+ uword addr = reinterpret_cast<uword>(this); |
+ return reinterpret_cast<Dart_WeakPersistentHandle>( |
+ addr | kPrologueWeakPersistentTag); |
+ } |
+ Dart_WeakPersistentHandle apiHandle() { |
+ return reinterpret_cast<Dart_WeakPersistentHandle>(this); |
+ } |
- static void Finalize(FinalizablePersistentHandle* handle) { |
+ static bool IsPrologueWeakPersistentHandle(Dart_WeakPersistentHandle handle) { |
+ uword addr = reinterpret_cast<uword>(handle); |
+ return (addr & kWeakPersistentTagMask) == kPrologueWeakPersistentTag; |
+ } |
+ static FinalizablePersistentHandle* Cast(Dart_WeakPersistentHandle handle); |
+ static void Finalize(FinalizablePersistentHandle* handle, |
+ bool is_prologue_weak) { |
Dart_WeakPersistentHandleFinalizer callback = handle->callback(); |
if (callback != NULL) { |
void* peer = handle->peer(); |
handle->Clear(); |
- (*callback)(reinterpret_cast<Dart_WeakPersistentHandle>(handle), peer); |
+ Dart_WeakPersistentHandle object = is_prologue_weak ? |
+ handle->apiPrologueHandle() : |
+ handle->apiHandle(); |
+ (*callback)(object, peer); |
} else { |
handle->Clear(); |
} |
} |
private: |
+ enum { |
+ kWeakPersistentTag = 0, |
+ kPrologueWeakPersistentTag = 1, |
+ kWeakPersistentTagSize = 1, |
+ kWeakPersistentTagMask = 1, |
+ }; |
+ |
friend class FinalizablePersistentHandles; |
FinalizablePersistentHandle() : raw_(NULL), peer_(NULL), callback_(NULL) { } |
@@ -403,7 +433,7 @@ |
: Handles<kFinalizablePersistentHandleSizeInWords, |
kFinalizablePersistentHandlesPerChunk, |
kOffsetOfRawPtrInFinalizablePersistentHandle>(), |
- free_list_(NULL) { } |
+ free_list_(NULL) { } |
~FinalizablePersistentHandles() { |
free_list_ = NULL; |
} |
@@ -413,10 +443,11 @@ |
void set_free_list(FinalizablePersistentHandle* value) { free_list_ = value; } |
// Visit all handles stored in the various handle blocks. |
- void VisitHandles(HandleVisitor* visitor) { |
+ void VisitHandles(HandleVisitor* visitor, bool is_prologue_weak) { |
Handles<kFinalizablePersistentHandleSizeInWords, |
kFinalizablePersistentHandlesPerChunk, |
- kOffsetOfRawPtrInFinalizablePersistentHandle>::Visit(visitor); |
+ kOffsetOfRawPtrInFinalizablePersistentHandle>::Visit( |
+ visitor, is_prologue_weak); |
} |
// Visit all object pointers stored in the various handles. |
@@ -479,16 +510,18 @@ |
RawObject** get_key(intptr_t i) { |
ASSERT(i >= 0); |
ASSERT(i < num_keys_); |
- return (reinterpret_cast<FinalizablePersistentHandle*>(keys_[i]))-> |
- raw_addr(); |
+ FinalizablePersistentHandle* ref = |
+ FinalizablePersistentHandle::Cast(keys_[i]); |
+ return ref->raw_addr(); |
} |
intptr_t num_values() const { return num_values_; } |
RawObject** get_value(intptr_t i) { |
ASSERT(i >= 0); |
ASSERT(i < num_values_); |
- return (reinterpret_cast<FinalizablePersistentHandle*>(values_[i]))-> |
- raw_addr(); |
+ FinalizablePersistentHandle* ref = |
+ FinalizablePersistentHandle::Cast(values_[i]); |
+ return ref->raw_addr(); |
} |
static WeakReferenceSet* Pop(WeakReferenceSet** queue) { |
@@ -652,9 +685,9 @@ |
void VisitWeakHandles(HandleVisitor* visitor, |
bool visit_prologue_weak_handles) { |
- weak_persistent_handles().VisitHandles(visitor); |
+ weak_persistent_handles().VisitHandles(visitor, false); |
if (visit_prologue_weak_handles) { |
- prologue_weak_persistent_handles().VisitHandles(visitor); |
+ prologue_weak_persistent_handles().VisitHandles(visitor, true); |
} |
} |