Chromium Code Reviews| 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 |