| 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 |