Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(30)

Side by Side Diff: runtime/vm/dart_api_state.h

Issue 1459173004: Remove support for object grouping during Garbage Collection (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: code-review Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/dart_api_impl_test.cc ('k') | runtime/vm/gc_marker.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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, 259 kExternalSizeBitsSize = (kBitsPerWord - 1),
269 kExternalSizeBitsSize = (kBitsPerWord - 2),
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
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
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
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_
OLDNEW
« no previous file with comments | « runtime/vm/dart_api_impl_test.cc ('k') | runtime/vm/gc_marker.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698