Merge pull request #8696 from sfc-gh-dadkins/sfc-gh-dadkins/arena-self-ref

Assert that we don't try to have an ArenaBlock depend on itself.
This commit is contained in:
Jingyu Zhou 2022-11-11 09:47:39 -08:00 committed by GitHub
commit 8ad98dc9db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 16 additions and 5 deletions

View File

@ -118,14 +118,14 @@ Arena::Arena(Arena&& r) noexcept = default;
Arena& Arena::operator=(const Arena& r) = default;
Arena& Arena::operator=(Arena&& r) noexcept = default;
void Arena::dependsOn(const Arena& p) {
if (p.impl) {
// x.dependsOn(y) is a no-op if they refer to the same ArenaBlocks.
// They will already have the same lifetime.
if (p.impl && p.impl.getPtr() != impl.getPtr()) {
allowAccess(impl.getPtr());
allowAccess(p.impl.getPtr());
ArenaBlock::dependOn(impl, p.impl.getPtr());
disallowAccess(p.impl.getPtr());
if (p.impl.getPtr() != impl.getPtr()) {
disallowAccess(impl.getPtr());
}
disallowAccess(impl.getPtr());
}
}
@ -297,6 +297,7 @@ void* ArenaBlock::make4kAlignedBuffer(uint32_t size) {
}
void ArenaBlock::dependOn(Reference<ArenaBlock>& self, ArenaBlock* other) {
ASSERT(self->getData() != other->getData());
other->addref();
if (!self || self->isTiny() || self->unused() < sizeof(ArenaBlockRef))
create(SMALL, self)->makeReference(other);
@ -775,6 +776,16 @@ TEST_CASE("/flow/Arena/Size") {
return Void();
}
// Test that x.dependsOn(x) works, and is effectively a no-op.
TEST_CASE("/flow/Arena/SelfRef") {
Arena a(4096);
// This should be a no-op.
a.dependsOn(a);
return Void();
}
TEST_CASE("flow/StringRef/eat") {
StringRef str = "test/case"_sr;
StringRef first = str.eat("/");
@ -815,4 +826,4 @@ TEST_CASE("flow/StringRef/eat") {
ASSERT(str == ""_sr);
return Void();
}
}