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 1073 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1084 | 1084 |
1085 // FIXME: The forward declaration is layering violation. | 1085 // FIXME: The forward declaration is layering violation. |
1086 #define DEFINE_TYPED_HEAP_TRAIT(Type) \ | 1086 #define DEFINE_TYPED_HEAP_TRAIT(Type) \ |
1087 class Type; \ | 1087 class Type; \ |
1088 template <> struct HeapIndexTrait<class Type> { \ | 1088 template <> struct HeapIndexTrait<class Type> { \ |
1089 static int index() { return Type##HeapIndex; }; \ | 1089 static int index() { return Type##HeapIndex; }; \ |
1090 }; | 1090 }; |
1091 FOR_EACH_TYPED_HEAP(DEFINE_TYPED_HEAP_TRAIT) | 1091 FOR_EACH_TYPED_HEAP(DEFINE_TYPED_HEAP_TRAIT) |
1092 #undef DEFINE_TYPED_HEAP_TRAIT | 1092 #undef DEFINE_TYPED_HEAP_TRAIT |
1093 | 1093 |
1094 template<typename T, typename Enabled = void> | |
1095 class AllocateObjectTrait { | |
1096 public: | |
1097 static Address allocate(size_t size) | |
1098 { | |
1099 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(
); | |
1100 return Heap::allocateOnHeapIndex(state, size, HeapIndexTrait<T>::index()
, GCInfoTrait<T>::index()); | |
1101 } | |
1102 | |
1103 static void constructor() | |
1104 { | |
1105 } | |
1106 }; | |
1107 | |
1108 template<typename T> | |
1109 class AllocateObjectTrait<T, typename WTF::EnableIf<blink::IsGarbageCollectedMix
in<T>::value>::Type> { | |
1110 public: | |
1111 // An object which implements GarbageCollectedMixin is marked | |
1112 // and traced during GC by first adjusting object references to | |
1113 // it to refer to the leftmost base for the object (which would | |
1114 // be a GarbageCollected-derived class.) The prefixed object header | |
1115 // can be located after that adjustment and its trace() vtbl slot | |
1116 // will be used to fully trace the object, if not already marked. | |
1117 // | |
1118 // A C++ object's vptr will be initialized to its leftmost base's | |
1119 // vtable after the constructors of all its subclasses have run, | |
1120 // so if a subclass constructor tries to access any of the vtbl | |
1121 // entries of its leftmost base prematurely, it'll find an as-yet | |
1122 // incorrect vptr and fail. Which is exactly what a garbage collector | |
1123 // will try to do if it tries to access the leftmost base while one | |
1124 // of the subclass constructors of a GC mixin object triggers a GC. | |
1125 // It is consequently not safe to allow any GCs while these objects | |
1126 // are under (sub constructor) construction. | |
1127 // | |
1128 // To achieve that, the construction of mixins are handled in a | |
1129 // special manner: | |
1130 // | |
1131 // - The initial allocation of the mixin object will enter a no GC scope. | |
1132 // - The constructor for the leftmost base, which is when the mixin | |
1133 // object is in a state ready for a GC, leaves that GC scope. | |
1134 // - no-GC scope entering/leaving must support nesting. | |
1135 // | |
1136 static Address allocate(size_t size) | |
1137 { | |
1138 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(
); | |
1139 Address object = Heap::allocateOnHeapIndex(state, size, HeapIndexTrait<T
>::index(), GCInfoTrait<T>::index()); | |
1140 state->enterGCForbiddenScope(); | |
1141 return object; | |
1142 } | |
1143 | |
1144 static void constructor() | |
1145 { | |
1146 // FIXME: if prompt conservative GCs are needed, forced GCs that | |
1147 // were denied while within this scope, could now be performed. | |
1148 // For now, assume the next out-of-line allocation request will | |
1149 // happen soon enough and take care of it. Mixin objects aren't | |
1150 // overly common. | |
1151 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(
); | |
1152 state->leaveGCForbiddenScope(); | |
1153 } | |
1154 }; | |
1155 | |
1156 // Base class for objects allocated in the Blink garbage-collected heap. | 1094 // Base class for objects allocated in the Blink garbage-collected heap. |
1157 // | 1095 // |
1158 // Defines a 'new' operator that allocates the memory in the heap. 'delete' | 1096 // Defines a 'new' operator that allocates the memory in the heap. 'delete' |
1159 // should not be called on objects that inherit from GarbageCollected. | 1097 // should not be called on objects that inherit from GarbageCollected. |
1160 // | 1098 // |
1161 // Instances of GarbageCollected will *NOT* get finalized. Their destructor | 1099 // Instances of GarbageCollected will *NOT* get finalized. Their destructor |
1162 // will not be called. Therefore, only classes that have trivial destructors | 1100 // will not be called. Therefore, only classes that have trivial destructors |
1163 // with no semantic meaning (including all their subclasses) should inherit from | 1101 // with no semantic meaning (including all their subclasses) should inherit from |
1164 // GarbageCollected. If there are non-trival destructors in a given class or | 1102 // GarbageCollected. If there are non-trival destructors in a given class or |
1165 // any of its subclasses, GarbageCollectedFinalized should be used which | 1103 // any of its subclasses, GarbageCollectedFinalized should be used which |
(...skipping 28 matching lines...) Expand all Loading... |
1194 } | 1132 } |
1195 | 1133 |
1196 void operator delete(void* p) | 1134 void operator delete(void* p) |
1197 { | 1135 { |
1198 ASSERT_NOT_REACHED(); | 1136 ASSERT_NOT_REACHED(); |
1199 } | 1137 } |
1200 | 1138 |
1201 protected: | 1139 protected: |
1202 GarbageCollected() | 1140 GarbageCollected() |
1203 { | 1141 { |
1204 AllocateObjectTrait<T>::constructor(); | |
1205 } | 1142 } |
1206 }; | 1143 }; |
1207 | 1144 |
1208 // Base class for objects allocated in the Blink garbage-collected heap. | 1145 // Base class for objects allocated in the Blink garbage-collected heap. |
1209 // | 1146 // |
1210 // Defines a 'new' operator that allocates the memory in the heap. 'delete' | 1147 // Defines a 'new' operator that allocates the memory in the heap. 'delete' |
1211 // should not be called on objects that inherit from GarbageCollected. | 1148 // should not be called on objects that inherit from GarbageCollected. |
1212 // | 1149 // |
1213 // Instances of GarbageCollectedFinalized will have their destructor called when | 1150 // Instances of GarbageCollectedFinalized will have their destructor called when |
1214 // the garbage collector determines that the object is no longer reachable. | 1151 // the garbage collector determines that the object is no longer reachable. |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1483 { | 1420 { |
1484 ASSERT(state->isAllocationAllowed()); | 1421 ASSERT(state->isAllocationAllowed()); |
1485 ASSERT(heapIndex != LargeObjectHeapIndex); | 1422 ASSERT(heapIndex != LargeObjectHeapIndex); |
1486 NormalPageHeap* heap = static_cast<NormalPageHeap*>(state->heap(heapIndex)); | 1423 NormalPageHeap* heap = static_cast<NormalPageHeap*>(state->heap(heapIndex)); |
1487 return heap->allocateObject(allocationSizeFromSize(size), gcInfoIndex); | 1424 return heap->allocateObject(allocationSizeFromSize(size), gcInfoIndex); |
1488 } | 1425 } |
1489 | 1426 |
1490 template<typename T> | 1427 template<typename T> |
1491 Address Heap::allocate(size_t size) | 1428 Address Heap::allocate(size_t size) |
1492 { | 1429 { |
1493 return AllocateObjectTrait<T>::allocate(size); | 1430 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(); |
| 1431 return Heap::allocateOnHeapIndex(state, size, HeapIndexTrait<T>::index(), GC
InfoTrait<T>::index()); |
1494 } | 1432 } |
1495 | 1433 |
1496 template<typename T> | 1434 template<typename T> |
1497 Address Heap::reallocate(void* previous, size_t size) | 1435 Address Heap::reallocate(void* previous, size_t size) |
1498 { | 1436 { |
1499 if (!size) { | 1437 if (!size) { |
1500 // If the new size is 0 this is equivalent to either free(previous) or | 1438 // If the new size is 0 this is equivalent to either free(previous) or |
1501 // malloc(0). In both cases we do nothing and return nullptr. | 1439 // malloc(0). In both cases we do nothing and return nullptr. |
1502 return nullptr; | 1440 return nullptr; |
1503 } | 1441 } |
(...skipping 1060 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2564 template<typename T, size_t inlineCapacity> | 2502 template<typename T, size_t inlineCapacity> |
2565 struct GCInfoTrait<HeapVector<T, inlineCapacity>> : public GCInfoTrait<Vector<T,
inlineCapacity, HeapAllocator>> { }; | 2503 struct GCInfoTrait<HeapVector<T, inlineCapacity>> : public GCInfoTrait<Vector<T,
inlineCapacity, HeapAllocator>> { }; |
2566 template<typename T, size_t inlineCapacity> | 2504 template<typename T, size_t inlineCapacity> |
2567 struct GCInfoTrait<HeapDeque<T, inlineCapacity>> : public GCInfoTrait<Deque<T, i
nlineCapacity, HeapAllocator>> { }; | 2505 struct GCInfoTrait<HeapDeque<T, inlineCapacity>> : public GCInfoTrait<Deque<T, i
nlineCapacity, HeapAllocator>> { }; |
2568 template<typename T, typename U, typename V> | 2506 template<typename T, typename U, typename V> |
2569 struct GCInfoTrait<HeapHashCountedSet<T, U, V>> : public GCInfoTrait<HashCounted
Set<T, U, V, HeapAllocator>> { }; | 2507 struct GCInfoTrait<HeapHashCountedSet<T, U, V>> : public GCInfoTrait<HashCounted
Set<T, U, V, HeapAllocator>> { }; |
2570 | 2508 |
2571 } // namespace blink | 2509 } // namespace blink |
2572 | 2510 |
2573 #endif // Heap_h | 2511 #endif // Heap_h |
OLD | NEW |