| 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 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 551 int CountHandles() const { | 551 int CountHandles() const { |
| 552 return CountScopedHandles(); | 552 return CountScopedHandles(); |
| 553 } | 553 } |
| 554 | 554 |
| 555 private: | 555 private: |
| 556 FinalizablePersistentHandle* free_list_; | 556 FinalizablePersistentHandle* free_list_; |
| 557 DISALLOW_COPY_AND_ASSIGN(FinalizablePersistentHandles); | 557 DISALLOW_COPY_AND_ASSIGN(FinalizablePersistentHandles); |
| 558 }; | 558 }; |
| 559 | 559 |
| 560 | 560 |
| 561 class WeakReferenceSet { | |
| 562 public: | |
| 563 WeakReferenceSet(Dart_WeakPersistentHandle* keys, intptr_t keys_length, | |
| 564 Dart_WeakPersistentHandle* values, intptr_t values_length) | |
| 565 : next_(NULL), | |
| 566 keys_(keys), num_keys_(keys_length), | |
| 567 values_(values), num_values_(values_length) { | |
| 568 } | |
| 569 ~WeakReferenceSet() {} | |
| 570 | |
| 571 WeakReferenceSet* next() const { return next_; } | |
| 572 | |
| 573 intptr_t num_keys() const { return num_keys_; } | |
| 574 RawObject** get_key(intptr_t i) { | |
| 575 ASSERT(i >= 0); | |
| 576 ASSERT(i < num_keys_); | |
| 577 FinalizablePersistentHandle* ref = | |
| 578 FinalizablePersistentHandle::Cast(keys_[i]); | |
| 579 return ref->raw_addr(); | |
| 580 } | |
| 581 | |
| 582 intptr_t num_values() const { return num_values_; } | |
| 583 RawObject** get_value(intptr_t i) { | |
| 584 ASSERT(i >= 0); | |
| 585 ASSERT(i < num_values_); | |
| 586 FinalizablePersistentHandle* ref = | |
| 587 FinalizablePersistentHandle::Cast(values_[i]); | |
| 588 return ref->raw_addr(); | |
| 589 } | |
| 590 | |
| 591 static WeakReferenceSet* Pop(WeakReferenceSet** queue) { | |
| 592 ASSERT(queue != NULL); | |
| 593 WeakReferenceSet* head = *queue; | |
| 594 if (head != NULL) { | |
| 595 *queue = head->next(); | |
| 596 head->next_ = NULL; | |
| 597 } | |
| 598 return head; | |
| 599 } | |
| 600 | |
| 601 static void Push(WeakReferenceSet* reference_set, WeakReferenceSet** queue) { | |
| 602 ASSERT(reference_set != NULL); | |
| 603 ASSERT(queue != NULL); | |
| 604 reference_set->next_ = *queue; | |
| 605 *queue = reference_set; | |
| 606 } | |
| 607 | |
| 608 private: | |
| 609 WeakReferenceSet* next_; | |
| 610 Dart_WeakPersistentHandle* keys_; | |
| 611 intptr_t num_keys_; | |
| 612 Dart_WeakPersistentHandle* values_; | |
| 613 intptr_t num_values_; | |
| 614 DISALLOW_COPY_AND_ASSIGN(WeakReferenceSet); | |
| 615 }; | |
| 616 | |
| 617 | |
| 618 // Structure used for the implementation of local scopes used in dart_api. | 561 // Structure used for the implementation of local scopes used in dart_api. |
| 619 // These local scopes manage handles and memory allocated in the scope. | 562 // These local scopes manage handles and memory allocated in the scope. |
| 620 class ApiLocalScope { | 563 class ApiLocalScope { |
| 621 public: | 564 public: |
| 622 ApiLocalScope(ApiLocalScope* previous, uword stack_marker) : | 565 ApiLocalScope(ApiLocalScope* previous, uword stack_marker) : |
| 623 previous_(previous), stack_marker_(stack_marker) { } | 566 previous_(previous), stack_marker_(stack_marker) { } |
| 624 ~ApiLocalScope() { | 567 ~ApiLocalScope() { |
| 625 previous_ = NULL; | 568 previous_ = NULL; |
| 626 } | 569 } |
| 627 | 570 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 650 private: | 593 private: |
| 651 ApiLocalScope* previous_; | 594 ApiLocalScope* previous_; |
| 652 uword stack_marker_; | 595 uword stack_marker_; |
| 653 LocalHandles local_handles_; | 596 LocalHandles local_handles_; |
| 654 ApiZone zone_; | 597 ApiZone zone_; |
| 655 | 598 |
| 656 DISALLOW_COPY_AND_ASSIGN(ApiLocalScope); | 599 DISALLOW_COPY_AND_ASSIGN(ApiLocalScope); |
| 657 }; | 600 }; |
| 658 | 601 |
| 659 | 602 |
| 603 class ApiNativeScope { |
| 604 public: |
| 605 ApiNativeScope() { |
| 606 // Currently no support for nesting native scopes. |
| 607 ASSERT(Current() == NULL); |
| 608 Thread::SetThreadLocal(Api::api_native_key_, reinterpret_cast<uword>(this)); |
| 609 } |
| 610 |
| 611 ~ApiNativeScope() { |
| 612 ASSERT(Current() == this); |
| 613 Thread::SetThreadLocal(Api::api_native_key_, 0); |
| 614 } |
| 615 |
| 616 static inline ApiNativeScope* Current() { |
| 617 return reinterpret_cast<ApiNativeScope*>( |
| 618 Thread::GetThreadLocal(Api::api_native_key_)); |
| 619 } |
| 620 |
| 621 Zone* zone() { return zone_.GetZone(); } |
| 622 |
| 623 private: |
| 624 ApiZone zone_; |
| 625 }; |
| 626 |
| 627 |
| 628 // Api growable arrays use a zone for allocation. The constructor |
| 629 // picks the zone from the current isolate if in an isolate |
| 630 // environment. When outside an isolate environment it picks the zone |
| 631 // from the current native scope. |
| 632 template<typename T> |
| 633 class ApiGrowableArray : public BaseGrowableArray<T, ValueObject> { |
| 634 public: |
| 635 explicit ApiGrowableArray(int initial_capacity) |
| 636 : BaseGrowableArray<T, ValueObject>( |
| 637 initial_capacity, |
| 638 ApiNativeScope::Current()->zone()) {} |
| 639 ApiGrowableArray() |
| 640 : BaseGrowableArray<T, ValueObject>( |
| 641 ApiNativeScope::Current()->zone()) {} |
| 642 ApiGrowableArray(intptr_t initial_capacity, Zone* zone) |
| 643 : BaseGrowableArray<T, ValueObject>(initial_capacity, zone) {} |
| 644 }; |
| 645 |
| 646 |
| 647 // Forward declarations. |
| 648 class WeakReferenceSetBuilder; |
| 649 class WeakReferenceSet; |
| 650 |
| 651 |
| 660 // Implementation of the API State used in dart api for maintaining | 652 // Implementation of the API State used in dart api for maintaining |
| 661 // local scopes, persistent handles etc. These are setup on a per isolate | 653 // local scopes, persistent handles etc. These are setup on a per isolate |
| 662 // basis and destroyed when the isolate is shutdown. | 654 // basis and destroyed when the isolate is shutdown. |
| 663 class ApiState { | 655 class ApiState { |
| 664 public: | 656 public: |
| 665 ApiState() : persistent_handles_(), | 657 ApiState() : persistent_handles_(), |
| 666 weak_persistent_handles_(), | 658 weak_persistent_handles_(), |
| 667 prologue_weak_persistent_handles_(), | 659 prologue_weak_persistent_handles_(), |
| 668 reusable_scope_(NULL), | 660 reusable_scope_(NULL), |
| 669 top_scope_(NULL), | 661 top_scope_(NULL), |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 816 acquired_error_->set_raw( | 808 acquired_error_->set_raw( |
| 817 String::New("Internal Dart data pointers have been acquired, " | 809 String::New("Internal Dart data pointers have been acquired, " |
| 818 "please release them using Dart_TypedDataReleaseData.")); | 810 "please release them using Dart_TypedDataReleaseData.")); |
| 819 } | 811 } |
| 820 | 812 |
| 821 PersistentHandle* AcquiredError() const { | 813 PersistentHandle* AcquiredError() const { |
| 822 ASSERT(acquired_error_ != NULL); | 814 ASSERT(acquired_error_ != NULL); |
| 823 return acquired_error_; | 815 return acquired_error_; |
| 824 } | 816 } |
| 825 | 817 |
| 826 void DelayWeakReferenceSet(WeakReferenceSet* reference_set) { | 818 WeakReferenceSetBuilder* NewWeakReferenceSetBuilder(); |
| 827 WeakReferenceSet::Push(reference_set, &delayed_weak_reference_sets_); | 819 |
| 828 } | 820 void DelayWeakReferenceSet(WeakReferenceSet* reference_set); |
| 829 | 821 |
| 830 private: | 822 private: |
| 831 PersistentHandles persistent_handles_; | 823 PersistentHandles persistent_handles_; |
| 832 FinalizablePersistentHandles weak_persistent_handles_; | 824 FinalizablePersistentHandles weak_persistent_handles_; |
| 833 FinalizablePersistentHandles prologue_weak_persistent_handles_; | 825 FinalizablePersistentHandles prologue_weak_persistent_handles_; |
| 834 ApiLocalScope* reusable_scope_; | 826 ApiLocalScope* reusable_scope_; |
| 835 ApiLocalScope* top_scope_; | 827 ApiLocalScope* top_scope_; |
| 836 WeakReferenceSet* delayed_weak_reference_sets_; | 828 WeakReferenceSet* delayed_weak_reference_sets_; |
| 837 | 829 |
| 838 // Persistent handles to important objects. | 830 // Persistent handles to important objects. |
| 839 PersistentHandle* null_; | 831 PersistentHandle* null_; |
| 840 PersistentHandle* true_; | 832 PersistentHandle* true_; |
| 841 PersistentHandle* false_; | 833 PersistentHandle* false_; |
| 842 PersistentHandle* acquired_error_; | 834 PersistentHandle* acquired_error_; |
| 843 | 835 |
| 844 DISALLOW_COPY_AND_ASSIGN(ApiState); | 836 DISALLOW_COPY_AND_ASSIGN(ApiState); |
| 845 }; | 837 }; |
| 846 | 838 |
| 847 | 839 |
| 848 class ApiNativeScope { | 840 class WeakReferenceSet { |
| 849 public: | 841 public: |
| 850 ApiNativeScope() { | 842 explicit WeakReferenceSet(Zone* zone) |
| 851 // Currently no support for nesting native scopes. | 843 : next_(NULL), |
| 852 ASSERT(Current() == NULL); | 844 keys_(1, zone), |
| 853 Thread::SetThreadLocal(Api::api_native_key_, reinterpret_cast<uword>(this)); | 845 values_(1, zone) { |
| 846 } |
| 847 ~WeakReferenceSet() {} |
| 848 |
| 849 WeakReferenceSet* next() const { return next_; } |
| 850 |
| 851 intptr_t num_keys() const { return keys_.length(); } |
| 852 RawObject** get_key(intptr_t i) { |
| 853 ASSERT(i >= 0); |
| 854 ASSERT(i < num_keys()); |
| 855 FinalizablePersistentHandle* ref = |
| 856 FinalizablePersistentHandle::Cast(keys_[i]); |
| 857 return ref->raw_addr(); |
| 854 } | 858 } |
| 855 | 859 |
| 856 ~ApiNativeScope() { | 860 intptr_t num_values() const { return values_.length(); } |
| 857 ASSERT(Current() == this); | 861 RawObject** get_value(intptr_t i) { |
| 858 Thread::SetThreadLocal(Api::api_native_key_, 0); | 862 ASSERT(i >= 0); |
| 863 ASSERT(i < num_values()); |
| 864 FinalizablePersistentHandle* ref = |
| 865 FinalizablePersistentHandle::Cast(values_[i]); |
| 866 return ref->raw_addr(); |
| 859 } | 867 } |
| 860 | 868 |
| 861 static inline ApiNativeScope* Current() { | 869 bool SingletonKeyEqualsValue() const { |
| 862 return reinterpret_cast<ApiNativeScope*>( | 870 ASSERT((num_keys() == 1) && (num_values() == 1)); |
| 863 Thread::GetThreadLocal(Api::api_native_key_)); | 871 return (keys_[0] == values_[0]); |
| 864 } | 872 } |
| 865 | 873 |
| 866 Zone* zone() { return zone_.GetZone(); } | 874 void Append(Dart_WeakPersistentHandle key, Dart_WeakPersistentHandle value) { |
| 875 keys_.Add(key); |
| 876 values_.Add(value); |
| 877 } |
| 878 |
| 879 void AppendKey(Dart_WeakPersistentHandle key) { |
| 880 keys_.Add(key); |
| 881 } |
| 882 |
| 883 void AppendValue(Dart_WeakPersistentHandle value) { |
| 884 values_.Add(value); |
| 885 } |
| 886 |
| 887 static WeakReferenceSet* Pop(WeakReferenceSet** queue) { |
| 888 ASSERT(queue != NULL); |
| 889 WeakReferenceSet* head = *queue; |
| 890 if (head != NULL) { |
| 891 *queue = head->next(); |
| 892 head->next_ = NULL; |
| 893 } |
| 894 return head; |
| 895 } |
| 896 |
| 897 static void Push(WeakReferenceSet* reference_set, WeakReferenceSet** queue) { |
| 898 ASSERT(reference_set != NULL); |
| 899 ASSERT(queue != NULL); |
| 900 reference_set->next_ = *queue; |
| 901 *queue = reference_set; |
| 902 } |
| 903 |
| 904 void* operator new(uword size, Zone* zone) { |
| 905 return reinterpret_cast<void*>(zone->AllocUnsafe(size)); |
| 906 } |
| 907 |
| 908 // Disallow explicit deallocation of WeakReferenceSet. |
| 909 void operator delete(void* pointer) { UNREACHABLE(); } |
| 867 | 910 |
| 868 private: | 911 private: |
| 869 ApiZone zone_; | 912 WeakReferenceSet* next_; |
| 913 ApiGrowableArray<Dart_WeakPersistentHandle> keys_; |
| 914 ApiGrowableArray<Dart_WeakPersistentHandle> values_; |
| 915 |
| 916 DISALLOW_COPY_AND_ASSIGN(WeakReferenceSet); |
| 870 }; | 917 }; |
| 871 | 918 |
| 872 | 919 |
| 873 // Api growable arrays use a zone for allocation. The constructor | 920 class WeakReferenceSetBuilder { |
| 874 // picks the zone from the current isolate if in an isolate | |
| 875 // environment. When outside an isolate environment it picks the zone | |
| 876 // from the current native scope. | |
| 877 template<typename T> | |
| 878 class ApiGrowableArray : public BaseGrowableArray<T, ValueObject> { | |
| 879 public: | 921 public: |
| 880 explicit ApiGrowableArray(int initial_capacity) | 922 ApiState* api_state() const { |
| 881 : BaseGrowableArray<T, ValueObject>( | 923 return api_state_; |
| 882 initial_capacity, | 924 } |
| 883 ApiNativeScope::Current()->zone()) {} | 925 |
| 884 ApiGrowableArray() | 926 WeakReferenceSet* NewWeakReferenceSet() { |
| 885 : BaseGrowableArray<T, ValueObject>( | 927 return new (zone_) WeakReferenceSet(zone_); |
| 886 ApiNativeScope::Current()->zone()) {} | 928 } |
| 929 |
| 930 private: |
| 931 explicit WeakReferenceSetBuilder(ApiState* api_state) |
| 932 : api_state_(api_state), |
| 933 zone_(api_state->top_scope()->zone()) { |
| 934 } |
| 935 |
| 936 ApiState* api_state_; |
| 937 Zone* zone_; |
| 938 |
| 939 friend class ApiState; |
| 940 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakReferenceSetBuilder); |
| 887 }; | 941 }; |
| 888 | 942 |
| 889 | 943 |
| 890 } // namespace dart | 944 } // namespace dart |
| 891 | 945 |
| 892 #endif // VM_DART_API_STATE_H_ | 946 #endif // VM_DART_API_STATE_H_ |
| OLD | NEW |