Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qv4identifiertable.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 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
4#include "qv4symbol_p.h"
5#include <private/qv4identifierhashdata_p.h>
6#include <private/qprimefornumbits_p.h>
7
9
10namespace QV4 {
11
13 : engine(engine)
14 , size(0)
15 , numBits(numBits)
16{
20 memset(entriesByHash, 0, alloc*sizeof(Heap::String *));
21 memset(entriesById, 0, alloc*sizeof(Heap::String *));
22}
23
25{
26 free(entriesByHash);
27 free(entriesById);
28 for (const auto &h : std::as_const(idHashes))
29 h->identifierTable = nullptr;
30}
31
33{
34 uint hash = str->hashValue();
35
37 return;
38
40
41 bool grow = (alloc <= size*2);
42
43 if (grow) {
44 ++numBits;
45 int newAlloc = qPrimeForNumBits(numBits);
46 Heap::StringOrSymbol **newEntries = (Heap::StringOrSymbol **)malloc(newAlloc*sizeof(Heap::String *));
47 memset(newEntries, 0, newAlloc*sizeof(Heap::StringOrSymbol *));
48 for (uint i = 0; i < alloc; ++i) {
50 if (!e)
51 continue;
52 uint idx = e->stringHash % newAlloc;
53 while (newEntries[idx]) {
54 ++idx;
55 idx %= newAlloc;
56 }
57 newEntries[idx] = e;
58 }
59 free(entriesByHash);
60 entriesByHash = newEntries;
61
62 newEntries = (Heap::StringOrSymbol **)malloc(newAlloc*sizeof(Heap::String *));
63 memset(newEntries, 0, newAlloc*sizeof(Heap::StringOrSymbol *));
64 for (uint i = 0; i < alloc; ++i) {
66 if (!e)
67 continue;
68 uint idx = e->identifier.id() % newAlloc;
69 while (newEntries[idx]) {
70 ++idx;
71 idx %= newAlloc;
72 }
73 newEntries[idx] = e;
74 }
75 free(entriesById);
76 entriesById = newEntries;
77
78 alloc = newAlloc;
79 }
80
81 uint idx = hash % alloc;
82 while (entriesByHash[idx]) {
83 ++idx;
84 idx %= alloc;
85 }
86 entriesByHash[idx] = str;
87
88 idx = str->identifier.id() % alloc;
89 while (entriesById[idx]) {
90 ++idx;
91 idx %= alloc;
92 }
93 entriesById[idx] = str;
94
95 ++size;
96}
97
98
99
101{
102 uint subtype;
103 uint hash = String::createHashValue(s.constData(), s.size(), &subtype);
106 str->stringHash = hash;
107 str->subtype = subtype;
108 str->identifier = PropertyKey::fromArrayIndex(hash);
109 return str;
110 }
111 return resolveStringEntry(s, hash, subtype);
112}
113
114Heap::String *IdentifierTable::resolveStringEntry(const QString &s, uint hash, uint subtype)
115{
116 uint idx = hash % alloc;
117 while (Heap::StringOrSymbol *e = entriesByHash[idx]) {
118 if (e->stringHash == hash && e->toQString() == s)
119 return static_cast<Heap::String *>(e);
120 ++idx;
121 idx %= alloc;
122 }
123
124 Heap::String *str = engine->newString(s);
125 str->stringHash = hash;
126 str->subtype = subtype;
127 addEntry(str);
128 return str;
129}
130
132{
133 Q_ASSERT(s.at(0) == QLatin1Char('@'));
134
135 uint subtype;
136 uint hash = String::createHashValue(s.constData(), s.size(), &subtype);
137 uint idx = hash % alloc;
138 while (Heap::StringOrSymbol *e = entriesByHash[idx]) {
139 if (e->stringHash == hash && e->toQString() == s)
140 return static_cast<Heap::Symbol *>(e);
141 ++idx;
142 idx %= alloc;
143 }
144
146 str->stringHash = hash;
147 str->subtype = subtype;
148 addEntry(str);
149 return str;
150
151}
152
153
155{
156 if (str->identifier.isValid())
157 return str->identifier;
158 uint hash = str->hashValue();
160 str->identifier = PropertyKey::fromArrayIndex(hash);
161 return str->identifier;
162 }
163
164 uint idx = hash % alloc;
165 while (Heap::StringOrSymbol *e = entriesByHash[idx]) {
166 if (e->stringHash == hash && e->toQString() == str->toQString()) {
167 str->identifier = e->identifier;
168 return e->identifier;
169 }
170 ++idx;
171 idx %= alloc;
172 }
173
174 addEntry(const_cast<QV4::Heap::String *>(str));
175 return str->identifier;
176}
177
179{
180 if (i.isArrayIndex())
181 return engine->newString(QString::number(i.asArrayIndex()));
182 if (!i.isValid())
183 return nullptr;
184
185 uint idx = i.id() % alloc;
186 while (1) {
188 if (!e || e->identifier == i)
189 return e;
190 ++idx;
191 idx %= alloc;
192 }
193}
194
196{
198 Q_ASSERT(s && s->internalClass->vtable->isString);
199 return static_cast<Heap::String *>(s);
200}
201
203{
205 Q_ASSERT(!s || !s->internalClass->vtable->isString);
206 return static_cast<Heap::Symbol *>(s);
207}
208
210{
211 for (const auto &h : idHashes)
212 h->markObjects(markStack);
213}
214
216{
217 int freed = 0;
218
219 Heap::StringOrSymbol **newTable = (Heap::StringOrSymbol **)malloc(alloc*sizeof(Heap::String *));
220 memset(newTable, 0, alloc*sizeof(Heap::StringOrSymbol *));
221 memset(entriesById, 0, alloc*sizeof(Heap::StringOrSymbol *));
222 for (uint i = 0; i < alloc; ++i) {
224 if (!e)
225 continue;
226 if (!e->isMarked()) {
227 ++freed;
228 continue;
229 }
230 uint idx = e->hashValue() % alloc;
231 while (newTable[idx]) {
232 ++idx;
233 if (idx == alloc)
234 idx = 0;
235 }
236 newTable[idx] = e;
237
238 idx = e->identifier.id() % alloc;
239 while (entriesById[idx]) {
240 ++idx;
241 if (idx == alloc)
242 idx = 0;
243 }
244 entriesById[idx] = e;
245 }
246 free(entriesByHash);
247 entriesByHash = newTable;
248
249 size -= freed;
250}
251
253{
254 uint subtype;
255 const uint hash = String::createHashValue(s.constData(), s.size(), &subtype);
258 return resolveStringEntry(s, hash, subtype)->identifier;
259}
260
262{
263 uint subtype;
264 uint hash = String::createHashValue(s, len, &subtype);
267 return resolveStringEntry(QString::fromLatin1(s, len), hash, subtype)->identifier;
268}
269
270}
271
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5710
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:7822
QHash< int, QWidget * > hash
[35multi]
QString str
[2]
double e
Combined button and popup list for selecting options.
\qmltype Particle \inqmlmodule QtQuick.Particles
static int grow(QLayoutStruct &ls, int delta)
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLfloat GLfloat GLfloat GLfloat h
GLenum GLsizei len
GLdouble s
[6]
Definition qopenglext.h:235
QT_BEGIN_NAMESPACE int qPrimeForNumBits(int numBits)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
unsigned int uint
Definition qtypes.h:29
QJSEngine engine
[0]
\inmodule QtCore \reentrant
Definition qchar.h:17
Heap::String * newString(const QString &s=QString())
Heap::Symbol * symbolForId(PropertyKey i) const
PropertyKey asPropertyKey(const Heap::String *str)
Heap::Symbol * insertSymbol(const QString &s)
Heap::StringOrSymbol ** entriesById
IdentifierTable(ExecutionEngine *engine, int numBits=8)
Heap::String * stringForId(PropertyKey i) const
Heap::String * insertString(const QString &s)
QSet< IdentifierHashData * > idHashes
void addEntry(Heap::StringOrSymbol *str)
Heap::StringOrSymbol ** entriesByHash
PropertyKey asPropertyKeyImpl(const Heap::String *str)
Heap::StringOrSymbol * resolveId(PropertyKey i) const
void markObjects(MarkStack *markStack)
static PropertyKey fromStringOrSymbol(StringOrSymbol *b)
static PropertyKey fromArrayIndex(uint idx)
static uint createHashValue(const QChar *ch, int length, uint *subtype)
static V4_NEEDS_DESTROY Heap::Symbol * create(ExecutionEngine *e, const QString &s)