Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qqmljsmemorypool_p.h
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant
4
5#ifndef QQMLJSMEMORYPOOL_P_H
6#define QQMLJSMEMORYPOOL_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <QtCore/private/qglobal_p.h>
20#include <QtCore/qstring.h>
21#include <QtCore/qvector.h>
22
23#include <cstdlib>
24
25QT_BEGIN_NAMESPACE
26
27namespace QQmlJS {
28
29class Managed;
30
32{
34
35public:
36 MemoryPool() = default;
38 {
39 if (_blocks) {
40 for (int i = 0; i < _allocatedBlocks; ++i) {
41 if (char *b = _blocks[i])
42 free(b);
43 }
44
45 free(_blocks);
46 }
47 }
48
49 inline void *allocate(size_t size)
50 {
51 size = (size + 7) & ~size_t(7);
52 if (Q_LIKELY(_ptr && size < size_t(_end - _ptr))) {
53 void *addr = _ptr;
54 _ptr += size;
55 return addr;
56 }
57 return allocate_helper(size);
58 }
59
60 void reset()
61 {
62 _blockCount = -1;
63 _ptr = _end = nullptr;
64 }
65
66 template <typename Tp> Tp *New() { return new (this->allocate(sizeof(Tp))) Tp(); }
67 template <typename Tp, typename... Ta> Tp *New(Ta... args)
68 { return new (this->allocate(sizeof(Tp))) Tp(args...); }
69
70 QStringView newString(QString string) {
71 return strings.emplace_back(std::move(string));
72 }
73
74private:
75 Q_NEVER_INLINE void *allocate_helper(size_t size)
76 {
77 size_t currentBlockSize = DEFAULT_BLOCK_SIZE;
78 while (Q_UNLIKELY(size >= currentBlockSize))
79 currentBlockSize *= 2;
80
81 if (++_blockCount == _allocatedBlocks) {
82 if (! _allocatedBlocks)
83 _allocatedBlocks = DEFAULT_BLOCK_COUNT;
84 else
85 _allocatedBlocks *= 2;
86
87 _blocks = reinterpret_cast<char **>(realloc(_blocks, sizeof(char *) * size_t(_allocatedBlocks)));
88 Q_CHECK_PTR(_blocks);
89
90 for (int index = _blockCount; index < _allocatedBlocks; ++index)
91 _blocks[index] = nullptr;
92 }
93
94 char *&block = _blocks[_blockCount];
95
96 if (! block) {
97 block = reinterpret_cast<char *>(malloc(currentBlockSize));
98 Q_CHECK_PTR(block);
99 }
100
101 _ptr = block;
102 _end = _ptr + currentBlockSize;
103
104 void *addr = _ptr;
105 _ptr += size;
106 return addr;
107 }
108
109private:
110 char **_blocks = nullptr;
111 int _allocatedBlocks = 0;
112 int _blockCount = -1;
113 char *_ptr = nullptr;
114 char *_end = nullptr;
115 QStringList strings;
116
117 enum
118 {
119 DEFAULT_BLOCK_SIZE = 8 * 1024,
120 DEFAULT_BLOCK_COUNT = 8
121 };
122};
123
125{
127public:
128 Managed() = default;
129 ~Managed() = default;
130
131 void *operator new(size_t size, MemoryPool *pool) { return pool->allocate(size); }
132 void operator delete(void *) {}
133 void operator delete(void *, MemoryPool *) {}
134};
135
136} // namespace QQmlJS
137
138QT_END_NAMESPACE
139
140#endif
void operator delete(void *)
~Managed()=default
void operator delete(void *, MemoryPool *)
void * operator new(size_t size, MemoryPool *pool)
QStringView newString(QString string)
MemoryPool()=default
void * allocate(size_t size)
Tp * New(Ta... args)