[clang] 41803a2 - [clang][bytecode] Replace MoveFn With DtorFn + memcpy (#151717)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Aug 2 05:47:53 PDT 2025
Author: Timm Baeder
Date: 2025-08-02T14:47:49+02:00
New Revision: 41803a24140c3c53bbc82c7b61c7b196cf9d113a
URL: https://github.com/llvm/llvm-project/commit/41803a24140c3c53bbc82c7b61c7b196cf9d113a
DIFF: https://github.com/llvm/llvm-project/commit/41803a24140c3c53bbc82c7b61c7b196cf9d113a.diff
LOG: [clang][bytecode] Replace MoveFn With DtorFn + memcpy (#151717)
First, the old MoveFn was rather inefficient, since the dead data cannot
ever be accessed anyway.
Second, there was a problem where the only reason a block still had a
pointer to it (and thus was made into a DeadBlock instead of simply
being deallocated) as that a nested field in the block pointed to the
block itself.
Fix this by calling the dtor function unconditionally. If the block
*still* has pointers after that, we really need to create a DeadBlock
for it.
Added:
Modified:
clang/lib/AST/ByteCode/InterpState.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/ByteCode/InterpState.cpp b/clang/lib/AST/ByteCode/InterpState.cpp
index 30108475d7db0..32ad07bb55d45 100644
--- a/clang/lib/AST/ByteCode/InterpState.cpp
+++ b/clang/lib/AST/ByteCode/InterpState.cpp
@@ -77,27 +77,27 @@ void InterpState::deallocate(Block *B) {
const Descriptor *Desc = B->getDescriptor();
assert(Desc);
+ // The block might have a pointer saved in a field in its data
+ // that points to the block itself. We call the dtor first,
+ // which will destroy all the data but leave InlineDescriptors
+ // intact. If the block THEN still has pointers, we create a
+ // DeadBlock for it.
+ if (B->IsInitialized)
+ B->invokeDtor();
+
if (B->hasPointers()) {
size_t Size = B->getSize();
-
// Allocate a new block, transferring over pointers.
char *Memory =
reinterpret_cast<char *>(std::malloc(sizeof(DeadBlock) + Size));
auto *D = new (Memory) DeadBlock(DeadBlocks, B);
- std::memset(D->B.rawData(), 0, D->B.getSize());
-
- // Move data and metadata from the old block to the new (dead)block.
- if (B->IsInitialized && Desc->MoveFn) {
- Desc->MoveFn(B, B->data(), D->data(), Desc);
- if (Desc->getMetadataSize() > 0)
- std::memcpy(D->rawData(), B->rawData(), Desc->getMetadataSize());
- }
+ // Since the block doesn't hold any actual data anymore, we can just
+ // memcpy() everything over.
+ std::memcpy(D->rawData(), B->rawData(), Desc->getAllocSize());
D->B.IsInitialized = B->IsInitialized;
// We moved the contents over to the DeadBlock.
B->IsInitialized = false;
- } else if (B->IsInitialized) {
- B->invokeDtor();
}
}
More information about the cfe-commits
mailing list