| Index: runtime/vm/dart_api_state.h
|
| diff --git a/runtime/vm/dart_api_state.h b/runtime/vm/dart_api_state.h
|
| index b510377352cdc294d017c4922a86bd2e052e0c5f..b5a3d38b9b98041700c1d8678d1ee437a0bb609a 100644
|
| --- a/runtime/vm/dart_api_state.h
|
| +++ b/runtime/vm/dart_api_state.h
|
| @@ -15,8 +15,9 @@
|
| #include "vm/handles.h"
|
| #include "vm/object.h"
|
| #include "vm/os.h"
|
| -#include "vm/raw_object.h"
|
| #include "vm/os_thread.h"
|
| +#include "vm/raw_object.h"
|
| +#include "vm/thread_pool.h"
|
| #include "vm/visitor.h"
|
| #include "vm/weak_table.h"
|
|
|
| @@ -24,6 +25,25 @@
|
|
|
| namespace dart {
|
|
|
| +class FinalizablePersistentHandle;
|
| +typedef MallocGrowableArray<FinalizablePersistentHandle*> FinalizationQueue;
|
| +
|
| +
|
| +class BackgroundFinalizer : public ThreadPool::Task {
|
| + public:
|
| + BackgroundFinalizer(Isolate* isolate, FinalizationQueue* queue);
|
| + virtual ~BackgroundFinalizer() { }
|
| +
|
| + void Run();
|
| +
|
| + private:
|
| + Isolate* isolate_;
|
| + FinalizationQueue* queue_;
|
| +
|
| + DISALLOW_IMPLICIT_CONSTRUCTORS(BackgroundFinalizer);
|
| +};
|
| +
|
| +
|
| // Implementation of Zone support for very fast allocation of small chunks
|
| // of memory. The chunks cannot be deallocated individually, but instead
|
| // zones support deallocating all chunks in one fast operation when the
|
| @@ -227,9 +247,14 @@ class FinalizablePersistentHandle {
|
| }
|
|
|
| // Called when the referent becomes unreachable.
|
| - void UpdateUnreachable(Isolate* isolate) {
|
| + void UpdateUnreachable(Isolate* isolate, FinalizationQueue* queue) {
|
| EnsureFreeExternal(isolate);
|
| - Finalize(isolate, this);
|
| + if (queue == NULL) {
|
| + Finalize(isolate, this);
|
| + } else {
|
| + MarkForFinalization();
|
| + queue->Add(this);
|
| + }
|
| }
|
|
|
| // Called when the referent has moved, potentially between generations.
|
| @@ -299,6 +324,11 @@ class FinalizablePersistentHandle {
|
| callback_ = NULL;
|
| }
|
|
|
| + void MarkForFinalization() {
|
| + raw_ = Object::null();
|
| + ASSERT(callback_ != NULL);
|
| + }
|
| +
|
| 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(); }
|
| @@ -333,10 +363,13 @@ class FinalizablePersistentHandle {
|
| Heap::kNew : Heap::kOld;
|
| }
|
|
|
| + friend class BackgroundFinalizer;
|
| +
|
| RawObject* raw_;
|
| void* peer_;
|
| uword external_data_;
|
| Dart_WeakPersistentHandleFinalizer callback_;
|
| +
|
| DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods.
|
| DISALLOW_COPY_AND_ASSIGN(FinalizablePersistentHandle);
|
| };
|
| @@ -501,9 +534,11 @@ class FinalizablePersistentHandles
|
| : Handles<kFinalizablePersistentHandleSizeInWords,
|
| kFinalizablePersistentHandlesPerChunk,
|
| kOffsetOfRawPtrInFinalizablePersistentHandle>(),
|
| - free_list_(NULL) { }
|
| + free_list_(NULL), mutex_(new Mutex()) { }
|
| ~FinalizablePersistentHandles() {
|
| free_list_ = NULL;
|
| + delete mutex_;
|
| + mutex_ = NULL;
|
| }
|
|
|
| // Accessors.
|
| @@ -530,25 +565,31 @@ class FinalizablePersistentHandles
|
| // by calling FreeHandle.
|
| FinalizablePersistentHandle* AllocateHandle() {
|
| FinalizablePersistentHandle* handle;
|
| - if (free_list_ != NULL) {
|
| - handle = free_list_;
|
| - free_list_ = handle->Next();
|
| - handle->set_raw(Object::null());
|
| - } else {
|
| - handle = reinterpret_cast<FinalizablePersistentHandle*>(
|
| - AllocateScopedHandle());
|
| - handle->Clear();
|
| + {
|
| + MutexLocker ml(mutex_);
|
| + if (free_list_ != NULL) {
|
| + handle = free_list_;
|
| + free_list_ = handle->Next();
|
| + handle->set_raw(Object::null());
|
| + return handle;
|
| + }
|
| }
|
| +
|
| + handle = reinterpret_cast<FinalizablePersistentHandle*>(
|
| + AllocateScopedHandle());
|
| + handle->Clear();
|
| return handle;
|
| }
|
|
|
| void FreeHandle(FinalizablePersistentHandle* handle) {
|
| + MutexLocker ml(mutex_);
|
| handle->FreeHandle(free_list());
|
| set_free_list(handle);
|
| }
|
|
|
| // Validate if passed in handle is a Persistent Handle.
|
| bool IsValidHandle(Dart_WeakPersistentHandle object) const {
|
| + MutexLocker ml(mutex_);
|
| return IsValidScopedHandle(reinterpret_cast<uword>(object));
|
| }
|
|
|
| @@ -559,6 +600,7 @@ class FinalizablePersistentHandles
|
|
|
| private:
|
| FinalizablePersistentHandle* free_list_;
|
| + Mutex* mutex_;
|
| DISALLOW_COPY_AND_ASSIGN(FinalizablePersistentHandles);
|
| };
|
|
|
|
|