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 1013 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1024 static bool s_lastGCWasConservative; | 1024 static bool s_lastGCWasConservative; |
1025 static FreePagePool* s_freePagePool; | 1025 static FreePagePool* s_freePagePool; |
1026 static OrphanedPagePool* s_orphanedPagePool; | 1026 static OrphanedPagePool* s_orphanedPagePool; |
1027 static RegionTree* s_regionTree; | 1027 static RegionTree* s_regionTree; |
1028 static size_t s_allocatedSpace; | 1028 static size_t s_allocatedSpace; |
1029 static size_t s_allocatedObjectSize; | 1029 static size_t s_allocatedObjectSize; |
1030 static size_t s_markedObjectSize; | 1030 static size_t s_markedObjectSize; |
1031 friend class ThreadState; | 1031 friend class ThreadState; |
1032 }; | 1032 }; |
1033 | 1033 |
1034 template<typename T> | |
1035 struct HeapIndexTrait { | |
1036 static int index() { return NormalPageHeapIndex; }; | |
1037 }; | |
1038 | |
1039 // FIXME: The forward declaration is layering violation. | |
1040 #define DEFINE_TYPED_HEAP_TRAIT(Type) \ | |
1041 class Type; \ | |
1042 template <> struct HeapIndexTrait<class Type> { \ | |
1043 static int index() { return Type##HeapIndex; }; \ | |
1044 }; | |
1045 FOR_EACH_TYPED_HEAP(DEFINE_TYPED_HEAP_TRAIT) | |
1046 #undef DEFINE_TYPED_HEAP_TRAIT | |
1047 | |
1048 template<typename T, typename Enabled = void> | |
1049 class AllocateObjectTrait { | |
1050 public: | |
1051 static inline Address allocate(size_t size) | |
1052 { | |
1053 return Heap::allocateOnHeapIndex<T>(size, HeapIndexTrait<T>::index(), GC InfoTrait<T>::index()); | |
1054 } | |
1055 | |
1056 static inline void constructor() | |
1057 { | |
1058 } | |
1059 }; | |
1060 | |
1061 template<typename T> | |
1062 class AllocateObjectTrait<T, typename WTF::EnableIf<blink::IsGarbageCollectedMix in<T>::value>::Type> { | |
1063 public: | |
1064 // An object which implements GarbageCollectedMixin is marked | |
1065 // and traced during GC by first adjusting object references to | |
1066 // it to refer to the leftmost base for the object (which would | |
1067 // be a GarbageCollected-derived class.) The prefixed object header | |
1068 // can be located after that adjustment and its trace() vtbl slot | |
1069 // will be used to fully trace the object, if not already marked. | |
1070 // | |
1071 // A C++ object's vptr will be initialized to its leftmost base's | |
1072 // vtabke after the constructors of all its subclasses have run, | |
haraken
2015/02/23 08:24:23
vtable
sof
2015/02/23 10:29:02
Done.
| |
1073 // so if a subclass constructor tries to access any of the vtbl | |
1074 // entries of its leftmost base prematurely, it'll find an as-yet | |
1075 // incorrect vptr and fail. Which is exactly what a garbage collector | |
1076 // will try to do if it tries to access the leftmost base while one | |
1077 // of the subclass constructors of a GC mixin object triggers a GC. | |
1078 // It is consequently not safe to allow any GCs while these objects | |
1079 // are under (sub constructor) construction. | |
1080 // | |
1081 // To achieve that, the construction of mixins are handled in a | |
1082 // special manner: | |
1083 // | |
1084 // - The initial allocation of the mixin object will enter a no GC scope. | |
1085 // - The constructor for the leftmost base, which is when the mixin | |
1086 // object is in a state ready for a GC, leaves that GC scope. | |
1087 // - no-GC scope entering/leaving must support nesting. | |
1088 // | |
1089 static inline Address allocate(size_t size) | |
1090 { | |
1091 Address object = Heap::allocateOnHeapIndex<T>(size, HeapIndexTrait<T>::i ndex(), GCInfoTrait<T>::index()); | |
1092 ThreadState::current()->enterNoGCAllowedScope(); | |
haraken
2015/02/23 08:24:22
Are compilers smart enough to remove the two Threa
sof
2015/02/23 10:29:02
Reasonable to assume so, but we might as well manu
| |
1093 return object; | |
1094 } | |
1095 | |
1096 static inline void constructor() | |
1097 { | |
1098 ThreadState::current()->leaveNoGCAllowedScope(); | |
1099 } | |
1100 }; | |
1101 | |
1034 // Base class for objects allocated in the Blink garbage-collected heap. | 1102 // Base class for objects allocated in the Blink garbage-collected heap. |
1035 // | 1103 // |
1036 // Defines a 'new' operator that allocates the memory in the heap. 'delete' | 1104 // Defines a 'new' operator that allocates the memory in the heap. 'delete' |
1037 // should not be called on objects that inherit from GarbageCollected. | 1105 // should not be called on objects that inherit from GarbageCollected. |
1038 // | 1106 // |
1039 // Instances of GarbageCollected will *NOT* get finalized. Their destructor | 1107 // Instances of GarbageCollected will *NOT* get finalized. Their destructor |
1040 // will not be called. Therefore, only classes that have trivial destructors | 1108 // will not be called. Therefore, only classes that have trivial destructors |
1041 // with no semantic meaning (including all their subclasses) should inherit from | 1109 // with no semantic meaning (including all their subclasses) should inherit from |
1042 // GarbageCollected. If there are non-trival destructors in a given class or | 1110 // GarbageCollected. If there are non-trival destructors in a given class or |
1043 // any of its subclasses, GarbageCollectedFinalized should be used which | 1111 // any of its subclasses, GarbageCollectedFinalized should be used which |
(...skipping 28 matching lines...) Expand all Loading... | |
1072 } | 1140 } |
1073 | 1141 |
1074 void operator delete(void* p) | 1142 void operator delete(void* p) |
1075 { | 1143 { |
1076 ASSERT_NOT_REACHED(); | 1144 ASSERT_NOT_REACHED(); |
1077 } | 1145 } |
1078 | 1146 |
1079 protected: | 1147 protected: |
1080 GarbageCollected() | 1148 GarbageCollected() |
1081 { | 1149 { |
1150 AllocateObjectTrait<T>::constructor(); | |
1082 } | 1151 } |
1083 }; | 1152 }; |
1084 | 1153 |
1085 // Base class for objects allocated in the Blink garbage-collected heap. | 1154 // Base class for objects allocated in the Blink garbage-collected heap. |
1086 // | 1155 // |
1087 // Defines a 'new' operator that allocates the memory in the heap. 'delete' | 1156 // Defines a 'new' operator that allocates the memory in the heap. 'delete' |
1088 // should not be called on objects that inherit from GarbageCollected. | 1157 // should not be called on objects that inherit from GarbageCollected. |
1089 // | 1158 // |
1090 // Instances of GarbageCollectedFinalized will have their destructor called when | 1159 // Instances of GarbageCollectedFinalized will have their destructor called when |
1091 // the garbage collector determines that the object is no longer reachable. | 1160 // the garbage collector determines that the object is no longer reachable. |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1369 } | 1438 } |
1370 return outOfLineAllocate(allocationSize, gcInfoIndex); | 1439 return outOfLineAllocate(allocationSize, gcInfoIndex); |
1371 } | 1440 } |
1372 | 1441 |
1373 Address NormalPageHeap::allocate(size_t size, size_t gcInfoIndex) | 1442 Address NormalPageHeap::allocate(size_t size, size_t gcInfoIndex) |
1374 { | 1443 { |
1375 return allocateObject(allocationSizeFromSize(size), gcInfoIndex); | 1444 return allocateObject(allocationSizeFromSize(size), gcInfoIndex); |
1376 } | 1445 } |
1377 | 1446 |
1378 template<typename T> | 1447 template<typename T> |
1379 struct HeapIndexTrait { | |
1380 static int index() { return NormalPageHeapIndex; }; | |
1381 }; | |
1382 | |
1383 // FIXME: The forward declaration is layering violation. | |
1384 #define DEFINE_TYPED_HEAP_TRAIT(Type) \ | |
1385 class Type; \ | |
1386 template <> struct HeapIndexTrait<class Type> { \ | |
1387 static int index() { return Type##HeapIndex; }; \ | |
1388 }; | |
1389 FOR_EACH_TYPED_HEAP(DEFINE_TYPED_HEAP_TRAIT) | |
1390 #undef DEFINE_TYPED_HEAP_TRAIT | |
1391 | |
1392 template<typename T> | |
1393 Address Heap::allocateOnHeapIndex(size_t size, int heapIndex, size_t gcInfoIndex ) | 1448 Address Heap::allocateOnHeapIndex(size_t size, int heapIndex, size_t gcInfoIndex ) |
1394 { | 1449 { |
1395 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(); | 1450 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(); |
1396 ASSERT(state->isAllocationAllowed()); | 1451 ASSERT(state->isAllocationAllowed()); |
1397 return static_cast<NormalPageHeap*>(state->heap(heapIndex))->allocate(size, gcInfoIndex); | 1452 return static_cast<NormalPageHeap*>(state->heap(heapIndex))->allocate(size, gcInfoIndex); |
1398 } | 1453 } |
1399 | 1454 |
1400 template<typename T> | 1455 template<typename T> |
1401 Address Heap::allocate(size_t size) | 1456 Address Heap::allocate(size_t size) |
1402 { | 1457 { |
1403 return allocateOnHeapIndex<T>(size, HeapIndexTrait<T>::index(), GCInfoTrait< T>::index()); | 1458 return AllocateObjectTrait<T>::allocate(size); |
1404 } | 1459 } |
1405 | 1460 |
1406 template<typename T> | 1461 template<typename T> |
1407 Address Heap::reallocate(void* previous, size_t size) | 1462 Address Heap::reallocate(void* previous, size_t size) |
1408 { | 1463 { |
1409 if (!size) { | 1464 if (!size) { |
1410 // If the new size is 0 this is equivalent to either free(previous) or | 1465 // If the new size is 0 this is equivalent to either free(previous) or |
1411 // malloc(0). In both cases we do nothing and return nullptr. | 1466 // malloc(0). In both cases we do nothing and return nullptr. |
1412 return nullptr; | 1467 return nullptr; |
1413 } | 1468 } |
(...skipping 1027 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2441 template<typename T, size_t inlineCapacity> | 2496 template<typename T, size_t inlineCapacity> |
2442 struct GCInfoTrait<HeapVector<T, inlineCapacity>> : public GCInfoTrait<Vector<T, inlineCapacity, HeapAllocator>> { }; | 2497 struct GCInfoTrait<HeapVector<T, inlineCapacity>> : public GCInfoTrait<Vector<T, inlineCapacity, HeapAllocator>> { }; |
2443 template<typename T, size_t inlineCapacity> | 2498 template<typename T, size_t inlineCapacity> |
2444 struct GCInfoTrait<HeapDeque<T, inlineCapacity>> : public GCInfoTrait<Deque<T, i nlineCapacity, HeapAllocator>> { }; | 2499 struct GCInfoTrait<HeapDeque<T, inlineCapacity>> : public GCInfoTrait<Deque<T, i nlineCapacity, HeapAllocator>> { }; |
2445 template<typename T, typename U, typename V> | 2500 template<typename T, typename U, typename V> |
2446 struct GCInfoTrait<HeapHashCountedSet<T, U, V>> : public GCInfoTrait<HashCounted Set<T, U, V, HeapAllocator>> { }; | 2501 struct GCInfoTrait<HeapHashCountedSet<T, U, V>> : public GCInfoTrait<HashCounted Set<T, U, V, HeapAllocator>> { }; |
2447 | 2502 |
2448 } // namespace blink | 2503 } // namespace blink |
2449 | 2504 |
2450 #endif // Heap_h | 2505 #endif // Heap_h |
OLD | NEW |