@zigc/lib 0.16.0-test.1 → 0.17.0-dev.131
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +19 -0
- package/c/fcntl.zig +6 -1
- package/c/inttypes.zig +0 -10
- package/c/math.zig +138 -114
- package/c/pthread.zig +57 -0
- package/c/search.zig +1 -27
- package/c/stdlib/drand48.zig +0 -57
- package/c/stdlib.zig +0 -100
- package/c/string.zig +20 -7
- package/c/strings.zig +0 -38
- package/c/stropts.zig +17 -0
- package/c/unistd.zig +27 -26
- package/c/wchar.zig +10 -0
- package/c.zig +3 -2
- package/compiler/aro/aro/Attribute/names.zig +604 -589
- package/compiler/aro/aro/Attribute.zig +202 -116
- package/compiler/aro/aro/Builtins/common.zig +874 -863
- package/compiler/aro/aro/Builtins/eval.zig +15 -7
- package/compiler/aro/aro/Builtins.zig +0 -1
- package/compiler/aro/aro/CodeGen.zig +8 -7
- package/compiler/aro/aro/Compilation.zig +137 -111
- package/compiler/aro/aro/Diagnostics.zig +21 -17
- package/compiler/aro/aro/Driver/GCCDetector.zig +635 -0
- package/compiler/aro/aro/Driver.zig +138 -63
- package/compiler/aro/aro/LangOpts.zig +12 -2
- package/compiler/aro/aro/Parser/Diagnostic.zig +79 -19
- package/compiler/aro/aro/Parser.zig +352 -153
- package/compiler/aro/aro/Pragma.zig +3 -2
- package/compiler/aro/aro/Preprocessor/Diagnostic.zig +21 -0
- package/compiler/aro/aro/Preprocessor.zig +136 -62
- package/compiler/aro/aro/Target.zig +17 -12
- package/compiler/aro/aro/Tokenizer.zig +31 -14
- package/compiler/aro/aro/Toolchain.zig +4 -7
- package/compiler/aro/aro/Tree.zig +178 -148
- package/compiler/aro/aro/TypeStore.zig +82 -24
- package/compiler/aro/aro/Value.zig +13 -17
- package/compiler/aro/aro/features.zig +1 -0
- package/compiler/aro/aro/pragmas/message.zig +3 -2
- package/compiler/aro/aro/pragmas/once.zig +0 -1
- package/compiler/aro/aro/record_layout.zig +3 -3
- package/compiler/aro/aro/text_literal.zig +3 -2
- package/compiler/aro/assembly_backend/x86_64.zig +7 -8
- package/compiler/aro/backend/Assembly.zig +1 -2
- package/compiler/aro/backend/Interner.zig +2 -2
- package/compiler/aro/backend/Ir.zig +100 -92
- package/compiler/aro/include/ptrcheck.h +49 -0
- package/compiler/aro/main.zig +26 -10
- package/compiler/build_runner.zig +1 -2
- package/compiler/objdump.zig +93 -0
- package/compiler/reduce/Walk.zig +7 -7
- package/compiler/reduce.zig +5 -1
- package/compiler/resinator/compile.zig +2 -2
- package/compiler/resinator/main.zig +7 -1
- package/compiler/resinator/preprocess.zig +1 -3
- package/compiler/std-docs.zig +8 -1
- package/compiler/test_runner.zig +194 -62
- package/compiler/translate-c/MacroTranslator.zig +80 -11
- package/compiler/translate-c/PatternList.zig +1 -9
- package/compiler/translate-c/Scope.zig +43 -6
- package/compiler/translate-c/Translator.zig +369 -127
- package/compiler/translate-c/ast.zig +19 -11
- package/compiler/translate-c/main.zig +76 -17
- package/compiler_rt/cos.zig +140 -53
- package/compiler_rt/divmodei4.zig +40 -17
- package/compiler_rt/exp.zig +1 -6
- package/compiler_rt/exp2.zig +1 -6
- package/compiler_rt/exp_f128.zig +377 -0
- package/compiler_rt/fabs.zig +0 -2
- package/compiler_rt/fma.zig +0 -2
- package/compiler_rt/fmax.zig +0 -2
- package/compiler_rt/fmin.zig +0 -2
- package/compiler_rt/fmod.zig +0 -2
- package/compiler_rt/limb64.zig +1127 -0
- package/compiler_rt/log.zig +0 -2
- package/compiler_rt/log10.zig +0 -2
- package/compiler_rt/log2.zig +0 -2
- package/compiler_rt/long_double.zig +37 -0
- package/compiler_rt/mulXi3.zig +1 -1
- package/compiler_rt/mulo.zig +6 -1
- package/compiler_rt/rem_pio2l.zig +173 -0
- package/compiler_rt/round.zig +0 -2
- package/compiler_rt/sin.zig +139 -56
- package/compiler_rt/sincos.zig +277 -72
- package/compiler_rt/sqrt.zig +0 -2
- package/compiler_rt/ssp.zig +1 -1
- package/compiler_rt/tan.zig +117 -48
- package/compiler_rt/trig.zig +256 -6
- package/compiler_rt/trunc.zig +0 -2
- package/compiler_rt/udivmodei4.zig +28 -0
- package/compiler_rt.zig +2 -0
- package/fuzzer.zig +857 -307
- package/libc/musl/arch/mipsn32/syscall_arch.h +35 -32
- package/libc/musl/src/math/pow.c +343 -0
- package/package.json +1 -1
- package/std/Build/Cache.zig +6 -6
- package/std/Build/Fuzz.zig +6 -19
- package/std/Build/Module.zig +1 -1
- package/std/Build/Step/CheckObject.zig +3 -3
- package/std/Build/Step/Compile.zig +18 -1
- package/std/Build/Step/ConfigHeader.zig +49 -33
- package/std/Build/Step/InstallArtifact.zig +18 -0
- package/std/Build/Step/Run.zig +538 -89
- package/std/Build/Step/TranslateC.zig +0 -6
- package/std/Build/Step.zig +10 -19
- package/std/Build/WebServer.zig +31 -19
- package/std/Build/abi.zig +47 -11
- package/std/Build.zig +17 -17
- package/std/Io/Dir.zig +7 -2
- package/std/Io/Dispatch.zig +5 -13
- package/std/Io/File/Reader.zig +3 -1
- package/std/Io/File/Writer.zig +8 -6
- package/std/Io/File.zig +1 -0
- package/std/Io/Kqueue.zig +2 -2
- package/std/Io/Reader.zig +8 -9
- package/std/Io/Semaphore.zig +112 -17
- package/std/Io/Terminal.zig +1 -1
- package/std/Io/Threaded.zig +352 -180
- package/std/Io/Uring.zig +15 -16
- package/std/Io/Writer.zig +46 -42
- package/std/Io/net.zig +11 -11
- package/std/Io.zig +1052 -20
- package/std/SemanticVersion.zig +1 -1
- package/std/Target/Query.zig +2 -2
- package/std/Target.zig +53 -7
- package/std/Thread.zig +8 -3
- package/std/array_hash_map.zig +105 -573
- package/std/array_list.zig +22 -31
- package/std/bit_set.zig +22 -6
- package/std/builtin/assembly.zig +68 -0
- package/std/builtin.zig +4 -0
- package/std/c/haiku.zig +3 -0
- package/std/c/serenity.zig +1 -6
- package/std/c.zig +106 -24
- package/std/compress/flate/Compress.zig +3 -3
- package/std/compress/flate/Decompress.zig +2 -3
- package/std/compress/zstd/Decompress.zig +2 -4
- package/std/crypto/Certificate/Bundle.zig +15 -1
- package/std/crypto/Certificate.zig +13 -1
- package/std/crypto/ascon.zig +75 -33
- package/std/crypto/codecs/asn1/Oid.zig +12 -1
- package/std/crypto/codecs/asn1.zig +33 -18
- package/std/crypto/codecs/base64_hex_ct.zig +16 -8
- package/std/crypto/ml_kem.zig +2 -9
- package/std/crypto/tls/Client.zig +79 -4
- package/std/crypto/tls.zig +1 -1
- package/std/crypto.zig +1 -0
- package/std/debug/Dwarf.zig +29 -9
- package/std/debug/Info.zig +4 -0
- package/std/debug/MachOFile.zig +46 -8
- package/std/debug/Pdb.zig +540 -37
- package/std/debug/SelfInfo/Elf.zig +19 -18
- package/std/debug/SelfInfo/MachO.zig +18 -7
- package/std/debug/SelfInfo/Windows.zig +138 -36
- package/std/debug.zig +181 -66
- package/std/enums.zig +25 -19
- package/std/fmt.zig +8 -3
- package/std/fs/path.zig +6 -4
- package/std/heap/ArenaAllocator.zig +145 -154
- package/std/heap/BufferFirstAllocator.zig +165 -0
- package/std/heap/debug_allocator.zig +7 -7
- package/std/heap.zig +2 -126
- package/std/http/Client.zig +31 -30
- package/std/http.zig +14 -13
- package/std/json/Scanner.zig +2 -2
- package/std/json/Stringify.zig +3 -3
- package/std/json/dynamic.zig +4 -4
- package/std/math/big/int.zig +16 -17
- package/std/mem/Allocator.zig +4 -5
- package/std/mem.zig +48 -0
- package/std/os/emscripten.zig +2 -18
- package/std/os/linux/IoUring.zig +2 -0
- package/std/os/linux/aarch64.zig +41 -12
- package/std/os/linux/arc.zig +173 -0
- package/std/os/linux/arm.zig +41 -12
- package/std/os/linux/hexagon.zig +33 -11
- package/std/os/linux/loongarch32.zig +41 -13
- package/std/os/linux/loongarch64.zig +41 -12
- package/std/os/linux/m68k.zig +41 -13
- package/std/os/linux/mips.zig +67 -36
- package/std/os/linux/mips64.zig +60 -29
- package/std/os/linux/mipsn32.zig +60 -29
- package/std/os/linux/or1k.zig +41 -12
- package/std/os/linux/powerpc.zig +41 -12
- package/std/os/linux/powerpc64.zig +41 -12
- package/std/os/linux/riscv32.zig +41 -12
- package/std/os/linux/riscv64.zig +41 -12
- package/std/os/linux/s390x.zig +44 -7
- package/std/os/linux/sparc64.zig +83 -52
- package/std/os/linux/thumb.zig +52 -36
- package/std/os/linux/x32.zig +41 -12
- package/std/os/linux/x86.zig +42 -13
- package/std/os/linux/x86_64.zig +41 -12
- package/std/os/linux.zig +419 -438
- package/std/os/uefi/tables/boot_services.zig +9 -8
- package/std/os/windows.zig +2 -2
- package/std/os.zig +41 -0
- package/std/pdb.zig +143 -4
- package/std/posix.zig +6 -12
- package/std/priority_dequeue.zig +13 -12
- package/std/priority_queue.zig +5 -4
- package/std/process/Child.zig +1 -1
- package/std/process/Environ.zig +1 -1
- package/std/process.zig +1 -1
- package/std/sort.zig +3 -3
- package/std/start.zig +17 -4
- package/std/std.zig +19 -6
- package/std/testing/FailingAllocator.zig +4 -4
- package/std/testing/Smith.zig +37 -2
- package/std/zig/Ast/Render.zig +187 -459
- package/std/zig/Ast.zig +0 -4
- package/std/zig/AstGen.zig +86 -103
- package/std/zig/AstRlAnnotate.zig +0 -11
- package/std/zig/AstSmith.zig +2602 -0
- package/std/zig/BuiltinFn.zig +0 -32
- package/std/zig/Client.zig +8 -3
- package/std/zig/LibCInstallation.zig +4 -3
- package/std/zig/Parse.zig +90 -81
- package/std/zig/Server.zig +26 -0
- package/std/zig/WindowsSdk.zig +13 -13
- package/std/zig/Zir.zig +66 -62
- package/std/zig/ZonGen.zig +6 -5
- package/std/zig/c_translation/helpers.zig +14 -9
- package/std/zig/llvm/Builder.zig +119 -60
- package/std/zig/system.zig +20 -4
- package/std/zig/tokenizer.zig +2 -1
- package/std/zig.zig +7 -10
- package/std/zip.zig +5 -5
- package/zig.h +340 -1
- package/compiler/aro/aro/Driver/Filesystem.zig +0 -241
- package/libc/mingw/complex/cabs.c +0 -48
- package/libc/mingw/complex/cabsf.c +0 -48
- package/libc/mingw/complex/cacos.c +0 -50
- package/libc/mingw/complex/cacosf.c +0 -50
- package/libc/mingw/complex/carg.c +0 -48
- package/libc/mingw/complex/cargf.c +0 -48
- package/libc/mingw/complex/casin.c +0 -50
- package/libc/mingw/complex/casinf.c +0 -50
- package/libc/mingw/complex/catan.c +0 -50
- package/libc/mingw/complex/catanf.c +0 -50
- package/libc/mingw/complex/ccos.c +0 -50
- package/libc/mingw/complex/ccosf.c +0 -50
- package/libc/mingw/complex/cexp.c +0 -48
- package/libc/mingw/complex/cexpf.c +0 -48
- package/libc/mingw/complex/cimag.c +0 -48
- package/libc/mingw/complex/cimagf.c +0 -48
- package/libc/mingw/complex/clog.c +0 -48
- package/libc/mingw/complex/clog10.c +0 -49
- package/libc/mingw/complex/clog10f.c +0 -49
- package/libc/mingw/complex/clogf.c +0 -48
- package/libc/mingw/complex/conj.c +0 -48
- package/libc/mingw/complex/conjf.c +0 -48
- package/libc/mingw/complex/cpow.c +0 -48
- package/libc/mingw/complex/cpowf.c +0 -48
- package/libc/mingw/complex/cproj.c +0 -48
- package/libc/mingw/complex/cprojf.c +0 -48
- package/libc/mingw/complex/creal.c +0 -48
- package/libc/mingw/complex/crealf.c +0 -48
- package/libc/mingw/complex/csin.c +0 -50
- package/libc/mingw/complex/csinf.c +0 -50
- package/libc/mingw/complex/csqrt.c +0 -48
- package/libc/mingw/complex/csqrtf.c +0 -48
- package/libc/mingw/complex/ctan.c +0 -50
- package/libc/mingw/complex/ctanf.c +0 -50
- package/libc/mingw/math/arm/s_rint.c +0 -86
- package/libc/mingw/math/arm/s_rintf.c +0 -51
- package/libc/mingw/math/arm/sincos.S +0 -30
- package/libc/mingw/math/arm-common/sincosl.c +0 -13
- package/libc/mingw/math/arm64/rint.c +0 -12
- package/libc/mingw/math/arm64/rintf.c +0 -12
- package/libc/mingw/math/arm64/sincos.S +0 -32
- package/libc/mingw/math/bsd_private_base.h +0 -148
- package/libc/mingw/math/fdiml.c +0 -24
- package/libc/mingw/math/frexpf.c +0 -13
- package/libc/mingw/math/frexpl.c +0 -71
- package/libc/mingw/math/x86/acosf.c +0 -29
- package/libc/mingw/math/x86/atanf.c +0 -23
- package/libc/mingw/math/x86/atanl.c +0 -18
- package/libc/mingw/math/x86/cos.def.h +0 -65
- package/libc/mingw/math/x86/cosl.c +0 -46
- package/libc/mingw/math/x86/cosl_internal.S +0 -55
- package/libc/mingw/math/x86/ldexp.c +0 -23
- package/libc/mingw/math/x86/scalbn.S +0 -41
- package/libc/mingw/math/x86/scalbnf.S +0 -40
- package/libc/mingw/math/x86/sin.def.h +0 -65
- package/libc/mingw/math/x86/sinl.c +0 -46
- package/libc/mingw/math/x86/sinl_internal.S +0 -58
- package/libc/mingw/math/x86/tanl.S +0 -62
- package/libc/mingw/misc/btowc.c +0 -28
- package/libc/mingw/misc/wcstof.c +0 -66
- package/libc/mingw/misc/wcstoimax.c +0 -132
- package/libc/mingw/misc/wcstoumax.c +0 -126
- package/libc/mingw/misc/wctob.c +0 -29
- package/libc/mingw/misc/winbs_uint64.c +0 -6
- package/libc/mingw/misc/winbs_ulong.c +0 -6
- package/libc/mingw/misc/winbs_ushort.c +0 -6
- package/libc/mingw/stdio/_Exit.c +0 -10
- package/libc/mingw/stdio/_findfirst64i32.c +0 -21
- package/libc/mingw/stdio/_findnext64i32.c +0 -21
- package/libc/mingw/stdio/_fstat64i32.c +0 -37
- package/libc/mingw/stdio/_stat64i32.c +0 -37
- package/libc/mingw/stdio/_wfindfirst64i32.c +0 -21
- package/libc/mingw/stdio/_wfindnext64i32.c +0 -21
- package/libc/mingw/stdio/_wstat64i32.c +0 -37
- package/libc/mingw/winpthreads/spinlock.c +0 -82
- package/libc/musl/src/legacy/isastream.c +0 -7
- package/libc/musl/src/legacy/valloc.c +0 -8
- package/libc/musl/src/linux/tee.c +0 -8
- package/libc/musl/src/math/__cosl.c +0 -96
- package/libc/musl/src/math/__sinl.c +0 -78
- package/libc/musl/src/math/__tanl.c +0 -143
- package/libc/musl/src/math/aarch64/lrint.c +0 -10
- package/libc/musl/src/math/aarch64/lrintf.c +0 -10
- package/libc/musl/src/math/aarch64/rintf.c +0 -7
- package/libc/musl/src/math/cosl.c +0 -39
- package/libc/musl/src/math/fdim.c +0 -10
- package/libc/musl/src/math/fdimf.c +0 -10
- package/libc/musl/src/math/fdiml.c +0 -18
- package/libc/musl/src/math/finite.c +0 -7
- package/libc/musl/src/math/finitef.c +0 -7
- package/libc/musl/src/math/frexp.c +0 -23
- package/libc/musl/src/math/frexpf.c +0 -23
- package/libc/musl/src/math/frexpl.c +0 -29
- package/libc/musl/src/math/i386/lrint.c +0 -8
- package/libc/musl/src/math/i386/lrintf.c +0 -8
- package/libc/musl/src/math/i386/rintf.c +0 -7
- package/libc/musl/src/math/lrint.c +0 -72
- package/libc/musl/src/math/lrintf.c +0 -8
- package/libc/musl/src/math/powerpc64/lrint.c +0 -16
- package/libc/musl/src/math/powerpc64/lrintf.c +0 -16
- package/libc/musl/src/math/rintf.c +0 -30
- package/libc/musl/src/math/s390x/rintf.c +0 -15
- package/libc/musl/src/math/sincosl.c +0 -60
- package/libc/musl/src/math/sinl.c +0 -41
- package/libc/musl/src/math/tanl.c +0 -29
- package/libc/musl/src/math/x32/lrint.s +0 -5
- package/libc/musl/src/math/x32/lrintf.s +0 -5
- package/libc/musl/src/math/x86_64/lrint.c +0 -8
- package/libc/musl/src/math/x86_64/lrintf.c +0 -8
- package/libc/musl/src/string/strdup.c +0 -10
- package/libc/musl/src/string/strndup.c +0 -12
- package/libc/musl/src/string/wcsdup.c +0 -10
- package/libc/musl/src/thread/pthread_spin_destroy.c +0 -6
- package/libc/musl/src/thread/pthread_spin_init.c +0 -6
- package/libc/musl/src/thread/pthread_spin_lock.c +0 -8
- package/libc/musl/src/thread/pthread_spin_trylock.c +0 -7
- package/libc/musl/src/thread/pthread_spin_unlock.c +0 -7
- package/libc/musl/src/unistd/dup2.c +0 -20
- package/libc/musl/src/unistd/dup3.c +0 -26
- package/libc/wasi/libc-bottom-half/sources/reallocarray.c +0 -14
- package/libc/wasi/thread-stub/pthread_spin_lock.c +0 -8
- package/libc/wasi/thread-stub/pthread_spin_trylock.c +0 -8
- package/libc/wasi/thread-stub/pthread_spin_unlock.c +0 -7
|
@@ -358,14 +358,16 @@ fn alloc(ctx: *anyopaque, n: usize, alignment: Alignment, ret_addr: usize) ?[*]u
|
|
|
358
358
|
const end_index = @atomicRmw(usize, &node.end_index, .Add, alignable, .acquire); // acquire any memory that may have been freed
|
|
359
359
|
const aligned_index = alignedIndex(buf.ptr, end_index, alignment);
|
|
360
360
|
assert(end_index + alignable >= aligned_index + n);
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
361
|
+
if (end_index + alignable != aligned_index + n) {
|
|
362
|
+
_ = @cmpxchgStrong(
|
|
363
|
+
usize,
|
|
364
|
+
&node.end_index,
|
|
365
|
+
end_index + alignable,
|
|
366
|
+
aligned_index + n,
|
|
367
|
+
.monotonic, // no need to release alignment padding; there's no one accessing it!
|
|
368
|
+
.monotonic,
|
|
369
|
+
);
|
|
370
|
+
}
|
|
369
371
|
|
|
370
372
|
if (aligned_index + n > buf.len) break :first_node .{ node, buf.len };
|
|
371
373
|
return buf[aligned_index..][0..n].ptr;
|
|
@@ -682,45 +684,40 @@ test "reset while retaining a buffer" {
|
|
|
682
684
|
try std.testing.expectEqual(2, arena_allocator.queryCapacity());
|
|
683
685
|
}
|
|
684
686
|
|
|
685
|
-
test "fuzz" {
|
|
687
|
+
test "fuzz multi threaded" {
|
|
686
688
|
@disableInstrumentation();
|
|
687
689
|
if (@import("builtin").single_threaded) return error.SkipZigTest;
|
|
688
690
|
|
|
689
691
|
const gpa = std.heap.smp_allocator;
|
|
690
692
|
|
|
693
|
+
var io_instance: std.Io.Threaded = .init(gpa, .{});
|
|
694
|
+
defer io_instance.deinit();
|
|
695
|
+
|
|
691
696
|
var arena_state: ArenaAllocator.State = .init;
|
|
692
697
|
// No need to deinit arena_state, all allocations are in `sample_buffer`!
|
|
693
698
|
|
|
694
|
-
const
|
|
699
|
+
const buffer_size = FuzzContext.max_alloc_count * FuzzContext.max_alloc_size;
|
|
700
|
+
|
|
701
|
+
const control_buffer = try gpa.alloc(u8, buffer_size);
|
|
695
702
|
defer gpa.free(control_buffer);
|
|
696
703
|
var control_instance: std.heap.FixedBufferAllocator = .init(control_buffer);
|
|
697
704
|
|
|
698
|
-
const sample_buffer = try gpa.alloc(u8,
|
|
705
|
+
const sample_buffer = try gpa.alloc(u8, buffer_size);
|
|
699
706
|
defer gpa.free(sample_buffer);
|
|
700
707
|
var sample_instance: FuzzAllocator = .init(sample_buffer);
|
|
701
708
|
|
|
702
|
-
var allocs: FuzzContext.Allocs = try .initCapacity(gpa, FuzzContext.max_alloc_count);
|
|
703
|
-
defer allocs.deinit(gpa);
|
|
704
|
-
|
|
705
709
|
try std.testing.fuzz(FuzzContext.Init{
|
|
706
|
-
.
|
|
707
|
-
.allocs = &allocs,
|
|
710
|
+
.threaded_instance = &io_instance,
|
|
708
711
|
.arena_state = &arena_state,
|
|
709
712
|
.control_instance = &control_instance,
|
|
710
713
|
.sample_instance = &sample_instance,
|
|
711
|
-
},
|
|
714
|
+
}, fuzzMultiThreaded, .{});
|
|
712
715
|
}
|
|
713
716
|
|
|
714
|
-
fn
|
|
717
|
+
fn fuzzMultiThreaded(fuzz_init: FuzzContext.Init, smith: *std.testing.Smith) anyerror!void {
|
|
715
718
|
@disableInstrumentation();
|
|
716
719
|
const testing = std.testing;
|
|
717
|
-
|
|
718
|
-
// We use a 'fresh' `Threaded` instance every time to reset threadlocals to
|
|
719
|
-
// their default values.
|
|
720
|
-
|
|
721
|
-
var io_instance: std.Io.Threaded = .init(fuzz_init.gpa, .{});
|
|
722
|
-
defer io_instance.deinit();
|
|
723
|
-
const io = io_instance.io();
|
|
720
|
+
const io = fuzz_init.threaded_instance.io();
|
|
724
721
|
|
|
725
722
|
fuzz_init.sample_instance.prepareFailures(smith);
|
|
726
723
|
|
|
@@ -731,59 +728,57 @@ fn fuzzArenaAllocator(fuzz_init: FuzzContext.Init, smith: *std.testing.Smith) an
|
|
|
731
728
|
defer fuzz_init.arena_state.* = arena_instance.state;
|
|
732
729
|
|
|
733
730
|
var ctx: FuzzContext = .init(
|
|
734
|
-
io,
|
|
735
731
|
control_allocator,
|
|
736
732
|
arena_instance.allocator(),
|
|
737
|
-
fuzz_init.allocs,
|
|
738
733
|
);
|
|
739
734
|
defer ctx.deinit();
|
|
740
735
|
|
|
741
|
-
ctx.rwl.lockUncancelable(io);
|
|
742
|
-
|
|
743
736
|
var group: std.Io.Group = .init;
|
|
744
737
|
defer group.cancel(io);
|
|
745
738
|
|
|
739
|
+
var n_allocs: usize = 0;
|
|
746
740
|
var n_actions: usize = 0;
|
|
747
741
|
while (!smith.eosWeightedSimple(99, 1) and n_actions < FuzzContext.max_action_count) {
|
|
748
742
|
errdefer comptime unreachable;
|
|
749
743
|
|
|
750
|
-
const
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
.
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
744
|
+
const weights: []const testing.Smith.Weight = if (n_allocs == FuzzContext.max_alloc_count)
|
|
745
|
+
&.{
|
|
746
|
+
.value(FuzzContext.Action, .resize, 1),
|
|
747
|
+
.value(FuzzContext.Action, .remap, 1),
|
|
748
|
+
.value(FuzzContext.Action, .free, 1),
|
|
749
|
+
}
|
|
750
|
+
else
|
|
751
|
+
&.{
|
|
752
|
+
.value(FuzzContext.Action, .resize, 1),
|
|
753
|
+
.value(FuzzContext.Action, .remap, 1),
|
|
754
|
+
.value(FuzzContext.Action, .free, 1),
|
|
755
|
+
.value(FuzzContext.Action, .alloc, 3),
|
|
756
|
+
};
|
|
757
|
+
switch (smith.valueWeighted(FuzzContext.Action, weights)) {
|
|
758
|
+
.alloc => {
|
|
759
|
+
const alloc_index = n_allocs;
|
|
760
|
+
n_allocs += 1;
|
|
761
|
+
ctx.allocs[alloc_index].common.len = .free;
|
|
762
|
+
group.concurrent(io, FuzzContext.doOneAlloc, .{
|
|
763
|
+
&ctx,
|
|
764
|
+
nextLen(smith),
|
|
765
|
+
smith.valueRangeAtMost(
|
|
768
766
|
Alignment,
|
|
769
767
|
.@"1",
|
|
770
768
|
.fromByteUnits(2 * std.heap.page_size_max),
|
|
771
769
|
),
|
|
772
|
-
|
|
773
|
-
}
|
|
770
|
+
@enumFromInt(alloc_index),
|
|
771
|
+
}) catch unreachable;
|
|
774
772
|
},
|
|
775
|
-
.resize => .
|
|
776
|
-
.remap => .
|
|
777
|
-
.free => .
|
|
778
|
-
}
|
|
779
|
-
group.concurrent(io, FuzzContext.doOneAction, .{ &ctx, action }) catch break;
|
|
773
|
+
.resize => group.concurrent(io, FuzzContext.doOneResize, .{ &ctx, nextLen(smith) }) catch unreachable,
|
|
774
|
+
.remap => group.concurrent(io, FuzzContext.doOneRemap, .{ &ctx, nextLen(smith) }) catch unreachable,
|
|
775
|
+
.free => group.concurrent(io, FuzzContext.doOneFree, .{&ctx}) catch unreachable,
|
|
776
|
+
}
|
|
780
777
|
n_actions += 1;
|
|
781
778
|
}
|
|
782
779
|
|
|
783
|
-
ctx.rwl.unlock(io);
|
|
784
|
-
|
|
785
780
|
try group.await(io);
|
|
786
|
-
try ctx.check();
|
|
781
|
+
try ctx.check(n_allocs);
|
|
787
782
|
|
|
788
783
|
// This also covers the `deinit` logic since `free_all` uses it internally.
|
|
789
784
|
|
|
@@ -806,73 +801,71 @@ fn fuzzArenaAllocator(fuzz_init: FuzzContext.Init, smith: *std.testing.Smith) an
|
|
|
806
801
|
}
|
|
807
802
|
|
|
808
803
|
fuzz_init.control_instance.reset();
|
|
809
|
-
fuzz_init.allocs.clearRetainingCapacity();
|
|
810
|
-
}
|
|
811
|
-
fn nextLen(smith: *std.testing.Smith) usize {
|
|
812
|
-
@disableInstrumentation();
|
|
813
|
-
return usizeRange(smith, 1, 16 << 10 << 10);
|
|
814
804
|
}
|
|
815
|
-
fn
|
|
805
|
+
fn nextLen(smith: *std.testing.Smith) @typeInfo(FuzzContext.Alloc.Len).@"enum".tag_type {
|
|
816
806
|
@disableInstrumentation();
|
|
817
|
-
const
|
|
818
|
-
return smith.valueRangeAtMost(
|
|
807
|
+
const BackingInt = @typeInfo(FuzzContext.Alloc.Len).@"enum".tag_type;
|
|
808
|
+
return smith.valueRangeAtMost(BackingInt, 1, FuzzContext.max_alloc_size);
|
|
819
809
|
}
|
|
820
810
|
|
|
821
811
|
const FuzzContext = struct {
|
|
822
|
-
io: std.Io,
|
|
823
|
-
rwl: std.Io.RwLock,
|
|
824
|
-
|
|
825
812
|
control_allocator: Allocator,
|
|
826
813
|
sample_allocator: Allocator,
|
|
827
814
|
|
|
828
|
-
|
|
815
|
+
last_alloc_index: Alloc.Index,
|
|
816
|
+
allocs: [max_alloc_count]Alloc,
|
|
829
817
|
|
|
830
|
-
const max_alloc_count =
|
|
818
|
+
const max_alloc_count = 64;
|
|
831
819
|
const max_action_count = 2 * max_alloc_count;
|
|
832
820
|
|
|
833
|
-
const
|
|
821
|
+
const max_alloc_size = 16 << 10;
|
|
822
|
+
|
|
823
|
+
const Alloc = struct {
|
|
834
824
|
control_ptr: [*]u8,
|
|
835
825
|
sample_ptr: [*]u8,
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
826
|
+
common: packed struct(usize) {
|
|
827
|
+
len: Len,
|
|
828
|
+
alignment: Alignment,
|
|
829
|
+
_: @Int(.unsigned, padding_bits) = 0,
|
|
830
|
+
},
|
|
831
|
+
|
|
832
|
+
const Len = enum(@Int(.unsigned, len_bits)) {
|
|
833
|
+
free = (1 << len_bits) - 1,
|
|
834
|
+
_,
|
|
835
|
+
};
|
|
836
|
+
const len_bits = @min(64, @bitSizeOf(usize)) - @bitSizeOf(Alignment);
|
|
837
|
+
const padding_bits = @bitSizeOf(usize) - (len_bits + @bitSizeOf(Alignment));
|
|
839
838
|
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
839
|
+
const Index = enum(usize) {
|
|
840
|
+
none = std.math.maxInt(usize),
|
|
841
|
+
_,
|
|
842
|
+
};
|
|
843
843
|
};
|
|
844
844
|
|
|
845
|
-
const Action =
|
|
846
|
-
alloc
|
|
847
|
-
resize
|
|
848
|
-
remap
|
|
845
|
+
const Action = enum {
|
|
846
|
+
alloc,
|
|
847
|
+
resize,
|
|
848
|
+
remap,
|
|
849
849
|
free,
|
|
850
850
|
};
|
|
851
851
|
|
|
852
|
-
threadlocal var tls_next: u8 = 0;
|
|
853
|
-
threadlocal var tls_last_index: ?usize = null;
|
|
854
|
-
|
|
855
852
|
const Init = struct {
|
|
856
|
-
|
|
857
|
-
allocs: *FuzzContext.Allocs,
|
|
853
|
+
threaded_instance: *std.Io.Threaded,
|
|
858
854
|
arena_state: *ArenaAllocator.State,
|
|
859
855
|
control_instance: *std.heap.FixedBufferAllocator,
|
|
860
856
|
sample_instance: *FuzzAllocator,
|
|
861
857
|
};
|
|
862
858
|
|
|
863
859
|
fn init(
|
|
864
|
-
io: std.Io,
|
|
865
860
|
control_allocator: Allocator,
|
|
866
861
|
sample_allocator: Allocator,
|
|
867
|
-
allocs: *Allocs,
|
|
868
862
|
) FuzzContext {
|
|
869
863
|
@disableInstrumentation();
|
|
870
864
|
return .{
|
|
871
|
-
.io = io,
|
|
872
|
-
.rwl = .init,
|
|
873
865
|
.control_allocator = control_allocator,
|
|
874
866
|
.sample_allocator = sample_allocator,
|
|
875
|
-
.
|
|
867
|
+
.last_alloc_index = .none,
|
|
868
|
+
.allocs = undefined,
|
|
876
869
|
};
|
|
877
870
|
}
|
|
878
871
|
|
|
@@ -881,35 +874,22 @@ const FuzzContext = struct {
|
|
|
881
874
|
ctx.* = undefined;
|
|
882
875
|
}
|
|
883
876
|
|
|
884
|
-
fn check(ctx: *const FuzzContext) !void {
|
|
877
|
+
fn check(ctx: *const FuzzContext, n_allocs: usize) !void {
|
|
885
878
|
@disableInstrumentation();
|
|
886
|
-
for (
|
|
887
|
-
const len: usize = switch (
|
|
879
|
+
for (ctx.allocs[0..n_allocs]) |allocation| {
|
|
880
|
+
const len: usize = switch (allocation.common.len) {
|
|
888
881
|
.free => continue,
|
|
889
882
|
_ => |len| @intFromEnum(len),
|
|
890
883
|
};
|
|
891
|
-
const control =
|
|
892
|
-
const sample =
|
|
884
|
+
const control = allocation.control_ptr[0..len];
|
|
885
|
+
const sample = allocation.sample_ptr[0..len];
|
|
893
886
|
try std.testing.expectEqualSlices(u8, control, sample);
|
|
894
887
|
}
|
|
895
888
|
}
|
|
896
889
|
|
|
897
|
-
fn
|
|
890
|
+
fn doOneAlloc(ctx: *FuzzContext, len: usize, alignment: Alignment, index: Alloc.Index) void {
|
|
898
891
|
@disableInstrumentation();
|
|
899
|
-
ctx.
|
|
900
|
-
defer ctx.rwl.unlockShared(ctx.io);
|
|
901
|
-
|
|
902
|
-
switch (action) {
|
|
903
|
-
.alloc => |act| ctx.doOneAlloc(act.len, act.alignment, act.index),
|
|
904
|
-
.resize => |act| ctx.doOneResize(act.new_len),
|
|
905
|
-
.remap => |act| ctx.doOneRemap(act.new_len),
|
|
906
|
-
.free => ctx.doOneFree(),
|
|
907
|
-
}
|
|
908
|
-
}
|
|
909
|
-
|
|
910
|
-
fn doOneAlloc(ctx: *FuzzContext, len: usize, alignment: Alignment, index: usize) void {
|
|
911
|
-
@disableInstrumentation();
|
|
912
|
-
assert(ctx.allocs.items(.len)[index] == .free);
|
|
892
|
+
assert(ctx.allocs[@intFromEnum(index)].common.len == .free);
|
|
913
893
|
|
|
914
894
|
const control_ptr = ctx.control_allocator.rawAlloc(len, alignment, @returnAddress()) orelse
|
|
915
895
|
return;
|
|
@@ -918,38 +898,42 @@ const FuzzContext = struct {
|
|
|
918
898
|
return;
|
|
919
899
|
};
|
|
920
900
|
|
|
921
|
-
ctx.allocs
|
|
901
|
+
ctx.allocs[@intFromEnum(index)] = .{
|
|
922
902
|
.control_ptr = control_ptr,
|
|
923
903
|
.sample_ptr = sample_ptr,
|
|
924
|
-
.
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
904
|
+
.common = .{
|
|
905
|
+
.len = @enumFromInt(len),
|
|
906
|
+
.alignment = alignment,
|
|
907
|
+
},
|
|
908
|
+
};
|
|
909
|
+
|
|
910
|
+
for (control_ptr[0..len], sample_ptr[0..len], 0..) |*control, *sample, i| {
|
|
911
|
+
control.* = @truncate(i);
|
|
912
|
+
sample.* = @truncate(i);
|
|
932
913
|
}
|
|
933
914
|
|
|
934
|
-
|
|
915
|
+
@atomicStore(Alloc.Index, &ctx.last_alloc_index, index, .release);
|
|
935
916
|
}
|
|
936
917
|
fn doOneResize(ctx: *FuzzContext, new_len: usize) void {
|
|
937
918
|
@disableInstrumentation();
|
|
938
|
-
const index = tls_last_index orelse return;
|
|
939
|
-
const len = ctx.allocs.items(.len)[index];
|
|
940
|
-
assert(len != .free);
|
|
941
|
-
const memory = ctx.allocs.items(.sample_ptr)[index][0..@intFromEnum(len)];
|
|
942
|
-
const alignment = ctx.allocs.items(.alignment)[index];
|
|
943
919
|
|
|
944
|
-
|
|
945
|
-
|
|
920
|
+
const index = @atomicRmw(Alloc.Index, &ctx.last_alloc_index, .Xchg, .none, .acquire);
|
|
921
|
+
if (index == .none) return;
|
|
922
|
+
|
|
923
|
+
const allocation = &ctx.allocs[@intFromEnum(index)];
|
|
924
|
+
assert(allocation.common.len != .free);
|
|
925
|
+
const memory = allocation.sample_ptr[0..@intFromEnum(allocation.common.len)];
|
|
926
|
+
const alignment = allocation.common.alignment;
|
|
927
|
+
|
|
928
|
+
assert(alignment.check(@intFromPtr(allocation.control_ptr)));
|
|
929
|
+
assert(alignment.check(@intFromPtr(allocation.sample_ptr)));
|
|
946
930
|
|
|
947
931
|
// Since `resize` is fallible, we have to ensure that `control_allocator`
|
|
948
932
|
// is always successful by reserving the memory we need beforehand.
|
|
949
933
|
const new_control_ptr = ctx.control_allocator.rawAlloc(new_len, alignment, @returnAddress()) orelse
|
|
950
934
|
return;
|
|
951
935
|
if (ctx.sample_allocator.rawResize(memory, alignment, new_len, @returnAddress())) {
|
|
952
|
-
const old_control =
|
|
936
|
+
const old_control = allocation.control_ptr[0..memory.len];
|
|
953
937
|
const overlap = @min(memory.len, new_len);
|
|
954
938
|
@memcpy(new_control_ptr[0..overlap], old_control[0..overlap]);
|
|
955
939
|
ctx.control_allocator.rawFree(old_control, alignment, @returnAddress());
|
|
@@ -958,23 +942,27 @@ const FuzzContext = struct {
|
|
|
958
942
|
return;
|
|
959
943
|
}
|
|
960
944
|
|
|
961
|
-
ctx.allocs
|
|
945
|
+
ctx.allocs[@intFromEnum(index)] = .{
|
|
962
946
|
.control_ptr = new_control_ptr,
|
|
963
947
|
.sample_ptr = memory.ptr,
|
|
964
|
-
.
|
|
965
|
-
|
|
966
|
-
|
|
948
|
+
.common = .{
|
|
949
|
+
.len = @enumFromInt(new_len),
|
|
950
|
+
.alignment = alignment,
|
|
951
|
+
},
|
|
952
|
+
};
|
|
967
953
|
|
|
968
954
|
if (new_len > memory.len) {
|
|
969
955
|
for (
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
956
|
+
allocation.control_ptr[memory.len..new_len],
|
|
957
|
+
allocation.sample_ptr[memory.len..new_len],
|
|
958
|
+
0..,
|
|
959
|
+
) |*control, *sample, i| {
|
|
960
|
+
control.* = @truncate(i);
|
|
961
|
+
sample.* = @truncate(i);
|
|
976
962
|
}
|
|
977
963
|
}
|
|
964
|
+
|
|
965
|
+
@atomicStore(Alloc.Index, &ctx.last_alloc_index, index, .release);
|
|
978
966
|
}
|
|
979
967
|
fn doOneRemap(ctx: *FuzzContext, new_len: usize) void {
|
|
980
968
|
@disableInstrumentation();
|
|
@@ -982,26 +970,29 @@ const FuzzContext = struct {
|
|
|
982
970
|
}
|
|
983
971
|
fn doOneFree(ctx: *FuzzContext) void {
|
|
984
972
|
@disableInstrumentation();
|
|
985
|
-
const index = tls_last_index orelse return;
|
|
986
|
-
const len = ctx.allocs.items(.len)[index];
|
|
987
|
-
assert(len != .free);
|
|
988
|
-
const memory = ctx.allocs.items(.sample_ptr)[index][0..@intFromEnum(len)];
|
|
989
|
-
const alignment = ctx.allocs.items(.alignment)[index];
|
|
990
973
|
|
|
991
|
-
|
|
992
|
-
|
|
974
|
+
const index = @atomicRmw(Alloc.Index, &ctx.last_alloc_index, .Xchg, .none, .acquire);
|
|
975
|
+
if (index == .none) return;
|
|
993
976
|
|
|
994
|
-
ctx.
|
|
995
|
-
|
|
977
|
+
const allocation = &ctx.allocs[@intFromEnum(index)];
|
|
978
|
+
assert(allocation.common.len != .free);
|
|
979
|
+
const len: usize = @intFromEnum(allocation.common.len);
|
|
980
|
+
const alignment = allocation.common.alignment;
|
|
996
981
|
|
|
997
|
-
|
|
982
|
+
assert(alignment.check(@intFromPtr(allocation.control_ptr)));
|
|
983
|
+
assert(alignment.check(@intFromPtr(allocation.sample_ptr)));
|
|
984
|
+
|
|
985
|
+
ctx.control_allocator.rawFree(allocation.control_ptr[0..len], alignment, @returnAddress());
|
|
986
|
+
ctx.sample_allocator.rawFree(allocation.sample_ptr[0..len], alignment, @returnAddress());
|
|
987
|
+
|
|
988
|
+
ctx.allocs[@intFromEnum(index)] = .{
|
|
998
989
|
.control_ptr = undefined,
|
|
999
990
|
.sample_ptr = undefined,
|
|
1000
|
-
.
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
991
|
+
.common = .{
|
|
992
|
+
.len = .free,
|
|
993
|
+
.alignment = .@"1",
|
|
994
|
+
},
|
|
995
|
+
};
|
|
1005
996
|
}
|
|
1006
997
|
};
|
|
1007
998
|
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
//! An allocator that attempts to allocate from the given buffer, falling back to
|
|
2
|
+
//! `fallback_allocator` if this fails.
|
|
3
|
+
|
|
4
|
+
const std = @import("../std.zig");
|
|
5
|
+
const heap = std.heap;
|
|
6
|
+
const testing = std.testing;
|
|
7
|
+
|
|
8
|
+
const Alignment = std.mem.Alignment;
|
|
9
|
+
const Allocator = std.mem.Allocator;
|
|
10
|
+
const FixedBufferAllocator = std.heap.FixedBufferAllocator;
|
|
11
|
+
|
|
12
|
+
const BufferFirstAllocator = @This();
|
|
13
|
+
|
|
14
|
+
fallback_allocator: Allocator,
|
|
15
|
+
fixed_buffer_allocator: FixedBufferAllocator,
|
|
16
|
+
|
|
17
|
+
pub fn init(buffer: []u8, fallback_allocator: Allocator) BufferFirstAllocator {
|
|
18
|
+
return .{
|
|
19
|
+
.fallback_allocator = fallback_allocator,
|
|
20
|
+
.fixed_buffer_allocator = .init(buffer),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
pub fn allocator(self: *BufferFirstAllocator) Allocator {
|
|
25
|
+
return .{
|
|
26
|
+
.ptr = self,
|
|
27
|
+
.vtable = &.{
|
|
28
|
+
.alloc = alloc,
|
|
29
|
+
.resize = resize,
|
|
30
|
+
.remap = remap,
|
|
31
|
+
.free = free,
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
fn alloc(
|
|
37
|
+
ctx: *anyopaque,
|
|
38
|
+
len: usize,
|
|
39
|
+
alignment: Alignment,
|
|
40
|
+
ra: usize,
|
|
41
|
+
) ?[*]u8 {
|
|
42
|
+
const self: *BufferFirstAllocator = @ptrCast(@alignCast(ctx));
|
|
43
|
+
return FixedBufferAllocator.alloc(&self.fixed_buffer_allocator, len, alignment, ra) orelse
|
|
44
|
+
return self.fallback_allocator.rawAlloc(len, alignment, ra);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
fn resize(
|
|
48
|
+
ctx: *anyopaque,
|
|
49
|
+
buf: []u8,
|
|
50
|
+
alignment: Alignment,
|
|
51
|
+
new_len: usize,
|
|
52
|
+
ra: usize,
|
|
53
|
+
) bool {
|
|
54
|
+
const self: *BufferFirstAllocator = @ptrCast(@alignCast(ctx));
|
|
55
|
+
if (self.fixed_buffer_allocator.ownsPtr(buf.ptr)) {
|
|
56
|
+
return FixedBufferAllocator.resize(&self.fixed_buffer_allocator, buf, alignment, new_len, ra);
|
|
57
|
+
} else {
|
|
58
|
+
return self.fallback_allocator.rawResize(buf, alignment, new_len, ra);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
fn remap(
|
|
63
|
+
context: *anyopaque,
|
|
64
|
+
memory: []u8,
|
|
65
|
+
alignment: Alignment,
|
|
66
|
+
new_len: usize,
|
|
67
|
+
return_address: usize,
|
|
68
|
+
) ?[*]u8 {
|
|
69
|
+
const self: *BufferFirstAllocator = @ptrCast(@alignCast(context));
|
|
70
|
+
if (self.fixed_buffer_allocator.ownsPtr(memory.ptr)) {
|
|
71
|
+
return FixedBufferAllocator.remap(&self.fixed_buffer_allocator, memory, alignment, new_len, return_address);
|
|
72
|
+
} else {
|
|
73
|
+
return self.fallback_allocator.rawRemap(memory, alignment, new_len, return_address);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
fn free(
|
|
78
|
+
ctx: *anyopaque,
|
|
79
|
+
buf: []u8,
|
|
80
|
+
alignment: Alignment,
|
|
81
|
+
ra: usize,
|
|
82
|
+
) void {
|
|
83
|
+
const self: *BufferFirstAllocator = @ptrCast(@alignCast(ctx));
|
|
84
|
+
if (self.fixed_buffer_allocator.ownsPtr(buf.ptr)) {
|
|
85
|
+
return FixedBufferAllocator.free(&self.fixed_buffer_allocator, buf, alignment, ra);
|
|
86
|
+
} else {
|
|
87
|
+
return self.fallback_allocator.rawFree(buf, alignment, ra);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
test "BufferFirstAllocator" {
|
|
92
|
+
// Buffer first specific tests
|
|
93
|
+
{
|
|
94
|
+
var buffer: [10]u8 = undefined;
|
|
95
|
+
var bfa_state: BufferFirstAllocator = .init(&buffer, std.testing.allocator);
|
|
96
|
+
const bfa = bfa_state.allocator();
|
|
97
|
+
|
|
98
|
+
// We're under the limit, so we should be allocated in the buffer
|
|
99
|
+
const txt0 = "hellowrld";
|
|
100
|
+
const buf0 = try bfa.create(@TypeOf(txt0.*));
|
|
101
|
+
buf0.* = txt0.*;
|
|
102
|
+
try testing.expect(bfa_state.fixed_buffer_allocator.ownsPtr(buf0.ptr));
|
|
103
|
+
|
|
104
|
+
// We're now over the limit, so we should be allocated from the fallback
|
|
105
|
+
const txt1 = "test!";
|
|
106
|
+
const buf1 = try bfa.create(@TypeOf(txt1.*));
|
|
107
|
+
buf1.* = txt1.*;
|
|
108
|
+
try testing.expect(!bfa_state.fixed_buffer_allocator.ownsPtr(buf1.ptr));
|
|
109
|
+
|
|
110
|
+
// Free the allocation that took up space in the buffer
|
|
111
|
+
try testing.expectEqualStrings(txt0, buf0);
|
|
112
|
+
bfa.destroy(buf0);
|
|
113
|
+
|
|
114
|
+
// The next allocation would go in the buffer, but it's too big so it doesn't
|
|
115
|
+
const txt2 = "qwertyqwerty";
|
|
116
|
+
const buf2 = try bfa.create(@TypeOf(txt2.*));
|
|
117
|
+
buf2.* = txt2.*;
|
|
118
|
+
try testing.expect(!bfa_state.fixed_buffer_allocator.ownsPtr(buf2.ptr));
|
|
119
|
+
|
|
120
|
+
// The next allocation is smaller and fits in the buffer
|
|
121
|
+
const txt3 = "dvorak";
|
|
122
|
+
const buf3 = try bfa.create(@TypeOf(txt3.*));
|
|
123
|
+
buf3.* = txt3.*;
|
|
124
|
+
try testing.expect(bfa_state.fixed_buffer_allocator.ownsPtr(buf3.ptr));
|
|
125
|
+
|
|
126
|
+
// The remainder in the buffer is too small for the following allocation so it falls back
|
|
127
|
+
const txt4 = "moretext";
|
|
128
|
+
const buf4 = try bfa.create(@TypeOf(txt4.*));
|
|
129
|
+
buf4.* = txt4.*;
|
|
130
|
+
try testing.expect(!bfa_state.fixed_buffer_allocator.ownsPtr(buf4.ptr));
|
|
131
|
+
|
|
132
|
+
// Check equality on the remaining buffers and free them
|
|
133
|
+
try testing.expectEqualStrings(txt1, buf1);
|
|
134
|
+
bfa.destroy(buf1);
|
|
135
|
+
try testing.expectEqualStrings(txt2, buf2);
|
|
136
|
+
bfa.destroy(buf2);
|
|
137
|
+
try testing.expectEqualStrings(txt3, buf3);
|
|
138
|
+
bfa.destroy(buf3);
|
|
139
|
+
try testing.expectEqualStrings(txt4, buf4);
|
|
140
|
+
bfa.destroy(buf4);
|
|
141
|
+
|
|
142
|
+
try testing.expectEqual(0, bfa_state.fixed_buffer_allocator.end_index);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Standard allocator tests
|
|
146
|
+
{
|
|
147
|
+
var buf: [4096]u8 = undefined;
|
|
148
|
+
{
|
|
149
|
+
var bfa: BufferFirstAllocator = .init(&buf, std.testing.allocator);
|
|
150
|
+
try heap.testAllocator(bfa.allocator());
|
|
151
|
+
}
|
|
152
|
+
{
|
|
153
|
+
var bfa: BufferFirstAllocator = .init(&buf, std.testing.allocator);
|
|
154
|
+
try heap.testAllocatorAligned(bfa.allocator());
|
|
155
|
+
}
|
|
156
|
+
{
|
|
157
|
+
var bfa: BufferFirstAllocator = .init(&buf, std.testing.allocator);
|
|
158
|
+
try heap.testAllocatorLargeAlignment(bfa.allocator());
|
|
159
|
+
}
|
|
160
|
+
{
|
|
161
|
+
var bfa: BufferFirstAllocator = .init(&buf, std.testing.allocator);
|
|
162
|
+
try heap.testAllocatorAlignedShrink(bfa.allocator());
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
//! Resizing and remapping are forwarded directly to the backing allocator,
|
|
82
82
|
//! except where such operations would change the category from large to small.
|
|
83
83
|
const builtin = @import("builtin");
|
|
84
|
-
const StackTrace = std.
|
|
84
|
+
const StackTrace = std.debug.StackTrace;
|
|
85
85
|
|
|
86
86
|
const std = @import("std");
|
|
87
87
|
const log = std.log.scoped(.DebugAllocator);
|
|
@@ -229,7 +229,7 @@ pub fn DebugAllocator(comptime config: Config) type {
|
|
|
229
229
|
std.debug.dumpStackTrace(self.getStackTrace(trace_kind));
|
|
230
230
|
}
|
|
231
231
|
|
|
232
|
-
fn getStackTrace(self: *LargeAlloc, trace_kind: TraceKind) std.
|
|
232
|
+
fn getStackTrace(self: *LargeAlloc, trace_kind: TraceKind) std.debug.StackTrace {
|
|
233
233
|
assert(@intFromEnum(trace_kind) < trace_n);
|
|
234
234
|
const stack_addresses = &self.stack_addresses[@intFromEnum(trace_kind)];
|
|
235
235
|
var len: usize = 0;
|
|
@@ -237,8 +237,8 @@ pub fn DebugAllocator(comptime config: Config) type {
|
|
|
237
237
|
len += 1;
|
|
238
238
|
}
|
|
239
239
|
return .{
|
|
240
|
-
.
|
|
241
|
-
.
|
|
240
|
+
.return_addresses = stack_addresses[0..len],
|
|
241
|
+
.skipped = if (len < stack_addresses.len) .none else .unknown,
|
|
242
242
|
};
|
|
243
243
|
}
|
|
244
244
|
|
|
@@ -339,8 +339,8 @@ pub fn DebugAllocator(comptime config: Config) type {
|
|
|
339
339
|
len += 1;
|
|
340
340
|
}
|
|
341
341
|
return .{
|
|
342
|
-
.
|
|
343
|
-
.
|
|
342
|
+
.return_addresses = stack_addresses[0..len],
|
|
343
|
+
.skipped = if (len < stack_addresses.len) .none else .unknown,
|
|
344
344
|
};
|
|
345
345
|
}
|
|
346
346
|
|
|
@@ -508,7 +508,7 @@ pub fn DebugAllocator(comptime config: Config) type {
|
|
|
508
508
|
|
|
509
509
|
fn collectStackTrace(first_trace_addr: usize, addr_buf: *[stack_n]usize) void {
|
|
510
510
|
const st = std.debug.captureCurrentStackTrace(.{ .first_address = first_trace_addr }, addr_buf);
|
|
511
|
-
@memset(addr_buf[@min(st.
|
|
511
|
+
@memset(addr_buf[@min(st.return_addresses.len, addr_buf.len)..], 0);
|
|
512
512
|
}
|
|
513
513
|
|
|
514
514
|
fn reportDoubleFree(ret_addr: usize, alloc_stack_trace: StackTrace, free_stack_trace: StackTrace) void {
|