@@ -18,7 +18,7 @@ var c_allocator_state = Allocator{
18
18
};
19
19
20
20
fn cRealloc (self : * Allocator , old_mem : []u8 , old_align : u29 , new_size : usize , new_align : u29 ) ! []u8 {
21
- assert (new_align <= @alignOf (c_longdouble ));
21
+ if (new_align > @alignOf (c_longdouble )) return error . OutOfMemory ;
22
22
const old_ptr = if (old_mem .len == 0 ) null else @ptrCast (* c_void , old_mem .ptr );
23
23
const buf = c .realloc (old_ptr , new_size ) orelse return error .OutOfMemory ;
24
24
return @ptrCast ([* ]u8 , buf )[0.. new_size ];
@@ -143,7 +143,7 @@ pub const DirectAllocator = struct {
143
143
const result = try alloc (allocator , new_size , new_align );
144
144
if (old_mem .len != 0 ) {
145
145
@memcpy (result .ptr , old_mem .ptr , std .math .min (old_mem .len , result .len ));
146
- _ = os .posix .munmap (@ptrToInt (old_mem .ptr ), old_mem .len );
146
+ _ = os .posix .munmap (@ptrToInt (old_mem .ptr ), old_mem .len );
147
147
}
148
148
return result ;
149
149
},
@@ -155,12 +155,12 @@ pub const DirectAllocator = struct {
155
155
const old_record_addr = old_adjusted_addr + old_mem .len ;
156
156
const root_addr = @intToPtr (* align (1 ) usize , old_record_addr ).* ;
157
157
const old_ptr = @intToPtr (* c_void , root_addr );
158
-
159
- if (new_size == 0 ) {
158
+
159
+ if (new_size == 0 ) {
160
160
if (os .windows .HeapFree (self .heap_handle .? , 0 , old_ptr ) == 0 ) unreachable ;
161
161
return old_mem [0.. 0];
162
162
}
163
-
163
+
164
164
const amt = new_size + new_align + @sizeOf (usize );
165
165
const new_ptr = os .windows .HeapReAlloc (
166
166
self .heap_handle .? ,
@@ -178,11 +178,7 @@ pub const DirectAllocator = struct {
178
178
// or the memory starting at the old offset would be outside of the new allocation,
179
179
// then we need to copy the memory to a valid aligned address and use that
180
180
const new_aligned_addr = mem .alignForward (new_root_addr , new_align );
181
- @memcpy (
182
- @intToPtr ([* ]u8 , new_aligned_addr ),
183
- @intToPtr ([* ]u8 , new_adjusted_addr ),
184
- std .math .min (old_mem .len , new_size ),
185
- );
181
+ @memcpy (@intToPtr ([* ]u8 , new_aligned_addr ), @intToPtr ([* ]u8 , new_adjusted_addr ), std .math .min (old_mem .len , new_size ));
186
182
new_adjusted_addr = new_aligned_addr ;
187
183
}
188
184
const new_record_addr = new_adjusted_addr + new_size ;
@@ -209,7 +205,7 @@ pub const ArenaAllocator = struct {
209
205
return ArenaAllocator {
210
206
.allocator = Allocator {
211
207
.reallocFn = realloc ,
212
- .shrinkFn = shrink ,
208
+ .shrinkFn = null ,
213
209
},
214
210
.child_allocator = child_allocator ,
215
211
.buffer_list = std .LinkedList ([]u8 ).init (),
@@ -231,8 +227,7 @@ pub const ArenaAllocator = struct {
231
227
const actual_min_size = minimum_size + @sizeOf (BufNode );
232
228
var len = prev_len ;
233
229
while (true ) {
234
- len += len / 2 ;
235
- len += os .page_size - @rem (len , os .page_size );
230
+ len = mem .alignForward (len + len / 2 , os .page_size );
236
231
if (len >= actual_min_size ) break ;
237
232
}
238
233
const buf = try self .child_allocator .alignedAlloc (u8 , @alignOf (BufNode ), len );
@@ -248,9 +243,11 @@ pub const ArenaAllocator = struct {
248
243
return buf_node ;
249
244
}
250
245
251
- fn alloc (allocator : * Allocator , n : usize , alignment : u29 ) ! []u8 {
246
+ fn realloc (allocator : * Allocator , old_mem : [] u8 , old_align : u29 , n : usize , alignment : u29 ) ! []u8 {
252
247
const self = @fieldParentPtr (ArenaAllocator , "allocator" , allocator );
253
248
249
+ assert (old_mem .len == 0 ); // because shrinkFn == null
250
+
254
251
var cur_node = if (self .buffer_list .last ) | last_node | last_node else try self .createNode (0 , n + alignment );
255
252
while (true ) {
256
253
const cur_buf = cur_node .data [@sizeOf (BufNode ).. ];
@@ -267,21 +264,6 @@ pub const ArenaAllocator = struct {
267
264
return result ;
268
265
}
269
266
}
270
-
271
- fn realloc (allocator : * Allocator , old_mem : []u8 , old_align : u29 , new_size : usize , new_align : u29 ) ! []u8 {
272
- if (new_size <= old_mem .len and new_align <= new_size ) {
273
- // We can't do anything with the memory, so tell the client to keep it.
274
- return error .OutOfMemory ;
275
- } else {
276
- const result = try alloc (allocator , new_size , new_align );
277
- @memcpy (result .ptr , old_mem .ptr , std .math .min (old_mem .len , result .len ));
278
- return result ;
279
- }
280
- }
281
-
282
- fn shrink (allocator : * Allocator , old_mem : []u8 , old_align : u29 , new_size : usize , new_align : u29 ) []u8 {
283
- return old_mem [0.. new_size ];
284
- }
285
267
};
286
268
287
269
pub const FixedBufferAllocator = struct {
@@ -293,15 +275,17 @@ pub const FixedBufferAllocator = struct {
293
275
return FixedBufferAllocator {
294
276
.allocator = Allocator {
295
277
.reallocFn = realloc ,
296
- .shrinkFn = shrink ,
278
+ .shrinkFn = null ,
297
279
},
298
280
.buffer = buffer ,
299
281
.end_index = 0 ,
300
282
};
301
283
}
302
284
303
- fn alloc (allocator : * Allocator , n : usize , alignment : u29 ) ! []u8 {
285
+ fn realloc (allocator : * Allocator , old_mem : [] u8 , old_align : u29 , n : usize , alignment : u29 ) ! []u8 {
304
286
const self = @fieldParentPtr (FixedBufferAllocator , "allocator" , allocator );
287
+ assert (old_mem .len == 0 ); // because shrinkFn == null
288
+
305
289
const addr = @ptrToInt (self .buffer .ptr ) + self .end_index ;
306
290
const adjusted_addr = mem .alignForward (addr , alignment );
307
291
const adjusted_index = self .end_index + (adjusted_addr - addr );
@@ -314,39 +298,14 @@ pub const FixedBufferAllocator = struct {
314
298
315
299
return result ;
316
300
}
317
-
318
- fn realloc (allocator : * Allocator , old_mem : []u8 , old_align : u29 , new_size : usize , new_align : u29 ) ! []u8 {
319
- const self = @fieldParentPtr (FixedBufferAllocator , "allocator" , allocator );
320
- assert (old_mem .len <= self .end_index );
321
- if (old_mem .ptr == self .buffer .ptr + self .end_index - old_mem .len and
322
- mem .alignForward (@ptrToInt (old_mem .ptr ), new_align ) == @ptrToInt (old_mem .ptr ))
323
- {
324
- const start_index = self .end_index - old_mem .len ;
325
- const new_end_index = start_index + new_size ;
326
- if (new_end_index > self .buffer .len ) return error .OutOfMemory ;
327
- const result = self .buffer [start_index .. new_end_index ];
328
- self .end_index = new_end_index ;
329
- return result ;
330
- } else if (new_size <= old_mem .len and new_align <= old_align ) {
331
- // We can't do anything with the memory, so tell the client to keep it.
332
- return error .OutOfMemory ;
333
- } else {
334
- const result = try alloc (allocator , new_size , new_align );
335
- @memcpy (result .ptr , old_mem .ptr , std .math .min (old_mem .len , result .len ));
336
- return result ;
337
- }
338
- }
339
-
340
- fn shrink (allocator : * Allocator , old_mem : []u8 , old_align : u29 , new_size : usize , new_align : u29 ) []u8 {
341
- return old_mem [0.. new_size ];
342
- }
343
301
};
344
302
345
- // FIXME : Exposed LLVM intrinsics is a bug
303
+ // TODO : Exposed LLVM intrinsics is a bug
346
304
// See: https://github.com/ziglang/zig/issues/2291
347
305
extern fn @"llvm.wasm.memory.size.i32" (u32 ) u32 ;
348
306
extern fn @"llvm.wasm.memory.grow.i32" (u32 , u32 ) i32 ;
349
307
308
+ /// TODO Currently this allocator does not actually reclaim memory, but it should.
350
309
pub const wasm_allocator = & wasm_allocator_state .allocator ;
351
310
var wasm_allocator_state = WasmAllocator {
352
311
.allocator = Allocator {
@@ -433,11 +392,11 @@ const WasmAllocator = struct {
433
392
}
434
393
};
435
394
395
+ /// Lock free
436
396
pub const ThreadSafeFixedBufferAllocator = blk : {
437
397
if (builtin .single_threaded ) {
438
398
break :blk FixedBufferAllocator ;
439
399
} else {
440
- // lock free
441
400
break :blk struct {
442
401
allocator : Allocator ,
443
402
end_index : usize ,
@@ -447,14 +406,15 @@ pub const ThreadSafeFixedBufferAllocator = blk: {
447
406
return ThreadSafeFixedBufferAllocator {
448
407
.allocator = Allocator {
449
408
.reallocFn = realloc ,
450
- .shrinkFn = shrink ,
409
+ .shrinkFn = null ,
451
410
},
452
411
.buffer = buffer ,
453
412
.end_index = 0 ,
454
413
};
455
414
}
456
415
457
- fn alloc (allocator : * Allocator , n : usize , alignment : u29 ) ! []u8 {
416
+ fn realloc (allocator : * Allocator , old_mem : []u8 , old_align : u29 , n : usize , alignment : u29 ) ! []u8 {
417
+ assert (old_mem .len == 0 ); // because shrinkFn == null
458
418
const self = @fieldParentPtr (ThreadSafeFixedBufferAllocator , "allocator" , allocator );
459
419
var end_index = @atomicLoad (usize , & self .end_index , builtin .AtomicOrder .SeqCst );
460
420
while (true ) {
@@ -468,21 +428,6 @@ pub const ThreadSafeFixedBufferAllocator = blk: {
468
428
end_index = @cmpxchgWeak (usize , & self .end_index , end_index , new_end_index , builtin .AtomicOrder .SeqCst , builtin .AtomicOrder .SeqCst ) orelse return self .buffer [adjusted_index .. new_end_index ];
469
429
}
470
430
}
471
-
472
- fn realloc (allocator : * Allocator , old_mem : []u8 , old_align : u29 , new_size : usize , new_align : u29 ) ! []u8 {
473
- if (new_size <= old_mem .len and new_align <= old_align ) {
474
- // We can't do anything useful with the memory, tell the client to keep it.
475
- return error .OutOfMemory ;
476
- } else {
477
- const result = try alloc (allocator , new_size , new_align );
478
- @memcpy (result .ptr , old_mem .ptr , std .math .min (old_mem .len , result .len ));
479
- return result ;
480
- }
481
- }
482
-
483
- fn shrink (allocator : * Allocator , old_mem : []u8 , old_align : u29 , new_size : usize , new_align : u29 ) []u8 {
484
- return old_mem [0.. new_size ];
485
- }
486
431
};
487
432
}
488
433
};
0 commit comments