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

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: Improve naming + optimize allocateOnHeapIndex() usage 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
« no previous file with comments | « Source/platform/heap/Handle.h ('k') | Source/platform/heap/ThreadState.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 902 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
OLDNEW
« no previous file with comments | « Source/platform/heap/Handle.h ('k') | Source/platform/heap/ThreadState.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698