@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.
Files changed (352) hide show
  1. package/LICENSE +19 -0
  2. package/c/fcntl.zig +6 -1
  3. package/c/inttypes.zig +0 -10
  4. package/c/math.zig +138 -114
  5. package/c/pthread.zig +57 -0
  6. package/c/search.zig +1 -27
  7. package/c/stdlib/drand48.zig +0 -57
  8. package/c/stdlib.zig +0 -100
  9. package/c/string.zig +20 -7
  10. package/c/strings.zig +0 -38
  11. package/c/stropts.zig +17 -0
  12. package/c/unistd.zig +27 -26
  13. package/c/wchar.zig +10 -0
  14. package/c.zig +3 -2
  15. package/compiler/aro/aro/Attribute/names.zig +604 -589
  16. package/compiler/aro/aro/Attribute.zig +202 -116
  17. package/compiler/aro/aro/Builtins/common.zig +874 -863
  18. package/compiler/aro/aro/Builtins/eval.zig +15 -7
  19. package/compiler/aro/aro/Builtins.zig +0 -1
  20. package/compiler/aro/aro/CodeGen.zig +8 -7
  21. package/compiler/aro/aro/Compilation.zig +137 -111
  22. package/compiler/aro/aro/Diagnostics.zig +21 -17
  23. package/compiler/aro/aro/Driver/GCCDetector.zig +635 -0
  24. package/compiler/aro/aro/Driver.zig +138 -63
  25. package/compiler/aro/aro/LangOpts.zig +12 -2
  26. package/compiler/aro/aro/Parser/Diagnostic.zig +79 -19
  27. package/compiler/aro/aro/Parser.zig +352 -153
  28. package/compiler/aro/aro/Pragma.zig +3 -2
  29. package/compiler/aro/aro/Preprocessor/Diagnostic.zig +21 -0
  30. package/compiler/aro/aro/Preprocessor.zig +136 -62
  31. package/compiler/aro/aro/Target.zig +17 -12
  32. package/compiler/aro/aro/Tokenizer.zig +31 -14
  33. package/compiler/aro/aro/Toolchain.zig +4 -7
  34. package/compiler/aro/aro/Tree.zig +178 -148
  35. package/compiler/aro/aro/TypeStore.zig +82 -24
  36. package/compiler/aro/aro/Value.zig +13 -17
  37. package/compiler/aro/aro/features.zig +1 -0
  38. package/compiler/aro/aro/pragmas/message.zig +3 -2
  39. package/compiler/aro/aro/pragmas/once.zig +0 -1
  40. package/compiler/aro/aro/record_layout.zig +3 -3
  41. package/compiler/aro/aro/text_literal.zig +3 -2
  42. package/compiler/aro/assembly_backend/x86_64.zig +7 -8
  43. package/compiler/aro/backend/Assembly.zig +1 -2
  44. package/compiler/aro/backend/Interner.zig +2 -2
  45. package/compiler/aro/backend/Ir.zig +100 -92
  46. package/compiler/aro/include/ptrcheck.h +49 -0
  47. package/compiler/aro/main.zig +26 -10
  48. package/compiler/build_runner.zig +1 -2
  49. package/compiler/objdump.zig +93 -0
  50. package/compiler/reduce/Walk.zig +7 -7
  51. package/compiler/reduce.zig +5 -1
  52. package/compiler/resinator/compile.zig +2 -2
  53. package/compiler/resinator/main.zig +7 -1
  54. package/compiler/resinator/preprocess.zig +1 -3
  55. package/compiler/std-docs.zig +8 -1
  56. package/compiler/test_runner.zig +194 -62
  57. package/compiler/translate-c/MacroTranslator.zig +80 -11
  58. package/compiler/translate-c/PatternList.zig +1 -9
  59. package/compiler/translate-c/Scope.zig +43 -6
  60. package/compiler/translate-c/Translator.zig +369 -127
  61. package/compiler/translate-c/ast.zig +19 -11
  62. package/compiler/translate-c/main.zig +76 -17
  63. package/compiler_rt/cos.zig +140 -53
  64. package/compiler_rt/divmodei4.zig +40 -17
  65. package/compiler_rt/exp.zig +1 -6
  66. package/compiler_rt/exp2.zig +1 -6
  67. package/compiler_rt/exp_f128.zig +377 -0
  68. package/compiler_rt/fabs.zig +0 -2
  69. package/compiler_rt/fma.zig +0 -2
  70. package/compiler_rt/fmax.zig +0 -2
  71. package/compiler_rt/fmin.zig +0 -2
  72. package/compiler_rt/fmod.zig +0 -2
  73. package/compiler_rt/limb64.zig +1127 -0
  74. package/compiler_rt/log.zig +0 -2
  75. package/compiler_rt/log10.zig +0 -2
  76. package/compiler_rt/log2.zig +0 -2
  77. package/compiler_rt/long_double.zig +37 -0
  78. package/compiler_rt/mulXi3.zig +1 -1
  79. package/compiler_rt/mulo.zig +6 -1
  80. package/compiler_rt/rem_pio2l.zig +173 -0
  81. package/compiler_rt/round.zig +0 -2
  82. package/compiler_rt/sin.zig +139 -56
  83. package/compiler_rt/sincos.zig +277 -72
  84. package/compiler_rt/sqrt.zig +0 -2
  85. package/compiler_rt/ssp.zig +1 -1
  86. package/compiler_rt/tan.zig +117 -48
  87. package/compiler_rt/trig.zig +256 -6
  88. package/compiler_rt/trunc.zig +0 -2
  89. package/compiler_rt/udivmodei4.zig +28 -0
  90. package/compiler_rt.zig +2 -0
  91. package/fuzzer.zig +857 -307
  92. package/libc/musl/arch/mipsn32/syscall_arch.h +35 -32
  93. package/libc/musl/src/math/pow.c +343 -0
  94. package/package.json +1 -1
  95. package/std/Build/Cache.zig +6 -6
  96. package/std/Build/Fuzz.zig +6 -19
  97. package/std/Build/Module.zig +1 -1
  98. package/std/Build/Step/CheckObject.zig +3 -3
  99. package/std/Build/Step/Compile.zig +18 -1
  100. package/std/Build/Step/ConfigHeader.zig +49 -33
  101. package/std/Build/Step/InstallArtifact.zig +18 -0
  102. package/std/Build/Step/Run.zig +538 -89
  103. package/std/Build/Step/TranslateC.zig +0 -6
  104. package/std/Build/Step.zig +10 -19
  105. package/std/Build/WebServer.zig +31 -19
  106. package/std/Build/abi.zig +47 -11
  107. package/std/Build.zig +17 -17
  108. package/std/Io/Dir.zig +7 -2
  109. package/std/Io/Dispatch.zig +5 -13
  110. package/std/Io/File/Reader.zig +3 -1
  111. package/std/Io/File/Writer.zig +8 -6
  112. package/std/Io/File.zig +1 -0
  113. package/std/Io/Kqueue.zig +2 -2
  114. package/std/Io/Reader.zig +8 -9
  115. package/std/Io/Semaphore.zig +112 -17
  116. package/std/Io/Terminal.zig +1 -1
  117. package/std/Io/Threaded.zig +352 -180
  118. package/std/Io/Uring.zig +15 -16
  119. package/std/Io/Writer.zig +46 -42
  120. package/std/Io/net.zig +11 -11
  121. package/std/Io.zig +1052 -20
  122. package/std/SemanticVersion.zig +1 -1
  123. package/std/Target/Query.zig +2 -2
  124. package/std/Target.zig +53 -7
  125. package/std/Thread.zig +8 -3
  126. package/std/array_hash_map.zig +105 -573
  127. package/std/array_list.zig +22 -31
  128. package/std/bit_set.zig +22 -6
  129. package/std/builtin/assembly.zig +68 -0
  130. package/std/builtin.zig +4 -0
  131. package/std/c/haiku.zig +3 -0
  132. package/std/c/serenity.zig +1 -6
  133. package/std/c.zig +106 -24
  134. package/std/compress/flate/Compress.zig +3 -3
  135. package/std/compress/flate/Decompress.zig +2 -3
  136. package/std/compress/zstd/Decompress.zig +2 -4
  137. package/std/crypto/Certificate/Bundle.zig +15 -1
  138. package/std/crypto/Certificate.zig +13 -1
  139. package/std/crypto/ascon.zig +75 -33
  140. package/std/crypto/codecs/asn1/Oid.zig +12 -1
  141. package/std/crypto/codecs/asn1.zig +33 -18
  142. package/std/crypto/codecs/base64_hex_ct.zig +16 -8
  143. package/std/crypto/ml_kem.zig +2 -9
  144. package/std/crypto/tls/Client.zig +79 -4
  145. package/std/crypto/tls.zig +1 -1
  146. package/std/crypto.zig +1 -0
  147. package/std/debug/Dwarf.zig +29 -9
  148. package/std/debug/Info.zig +4 -0
  149. package/std/debug/MachOFile.zig +46 -8
  150. package/std/debug/Pdb.zig +540 -37
  151. package/std/debug/SelfInfo/Elf.zig +19 -18
  152. package/std/debug/SelfInfo/MachO.zig +18 -7
  153. package/std/debug/SelfInfo/Windows.zig +138 -36
  154. package/std/debug.zig +181 -66
  155. package/std/enums.zig +25 -19
  156. package/std/fmt.zig +8 -3
  157. package/std/fs/path.zig +6 -4
  158. package/std/heap/ArenaAllocator.zig +145 -154
  159. package/std/heap/BufferFirstAllocator.zig +165 -0
  160. package/std/heap/debug_allocator.zig +7 -7
  161. package/std/heap.zig +2 -126
  162. package/std/http/Client.zig +31 -30
  163. package/std/http.zig +14 -13
  164. package/std/json/Scanner.zig +2 -2
  165. package/std/json/Stringify.zig +3 -3
  166. package/std/json/dynamic.zig +4 -4
  167. package/std/math/big/int.zig +16 -17
  168. package/std/mem/Allocator.zig +4 -5
  169. package/std/mem.zig +48 -0
  170. package/std/os/emscripten.zig +2 -18
  171. package/std/os/linux/IoUring.zig +2 -0
  172. package/std/os/linux/aarch64.zig +41 -12
  173. package/std/os/linux/arc.zig +173 -0
  174. package/std/os/linux/arm.zig +41 -12
  175. package/std/os/linux/hexagon.zig +33 -11
  176. package/std/os/linux/loongarch32.zig +41 -13
  177. package/std/os/linux/loongarch64.zig +41 -12
  178. package/std/os/linux/m68k.zig +41 -13
  179. package/std/os/linux/mips.zig +67 -36
  180. package/std/os/linux/mips64.zig +60 -29
  181. package/std/os/linux/mipsn32.zig +60 -29
  182. package/std/os/linux/or1k.zig +41 -12
  183. package/std/os/linux/powerpc.zig +41 -12
  184. package/std/os/linux/powerpc64.zig +41 -12
  185. package/std/os/linux/riscv32.zig +41 -12
  186. package/std/os/linux/riscv64.zig +41 -12
  187. package/std/os/linux/s390x.zig +44 -7
  188. package/std/os/linux/sparc64.zig +83 -52
  189. package/std/os/linux/thumb.zig +52 -36
  190. package/std/os/linux/x32.zig +41 -12
  191. package/std/os/linux/x86.zig +42 -13
  192. package/std/os/linux/x86_64.zig +41 -12
  193. package/std/os/linux.zig +419 -438
  194. package/std/os/uefi/tables/boot_services.zig +9 -8
  195. package/std/os/windows.zig +2 -2
  196. package/std/os.zig +41 -0
  197. package/std/pdb.zig +143 -4
  198. package/std/posix.zig +6 -12
  199. package/std/priority_dequeue.zig +13 -12
  200. package/std/priority_queue.zig +5 -4
  201. package/std/process/Child.zig +1 -1
  202. package/std/process/Environ.zig +1 -1
  203. package/std/process.zig +1 -1
  204. package/std/sort.zig +3 -3
  205. package/std/start.zig +17 -4
  206. package/std/std.zig +19 -6
  207. package/std/testing/FailingAllocator.zig +4 -4
  208. package/std/testing/Smith.zig +37 -2
  209. package/std/zig/Ast/Render.zig +187 -459
  210. package/std/zig/Ast.zig +0 -4
  211. package/std/zig/AstGen.zig +86 -103
  212. package/std/zig/AstRlAnnotate.zig +0 -11
  213. package/std/zig/AstSmith.zig +2602 -0
  214. package/std/zig/BuiltinFn.zig +0 -32
  215. package/std/zig/Client.zig +8 -3
  216. package/std/zig/LibCInstallation.zig +4 -3
  217. package/std/zig/Parse.zig +90 -81
  218. package/std/zig/Server.zig +26 -0
  219. package/std/zig/WindowsSdk.zig +13 -13
  220. package/std/zig/Zir.zig +66 -62
  221. package/std/zig/ZonGen.zig +6 -5
  222. package/std/zig/c_translation/helpers.zig +14 -9
  223. package/std/zig/llvm/Builder.zig +119 -60
  224. package/std/zig/system.zig +20 -4
  225. package/std/zig/tokenizer.zig +2 -1
  226. package/std/zig.zig +7 -10
  227. package/std/zip.zig +5 -5
  228. package/zig.h +340 -1
  229. package/compiler/aro/aro/Driver/Filesystem.zig +0 -241
  230. package/libc/mingw/complex/cabs.c +0 -48
  231. package/libc/mingw/complex/cabsf.c +0 -48
  232. package/libc/mingw/complex/cacos.c +0 -50
  233. package/libc/mingw/complex/cacosf.c +0 -50
  234. package/libc/mingw/complex/carg.c +0 -48
  235. package/libc/mingw/complex/cargf.c +0 -48
  236. package/libc/mingw/complex/casin.c +0 -50
  237. package/libc/mingw/complex/casinf.c +0 -50
  238. package/libc/mingw/complex/catan.c +0 -50
  239. package/libc/mingw/complex/catanf.c +0 -50
  240. package/libc/mingw/complex/ccos.c +0 -50
  241. package/libc/mingw/complex/ccosf.c +0 -50
  242. package/libc/mingw/complex/cexp.c +0 -48
  243. package/libc/mingw/complex/cexpf.c +0 -48
  244. package/libc/mingw/complex/cimag.c +0 -48
  245. package/libc/mingw/complex/cimagf.c +0 -48
  246. package/libc/mingw/complex/clog.c +0 -48
  247. package/libc/mingw/complex/clog10.c +0 -49
  248. package/libc/mingw/complex/clog10f.c +0 -49
  249. package/libc/mingw/complex/clogf.c +0 -48
  250. package/libc/mingw/complex/conj.c +0 -48
  251. package/libc/mingw/complex/conjf.c +0 -48
  252. package/libc/mingw/complex/cpow.c +0 -48
  253. package/libc/mingw/complex/cpowf.c +0 -48
  254. package/libc/mingw/complex/cproj.c +0 -48
  255. package/libc/mingw/complex/cprojf.c +0 -48
  256. package/libc/mingw/complex/creal.c +0 -48
  257. package/libc/mingw/complex/crealf.c +0 -48
  258. package/libc/mingw/complex/csin.c +0 -50
  259. package/libc/mingw/complex/csinf.c +0 -50
  260. package/libc/mingw/complex/csqrt.c +0 -48
  261. package/libc/mingw/complex/csqrtf.c +0 -48
  262. package/libc/mingw/complex/ctan.c +0 -50
  263. package/libc/mingw/complex/ctanf.c +0 -50
  264. package/libc/mingw/math/arm/s_rint.c +0 -86
  265. package/libc/mingw/math/arm/s_rintf.c +0 -51
  266. package/libc/mingw/math/arm/sincos.S +0 -30
  267. package/libc/mingw/math/arm-common/sincosl.c +0 -13
  268. package/libc/mingw/math/arm64/rint.c +0 -12
  269. package/libc/mingw/math/arm64/rintf.c +0 -12
  270. package/libc/mingw/math/arm64/sincos.S +0 -32
  271. package/libc/mingw/math/bsd_private_base.h +0 -148
  272. package/libc/mingw/math/fdiml.c +0 -24
  273. package/libc/mingw/math/frexpf.c +0 -13
  274. package/libc/mingw/math/frexpl.c +0 -71
  275. package/libc/mingw/math/x86/acosf.c +0 -29
  276. package/libc/mingw/math/x86/atanf.c +0 -23
  277. package/libc/mingw/math/x86/atanl.c +0 -18
  278. package/libc/mingw/math/x86/cos.def.h +0 -65
  279. package/libc/mingw/math/x86/cosl.c +0 -46
  280. package/libc/mingw/math/x86/cosl_internal.S +0 -55
  281. package/libc/mingw/math/x86/ldexp.c +0 -23
  282. package/libc/mingw/math/x86/scalbn.S +0 -41
  283. package/libc/mingw/math/x86/scalbnf.S +0 -40
  284. package/libc/mingw/math/x86/sin.def.h +0 -65
  285. package/libc/mingw/math/x86/sinl.c +0 -46
  286. package/libc/mingw/math/x86/sinl_internal.S +0 -58
  287. package/libc/mingw/math/x86/tanl.S +0 -62
  288. package/libc/mingw/misc/btowc.c +0 -28
  289. package/libc/mingw/misc/wcstof.c +0 -66
  290. package/libc/mingw/misc/wcstoimax.c +0 -132
  291. package/libc/mingw/misc/wcstoumax.c +0 -126
  292. package/libc/mingw/misc/wctob.c +0 -29
  293. package/libc/mingw/misc/winbs_uint64.c +0 -6
  294. package/libc/mingw/misc/winbs_ulong.c +0 -6
  295. package/libc/mingw/misc/winbs_ushort.c +0 -6
  296. package/libc/mingw/stdio/_Exit.c +0 -10
  297. package/libc/mingw/stdio/_findfirst64i32.c +0 -21
  298. package/libc/mingw/stdio/_findnext64i32.c +0 -21
  299. package/libc/mingw/stdio/_fstat64i32.c +0 -37
  300. package/libc/mingw/stdio/_stat64i32.c +0 -37
  301. package/libc/mingw/stdio/_wfindfirst64i32.c +0 -21
  302. package/libc/mingw/stdio/_wfindnext64i32.c +0 -21
  303. package/libc/mingw/stdio/_wstat64i32.c +0 -37
  304. package/libc/mingw/winpthreads/spinlock.c +0 -82
  305. package/libc/musl/src/legacy/isastream.c +0 -7
  306. package/libc/musl/src/legacy/valloc.c +0 -8
  307. package/libc/musl/src/linux/tee.c +0 -8
  308. package/libc/musl/src/math/__cosl.c +0 -96
  309. package/libc/musl/src/math/__sinl.c +0 -78
  310. package/libc/musl/src/math/__tanl.c +0 -143
  311. package/libc/musl/src/math/aarch64/lrint.c +0 -10
  312. package/libc/musl/src/math/aarch64/lrintf.c +0 -10
  313. package/libc/musl/src/math/aarch64/rintf.c +0 -7
  314. package/libc/musl/src/math/cosl.c +0 -39
  315. package/libc/musl/src/math/fdim.c +0 -10
  316. package/libc/musl/src/math/fdimf.c +0 -10
  317. package/libc/musl/src/math/fdiml.c +0 -18
  318. package/libc/musl/src/math/finite.c +0 -7
  319. package/libc/musl/src/math/finitef.c +0 -7
  320. package/libc/musl/src/math/frexp.c +0 -23
  321. package/libc/musl/src/math/frexpf.c +0 -23
  322. package/libc/musl/src/math/frexpl.c +0 -29
  323. package/libc/musl/src/math/i386/lrint.c +0 -8
  324. package/libc/musl/src/math/i386/lrintf.c +0 -8
  325. package/libc/musl/src/math/i386/rintf.c +0 -7
  326. package/libc/musl/src/math/lrint.c +0 -72
  327. package/libc/musl/src/math/lrintf.c +0 -8
  328. package/libc/musl/src/math/powerpc64/lrint.c +0 -16
  329. package/libc/musl/src/math/powerpc64/lrintf.c +0 -16
  330. package/libc/musl/src/math/rintf.c +0 -30
  331. package/libc/musl/src/math/s390x/rintf.c +0 -15
  332. package/libc/musl/src/math/sincosl.c +0 -60
  333. package/libc/musl/src/math/sinl.c +0 -41
  334. package/libc/musl/src/math/tanl.c +0 -29
  335. package/libc/musl/src/math/x32/lrint.s +0 -5
  336. package/libc/musl/src/math/x32/lrintf.s +0 -5
  337. package/libc/musl/src/math/x86_64/lrint.c +0 -8
  338. package/libc/musl/src/math/x86_64/lrintf.c +0 -8
  339. package/libc/musl/src/string/strdup.c +0 -10
  340. package/libc/musl/src/string/strndup.c +0 -12
  341. package/libc/musl/src/string/wcsdup.c +0 -10
  342. package/libc/musl/src/thread/pthread_spin_destroy.c +0 -6
  343. package/libc/musl/src/thread/pthread_spin_init.c +0 -6
  344. package/libc/musl/src/thread/pthread_spin_lock.c +0 -8
  345. package/libc/musl/src/thread/pthread_spin_trylock.c +0 -7
  346. package/libc/musl/src/thread/pthread_spin_unlock.c +0 -7
  347. package/libc/musl/src/unistd/dup2.c +0 -20
  348. package/libc/musl/src/unistd/dup3.c +0 -26
  349. package/libc/wasi/libc-bottom-half/sources/reallocarray.c +0 -14
  350. package/libc/wasi/thread-stub/pthread_spin_lock.c +0 -8
  351. package/libc/wasi/thread-stub/pthread_spin_trylock.c +0 -8
  352. 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
- _ = @cmpxchgStrong(
362
- usize,
363
- &node.end_index,
364
- end_index + alignable,
365
- aligned_index + n,
366
- .monotonic, // no need to release alignment padding; there's no one accessing it!
367
- .monotonic,
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 control_buffer = try gpa.alloc(u8, 64 << 10 << 10);
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, 64 << 10 << 10);
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
- .gpa = gpa,
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
- }, fuzzArenaAllocator, .{});
714
+ }, fuzzMultiThreaded, .{});
712
715
  }
713
716
 
714
- fn fuzzArenaAllocator(fuzz_init: FuzzContext.Init, smith: *std.testing.Smith) anyerror!void {
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 ActionTag = @typeInfo(FuzzContext.Action).@"union".tag_type.?;
751
- const weights: []const testing.Smith.Weight = weights: {
752
- if (ctx.allocs.len == ctx.allocs.capacity)
753
- break :weights &.{
754
- .value(ActionTag, .resize, 1),
755
- .value(ActionTag, .remap, 1),
756
- .value(ActionTag, .free, 1),
757
- };
758
- break :weights testing.Smith.baselineWeights(ActionTag) ++
759
- .{testing.Smith.Weight.value(ActionTag, .alloc, 2)};
760
- };
761
- const action: FuzzContext.Action = switch (smith.valueWeighted(ActionTag, weights)) {
762
- .alloc => action: {
763
- const alloc_index = ctx.allocs.addOneBounded() catch continue;
764
- ctx.allocs.items(.len)[alloc_index] = .free;
765
- break :action .{ .alloc = .{
766
- .len = nextLen(smith),
767
- .alignment = smith.valueRangeAtMost(
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
- .index = alloc_index,
773
- } };
770
+ @enumFromInt(alloc_index),
771
+ }) catch unreachable;
774
772
  },
775
- .resize => .{ .resize = .{ .new_len = nextLen(smith) } },
776
- .remap => .{ .remap = .{ .new_len = nextLen(smith) } },
777
- .free => .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 usizeRange(smith: *std.testing.Smith, at_least: usize, at_most: usize) usize {
805
+ fn nextLen(smith: *std.testing.Smith) @typeInfo(FuzzContext.Alloc.Len).@"enum".tag_type {
816
806
  @disableInstrumentation();
817
- const Int = @Int(.unsigned, @min(64, @bitSizeOf(usize)));
818
- return smith.valueRangeAtMost(Int, @intCast(at_least), @intCast(at_most));
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
- allocs: *Allocs,
815
+ last_alloc_index: Alloc.Index,
816
+ allocs: [max_alloc_count]Alloc,
829
817
 
830
- const max_alloc_count = 4096;
818
+ const max_alloc_count = 64;
831
819
  const max_action_count = 2 * max_alloc_count;
832
820
 
833
- const Allocs = std.MultiArrayList(struct {
821
+ const max_alloc_size = 16 << 10;
822
+
823
+ const Alloc = struct {
834
824
  control_ptr: [*]u8,
835
825
  sample_ptr: [*]u8,
836
- len: Len,
837
- alignment: Alignment,
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
- const Len = enum(usize) {
841
- free = std.math.maxInt(usize),
842
- _,
839
+ const Index = enum(usize) {
840
+ none = std.math.maxInt(usize),
841
+ _,
842
+ };
843
843
  };
844
844
 
845
- const Action = union(enum(u8)) {
846
- alloc: struct { len: usize, alignment: Alignment, index: usize },
847
- resize: struct { new_len: usize },
848
- remap: struct { new_len: usize },
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
- gpa: Allocator,
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
- .allocs = allocs,
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 (0..ctx.allocs.len) |index| {
887
- const len: usize = switch (ctx.allocs.items(.len)[index]) {
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 = ctx.allocs.items(.control_ptr)[index][0..len];
892
- const sample = ctx.allocs.items(.sample_ptr)[index][0..len];
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 doOneAction(ctx: *FuzzContext, action: Action) std.Io.Cancelable!void {
890
+ fn doOneAlloc(ctx: *FuzzContext, len: usize, alignment: Alignment, index: Alloc.Index) void {
898
891
  @disableInstrumentation();
899
- ctx.rwl.lockSharedUncancelable(ctx.io);
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.set(index, .{
901
+ ctx.allocs[@intFromEnum(index)] = .{
922
902
  .control_ptr = control_ptr,
923
903
  .sample_ptr = sample_ptr,
924
- .len = @enumFromInt(len),
925
- .alignment = alignment,
926
- });
927
-
928
- for (control_ptr[0..len], sample_ptr[0..len]) |*control, *sample| {
929
- control.* = tls_next;
930
- sample.* = tls_next;
931
- tls_next +%= 1;
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
- tls_last_index = index;
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
- assert(alignment.check(@intFromPtr(ctx.allocs.items(.control_ptr)[index])));
945
- assert(alignment.check(@intFromPtr(ctx.allocs.items(.sample_ptr)[index])));
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 = ctx.allocs.items(.control_ptr)[index][0..memory.len];
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.set(index, .{
945
+ ctx.allocs[@intFromEnum(index)] = .{
962
946
  .control_ptr = new_control_ptr,
963
947
  .sample_ptr = memory.ptr,
964
- .len = @enumFromInt(new_len),
965
- .alignment = alignment,
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
- ctx.allocs.items(.control_ptr)[index][memory.len..new_len],
971
- ctx.allocs.items(.sample_ptr)[index][memory.len..new_len],
972
- ) |*control, *sample| {
973
- control.* = tls_next;
974
- sample.* = tls_next;
975
- tls_next +%= 1;
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
- assert(alignment.check(@intFromPtr(ctx.allocs.items(.control_ptr)[index])));
992
- assert(alignment.check(@intFromPtr(ctx.allocs.items(.sample_ptr)[index])));
974
+ const index = @atomicRmw(Alloc.Index, &ctx.last_alloc_index, .Xchg, .none, .acquire);
975
+ if (index == .none) return;
993
976
 
994
- ctx.control_allocator.rawFree(ctx.allocs.items(.control_ptr)[index][0..memory.len], alignment, @returnAddress());
995
- ctx.sample_allocator.rawFree(ctx.allocs.items(.sample_ptr)[index][0..memory.len], alignment, @returnAddress());
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
- ctx.allocs.set(index, .{
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
- .len = .free,
1001
- .alignment = undefined,
1002
- });
1003
-
1004
- tls_last_index = null;
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.builtin.StackTrace;
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.builtin.StackTrace {
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
- .instruction_addresses = stack_addresses,
241
- .index = len,
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
- .instruction_addresses = stack_addresses,
343
- .index = len,
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.index, addr_buf.len)..], 0);
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 {