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