| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 "platform/thread.h" | 10 #include "platform/thread.h" |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 } | 113 } |
| 114 | 114 |
| 115 RawObject* raw_; | 115 RawObject* raw_; |
| 116 DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods. | 116 DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods. |
| 117 DISALLOW_COPY_AND_ASSIGN(PersistentHandle); | 117 DISALLOW_COPY_AND_ASSIGN(PersistentHandle); |
| 118 }; | 118 }; |
| 119 | 119 |
| 120 | 120 |
| 121 // Implementation of persistent handles which are handed out through the | 121 // Implementation of persistent handles which are handed out through the |
| 122 // dart API. | 122 // dart API. |
| 123 class WeakPersistentHandle { | 123 class FinalizablePersistentHandle { |
| 124 public: | 124 public: |
| 125 // Accessors. | 125 // Accessors. |
| 126 RawObject* raw() const { return raw_; } | 126 RawObject* raw() const { return raw_; } |
| 127 void set_raw(RawObject* raw) { raw_ = raw; } | 127 void set_raw(RawObject* raw) { raw_ = raw; } |
| 128 void set_raw(const LocalHandle& ref) { raw_ = ref.raw(); } | 128 void set_raw(const LocalHandle& ref) { raw_ = ref.raw(); } |
| 129 void set_raw(const Object& object) { raw_ = object.raw(); } | 129 void set_raw(const Object& object) { raw_ = object.raw(); } |
| 130 static intptr_t raw_offset() { return OFFSET_OF(WeakPersistentHandle, raw_); } | 130 static intptr_t raw_offset() { |
| 131 return OFFSET_OF(FinalizablePersistentHandle, raw_); |
| 132 } |
| 131 void* peer() const { return peer_; } | 133 void* peer() const { return peer_; } |
| 132 void set_peer(void* peer) { peer_ = peer; } | 134 void set_peer(void* peer) { peer_ = peer; } |
| 133 Dart_WeakPersistentHandleFinalizer callback() const { return callback_; } | 135 Dart_WeakPersistentHandleFinalizer callback() const { return callback_; } |
| 134 void set_callback(Dart_WeakPersistentHandleFinalizer callback) { | 136 void set_callback(Dart_WeakPersistentHandleFinalizer callback) { |
| 135 callback_ = callback; | 137 callback_ = callback; |
| 136 } | 138 } |
| 137 | 139 |
| 138 static void Finalize(WeakPersistentHandle* handle) { | 140 static void Finalize(FinalizablePersistentHandle* handle) { |
| 139 Dart_WeakPersistentHandleFinalizer callback = handle->callback(); | 141 Dart_WeakPersistentHandleFinalizer callback = handle->callback(); |
| 140 if (callback != NULL) { | 142 if (callback != NULL) { |
| 141 void* peer = handle->peer(); | 143 void* peer = handle->peer(); |
| 142 handle->Clear(); | 144 handle->Clear(); |
| 143 (*callback)(reinterpret_cast<Dart_Handle>(handle), peer); | 145 (*callback)(reinterpret_cast<Dart_Handle>(handle), peer); |
| 144 } else { | 146 } else { |
| 145 handle->Clear(); | 147 handle->Clear(); |
| 146 } | 148 } |
| 147 } | 149 } |
| 148 | 150 |
| 149 private: | 151 private: |
| 150 friend class WeakPersistentHandles; | 152 friend class FinalizablePersistentHandles; |
| 151 | 153 |
| 152 WeakPersistentHandle() : raw_(NULL), peer_(NULL), callback_(NULL) { } | 154 FinalizablePersistentHandle() : raw_(NULL), peer_(NULL), callback_(NULL) { } |
| 153 ~WeakPersistentHandle() { } | 155 ~FinalizablePersistentHandle() { } |
| 154 | 156 |
| 155 // Overload the raw_ field as a next pointer when adding freed | 157 // Overload the raw_ field as a next pointer when adding freed |
| 156 // handles to the free list. | 158 // handles to the free list. |
| 157 WeakPersistentHandle* Next() { | 159 FinalizablePersistentHandle* Next() { |
| 158 return reinterpret_cast<WeakPersistentHandle*>(raw_); | 160 return reinterpret_cast<FinalizablePersistentHandle*>(raw_); |
| 159 } | 161 } |
| 160 void SetNext(WeakPersistentHandle* free_list) { | 162 void SetNext(FinalizablePersistentHandle* free_list) { |
| 161 raw_ = reinterpret_cast<RawObject*>(free_list); | 163 raw_ = reinterpret_cast<RawObject*>(free_list); |
| 162 ASSERT(!raw_->IsHeapObject()); | 164 ASSERT(!raw_->IsHeapObject()); |
| 163 } | 165 } |
| 164 void FreeHandle(WeakPersistentHandle* free_list) { | 166 void FreeHandle(FinalizablePersistentHandle* free_list) { |
| 165 SetNext(free_list); | 167 SetNext(free_list); |
| 166 } | 168 } |
| 167 | 169 |
| 168 void Clear() { | 170 void Clear() { |
| 169 raw_ = Object::null(); | 171 raw_ = Object::null(); |
| 170 peer_ = NULL; | 172 peer_ = NULL; |
| 171 callback_ = NULL; | 173 callback_ = NULL; |
| 172 } | 174 } |
| 173 | 175 |
| 174 RawObject* raw_; | 176 RawObject* raw_; |
| 175 void* peer_; | 177 void* peer_; |
| 176 Dart_WeakPersistentHandleFinalizer callback_; | 178 Dart_WeakPersistentHandleFinalizer callback_; |
| 177 DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods. | 179 DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods. |
| 178 DISALLOW_COPY_AND_ASSIGN(WeakPersistentHandle); | 180 DISALLOW_COPY_AND_ASSIGN(FinalizablePersistentHandle); |
| 179 }; | 181 }; |
| 180 | 182 |
| 181 | 183 |
| 182 // Local handles repository structure. | 184 // Local handles repository structure. |
| 183 static const int kLocalHandleSizeInWords = sizeof(LocalHandle) / kWordSize; | 185 static const int kLocalHandleSizeInWords = sizeof(LocalHandle) / kWordSize; |
| 184 static const int kLocalHandlesPerChunk = 64; | 186 static const int kLocalHandlesPerChunk = 64; |
| 185 static const int kOffsetOfRawPtrInLocalHandle = 0; | 187 static const int kOffsetOfRawPtrInLocalHandle = 0; |
| 186 class LocalHandles : Handles<kLocalHandleSizeInWords, | 188 class LocalHandles : Handles<kLocalHandleSizeInWords, |
| 187 kLocalHandlesPerChunk, | 189 kLocalHandlesPerChunk, |
| 188 kOffsetOfRawPtrInLocalHandle> { | 190 kOffsetOfRawPtrInLocalHandle> { |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 int CountHandles() const { | 280 int CountHandles() const { |
| 279 return CountScopedHandles(); | 281 return CountScopedHandles(); |
| 280 } | 282 } |
| 281 | 283 |
| 282 private: | 284 private: |
| 283 PersistentHandle* free_list_; | 285 PersistentHandle* free_list_; |
| 284 DISALLOW_COPY_AND_ASSIGN(PersistentHandles); | 286 DISALLOW_COPY_AND_ASSIGN(PersistentHandles); |
| 285 }; | 287 }; |
| 286 | 288 |
| 287 | 289 |
| 288 // Weak persistent handles repository structure. | 290 // Finalizable persistent handles repository structure. |
| 289 static const int kWeakPersistentHandleSizeInWords = | 291 static const int kFinalizablePersistentHandleSizeInWords = |
| 290 sizeof(WeakPersistentHandle) / kWordSize; | 292 sizeof(FinalizablePersistentHandle) / kWordSize; |
| 291 static const int kWeakPersistentHandlesPerChunk = 64; | 293 static const int kFinalizablePersistentHandlesPerChunk = 64; |
| 292 static const int kOffsetOfRawPtrInWeakPersistentHandle = 0; | 294 static const int kOffsetOfRawPtrInFinalizablePersistentHandle = 0; |
| 293 class WeakPersistentHandles : Handles<kWeakPersistentHandleSizeInWords, | 295 class FinalizablePersistentHandles |
| 294 kWeakPersistentHandlesPerChunk, | 296 : Handles<kFinalizablePersistentHandleSizeInWords, |
| 295 kOffsetOfRawPtrInWeakPersistentHandle> { | 297 kFinalizablePersistentHandlesPerChunk, |
| 298 kOffsetOfRawPtrInFinalizablePersistentHandle> { |
| 296 public: | 299 public: |
| 297 WeakPersistentHandles() : Handles<kWeakPersistentHandleSizeInWords, | 300 FinalizablePersistentHandles() |
| 298 kWeakPersistentHandlesPerChunk, | 301 : Handles<kFinalizablePersistentHandleSizeInWords, |
| 299 kOffsetOfRawPtrInWeakPersistentHandle>(), | 302 kFinalizablePersistentHandlesPerChunk, |
| 300 free_list_(NULL) { } | 303 kOffsetOfRawPtrInFinalizablePersistentHandle>(), |
| 301 ~WeakPersistentHandles() { | 304 free_list_(NULL) { } |
| 305 ~FinalizablePersistentHandles() { |
| 302 free_list_ = NULL; | 306 free_list_ = NULL; |
| 303 } | 307 } |
| 304 | 308 |
| 305 // Accessors. | 309 // Accessors. |
| 306 WeakPersistentHandle* free_list() const { return free_list_; } | 310 FinalizablePersistentHandle* free_list() const { return free_list_; } |
| 307 void set_free_list(WeakPersistentHandle* value) { free_list_ = value; } | 311 void set_free_list(FinalizablePersistentHandle* value) { free_list_ = value; } |
| 308 | 312 |
| 309 // Visit all handles stored in the various handle blocks. | 313 // Visit all handles stored in the various handle blocks. |
| 310 void VisitWeakPersistentHandles(HandleVisitor* visitor) { | 314 void VisitHandles(HandleVisitor* visitor) { |
| 311 Handles<kWeakPersistentHandleSizeInWords, | 315 Handles<kFinalizablePersistentHandleSizeInWords, |
| 312 kWeakPersistentHandlesPerChunk, | 316 kFinalizablePersistentHandlesPerChunk, |
| 313 kOffsetOfRawPtrInWeakPersistentHandle>::Visit(visitor); | 317 kOffsetOfRawPtrInFinalizablePersistentHandle>::Visit(visitor); |
| 318 } |
| 319 |
| 320 // Visit all object pointers stored in the various handles. |
| 321 void VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 322 Handles<kFinalizablePersistentHandleSizeInWords, |
| 323 kFinalizablePersistentHandlesPerChunk, |
| 324 kOffsetOfRawPtrInFinalizablePersistentHandle>::VisitObjectPointers( |
| 325 visitor); |
| 314 } | 326 } |
| 315 | 327 |
| 316 // Allocates a persistent handle, these have to be destroyed explicitly | 328 // Allocates a persistent handle, these have to be destroyed explicitly |
| 317 // by calling FreeHandle. | 329 // by calling FreeHandle. |
| 318 WeakPersistentHandle* AllocateHandle() { | 330 FinalizablePersistentHandle* AllocateHandle() { |
| 319 WeakPersistentHandle* handle; | 331 FinalizablePersistentHandle* handle; |
| 320 if (free_list_ != NULL) { | 332 if (free_list_ != NULL) { |
| 321 handle = free_list_; | 333 handle = free_list_; |
| 322 free_list_ = handle->Next(); | 334 free_list_ = handle->Next(); |
| 323 } else { | 335 } else { |
| 324 handle = reinterpret_cast<WeakPersistentHandle*>(AllocateScopedHandle()); | 336 handle = reinterpret_cast<FinalizablePersistentHandle*>( |
| 337 AllocateScopedHandle()); |
| 325 } | 338 } |
| 326 handle->set_callback(NULL); | 339 handle->set_callback(NULL); |
| 327 return handle; | 340 return handle; |
| 328 } | 341 } |
| 329 | 342 |
| 330 void FreeHandle(WeakPersistentHandle* handle) { | 343 void FreeHandle(FinalizablePersistentHandle* handle) { |
| 331 handle->FreeHandle(free_list()); | 344 handle->FreeHandle(free_list()); |
| 332 set_free_list(handle); | 345 set_free_list(handle); |
| 333 } | 346 } |
| 334 | 347 |
| 335 // Validate if passed in handle is a Persistent Handle. | 348 // Validate if passed in handle is a Persistent Handle. |
| 336 bool IsValidHandle(Dart_Handle object) const { | 349 bool IsValidHandle(Dart_Handle object) const { |
| 337 return IsValidScopedHandle(reinterpret_cast<uword>(object)); | 350 return IsValidScopedHandle(reinterpret_cast<uword>(object)); |
| 338 } | 351 } |
| 339 | 352 |
| 340 // Returns a count of active handles (used for testing purposes). | 353 // Returns a count of active handles (used for testing purposes). |
| 341 int CountHandles() const { | 354 int CountHandles() const { |
| 342 return CountScopedHandles(); | 355 return CountScopedHandles(); |
| 343 } | 356 } |
| 344 | 357 |
| 345 private: | 358 private: |
| 346 WeakPersistentHandle* free_list_; | 359 FinalizablePersistentHandle* free_list_; |
| 347 DISALLOW_COPY_AND_ASSIGN(WeakPersistentHandles); | 360 DISALLOW_COPY_AND_ASSIGN(FinalizablePersistentHandles); |
| 348 }; | 361 }; |
| 349 | 362 |
| 350 | 363 |
| 351 class WeakReference { | 364 class WeakReference { |
| 352 public: | 365 public: |
| 353 WeakReference(Dart_Handle* keys, intptr_t keys_length, | 366 WeakReference(Dart_Handle* keys, intptr_t keys_length, |
| 354 Dart_Handle* values, intptr_t values_length) | 367 Dart_Handle* values, intptr_t values_length) |
| 355 : next_(NULL), | 368 : next_(NULL), |
| 356 keys_(keys), num_keys_(keys_length), | 369 keys_(keys), num_keys_(keys_length), |
| 357 values_(values), num_values_(values_length) { | 370 values_(values), num_values_(values_length) { |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 } | 464 } |
| 452 if (false_ != NULL) { | 465 if (false_ != NULL) { |
| 453 persistent_handles().FreeHandle(false_); | 466 persistent_handles().FreeHandle(false_); |
| 454 false_ = NULL; | 467 false_ = NULL; |
| 455 } | 468 } |
| 456 } | 469 } |
| 457 | 470 |
| 458 // Accessors. | 471 // Accessors. |
| 459 ApiLocalScope* top_scope() const { return top_scope_; } | 472 ApiLocalScope* top_scope() const { return top_scope_; } |
| 460 void set_top_scope(ApiLocalScope* value) { top_scope_ = value; } | 473 void set_top_scope(ApiLocalScope* value) { top_scope_ = value; } |
| 474 |
| 461 PersistentHandles& persistent_handles() { return persistent_handles_; } | 475 PersistentHandles& persistent_handles() { return persistent_handles_; } |
| 462 WeakPersistentHandles& weak_persistent_handles() { | 476 |
| 477 FinalizablePersistentHandles& weak_persistent_handles() { |
| 463 return weak_persistent_handles_; | 478 return weak_persistent_handles_; |
| 464 } | 479 } |
| 480 |
| 481 FinalizablePersistentHandles& prologue_weak_persistent_handles() { |
| 482 return prologue_weak_persistent_handles_; |
| 483 } |
| 484 |
| 465 WeakReference* delayed_weak_references() { return delayed_weak_references_; } | 485 WeakReference* delayed_weak_references() { return delayed_weak_references_; } |
| 466 void set_delayed_weak_references(WeakReference* reference) { | 486 void set_delayed_weak_references(WeakReference* reference) { |
| 467 delayed_weak_references_ = reference; | 487 delayed_weak_references_ = reference; |
| 468 } | 488 } |
| 489 |
| 469 void UnwindScopes(uword sp) { | 490 void UnwindScopes(uword sp) { |
| 470 while (top_scope_ != NULL && top_scope_->stack_marker() < sp) { | 491 while (top_scope_ != NULL && top_scope_->stack_marker() < sp) { |
| 471 ApiLocalScope* scope = top_scope_; | 492 ApiLocalScope* scope = top_scope_; |
| 472 top_scope_ = top_scope_->previous(); | 493 top_scope_ = top_scope_->previous(); |
| 473 delete scope; | 494 delete scope; |
| 474 } | 495 } |
| 475 } | 496 } |
| 476 | 497 |
| 477 void VisitObjectPointers(ObjectPointerVisitor* visitor) { | 498 void VisitObjectPointers(ObjectPointerVisitor* visitor, |
| 499 bool visit_prologue_weak_handles) { |
| 478 ApiLocalScope* scope = top_scope_; | 500 ApiLocalScope* scope = top_scope_; |
| 479 while (scope != NULL) { | 501 while (scope != NULL) { |
| 480 scope->local_handles()->VisitObjectPointers(visitor); | 502 scope->local_handles()->VisitObjectPointers(visitor); |
| 481 scope = scope->previous(); | 503 scope = scope->previous(); |
| 482 } | 504 } |
| 483 persistent_handles().VisitObjectPointers(visitor); | 505 persistent_handles().VisitObjectPointers(visitor); |
| 506 if (visit_prologue_weak_handles) { |
| 507 prologue_weak_persistent_handles().VisitObjectPointers(visitor); |
| 508 } |
| 484 } | 509 } |
| 485 | 510 |
| 486 void VisitWeakHandles(HandleVisitor* visitor) { | 511 void VisitWeakHandles(HandleVisitor* visitor, |
| 487 weak_persistent_handles().VisitWeakPersistentHandles(visitor); | 512 bool visit_prologue_weak_handles) { |
| 513 weak_persistent_handles().VisitHandles(visitor); |
| 514 if (visit_prologue_weak_handles) { |
| 515 prologue_weak_persistent_handles().VisitHandles(visitor); |
| 516 } |
| 488 } | 517 } |
| 489 | 518 |
| 490 bool IsValidLocalHandle(Dart_Handle object) const { | 519 bool IsValidLocalHandle(Dart_Handle object) const { |
| 491 ApiLocalScope* scope = top_scope_; | 520 ApiLocalScope* scope = top_scope_; |
| 492 while (scope != NULL) { | 521 while (scope != NULL) { |
| 493 if (scope->local_handles()->IsValidHandle(object)) { | 522 if (scope->local_handles()->IsValidHandle(object)) { |
| 494 return true; | 523 return true; |
| 495 } | 524 } |
| 496 scope = scope->previous(); | 525 scope = scope->previous(); |
| 497 } | 526 } |
| 498 return false; | 527 return false; |
| 499 } | 528 } |
| 500 | 529 |
| 501 bool IsValidPersistentHandle(Dart_Handle object) const { | 530 bool IsValidPersistentHandle(Dart_Handle object) const { |
| 502 return persistent_handles_.IsValidHandle(object); | 531 return persistent_handles_.IsValidHandle(object); |
| 503 } | 532 } |
| 504 | 533 |
| 505 bool IsValidWeakPersistentHandle(Dart_Handle object) const { | 534 bool IsValidWeakPersistentHandle(Dart_Handle object) const { |
| 506 return weak_persistent_handles_.IsValidHandle(object); | 535 return weak_persistent_handles_.IsValidHandle(object); |
| 507 } | 536 } |
| 508 | 537 |
| 538 bool IsValidPrologueWeakPersistentHandle(Dart_Handle object) const { |
| 539 return prologue_weak_persistent_handles_.IsValidHandle(object); |
| 540 } |
| 541 |
| 509 bool IsProtectedHandle(PersistentHandle* object) const { | 542 bool IsProtectedHandle(PersistentHandle* object) const { |
| 510 if (object == NULL) return false; | 543 if (object == NULL) return false; |
| 511 return object == null_ || object == true_ || object == false_; | 544 return object == null_ || object == true_ || object == false_; |
| 512 } | 545 } |
| 513 | 546 |
| 514 int CountLocalHandles() const { | 547 int CountLocalHandles() const { |
| 515 int total = 0; | 548 int total = 0; |
| 516 ApiLocalScope* scope = top_scope_; | 549 ApiLocalScope* scope = top_scope_; |
| 517 while (scope != NULL) { | 550 while (scope != NULL) { |
| 518 total += scope->local_handles()->CountHandles(); | 551 total += scope->local_handles()->CountHandles(); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 562 } | 595 } |
| 563 return false_; | 596 return false_; |
| 564 } | 597 } |
| 565 | 598 |
| 566 void DelayWeakReference(WeakReference* reference) { | 599 void DelayWeakReference(WeakReference* reference) { |
| 567 WeakReference::Push(reference, &delayed_weak_references_); | 600 WeakReference::Push(reference, &delayed_weak_references_); |
| 568 } | 601 } |
| 569 | 602 |
| 570 private: | 603 private: |
| 571 PersistentHandles persistent_handles_; | 604 PersistentHandles persistent_handles_; |
| 572 WeakPersistentHandles weak_persistent_handles_; | 605 FinalizablePersistentHandles weak_persistent_handles_; |
| 606 FinalizablePersistentHandles prologue_weak_persistent_handles_; |
| 573 ApiLocalScope* top_scope_; | 607 ApiLocalScope* top_scope_; |
| 574 WeakReference* delayed_weak_references_; | 608 WeakReference* delayed_weak_references_; |
| 575 | 609 |
| 576 // Persistent handles to important objects. | 610 // Persistent handles to important objects. |
| 577 PersistentHandle* null_; | 611 PersistentHandle* null_; |
| 578 PersistentHandle* true_; | 612 PersistentHandle* true_; |
| 579 PersistentHandle* false_; | 613 PersistentHandle* false_; |
| 580 | 614 |
| 581 DISALLOW_COPY_AND_ASSIGN(ApiState); | 615 DISALLOW_COPY_AND_ASSIGN(ApiState); |
| 582 }; | 616 }; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 621 ApiNativeScope::Current()->zone()->GetBaseZone()) {} | 655 ApiNativeScope::Current()->zone()->GetBaseZone()) {} |
| 622 ApiGrowableArray() | 656 ApiGrowableArray() |
| 623 : BaseGrowableArray<T, ValueObject>( | 657 : BaseGrowableArray<T, ValueObject>( |
| 624 ApiNativeScope::Current()->zone()->GetBaseZone()) {} | 658 ApiNativeScope::Current()->zone()->GetBaseZone()) {} |
| 625 }; | 659 }; |
| 626 | 660 |
| 627 | 661 |
| 628 } // namespace dart | 662 } // namespace dart |
| 629 | 663 |
| 630 #endif // VM_DART_API_STATE_H_ | 664 #endif // VM_DART_API_STATE_H_ |
| OLD | NEW |