|
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,27 @@ 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 | 167 | // Free `buffer`, which is what malloc() gave us, not `aligned_buffer`. |
199 | | - std::free(buffer); |
| 168 | + ET_ALIGNED_FREE(aligned_buffer); |
200 | 169 | return err; |
201 | 170 | } |
202 | 171 |
|
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))); |
| 172 | + // Pass the buffer pointer as context to FreeSegment |
| 173 | + return FreeableBuffer(aligned_buffer, size, FreeSegment, aligned_buffer); |
217 | 174 | } |
218 | 175 |
|
219 | 176 | Result<size_t> FileDataLoader::size() const { |
|
0 commit comments