1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 6 */ 7 8 /* arena allocation for the frame tree and closely-related objects */ 9 10 #ifndef nsPresArena_h___ 11 #define nsPresArena_h___ 12 13 #include "mozilla/ArenaAllocator.h" 14 #include "mozilla/ArenaObjectID.h" 15 #include "mozilla/ArenaRefPtr.h" 16 #include "mozilla/Assertions.h" 17 #include "mozilla/MemoryChecking.h" // Note: Do not remove this, needed for MOZ_HAVE_MEM_CHECKS below 18 #include "mozilla/MemoryReporting.h" 19 #include <stdint.h> 20 #include "nscore.h" 21 #include "nsDataHashtable.h" 22 #include "nsHashKeys.h" 23 #include "nsTArray.h" 24 #include "nsTHashtable.h" 25 26 class nsWindowSizes; 27 28 class nsPresArena { 29 public: 30 nsPresArena(); 31 ~nsPresArena(); 32 33 /** 34 * Pool allocation with recycler lists indexed by frame-type ID. 35 * Every aID must always be used with the same object size, aSize. 36 */ AllocateByFrameID(nsQueryFrame::FrameIID aID,size_t aSize)37 void* AllocateByFrameID(nsQueryFrame::FrameIID aID, size_t aSize) { 38 return Allocate(aID, aSize); 39 } FreeByFrameID(nsQueryFrame::FrameIID aID,void * aPtr)40 void FreeByFrameID(nsQueryFrame::FrameIID aID, void* aPtr) { 41 Free(aID, aPtr); 42 } 43 44 /** 45 * Pool allocation with recycler lists indexed by object-type ID (see above). 46 * Every aID must always be used with the same object size, aSize. 47 */ AllocateByObjectID(mozilla::ArenaObjectID aID,size_t aSize)48 void* AllocateByObjectID(mozilla::ArenaObjectID aID, size_t aSize) { 49 return Allocate(aID, aSize); 50 } FreeByObjectID(mozilla::ArenaObjectID aID,void * aPtr)51 void FreeByObjectID(mozilla::ArenaObjectID aID, void* aPtr) { 52 Free(aID, aPtr); 53 } 54 AllocateByCustomID(uint32_t aID,size_t aSize)55 void* AllocateByCustomID(uint32_t aID, size_t aSize) { 56 return Allocate(aID, aSize); 57 } FreeByCustomID(uint32_t aID,void * ptr)58 void FreeByCustomID(uint32_t aID, void* ptr) { Free(aID, ptr); } 59 60 /** 61 * Register an ArenaRefPtr to be cleared when this arena is about to 62 * be destroyed. 63 * 64 * (Defined in ArenaRefPtrInlines.h.) 65 * 66 * @param aPtr The ArenaRefPtr to clear. 67 * @param aObjectID The ArenaObjectID value that uniquely identifies 68 * the type of object the ArenaRefPtr holds. 69 */ 70 template <typename T> 71 void RegisterArenaRefPtr(mozilla::ArenaRefPtr<T>* aPtr); 72 73 /** 74 * Deregister an ArenaRefPtr that was previously registered with 75 * RegisterArenaRefPtr. 76 */ 77 template <typename T> DeregisterArenaRefPtr(mozilla::ArenaRefPtr<T> * aPtr)78 void DeregisterArenaRefPtr(mozilla::ArenaRefPtr<T>* aPtr) { 79 MOZ_ASSERT(mArenaRefPtrs.Contains(aPtr)); 80 mArenaRefPtrs.Remove(aPtr); 81 } 82 83 /** 84 * Clears all currently registered ArenaRefPtrs. This will be called during 85 * the destructor, but can be called by users of nsPresArena who want to 86 * ensure arena-allocated objects are released earlier. 87 */ 88 void ClearArenaRefPtrs(); 89 90 /** 91 * Clears all currently registered ArenaRefPtrs for the given ArenaObjectID. 92 * This is called when we reconstruct the rule tree so that style contexts 93 * pointing into the old rule tree aren't released afterwards, triggering an 94 * assertion in ~nsStyleContext. 95 */ 96 void ClearArenaRefPtrs(mozilla::ArenaObjectID aObjectID); 97 98 /** 99 * Increment nsWindowSizes with sizes of interesting objects allocated in this 100 * arena. 101 */ 102 void AddSizeOfExcludingThis(nsWindowSizes& aWindowSizes) const; 103 Check()104 void Check() { mPool.Check(); } 105 106 private: 107 void* Allocate(uint32_t aCode, size_t aSize); 108 void Free(uint32_t aCode, void* aPtr); 109 110 inline void ClearArenaRefPtrWithoutDeregistering( 111 void* aPtr, mozilla::ArenaObjectID aObjectID); 112 113 class FreeList { 114 public: 115 nsTArray<void*> mEntries; 116 size_t mEntrySize; 117 size_t mEntriesEverAllocated; 118 FreeList()119 FreeList() : mEntrySize(0), mEntriesEverAllocated(0) {} 120 SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf)121 size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { 122 return mEntries.ShallowSizeOfExcludingThis(aMallocSizeOf); 123 } 124 }; 125 126 FreeList mFreeLists[mozilla::eArenaObjectID_COUNT]; 127 mozilla::ArenaAllocator<8192, 8> mPool; 128 nsDataHashtable<nsPtrHashKey<void>, mozilla::ArenaObjectID> mArenaRefPtrs; 129 }; 130 131 #endif 132