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 |