Index: compiler-rt/lib/scudo/standalone/tests/vector_test.cpp =================================================================== --- compiler-rt/lib/scudo/standalone/tests/vector_test.cpp +++ compiler-rt/lib/scudo/standalone/tests/vector_test.cpp @@ -23,13 +23,18 @@ } TEST(ScudoVectorTest, Stride) { + // Fill 16 pages of elements, to exercise the code that grows the buffer as + // needed by allocating a bigger buffer and copying the old contents in it. + scudo::uptr NumElements = + 16U * scudo::getPageSizeCached() / sizeof(scudo::uptr); + scudo::Vector V; - for (scudo::uptr I = 0; I < 1000; I++) { + for (scudo::uptr I = 0; I < NumElements; I++) { V.push_back(I); EXPECT_EQ(V.size(), I + 1U); EXPECT_EQ(V[I], I); } - for (scudo::uptr I = 0; I < 1000; I++) + for (scudo::uptr I = 0; I < NumElements; I++) EXPECT_EQ(V[I], I); } Index: compiler-rt/lib/scudo/standalone/vector.h =================================================================== --- compiler-rt/lib/scudo/standalone/vector.h +++ compiler-rt/lib/scudo/standalone/vector.h @@ -9,7 +9,7 @@ #ifndef SCUDO_VECTOR_H_ #define SCUDO_VECTOR_H_ -#include "common.h" +#include "mem_map.h" #include @@ -27,7 +27,9 @@ } void destroy() { if (Data != &LocalData[0]) - unmap(Data, CapacityBytes, 0, &MapData); + ExternalBuffer.unmap(ExternalBuffer.getBase(), + ExternalBuffer.getCapacity()); + Data = nullptr; } T &operator[](uptr I) { DCHECK_LT(I, Size); @@ -82,20 +84,30 @@ void reallocate(uptr NewCapacity) { DCHECK_GT(NewCapacity, 0); DCHECK_LE(Size, NewCapacity); + + // Allocate a new memory buffer. + MemMapT NewExternalBuffer; NewCapacity = roundUp(NewCapacity * sizeof(T), getPageSizeCached()); - T *NewData = reinterpret_cast( - map(nullptr, NewCapacity, "scudo:vector", 0, &MapData)); - memcpy(NewData, Data, Size * sizeof(T)); + NewExternalBuffer.map(/*Addr=*/0U, NewCapacity, "scudo:vector"); + T *NewExternalData = reinterpret_cast(NewExternalBuffer.getBase()); + + // Move the old contents into it and free the old memory buffer. + memcpy(NewExternalData, Data, Size * sizeof(T)); destroy(); - Data = NewData; + + Data = NewExternalData; CapacityBytes = NewCapacity; + ExternalBuffer = NewExternalBuffer; } T *Data = nullptr; - T LocalData[256 / sizeof(T)] = {}; uptr CapacityBytes = 0; uptr Size = 0; - [[no_unique_address]] MapPlatformData MapData = {}; + + // We can store the contents within the VectorNoCtor itself up to a given + // capacity, or in an external memory buffer if it grows bigger than that. + T LocalData[256 / sizeof(T)] = {}; + MemMapT ExternalBuffer; }; template class Vector : public VectorNoCtor {