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

Side by Side Diff: Source/platform/heap/Visitor.h

Issue 980653002: Oilpan: disable conservative GCs during initial GC mixin construction. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Switch to a static const for mixinLevels Created 5 years, 9 months 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 | « Source/platform/heap/ThreadState.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 879 matching lines...) Expand 10 before | Expand all | Expand 10 after
890 TraceTrait<TYPE>::trace(visitor, const_cast<TYPE*>(this)); \ 890 TraceTrait<TYPE>::trace(visitor, const_cast<TYPE*>(this)); \
891 return; \ 891 return; \
892 } \ 892 } \
893 visitor->mark(static_cast<const TYPE*>(this), &blink::TraceTrait<TYPE>:: trace); \ 893 visitor->mark(static_cast<const TYPE*>(this), &blink::TraceTrait<TYPE>:: trace); \
894 } \ 894 } \
895 virtual bool isHeapObjectAlive(VISITOR visitor) const override \ 895 virtual bool isHeapObjectAlive(VISITOR visitor) const override \
896 { \ 896 { \
897 return visitor->isAlive(this); \ 897 return visitor->isAlive(this); \
898 } \ 898 } \
899 private: 899 private:
900
901 // A C++ object's vptr will be initialized to its leftmost base's
902 // vtable after the constructors of all its subclasses have run,
903 // so if a subclass constructor tries to access any of the vtbl
904 // entries of its leftmost base prematurely, it'll find an as-yet
905 // incorrect vptr and fail. Which is exactly what a garbage collector
906 // will try to do if it tries to access the leftmost base while one
907 // of the subclass constructors of a GC mixin object triggers a GC.
908 // It is consequently not safe to allow any GCs while these objects
909 // are under (sub constructor) construction.
910 //
911 // To achieve that, the construction of mixins are handled in a
912 // special manner:
913 //
914 // - The initial allocation of the mixin object will enter a no GC scope.
915 // This is done by overriding 'operator new' for mixin instances.
916 // - When the constructor for the mixin is invoked, after all the
917 // derived constructors have run, it will invoke the constructor
918 // for a field whose only purpose is to leave the GC scope.
919 // GarbageCollectedMixinConstructorMarker's constructor takes care of
920 // this and the field is declared by way of USING_GARBAGE_COLLECTED_MIXIN().
921
922 // Trait template to resolve the effective base GC class to use when allocating
923 // objects at some type T. Requires specialization for Node and CSSValue
924 // derived types to have these be allocated on appropriate heaps.
925 template<typename T, typename Enabled = void>
926 class EffectiveGCBaseTrait {
927 public:
928 using Type = T;
929 };
930
931 // FIXME: move these forward declarations and the
932 // EffectiveGCBaseTrait<> specializations out of
933 // here and into the header files for the respective types.
934 class Node;
935 class CSSValue;
936
937 template<typename T>
938 class EffectiveGCBaseTrait<T, typename WTF::EnableIf<WTF::IsSubclass<T, blink::N ode>::value>::Type> {
939 public:
940 using Type = Node;
941 };
942
943 template<typename T>
944 class EffectiveGCBaseTrait<T, typename WTF::EnableIf<WTF::IsSubclass<T, blink::C SSValue>::value>::Type> {
945 public:
946 using Type = CSSValue;
947 };
948
949 #define DEFINE_GARBAGE_COLLECTED_MIXIN_CONSTRUCTOR_MARKER(TYPE) \
950 public: \
951 GC_PLUGIN_IGNORE("crbug.com/456823") \
952 void* operator new(size_t size) \
haraken 2015/03/06 13:01:01 As far as I grep in the code base, GARBAGE_COLLECT
953 { \
954 void* object = Heap::allocate<typename EffectiveGCBaseTrait<TYPE>::Type> (size); \
955 ThreadState* state = ThreadStateFor<ThreadingTrait<TYPE>::Affinity>::sta te(); \
956 state->enterGCForbiddenScope(TYPE::mixinLevels); \
957 return object; \
958 } \
959 private: \
960 GarbageCollectedMixinConstructorMarker<TYPE> m_mixinConstructorMarker;
961
962 #if ENABLE(ASSERT)
963 #define DEFINE_GARBAGE_COLLECTED_MIXIN_NONNESTED_DEBUG() \
964 protected: \
965 virtual void mixinsCannotBeImplicitlyNested() final { }
966 #define DEFINE_GARBAGE_COLLECTED_MIXIN_NESTED_DEBUG(TYPE, SUBTYPE) \
967 protected: \
968 static void mixinsNestingOthersMustBeDeclaredAsSuch() \
969 { \
970 static_assert(WTF::IsSubclass<blink::TYPE, blink::SUBTYPE>::value, "Mixi n class does not derive from its nested mixin class; use USING_GARBAGE_COLLECTED _MIXIN_NESTED()."); \
971 }
972 #else
973 #define DEFINE_GARBAGE_COLLECTED_MIXIN_NONNESTED_DEBUG()
974 #define DEFINE_GARBAGE_COLLECTED_MIXIN_NESTED_DEBUG(TYPE, SUBTYPE)
975 #endif
976
977 #define DEFINE_GARBAGE_COLLECTED_MIXIN_NONNESTED() \
978 protected: \
979 static const unsigned mixinLevels = 1;
980 #define DEFINE_GARBAGE_COLLECTED_MIXIN_NESTED(TYPE, SUBTYPE) \
haraken 2015/03/06 13:01:01 Just to confirm: This mechanism can detect the fol
sof 2015/03/06 16:11:06 The final mixinsCannotBeImplicitlyNested() empty m
981 protected: \
982 static const unsigned mixinLevels = SUBTYPE::mixinLevels + 1;
983
900 #if ENABLE(INLINED_TRACE) 984 #if ENABLE(INLINED_TRACE)
901 #define USING_GARBAGE_COLLECTED_MIXIN(TYPE) \ 985 #define USING_GARBAGE_COLLECTED_MIXIN_BASE(TYPE) \
902 DEFINE_GARBAGE_COLLECTED_MIXIN_METHODS(blink::Visitor*, TYPE) \ 986 DEFINE_GARBAGE_COLLECTED_MIXIN_METHODS(blink::Visitor*, TYPE) \
903 DEFINE_GARBAGE_COLLECTED_MIXIN_METHODS(blink::InlinedGlobalMarkingVisitor, T YPE) 987 DEFINE_GARBAGE_COLLECTED_MIXIN_METHODS(blink::InlinedGlobalMarkingVisitor, T YPE) \
988 DEFINE_GARBAGE_COLLECTED_MIXIN_CONSTRUCTOR_MARKER(TYPE)
904 #else 989 #else
905 #define USING_GARBAGE_COLLECTED_MIXIN(TYPE) \ 990 #define USING_GARBAGE_COLLECTED_MIXIN_BASE(TYPE) \
906 DEFINE_GARBAGE_COLLECTED_MIXIN_METHODS(blink::Visitor*, TYPE) 991 DEFINE_GARBAGE_COLLECTED_MIXIN_METHODS(blink::Visitor*, TYPE) \
992 DEFINE_GARBAGE_COLLECTED_MIXIN_CONSTRUCTOR_MARKER(TYPE)
907 #endif 993 #endif
908 994
995 #define USING_GARBAGE_COLLECTED_MIXIN(TYPE) \
996 DEFINE_GARBAGE_COLLECTED_MIXIN_NONNESTED_DEBUG() \
997 DEFINE_GARBAGE_COLLECTED_MIXIN_NONNESTED() \
998 USING_GARBAGE_COLLECTED_MIXIN_BASE(TYPE)
999
1000 #define USING_GARBAGE_COLLECTED_MIXIN_NESTED(TYPE, SUBTYPE) \
1001 DEFINE_GARBAGE_COLLECTED_MIXIN_NESTED_DEBUG(TYPE, SUBTYPE) \
1002 DEFINE_GARBAGE_COLLECTED_MIXIN_NESTED(TYPE, SUBTYPE) \
1003 USING_GARBAGE_COLLECTED_MIXIN_BASE(TYPE)
1004
909 #if ENABLE(OILPAN) 1005 #if ENABLE(OILPAN)
910 #define WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TYPE) USING_GARBAGE_COLLECTED_MIXI N(TYPE) 1006 #define WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TYPE) USING_GARBAGE_COLLECTED_MIXI N(TYPE)
1007 #define WILL_BE_USING_GARBAGE_COLLECTED_MIXIN_NESTED(TYPE, NESTEDMIXIN) USING_GA RBAGE_COLLECTED_MIXIN_NESTED(TYPE, NESTEDMIXIN)
911 #else 1008 #else
912 #define WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TYPE) 1009 #define WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TYPE)
1010 #define WILL_BE_USING_GARBAGE_COLLECTED_MIXIN_NESTED(TYPE, NESTEDMIXIN)
913 #endif 1011 #endif
914 1012
915 // Template to determine if a class is a GarbageCollectedMixin by checking if it 1013 // Template to determine if a class is a GarbageCollectedMixin by checking if it
916 // has IsGarbageCollectedMixinMarker 1014 // has IsGarbageCollectedMixinMarker
917 template<typename T> 1015 template<typename T>
918 struct IsGarbageCollectedMixin { 1016 struct IsGarbageCollectedMixin {
919 private: 1017 private:
920 typedef char YesType; 1018 typedef char YesType;
921 struct NoType { 1019 struct NoType {
922 char padding[8]; 1020 char padding[8];
923 }; 1021 };
924 1022
925 template <typename U> static YesType checkMarker(typename U::IsGarbageCollec tedMixinMarker*); 1023 template <typename U> static YesType checkMarker(typename U::IsGarbageCollec tedMixinMarker*);
926 template <typename U> static NoType checkMarker(...); 1024 template <typename U> static NoType checkMarker(...);
927 1025
928 public: 1026 public:
929 static const bool value = sizeof(checkMarker<T>(nullptr)) == sizeof(YesType) ; 1027 static const bool value = sizeof(checkMarker<T>(nullptr)) == sizeof(YesType) ;
930 }; 1028 };
931 1029
1030 // An empty class with a constructor that's arranged invoked when all derived co nstructors
1031 // of a mixin instance have completed and it is safe to allow GCs again. See
1032 // AllocateObjectTrait<> comment for more.
1033 //
1034 // USING_GARBAGE_COLLECTED_MIXIN() declares a GarbageCollectedMixinConstructorMa rker<> private
1035 // field. By following Blink convention of using the macro at the top of a class declaration,
1036 // its constructor will run first.
1037 template<typename T>
1038 class GarbageCollectedMixinConstructorMarker {
1039 public:
1040 GarbageCollectedMixinConstructorMarker()
1041 {
1042 // FIXME: if prompt conservative GCs are needed, forced GCs that
1043 // were denied while within this scope, could now be performed.
1044 // For now, assume the next out-of-line allocation request will
1045 // happen soon enough and take care of it. Mixin objects aren't
1046 // overly common.
1047 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state( );
1048 state->leaveGCForbiddenScope();
1049 }
1050 };
1051
932 #if ENABLE(GC_PROFILING) 1052 #if ENABLE(GC_PROFILING)
933 template<typename T> 1053 template<typename T>
934 struct TypenameStringTrait { 1054 struct TypenameStringTrait {
935 static const String& get() 1055 static const String& get()
936 { 1056 {
937 DEFINE_STATIC_LOCAL(String, typenameString, (WTF::extractTypeNameFromFun ctionName(WTF::extractNameFunction<T>()))); 1057 DEFINE_STATIC_LOCAL(String, typenameString, (WTF::extractTypeNameFromFun ctionName(WTF::extractNameFunction<T>())));
938 return typenameString; 1058 return typenameString;
939 } 1059 }
940 }; 1060 };
941 #endif 1061 #endif
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1005 struct GCInfoTrait { 1125 struct GCInfoTrait {
1006 static size_t index() 1126 static size_t index()
1007 { 1127 {
1008 return GCInfoAtBase<typename GetGarbageCollectedBase<T>::type>::index(); 1128 return GCInfoAtBase<typename GetGarbageCollectedBase<T>::type>::index();
1009 } 1129 }
1010 }; 1130 };
1011 1131
1012 } // namespace blink 1132 } // namespace blink
1013 1133
1014 #endif // Visitor_h 1134 #endif // Visitor_h
OLDNEW
« no previous file with comments | « Source/platform/heap/ThreadState.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698