Index: runtime/vm/dart_api_state.h |
=================================================================== |
--- runtime/vm/dart_api_state.h (revision 35211) |
+++ runtime/vm/dart_api_state.h (working copy) |
@@ -558,63 +558,6 @@ |
}; |
-class WeakReferenceSet { |
- public: |
- WeakReferenceSet(Dart_WeakPersistentHandle* keys, intptr_t keys_length, |
- Dart_WeakPersistentHandle* values, intptr_t values_length) |
- : next_(NULL), |
- keys_(keys), num_keys_(keys_length), |
- values_(values), num_values_(values_length) { |
- } |
- ~WeakReferenceSet() {} |
- |
- WeakReferenceSet* next() const { return next_; } |
- |
- intptr_t num_keys() const { return num_keys_; } |
- RawObject** get_key(intptr_t i) { |
- ASSERT(i >= 0); |
- ASSERT(i < num_keys_); |
- 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_); |
- FinalizablePersistentHandle* ref = |
- FinalizablePersistentHandle::Cast(values_[i]); |
- return ref->raw_addr(); |
- } |
- |
- static WeakReferenceSet* Pop(WeakReferenceSet** queue) { |
- ASSERT(queue != NULL); |
- WeakReferenceSet* head = *queue; |
- if (head != NULL) { |
- *queue = head->next(); |
- head->next_ = NULL; |
- } |
- return head; |
- } |
- |
- static void Push(WeakReferenceSet* reference_set, WeakReferenceSet** queue) { |
- ASSERT(reference_set != NULL); |
- ASSERT(queue != NULL); |
- reference_set->next_ = *queue; |
- *queue = reference_set; |
- } |
- |
- private: |
- WeakReferenceSet* next_; |
- Dart_WeakPersistentHandle* keys_; |
- intptr_t num_keys_; |
- Dart_WeakPersistentHandle* values_; |
- intptr_t num_values_; |
- DISALLOW_COPY_AND_ASSIGN(WeakReferenceSet); |
-}; |
- |
- |
// 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 { |
@@ -657,6 +600,55 @@ |
}; |
+class ApiNativeScope { |
+ public: |
+ ApiNativeScope() { |
+ // Currently no support for nesting native scopes. |
+ ASSERT(Current() == NULL); |
+ Thread::SetThreadLocal(Api::api_native_key_, reinterpret_cast<uword>(this)); |
+ } |
+ |
+ ~ApiNativeScope() { |
+ ASSERT(Current() == this); |
+ Thread::SetThreadLocal(Api::api_native_key_, 0); |
+ } |
+ |
+ static inline ApiNativeScope* Current() { |
+ return reinterpret_cast<ApiNativeScope*>( |
+ Thread::GetThreadLocal(Api::api_native_key_)); |
+ } |
+ |
+ Zone* zone() { return zone_.GetZone(); } |
+ |
+ private: |
+ ApiZone zone_; |
+}; |
+ |
+ |
+// Api growable arrays use a zone for allocation. The constructor |
+// picks the zone from the current isolate if in an isolate |
+// environment. When outside an isolate environment it picks the zone |
+// from the current native scope. |
+template<typename T> |
+class ApiGrowableArray : public BaseGrowableArray<T, ValueObject> { |
+ public: |
+ explicit ApiGrowableArray(int initial_capacity) |
+ : BaseGrowableArray<T, ValueObject>( |
+ initial_capacity, |
+ ApiNativeScope::Current()->zone()) {} |
+ ApiGrowableArray() |
+ : BaseGrowableArray<T, ValueObject>( |
+ ApiNativeScope::Current()->zone()) {} |
+ ApiGrowableArray(intptr_t initial_capacity, Zone* zone) |
+ : BaseGrowableArray<T, ValueObject>(initial_capacity, zone) {} |
+}; |
+ |
+ |
+// Forward declarations. |
+class WeakReferenceSetBuilder; |
+class WeakReferenceSet; |
+ |
+ |
// Implementation of the API State used in dart api for maintaining |
// local scopes, persistent handles etc. These are setup on a per isolate |
// basis and destroyed when the isolate is shutdown. |
@@ -823,10 +815,10 @@ |
return acquired_error_; |
} |
- void DelayWeakReferenceSet(WeakReferenceSet* reference_set) { |
- WeakReferenceSet::Push(reference_set, &delayed_weak_reference_sets_); |
- } |
+ WeakReferenceSetBuilder* NewWeakReferenceSetBuilder(); |
+ void DelayWeakReferenceSet(WeakReferenceSet* reference_set); |
+ |
private: |
PersistentHandles persistent_handles_; |
FinalizablePersistentHandles weak_persistent_handles_; |
@@ -845,45 +837,107 @@ |
}; |
-class ApiNativeScope { |
+class WeakReferenceSet { |
public: |
- ApiNativeScope() { |
- // Currently no support for nesting native scopes. |
- ASSERT(Current() == NULL); |
- Thread::SetThreadLocal(Api::api_native_key_, reinterpret_cast<uword>(this)); |
+ explicit WeakReferenceSet(Zone* zone) |
+ : next_(NULL), |
+ keys_(1, zone), |
+ values_(1, zone) { |
} |
+ ~WeakReferenceSet() {} |
- ~ApiNativeScope() { |
- ASSERT(Current() == this); |
- Thread::SetThreadLocal(Api::api_native_key_, 0); |
+ WeakReferenceSet* next() const { return next_; } |
+ |
+ intptr_t num_keys() const { return keys_.length(); } |
+ RawObject** get_key(intptr_t i) { |
+ ASSERT(i >= 0); |
+ ASSERT(i < num_keys()); |
+ FinalizablePersistentHandle* ref = |
+ FinalizablePersistentHandle::Cast(keys_[i]); |
+ return ref->raw_addr(); |
} |
- static inline ApiNativeScope* Current() { |
- return reinterpret_cast<ApiNativeScope*>( |
- Thread::GetThreadLocal(Api::api_native_key_)); |
+ intptr_t num_values() const { return values_.length(); } |
+ RawObject** get_value(intptr_t i) { |
+ ASSERT(i >= 0); |
+ ASSERT(i < num_values()); |
+ FinalizablePersistentHandle* ref = |
+ FinalizablePersistentHandle::Cast(values_[i]); |
+ return ref->raw_addr(); |
} |
- Zone* zone() { return zone_.GetZone(); } |
+ bool SingletonKeyEqualsValue() const { |
+ ASSERT((num_keys() == 1) && (num_values() == 1)); |
+ return (keys_[0] == values_[0]); |
+ } |
+ void Append(Dart_WeakPersistentHandle key, Dart_WeakPersistentHandle value) { |
+ keys_.Add(key); |
+ values_.Add(value); |
+ } |
+ |
+ void AppendKey(Dart_WeakPersistentHandle key) { |
+ keys_.Add(key); |
+ } |
+ |
+ void AppendValue(Dart_WeakPersistentHandle value) { |
+ values_.Add(value); |
+ } |
+ |
+ static WeakReferenceSet* Pop(WeakReferenceSet** queue) { |
+ ASSERT(queue != NULL); |
+ WeakReferenceSet* head = *queue; |
+ if (head != NULL) { |
+ *queue = head->next(); |
+ head->next_ = NULL; |
+ } |
+ return head; |
+ } |
+ |
+ static void Push(WeakReferenceSet* reference_set, WeakReferenceSet** queue) { |
+ ASSERT(reference_set != NULL); |
+ ASSERT(queue != NULL); |
+ reference_set->next_ = *queue; |
+ *queue = reference_set; |
+ } |
+ |
+ void* operator new(uword size, Zone* zone) { |
+ return reinterpret_cast<void*>(zone->AllocUnsafe(size)); |
+ } |
+ |
+ // Disallow explicit deallocation of WeakReferenceSet. |
+ void operator delete(void* pointer) { UNREACHABLE(); } |
+ |
private: |
- ApiZone zone_; |
+ WeakReferenceSet* next_; |
+ ApiGrowableArray<Dart_WeakPersistentHandle> keys_; |
+ ApiGrowableArray<Dart_WeakPersistentHandle> values_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(WeakReferenceSet); |
}; |
-// Api growable arrays use a zone for allocation. The constructor |
-// picks the zone from the current isolate if in an isolate |
-// environment. When outside an isolate environment it picks the zone |
-// from the current native scope. |
-template<typename T> |
-class ApiGrowableArray : public BaseGrowableArray<T, ValueObject> { |
+class WeakReferenceSetBuilder { |
public: |
- explicit ApiGrowableArray(int initial_capacity) |
- : BaseGrowableArray<T, ValueObject>( |
- initial_capacity, |
- ApiNativeScope::Current()->zone()) {} |
- ApiGrowableArray() |
- : BaseGrowableArray<T, ValueObject>( |
- ApiNativeScope::Current()->zone()) {} |
+ ApiState* api_state() const { |
+ return api_state_; |
+ } |
+ |
+ WeakReferenceSet* NewWeakReferenceSet() { |
+ return new (zone_) WeakReferenceSet(zone_); |
+ } |
+ |
+ private: |
+ explicit WeakReferenceSetBuilder(ApiState* api_state) |
+ : api_state_(api_state), |
+ zone_(api_state->top_scope()->zone()) { |
+ } |
+ |
+ ApiState* api_state_; |
+ Zone* zone_; |
+ |
+ friend class ApiState; |
+ DISALLOW_IMPLICIT_CONSTRUCTORS(WeakReferenceSetBuilder); |
}; |