diff options
author | Timm Baeder <tbaeder@redhat.com> | 2025-08-18 17:15:31 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-08-18 17:15:31 +0200 |
commit | 6ce13ae1c20515e7c4554cde028e3a0990786075 (patch) | |
tree | 320f0d2c13267df35df93d4f7cdd9ea8a7f0c710 /clang/lib/AST/ByteCode/Compiler.cpp | |
parent | 08a140add86081932515188bd9120fd5e69f3ac3 (diff) | |
download | llvm-6ce13ae1c20515e7c4554cde028e3a0990786075.zip llvm-6ce13ae1c20515e7c4554cde028e3a0990786075.tar.gz llvm-6ce13ae1c20515e7c4554cde028e3a0990786075.tar.bz2 |
[clang][bytecode] Always track item types in InterpStack (#151088)
This has been a long-standing problem, but we didn't use to call the
destructors of items on the stack unless we explicitly `pop()` or
`discard()` them.
When interpretation was interrupted midway-through (because something
failed), we left `Pointer`s on the stack. Since all `Block`s track what
`Pointer`s point to them (via a doubly-linked list in the `Pointer`),
that meant we potentially leave deallocated pointers in that list. We
used to work around this by removing the `Pointer` from the list before
deallocating the block.
However, we now want to track pointers to global blocks as well, which
poses a problem since the blocks are never deallocated and thus those
pointers are always left dangling.
I've tried a few different approaches to fixing this but in the end I
just gave up on the idea of never knowing what items are in the stack.
We already have an `ItemTypes` vector that we use for debugging
assertions. This patch simply enables this vector unconditionally and
uses it in the abort case to properly `discard()` all elements from the
stack. That's a little sad IMO but I don't know of another way of
solving this problem.
As expected, this is a slight hit to compile times:
https://llvm-compile-time-tracker.com/compare.php?from=574d0a92060bf4808776b7a0239ffe91a092b15d&to=0317105f559093cfb909bfb01857a6b837991940&stat=instructions:u
Diffstat (limited to 'clang/lib/AST/ByteCode/Compiler.cpp')
-rw-r--r-- | clang/lib/AST/ByteCode/Compiler.cpp | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index 5c41647..f2ce69a 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -2980,20 +2980,25 @@ bool Compiler<Emitter>::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) { if (T && !E->isLValue()) return this->delegate(Init); - if (std::optional<unsigned> GlobalIndex = P.createGlobal(E)) { - if (!this->emitGetPtrGlobal(*GlobalIndex, E)) - return false; + std::optional<unsigned> GlobalIndex = P.createGlobal(E); + if (!GlobalIndex) + return false; - if (T) { - if (!this->visit(Init)) - return false; - return this->emitInitGlobal(*T, *GlobalIndex, E); - } + if (!this->emitGetPtrGlobal(*GlobalIndex, E)) + return false; + + // Since this is a global variable, we might've already seen, + // don't do it again. + if (P.isGlobalInitialized(*GlobalIndex)) + return true; - return this->visitInitializer(Init) && this->emitFinishInit(E); + if (T) { + if (!this->visit(Init)) + return false; + return this->emitInitGlobal(*T, *GlobalIndex, E); } - return false; + return this->visitInitializer(Init) && this->emitFinishInit(E); } // Otherwise, use a local variable. |