Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1184)

Side by Side Diff: Source/platform/heap/Heap.h

Issue 946163003: Prevent GCs when constructing GC mixin objects. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: add assert Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698