| OLD | NEW |
| 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 Loading... |
| 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)
\ |
| 953 {
\ |
| 954 void* object = Heap::allocate<typename EffectiveGCBaseTrait<TYPE>::Type>
(size); \ |
| 955 ThreadState* state = ThreadStateFor<ThreadingTrait<TYPE>::Affinity>::sta
te(); \ |
| 956 state->enterGCForbiddenScope();
\ |
| 957 return object;
\ |
| 958 }
\ |
| 959 private:
\ |
| 960 const GarbageCollectedMixinConstructorMarker<TYPE> m_mixinConstructorMarker; |
| 961 |
| 900 #if ENABLE(INLINED_TRACE) | 962 #if ENABLE(INLINED_TRACE) |
| 901 #define USING_GARBAGE_COLLECTED_MIXIN(TYPE) \ | 963 #define USING_GARBAGE_COLLECTED_MIXIN(TYPE) \ |
| 902 DEFINE_GARBAGE_COLLECTED_MIXIN_METHODS(blink::Visitor*, TYPE) \ | 964 DEFINE_GARBAGE_COLLECTED_MIXIN_METHODS(blink::Visitor*, TYPE) \ |
| 903 DEFINE_GARBAGE_COLLECTED_MIXIN_METHODS(blink::InlinedGlobalMarkingVisitor, T
YPE) | 965 DEFINE_GARBAGE_COLLECTED_MIXIN_METHODS(blink::InlinedGlobalMarkingVisitor, T
YPE) \ |
| 966 DEFINE_GARBAGE_COLLECTED_MIXIN_CONSTRUCTOR_MARKER(TYPE) |
| 904 #else | 967 #else |
| 905 #define USING_GARBAGE_COLLECTED_MIXIN(TYPE) \ | 968 #define USING_GARBAGE_COLLECTED_MIXIN(TYPE) \ |
| 906 DEFINE_GARBAGE_COLLECTED_MIXIN_METHODS(blink::Visitor*, TYPE) | 969 DEFINE_GARBAGE_COLLECTED_MIXIN_METHODS(blink::Visitor*, TYPE) \ |
| 970 DEFINE_GARBAGE_COLLECTED_MIXIN_CONSTRUCTOR_MARKER(TYPE) |
| 907 #endif | 971 #endif |
| 908 | 972 |
| 909 #if ENABLE(OILPAN) | 973 #if ENABLE(OILPAN) |
| 910 #define WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TYPE) USING_GARBAGE_COLLECTED_MIXI
N(TYPE) | 974 #define WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TYPE) USING_GARBAGE_COLLECTED_MIXI
N(TYPE) |
| 911 #else | 975 #else |
| 912 #define WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TYPE) | 976 #define WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TYPE) |
| 913 #endif | 977 #endif |
| 914 | 978 |
| 915 // Template to determine if a class is a GarbageCollectedMixin by checking if it | 979 // Template to determine if a class is a GarbageCollectedMixin by checking if it |
| 916 // has IsGarbageCollectedMixinMarker | 980 // has IsGarbageCollectedMixinMarker |
| 917 template<typename T> | 981 template<typename T> |
| 918 struct IsGarbageCollectedMixin { | 982 struct IsGarbageCollectedMixin { |
| 919 private: | 983 private: |
| 920 typedef char YesType; | 984 typedef char YesType; |
| 921 struct NoType { | 985 struct NoType { |
| 922 char padding[8]; | 986 char padding[8]; |
| 923 }; | 987 }; |
| 924 | 988 |
| 925 template <typename U> static YesType checkMarker(typename U::IsGarbageCollec
tedMixinMarker*); | 989 template <typename U> static YesType checkMarker(typename U::IsGarbageCollec
tedMixinMarker*); |
| 926 template <typename U> static NoType checkMarker(...); | 990 template <typename U> static NoType checkMarker(...); |
| 927 | 991 |
| 928 public: | 992 public: |
| 929 static const bool value = sizeof(checkMarker<T>(nullptr)) == sizeof(YesType)
; | 993 static const bool value = sizeof(checkMarker<T>(nullptr)) == sizeof(YesType)
; |
| 930 }; | 994 }; |
| 931 | 995 |
| 996 // An empty class with a constructor that's arranged invoked when all derived co
nstructors |
| 997 // of a mixin instance have completed and it is safe to allow GCs again. See |
| 998 // AllocateObjectTrait<> comment for more. |
| 999 // |
| 1000 // USING_GARBAGE_COLLECTED_MIXIN() declares a GarbageCollectedMixinConstructorMa
rker<> private |
| 1001 // field. By following Blink convention of using the macro at the top of a class
declaration, |
| 1002 // its constructor will run first. |
| 1003 template<typename T> |
| 1004 class GarbageCollectedMixinConstructorMarker { |
| 1005 public: |
| 1006 GarbageCollectedMixinConstructorMarker() |
| 1007 { |
| 1008 // FIXME: if prompt conservative GCs are needed, forced GCs that |
| 1009 // were denied while within this scope, could now be performed. |
| 1010 // For now, assume the next out-of-line allocation request will |
| 1011 // happen soon enough and take care of it. Mixin objects aren't |
| 1012 // overly common. |
| 1013 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(
); |
| 1014 state->leaveGCForbiddenScope(); |
| 1015 } |
| 1016 }; |
| 1017 |
| 932 #if ENABLE(GC_PROFILING) | 1018 #if ENABLE(GC_PROFILING) |
| 933 template<typename T> | 1019 template<typename T> |
| 934 struct TypenameStringTrait { | 1020 struct TypenameStringTrait { |
| 935 static const String& get() | 1021 static const String& get() |
| 936 { | 1022 { |
| 937 DEFINE_STATIC_LOCAL(String, typenameString, (WTF::extractTypeNameFromFun
ctionName(WTF::extractNameFunction<T>()))); | 1023 DEFINE_STATIC_LOCAL(String, typenameString, (WTF::extractTypeNameFromFun
ctionName(WTF::extractNameFunction<T>()))); |
| 938 return typenameString; | 1024 return typenameString; |
| 939 } | 1025 } |
| 940 }; | 1026 }; |
| 941 #endif | 1027 #endif |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1005 struct GCInfoTrait { | 1091 struct GCInfoTrait { |
| 1006 static size_t index() | 1092 static size_t index() |
| 1007 { | 1093 { |
| 1008 return GCInfoAtBase<typename GetGarbageCollectedBase<T>::type>::index(); | 1094 return GCInfoAtBase<typename GetGarbageCollectedBase<T>::type>::index(); |
| 1009 } | 1095 } |
| 1010 }; | 1096 }; |
| 1011 | 1097 |
| 1012 } // namespace blink | 1098 } // namespace blink |
| 1013 | 1099 |
| 1014 #endif // Visitor_h | 1100 #endif // Visitor_h |
| OLD | NEW |