diff --git a/extension/data_loader/file_descriptor_data_loader.cpp b/extension/data_loader/file_descriptor_data_loader.cpp index 48e81fd7062..d946b506905 100644 --- a/extension/data_loader/file_descriptor_data_loader.cpp +++ b/extension/data_loader/file_descriptor_data_loader.cpp @@ -41,19 +41,6 @@ static bool is_power_of_2(size_t value) { return value > 0 && (value & ~(value - 1)) == value; } -/** - * Returns the next alignment for a given pointer. - */ -static uint8_t* align_pointer(void* ptr, size_t alignment) { - intptr_t addr = reinterpret_cast(ptr); - if ((addr & (alignment - 1)) == 0) { - // Already aligned. - return reinterpret_cast(ptr); - } - // Bump forward. - addr = (addr | (alignment - 1)) + 1; - return reinterpret_cast(addr); -} } // namespace FileDescriptorDataLoader::~FileDescriptorDataLoader() { @@ -139,13 +126,13 @@ namespace { /** * FreeableBuffer::FreeFn-compatible callback. * - * `context` is actually a ptrdiff_t value (not a pointer) that contains the - * offset in bytes between `data` and the actual pointer to free. + * `context` is the original buffer pointer. It is allocated with + * ET_ALIGNED_ALLOC, and must be freed with ET_ALIGNED_FREE. + * + * `data` and `size` are unused. */ void FreeSegment(void* context, void* data, ET_UNUSED size_t size) { - ptrdiff_t offset = reinterpret_cast(context); - ET_DCHECK_MSG(offset >= 0, "Unexpected offset %ld", (long int)offset); - std::free(static_cast(data) - offset); + ET_ALIGNED_FREE(context); } } // namespace @@ -173,57 +160,24 @@ Result FileDescriptorDataLoader::load( } // Allocate memory for the FreeableBuffer. - size_t alloc_size = size; - if (alignment_ > alignof(std::max_align_t)) { - // malloc() will align to smaller values, but we must manually align to - // larger values. - alloc_size += alignment_; - } - void* buffer = std::malloc(alloc_size); - if (buffer == nullptr) { + void* aligned_buffer = ET_ALIGNED_ALLOC(alignment_, size); + if (aligned_buffer == nullptr) { ET_LOG( Error, - "Reading from %s at offset %zu: malloc(%zd) failed", + "Reading from %s at offset %zu: ET_ALIGNED_ALLOC(%zd) failed", file_descriptor_uri_, offset, size); return Error::MemoryAllocationFailed; } - // Align. - void* aligned_buffer = align_pointer(buffer, alignment_); - - // Assert that the alignment didn't overflow the buffer. - ET_DCHECK_MSG( - reinterpret_cast(aligned_buffer) + size <= - reinterpret_cast(buffer) + alloc_size, - "aligned_buffer %p + size %zu > buffer %p + alloc_size %zu", - aligned_buffer, - size, - buffer, - alloc_size); - auto err = load_into(offset, size, segment_info, aligned_buffer); if (err != Error::Ok) { - // Free `buffer`, which is what malloc() gave us, not `aligned_buffer`. - std::free(buffer); + ET_ALIGNED_FREE(aligned_buffer); return err; } - // We can't naively free this pointer, since it may not be what malloc() gave - // us. Pass the offset to the real buffer as context. This is the number of - // bytes that need to be subtracted from the FreeableBuffer::data() pointer to - // find the actual pointer to free. - return FreeableBuffer( - aligned_buffer, - size, - FreeSegment, - /*free_fn_context=*/ - reinterpret_cast( - // Using signed types here because it will produce a signed ptrdiff_t - // value, though for us it will always be non-negative. - reinterpret_cast(aligned_buffer) - - reinterpret_cast(buffer))); + return FreeableBuffer(aligned_buffer, size, FreeSegment, aligned_buffer); } Result FileDescriptorDataLoader::size() const {