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(); } } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits