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

Side by Side Diff: runtime/vm/dart_api_state.h

Issue 8984006: Implement weak persistent handles in the Dart API. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address review comments Created 9 years 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #ifndef VM_DART_API_STATE_H_ 5 #ifndef VM_DART_API_STATE_H_
6 #define VM_DART_API_STATE_H_ 6 #define VM_DART_API_STATE_H_
7 7
8 #include "include/dart_api.h" 8 #include "include/dart_api.h"
9 9
10 #include "vm/dart_api_impl.h" 10 #include "vm/dart_api_impl.h"
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 ~LocalHandle() { } 67 ~LocalHandle() { }
68 68
69 RawObject* raw_; 69 RawObject* raw_;
70 DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods. 70 DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods.
71 DISALLOW_COPY_AND_ASSIGN(LocalHandle); 71 DISALLOW_COPY_AND_ASSIGN(LocalHandle);
72 }; 72 };
73 73
74 74
75 // A distinguished callback which indicates that a persistent handle 75 // A distinguished callback which indicates that a persistent handle
76 // should not be deleted from the dart api. 76 // should not be deleted from the dart api.
77 void ProtectedHandleCallback(); 77 void ProtectedHandleCallback(void* peer);
78 78
79 79
80 // Implementation of persistent handles which are handed out through the 80 // Implementation of persistent handles which are handed out through the
81 // dart API. 81 // dart API.
82 class PersistentHandle { 82 class PersistentHandle {
83 public: 83 public:
84 enum { 84 enum Kind {
85 StrongReference = 0, 85 StrongReference = 0,
86 WeakReference, 86 WeakReference,
87 }; 87 };
88 88
89 // Adaptor for visiting handles with matching reference kind.
90 class Visitor : public HandleVisitor {
91 public:
92 Visitor(ObjectPointerVisitor* visitor, Kind kind) {
93 ASSERT(visitor != NULL);
94 kind_ = kind;
95 object_pointer_visitor_ = visitor;
96 }
97
98 void Visit(uword* addr) {
99 PersistentHandle* handle = reinterpret_cast<PersistentHandle*>(addr);
100 if (handle->kind() == kind_) {
101 object_pointer_visitor_->VisitPointer(&handle->raw_);
102 }
103 }
104
105 ~Visitor() {}
106
107 private:
108 Kind kind_;
109 ObjectPointerVisitor* object_pointer_visitor_;
110
111 DISALLOW_COPY_AND_ASSIGN(Visitor);
112 };
113
89 // Accessors. 114 // Accessors.
90 RawObject* raw() const { return raw_; } 115 RawObject* raw() const { return raw_; }
91 void set_raw(const LocalHandle& ref) { raw_ = ref.raw(); } 116 void set_raw(const LocalHandle& ref) { raw_ = ref.raw(); }
92 void set_raw(const Object& object) { raw_ = object.raw(); } 117 void set_raw(const Object& object) { raw_ = object.raw(); }
93 static intptr_t raw_offset() { return OFFSET_OF(PersistentHandle, raw_); } 118 static intptr_t raw_offset() { return OFFSET_OF(PersistentHandle, raw_); }
94 void* callback() const { return callback_; } 119 Kind kind() const { return kind_; }
95 void set_callback(void* value) { callback_ = value; } 120 void set_kind(Kind kind) { kind_ = kind; }
96 intptr_t type() const { return type_; } 121 void* peer() const { return peer_; }
97 void set_type(intptr_t value) { type_ = value; } 122 void set_peer(void* peer) { peer_ = peer; }
123 Dart_PeerFinalizer callback() const { return callback_; }
124 void set_callback(Dart_PeerFinalizer callback) { callback_ = callback; }
98 125
99 // Some handles are protected from being freed via the external dart api. 126 // Some handles are protected from being freed via the external dart api.
100 bool IsProtected() { 127 bool IsProtected() {
101 return callback() == &ProtectedHandleCallback; 128 return callback() == ProtectedHandleCallback;
102 } 129 }
103 130
104 private: 131 private:
105 friend class PersistentHandles; 132 friend class PersistentHandles;
106 133
107 PersistentHandle() { } 134 PersistentHandle() : kind_(StrongReference), peer_(NULL), callback_(NULL) { }
108 ~PersistentHandle() { } 135 ~PersistentHandle() { }
109 136
110 // Overload the callback_ field as a next pointer when adding freed 137 // Overload the callback_ field as a next pointer when adding freed
111 // handles to the free list. 138 // handles to the free list.
112 PersistentHandle* Next() { 139 PersistentHandle* Next() {
113 return reinterpret_cast<PersistentHandle*>(callback_); 140 return reinterpret_cast<PersistentHandle*>(callback_);
114 } 141 }
115 void SetNext(PersistentHandle* free_list) { 142 void SetNext(PersistentHandle* free_list) {
116 callback_ = reinterpret_cast<void*>(free_list); 143 callback_ = reinterpret_cast<Dart_PeerFinalizer>(free_list);
117 } 144 }
118 void FreeHandle(PersistentHandle* free_list) { 145 void FreeHandle(PersistentHandle* free_list) {
119 raw_ = NULL; 146 raw_ = NULL;
120 SetNext(free_list); 147 SetNext(free_list);
121 } 148 }
122 149
123 RawObject* raw_; 150 RawObject* raw_;
124 void* callback_; 151 Kind kind_;
125 intptr_t type_; 152 void* peer_;
153 Dart_PeerFinalizer callback_;
126 DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods. 154 DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods.
127 DISALLOW_COPY_AND_ASSIGN(PersistentHandle); 155 DISALLOW_COPY_AND_ASSIGN(PersistentHandle);
128 }; 156 };
129 157
130 158
131 // Local handles repository structure. 159 // Local handles repository structure.
132 static const int kLocalHandleSizeInWords = sizeof(LocalHandle) / kWordSize; 160 static const int kLocalHandleSizeInWords = sizeof(LocalHandle) / kWordSize;
133 static const int kLocalHandlesPerChunk = 64; 161 static const int kLocalHandlesPerChunk = 64;
134 static const int kOffsetOfRawPtrInLocalHandle = 0; 162 static const int kOffsetOfRawPtrInLocalHandle = 0;
135 class LocalHandles : Handles<kLocalHandleSizeInWords, 163 class LocalHandles : Handles<kLocalHandleSizeInWords,
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 PersistentHandle* free_list() const { return free_list_; } 220 PersistentHandle* free_list() const { return free_list_; }
193 void set_free_list(PersistentHandle* value) { free_list_ = value; } 221 void set_free_list(PersistentHandle* value) { free_list_ = value; }
194 222
195 // Visit all object pointers stored in the various handles. 223 // Visit all object pointers stored in the various handles.
196 void VisitObjectPointers(ObjectPointerVisitor* visitor) { 224 void VisitObjectPointers(ObjectPointerVisitor* visitor) {
197 Handles<kPersistentHandleSizeInWords, 225 Handles<kPersistentHandleSizeInWords,
198 kPersistentHandlesPerChunk, 226 kPersistentHandlesPerChunk,
199 kOffsetOfRawPtrInPersistentHandle>::VisitObjectPointers(visitor); 227 kOffsetOfRawPtrInPersistentHandle>::VisitObjectPointers(visitor);
200 } 228 }
201 229
230 // Visits the object pointers in strong persistent handles.
231 void VisitStrongObjectPointers(ObjectPointerVisitor* visitor) {
232 PersistentHandle::Visitor strong_visitor(visitor,
233 PersistentHandle::StrongReference);
234 Handles<kPersistentHandleSizeInWords,
235 kPersistentHandlesPerChunk,
236 kOffsetOfRawPtrInPersistentHandle>::Visit(&strong_visitor);
237 }
238
239 // Visits the object pointers in weak persistent handles.
240 void VisitWeakObjectPointers(ObjectPointerVisitor* visitor) {
241 PersistentHandle::Visitor weak_visitor(visitor,
242 PersistentHandle::WeakReference);
243 Handles<kPersistentHandleSizeInWords,
244 kPersistentHandlesPerChunk,
245 kOffsetOfRawPtrInPersistentHandle>::Visit(&weak_visitor);
246 }
247
202 // Allocates a persistent handle, these have to be destroyed explicitly 248 // Allocates a persistent handle, these have to be destroyed explicitly
203 // by calling FreeHandle. 249 // by calling FreeHandle.
204 PersistentHandle* AllocateHandle() { 250 PersistentHandle* AllocateHandle() {
205 PersistentHandle* handle; 251 PersistentHandle* handle;
206 if (free_list_ != NULL) { 252 if (free_list_ != NULL) {
207 handle = free_list_; 253 handle = free_list_;
208 free_list_ = handle->Next(); 254 free_list_ = handle->Next();
209 } else { 255 } else {
210 handle = reinterpret_cast<PersistentHandle*>(AllocateScopedHandle()); 256 handle = reinterpret_cast<PersistentHandle*>(AllocateScopedHandle());
211 } 257 }
212 handle->set_callback(NULL); 258 handle->set_callback(NULL);
213 handle->set_type(PersistentHandle::StrongReference); 259 handle->set_kind(PersistentHandle::StrongReference);
214 return handle; 260 return handle;
215 } 261 }
216 262
217 void FreeHandle(PersistentHandle* handle) { 263 void FreeHandle(PersistentHandle* handle) {
218 handle->FreeHandle(free_list()); 264 handle->FreeHandle(free_list());
219 set_free_list(handle); 265 set_free_list(handle);
220 } 266 }
221 267
222 // Validate if passed in handle is a Persistent Handle. 268 // Validate if passed in handle is a Persistent Handle.
223 bool IsValidHandle(Dart_Handle object) const { 269 bool IsValidHandle(Dart_Handle object) const {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 PersistentHandles& persistent_handles() { return persistent_handles_; } 340 PersistentHandles& persistent_handles() { return persistent_handles_; }
295 341
296 void UnwindScopes(uword sp) { 342 void UnwindScopes(uword sp) {
297 while (top_scope_ != NULL && top_scope_->stack_marker() < sp) { 343 while (top_scope_ != NULL && top_scope_->stack_marker() < sp) {
298 ApiLocalScope* scope = top_scope_; 344 ApiLocalScope* scope = top_scope_;
299 top_scope_ = top_scope_->previous(); 345 top_scope_ = top_scope_->previous();
300 delete scope; 346 delete scope;
301 } 347 }
302 } 348 }
303 349
304 void VisitObjectPointers(ObjectPointerVisitor* visitor) { 350 void VisitStrongObjectPointers(ObjectPointerVisitor* visitor) {
305 ApiLocalScope* scope = top_scope_; 351 ApiLocalScope* scope = top_scope_;
306 while (scope != NULL) { 352 while (scope != NULL) {
307 scope->local_handles()->VisitObjectPointers(visitor); 353 scope->local_handles()->VisitObjectPointers(visitor);
308 scope = scope->previous(); 354 scope = scope->previous();
309 } 355 }
310 persistent_handles().VisitObjectPointers(visitor); 356
357 persistent_handles().VisitStrongObjectPointers(visitor);
358 }
359
360 void VisitWeakObjectPointers(ObjectPointerVisitor* visitor) {
361 persistent_handles().VisitWeakObjectPointers(visitor);
362 }
363
364 void VisitObjectPointers(ObjectPointerVisitor* visitor) {
365 VisitStrongObjectPointers(visitor);
366 VisitWeakObjectPointers(visitor);
311 } 367 }
312 368
313 bool IsValidLocalHandle(Dart_Handle object) const { 369 bool IsValidLocalHandle(Dart_Handle object) const {
314 ApiLocalScope* scope = top_scope_; 370 ApiLocalScope* scope = top_scope_;
315 while (scope != NULL) { 371 while (scope != NULL) {
316 if (scope->local_handles()->IsValidHandle(object)) { 372 if (scope->local_handles()->IsValidHandle(object)) {
317 return true; 373 return true;
318 } 374 }
319 scope = scope->previous(); 375 scope = scope->previous();
320 } 376 }
(...skipping 24 matching lines...) Expand all
345 } 401 }
346 return total; 402 return total;
347 } 403 }
348 PersistentHandle* Null() { 404 PersistentHandle* Null() {
349 if (null_ == NULL) { 405 if (null_ == NULL) {
350 DARTSCOPE(Isolate::Current()); 406 DARTSCOPE(Isolate::Current());
351 407
352 Object& null_object = Object::Handle(); 408 Object& null_object = Object::Handle();
353 null_ = persistent_handles().AllocateHandle(); 409 null_ = persistent_handles().AllocateHandle();
354 null_->set_raw(null_object); 410 null_->set_raw(null_object);
355 null_->set_callback(reinterpret_cast<void*>(&ProtectedHandleCallback)); 411 null_->set_callback(ProtectedHandleCallback);
356 } 412 }
357 return null_; 413 return null_;
358 } 414 }
359 PersistentHandle* True() { 415 PersistentHandle* True() {
360 if (true_ == NULL) { 416 if (true_ == NULL) {
361 DARTSCOPE(Isolate::Current()); 417 DARTSCOPE(Isolate::Current());
362 418
363 const Object& true_object = Object::Handle(Bool::True()); 419 const Object& true_object = Object::Handle(Bool::True());
364 true_ = persistent_handles().AllocateHandle(); 420 true_ = persistent_handles().AllocateHandle();
365 true_->set_raw(true_object); 421 true_->set_raw(true_object);
366 true_->set_callback(reinterpret_cast<void*>(&ProtectedHandleCallback)); 422 true_->set_callback(ProtectedHandleCallback);
367 } 423 }
368 return true_; 424 return true_;
369 } 425 }
370 PersistentHandle* False() { 426 PersistentHandle* False() {
371 if (false_ == NULL) { 427 if (false_ == NULL) {
372 DARTSCOPE(Isolate::Current()); 428 DARTSCOPE(Isolate::Current());
373 429
374 const Object& false_object = Object::Handle(Bool::False()); 430 const Object& false_object = Object::Handle(Bool::False());
375 false_ = persistent_handles().AllocateHandle(); 431 false_ = persistent_handles().AllocateHandle();
376 false_->set_raw(false_object); 432 false_->set_raw(false_object);
377 false_->set_callback(reinterpret_cast<void*>(&ProtectedHandleCallback)); 433 false_->set_callback(ProtectedHandleCallback);
378 } 434 }
379 return false_; 435 return false_;
380 } 436 }
381 437
382 private: 438 private:
383 PersistentHandles persistent_handles_; 439 PersistentHandles persistent_handles_;
384 ApiLocalScope* top_scope_; 440 ApiLocalScope* top_scope_;
385 441
386 // Persistent handles to important objects. 442 // Persistent handles to important objects.
387 PersistentHandle* null_; 443 PersistentHandle* null_;
388 PersistentHandle* true_; 444 PersistentHandle* true_;
389 PersistentHandle* false_; 445 PersistentHandle* false_;
390 446
391 DISALLOW_COPY_AND_ASSIGN(ApiState); 447 DISALLOW_COPY_AND_ASSIGN(ApiState);
392 }; 448 };
393 449
394 } // namespace dart 450 } // namespace dart
395 451
396 #endif // VM_DART_API_STATE_H_ 452 #endif // VM_DART_API_STATE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698