mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-26 04:46:08 +00:00
Reland "[scudo] Apply filling when realloc shrinks and re-grows a block in-place" (#95838)
Reland of #93212, which had been reverted in commit bddd8eae17df6511aee789744ccdc158de817081.
This commit is contained in:
parent
519175c3f5
commit
7fc975aa26
@ -549,6 +549,19 @@ public:
|
||||
// header to reflect the size change.
|
||||
if (reinterpret_cast<uptr>(OldTaggedPtr) + NewSize <= BlockEnd) {
|
||||
if (NewSize > OldSize || (OldSize - NewSize) < getPageSizeCached()) {
|
||||
// If we have reduced the size, set the extra bytes to the fill value
|
||||
// so that we are ready to grow it again in the future.
|
||||
if (NewSize < OldSize) {
|
||||
const FillContentsMode FillContents =
|
||||
TSDRegistry.getDisableMemInit() ? NoFill
|
||||
: Options.getFillContentsMode();
|
||||
if (FillContents != NoFill) {
|
||||
memset(reinterpret_cast<char *>(OldTaggedPtr) + NewSize,
|
||||
FillContents == ZeroFill ? 0 : PatternFillByte,
|
||||
OldSize - NewSize);
|
||||
}
|
||||
}
|
||||
|
||||
Header.SizeOrUnusedBytes =
|
||||
(ClassId ? NewSize
|
||||
: BlockEnd -
|
||||
|
@ -447,19 +447,32 @@ SCUDO_TYPED_TEST(ScudoCombinedDeathTest, ReallocateSame) {
|
||||
// returns the same chunk. This requires that all the sizes we iterate on use
|
||||
// the same block size, but that should be the case for MaxSize - 64 with our
|
||||
// default class size maps.
|
||||
constexpr scudo::uptr ReallocSize =
|
||||
constexpr scudo::uptr InitialSize =
|
||||
TypeParam::Primary::SizeClassMap::MaxSize - 64;
|
||||
void *P = Allocator->allocate(ReallocSize, Origin);
|
||||
const char Marker = 'A';
|
||||
memset(P, Marker, ReallocSize);
|
||||
Allocator->setFillContents(scudo::PatternOrZeroFill);
|
||||
|
||||
void *P = Allocator->allocate(InitialSize, Origin);
|
||||
scudo::uptr CurrentSize = InitialSize;
|
||||
for (scudo::sptr Delta = -32; Delta < 32; Delta += 8) {
|
||||
memset(P, Marker, CurrentSize);
|
||||
const scudo::uptr NewSize =
|
||||
static_cast<scudo::uptr>(static_cast<scudo::sptr>(ReallocSize) + Delta);
|
||||
static_cast<scudo::uptr>(static_cast<scudo::sptr>(InitialSize) + Delta);
|
||||
void *NewP = Allocator->reallocate(P, NewSize);
|
||||
EXPECT_EQ(NewP, P);
|
||||
for (scudo::uptr I = 0; I < ReallocSize - 32; I++)
|
||||
|
||||
// Verify that existing contents have been preserved.
|
||||
for (scudo::uptr I = 0; I < scudo::Min(CurrentSize, NewSize); I++)
|
||||
EXPECT_EQ((reinterpret_cast<char *>(NewP))[I], Marker);
|
||||
|
||||
// Verify that new bytes are set according to FillContentsMode.
|
||||
for (scudo::uptr I = CurrentSize; I < NewSize; I++) {
|
||||
unsigned char V = (reinterpret_cast<unsigned char *>(NewP))[I];
|
||||
EXPECT_TRUE(V == scudo::PatternFillByte || V == 0);
|
||||
}
|
||||
|
||||
checkMemoryTaggingMaybe(Allocator, NewP, NewSize, 0);
|
||||
CurrentSize = NewSize;
|
||||
}
|
||||
Allocator->deallocate(P, Origin);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user