|
21 | 21 |
|
22 | 22 | #include <executorch/runtime/core/error.h>
|
23 | 23 | #include <executorch/runtime/core/result.h>
|
| 24 | +#include <executorch/runtime/platform/compiler.h> |
24 | 25 | #include <executorch/runtime/platform/log.h>
|
25 | 26 |
|
26 | 27 | // Some platforms (e.g. Xtensa) do not support pread() that we use to read the
|
@@ -49,20 +50,6 @@ namespace {
|
49 | 50 | static bool is_power_of_2(size_t value) {
|
50 | 51 | return value > 0 && (value & ~(value - 1)) == value;
|
51 | 52 | }
|
52 |
| - |
53 |
| -/** |
54 |
| - * Returns the next alignment for a given pointer. |
55 |
| - */ |
56 |
| -static uint8_t* align_pointer(void* ptr, size_t alignment) { |
57 |
| - intptr_t addr = reinterpret_cast<intptr_t>(ptr); |
58 |
| - if ((addr & (alignment - 1)) == 0) { |
59 |
| - // Already aligned. |
60 |
| - return reinterpret_cast<uint8_t*>(ptr); |
61 |
| - } |
62 |
| - // Bump forward. |
63 |
| - addr = (addr | (alignment - 1)) + 1; |
64 |
| - return reinterpret_cast<uint8_t*>(addr); |
65 |
| -} |
66 | 53 | } // namespace
|
67 | 54 |
|
68 | 55 | FileDataLoader::~FileDataLoader() {
|
@@ -129,13 +116,13 @@ namespace {
|
129 | 116 | /**
|
130 | 117 | * FreeableBuffer::FreeFn-compatible callback.
|
131 | 118 | *
|
132 |
| - * `context` is actually a ptrdiff_t value (not a pointer) that contains the |
133 |
| - * offset in bytes between `data` and the actual pointer to free. |
| 119 | + * `context` is the original buffer pointer. It is allocated with |
| 120 | + * ET_ALIGNED_ALLOC, and must be freed with ET_ALIGNED_FREE. |
| 121 | + * |
| 122 | + * `data` and `size` are unused. |
134 | 123 | */
|
135 | 124 | void FreeSegment(void* context, void* data, ET_UNUSED size_t size) {
|
136 |
| - ptrdiff_t offset = reinterpret_cast<ptrdiff_t>(context); |
137 |
| - ET_DCHECK_MSG(offset >= 0, "Unexpected offset %ld", (long int)offset); |
138 |
| - std::free(static_cast<uint8_t*>(data) - offset); |
| 125 | + ET_ALIGNED_FREE(context); |
139 | 126 | }
|
140 | 127 | } // namespace
|
141 | 128 |
|
@@ -163,57 +150,26 @@ Result<FreeableBuffer> FileDataLoader::load(
|
163 | 150 | }
|
164 | 151 |
|
165 | 152 | // Allocate memory for the FreeableBuffer.
|
166 |
| - size_t alloc_size = size; |
167 |
| - if (alignment_ > alignof(std::max_align_t)) { |
168 |
| - // malloc() will align to smaller values, but we must manually align to |
169 |
| - // larger values. |
170 |
| - alloc_size += alignment_; |
171 |
| - } |
172 |
| - void* buffer = std::malloc(alloc_size); |
173 |
| - if (buffer == nullptr) { |
| 153 | + void* aligned_buffer = ET_ALIGNED_ALLOC(alignment_, size); |
| 154 | + if (aligned_buffer == nullptr) { |
174 | 155 | ET_LOG(
|
175 | 156 | Error,
|
176 |
| - "Reading from %s at offset %zu: malloc(%zd) failed", |
| 157 | + "Reading from %s at offset %zu: ET_ALIGNED_ALLOC(%zd, %zd) failed", |
177 | 158 | file_name_,
|
178 | 159 | offset,
|
| 160 | + alignment_, |
179 | 161 | size);
|
180 | 162 | return Error::MemoryAllocationFailed;
|
181 | 163 | }
|
182 | 164 |
|
183 |
| - // Align. |
184 |
| - void* aligned_buffer = align_pointer(buffer, alignment_); |
185 |
| - |
186 |
| - // Assert that the alignment didn't overflow the buffer. |
187 |
| - ET_DCHECK_MSG( |
188 |
| - reinterpret_cast<uintptr_t>(aligned_buffer) + size <= |
189 |
| - reinterpret_cast<uintptr_t>(buffer) + alloc_size, |
190 |
| - "aligned_buffer %p + size %zu > buffer %p + alloc_size %zu", |
191 |
| - aligned_buffer, |
192 |
| - size, |
193 |
| - buffer, |
194 |
| - alloc_size); |
195 |
| - |
196 | 165 | auto err = load_into(offset, size, segment_info, aligned_buffer);
|
197 | 166 | if (err != Error::Ok) {
|
198 |
| - // Free `buffer`, which is what malloc() gave us, not `aligned_buffer`. |
199 |
| - std::free(buffer); |
| 167 | + ET_ALIGNED_FREE(aligned_buffer); |
200 | 168 | return err;
|
201 | 169 | }
|
202 | 170 |
|
203 |
| - // We can't naively free this pointer, since it may not be what malloc() gave |
204 |
| - // us. Pass the offset to the real buffer as context. This is the number of |
205 |
| - // bytes that need to be subtracted from the FreeableBuffer::data() pointer to |
206 |
| - // find the actual pointer to free. |
207 |
| - return FreeableBuffer( |
208 |
| - aligned_buffer, |
209 |
| - size, |
210 |
| - FreeSegment, |
211 |
| - /*free_fn_context=*/ |
212 |
| - reinterpret_cast<void*>( |
213 |
| - // Using signed types here because it will produce a signed ptrdiff_t |
214 |
| - // value, though for us it will always be non-negative. |
215 |
| - reinterpret_cast<intptr_t>(aligned_buffer) - |
216 |
| - reinterpret_cast<intptr_t>(buffer))); |
| 171 | + // Pass the aligned_buffer pointer as context to FreeSegment. |
| 172 | + return FreeableBuffer(aligned_buffer, size, FreeSegment, aligned_buffer); |
217 | 173 | }
|
218 | 174 |
|
219 | 175 | Result<size_t> FileDataLoader::size() const {
|
|
0 commit comments