diff --git a/src/gpgmm/common/BuddyMemoryAllocator.cpp b/src/gpgmm/common/BuddyMemoryAllocator.cpp index 809c4f5d..b29ee0fd 100644 --- a/src/gpgmm/common/BuddyMemoryAllocator.cpp +++ b/src/gpgmm/common/BuddyMemoryAllocator.cpp @@ -54,7 +54,7 @@ namespace gpgmm { const uint64_t allocationSize = UpperPowerOfTwo(request.SizeInBytes); // Request cannot exceed memory size. - GPGMM_INVALID_IF(allocationSize > mMemorySize); + GPGMM_RETURN_ERROR_IF(allocationSize > mMemorySize, "Allocation size exceeds memory size"); // Attempt to sub-allocate a block of the requested size. std::unique_ptr subAllocation; diff --git a/src/gpgmm/common/Error.h b/src/gpgmm/common/Error.h index a2459899..83a20dc5 100644 --- a/src/gpgmm/common/Error.h +++ b/src/gpgmm/common/Error.h @@ -34,17 +34,18 @@ { \ auto result = expr; \ if (GPGMM_UNLIKELY(!result.IsSuccess())) { \ - return {}; \ + return result.AcquireError(); \ } \ } \ for (;;) \ break -#define GPGMM_INVALID_IF(expr) \ - if (GPGMM_UNLIKELY(expr)) { \ - return {}; \ - } \ - for (;;) \ +#define GPGMM_RETURN_ERROR_IF(expr, msg) \ + if (GPGMM_UNLIKELY(expr)) { \ + gpgmm::DebugLog() << msg; \ + return std::move(::gpgmm::ErrorCodeType(kInternalFailureResult)); \ + } \ + for (;;) \ break namespace gpgmm { @@ -97,6 +98,10 @@ namespace gpgmm { return std::move(mResult); } + ErrorT&& AcquireError() { + return std::move(mErrorCode); + } + bool IsSuccess() const { return mErrorCode == kInternalSuccessResult; } @@ -129,6 +134,10 @@ namespace gpgmm { return mErrorCode == kInternalSuccessResult; } + ErrorT&& AcquireError() { + return std::move(mErrorCode); + } + private: ErrorT mErrorCode; }; diff --git a/src/gpgmm/common/MemoryAllocator.cpp b/src/gpgmm/common/MemoryAllocator.cpp index e0481ccb..fbb77569 100644 --- a/src/gpgmm/common/MemoryAllocator.cpp +++ b/src/gpgmm/common/MemoryAllocator.cpp @@ -157,35 +157,31 @@ namespace gpgmm { } MaybeError MemoryAllocatorBase::ValidateRequest(const MemoryAllocationRequest& request) const { - ASSERT(request.SizeInBytes > 0 && request.Alignment > 0); + // Check for non-zero size and alignment. + GPGMM_RETURN_ERROR_IF(request.SizeInBytes == 0, "Request cannot have zero size."); + GPGMM_RETURN_ERROR_IF(request.Alignment == 0, "Request cannot have zero alignment."); // Check request size cannot overflow. - if (request.SizeInBytes > std::numeric_limits::max() - (request.Alignment - 1)) { - DebugLog(MessageId::kSizeExceeded, this) - << "Requested size rejected due to overflow: " + std::to_string(request.SizeInBytes) - << " bytes."; - return std::move(ErrorCodeType(kInternalFailureResult)); - } + GPGMM_RETURN_ERROR_IF( + request.SizeInBytes > std::numeric_limits::max() - (request.Alignment - 1), + "Requested size invalid due to overflow: " + std::to_string(request.SizeInBytes) + + " bytes."); // Check request size cannot overflow |this| memory allocator. - const uint64_t alignedSize = AlignTo(request.SizeInBytes, request.Alignment); - if (GetMemorySize() != kInvalidSize && alignedSize > GetMemorySize()) { - DebugLog(MessageId::kSizeExceeded, this) - << "Requested size exceeds memory size (" + std::to_string(alignedSize) + " vs " + - std::to_string(GetMemorySize()) + " bytes)."; - return std::move(ErrorCodeType(kInternalFailureResult)); - } + const uint64_t requestedAlignedSize = AlignTo(request.SizeInBytes, request.Alignment); + GPGMM_RETURN_ERROR_IF( + GetMemorySize() != kInvalidSize && requestedAlignedSize > GetMemorySize(), + "Requested size, after alignment, exceeds memory size (" + + std::to_string(requestedAlignedSize) + " vs " + std::to_string(GetMemorySize()) + + " bytes)."); // Check request size has compatible alignment with |this| memory allocator. // Alignment value of 1 means no alignment required. - if (GetMemoryAlignment() == 0 || - (GetMemoryAlignment() > 1 && !IsAligned(GetMemoryAlignment(), request.Alignment))) { - DebugLog(MessageId::kAlignmentMismatch, this) - << "Requested alignment exceeds memory alignment (" + - std::to_string(request.Alignment) + " vs " + - std::to_string(GetMemoryAlignment()) + " bytes)."; - return std::move(ErrorCodeType(kInternalFailureResult)); - } + GPGMM_RETURN_ERROR_IF( + GetMemoryAlignment() == 0 || + (GetMemoryAlignment() > 1 && !IsAligned(GetMemoryAlignment(), request.Alignment)), + "Requested alignment exceeds memory alignment (" + std::to_string(request.Alignment) + + " vs " + std::to_string(GetMemoryAlignment()) + " bytes)."); return {}; } diff --git a/src/gpgmm/common/SlabMemoryAllocator.cpp b/src/gpgmm/common/SlabMemoryAllocator.cpp index 3b789f9b..89b8ec77 100644 --- a/src/gpgmm/common/SlabMemoryAllocator.cpp +++ b/src/gpgmm/common/SlabMemoryAllocator.cpp @@ -202,7 +202,8 @@ namespace gpgmm { std::lock_guard lock(mMutex); - GPGMM_INVALID_IF(request.SizeInBytes > mBlockSize); + GPGMM_RETURN_ERROR_IF(request.SizeInBytes > mBlockSize, + "Allocation size exceeded block size."); uint64_t slabSize = ComputeSlabSize(request.SizeInBytes, std::max(mMinSlabSize, mLastUsedSlabSize), @@ -229,7 +230,8 @@ namespace gpgmm { uint64_t newSlabSize = ComputeSlabSize( request.SizeInBytes, static_cast(slabSize * mSlabGrowthFactor), request.AvailableForAllocation); - GPGMM_INVALID_IF(newSlabSize == kInvalidSize); + + GPGMM_RETURN_ERROR_IF(newSlabSize == kInvalidSize, "Slab size was invalid."); // If the new slab size exceeds the limit, then re-use the previous, smaller size. if (newSlabSize > mMaxSlabSize) { @@ -518,7 +520,8 @@ namespace gpgmm { GPGMM_RETURN_IF_ERROR(ValidateRequest(request)); const uint64_t blockSize = AlignTo(request.SizeInBytes, request.Alignment); - GPGMM_INVALID_IF(blockSize > mMaxSlabSize); + + GPGMM_RETURN_ERROR_IF(blockSize > mMaxSlabSize, "Block size exceeded max slab size."); // Create a slab allocator for the new entry. auto entry =