Skip to content

Commit 41803a2

Browse files
authored
[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.
1 parent 0e40051 commit 41803a2

File tree

1 file changed

+11
-11
lines changed

1 file changed

+11
-11
lines changed

clang/lib/AST/ByteCode/InterpState.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -77,27 +77,27 @@ void InterpState::deallocate(Block *B) {
7777
const Descriptor *Desc = B->getDescriptor();
7878
assert(Desc);
7979

80+
// The block might have a pointer saved in a field in its data
81+
// that points to the block itself. We call the dtor first,
82+
// which will destroy all the data but leave InlineDescriptors
83+
// intact. If the block THEN still has pointers, we create a
84+
// DeadBlock for it.
85+
if (B->IsInitialized)
86+
B->invokeDtor();
87+
8088
if (B->hasPointers()) {
8189
size_t Size = B->getSize();
82-
8390
// Allocate a new block, transferring over pointers.
8491
char *Memory =
8592
reinterpret_cast<char *>(std::malloc(sizeof(DeadBlock) + Size));
8693
auto *D = new (Memory) DeadBlock(DeadBlocks, B);
87-
std::memset(D->B.rawData(), 0, D->B.getSize());
88-
89-
// Move data and metadata from the old block to the new (dead)block.
90-
if (B->IsInitialized && Desc->MoveFn) {
91-
Desc->MoveFn(B, B->data(), D->data(), Desc);
92-
if (Desc->getMetadataSize() > 0)
93-
std::memcpy(D->rawData(), B->rawData(), Desc->getMetadataSize());
94-
}
94+
// Since the block doesn't hold any actual data anymore, we can just
95+
// memcpy() everything over.
96+
std::memcpy(D->rawData(), B->rawData(), Desc->getAllocSize());
9597
D->B.IsInitialized = B->IsInitialized;
9698

9799
// We moved the contents over to the DeadBlock.
98100
B->IsInitialized = false;
99-
} else if (B->IsInitialized) {
100-
B->invokeDtor();
101101
}
102102
}
103103

0 commit comments

Comments
 (0)