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 902 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
913 // with the visitor and the closure pointer. Returns false when there is | 913 // with the visitor and the closure pointer. Returns false when there is |
914 // nothing more to do. | 914 // nothing more to do. |
915 static bool popAndInvokeWeakPointerCallback(Visitor*); | 915 static bool popAndInvokeWeakPointerCallback(Visitor*); |
916 | 916 |
917 // Register an ephemeron table for fixed-point iteration. | 917 // Register an ephemeron table for fixed-point iteration. |
918 static void registerWeakTable(void* containerObject, EphemeronCallback, Ephe
meronCallback); | 918 static void registerWeakTable(void* containerObject, EphemeronCallback, Ephe
meronCallback); |
919 #if ENABLE(ASSERT) | 919 #if ENABLE(ASSERT) |
920 static bool weakTableRegistered(const void*); | 920 static bool weakTableRegistered(const void*); |
921 #endif | 921 #endif |
922 | 922 |
| 923 static inline Address allocateOnHeapIndex(ThreadState*, size_t, int heapInde
x, size_t gcInfoIndex); |
923 template<typename T> static Address allocateOnHeapIndex(size_t, int heapInde
x, size_t gcInfoIndex); | 924 template<typename T> static Address allocateOnHeapIndex(size_t, int heapInde
x, size_t gcInfoIndex); |
924 template<typename T> static Address allocate(size_t); | 925 template<typename T> static Address allocate(size_t); |
925 template<typename T> static Address reallocate(void* previous, size_t); | 926 template<typename T> static Address reallocate(void* previous, size_t); |
926 | 927 |
927 static void collectGarbage(ThreadState::StackState, ThreadState::GCType = Th
readState::GCWithSweep); | 928 static void collectGarbage(ThreadState::StackState, ThreadState::GCType = Th
readState::GCWithSweep); |
928 static void collectGarbageForTerminatingThread(ThreadState*); | 929 static void collectGarbageForTerminatingThread(ThreadState*); |
929 static void collectAllGarbage(); | 930 static void collectAllGarbage(); |
930 | 931 |
931 static void processMarkingStack(Visitor*); | 932 static void processMarkingStack(Visitor*); |
932 static void postMarkingProcessing(Visitor*); | 933 static void postMarkingProcessing(Visitor*); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1024 static bool s_lastGCWasConservative; | 1025 static bool s_lastGCWasConservative; |
1025 static FreePagePool* s_freePagePool; | 1026 static FreePagePool* s_freePagePool; |
1026 static OrphanedPagePool* s_orphanedPagePool; | 1027 static OrphanedPagePool* s_orphanedPagePool; |
1027 static RegionTree* s_regionTree; | 1028 static RegionTree* s_regionTree; |
1028 static size_t s_allocatedSpace; | 1029 static size_t s_allocatedSpace; |
1029 static size_t s_allocatedObjectSize; | 1030 static size_t s_allocatedObjectSize; |
1030 static size_t s_markedObjectSize; | 1031 static size_t s_markedObjectSize; |
1031 friend class ThreadState; | 1032 friend class ThreadState; |
1032 }; | 1033 }; |
1033 | 1034 |
| 1035 template<typename T> |
| 1036 struct HeapIndexTrait { |
| 1037 static int index() { return NormalPageHeapIndex; }; |
| 1038 }; |
| 1039 |
| 1040 // FIXME: The forward declaration is layering violation. |
| 1041 #define DEFINE_TYPED_HEAP_TRAIT(Type) \ |
| 1042 class Type; \ |
| 1043 template <> struct HeapIndexTrait<class Type> { \ |
| 1044 static int index() { return Type##HeapIndex; }; \ |
| 1045 }; |
| 1046 FOR_EACH_TYPED_HEAP(DEFINE_TYPED_HEAP_TRAIT) |
| 1047 #undef DEFINE_TYPED_HEAP_TRAIT |
| 1048 |
| 1049 template<typename T, typename Enabled = void> |
| 1050 class AllocateObjectTrait { |
| 1051 public: |
| 1052 static inline Address allocate(size_t size) |
| 1053 { |
| 1054 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(
); |
| 1055 return Heap::allocateOnHeapIndex(state, size, HeapIndexTrait<T>::index()
, GCInfoTrait<T>::index()); |
| 1056 } |
| 1057 |
| 1058 static inline void constructor() |
| 1059 { |
| 1060 } |
| 1061 }; |
| 1062 |
| 1063 template<typename T> |
| 1064 class AllocateObjectTrait<T, typename WTF::EnableIf<blink::IsGarbageCollectedMix
in<T>::value>::Type> { |
| 1065 public: |
| 1066 // An object which implements GarbageCollectedMixin is marked |
| 1067 // and traced during GC by first adjusting object references to |
| 1068 // it to refer to the leftmost base for the object (which would |
| 1069 // be a GarbageCollected-derived class.) The prefixed object header |
| 1070 // can be located after that adjustment and its trace() vtbl slot |
| 1071 // will be used to fully trace the object, if not already marked. |
| 1072 // |
| 1073 // A C++ object's vptr will be initialized to its leftmost base's |
| 1074 // vtable after the constructors of all its subclasses have run, |
| 1075 // so if a subclass constructor tries to access any of the vtbl |
| 1076 // entries of its leftmost base prematurely, it'll find an as-yet |
| 1077 // incorrect vptr and fail. Which is exactly what a garbage collector |
| 1078 // will try to do if it tries to access the leftmost base while one |
| 1079 // of the subclass constructors of a GC mixin object triggers a GC. |
| 1080 // It is consequently not safe to allow any GCs while these objects |
| 1081 // are under (sub constructor) construction. |
| 1082 // |
| 1083 // To achieve that, the construction of mixins are handled in a |
| 1084 // special manner: |
| 1085 // |
| 1086 // - The initial allocation of the mixin object will enter a no GC scope. |
| 1087 // - The constructor for the leftmost base, which is when the mixin |
| 1088 // object is in a state ready for a GC, leaves that GC scope. |
| 1089 // - no-GC scope entering/leaving must support nesting. |
| 1090 // |
| 1091 static inline Address allocate(size_t size) |
| 1092 { |
| 1093 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(
); |
| 1094 Address object = Heap::allocateOnHeapIndex(state, size, HeapIndexTrait<T
>::index(), GCInfoTrait<T>::index()); |
| 1095 state->enterGCForbiddenScope(); |
| 1096 return object; |
| 1097 } |
| 1098 |
| 1099 static inline void constructor() |
| 1100 { |
| 1101 // FIXME: if prompt conservative GCs are needed, forced GCs that |
| 1102 // were denied while within this scope, could now be performed. |
| 1103 // For now, assume the next out-of-line allocation request will |
| 1104 // happen soon enough and take care of it. Mixin objects aren't |
| 1105 // overly common. |
| 1106 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(
); |
| 1107 state->leaveGCForbiddenScope(); |
| 1108 } |
| 1109 }; |
| 1110 |
1034 // Base class for objects allocated in the Blink garbage-collected heap. | 1111 // Base class for objects allocated in the Blink garbage-collected heap. |
1035 // | 1112 // |
1036 // Defines a 'new' operator that allocates the memory in the heap. 'delete' | 1113 // Defines a 'new' operator that allocates the memory in the heap. 'delete' |
1037 // should not be called on objects that inherit from GarbageCollected. | 1114 // should not be called on objects that inherit from GarbageCollected. |
1038 // | 1115 // |
1039 // Instances of GarbageCollected will *NOT* get finalized. Their destructor | 1116 // Instances of GarbageCollected will *NOT* get finalized. Their destructor |
1040 // will not be called. Therefore, only classes that have trivial destructors | 1117 // will not be called. Therefore, only classes that have trivial destructors |
1041 // with no semantic meaning (including all their subclasses) should inherit from | 1118 // with no semantic meaning (including all their subclasses) should inherit from |
1042 // GarbageCollected. If there are non-trival destructors in a given class or | 1119 // GarbageCollected. If there are non-trival destructors in a given class or |
1043 // any of its subclasses, GarbageCollectedFinalized should be used which | 1120 // any of its subclasses, GarbageCollectedFinalized should be used which |
(...skipping 28 matching lines...) Expand all Loading... |
1072 } | 1149 } |
1073 | 1150 |
1074 void operator delete(void* p) | 1151 void operator delete(void* p) |
1075 { | 1152 { |
1076 ASSERT_NOT_REACHED(); | 1153 ASSERT_NOT_REACHED(); |
1077 } | 1154 } |
1078 | 1155 |
1079 protected: | 1156 protected: |
1080 GarbageCollected() | 1157 GarbageCollected() |
1081 { | 1158 { |
| 1159 AllocateObjectTrait<T>::constructor(); |
1082 } | 1160 } |
1083 }; | 1161 }; |
1084 | 1162 |
1085 // Base class for objects allocated in the Blink garbage-collected heap. | 1163 // Base class for objects allocated in the Blink garbage-collected heap. |
1086 // | 1164 // |
1087 // Defines a 'new' operator that allocates the memory in the heap. 'delete' | 1165 // Defines a 'new' operator that allocates the memory in the heap. 'delete' |
1088 // should not be called on objects that inherit from GarbageCollected. | 1166 // should not be called on objects that inherit from GarbageCollected. |
1089 // | 1167 // |
1090 // Instances of GarbageCollectedFinalized will have their destructor called when | 1168 // Instances of GarbageCollectedFinalized will have their destructor called when |
1091 // the garbage collector determines that the object is no longer reachable. | 1169 // the garbage collector determines that the object is no longer reachable. |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1368 return result; | 1446 return result; |
1369 } | 1447 } |
1370 return outOfLineAllocate(allocationSize, gcInfoIndex); | 1448 return outOfLineAllocate(allocationSize, gcInfoIndex); |
1371 } | 1449 } |
1372 | 1450 |
1373 Address NormalPageHeap::allocate(size_t size, size_t gcInfoIndex) | 1451 Address NormalPageHeap::allocate(size_t size, size_t gcInfoIndex) |
1374 { | 1452 { |
1375 return allocateObject(allocationSizeFromSize(size), gcInfoIndex); | 1453 return allocateObject(allocationSizeFromSize(size), gcInfoIndex); |
1376 } | 1454 } |
1377 | 1455 |
1378 template<typename T> | 1456 Address Heap::allocateOnHeapIndex(ThreadState* state, size_t size, int heapIndex
, size_t gcInfoIndex) |
1379 struct HeapIndexTrait { | 1457 { |
1380 static int index() { return NormalPageHeapIndex; }; | 1458 ASSERT(state->isAllocationAllowed()); |
1381 }; | 1459 return static_cast<NormalPageHeap*>(state->heap(heapIndex))->allocate(size,
gcInfoIndex); |
1382 | 1460 } |
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 | 1461 |
1392 template<typename T> | 1462 template<typename T> |
1393 Address Heap::allocateOnHeapIndex(size_t size, int heapIndex, size_t gcInfoIndex
) | 1463 Address Heap::allocateOnHeapIndex(size_t size, int heapIndex, size_t gcInfoIndex
) |
1394 { | 1464 { |
1395 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(); | 1465 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(); |
1396 ASSERT(state->isAllocationAllowed()); | 1466 return allocateOnHeapIndex(state, size, heapIndex, gcInfoIndex); |
1397 return static_cast<NormalPageHeap*>(state->heap(heapIndex))->allocate(size,
gcInfoIndex); | |
1398 } | 1467 } |
1399 | 1468 |
1400 template<typename T> | 1469 template<typename T> |
1401 Address Heap::allocate(size_t size) | 1470 Address Heap::allocate(size_t size) |
1402 { | 1471 { |
1403 return allocateOnHeapIndex<T>(size, HeapIndexTrait<T>::index(), GCInfoTrait<
T>::index()); | 1472 return AllocateObjectTrait<T>::allocate(size); |
1404 } | 1473 } |
1405 | 1474 |
1406 template<typename T> | 1475 template<typename T> |
1407 Address Heap::reallocate(void* previous, size_t size) | 1476 Address Heap::reallocate(void* previous, size_t size) |
1408 { | 1477 { |
1409 if (!size) { | 1478 if (!size) { |
1410 // If the new size is 0 this is equivalent to either free(previous) or | 1479 // 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. | 1480 // malloc(0). In both cases we do nothing and return nullptr. |
1412 return nullptr; | 1481 return nullptr; |
1413 } | 1482 } |
(...skipping 1027 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2441 template<typename T, size_t inlineCapacity> | 2510 template<typename T, size_t inlineCapacity> |
2442 struct GCInfoTrait<HeapVector<T, inlineCapacity>> : public GCInfoTrait<Vector<T,
inlineCapacity, HeapAllocator>> { }; | 2511 struct GCInfoTrait<HeapVector<T, inlineCapacity>> : public GCInfoTrait<Vector<T,
inlineCapacity, HeapAllocator>> { }; |
2443 template<typename T, size_t inlineCapacity> | 2512 template<typename T, size_t inlineCapacity> |
2444 struct GCInfoTrait<HeapDeque<T, inlineCapacity>> : public GCInfoTrait<Deque<T, i
nlineCapacity, HeapAllocator>> { }; | 2513 struct GCInfoTrait<HeapDeque<T, inlineCapacity>> : public GCInfoTrait<Deque<T, i
nlineCapacity, HeapAllocator>> { }; |
2445 template<typename T, typename U, typename V> | 2514 template<typename T, typename U, typename V> |
2446 struct GCInfoTrait<HeapHashCountedSet<T, U, V>> : public GCInfoTrait<HashCounted
Set<T, U, V, HeapAllocator>> { }; | 2515 struct GCInfoTrait<HeapHashCountedSet<T, U, V>> : public GCInfoTrait<HashCounted
Set<T, U, V, HeapAllocator>> { }; |
2447 | 2516 |
2448 } // namespace blink | 2517 } // namespace blink |
2449 | 2518 |
2450 #endif // Heap_h | 2519 #endif // Heap_h |
OLD | NEW |