aboutsummaryrefslogtreecommitdiff
path: root/compiler-rt
diff options
context:
space:
mode:
authorFabio D'Urso <fdurso@google.com>2024-06-19 09:37:23 +0200
committerGitHub <noreply@github.com>2024-06-19 09:37:23 +0200
commit7fc975aa26f2e0ce6c80629209115ea58b245da5 (patch)
tree47303613672d8e61655eef6c61436b2b9bb0f7f7 /compiler-rt
parent519175c3f5d844bac0cf3173396dc41db2873e1d (diff)
downloadllvm-7fc975aa26f2e0ce6c80629209115ea58b245da5.zip
llvm-7fc975aa26f2e0ce6c80629209115ea58b245da5.tar.gz
llvm-7fc975aa26f2e0ce6c80629209115ea58b245da5.tar.bz2
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.
Diffstat (limited to 'compiler-rt')
-rw-r--r--compiler-rt/lib/scudo/standalone/combined.h13
-rw-r--r--compiler-rt/lib/scudo/standalone/tests/combined_test.cpp23
2 files changed, 31 insertions, 5 deletions
diff --git a/compiler-rt/lib/scudo/standalone/combined.h b/compiler-rt/lib/scudo/standalone/combined.h
index f9ed365..fcf6565 100644
--- a/compiler-rt/lib/scudo/standalone/combined.h
+++ b/compiler-rt/lib/scudo/standalone/combined.h
@@ -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 -
diff --git a/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp b/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp
index 1a36155..16b19e8 100644
--- a/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp
+++ b/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp
@@ -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);
}