Chromium Code Reviews| 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/utils.h" | 10 #include "platform/utils.h" |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 196 DISALLOW_COPY_AND_ASSIGN(PersistentHandle); | 196 DISALLOW_COPY_AND_ASSIGN(PersistentHandle); |
| 197 }; | 197 }; |
| 198 | 198 |
| 199 | 199 |
| 200 // Implementation of persistent handles which are handed out through the | 200 // Implementation of persistent handles which are handed out through the |
| 201 // dart API. | 201 // dart API. |
| 202 class FinalizablePersistentHandle { | 202 class FinalizablePersistentHandle { |
| 203 public: | 203 public: |
| 204 static FinalizablePersistentHandle* New( | 204 static FinalizablePersistentHandle* New( |
| 205 Isolate* isolate, | 205 Isolate* isolate, |
| 206 bool is_prologue, | |
| 207 const Object& object, | 206 const Object& object, |
| 208 void* peer, | 207 void* peer, |
| 209 Dart_WeakPersistentHandleFinalizer callback, | 208 Dart_WeakPersistentHandleFinalizer callback, |
| 210 intptr_t external_size); | 209 intptr_t external_size); |
| 211 | 210 |
| 212 // Accessors. | 211 // Accessors. |
| 213 RawObject* raw() const { return raw_; } | 212 RawObject* raw() const { return raw_; } |
| 214 RawObject** raw_addr() { return &raw_; } | 213 RawObject** raw_addr() { return &raw_; } |
| 215 static intptr_t raw_offset() { | 214 static intptr_t raw_offset() { |
| 216 return OFFSET_OF(FinalizablePersistentHandle, raw_); | 215 return OFFSET_OF(FinalizablePersistentHandle, raw_); |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 244 } | 243 } |
| 245 } | 244 } |
| 246 | 245 |
| 247 // Idempotent. Called when the handle is explicitly deleted or the | 246 // Idempotent. Called when the handle is explicitly deleted or the |
| 248 // referent becomes unreachable. | 247 // referent becomes unreachable. |
| 249 void EnsureFreeExternal(Isolate* isolate) { | 248 void EnsureFreeExternal(Isolate* isolate) { |
| 250 isolate->heap()->FreeExternal(external_size(), SpaceForExternal()); | 249 isolate->heap()->FreeExternal(external_size(), SpaceForExternal()); |
| 251 set_external_size(0); | 250 set_external_size(0); |
| 252 } | 251 } |
| 253 | 252 |
| 254 bool IsPrologueWeakPersistent() { | |
| 255 return PrologueWeakBit::decode(external_data_); | |
| 256 } | |
| 257 | |
| 258 void SetPrologueWeakPersistent(bool value) { | |
| 259 external_data_ = PrologueWeakBit::update(value, external_data_); | |
| 260 } | |
| 261 | |
| 262 static FinalizablePersistentHandle* Cast(Dart_WeakPersistentHandle handle); | 253 static FinalizablePersistentHandle* Cast(Dart_WeakPersistentHandle handle); |
| 263 | 254 |
| 264 private: | 255 private: |
| 265 enum { | 256 enum { |
| 266 kExternalNewSpaceBit = 0, | 257 kExternalNewSpaceBit = 0, |
| 267 kPrologueWeakBit = 1, | 258 kExternalSizeBits = 1, |
| 268 kExternalSizeBits = 2, | |
| 269 kExternalSizeBitsSize = (kBitsPerWord - 2), | 259 kExternalSizeBitsSize = (kBitsPerWord - 2), |
|
Ivan Posva
2015/11/20 04:52:05
Should this be "(kBitsPerWord - 1)" now that we ha
siva
2015/11/20 17:11:42
Done.
| |
| 270 }; | 260 }; |
| 271 | 261 |
| 272 // This part of external_data_ is the number of externally allocated bytes. | 262 // This part of external_data_ is the number of externally allocated bytes. |
| 273 // TODO(koda): Measure size in words instead. | 263 // TODO(koda): Measure size in words instead. |
| 274 class ExternalSizeBits : public BitField<intptr_t, | 264 class ExternalSizeBits : public BitField<intptr_t, |
| 275 kExternalSizeBits, | 265 kExternalSizeBits, |
| 276 kExternalSizeBitsSize> {}; // NOLINT | 266 kExternalSizeBitsSize> {}; // NOLINT |
| 277 // This bit of external_data_ is true if the referent was created in new | 267 // This bit of external_data_ is true if the referent was created in new |
| 278 // space and UpdateRelocated has not yet detected any promotion. | 268 // space and UpdateRelocated has not yet detected any promotion. |
| 279 class ExternalNewSpaceBit : public BitField<bool, kExternalNewSpaceBit, 1> {}; | 269 class ExternalNewSpaceBit : public BitField<bool, kExternalNewSpaceBit, 1> {}; |
| 280 // This bit is used to indicate that it is a prologue weak persistent handle. | |
| 281 class PrologueWeakBit : public BitField<bool, kPrologueWeakBit, 1> {}; | |
| 282 | 270 |
| 283 friend class FinalizablePersistentHandles; | 271 friend class FinalizablePersistentHandles; |
| 284 | 272 |
| 285 FinalizablePersistentHandle() | 273 FinalizablePersistentHandle() |
| 286 : raw_(NULL), | 274 : raw_(NULL), |
| 287 peer_(NULL), | 275 peer_(NULL), |
| 288 external_data_(0), | 276 external_data_(0), |
| 289 callback_(NULL) { } | 277 callback_(NULL) { } |
| 290 ~FinalizablePersistentHandle() { } | 278 ~FinalizablePersistentHandle() { } |
| 291 | 279 |
| (...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 666 initial_capacity, | 654 initial_capacity, |
| 667 ApiNativeScope::Current()->zone()) {} | 655 ApiNativeScope::Current()->zone()) {} |
| 668 ApiGrowableArray() | 656 ApiGrowableArray() |
| 669 : BaseGrowableArray<T, ValueObject>( | 657 : BaseGrowableArray<T, ValueObject>( |
| 670 ApiNativeScope::Current()->zone()) {} | 658 ApiNativeScope::Current()->zone()) {} |
| 671 ApiGrowableArray(intptr_t initial_capacity, Zone* zone) | 659 ApiGrowableArray(intptr_t initial_capacity, Zone* zone) |
| 672 : BaseGrowableArray<T, ValueObject>(initial_capacity, zone) {} | 660 : BaseGrowableArray<T, ValueObject>(initial_capacity, zone) {} |
| 673 }; | 661 }; |
| 674 | 662 |
| 675 | 663 |
| 676 // Forward declarations. | |
| 677 class WeakReferenceSetBuilder; | |
| 678 class WeakReferenceSet; | |
| 679 | |
| 680 | |
| 681 // Implementation of the API State used in dart api for maintaining | 664 // Implementation of the API State used in dart api for maintaining |
| 682 // local scopes, persistent handles etc. These are setup on a per isolate | 665 // local scopes, persistent handles etc. These are setup on a per isolate |
| 683 // basis and destroyed when the isolate is shutdown. | 666 // basis and destroyed when the isolate is shutdown. |
| 684 class ApiState { | 667 class ApiState { |
| 685 public: | 668 public: |
| 686 ApiState() : persistent_handles_(), | 669 ApiState() : persistent_handles_(), |
| 687 weak_persistent_handles_(), | 670 weak_persistent_handles_(), |
| 688 prologue_weak_persistent_handles_(), | |
| 689 reusable_scope_(NULL), | 671 reusable_scope_(NULL), |
| 690 top_scope_(NULL), | 672 top_scope_(NULL), |
| 691 delayed_weak_reference_sets_(NULL), | |
| 692 null_(NULL), | 673 null_(NULL), |
| 693 true_(NULL), | 674 true_(NULL), |
| 694 false_(NULL), | 675 false_(NULL), |
| 695 acquired_error_(NULL) {} | 676 acquired_error_(NULL) {} |
| 696 ~ApiState() { | 677 ~ApiState() { |
| 697 while (top_scope_ != NULL) { | 678 while (top_scope_ != NULL) { |
| 698 ApiLocalScope* scope = top_scope_; | 679 ApiLocalScope* scope = top_scope_; |
| 699 top_scope_ = top_scope_->previous(); | 680 top_scope_ = top_scope_->previous(); |
| 700 delete scope; | 681 delete scope; |
| 701 } | 682 } |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 725 } | 706 } |
| 726 ApiLocalScope* top_scope() const { return top_scope_; } | 707 ApiLocalScope* top_scope() const { return top_scope_; } |
| 727 void set_top_scope(ApiLocalScope* value) { top_scope_ = value; } | 708 void set_top_scope(ApiLocalScope* value) { top_scope_ = value; } |
| 728 | 709 |
| 729 PersistentHandles& persistent_handles() { return persistent_handles_; } | 710 PersistentHandles& persistent_handles() { return persistent_handles_; } |
| 730 | 711 |
| 731 FinalizablePersistentHandles& weak_persistent_handles() { | 712 FinalizablePersistentHandles& weak_persistent_handles() { |
| 732 return weak_persistent_handles_; | 713 return weak_persistent_handles_; |
| 733 } | 714 } |
| 734 | 715 |
| 735 FinalizablePersistentHandles& prologue_weak_persistent_handles() { | |
| 736 return prologue_weak_persistent_handles_; | |
| 737 } | |
| 738 | |
| 739 WeakReferenceSet* delayed_weak_reference_sets() { | |
| 740 return delayed_weak_reference_sets_; | |
| 741 } | |
| 742 void set_delayed_weak_reference_sets(WeakReferenceSet* reference_set) { | |
| 743 delayed_weak_reference_sets_ = reference_set; | |
| 744 } | |
| 745 | |
| 746 void UnwindScopes(uword stack_marker) { | 716 void UnwindScopes(uword stack_marker) { |
| 747 // Unwind all scopes using the same stack_marker, i.e. all scopes allocated | 717 // Unwind all scopes using the same stack_marker, i.e. all scopes allocated |
| 748 // under the same top_exit_frame_info. | 718 // under the same top_exit_frame_info. |
| 749 while (top_scope_ != NULL && | 719 while (top_scope_ != NULL && |
| 750 top_scope_->stack_marker() != 0 && | 720 top_scope_->stack_marker() != 0 && |
| 751 top_scope_->stack_marker() == stack_marker) { | 721 top_scope_->stack_marker() == stack_marker) { |
| 752 ApiLocalScope* scope = top_scope_; | 722 ApiLocalScope* scope = top_scope_; |
| 753 top_scope_ = top_scope_->previous(); | 723 top_scope_ = top_scope_->previous(); |
| 754 delete scope; | 724 delete scope; |
| 755 } | 725 } |
| 756 } | 726 } |
| 757 | 727 |
| 758 void VisitObjectPointers(ObjectPointerVisitor* visitor, | 728 void VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 759 bool visit_prologue_weak_handles) { | |
| 760 ApiLocalScope* scope = top_scope_; | 729 ApiLocalScope* scope = top_scope_; |
| 761 while (scope != NULL) { | 730 while (scope != NULL) { |
| 762 scope->local_handles()->VisitObjectPointers(visitor); | 731 scope->local_handles()->VisitObjectPointers(visitor); |
| 763 scope = scope->previous(); | 732 scope = scope->previous(); |
| 764 } | 733 } |
| 765 persistent_handles().VisitObjectPointers(visitor); | 734 persistent_handles().VisitObjectPointers(visitor); |
| 766 if (visit_prologue_weak_handles) { | |
| 767 prologue_weak_persistent_handles().VisitObjectPointers(visitor); | |
| 768 } | |
| 769 } | 735 } |
| 770 | 736 |
| 771 void VisitWeakHandles(HandleVisitor* visitor, | 737 void VisitWeakHandles(HandleVisitor* visitor) { |
| 772 bool visit_prologue_weak_handles) { | |
| 773 weak_persistent_handles().VisitHandles(visitor); | 738 weak_persistent_handles().VisitHandles(visitor); |
| 774 if (visit_prologue_weak_handles) { | |
| 775 prologue_weak_persistent_handles().VisitHandles(visitor); | |
| 776 } | |
| 777 } | |
| 778 | |
| 779 void VisitPrologueWeakHandles(HandleVisitor* visitor) { | |
| 780 prologue_weak_persistent_handles().VisitHandles(visitor); | |
| 781 } | 739 } |
| 782 | 740 |
| 783 bool IsValidLocalHandle(Dart_Handle object) const { | 741 bool IsValidLocalHandle(Dart_Handle object) const { |
| 784 ApiLocalScope* scope = top_scope_; | 742 ApiLocalScope* scope = top_scope_; |
| 785 while (scope != NULL) { | 743 while (scope != NULL) { |
| 786 if (scope->local_handles()->IsValidHandle(object)) { | 744 if (scope->local_handles()->IsValidHandle(object)) { |
| 787 return true; | 745 return true; |
| 788 } | 746 } |
| 789 scope = scope->previous(); | 747 scope = scope->previous(); |
| 790 } | 748 } |
| 791 return false; | 749 return false; |
| 792 } | 750 } |
| 793 | 751 |
| 794 bool IsValidPersistentHandle(Dart_PersistentHandle object) const { | 752 bool IsValidPersistentHandle(Dart_PersistentHandle object) const { |
| 795 return persistent_handles_.IsValidHandle(object); | 753 return persistent_handles_.IsValidHandle(object); |
| 796 } | 754 } |
| 797 | 755 |
| 798 bool IsValidWeakPersistentHandle(Dart_WeakPersistentHandle object) const { | 756 bool IsValidWeakPersistentHandle(Dart_WeakPersistentHandle object) const { |
| 799 return weak_persistent_handles_.IsValidHandle(object); | 757 return weak_persistent_handles_.IsValidHandle(object); |
| 800 } | 758 } |
| 801 | 759 |
| 802 bool IsValidPrologueWeakPersistentHandle( | |
| 803 Dart_WeakPersistentHandle object) const { | |
| 804 return prologue_weak_persistent_handles_.IsValidHandle(object); | |
| 805 } | |
| 806 | |
| 807 bool IsProtectedHandle(PersistentHandle* object) const { | 760 bool IsProtectedHandle(PersistentHandle* object) const { |
| 808 if (object == NULL) return false; | 761 if (object == NULL) return false; |
| 809 return object == null_ || object == true_ || object == false_; | 762 return object == null_ || object == true_ || object == false_; |
| 810 } | 763 } |
| 811 | 764 |
| 812 int CountLocalHandles() const { | 765 int CountLocalHandles() const { |
| 813 int total = 0; | 766 int total = 0; |
| 814 ApiLocalScope* scope = top_scope_; | 767 ApiLocalScope* scope = top_scope_; |
| 815 while (scope != NULL) { | 768 while (scope != NULL) { |
| 816 total += scope->local_handles()->CountHandles(); | 769 total += scope->local_handles()->CountHandles(); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 838 "please release them using Dart_TypedDataReleaseData.")); | 791 "please release them using Dart_TypedDataReleaseData.")); |
| 839 acquired_error_ = persistent_handles().AllocateHandle(); | 792 acquired_error_ = persistent_handles().AllocateHandle(); |
| 840 acquired_error_->set_raw(ApiError::New(msg)); | 793 acquired_error_->set_raw(ApiError::New(msg)); |
| 841 } | 794 } |
| 842 | 795 |
| 843 PersistentHandle* AcquiredError() const { | 796 PersistentHandle* AcquiredError() const { |
| 844 ASSERT(acquired_error_ != NULL); | 797 ASSERT(acquired_error_ != NULL); |
| 845 return acquired_error_; | 798 return acquired_error_; |
| 846 } | 799 } |
| 847 | 800 |
| 848 WeakReferenceSetBuilder* NewWeakReferenceSetBuilder(); | |
| 849 | |
| 850 void DelayWeakReferenceSet(WeakReferenceSet* reference_set); | |
| 851 | |
| 852 WeakTable* acquired_table() { return &acquired_table_; } | 801 WeakTable* acquired_table() { return &acquired_table_; } |
| 853 | 802 |
| 854 private: | 803 private: |
| 855 PersistentHandles persistent_handles_; | 804 PersistentHandles persistent_handles_; |
| 856 FinalizablePersistentHandles weak_persistent_handles_; | 805 FinalizablePersistentHandles weak_persistent_handles_; |
| 857 FinalizablePersistentHandles prologue_weak_persistent_handles_; | |
| 858 ApiLocalScope* reusable_scope_; | 806 ApiLocalScope* reusable_scope_; |
| 859 ApiLocalScope* top_scope_; | 807 ApiLocalScope* top_scope_; |
| 860 WeakReferenceSet* delayed_weak_reference_sets_; | |
| 861 WeakTable acquired_table_; | 808 WeakTable acquired_table_; |
| 862 | 809 |
| 863 // Persistent handles to important objects. | 810 // Persistent handles to important objects. |
| 864 PersistentHandle* null_; | 811 PersistentHandle* null_; |
| 865 PersistentHandle* true_; | 812 PersistentHandle* true_; |
| 866 PersistentHandle* false_; | 813 PersistentHandle* false_; |
| 867 PersistentHandle* acquired_error_; | 814 PersistentHandle* acquired_error_; |
| 868 | 815 |
| 869 DISALLOW_COPY_AND_ASSIGN(ApiState); | 816 DISALLOW_COPY_AND_ASSIGN(ApiState); |
| 870 }; | 817 }; |
| 871 | 818 |
| 872 | 819 |
| 873 class WeakReferenceSet { | |
| 874 public: | |
| 875 explicit WeakReferenceSet(Zone* zone) | |
| 876 : next_(NULL), | |
| 877 keys_(1, zone), | |
| 878 values_(1, zone) { | |
| 879 } | |
| 880 ~WeakReferenceSet() {} | |
| 881 | |
| 882 WeakReferenceSet* next() const { return next_; } | |
| 883 | |
| 884 intptr_t num_keys() const { return keys_.length(); } | |
| 885 RawObject** get_key(intptr_t i) { | |
| 886 ASSERT(i >= 0); | |
| 887 ASSERT(i < num_keys()); | |
| 888 FinalizablePersistentHandle* ref = | |
| 889 FinalizablePersistentHandle::Cast(keys_[i]); | |
| 890 return ref->raw_addr(); | |
| 891 } | |
| 892 | |
| 893 intptr_t num_values() const { return values_.length(); } | |
| 894 RawObject** get_value(intptr_t i) { | |
| 895 ASSERT(i >= 0); | |
| 896 ASSERT(i < num_values()); | |
| 897 FinalizablePersistentHandle* ref = | |
| 898 FinalizablePersistentHandle::Cast(values_[i]); | |
| 899 return ref->raw_addr(); | |
| 900 } | |
| 901 | |
| 902 bool SingletonKeyEqualsValue() const { | |
| 903 ASSERT((num_keys() == 1) && (num_values() == 1)); | |
| 904 return (keys_[0] == values_[0]); | |
| 905 } | |
| 906 | |
| 907 void Append(Dart_WeakPersistentHandle key, Dart_WeakPersistentHandle value) { | |
| 908 keys_.Add(key); | |
| 909 values_.Add(value); | |
| 910 } | |
| 911 | |
| 912 void AppendKey(Dart_WeakPersistentHandle key) { | |
| 913 keys_.Add(key); | |
| 914 } | |
| 915 | |
| 916 void AppendValue(Dart_WeakPersistentHandle value) { | |
| 917 values_.Add(value); | |
| 918 } | |
| 919 | |
| 920 static WeakReferenceSet* Pop(WeakReferenceSet** queue) { | |
| 921 ASSERT(queue != NULL); | |
| 922 WeakReferenceSet* head = *queue; | |
| 923 if (head != NULL) { | |
| 924 *queue = head->next(); | |
| 925 head->next_ = NULL; | |
| 926 } | |
| 927 return head; | |
| 928 } | |
| 929 | |
| 930 static void Push(WeakReferenceSet* reference_set, WeakReferenceSet** queue) { | |
| 931 ASSERT(reference_set != NULL); | |
| 932 ASSERT(queue != NULL); | |
| 933 reference_set->next_ = *queue; | |
| 934 *queue = reference_set; | |
| 935 } | |
| 936 | |
| 937 void* operator new(uword size, Zone* zone) { | |
| 938 return reinterpret_cast<void*>(zone->AllocUnsafe(size)); | |
| 939 } | |
| 940 | |
| 941 // Disallow explicit deallocation of WeakReferenceSet. | |
| 942 void operator delete(void* pointer) { UNREACHABLE(); } | |
| 943 | |
| 944 private: | |
| 945 WeakReferenceSet* next_; | |
| 946 ApiGrowableArray<Dart_WeakPersistentHandle> keys_; | |
| 947 ApiGrowableArray<Dart_WeakPersistentHandle> values_; | |
| 948 | |
| 949 DISALLOW_COPY_AND_ASSIGN(WeakReferenceSet); | |
| 950 }; | |
| 951 | |
| 952 | |
| 953 class WeakReferenceSetBuilder { | |
| 954 public: | |
| 955 ApiState* api_state() const { | |
| 956 return api_state_; | |
| 957 } | |
| 958 | |
| 959 WeakReferenceSet* NewWeakReferenceSet() { | |
| 960 return new (zone_) WeakReferenceSet(zone_); | |
| 961 } | |
| 962 | |
| 963 private: | |
| 964 explicit WeakReferenceSetBuilder(ApiState* api_state) | |
| 965 : api_state_(api_state), | |
| 966 zone_(api_state->top_scope()->zone()) { | |
| 967 } | |
| 968 | |
| 969 ApiState* api_state_; | |
| 970 Zone* zone_; | |
| 971 | |
| 972 friend class ApiState; | |
| 973 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakReferenceSetBuilder); | |
| 974 }; | |
| 975 | |
| 976 | |
| 977 inline FinalizablePersistentHandle* FinalizablePersistentHandle::New( | 820 inline FinalizablePersistentHandle* FinalizablePersistentHandle::New( |
| 978 Isolate* isolate, | 821 Isolate* isolate, |
| 979 bool is_prologue, | |
| 980 const Object& object, | 822 const Object& object, |
| 981 void* peer, | 823 void* peer, |
| 982 Dart_WeakPersistentHandleFinalizer callback, | 824 Dart_WeakPersistentHandleFinalizer callback, |
| 983 intptr_t external_size) { | 825 intptr_t external_size) { |
| 984 ApiState* state = isolate->api_state(); | 826 ApiState* state = isolate->api_state(); |
| 985 ASSERT(state != NULL); | 827 ASSERT(state != NULL); |
| 986 FinalizablePersistentHandle* ref = is_prologue ? | 828 FinalizablePersistentHandle* ref = |
| 987 state->prologue_weak_persistent_handles().AllocateHandle() : | |
| 988 state->weak_persistent_handles().AllocateHandle(); | 829 state->weak_persistent_handles().AllocateHandle(); |
| 989 ref->SetPrologueWeakPersistent(is_prologue); | |
| 990 ref->set_raw(object); | 830 ref->set_raw(object); |
| 991 ref->set_peer(peer); | 831 ref->set_peer(peer); |
| 992 ref->set_callback(callback); | 832 ref->set_callback(callback); |
| 993 // This may trigger GC, so it must be called last. | 833 // This may trigger GC, so it must be called last. |
| 994 ref->SetExternalSize(external_size, isolate); | 834 ref->SetExternalSize(external_size, isolate); |
| 995 return ref; | 835 return ref; |
| 996 } | 836 } |
| 997 | 837 |
| 998 } // namespace dart | 838 } // namespace dart |
| 999 | 839 |
| 1000 #endif // VM_DART_API_STATE_H_ | 840 #endif // VM_DART_API_STATE_H_ |
| OLD | NEW |