Index: compiler-rt/lib/xray/xray_buffer_queue.h =================================================================== --- compiler-rt/lib/xray/xray_buffer_queue.h +++ compiler-rt/lib/xray/xray_buffer_queue.h @@ -39,7 +39,6 @@ BufferExtents *Extents; }; -private: struct BufferRep { // The managed buffer. Buffer Buff; @@ -49,6 +48,7 @@ bool Used = false; }; +private: // This models a ForwardIterator. |T| Must be either a `Buffer` or `const // Buffer`. Note that we only advance to the "used" buffers, when // incrementing, so that at dereference we're always at a valid point. Index: compiler-rt/lib/xray/xray_buffer_queue.cc =================================================================== --- compiler-rt/lib/xray/xray_buffer_queue.cc +++ compiler-rt/lib/xray/xray_buffer_queue.cc @@ -16,14 +16,46 @@ #include "sanitizer_common/sanitizer_allocator_internal.h" #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_libc.h" +#include using namespace __xray; using namespace __sanitizer; +static BufferQueue::BufferRep *initArray(size_t N) { + auto A = reinterpret_cast(InternalAlloc( + N * sizeof(BufferQueue::BufferRep), nullptr, kCacheLineSize)); + if (A != nullptr) + while (N > 0) + new (A + (--N)) BufferQueue::BufferRep(); + return A; +} + +static void **initOwnedBuffers(size_t N) { + auto A = reinterpret_cast( + InternalAlloc(sizeof(void *) * N, nullptr, kCacheLineSize)); + if (A != nullptr) + while (N > 0) + new (A + --N) void *{nullptr}; + return A; +} + BufferQueue::BufferQueue(size_t B, size_t N, bool &Success) - : BufferSize(B), Buffers(new BufferRep[N]()), BufferCount(N), Finalizing{0}, - OwnedBuffers(new void *[N]()), Next(Buffers), First(Buffers), + : BufferSize(B), Buffers(initArray(N)), BufferCount(N), Finalizing{0}, + OwnedBuffers(initOwnedBuffers(N)), Next(Buffers), First(Buffers), LiveBuffers(0) { + if (Buffers == nullptr) { + Success = false; + return; + } + if (OwnedBuffers == nullptr) { + // Clean up the buffers we've already allocated. + for (auto B = Buffers, E = Buffers + BufferCount; B != E; ++B) + B->~BufferRep(); + InternalFree(Buffers); + Success = false; + return; + }; + for (size_t i = 0; i < N; ++i) { auto &T = Buffers[i]; void *Tmp = InternalAlloc(BufferSize, nullptr, 64); @@ -109,6 +141,8 @@ InternalFree(Buf.Data); InternalFree(Buf.Extents); } - delete[] Buffers; - delete[] OwnedBuffers; + for (auto B = Buffers, E = Buffers + BufferCount; B != E; ++B) + B->~BufferRep(); + InternalFree(Buffers); + InternalFree(OwnedBuffers); }