Fix removal of members from the InternalClass
Removing identifiers from the propertyhash could cause subtle issues
if there was an identifier that hashed to the same value as the identifier
being removed stored in the hash afterwards. This identifier could
end up in a state where it could not be found anymore.
Amends ea164ca4a8
Change-Id: I2881865ee83833b6364d9be55579b8fc7d7c5016
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This commit is contained in:
parent
4615ffda64
commit
0dd479fc8d
|
@ -88,19 +88,30 @@ void PropertyHash::addEntry(const PropertyHash::Entry &entry, int classSize)
|
||||||
|
|
||||||
int PropertyHash::removeIdentifier(Identifier *identifier, int classSize)
|
int PropertyHash::removeIdentifier(Identifier *identifier, int classSize)
|
||||||
{
|
{
|
||||||
detach(false, classSize);
|
int val = -1;
|
||||||
uint idx = identifier->hashValue % d->alloc;
|
PropertyHashData *dd = new PropertyHashData(d->numBits);
|
||||||
while (1) {
|
for (int i = 0; i < d->alloc; ++i) {
|
||||||
if (d->entries[idx].identifier == identifier) {
|
const Entry &e = d->entries[i];
|
||||||
int val = d->entries[idx].index;
|
if (!e.identifier || e.index >= static_cast<unsigned>(classSize))
|
||||||
d->entries[idx] = { nullptr, 0 };
|
continue;
|
||||||
return val;
|
if (e.identifier == identifier) {
|
||||||
|
val = e.index;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
uint idx = e.identifier->hashValue % dd->alloc;
|
||||||
++idx;
|
while (dd->entries[idx].identifier) {
|
||||||
idx %= d->alloc;
|
++idx;
|
||||||
|
idx %= dd->alloc;
|
||||||
|
}
|
||||||
|
dd->entries[idx] = e;
|
||||||
}
|
}
|
||||||
Q_UNREACHABLE();
|
dd->size = classSize;
|
||||||
|
if (!--d->refCount)
|
||||||
|
delete d;
|
||||||
|
d = dd;
|
||||||
|
|
||||||
|
Q_ASSERT(val != -1);
|
||||||
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PropertyHash::detach(bool grow, int classSize)
|
void PropertyHash::detach(bool grow, int classSize)
|
||||||
|
|
Loading…
Reference in New Issue