18#include <private/qv4global_p.h>
19#include <private/qv4value_p.h>
20#include <private/qv4scopedvalue_p.h>
21#include <private/qv4object_p.h>
22#include <private/qv4mmdefs_p.h>
117 constexpr static inline std::size_t
align(std::size_t
size)
118 {
return (
size + Chunk::SlotSize - 1) & ~(Chunk::SlotSize - 1); }
120 template<
typename ManagedType>
125 typename ManagedType::Data *
d =
static_cast<typename ManagedType::Data *
>(allocData(
size));
126 d->internalClass.set(
engine, ic);
127 Q_ASSERT(
d->internalClass &&
d->internalClass->vtable);
132 template<
typename ManagedType>
135 return allocManaged<ManagedType>(
size, ic->d());
138 template<
typename ManagedType>
143 return allocManaged<ManagedType>(
size, ic);
146 template <
typename ObjectType>
149 Heap::Object *
o = allocObjectWithMemberData(ObjectType::staticVTable(), ic->
size);
150 o->internalClass.set(
engine, ic);
151 Q_ASSERT(
o->internalClass.get() &&
o->vtable());
152 Q_ASSERT(
o->vtable() == ObjectType::staticVTable());
153 return static_cast<typename ObjectType::Data *
>(
o);
156 template <
typename ObjectType>
159 return allocateObject<ObjectType>(ic->d());
162 template <
typename ObjectType>
167 ic = ic->changeVTable(ObjectType::staticVTable());
168 ic = ic->changePrototype(ObjectType::defaultPrototype(
engine)->
d());
169 return allocateObject<ObjectType>(ic);
172 template <
typename ManagedType,
typename Arg1>
175 typename ManagedType::Data *
o =
reinterpret_cast<typename ManagedType::Data *
>(allocString(unmanagedSize));
176 o->internalClass.set(
engine, ManagedType::defaultInternalClass(
engine));
177 Q_ASSERT(
o->internalClass &&
o->internalClass->vtable);
178 o->init(std::forward<Arg1>(
arg1));
182 template <
typename ObjectType,
typename... Args>
185 typename ObjectType::Data *
d = allocateObject<ObjectType>(ic);
186 d->init(std::forward<Args>(
args)...);
190 template <
typename ObjectType,
typename... Args>
193 typename ObjectType::Data *
d = allocateObject<ObjectType>(ic);
194 d->init(std::forward<Args>(
args)...);
198 template <
typename ObjectType,
typename... Args>
203 t->d_unchecked()->init(std::forward<Args>(
args)...);
207 template <
typename ManagedType,
typename... Args>
212 t->d_unchecked()->init(std::forward<Args>(
args)...);
218 void dumpStats()
const;
220 size_t getUsedMem()
const;
221 size_t getAllocatedMem()
const;
222 size_t getLargeItemsMem()
const;
228 template<
typename ManagedType>
231 Heap::Base *
b = *allocate(&icAllocator, align(
sizeof(
typename ManagedType::Data)));
232 return static_cast<typename ManagedType::Data *
>(
b);
240 Heap::Base *allocString(std::size_t unmanagedSize);
242 Heap::Object *allocObjectWithMemberData(
const QV4::VTable *vtable,
uint nMembers);
246 MinUnmanagedHeapSizeGCLimit = 128 * 1024
249 void collectFromJSStack(MarkStack *markStack)
const;
251 void sweep(
bool lastSweep =
false, ClassDestroyStatsCallback classCountPtr =
nullptr);
252 bool shouldRunGC()
const;
253 void collectRoots(MarkStack *markStack);
255 HeapItem *allocate(BlockAllocator *allocator, std::size_t
size)
257 bool didGCRun =
false;
263 if (unmanagedHeapSize > unmanagedHeapSizeGCLimit) {
267 if (3*unmanagedHeapSizeGCLimit <= 4 * unmanagedHeapSize) {
269 unmanagedHeapSizeGCLimit = std::max(unmanagedHeapSizeGCLimit,
270 unmanagedHeapSize) * 2;
271 }
else if (unmanagedHeapSize * 4 <= unmanagedHeapSizeGCLimit) {
273 unmanagedHeapSizeGCLimit =
qMax(std::size_t(MinUnmanagedHeapSizeGCLimit),
274 unmanagedHeapSizeGCLimit/2);
279 if (
size > Chunk::DataSize)
280 return hugeItemAllocator.allocate(
size);
282 if (HeapItem *
m = allocator->allocate(
size))
285 if (!didGCRun && shouldRunGC())
288 return allocator->allocate(
size,
true);
303 std::size_t unmanagedHeapSize = 0;
305 std::size_t usedSlotsAfterLastFullSweep = 0;
307 bool gcBlocked =
false;
308 bool aggressiveGC =
false;
309 bool gcStats =
false;
310 bool gcCollectorStats =
false;
312 int allocationCount = 0;
313 size_t lastAllocRequestedSlots = 0;
316 size_t maxReservedMem = 0;
317 size_t maxAllocatedMem = 0;
318 size_t maxUsedMem = 0;
319 uint allocations[BlockAllocator::NumBins];
QVector< Value * > m_pendingFreedObjectWrapperValue
QV4::ExecutionEngine * engine
ObjectType::Data * allocateObject(Heap::InternalClass *ic)
ManagedType::Data * allocManaged(std::size_t size, Heap::InternalClass *ic)
ManagedType::Data * allocManaged(std::size_t size, InternalClass *ic)
void changeUnmanagedHeapSizeUsage(qptrdiff delta)
ObjectType::Data * allocate(Args &&... args)
ChunkAllocator * chunkAllocator
PersistentValueStorage * m_persistentValues
ManagedType::Data * allocWithStringData(std::size_t unmanagedSize, Arg1 &&arg1)
PersistentValueStorage * m_weakValues
ManagedType::Data * allocManaged(std::size_t size)
BlockAllocator blockAllocator
HugeItemAllocator hugeItemAllocator
ManagedType::Data * allocIC()
ObjectType::Data * allocateObject()
ObjectType::Data * allocObject(InternalClass *ic, Args &&... args)
ManagedType::Data * alloc(Args &&... args)
ObjectType::Data * allocObject(Heap::InternalClass *ic, Args &&... args)
std::size_t unmanagedHeapSizeGCLimit
static constexpr std::size_t align(std::size_t size)
ObjectType::Data * allocateObject(InternalClass *ic)
BlockAllocator icAllocator
QMap< QString, QString > map
[6]
Combined button and popup list for selecting options.
\qmltype Particle \inqmlmodule QtQuick.Particles
void(* ClassDestroyStatsCallback)(const char *)
#define Q_STATIC_ASSERT(Condition)
constexpr const T & qMax(const T &a, const T &b)
GLboolean GLboolean GLboolean b
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint GLuint GLuint GLuint arg1
QFuture< QSet< QChar > > set
[10]
ChunkAllocator * chunkAllocator
HeapItem * freeBins[NumBins]
size_t usedSlotsAfterLastSweep
std::vector< Chunk * > chunks
BlockAllocator(ChunkAllocator *chunkAllocator, ExecutionEngine *engine)
HeapItem * allocate(size_t size, bool forceAllocation=false)
size_t totalSlots() const
static size_t binForSlots(size_t nSlots)
size_t allocatedMem() const
std::vector< HugeChunk > chunks
HugeItemAllocator(ChunkAllocator *chunkAllocator, ExecutionEngine *engine)
ChunkAllocator * chunkAllocator
HeapItem * allocate(size_t size)
void sweep(ClassDestroyStatsCallback classCountPtr)