OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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_ |
OLD | NEW |