| 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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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(void* peer); | 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 Kind { | |
| 85 StrongReference = 0, | |
| 86 WeakReference, | |
| 87 }; | |
| 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 | |
| 114 // Accessors. | 84 // Accessors. |
| 115 RawObject* raw() const { return raw_; } | 85 RawObject* raw() const { return raw_; } |
| 86 void set_raw(RawObject* ref) { raw_ = ref; } |
| 116 void set_raw(const LocalHandle& ref) { raw_ = ref.raw(); } | 87 void set_raw(const LocalHandle& ref) { raw_ = ref.raw(); } |
| 117 void set_raw(const Object& object) { raw_ = object.raw(); } | 88 void set_raw(const Object& object) { raw_ = object.raw(); } |
| 118 static intptr_t raw_offset() { return OFFSET_OF(PersistentHandle, raw_); } | 89 static intptr_t raw_offset() { return OFFSET_OF(PersistentHandle, raw_); } |
| 119 Kind kind() const { return kind_; } | 90 |
| 120 void set_kind(Kind kind) { kind_ = kind; } | 91 private: |
| 92 friend class PersistentHandles; |
| 93 |
| 94 PersistentHandle() { } |
| 95 ~PersistentHandle() { } |
| 96 |
| 97 // Overload the raw_ field as a next pointer when adding freed |
| 98 // handles to the free list. |
| 99 PersistentHandle* Next() { |
| 100 return reinterpret_cast<PersistentHandle*>(raw_); |
| 101 } |
| 102 void SetNext(PersistentHandle* free_list) { |
| 103 raw_ = reinterpret_cast<RawObject*>(free_list); |
| 104 } |
| 105 void FreeHandle(PersistentHandle* free_list) { |
| 106 SetNext(free_list); |
| 107 } |
| 108 |
| 109 RawObject* raw_; |
| 110 DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods. |
| 111 DISALLOW_COPY_AND_ASSIGN(PersistentHandle); |
| 112 }; |
| 113 |
| 114 |
| 115 // Implementation of persistent handles which are handed out through the |
| 116 // dart API. |
| 117 class WeakPersistentHandle { |
| 118 public: |
| 119 // Accessors. |
| 120 RawObject* raw() const { return raw_; } |
| 121 void set_raw(RawObject* raw) { raw_ = raw; } |
| 122 void set_raw(const LocalHandle& ref) { raw_ = ref.raw(); } |
| 123 void set_raw(const Object& object) { raw_ = object.raw(); } |
| 124 static intptr_t raw_offset() { return OFFSET_OF(WeakPersistentHandle, raw_); } |
| 121 void* peer() const { return peer_; } | 125 void* peer() const { return peer_; } |
| 122 void set_peer(void* peer) { peer_ = peer; } | 126 void set_peer(void* peer) { peer_ = peer; } |
| 123 Dart_PeerFinalizer callback() const { return callback_; } | 127 Dart_PeerFinalizer callback() const { return callback_; } |
| 124 void set_callback(Dart_PeerFinalizer callback) { callback_ = callback; } | 128 void set_callback(Dart_PeerFinalizer callback) { callback_ = callback; } |
| 125 | 129 |
| 126 // Some handles are protected from being freed via the external dart api. | 130 void Finalize() { |
| 127 bool IsProtected() { | 131 if (callback_ != NULL) { |
| 128 return callback() == ProtectedHandleCallback; | 132 (*callback_)(peer_); |
| 133 } |
| 134 Clear(); |
| 129 } | 135 } |
| 130 | 136 |
| 131 private: | 137 private: |
| 132 friend class PersistentHandles; | 138 friend class WeakPersistentHandles; |
| 133 | 139 |
| 134 PersistentHandle() : kind_(StrongReference), peer_(NULL), callback_(NULL) { } | 140 WeakPersistentHandle() : raw_(NULL), peer_(NULL), callback_(NULL) { } |
| 135 ~PersistentHandle() { } | 141 ~WeakPersistentHandle() { } |
| 136 | 142 |
| 137 // Overload the callback_ field as a next pointer when adding freed | 143 // Overload the callback_ field as a next pointer when adding freed |
| 138 // handles to the free list. | 144 // handles to the free list. |
| 139 PersistentHandle* Next() { | 145 WeakPersistentHandle* Next() { |
| 140 return reinterpret_cast<PersistentHandle*>(callback_); | 146 return reinterpret_cast<WeakPersistentHandle*>(callback_); |
| 141 } | 147 } |
| 142 void SetNext(PersistentHandle* free_list) { | 148 void SetNext(WeakPersistentHandle* free_list) { |
| 143 callback_ = reinterpret_cast<Dart_PeerFinalizer>(free_list); | 149 callback_ = reinterpret_cast<Dart_PeerFinalizer>(free_list); |
| 144 } | 150 } |
| 145 void FreeHandle(PersistentHandle* free_list) { | 151 void FreeHandle(WeakPersistentHandle* free_list) { |
| 146 raw_ = NULL; | 152 raw_ = NULL; |
| 147 SetNext(free_list); | 153 SetNext(free_list); |
| 148 } | 154 } |
| 149 | 155 |
| 156 void Clear() { |
| 157 raw_ = Object::null(); |
| 158 peer_ = NULL; |
| 159 callback_ = NULL; |
| 160 } |
| 161 |
| 150 RawObject* raw_; | 162 RawObject* raw_; |
| 151 Kind kind_; | |
| 152 void* peer_; | 163 void* peer_; |
| 153 Dart_PeerFinalizer callback_; | 164 Dart_PeerFinalizer callback_; |
| 154 DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods. | 165 DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods. |
| 155 DISALLOW_COPY_AND_ASSIGN(PersistentHandle); | 166 DISALLOW_COPY_AND_ASSIGN(WeakPersistentHandle); |
| 156 }; | 167 }; |
| 157 | 168 |
| 158 | 169 |
| 159 // Local handles repository structure. | 170 // Local handles repository structure. |
| 160 static const int kLocalHandleSizeInWords = sizeof(LocalHandle) / kWordSize; | 171 static const int kLocalHandleSizeInWords = sizeof(LocalHandle) / kWordSize; |
| 161 static const int kLocalHandlesPerChunk = 64; | 172 static const int kLocalHandlesPerChunk = 64; |
| 162 static const int kOffsetOfRawPtrInLocalHandle = 0; | 173 static const int kOffsetOfRawPtrInLocalHandle = 0; |
| 163 class LocalHandles : Handles<kLocalHandleSizeInWords, | 174 class LocalHandles : Handles<kLocalHandleSizeInWords, |
| 164 kLocalHandlesPerChunk, | 175 kLocalHandlesPerChunk, |
| 165 kOffsetOfRawPtrInLocalHandle> { | 176 kOffsetOfRawPtrInLocalHandle> { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 PersistentHandle* free_list() const { return free_list_; } | 231 PersistentHandle* free_list() const { return free_list_; } |
| 221 void set_free_list(PersistentHandle* value) { free_list_ = value; } | 232 void set_free_list(PersistentHandle* value) { free_list_ = value; } |
| 222 | 233 |
| 223 // Visit all object pointers stored in the various handles. | 234 // Visit all object pointers stored in the various handles. |
| 224 void VisitObjectPointers(ObjectPointerVisitor* visitor) { | 235 void VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 225 Handles<kPersistentHandleSizeInWords, | 236 Handles<kPersistentHandleSizeInWords, |
| 226 kPersistentHandlesPerChunk, | 237 kPersistentHandlesPerChunk, |
| 227 kOffsetOfRawPtrInPersistentHandle>::VisitObjectPointers(visitor); | 238 kOffsetOfRawPtrInPersistentHandle>::VisitObjectPointers(visitor); |
| 228 } | 239 } |
| 229 | 240 |
| 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 | |
| 248 // Allocates a persistent handle, these have to be destroyed explicitly | 241 // Allocates a persistent handle, these have to be destroyed explicitly |
| 249 // by calling FreeHandle. | 242 // by calling FreeHandle. |
| 250 PersistentHandle* AllocateHandle() { | 243 PersistentHandle* AllocateHandle() { |
| 251 PersistentHandle* handle; | 244 PersistentHandle* handle; |
| 252 if (free_list_ != NULL) { | 245 if (free_list_ != NULL) { |
| 253 handle = free_list_; | 246 handle = free_list_; |
| 254 free_list_ = handle->Next(); | 247 free_list_ = handle->Next(); |
| 255 } else { | 248 } else { |
| 256 handle = reinterpret_cast<PersistentHandle*>(AllocateScopedHandle()); | 249 handle = reinterpret_cast<PersistentHandle*>(AllocateScopedHandle()); |
| 257 } | 250 } |
| 258 handle->set_callback(NULL); | 251 handle->set_raw(NULL); |
| 259 handle->set_kind(PersistentHandle::StrongReference); | |
| 260 return handle; | 252 return handle; |
| 261 } | 253 } |
| 262 | 254 |
| 263 void FreeHandle(PersistentHandle* handle) { | 255 void FreeHandle(PersistentHandle* handle) { |
| 264 handle->FreeHandle(free_list()); | 256 handle->FreeHandle(free_list()); |
| 265 set_free_list(handle); | 257 set_free_list(handle); |
| 266 } | 258 } |
| 267 | 259 |
| 268 // Validate if passed in handle is a Persistent Handle. | 260 // Validate if passed in handle is a Persistent Handle. |
| 269 bool IsValidHandle(Dart_Handle object) const { | 261 bool IsValidHandle(Dart_Handle object) const { |
| 270 return IsValidScopedHandle(reinterpret_cast<uword>(object)); | 262 return IsValidScopedHandle(reinterpret_cast<uword>(object)); |
| 271 } | 263 } |
| 272 | 264 |
| 273 // Returns a count of active handles (used for testing purposes). | 265 // Returns a count of active handles (used for testing purposes). |
| 274 int CountHandles() const { | 266 int CountHandles() const { |
| 275 return CountScopedHandles(); | 267 return CountScopedHandles(); |
| 276 } | 268 } |
| 277 | 269 |
| 278 private: | 270 private: |
| 279 PersistentHandle* free_list_; | 271 PersistentHandle* free_list_; |
| 280 DISALLOW_COPY_AND_ASSIGN(PersistentHandles); | 272 DISALLOW_COPY_AND_ASSIGN(PersistentHandles); |
| 281 }; | 273 }; |
| 282 | 274 |
| 283 | 275 |
| 276 // Weak persistent handles repository structure. |
| 277 static const int kWeakPersistentHandleSizeInWords = |
| 278 sizeof(WeakPersistentHandle) / kWordSize; |
| 279 static const int kWeakPersistentHandlesPerChunk = 64; |
| 280 static const int kOffsetOfRawPtrInWeakPersistentHandle = 0; |
| 281 class WeakPersistentHandles : Handles<kWeakPersistentHandleSizeInWords, |
| 282 kWeakPersistentHandlesPerChunk, |
| 283 kOffsetOfRawPtrInWeakPersistentHandle> { |
| 284 public: |
| 285 WeakPersistentHandles() : Handles<kWeakPersistentHandleSizeInWords, |
| 286 kWeakPersistentHandlesPerChunk, |
| 287 kOffsetOfRawPtrInWeakPersistentHandle>(), |
| 288 free_list_(NULL) { } |
| 289 ~WeakPersistentHandles() { |
| 290 free_list_ = NULL; |
| 291 } |
| 292 |
| 293 // Accessors. |
| 294 WeakPersistentHandle* free_list() const { return free_list_; } |
| 295 void set_free_list(WeakPersistentHandle* value) { free_list_ = value; } |
| 296 |
| 297 // Visit all handles stored in the various handle blocks. |
| 298 void VisitWeakPersistentHandles(HandleVisitor* visitor) { |
| 299 Handles<kWeakPersistentHandleSizeInWords, |
| 300 kWeakPersistentHandlesPerChunk, |
| 301 kOffsetOfRawPtrInWeakPersistentHandle>::Visit(visitor); |
| 302 } |
| 303 |
| 304 // Allocates a persistent handle, these have to be destroyed explicitly |
| 305 // by calling FreeHandle. |
| 306 WeakPersistentHandle* AllocateHandle() { |
| 307 WeakPersistentHandle* handle; |
| 308 if (free_list_ != NULL) { |
| 309 handle = free_list_; |
| 310 free_list_ = handle->Next(); |
| 311 } else { |
| 312 handle = reinterpret_cast<WeakPersistentHandle*>(AllocateScopedHandle()); |
| 313 } |
| 314 handle->set_callback(NULL); |
| 315 return handle; |
| 316 } |
| 317 |
| 318 void FreeHandle(WeakPersistentHandle* handle) { |
| 319 handle->FreeHandle(free_list()); |
| 320 set_free_list(handle); |
| 321 } |
| 322 |
| 323 // Validate if passed in handle is a Persistent Handle. |
| 324 bool IsValidHandle(Dart_Handle object) const { |
| 325 return IsValidScopedHandle(reinterpret_cast<uword>(object)); |
| 326 } |
| 327 |
| 328 // Returns a count of active handles (used for testing purposes). |
| 329 int CountHandles() const { |
| 330 return CountScopedHandles(); |
| 331 } |
| 332 |
| 333 private: |
| 334 WeakPersistentHandle* free_list_; |
| 335 DISALLOW_COPY_AND_ASSIGN(WeakPersistentHandles); |
| 336 }; |
| 337 |
| 338 |
| 284 // Structure used for the implementation of local scopes used in dart_api. | 339 // Structure used for the implementation of local scopes used in dart_api. |
| 285 // These local scopes manage handles and memory allocated in the scope. | 340 // These local scopes manage handles and memory allocated in the scope. |
| 286 class ApiLocalScope { | 341 class ApiLocalScope { |
| 287 public: | 342 public: |
| 288 ApiLocalScope(ApiLocalScope* previous, uword stack_marker) : | 343 ApiLocalScope(ApiLocalScope* previous, uword stack_marker) : |
| 289 previous_(previous), stack_marker_(stack_marker) { } | 344 previous_(previous), stack_marker_(stack_marker) { } |
| 290 ~ApiLocalScope() { | 345 ~ApiLocalScope() { |
| 291 previous_ = NULL; | 346 previous_ = NULL; |
| 292 } | 347 } |
| 293 | 348 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 if (false_ != NULL) { | 386 if (false_ != NULL) { |
| 332 persistent_handles().FreeHandle(false_); | 387 persistent_handles().FreeHandle(false_); |
| 333 false_ = NULL; | 388 false_ = NULL; |
| 334 } | 389 } |
| 335 } | 390 } |
| 336 | 391 |
| 337 // Accessors. | 392 // Accessors. |
| 338 ApiLocalScope* top_scope() const { return top_scope_; } | 393 ApiLocalScope* top_scope() const { return top_scope_; } |
| 339 void set_top_scope(ApiLocalScope* value) { top_scope_ = value; } | 394 void set_top_scope(ApiLocalScope* value) { top_scope_ = value; } |
| 340 PersistentHandles& persistent_handles() { return persistent_handles_; } | 395 PersistentHandles& persistent_handles() { return persistent_handles_; } |
| 396 WeakPersistentHandles& weak_persistent_handles() { |
| 397 return weak_persistent_handles_; |
| 398 } |
| 341 | 399 |
| 342 void UnwindScopes(uword sp) { | 400 void UnwindScopes(uword sp) { |
| 343 while (top_scope_ != NULL && top_scope_->stack_marker() < sp) { | 401 while (top_scope_ != NULL && top_scope_->stack_marker() < sp) { |
| 344 ApiLocalScope* scope = top_scope_; | 402 ApiLocalScope* scope = top_scope_; |
| 345 top_scope_ = top_scope_->previous(); | 403 top_scope_ = top_scope_->previous(); |
| 346 delete scope; | 404 delete scope; |
| 347 } | 405 } |
| 348 } | 406 } |
| 349 | 407 |
| 350 void VisitStrongObjectPointers(ObjectPointerVisitor* visitor) { | 408 void VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 351 ApiLocalScope* scope = top_scope_; | 409 ApiLocalScope* scope = top_scope_; |
| 352 while (scope != NULL) { | 410 while (scope != NULL) { |
| 353 scope->local_handles()->VisitObjectPointers(visitor); | 411 scope->local_handles()->VisitObjectPointers(visitor); |
| 354 scope = scope->previous(); | 412 scope = scope->previous(); |
| 355 } | 413 } |
| 356 | 414 persistent_handles().VisitObjectPointers(visitor); |
| 357 persistent_handles().VisitStrongObjectPointers(visitor); | |
| 358 } | 415 } |
| 359 | 416 |
| 360 void VisitWeakObjectPointers(ObjectPointerVisitor* visitor) { | 417 void VisitWeakHandles(HandleVisitor* visitor) { |
| 361 persistent_handles().VisitWeakObjectPointers(visitor); | 418 weak_persistent_handles().VisitWeakPersistentHandles(visitor); |
| 362 } | |
| 363 | |
| 364 void VisitObjectPointers(ObjectPointerVisitor* visitor) { | |
| 365 VisitStrongObjectPointers(visitor); | |
| 366 VisitWeakObjectPointers(visitor); | |
| 367 } | 419 } |
| 368 | 420 |
| 369 bool IsValidLocalHandle(Dart_Handle object) const { | 421 bool IsValidLocalHandle(Dart_Handle object) const { |
| 370 ApiLocalScope* scope = top_scope_; | 422 ApiLocalScope* scope = top_scope_; |
| 371 while (scope != NULL) { | 423 while (scope != NULL) { |
| 372 if (scope->local_handles()->IsValidHandle(object)) { | 424 if (scope->local_handles()->IsValidHandle(object)) { |
| 373 return true; | 425 return true; |
| 374 } | 426 } |
| 375 scope = scope->previous(); | 427 scope = scope->previous(); |
| 376 } | 428 } |
| 377 return false; | 429 return false; |
| 378 } | 430 } |
| 431 |
| 379 bool IsValidPersistentHandle(Dart_Handle object) const { | 432 bool IsValidPersistentHandle(Dart_Handle object) const { |
| 380 return persistent_handles_.IsValidHandle(object); | 433 return persistent_handles_.IsValidHandle(object); |
| 381 } | 434 } |
| 382 | 435 |
| 436 bool IsValidWeakPersistentHandle(Dart_Handle object) const { |
| 437 return weak_persistent_handles_.IsValidHandle(object); |
| 438 } |
| 439 |
| 440 bool IsProtectedHandle(PersistentHandle* object) const { |
| 441 if (object == NULL) return false; |
| 442 return object == null_ || object == true_ || object == false_; |
| 443 } |
| 444 |
| 383 int CountLocalHandles() const { | 445 int CountLocalHandles() const { |
| 384 int total = 0; | 446 int total = 0; |
| 385 ApiLocalScope* scope = top_scope_; | 447 ApiLocalScope* scope = top_scope_; |
| 386 while (scope != NULL) { | 448 while (scope != NULL) { |
| 387 total += scope->local_handles()->CountHandles(); | 449 total += scope->local_handles()->CountHandles(); |
| 388 scope = scope->previous(); | 450 scope = scope->previous(); |
| 389 } | 451 } |
| 390 return total; | 452 return total; |
| 391 } | 453 } |
| 392 int CountPersistentHandles() const { | 454 int CountPersistentHandles() const { |
| 393 return persistent_handles_.CountHandles(); | 455 return persistent_handles_.CountHandles(); |
| 394 } | 456 } |
| 395 int ZoneSizeInBytes() const { | 457 int ZoneSizeInBytes() const { |
| 396 int total = 0; | 458 int total = 0; |
| 397 ApiLocalScope* scope = top_scope_; | 459 ApiLocalScope* scope = top_scope_; |
| 398 while (scope != NULL) { | 460 while (scope != NULL) { |
| 399 total += scope->zone().SizeInBytes(); | 461 total += scope->zone().SizeInBytes(); |
| 400 scope = scope->previous(); | 462 scope = scope->previous(); |
| 401 } | 463 } |
| 402 return total; | 464 return total; |
| 403 } | 465 } |
| 404 PersistentHandle* Null() { | 466 PersistentHandle* Null() { |
| 405 if (null_ == NULL) { | 467 if (null_ == NULL) { |
| 406 DARTSCOPE(Isolate::Current()); | 468 DARTSCOPE(Isolate::Current()); |
| 407 | 469 |
| 408 Object& null_object = Object::Handle(); | 470 Object& null_object = Object::Handle(); |
| 409 null_ = persistent_handles().AllocateHandle(); | 471 null_ = persistent_handles().AllocateHandle(); |
| 410 null_->set_raw(null_object); | 472 null_->set_raw(null_object); |
| 411 null_->set_callback(ProtectedHandleCallback); | |
| 412 } | 473 } |
| 413 return null_; | 474 return null_; |
| 414 } | 475 } |
| 415 PersistentHandle* True() { | 476 PersistentHandle* True() { |
| 416 if (true_ == NULL) { | 477 if (true_ == NULL) { |
| 417 DARTSCOPE(Isolate::Current()); | 478 DARTSCOPE(Isolate::Current()); |
| 418 | 479 |
| 419 const Object& true_object = Object::Handle(Bool::True()); | 480 const Object& true_object = Object::Handle(Bool::True()); |
| 420 true_ = persistent_handles().AllocateHandle(); | 481 true_ = persistent_handles().AllocateHandle(); |
| 421 true_->set_raw(true_object); | 482 true_->set_raw(true_object); |
| 422 true_->set_callback(ProtectedHandleCallback); | |
| 423 } | 483 } |
| 424 return true_; | 484 return true_; |
| 425 } | 485 } |
| 426 PersistentHandle* False() { | 486 PersistentHandle* False() { |
| 427 if (false_ == NULL) { | 487 if (false_ == NULL) { |
| 428 DARTSCOPE(Isolate::Current()); | 488 DARTSCOPE(Isolate::Current()); |
| 429 | 489 |
| 430 const Object& false_object = Object::Handle(Bool::False()); | 490 const Object& false_object = Object::Handle(Bool::False()); |
| 431 false_ = persistent_handles().AllocateHandle(); | 491 false_ = persistent_handles().AllocateHandle(); |
| 432 false_->set_raw(false_object); | 492 false_->set_raw(false_object); |
| 433 false_->set_callback(ProtectedHandleCallback); | |
| 434 } | 493 } |
| 435 return false_; | 494 return false_; |
| 436 } | 495 } |
| 437 | 496 |
| 438 private: | 497 private: |
| 439 PersistentHandles persistent_handles_; | 498 PersistentHandles persistent_handles_; |
| 499 WeakPersistentHandles weak_persistent_handles_; |
| 440 ApiLocalScope* top_scope_; | 500 ApiLocalScope* top_scope_; |
| 441 | 501 |
| 442 // Persistent handles to important objects. | 502 // Persistent handles to important objects. |
| 443 PersistentHandle* null_; | 503 PersistentHandle* null_; |
| 444 PersistentHandle* true_; | 504 PersistentHandle* true_; |
| 445 PersistentHandle* false_; | 505 PersistentHandle* false_; |
| 446 | 506 |
| 447 DISALLOW_COPY_AND_ASSIGN(ApiState); | 507 DISALLOW_COPY_AND_ASSIGN(ApiState); |
| 448 }; | 508 }; |
| 449 | 509 |
| 450 } // namespace dart | 510 } // namespace dart |
| 451 | 511 |
| 452 #endif // VM_DART_API_STATE_H_ | 512 #endif // VM_DART_API_STATE_H_ |
| OLD | NEW |