{
"file_path": "/app/HACKING.adoc",
"limit": 150
}File does not exist. Note: your current working directory is /app. [error] tool reported failure
{
"command": "ls /app && echo \"---\" && find /app -name \"*.md\" -o -name \"*.adoc\" | head -40",
"description": "List repo root and docs"
}ocaml
---
/app/ocaml/BOOTSTRAP.adoc
/app/ocaml/CODE_OF_CONDUCT.md
/app/ocaml/CONTRIBUTING.md
/app/ocaml/HACKING.adoc
/app/ocaml/INSTALL.adoc
/app/ocaml/README.adoc
/app/ocaml/README.win32.adoc
/app/ocaml/.github/ISSUE_TEMPLATE/bug_report.md
/app/ocaml/.github/ISSUE_TEMPLATE/feature_request.md
/app/ocaml/typing/HACKING.adoc
/app/ocaml/typing/TODO.md
/app/ocaml/utils/HACKING.adoc
/app/ocaml/ocamltest/README.md
/app/ocaml/parsing/CONFLICTS.md
/app/ocaml/parsing/HACKING.adoc
/app/ocaml/parsing/VIPs.md
/app/ocaml/release-info/calendar.md
/app/ocaml/release-info/howto.md
/app/ocaml/release-info/introduction.md
/app/ocaml/runtime/HACKING.adoc
/app/ocaml/stdlib/CONTRIBUTING.md
/app/ocaml/stdlib/HACKING.adoc
/app/ocaml/testsuite/HACKING.adoc
/app/ocaml/manual/README.md
/app/ocaml/asmcomp/amd64/NOTES.md
/app/ocaml/asmcomp/arm64/NOTES.md
/app/ocaml/asmcomp/power/NOTES.md
/app/ocaml/asmcomp/riscv/NOTES.md
/app/ocaml/asmcomp/s390x/NOTES.md
/app/ocaml/release-info/templates/beta.md
/app/ocaml/release-info/templates/production.md
/app/ocaml/release-info/templates/rc.md
/app/ocaml/stdlib/templates/README.adoc
/app/ocaml/testsuite/in_prefix/README.md
/app/ocaml/manual/tests/README.md
/app/ocaml/tools/ci/inria/README.md
/app/ocaml/testsuite/tests/memory-model/README.md
/app/ocaml/manual/src/html_processing/README.md
[stdout]
ocaml
---
/app/ocaml/BOOTSTRAP.adoc
/app/ocaml/CODE_OF_CONDUCT.md
/app/ocaml/CONTRIBUTING.md
/app/ocaml/HACKING.adoc
/app/ocaml/INSTALL.adoc
/app/ocaml/README.adoc
/app/ocaml/README.win32.adoc
/app/ocaml/.github/ISSUE_TEMPLATE/bug_report.md
/app/ocaml/.github/ISSUE_TEMPLATE/feature_request.md
/app/ocaml/typing/HACKING.adoc
/app/ocaml/typing/TODO.md
/app/ocaml/utils/HACKING.adoc
/app/ocaml/ocamltest/README.md
/app/ocaml/parsing/CONFLICTS.md
/app/ocaml/parsing/HACKING.adoc
/app/ocaml/parsing/VIPs.md
/app/ocaml/release-info/calendar.md
/app/ocaml/release-info/howto.md
/app/ocaml/release-info/introduction.md
/app/ocaml/runtime/HACKING.adoc
/app/ocaml/stdlib/CONTRIBUTING.md
/app/ocaml/stdlib/HACKING.adoc
/app/ocaml/testsuite/HACKING.adoc
/app/ocaml/manual/README.md
/app/ocaml/asmcomp/amd64/NOTES.md
/app/ocaml/asmcomp/arm64/NOTES.md
/app/ocaml/asmcomp/power/NOTES.md
/app/ocaml/asmcomp/riscv/NOTES.md
/app/ocaml/asmcomp/s390x/NOTES.md
/app/ocaml/release-info/templates/beta.md
/app/ocaml/release-info/templates/production.md
/app/ocaml/release-info/templates/rc.md
/app/ocaml/stdlib/templates/README.adoc
/app/ocaml/testsuite/in_prefix/README.md
/app/ocaml/manual/tests/README.md
/app/ocaml/tools/ci/inria/README.md
/app/ocaml/testsuite/tests/memory-model/README.md
/app/ocaml/manual/src/html_processing/README.md
[metadata] {"noOutputExpected": false}{
"file_path": "/app/ocaml/HACKING.adoc",
"limit": 200
}1 = Hacking the compiler :camel: 2 3 This document is a work-in-progress attempt to provide useful 4 information for people willing to inspect or modify the compiler 5 distribution's codebase. Feel free to improve it by sending change 6 proposals for it. 7 8 If you already have a patch that you would like to contribute to the 9 official distribution, please see link:CONTRIBUTING.md[]. 10 11 === Your first compiler modification 12 13 1. Create a new git branch to store your changes. 14 + 15 ---- 16 git checkout -b my-modification 17 ---- 18 Usually, this branch wants to be based on `trunk`. If your changes must be on a 19 specific release, use its release branch (*not* the release tag) instead. For 20 example, to make a fix for 4.11.1, base your branch on *4.11* (not on *4.11.1*). 21 The `configure` step for the compiler recognises a development build from the 22 `+dev` in the version number (see file `VERSION`), and release tarballs and the tagged Git commits do 23 not have this which causes some important development things to be disabled 24 (ocamltest and converting C compiler warnings to errors). 25 26 2. Consult link:INSTALL.adoc[] for build instructions. Here is the gist of it: 27 + 28 ---- 29 ./configure 30 make -j 4 31 ---- 32 If you are on a release build and need development options, you can add 33 `--enable-ocamltest` (to allow running the testsuite) and `--enable-warn-error` 34 (so you don't get caught by CI later!). 35 36 3. Try the newly built compiler binaries `ocamlc`, `ocamlopt` or their 37 `.opt` version. To try the toplevel, use: 38 + 39 ---- 40 make runtop 41 ---- 42 43 4. Hack frenetically and keep rebuilding. 44 45 5. Run the testsuite from time to time. 46 + 47 ---- 48 make tests 49 ---- 50 51 6. You did it, Well done! Consult link:CONTRIBUTING.md[] to send your contribution upstream. 52 53 See also our <<tips,development tips and tricks>>, for example on how to 54 <<opam-switch,create an opam switch>> to test your modified compiler. 55 56 === What to do 57 58 There is always a lot of potential tasks, both for old and 59 newcomers. Here are various potential projects: 60 61 * https://github.com/ocaml/ocaml/issues[The OCaml 62 bugtracker] contains reported bugs and feature requests. Some 63 changes that should be accessible to newcomers are marked with the 64 tag link:++https://github.com/ocaml/ocaml/issues?q=is%3Aopen+is%3Aissue+label%3Anewcomer-job++[ 65 newcomer-job]. 66 67 * The 68 https://github.com/ocamllabs/compiler-hacking/wiki/Things-to-work-on[OCaml 69 Labs compiler-hacking wiki] contains various ideas of changes to 70 propose, some easy, some requiring a fair amount of work. 71 72 * Documentation improvements are always much appreciated, either in 73 the various `.mli` files or in the official manual 74 (See link:manual/README.md[]). If you invest effort in understanding 75 a part of the codebase, submitting a pull request that adds 76 clarifying comments can be an excellent contribution to help you, 77 next time, and other code readers. 78 79 * The https://github.com/ocaml/ocaml[github project] contains a lot of 80 pull requests, many of them being in dire need of a review -- we 81 have more people willing to contribute changes than to review 82 someone else's change. Picking one of them, trying to understand the 83 code (looking at the code around it) and asking questions about what 84 you don't understand or what feels odd is super-useful. It helps the 85 contribution process, and it is also an excellent way to get to know 86 various parts of the compiler from the angle of a specific aspect or 87 feature. 88 + 89 Again, reviewing small or medium-sized pull requests is accessible to 90 anyone with OCaml programming experience, and helps maintainers and 91 other contributors. If you also submit pull requests yourself, a good 92 discipline is to review at least as many pull requests as you submit. 93 94 == Structure of the compiler 95 96 The compiler codebase can be intimidating at first sight. Here are 97 a few pointers to get started. 98 99 === Compilation pipeline 100 101 ==== The driver -- link:driver/[] 102 103 The driver contains the "main" function of the compilers that drive 104 compilation. It parses the command-line arguments and composes the 105 required compiler passes by calling functions from the various parts 106 of the compiler described below. 107 108 ==== Parsing -- link:parsing/[] 109 110 Parses source files and produces an Abstract Syntax Tree (AST) 111 (link:parsing/parsetree.mli[] has lot of helpful comments). See 112 link:parsing/HACKING.adoc[]. 113 114 The logic for Camlp4 and Ppx preprocessing is not in link:parsing/[], 115 but in link:driver/[], see link:driver/pparse.mli[] and 116 link:driver/pparse.ml[]. 117 118 ==== Typing -- link:typing/[] 119 120 Type-checks the AST and produces a typed representation of the program 121 (link:typing/typedtree.mli[] has some helpful comments). See 122 link:typing/HACKING.adoc[]. 123 124 ==== The bytecode compiler -- link:bytecomp/[] 125 126 ==== The native compiler -- link:middle_end/[] and link:asmcomp/[] 127 128 === Runtime system 129 130 The low-level routines that OCaml programs use during their execution: 131 garbage collection, interaction with the operating system 132 (IO in particular), low-level primitives to manipulate some OCaml data 133 structures, etc. Mostly implemented in C, with some rare bits of 134 assembly code in architecture-specific files. The "includes" 135 corresponding to the `.c` files are in the link:runtime/caml[] 136 subdirectory. 137 138 Some files are only used by bytecode programs, some only used by 139 native-compiled programs, but most of the runtime code is 140 common. (See `runtime_COMMON_C_SOURCES`, `runtime_BYTECODE_ONLY_C_SOURCES`, 141 and `runtime_NATIVE_ONLY_C_SOURCES` in link:Makefile[] for the list of common, 142 bytecode-only, and native-only source files.) 143 144 See link:runti
{
"command": "cd /app/ocaml && git status 2>/dev/null | head -50; echo \"====\"; git log --oneline -20 2>/dev/null; echo \"====\"; git diff --stat HEAD 2>/dev/null | head -40",
"description": "Check git status and recent changes"
}====
====
[stdout]
====
====
[metadata] {"noOutputExpected": false}{
"command": "ls -la && echo \"====\" && ls runtime/ | head -50 && echo \"====\" && ls runtime/caml/ | grep -iE \"gc|major|sweep|freelist|heap\"",
"description": "Inspect runtime GC files"
}total 2300 drwxr-xr-x 1 root root 26 Oct 28 2025 . drwxr-xr-x 1 root root 27 Oct 28 2025 .. -rw-r--r-- 1 root root 319736 Oct 28 2025 .depend -rw-r--r-- 1 root root 980 Oct 28 2025 .depend.menhir -rw-r--r-- 1 root root 185 Oct 28 2025 .editorconfig -rw-r--r-- 1 root root 10409 Oct 28 2025 .gitattributes drwxr-xr-x 4 root root 57 Oct 28 2025 .github -rw-r--r-- 1 root root 7750 Oct 28 2025 .gitignore -rw-r--r-- 1 root root 208 Oct 28 2025 .gitmodules -rw-r--r-- 1 root root 5944 Oct 28 2025 .mailmap -rw-r--r-- 1 root root 32 Oct 28 2025 .ocp-indent -rw-r--r-- 1 root root 3972 Oct 28 2025 BOOTSTRAP.adoc -rw-r--r-- 1 root root 312 Oct 28 2025 CODE_OF_CONDUCT.md -rw-r--r-- 1 root root 19923 Oct 28 2025 CONTRIBUTING.md -rw-r--r-- 1 root root 680162 Oct 28 2025 Changes -rw-r--r-- 1 root root 33712 Oct 28 2025 HACKING.adoc -rw-r--r-- 1 root root 9997 Oct 28 2025 INSTALL.adoc -rw-r--r-- 1 root root 27179 Oct 28 2025 LICENSE -rw-r--r-- 1 root root 97687 Oct 28 2025 Makefile -rw-r--r-- 1 root root 3624 Oct 28 2025 Makefile.best_binaries -rw-r--r-- 1 root root 6986 Oct 28 2025 Makefile.build_config.in -rw-r--r-- 1 root root 18146 Oct 28 2025 Makefile.common -rw-r--r-- 1 root root 7022 Oct 28 2025 Makefile.config.in -rw-r--r-- 1 root root 1585 Oct 28 2025 Makefile.config_if_required -rw-r--r-- 1 root root 5685 Oct 28 2025 Makefile.cross -rw-r--r-- 1 root root 2530 Oct 28 2025 Makefile.dev -rw-r--r-- 1 root root 11453 Oct 28 2025 Makefile.menhir -rw-r--r-- 1 root root 7773 Oct 28 2025 README.adoc -rw-r--r-- 1 root root 14095 Oct 28 2025 README.win32.adoc -rw-r--r-- 1 root root 595 Oct 28 2025 VERSION -rw-r--r-- 1 root root 21108 Oct 28 2025 aclocal.m4 drwxr-xr-x 4 root root 4096 Oct 28 2025 api_docgen -rw-r--r-- 1 root root 2299 Oct 28 2025 appveyor.yml drwxr-xr-x 7 root root 4096 Oct 28 2025 asmcomp drwxr-xr-x 3 root root 66 Oct 28 2025 boot drwxr-xr-x 2 root root 4096 Oct 28 2025 build-aux drwxr-xr-x 2 root root 4096 Oct 28 2025 bytecomp drwxr-xr-x 2 root root 29 Oct 28 2025 compilerlibs -rwxr-xr-x 1 root root 744110 Oct 28 2025 configure -rw-r--r-- 1 root root 103101 Oct 28 2025 configure.ac drwxr-xr-x 2 root root 4096 Oct 28 2025 debugger drwxr-xr-x 2 root root 4096 Oct 28 2025 driver -rw-r--r-- 1 root root 7844 Oct 28 2025 dune -rw-r--r-- 1 root root 76 Oct 28 2025 dune-project drwxr-xr-x 2 root root 4096 Oct 28 2025 file_formats drwxr-xr-x 2 root root 10 Oct 28 2025 flexdll drwxr-xr-x 2 root root 4096 Oct 28 2025 lambda drwxr-xr-x 2 root root 4096 Oct 28 2025 lex drwxr-xr-x 2 root root 4096 Oct 28 2025 man drwxr-xr-x 6 root root 152 Oct 28 2025 manual drwxr-xr-x 4 root root 4096 Oct 28 2025 middle_end -rw-r--r-- 1 root root 98 Oct 28 2025 ocaml-variants.install -rw-r--r-- 1 root root 5420 Oct 28 2025 ocaml-variants.opam drwxr-xr-x 2 root root 4096 Oct 28 2025 ocamldoc drwxr-xr-x 2 root root 4096 Oct 28 2025 ocamltest drwxr-xr-x 7 root root 165 Oct 28 2025 otherlibs drwxr-xr-x 2 root root 4096 Oct 28 2025 parsing drwxr-xr-x 3 root root 153 Oct 28 2025 release-info drwxr-xr-x 3 root root 4096 Oct 28 2025 runtime drwxr-xr-x 4 root root 8192 Oct 28 2025 stdlib drwxr-xr-x 6 root root 149 Oct 28 2025 testsuite drwxr-xr-x 4 root root 4096 Oct 28 2025 tools drwxr-xr-x 4 root root 4096 Oct 28 2025 toplevel drwxr-xr-x 2 root root 4096 Oct 28 2025 typing drwxr-xr-x 2 root root 4096 Oct 28 2025 utils drwxr-xr-x 2 root root 10 Oct 28 2025 winpthreads drwxr-xr-x 2 root root 4096 Oct 28 2025 yacc ==== HACKING.adoc addrmap.c afl.c alloc.c amd64.S amd64nt.asm arm64.S array.c backtrace.c backtrace_byt.c backtrace_nat.c bigarray.c blake2.c callback.c caml clambda_checks.c codefrag.c compare.c custom.c debugger.c domain.c dune dynlink.c dynlink_nat.c extern.c fail.c fail_byt.c fail_nat.c fiber.c finalise.c fix_code.c floats.c frame_descriptors.c gc_ctrl.c gc_stats.c gen_primitives.sh gen_primsc.sh globroots.c hash.c instrtrace.c intern.c interp.c ints.c io.c lexing.c lf_skiplist.c main.c major_gc.c md5.c memory.c ==== gc.h gc_ctrl.h gc_stats.h major_gc.h minor_gc.h shared_heap.h [stdout] total 2300 drwxr-xr-x 1 root root 26 Oct 28 2025 . drwxr-xr-x 1 root root 27 Oct 28 2025 .. -rw-r--r-- 1 root root 319736 Oct 28 2025 .depend -rw-r--r-- 1 root root 980 Oct 28 2025 .depend.menhir -rw-r--r-- 1 root root 185 Oct 28 2025 .editorconfig -rw-r--r-- 1 root root 10409 Oct 28 2025 .gitattributes drwxr-xr-x 4 root root 57 Oct 28 2025 .github -rw-r--r-- 1 root root 7750 Oct 28 2025 .gitignore -rw-r--r-- 1 root root 208 Oct 28 2025 .gitmodules -rw-r--r-- 1 root root 5944 Oct 28 2025 .mailmap -rw-r--r-- 1 root root 32 Oct 28 2025 .ocp-indent -rw-r--r-- 1 root root 3972 Oct 28 2025 BOOTSTRAP.adoc -rw-r--r-- 1 root root 312 Oct 28 2025 CODE_OF_CONDUCT.md -rw-r--r-- 1 root root 19923 Oct 28 2025 CONTRIBUTING.md -rw-r--r-- 1 root root 680162 Oct 28 2025 Changes -rw-r--r-- 1 root root 33712 Oct 28 2025 HACKING.adoc -rw-r--r-- 1 root root 9997 Oct 28 2025 INSTALL.adoc -rw-r--r-- 1 root root 27179 Oct 28 2025 LICENSE -rw-r--r-- 1 root root 97687 Oct 28 2025 Makefile -rw-r--r-- 1 root root 3624 Oct 28 2025 Makefile.best_binaries -rw-r--r-- 1 root root 6986 Oct 28 2025 Makefile.build_config.in -rw-r--r-- 1 root root 18146 Oct 28 2025 Makefile.common -rw-r--r-- 1 root root 7022 Oct 28 2025 Makefile.config.in -rw-r--r-- 1 root root 1585 Oct 28 2025 Makefile.config_if_required -rw-r--r-- 1 root root 5685 Oct 28 2025 Makefile.cross -rw-r--r-- 1 root root 2530 Oct 28 2025 Makefile.dev -rw-r--r-- 1 root root 11453 Oct 28 2025 Makefile.menhir -rw-r--r-- 1 root root 7773 Oct 28 2025 README.adoc -rw-r--r-- 1 root root 14095 Oct 28 2025 README.win32.adoc -rw-r--r-- 1 root root 595 Oct 28 2025 VERSION -rw-r--r-- 1 root root 21108 Oct 28 2025 acloc
{
"command": "ls runtime/*.c | xargs grep -l -iE \"freelist|sweep|run.?length|compress\" 2>/dev/null; echo \"====\"; ls -la runtime/caml/*.h | head -40",
"description": "Find GC-related source files"
}runtime/blake2.c
runtime/domain.c
runtime/extern.c
runtime/gc_ctrl.c
runtime/intern.c
runtime/ints.c
runtime/major_gc.c
runtime/shared_heap.c
runtime/startup_aux.c
runtime/weak.c
runtime/zstd.c
====
-rw-r--r-- 1 root root 2814 Oct 28 2025 runtime/caml/address_class.h
-rw-r--r-- 1 root root 3213 Oct 28 2025 runtime/caml/addrmap.h
-rw-r--r-- 1 root root 4277 Oct 28 2025 runtime/caml/alloc.h
-rw-r--r-- 1 root root 3172 Oct 28 2025 runtime/caml/asm.h
-rw-r--r-- 1 root root 6237 Oct 28 2025 runtime/caml/backtrace.h
-rw-r--r-- 1 root root 4851 Oct 28 2025 runtime/caml/backtrace_prim.h
-rw-r--r-- 1 root root 4928 Oct 28 2025 runtime/caml/bigarray.h
-rw-r--r-- 1 root root 1796 Oct 28 2025 runtime/caml/blake2.h
-rw-r--r-- 1 root root 3452 Oct 28 2025 runtime/caml/callback.h
-rw-r--r-- 1 root root 2975 Oct 28 2025 runtime/caml/camlatomic.h
-rw-r--r-- 1 root root 4122 Oct 28 2025 runtime/caml/codefrag.h
-rw-r--r-- 1 root root 1246 Oct 28 2025 runtime/caml/compare.h
-rw-r--r-- 1 root root 1602 Oct 28 2025 runtime/caml/compatibility.h
-rw-r--r-- 1 root root 8557 Oct 28 2025 runtime/caml/config.h
-rw-r--r-- 1 root root 3786 Oct 28 2025 runtime/caml/custom.h
-rw-r--r-- 1 root root 5556 Oct 28 2025 runtime/caml/debugger.h
-rw-r--r-- 1 root root 10286 Oct 28 2025 runtime/caml/domain.h
-rw-r--r-- 1 root root 2867 Oct 28 2025 runtime/caml/domain_state.h
-rw-r--r-- 1 root root 2318 Oct 28 2025 runtime/caml/dynlink.h
-rw-r--r-- 1 root root 6709 Oct 28 2025 runtime/caml/fail.h
-rw-r--r-- 1 root root 12607 Oct 28 2025 runtime/caml/fiber.h
-rw-r--r-- 1 root root 3083 Oct 28 2025 runtime/caml/finalise.h
-rw-r--r-- 1 root root 1848 Oct 28 2025 runtime/caml/fix_code.h
-rw-r--r-- 1 root root 6052 Oct 28 2025 runtime/caml/frame_descriptors.h
-rw-r--r-- 1 root root 1726 Oct 28 2025 runtime/caml/gc.h
-rw-r--r-- 1 root root 2328 Oct 28 2025 runtime/caml/gc_ctrl.h
-rw-r--r-- 1 root root 3405 Oct 28 2025 runtime/caml/gc_stats.h
-rw-r--r-- 1 root root 1515 Oct 28 2025 runtime/caml/globroots.h
-rw-r--r-- 1 root root 1675 Oct 28 2025 runtime/caml/hash.h
-rw-r--r-- 1 root root 1519 Oct 28 2025 runtime/caml/hooks.h
-rw-r--r-- 1 root root 1640 Oct 28 2025 runtime/caml/instrtrace.h
-rw-r--r-- 1 root root 2902 Oct 28 2025 runtime/caml/instruct.h
-rw-r--r-- 1 root root 1604 Oct 28 2025 runtime/caml/interp.h
-rw-r--r-- 1 root root 8674 Oct 28 2025 runtime/caml/intext.h
-rw-r--r-- 1 root root 6045 Oct 28 2025 runtime/caml/io.h
-rw-r--r-- 1 root root 5999 Oct 28 2025 runtime/caml/lf_skiplist.h
-rw-r--r-- 1 root root 2871 Oct 28 2025 runtime/caml/major_gc.h
-rw-r--r-- 1 root root 1883 Oct 28 2025 runtime/caml/md5.h
-rw-r--r-- 1 root root 23438 Oct 28 2025 runtime/caml/memory.h
-rw-r--r-- 1 root root 5639 Oct 28 2025 runtime/caml/memprof.h
[stdout]
runtime/blake2.c
runtime/domain.c
runtime/extern.c
runtime/gc_ctrl.c
runtime/intern.c
runtime/ints.c
runtime/major_gc.c
runtime/shared_heap.c
runtime/startup_aux.c
runtime/weak.c
runtime/zstd.c
====
-rw-r--r-- 1 root root 2814 Oct 28 2025 runtime/caml/address_class.h
-rw-r--r-- 1 root root 3213 Oct 28 2025 runtime/caml/addrmap.h
-rw-r--r-- 1 root root 4277 Oct 28 2025 runtime/caml/alloc.h
-rw-r--r-- 1 root root 3172 Oct 28 2025 runtime/caml/asm.h
-rw-r--r-- 1 root root 6237 Oct 28 2025 runtime/caml/backtrace.h
-rw-r--r-- 1 root root 4851 Oct 28 2025 runtime/caml/backtrace_prim.h
-rw-r--r-- 1 root root 4928 Oct 28 2025 runtime/caml/bigarray.h
-rw-r--r-- 1 root root 1796 Oct 28 2025 runtime/caml/blake2.h
-rw-r--r-- 1 root root 3452 Oct 28 2025 runtime/caml/callback.h
-rw-r--r-- 1 root root 2975 Oct 28 2025 runtime/caml/camlatomic.h
-rw-r--r-- 1 root root 4122 Oct 28 2025 runtime/caml/codefrag.h
-rw-r--r-- 1 root root 1246 Oct 28 2025 runtime/caml/compare.h
-rw-r--r-- 1 root root 1602 Oct 28 2025 runtime/caml/compatibility.h
-rw-r--r-- 1 root root 8557 Oct 28 2025 runtime/caml/config.h
-rw-r--r-- 1 root root 3786 Oct 28 2025 runtime/caml/custom.h
-rw-r--r-- 1 root root 5556 Oct 28 2025 runtime/caml/debugger.h
-rw-r--r-- 1 root root 10286 Oct 28 2025 runtime/caml/domain.h
-rw-r--r-- 1 root root 2867 Oct 28 2025 runtime/caml/domain_state.h
-rw-r--r-- 1 root root 2318 Oct 28 2025 runtime/caml/dynlink.h
-rw-r--r-- 1 root root 6709 Oct 28 2025 runtime/caml/fail.h
-rw-r--r-- 1 root root 12607 Oct 28 2025 runtime/caml/fiber.h
-rw-r--r-- 1 root root 3083 Oct 28 2025 runtime/caml/finalise.h
-rw-r--r-- 1 root root 1848 Oct 28 2025 runtime/caml/fix_code.h
-rw-r--r-- 1 root root 6052 Oct 28 2025 runtime/caml/frame_descriptors.h
-rw-r--r-- 1 root root 1726 Oct 28 2025 runtime/caml/gc.h
-rw-r--r-- 1 root root 2328 Oct 28 2025 runtime/caml/gc_ctrl.h
-rw-r--r-- 1 root root 3405 Oct 28 2025 runtime/caml/gc_stats.h
-rw-r--r-- 1 root root 1515 Oct 28 2025 runtime/caml/globroots.h
-rw-r--r-- 1 root root 1675 Oct 28 2025 runtime/caml/hash.h
-rw-r--r-- 1 root root 1519 Oct 28 2025 runtime/caml/hooks.h
-rw-r--r-- 1 root root 1640 Oct 28 2025 runtime/caml/instrtrace.h
-rw-r--r-- 1 root root 2902 Oct 28 2025 runtime/caml/instruct.h
-rw-r--r-- 1 root root 1604 Oct 28 2025 runtime/caml/interp.h
-rw-r--r-- 1 root root 8674 Oct 28 2025 runtime/caml/intext.h
-rw-r--r-- 1 root root 6045 Oct 28 2025 runtime/caml/io.h
-rw-r--r-- 1 root root 5999 Oct 28 2025 runtime/caml/lf_skiplist.h
-rw-r--r-- 1 root root 2871 Oct 28 2025 runtime/caml/major_gc.h
-rw-r--r-- 1 root root 1883 Oct 28 2025 runtime/caml/md5.h
-rw-r--r-- 1 root root 23438 Oct 28 2025 runtime/caml/memory.h
-rw-r--r-- 1 root root 5639 Oct 28 2025 runtime/caml/memprof.h
[metadata] {"noOutputExpected": false}{
"command": "grep -n -iE \"run.?length|rle|compress|freelist|free_list|sweep\" runtime/shared_heap.c runtime/caml/shared_heap.h runtime/major_gc.c runtime/caml/major_gc.h 2>/dev/null | head -80",
"description": "Search for run-length/free-list code"
}runtime/caml/shared_heap.h:106:intnat caml_sweep(struct caml_heap_state*, intnat);
runtime/caml/shared_heap.h:124:void caml_finalise_freelist(void);
runtime/caml/major_gc.h:22: Phase_sweep_and_mark_main,
runtime/caml/major_gc.h:24: Phase_sweep_ephe
runtime/caml/major_gc.h:36:void caml_finish_sweeping(void);
runtime/shared_heap.c:84:} pool_freelist = {
runtime/shared_heap.c:103: sizeclass next_to_sweep;
runtime/shared_heap.c:115:/* You need to hold the [pool_freelist] lock to call these functions. */
runtime/shared_heap.c:131: heap->next_to_sweep = 0;
runtime/shared_heap.c:158: caml_plat_lock_blocking(&pool_freelist.lock);
runtime/shared_heap.c:162: &pool_freelist.global_avail_pools[i], NULL);
runtime/shared_heap.c:166: &pool_freelist.global_full_pools[i], NULL);
runtime/shared_heap.c:176: a->next = pool_freelist.global_large;
runtime/shared_heap.c:177: pool_freelist.global_large = a;
runtime/shared_heap.c:181: caml_plat_unlock(&pool_freelist.lock);
runtime/shared_heap.c:188: caml_plat_lock_blocking(&pool_freelist.lock);
runtime/shared_heap.c:191: (pool**)&pool_freelist.global_avail_pools[i],
runtime/shared_heap.c:195: (pool**)&pool_freelist.global_full_pools[i],
runtime/shared_heap.c:199: while (pool_freelist.global_large) {
runtime/shared_heap.c:200: large_alloc* a = pool_freelist.global_large;
runtime/shared_heap.c:201: pool_freelist.global_large = a->next;
runtime/shared_heap.c:210: caml_plat_unlock(&pool_freelist.lock);
runtime/shared_heap.c:214: local->next_to_sweep = 0;
runtime/shared_heap.c:234:/* Allocating and deallocating pools from the global freelist. */
runtime/shared_heap.c:239: caml_plat_lock_blocking(&pool_freelist.lock);
runtime/shared_heap.c:240: if (!pool_freelist.free) {
runtime/shared_heap.c:244: CAMLassert(pool_freelist.free == NULL);
runtime/shared_heap.c:247: r->next = pool_freelist.free;
runtime/shared_heap.c:249: pool_freelist.free = r;
runtime/shared_heap.c:252: r = pool_freelist.free;
runtime/shared_heap.c:254: pool_freelist.free = r->next;
runtime/shared_heap.c:255: caml_plat_unlock(&pool_freelist.lock);
runtime/shared_heap.c:270: caml_plat_lock_blocking(&pool_freelist.lock);
runtime/shared_heap.c:271: pool->next = pool_freelist.free;
runtime/shared_heap.c:272: pool_freelist.free = pool;
runtime/shared_heap.c:273: caml_plat_unlock(&pool_freelist.lock);
runtime/shared_heap.c:310:/* Initialize a pool and its object freelist */
runtime/shared_heap.c:336:static intnat pool_sweep(struct caml_heap_state* local,
runtime/shared_heap.c:342:/* Adopt pool from the pool_freelist avail and full pools
runtime/shared_heap.c:350: if( !atomic_load_relaxed(&pool_freelist.global_avail_pools[sz]) &&
runtime/shared_heap.c:351: !atomic_load_relaxed(&pool_freelist.global_full_pools[sz]) )
runtime/shared_heap.c:355: caml_plat_lock_blocking(&pool_freelist.lock);
runtime/shared_heap.c:356: if( atomic_load_relaxed(&pool_freelist.global_avail_pools[sz]) ) {
runtime/shared_heap.c:357: r = atomic_load_relaxed(&pool_freelist.global_avail_pools[sz]);
runtime/shared_heap.c:360: atomic_store_relaxed(&pool_freelist.global_avail_pools[sz], r->next);
runtime/shared_heap.c:380: try our luck sweeping it later on */
runtime/shared_heap.c:382: r = atomic_load_relaxed(&pool_freelist.global_full_pools[sz]);
runtime/shared_heap.c:385: atomic_store_relaxed(&pool_freelist.global_full_pools[sz], r->next);
runtime/shared_heap.c:396: caml_plat_unlock(&pool_freelist.lock);
runtime/shared_heap.c:400: pool_sweep(local, &local->full_pools[sz], sz, 0);
runtime/shared_heap.c:416: /* Otherwise, try to sweep until we find one */
runtime/shared_heap.c:419: pool_sweep(local, &local->unswept_avail_pools[sz], sz, 0);
runtime/shared_heap.c:542:/* Sweeping of the major heap shared pools */
runtime/shared_heap.c:543:static intnat pool_sweep(struct caml_heap_state* local, pool** plist,
runtime/shared_heap.c:587: /* add to freelist. This could be optimised, we don't need
runtime/shared_heap.c:637: the pool (which indicates the start of the freelist) */
runtime/shared_heap.c:647: freelist */
runtime/shared_heap.c:678:static intnat large_alloc_sweep(struct caml_heap_state* local) {
runtime/shared_heap.c:730:intnat caml_sweep(struct caml_heap_state* local, intnat work) {
runtime/shared_heap.c:731: /* Sweep local pools */
runtime/shared_heap.c:732: while (work > 0 && local->next_to_sweep < NUM_SIZECLASSES) {
runtime/shared_heap.c:733: sizeclass sz = local->next_to_sweep;
runtime/shared_heap.c:734: intnat full_sweep_work = 0;
runtime/shared_heap.c:735: intnat avail_sweep_work =
runtime/shared_heap.c:736: pool_sweep(local, &local->unswept_avail_pools[sz], sz, 1);
runtime/shared_heap.c:737: work -= avail_sweep_work;
runtime/shared_heap.c:740: full_sweep_work = pool_sweep(local,
runtime/shared_heap.c:744: work -= full_sweep_work;
runtime/shared_heap.c:747: if(full_sweep_work+avail_sweep_work == 0) {
runtime/shared_heap.c:748: local->next_to_sweep++;
runtime/shared_heap.c:752: /* Sweep global pools */
runtime/shared_heap.c:754: work -= large_alloc_sweep(local);
runtime/shared_heap.c:758: /* sweeping is complete, check everything worked */
runtime/shared_heap.c:841:/* Heap and freelist stats */
runtime/shared_heap.c:844: You need to hold the [pool_freelist] lock. */
runtime/shared_heap.c:846: caml_accum_heap_stats(&pool_freelist.stats, &heap->stats);
runtime/shared_heap.c:852: You need to hold the [pool_freelist] lock. */
runtime/shared_heap.c:860: caml_remove_heap_stats(&pool_freelist.stats, &pool_stats);
runtime/shared_heap.c:864: You need to hold the [pool_freelist] lock. */
runtime/shared_heap.c:866: caml_accum_heap_stats(&adopter->stats, &pool_freelist.stats);
[stdout]
runtime/caml/shared_heap.h:106:intnat caml_sweep(struct caml_heap_state*, intnat);
runtime/caml/shared_heap.h:124:void caml_finalise_free{
"command": "wc -l runtime/shared_heap.c runtime/major_gc.c runtime/caml/shared_heap.h && echo \"====\" && ls -la --time-style=full-iso runtime/*.c runtime/caml/*.h | sort -k6 | tail -30",
"description": "File sizes and modification times"
}1683 runtime/shared_heap.c
2231 runtime/major_gc.c
133 runtime/caml/shared_heap.h
4047 total
====
-rw-r--r-- 1 root root 13792 2025-10-28 22:07:06.000000000 +0000 runtime/str.c
-rw-r--r-- 1 root root 20622 2025-10-28 22:07:06.000000000 +0000 runtime/sys.c
-rw-r--r-- 1 root root 13154 2025-10-28 22:07:06.000000000 +0000 runtime/unix.c
-rw-r--r-- 1 root root 39093 2025-10-28 22:07:06.000000000 +0000 runtime/win32.c
-rw-r--r-- 1 root root 4066 2025-10-28 22:07:06.000000000 +0000 runtime/zstd.c
-rw-r--r-- 1 root root 25784 2025-10-28 22:07:07.000000000 +0000 runtime/array.c
-rw-r--r-- 1 root root 10286 2025-10-28 22:07:07.000000000 +0000 runtime/caml/domain.h
-rw-r--r-- 1 root root 6709 2025-10-28 22:07:07.000000000 +0000 runtime/caml/fail.h
-rw-r--r-- 1 root root 12607 2025-10-28 22:07:07.000000000 +0000 runtime/caml/fiber.h
-rw-r--r-- 1 root root 2871 2025-10-28 22:07:07.000000000 +0000 runtime/caml/major_gc.h
-rw-r--r-- 1 root root 5602 2025-10-28 22:07:07.000000000 +0000 runtime/caml/minor_gc.h
-rw-r--r-- 1 root root 26605 2025-10-28 22:07:07.000000000 +0000 runtime/caml/misc.h
-rw-r--r-- 1 root root 19228 2025-10-28 22:07:07.000000000 +0000 runtime/caml/mlvalues.h
-rw-r--r-- 1 root root 12102 2025-10-28 22:07:07.000000000 +0000 runtime/caml/runtime_events.h
-rw-r--r-- 1 root root 4376 2025-10-28 22:07:07.000000000 +0000 runtime/caml/shared_heap.h
-rw-r--r-- 1 root root 1807 2025-10-28 22:07:07.000000000 +0000 runtime/caml/sizeclasses.h
-rw-r--r-- 1 root root 1985 2025-10-28 22:07:07.000000000 +0000 runtime/caml/sync.h
-rw-r--r-- 1 root root 81558 2025-10-28 22:07:07.000000000 +0000 runtime/domain.c
-rw-r--r-- 1 root root 21039 2025-10-28 22:07:07.000000000 +0000 runtime/fiber.c
-rw-r--r-- 1 root root 17168 2025-10-28 22:07:07.000000000 +0000 runtime/gc_ctrl.c
-rw-r--r-- 1 root root 37347 2025-10-28 22:07:07.000000000 +0000 runtime/intern.c
-rw-r--r-- 1 root root 78117 2025-10-28 22:07:07.000000000 +0000 runtime/major_gc.c
-rw-r--r-- 1 root root 26172 2025-10-28 22:07:07.000000000 +0000 runtime/memory.c
-rw-r--r-- 1 root root 81969 2025-10-28 22:07:07.000000000 +0000 runtime/memprof.c
-rw-r--r-- 1 root root 37463 2025-10-28 22:07:07.000000000 +0000 runtime/minor_gc.c
-rw-r--r-- 1 root root 54981 2025-10-28 22:07:07.000000000 +0000 runtime/shared_heap.c
-rw-r--r-- 1 root root 22168 2025-10-28 22:07:07.000000000 +0000 runtime/signals.c
-rw-r--r-- 1 root root 6034 2025-10-28 22:07:07.000000000 +0000 runtime/sync.c
-rw-r--r-- 1 root root 20562 2025-10-28 22:07:07.000000000 +0000 runtime/tsan.c
-rw-r--r-- 1 root root 15482 2025-10-28 22:07:07.000000000 +0000 runtime/weak.c
[stdout]
1683 runtime/shared_heap.c
2231 runtime/major_gc.c
133 runtime/caml/shared_heap.h
4047 total
====
-rw-r--r-- 1 root root 13792 2025-10-28 22:07:06.000000000 +0000 runtime/str.c
-rw-r--r-- 1 root root 20622 2025-10-28 22:07:06.000000000 +0000 runtime/sys.c
-rw-r--r-- 1 root root 13154 2025-10-28 22:07:06.000000000 +0000 runtime/unix.c
-rw-r--r-- 1 root root 39093 2025-10-28 22:07:06.000000000 +0000 runtime/win32.c
-rw-r--r-- 1 root root 4066 2025-10-28 22:07:06.000000000 +0000 runtime/zstd.c
-rw-r--r-- 1 root root 25784 2025-10-28 22:07:07.000000000 +0000 runtime/array.c
-rw-r--r-- 1 root root 10286 2025-10-28 22:07:07.000000000 +0000 runtime/caml/domain.h
-rw-r--r-- 1 root root 6709 2025-10-28 22:07:07.000000000 +0000 runtime/caml/fail.h
-rw-r--r-- 1 root root 12607 2025-10-28 22:07:07.000000000 +0000 runtime/caml/fiber.h
-rw-r--r-- 1 root root 2871 2025-10-28 22:07:07.000000000 +0000 runtime/caml/major_gc.h
-rw-r--r-- 1 root root 5602 2025-10-28 22:07:07.000000000 +0000 runtime/caml/minor_gc.h
-rw-r--r-- 1 root root 26605 2025-10-28 22:07:07.000000000 +0000 runtime/caml/misc.h
-rw-r--r-- 1 root root 19228 2025-10-28 22:07:07.000000000 +0000 runtime/caml/mlvalues.h
-rw-r--r-- 1 root root 12102 2025-10-28 22:07:07.000000000 +0000 runtime/caml/runtime_events.h
-rw-r--r-- 1 root root 4376 2025-10-28 22:07:07.000000000 +0000 runtime/caml/shared_heap.h
-rw-r--r-- 1 root root 1807 2025-10-28 22:07:07.000000000 +0000 runtime/caml/sizeclasses.h
-rw-r--r-- 1 root root 1985 2025-10-28 22:07:07.000000000 +0000 runtime/caml/sync.h
-rw-r--r-- 1 root root 81558 2025-10-28 22:07:07.000000000 +0000 runtime/domain.c
-rw-r--r-- 1 root root 21039 2025-10-28 22:07:07.000000000 +0000 runtime/fiber.c
-rw-r--r-- 1 root root 17168 2025-10-28 22:07:07.000000000 +0000 runtime/gc_ctrl.c
-rw-r--r-- 1 root root 37347 2025-10-28 22:07:07.000000000 +0000 runtime/intern.c
-rw-r--r-- 1 root root 78117 2025-10-28 22:07:07.000000000 +0000 runtime/major_gc.c
-rw-r--r-- 1 root root 26172 2025-10-28 22:07:07.000000000 +0000 runtime/memory.c
-rw-r--r-- 1 root root 81969 2025-10-28 22:07:07.000000000 +0000 runtime/memprof.c
-rw-r--r-- 1 root root 37463 2025-10-28 22:07:07.000000000 +0000 runtime/minor_gc.c
-rw-r--r-- 1 root root 54981 2025-10-28 22:07:07.000000000 +0000 runtime/shared_heap.c
-rw-r--r-- 1 root root 22168 2025-10-28 22:07:07.000000000 +0000 runtime/signals.c
-rw-r--r-- 1 root root 6034 2025-10-28 22:07:07.000000000 +0000 runtime/sync.c
-rw-r--r-- 1 root root 20562 2025-10-28 22:07:07.000000000 +0000 runtime/tsan.c
-rw-r--r-- 1 root root 15482 2025-10-28 22:07:07.000000000 +0000 runtime/weak.c
[metadata] {"noOutputExpected": false}{
"file_path": "/app/ocaml/runtime/shared_heap.c",
"offset": 1,
"limit": 350
}1 /**************************************************************************/
2 /* */
3 /* OCaml */
4 /* */
5 /* KC Sivaramakrishnan, Indian Institute of Technology, Madras */
6 /* Stephen Dolan, University of Cambridge */
7 /* */
8 /* Copyright 2015 Indian Institute of Technology, Madras */
9 /* Copyright 2015 University of Cambridge */
10 /* */
11 /* All rights reserved. This file is distributed under the terms of */
12 /* the GNU Lesser General Public License version 2.1, with the */
13 /* special exception on linking described in the file LICENSE. */
14 /* */
15 /**************************************************************************/
16 #define CAML_INTERNALS
17
18 #include <stdbool.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <assert.h>
22 #include "caml/addrmap.h"
23 #include "caml/custom.h"
24 #include "caml/runtime_events.h"
25 #include "caml/fail.h"
26 #include "caml/fiber.h" /* for verification */
27 #include "caml/gc.h"
28 #include "caml/globroots.h"
29 #include "caml/major_gc.h"
30 #include "caml/memory.h"
31 #include "caml/memprof.h"
32 #include "caml/mlvalues.h"
33 #include "caml/platform.h"
34 #include "caml/roots.h"
35 #include "caml/shared_heap.h"
36 #include "caml/sizeclasses.h"
37 #include "caml/startup_aux.h"
38 #include "caml/weak.h"
39
40 CAMLexport atomic_uintnat caml_compactions_count;
41
42 typedef unsigned int sizeclass;
43
44 /* Initial MARKED, UNMARKED, and GARBAGE values; any permutation would work */
45 struct global_heap_state caml_global_heap_state = {
46 0 << HEADER_COLOR_SHIFT,
47 1 << HEADER_COLOR_SHIFT,
48 2 << HEADER_COLOR_SHIFT,
49 };
50
51 typedef struct pool {
52 struct pool* next;
53 value* next_obj;
54 caml_domain_state* owner;
55 sizeclass sz;
56 } pool;
57 static_assert(sizeof(pool) == Bsize_wsize(POOL_HEADER_WSIZE), "");
58 #define POOL_SLAB_WOFFSET(sz) (POOL_HEADER_WSIZE + wastage_sizeclass[sz])
59 #define POOL_FIRST_BLOCK(p, sz) ((header_t*)(p) + POOL_SLAB_WOFFSET(sz))
60 #define POOL_END(p) ((header_t*)(p) + POOL_WSIZE)
61
62
63 #define POOL_BLOCK_FREE_HD(hd) \
64 (Tag_hd(hd) == No_scan_tag && (Color_hd(hd) == NOT_MARKABLE))
65 #define POOL_BLOCK_FREE_HP(p) (POOL_BLOCK_FREE_HD(Hd_hp(p)))
66 #define POOL_FREE_HEADER(wosize) Make_header(wosize, No_scan_tag, NOT_MARKABLE)
67
68 typedef struct large_alloc {
69 caml_domain_state* owner;
70 struct large_alloc* next;
71 } large_alloc;
72 static_assert(sizeof(large_alloc) % sizeof(value) == 0, "");
73 #define LARGE_ALLOC_HEADER_SZ sizeof(large_alloc)
74
75 static struct {
76 caml_plat_mutex lock;
77 pool* free;
78
79 /* these only contain swept memory of terminated domains*/
80 struct heap_stats stats;
81 _Atomic(pool*) global_avail_pools[NUM_SIZECLASSES];
82 _Atomic(pool*) global_full_pools[NUM_SIZECLASSES];
83 large_alloc* global_large;
84 } pool_freelist = {
85 CAML_PLAT_MUTEX_INITIALIZER,
86 NULL,
87 { 0, },
88 { NULL, },
89 { NULL, },
90 NULL
91 };
92
93 /* readable and writable only by the current thread */
94 struct caml_heap_state {
95 pool* avail_pools[NUM_SIZECLASSES];
96 pool* full_pools[NUM_SIZECLASSES];
97 pool* unswept_avail_pools[NUM_SIZECLASSES];
98 pool* unswept_full_pools[NUM_SIZECLASSES];
99
100 large_alloc* swept_large;
101 large_alloc* unswept_large;
102
103 sizeclass next_to_sweep;
104
105 caml_domain_state* owner;
106
107 struct heap_stats stats;
108 };
109
110 struct compact_pool_stat {
111 int free_blocks;
112 int live_blocks;
113 };
114
115 /* You need to hold the [pool_freelist] lock to call these functions. */
116 static void orphan_heap_stats_with_lock(struct caml_heap_state *);
117 static void adopt_pool_stats_with_lock(struct caml_heap_state *,
118 pool *, sizeclass);
119 static void adopt_all_pool_stats_with_lock(struct caml_heap_state *adopter);
120
121
122 struct caml_heap_state* caml_init_shared_heap (void) {
123 struct caml_heap_state* heap;
124
125 heap = caml_stat_alloc_noexc(sizeof(struct caml_heap_state));
126 if(heap != NULL) {
127 for (int i = 0; i<NUM_SIZECLASSES; i++) {
128 heap->avail_pools[i] = heap->full_pools[i] =
129 heap->unswept_avail_pools[i] = heap->unswept_full_pools[i] = 0;
130 }
131 heap->next_to_sweep = 0;
132 heap->swept_large = NULL;
133 heap->unswept_large = NULL;
134 heap->owner = Caml_state;
135
136 memset(&heap->stats, 0, sizeof(heap->stats));
137 }
138 return heap;
139 }
140
141 static int move_all_pools(pool** src, _Atomic(pool*)* dst,
142 caml_domain_state* new_owner) {
143 int count = 0;
144 while (*src) {
145 pool* p = *src;
146 *src = p->next;
147 p->owner = new_owner;
148 p->next = *dst;
149 *dst = p;
150 count++;
151 }
152 return count;
153 }
154
155 void caml_orphan_shared_heap(struct caml_heap_state* heap) {
156 int released = 0, released_large = 0;
157
158 caml_plat_lock_blocking(&pool_freelist.lock);
159 for (int i = 0; i < NUM_SIZECLASSES; i++) {
160 released +=
161 move_all_pools(&heap->avail_pools[i],
162 &pool_freelist.global_avail_pools[i], NULL);
163
164 released +=
165 move_all_pools(&heap->full_pools[i],
166 &pool_freelist.global_full_pools[i], NULL);
167
168 /* should be swept by now */
169 CAMLassert(!heap->unswept_avail_pools[i]);
170 CAMLassert(!{
"file_path": "/app/ocaml/runtime/caml/sizeclasses.h"
}1 /* This file is generated by tools/gen_sizeclasses.ml */
2 #define POOL_WSIZE 4096
3 #define POOL_HEADER_WSIZE 4
4 #define SIZECLASS_MAX 128
5 #define NUM_SIZECLASSES 32
6
7 /* The largest size for this size class.
8 (A gap is left after smaller objects) */
9 static const unsigned int wsize_sizeclass[NUM_SIZECLASSES] =
10 { /* 0:*/ 1, 2, 3, 4, 5,
11 /* 5:*/ 6, 7, 8, 10, 12,
12 /* 10:*/ 14, 16, 17, 19, 22,
13 /* 15:*/ 25, 28, 32, 33, 37,
14 /* 20:*/ 42, 47, 53, 59, 65,
15 /* 25:*/ 73, 81, 89, 99, 108,
16 /* 30:*/ 118, 128 };
17
18 /* The number of padding words to use, at the beginning of a pool
19 of this sizeclass, to reach exactly POOL_WSIZE words. */
20 static const unsigned char wastage_sizeclass[NUM_SIZECLASSES] =
21 { /* 0:*/ 0, 0, 0, 0, 2,
22 /* 5:*/ 0, 4, 4, 2, 0,
23 /* 10:*/ 4, 12, 12, 7, 0,
24 /* 15:*/ 17, 4, 28, 0, 22,
25 /* 20:*/ 18, 3, 11, 21, 62,
26 /* 25:*/ 4, 42, 87, 33, 96,
27 /* 30:*/ 80, 124 };
28
29 /* Map from (positive) object sizes to size classes. */
30 static const unsigned char sizeclass_wsize[SIZECLASS_MAX + 1] =
31 { /* 0:*/ 255, 0, 1, 2, 3,
32 /* 5:*/ 4, 5, 6, 7, 8,
33 /* 10:*/ 8, 9, 9, 10, 10,
34 /* 15:*/ 11, 11, 12, 13, 13,
35 /* 20:*/ 14, 14, 14, 15, 15,
36 /* 25:*/ 15, 16, 16, 16, 17,
37 /* 30:*/ 17, 17, 17, 18, 19,
38 /* 35:*/ 19, 19, 19, 20, 20,
39 /* 40:*/ 20, 20, 20, 21, 21,
40 /* 45:*/ 21, 21, 21, 22, 22,
41 /* 50:*/ 22, 22, 22, 22, 23,
42 /* 55:*/ 23, 23, 23, 23, 23,
43 /* 60:*/ 24, 24, 24, 24, 24,
44 /* 65:*/ 24, 25, 25, 25, 25,
45 /* 70:*/ 25, 25, 25, 25, 26,
46 /* 75:*/ 26, 26, 26, 26, 26,
47 /* 80:*/ 26, 26, 27, 27, 27,
48 /* 85:*/ 27, 27, 27, 27, 27,
49 /* 90:*/ 28, 28, 28, 28, 28,
50 /* 95:*/ 28, 28, 28, 28, 28,
51 /*100:*/ 29, 29, 29, 29, 29,
52 /*105:*/ 29, 29, 29, 29, 30,
53 /*110:*/ 30, 30, 30, 30, 30,
54 /*115:*/ 30, 30, 30, 30, 31,
55 /*120:*/ 31, 31, 31, 31, 31,
56 /*125:*/ 31, 31, 31, 31 };
57
[metadata] {"type": "text", "file": {"filePath": "/app/ocaml/runtime/caml/sizeclasses.h", "content": "/* This file is generated by tools/gen_sizeclasses.ml */\n#define POOL_WSIZE 4096\n#define POOL_HEADER_WSIZE 4\n#define SIZECLASS_MAX 128\n#define NUM_SIZECLASSES 32\n\n/* The largest size for this size class.\n (A gap is left after smaller objects) */\nstatic const unsigned int wsize_sizeclass[NUM_SIZECLASSES] =\n{ /* 0:*/ 1, 2, 3, 4, 5,\n /* 5:*/ 6, 7, 8, 10, 12,\n /* 10:*/ 14, 16, 17, 19, 22,\n /* 15:*/ 25, 28, 32, 33, 37,\n /* 20:*/ 42, 47, 53, 59, 65,\n /* 25:*/ 73, 81, 89, 99, 108,\n /* 30:*/ 118, 128 };\n\n/* The number of padding words to use, at the beginning of a pool\n of this sizeclass, to reach exactly POOL_WSIZE words. */\nstatic const unsigned char wastage_sizeclass[NUM_SIZECLASSES] =\n{ /* 0:*/ 0, 0, 0, 0, 2,\n /* 5:*/ 0, 4, 4, 2, 0,\n /* 10:*/ 4, 12, 12, 7, 0,\n /* 15:*/ 17, 4, 28, 0, 22,\n /* 20:*/ 18, 3, 11, 21, 62,\n /* 25:*/ 4, 42, 87, 33, 96,\n /* 30:*/ 80, 124 };\n\n/* Map from (positive) object sizes to size classes. */\nstatic const unsigned char sizeclass_wsize[SIZECLASS_MAX + 1] =\n{ /* 0:*/ 255, 0, 1, 2, 3,\n /* 5:*/ 4, 5, 6, 7, 8,\n /* 10:*/ 8, 9, 9, 10, 10,\n /* 15:*/ 11, 11, 12, 13, 13,\n /* 20:*/ 14, 14, 14, 15, 15,\n /* 25:*/ 15, 16, 16, 16, 17,\n /* 30:*/ 17, 17, 17, 18, 19,\n /* 35:*/ 19, 19, 19, 20, 20,\n /* 40:*/ 20, 20, 20, 21, 21,\n /* 45:*/ 21, 21, 21, 22, 22,\n /* 50:*/ 22, 22, 22, 22, 23,\n /* 55:*/ 23, 23, 23, 23, 23,\n /* 60:*/ 24, 24, 24, 24, 24,\n /* 65:*/ 24, 25, 25, 25, 25,\n /* 70:*/ 25, 25, 25, 25, 26,\n /* 75:*/ 26, 26, 26, 26, 26,\n /* 80:*/ 26, 26, 27, 27, 27,\n /* 85:*/ 27, 27, 27, 27, 27,\n /* 90:*/ 28, 28, 28, 28, 28,\n /* 95:*/ 28, 28, 28, 28, 28,\n /*100:*/ 29, 29, 29, 29, 29,\n /*105:*/ 29, 29, 29, 29, 30,\n /*110:*/ 30, 30, 30, 30, 30,\n /*115:*/ 30, 30, 30, 30, 31,\n /*120:*/ 31, 31, 31, 31, 31,\n /*125:*/ 31, 31, 31, 31 };\n", "numLines": 57, "startLine": 1, "totalLines": 57}}{
"file_path": "/app/ocaml/runtime/shared_heap.c",
"offset": 350,
"limit": 450
}350 if( !atomic_load_relaxed(&pool_freelist.global_avail_pools[sz]) &&
351 !atomic_load_relaxed(&pool_freelist.global_full_pools[sz]) )
352 return NULL;
353
354 /* Haven't managed to find a pool locally, try the global ones */
355 caml_plat_lock_blocking(&pool_freelist.lock);
356 if( atomic_load_relaxed(&pool_freelist.global_avail_pools[sz]) ) {
357 r = atomic_load_relaxed(&pool_freelist.global_avail_pools[sz]);
358
359 if( r ) {
360 atomic_store_relaxed(&pool_freelist.global_avail_pools[sz], r->next);
361 r->next = 0;
362 r->owner = local->owner;
363 local->avail_pools[sz] = r;
364 adopt_pool_stats_with_lock(local, r, sz);
365
366 #ifdef DEBUG
367 {
368 value* next_obj = r->next_obj;
369 while( next_obj ) {
370 CAMLassert(POOL_BLOCK_FREE_HP(next_obj));
371 next_obj = (value*)next_obj[1];
372 }
373 }
374 #endif
375
376 }
377 }
378
379 /* There were no global avail pools, so let's adopt one of the full ones and
380 try our luck sweeping it later on */
381 if( !r ) {
382 r = atomic_load_relaxed(&pool_freelist.global_full_pools[sz]);
383
384 if( r ) {
385 atomic_store_relaxed(&pool_freelist.global_full_pools[sz], r->next);
386 r->next = local->full_pools[sz];
387 r->owner = local->owner;
388 local->full_pools[sz] = r;
389 adopt_pool_stats_with_lock(local, r, sz);
390
391 adopted_pool = 1;
392 r = 0; // this pool is full
393 }
394 }
395
396 caml_plat_unlock(&pool_freelist.lock);
397
398 if( !r && adopted_pool ) {
399 Caml_state->major_work_done_between_slices +=
400 pool_sweep(local, &local->full_pools[sz], sz, 0);
401 r = local->avail_pools[sz];
402 }
403
404 CAMLassert(r == NULL || r->owner == local->owner);
405 return r;
406 }
407
408 /* Allocating an object from a pool */
409 static pool* pool_find(struct caml_heap_state* local, sizeclass sz) {
410 pool* r;
411
412 /* Hopefully we have a pool we can use directly */
413 r = local->avail_pools[sz];
414 if (r) return r;
415
416 /* Otherwise, try to sweep until we find one */
417 while (!local->avail_pools[sz] && local->unswept_avail_pools[sz]) {
418 Caml_state->major_work_done_between_slices +=
419 pool_sweep(local, &local->unswept_avail_pools[sz], sz, 0);
420 }
421
422 r = local->avail_pools[sz];
423 if (r) return r;
424
425 /* Haven't managed to find a pool locally, try the global ones */
426 r = pool_global_adopt(local, sz);
427 if (r) return r;
428
429 /* Failing that, we need to allocate a new pool */
430 r = pool_acquire(local);
431 if (!r) return 0; /* if we can't allocate, give up */
432
433 local->stats.pool_words += POOL_WSIZE;
434 if (local->stats.pool_words > local->stats.pool_max_words)
435 local->stats.pool_max_words = local->stats.pool_words;
436 local->stats.pool_frag_words += POOL_HEADER_WSIZE + wastage_sizeclass[sz];
437
438 /* Having allocated a new pool, set it up for size sz */
439 local->avail_pools[sz] = r;
440 pool_initialize(r, sz, local->owner);
441
442 return r;
443 }
444
445 static void* pool_allocate(struct caml_heap_state* local, sizeclass sz) {
446 value* p;
447 value* next;
448 pool* r = pool_find(local, sz);
449
450 if (!r) return 0;
451
452 p = r->next_obj;
453 /* assert that p is inside the pool */
454 CAMLassert(p >= (value*)POOL_FIRST_BLOCK(r, sz));
455 CAMLassert(p < (value*)r + POOL_WSIZE);
456 CAMLassert(POOL_BLOCK_FREE_HP(p));
457
458 /* in this case there are more free blocks immediately after */
459 if( Wosize_hp(p) > 0 ) {
460 next = (value*)(p + wsize_sizeclass[sz]);
461 /* we update the pool header of the next block */
462 *next = POOL_FREE_HEADER(Wosize_hp(p) - 1);
463 /* also copy the next_obj pointer from p */
464 CAMLassert(p[1] == 0 || POOL_BLOCK_FREE_HP(p[1]));
465 next[1] = p[1];
466 } else {
467 next = (value*)p[1];
468 }
469
470 r->next_obj = next;
471 if (!next) {
472 local->avail_pools[sz] = r->next;
473 r->next = local->full_pools[sz];
474 local->full_pools[sz] = r;
475 }
476
477 CAMLassert(
478 /* either there's no more free space and we've moved the pool */
479 (r->next_obj == 0 && local->full_pools[sz] == r)
480 /* or there's still free space */
481 || POOL_BLOCK_FREE_HP(r->next_obj));
482
483 return p;
484 }
485
486 static void* large_allocate(struct caml_heap_state* local, mlsize_t sz) {
487 large_alloc* a = malloc(sz + LARGE_ALLOC_HEADER_SZ);
488 if (!a) return NULL;
489 local->stats.large_words += Wsize_bsize(sz + LARGE_ALLOC_HEADER_SZ);
490 if (local->stats.large_words > local->stats.large_max_words)
491 local->stats.large_max_words = local->stats.large_words;
492 local->stats.large_blocks++;
493 a->owner = local->owner;
494 a->next = local->swept_large;
495 local->swept_large = a;
496 return (char*)a + LARGE_ALLOC_HEADER_SZ;
497 }
498
499 value* caml_shared_try_alloc(struct caml_heap_state* local, mlsize_t wosize,
500 tag_t tag, reserved_t reserved)
501 {
502 mlsize_t whsize = Whsize_wosize(wosize);
503 value* p;
504 uintnat colour;
505
506 CAMLassert (wosize > 0);
507 CAMLassert (tag != Infix_tag);
508
509 CAML_EV_ALLOC(wosize);
510
511 if (whsize <= SIZECLASS_MAX) {
512 struct heap_stats* s;
513 sizeclass sz = sizeclass_wsize[whsize];
514 CAMLassert(wsize_sizeclass[sz] >= whsize);
515 p = pool_allocate(local, sz);
516 if (!p) return 0;
517 s = &local->stats;
518 s->pool_live_blocks++;
519 s->pool_live_words += whsize;
520 s->pool_frag_words += wsize_sizeclass[sz] - whsize;
521 } else {
522 p = large_allocate(local, Bsize_wsize(whsize));
523 if (!p) return 0;
524 }
525 colour = caml_global_heap_state.MARKED;
526 Hd_hp (p) = Make_header_with_reserved(wosize, tag, colo{
"file_path": "/app/ocaml/runtime/shared_heap.c",
"limit": 450,
"offset": 796
}796 void caml_finalise_heap(void) {
797 struct caml_heap_state *local = Caml_state->shared_heap;
798 sizeclass sz;
799
800 /* Finalise and release unswept local pools. */
801 for (sz = 0; sz < NUM_SIZECLASSES; sz++) {
802 pool_finalise(local, &local->unswept_avail_pools[sz], sz);
803 pool_finalise(local, &local->unswept_full_pools[sz], sz);
804 }
805
806 /* Finalise and free large unswept objects. */
807 if (local->unswept_large)
808 large_alloc_finalise(local);
809 }
810
811 uintnat caml_heap_size(struct caml_heap_state* local) {
812 return Bsize_wsize(local->stats.pool_words + local->stats.large_words);
813 }
814
815 uintnat caml_top_heap_words(struct caml_heap_state* local) {
816 /* FIXME: summing two maximums computed at different points in time
817 returns an incorrect result. */
818 return local->stats.pool_max_words + local->stats.large_max_words;
819 }
820
821
822 uintnat caml_heap_blocks(struct caml_heap_state* local) {
823 return local->stats.pool_live_blocks + local->stats.large_blocks;
824 }
825
826 void caml_redarken_pool(struct pool* r, scanning_action f, void* fdata) {
827 mlsize_t wh = wsize_sizeclass[r->sz];
828 header_t* p = POOL_FIRST_BLOCK(r, r->sz);
829 header_t* end = POOL_END(r);
830
831 while (p + wh <= end) {
832 header_t hd = p[0];
833 if (Has_status_hd(hd, caml_global_heap_state.MARKED)) {
834 f(fdata, Val_hp(p), 0);
835 }
836 p += wh;
837 }
838 }
839
840
841 /* Heap and freelist stats */
842
843 /* Move the given heap stats to the orphan pools.
844 You need to hold the [pool_freelist] lock. */
845 static void orphan_heap_stats_with_lock(struct caml_heap_state *heap) {
846 caml_accum_heap_stats(&pool_freelist.stats, &heap->stats);
847 memset(&heap->stats, 0, sizeof(heap->stats));
848 }
849
850 /* The stats for an adopted pool are moved from the free pool stats to
851 the heap stats of the adopting domain.
852 You need to hold the [pool_freelist] lock. */
853 static void adopt_pool_stats_with_lock(
854 struct caml_heap_state* adopter, pool *r, sizeclass sz)
855 {
856 struct heap_stats pool_stats = { 0, };
857
858 calc_pool_stats(r, sz, &pool_stats);
859 caml_accum_heap_stats(&adopter->stats, &pool_stats);
860 caml_remove_heap_stats(&pool_freelist.stats, &pool_stats);
861 }
862
863 /* Move the stats of all orphan pools into the given heap.
864 You need to hold the [pool_freelist] lock. */
865 static void adopt_all_pool_stats_with_lock(struct caml_heap_state *adopter) {
866 caml_accum_heap_stats(&adopter->stats, &pool_freelist.stats);
867 memset(&pool_freelist.stats, 0, sizeof(pool_freelist.stats));
868 }
869
870 void caml_collect_heap_stats_sample(
871 struct caml_heap_state* local,
872 struct heap_stats* sample)
873 {
874 *sample = local->stats;
875 }
876
877 /* Add the orphan pool stats to a stats accumulator. */
878 void caml_accum_orphan_heap_stats(struct heap_stats* acc)
879 {
880 caml_plat_lock_blocking(&pool_freelist.lock);
881 caml_accum_heap_stats(acc, &pool_freelist.stats);
882 caml_plat_unlock(&pool_freelist.lock);
883 }
884
885
886 /* Atoms */
887 static const header_t atoms[256] = {
888 #define A(i) Make_header(0, i, NOT_MARKABLE)
889 A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9),A(10),
890 A(11),A(12),A(13),A(14),A(15),A(16),A(17),A(18),A(19),A(20),
891 A(21),A(22),A(23),A(24),A(25),A(26),A(27),A(28),A(29),A(30),
892 A(31),A(32),A(33),A(34),A(35),A(36),A(37),A(38),A(39),A(40),
893 A(41),A(42),A(43),A(44),A(45),A(46),A(47),A(48),A(49),A(50),
894 A(51),A(52),A(53),A(54),A(55),A(56),A(57),A(58),A(59),A(60),
895 A(61),A(62),A(63),A(64),A(65),A(66),A(67),A(68),A(69),A(70),
896 A(71),A(72),A(73),A(74),A(75),A(76),A(77),A(78),A(79),A(80),
897 A(81),A(82),A(83),A(84),A(85),A(86),A(87),A(88),A(89),A(90),
898 A(91),A(92),A(93),A(94),A(95),A(96),A(97),A(98),A(99),A(100),
899 A(101),A(102),A(103),A(104),A(105),A(106),A(107),A(108),A(109),
900 A(110),A(111),A(112),A(113),A(114),A(115),A(116),A(117),A(118),
901 A(119),A(120),A(121),A(122),A(123),A(124),A(125),A(126),A(127),
902 A(128),A(129),A(130),A(131),A(132),A(133),A(134),A(135),A(136),
903 A(137),A(138),A(139),A(140),A(141),A(142),A(143),A(144),A(145),
904 A(146),A(147),A(148),A(149),A(150),A(151),A(152),A(153),A(154),
905 A(155),A(156),A(157),A(158),A(159),A(160),A(161),A(162),A(163),
906 A(164),A(165),A(166),A(167),A(168),A(169),A(170),A(171),A(172),
907 A(173),A(174),A(175),A(176),A(177),A(178),A(179),A(180),A(181),
908 A(182),A(183),A(184),A(185),A(186),A(187),A(188),A(189),A(190),
909 A(191),A(192),A(193),A(194),A(195),A(196),A(197),A(198),A(199),
910 A(200),A(201),A(202),A(203),A(204),A(205),A(206),A(207),A(208),
911 A(209),A(210),A(211),A(212),A(213),A(214),A(215),A(216),A(217),
912 A(218),A(219),A(220),A(221),A(222),A(223),A(224),A(225),A(226),
913 A(227),A(228),A(229),A(230),A(231),A(232),A(233),A(234),A(235),
914 A(236),A(237),A(238),A(239),A(240),A(241),A(242),A(243),A(244),
915 A(245),A(246),A(247),A(248),A(249),A(250),A(251),A(252),A(253),
916 A(254),A(255)
917 #undef A
918 };
919
920 CAMLexport value caml_atom(tag_t tag) {
921 return Val_hp(&atoms[tag]);
922 }
923
924 void caml_init_major_heap (asize_t size) {
925 }
926
927
928 /* Verify heap invariants.
929
930 Verification happens just after the heap is cycled during STW, so
931 everything should be unmarked. If something reachable marked after
932 cycling the heap, it means that garbage was reachable beforehand.
933 */
934 struct heap_verify_state {
935 value* stack;
936 int stack_len;
937 int sp;
938 intnat objs;
939 struct addrmap seen;
940 };
941
942 struct heap_verify_state* caml_verify_begin (void)
943 {
944 struct heap_verify_state init = {0, 0, 0, 0, ADDRMAP_INIT};
945 struct heap_verify_state* st = caml_stat_alloc(sizeof init);
946 *st = init;
947 return st;
948 }
949
950 static void verify_push (void* st_v, value v, volatile value* ignored)
951 {
952 stru{
"file_path": "/app/ocaml/runtime/shared_heap.c",
"limit": 450,
"offset": 1245
}1245
1246 /* if we're unable to allocate pool_stats here then we should avoid
1247 evacuating this size class. It's unlikely but it may be that we had
1248 better success with an earlier size class and that results in some
1249 memory being freed up. */
1250 if( pool_stats == NULL ) {
1251 caml_gc_log("Unable to allocate pool_stats for size class %d", sz_class);
1252
1253 continue;
1254 }
1255
1256 cur_pool = heap->unswept_avail_pools[sz_class];
1257
1258 /* Count the number of free and live blocks in each pool. Note that a live
1259 block here currently has the header status UNMARKED (because it was
1260 MARKED in the previous cycle). After compaction the shared pools will
1261 contain UNMARKED and GARBAGE from the "to" pools and UNMARKED from the
1262 "from" pools which were evacuated.
1263
1264 At the cost of some complexity or an additional pass we could compute the
1265 exact amount of space needed or even sweep all pools in this counting
1266 pass.
1267 */
1268 int k = 0;
1269 int total_live_blocks = 0;
1270 #ifdef DEBUG
1271 int total_free_blocks = 0;
1272 #endif
1273 while (cur_pool) {
1274 header_t* p = POOL_FIRST_BLOCK(cur_pool, sz_class);
1275 header_t* end = POOL_END(cur_pool);
1276 mlsize_t wh = wsize_sizeclass[sz_class];
1277
1278 pool_stats[k].free_blocks = 0;
1279 pool_stats[k].live_blocks = 0;
1280
1281 while (p + wh <= end) {
1282 header_t h = (header_t)atomic_load_relaxed((atomic_uintnat*)p);
1283
1284 if (POOL_BLOCK_FREE_HD(h)) {
1285 /* this tells us the number of spaces of size wh after this */
1286 mlsize_t wosize = Wosize_hd(h);
1287
1288 pool_stats[k].free_blocks += wosize + 1;
1289 #ifdef DEBUG
1290 total_free_blocks += wosize + 1;
1291 #endif
1292 /* skip to the next block */
1293 p += wh * wosize;
1294 } else if (Has_status_hd(h, caml_global_heap_state.UNMARKED)) {
1295 total_live_blocks++;
1296 pool_stats[k].live_blocks++;
1297 }
1298 p += wh;
1299 }
1300
1301 cur_pool = cur_pool->next;
1302 k++;
1303 }
1304
1305 /* Note that partially filled pools must have at least some free space*/
1306 #ifdef DEBUG
1307 CAMLassert(total_free_blocks > 0);
1308 #endif
1309
1310 if (!total_live_blocks) {
1311 /* No live (i.e unmarked) blocks in partially filled pools, nothing to do
1312 for this size class */
1313 continue;
1314 }
1315
1316 /* Now we use the pool stats to calculate which pools will be evacuated. We
1317 want to walk through the pools and check whether we have enough free
1318 blocks in the pools behind us to accommodate all the remaining live
1319 blocks. */
1320 int free_blocks = 0;
1321 int j = 0;
1322 int remaining_live_blocks = total_live_blocks;
1323
1324 cur_pool = heap->unswept_avail_pools[sz_class];
1325 /* [last_pool_p] will be a pointer to the next field of the last
1326 non-evacuating pool. We need this so we can snip the list of evacuating
1327 pools from [unswept_avail_pools] and eventually attach them all to
1328 [evacuated_pools]. */
1329 pool **last_pool_p = &heap->unswept_avail_pools[sz_class];
1330 while (cur_pool) {
1331 if (free_blocks >= remaining_live_blocks) {
1332 break;
1333 }
1334
1335 free_blocks += pool_stats[j].free_blocks;
1336 remaining_live_blocks -= pool_stats[j].live_blocks;
1337 last_pool_p = &cur_pool->next;
1338 cur_pool = cur_pool->next;
1339 j++;
1340 }
1341
1342 /* We're done with the pool stats. */
1343 caml_stat_free(pool_stats);
1344
1345 /* `cur_pool` now points to the first pool we are evacuating, or NULL if
1346 we could not compact this particular size class (for this domain) */
1347
1348 /* Snip the evacuating pools from list of pools we are retaining */
1349 *last_pool_p = NULL;
1350
1351 /* Evacuate marked blocks from the evacuating pools into the
1352 avail pools. */
1353 while (cur_pool) {
1354 header_t* p = POOL_FIRST_BLOCK(cur_pool, sz_class);
1355 header_t* end = POOL_END(cur_pool);
1356 mlsize_t wh = wsize_sizeclass[sz_class];
1357
1358 while (p + wh <= end) {
1359 header_t hd = (header_t)atomic_load_relaxed((atomic_uintnat*)p);
1360
1361 if (!POOL_BLOCK_FREE_HD(hd)) {
1362 CAMLassert (!Has_status_hd(hd, caml_global_heap_state.MARKED));
1363 CAMLassert (!Has_status_hd(hd, NOT_MARKABLE));
1364
1365 /* Reminder: since colours have rotated, UNMARKED indicates a MARKED
1366 (i.e live) block */
1367 if (Has_status_hd(hd, caml_global_heap_state.UNMARKED)) {
1368 /* live block in an evacuating pool, so we evacuate it to
1369 * the first available block */
1370 pool* to_pool = heap->unswept_avail_pools[sz_class];
1371 value* new_p = to_pool->next_obj;
1372 CAMLassert(POOL_BLOCK_FREE_HP(new_p));
1373 /* if there are free blocks after this, use those */
1374 mlsize_t wosize = Wosize_hp(new_p);
1375 if( wosize > 0 ) {
1376 /* copy the header and free pointer over */
1377 value* next = (value*)(new_p + wh);
1378
1379 CAMLassert(
1380 POOL_FIRST_BLOCK(to_pool, sz_class) <= (header_t*)next
1381 );
1382
1383 CAMLassert((header_t*)next <= POOL_END(to_pool));
1384
1385 *next = POOL_FREE_HEADER(wosize - 1);
1386 next[1] = new_p[1];
1387 to_pool->next_obj = next;
1388 } else {
1389 value *next = (value*)new_p[1];
1390 to_pool->next_obj = next;
1391
1392{
"command": "grep -n \"define \\(Hd_hp\\|Wosize_hp\\|Wosize_hd\\|Whsize_hd\\|Whsize_hp\\|Hd_hd\\|Val_hp\\|Hp_val\\|Wosize_whsize\\|Make_header\\|Tag_hd\\|Color_hd\\)\" runtime/caml/mlvalues.h | head -40",
"description": "Inspect header/value macros"
}160:#define Tag_hd(hd) ((tag_t) ((hd) & HEADER_TAG_MASK))
162:#define Wosize_hd(hd) ((mlsize_t) (((hd) & HEADER_WOSIZE_MASK) \
184:#define Color_hd(hd) ((hd) & HEADER_COLOR_MASK)
195:#define Hd_hp(hp) (* ((volatile header_t *) (hp))) /* Also an l-value. */
196:#define Hp_val(val) (((volatile header_t *) (val)) - 1)
200:#define Val_hp(hp) ((value) (((header_t *) (hp)) + 1))
210:#define Wosize_hp(hp) (Wosize_hd (Hd_hp (hp)))
212:#define Wosize_whsize(sz) ((sz) - 1)
222:#define Whsize_hp(hp) (Whsize_wosize (Wosize_hp (hp)))
225:#define Whsize_hd(hd) (Whsize_wosize (Wosize_hd (hd)))
[stdout]
160:#define Tag_hd(hd) ((tag_t) ((hd) & HEADER_TAG_MASK))
162:#define Wosize_hd(hd) ((mlsize_t) (((hd) & HEADER_WOSIZE_MASK) \
184:#define Color_hd(hd) ((hd) & HEADER_COLOR_MASK)
195:#define Hd_hp(hp) (* ((volatile header_t *) (hp))) /* Also an l-value. */
196:#define Hp_val(val) (((volatile header_t *) (val)) - 1)
200:#define Val_hp(hp) ((value) (((header_t *) (hp)) + 1))
210:#define Wosize_hp(hp) (Wosize_hd (Hd_hp (hp)))
212:#define Wosize_whsize(sz) ((sz) - 1)
222:#define Whsize_hp(hp) (Whsize_wosize (Wosize_hp (hp)))
225:#define Whsize_hd(hd) (Whsize_wosize (Wosize_hd (hd)))
[metadata] {"noOutputExpected": false}{
"command": "grep -rn \"Wosize_hd\\|Wosize_hp\\|POOL_FREE\\|POOL_BLOCK_FREE\\|wsize_sizeclass\" runtime/ --include=\"*.c\" --include=\"*.h\" | grep -v \"shared_heap.c\\|sizeclasses.h\"",
"description": "Find other RLE free-block users"
}runtime/extern.c:788: mlsize_t sz = Wosize_hd(hd);
runtime/extern.c:1298: mlsize_t sz = Wosize_hd(hd);
runtime/intern.c:585: size = Wosize_hd(header);
runtime/intern.c:591: size = Wosize_hd(header);
runtime/weak.c:154: size = Wosize_hd (hd);
runtime/minor_gc.c:276: CAMLassert(Wosize_hd(hd) == 2);
runtime/minor_gc.c:300: sz = Wosize_hd (hd);
runtime/minor_gc.c:329: sz = Wosize_hd (hd);
runtime/minor_gc.c:362: CAMLassert (Wosize_hd (hd) == 1);
runtime/major_gc.c:345: size = Wosize_hd(hd);
runtime/major_gc.c:1227: *work -= Wosize_hd(chd);
runtime/major_gc.c:1244: *work -= Wosize_hd(chd);
runtime/major_gc.c:1290: budget -= Wosize_hd(hd);
runtime/major_gc.c:1310: budget -= Wosize_hd(hd);
runtime/major_gc.c:1315: me.end = me.start + Wosize_hd(hd);
runtime/caml/mlvalues.h:162:#define Wosize_hd(hd) ((mlsize_t) (((hd) & HEADER_WOSIZE_MASK) \
runtime/caml/mlvalues.h:207:#define Wosize_val(val) (Wosize_hd (Hd_val (val)))
runtime/caml/mlvalues.h:210:#define Wosize_hp(hp) (Wosize_hd (Hd_hp (hp)))
runtime/caml/mlvalues.h:221:#define Bosize_hd(hd) (Bsize_wsize (Wosize_hd (hd)))
runtime/caml/mlvalues.h:222:#define Whsize_hp(hp) (Whsize_wosize (Wosize_hp (hp)))
runtime/caml/mlvalues.h:225:#define Whsize_hd(hd) (Whsize_wosize (Wosize_hd (hd)))
[stdout]
runtime/extern.c:788: mlsize_t sz = Wosize_hd(hd);
runtime/extern.c:1298: mlsize_t sz = Wosize_hd(hd);
runtime/intern.c:585: size = Wosize_hd(header);
runtime/intern.c:591: size = Wosize_hd(header);
runtime/weak.c:154: size = Wosize_hd (hd);
runtime/minor_gc.c:276: CAMLassert(Wosize_hd(hd) == 2);
runtime/minor_gc.c:300: sz = Wosize_hd (hd);
runtime/minor_gc.c:329: sz = Wosize_hd (hd);
runtime/minor_gc.c:362: CAMLassert (Wosize_hd (hd) == 1);
runtime/major_gc.c:345: size = Wosize_hd(hd);
runtime/major_gc.c:1227: *work -= Wosize_hd(chd);
runtime/major_gc.c:1244: *work -= Wosize_hd(chd);
runtime/major_gc.c:1290: budget -= Wosize_hd(hd);
runtime/major_gc.c:1310: budget -= Wosize_hd(hd);
runtime/major_gc.c:1315: me.end = me.start + Wosize_hd(hd);
runtime/caml/mlvalues.h:162:#define Wosize_hd(hd) ((mlsize_t) (((hd) & HEADER_WOSIZE_MASK) \
runtime/caml/mlvalues.h:207:#define Wosize_val(val) (Wosize_hd (Hd_val (val)))
runtime/caml/mlvalues.h:210:#define Wosize_hp(hp) (Wosize_hd (Hd_hp (hp)))
runtime/caml/mlvalues.h:221:#define Bosize_hd(hd) (Bsize_wsize (Wosize_hd (hd)))
runtime/caml/mlvalues.h:222:#define Whsize_hp(hp) (Whsize_wosize (Wosize_hp (hp)))
runtime/caml/mlvalues.h:225:#define Whsize_hd(hd) (Whsize_wosize (Wosize_hd (hd)))
[metadata] {"noOutputExpected": false}{
"command": "grep -n \"p += \\|p +=\\|Whsize_hd\\|Whsize_hp\" runtime/shared_heap.c",
"description": "Find all pointer advances in shared_heap.c"
}190: received_p += move_all_pools(
194: received_p += move_all_pools(
297: s->pool_live_words += Whsize_hd(hd);
298: s->pool_frag_words += wh - Whsize_hd(hd);
301: p += wh * Wosize_hd(hd); /* skip contiguous free blocks */
304: p += wh;
328: for (p += 2; p < end; p++) *p = Debug_free_major;
581: CAMLassert(Whsize_hd(hd) <= wh);
602: s->pool_live_words -= Whsize_hd(hd);
603: local->owner->swept_words += Whsize_hd(hd);
604: s->pool_frag_words -= (wh - Whsize_hd(hd));
644: p += wh * Wosize_hd(hd);
650: p += Whsize_hd(hd);
697: Whsize_hd(hd) + Wsize_bsize(LARGE_ALLOC_HEADER_SZ);
699: Whsize_hd(hd) + Wsize_bsize(LARGE_ALLOC_HEADER_SZ);
707: return Whsize_hd(hd);
779: CAMLassert(Whsize_hd(hd) <= wh);
787: p += wh * Wosize_hd(hd);
789: p += wh;
836: p += wh;
1124: p += wh * Wosize_hp(p);
1126: p += wh;
1293: p += wh * wosize;
1298: p += wh;
1401: memcpy(new_p, p, Whsize_hd(hd) * sizeof(value));
1420: heap->stats.pool_live_words -= Whsize_hd(hd);
1421: heap->stats.pool_frag_words -= (wh - Whsize_hd(hd));
1435: p += wosize * wh;
1438: p += wh;
1581: s->live += Whsize_hd(hd);
1582: s->overhead += wh - Whsize_hd(hd);
1588: p += Wosize_hd(hd) * wh;
1590: p += wh;
1601: s->allocated += Wsize_bsize(LARGE_ALLOC_HEADER_SZ) + Whsize_hd(hd);
[stdout]
190: received_p += move_all_pools(
194: received_p += move_all_pools(
297: s->pool_live_words += Whsize_hd(hd);
298: s->pool_frag_words += wh - Whsize_hd(hd);
301: p += wh * Wosize_hd(hd); /* skip contiguous free blocks */
304: p += wh;
328: for (p += 2; p < end; p++) *p = Debug_free_major;
581: CAMLassert(Whsize_hd(hd) <= wh);
602: s->pool_live_words -= Whsize_hd(hd);
603: local->owner->swept_words += Whsize_hd(hd);
604: s->pool_frag_words -= (wh - Whsize_hd(hd));
644: p += wh * Wosize_hd(hd);
650: p += Whsize_hd(hd);
697: Whsize_hd(hd) + Wsize_bsize(LARGE_ALLOC_HEADER_SZ);
699: Whsize_hd(hd) + Wsize_bsize(LARGE_ALLOC_HEADER_SZ);
707: return Whsize_hd(hd);
779: CAMLassert(Whsize_hd(hd) <= wh);
787: p += wh * Wosize_hd(hd);
789: p += wh;
836: p += wh;
1124: p += wh * Wosize_hp(p);
1126: p += wh;
1293: p += wh * wosize;
1298: p += wh;
1401: memcpy(new_p, p, Whsize_hd(hd) * sizeof(value));
1420: heap->stats.pool_live_words -= Whsize_hd(hd);
1421: heap->stats.pool_frag_words -= (wh - Whsize_hd(hd));
1435: p += wosize * wh;
1438: p += wh;
1581: s->live += Whsize_hd(hd);
1582: s->overhead += wh - Whsize_hd(hd);
1588: p += Wosize_hd(hd) * wh;
1590: p += wh;
1601: s->allocated += Wsize_bsize(LARGE_ALLOC_HEADER_SZ) + Whsize_hd(hd);
[metadata] {"noOutputExpected": false}{
"command": "grep -n \"next_obj\\|POOL_FREE_HEADER\\|Wosize\" runtime/shared_heap.c",
"description": "Find all freelist size usages"
}53: value* next_obj;
66:#define POOL_FREE_HEADER(wosize) Make_header(wosize, No_scan_tag, NOT_MARKABLE)
301: p += wh * Wosize_hd(hd); /* skip contiguous free blocks */
321: r->next_obj = (value*)p;
324: p[0] = POOL_FREE_HEADER(pool_blocks-1);
368: value* next_obj = r->next_obj;
369: while( next_obj ) {
370: CAMLassert(POOL_BLOCK_FREE_HP(next_obj));
371: next_obj = (value*)next_obj[1];
452: p = r->next_obj;
459: if( Wosize_hp(p) > 0 ) {
462: *next = POOL_FREE_HEADER(Wosize_hp(p) - 1);
463: /* also copy the next_obj pointer from p */
470: r->next_obj = next;
479: (r->next_obj == 0 && local->full_pools[sz] == r)
481: || POOL_BLOCK_FREE_HP(r->next_obj));
560: a->next_obj = 0;
590: *p = POOL_FREE_HEADER(0);
594: for (mlsize_t i = 1, wo = Wosize_whsize(wh); i < wo; i++) {
607: hd = POOL_FREE_HEADER(0);
624: if( last_free_block + (1 + Wosize_hp(last_free_block)) * wh == p ) {
626: *last_free_block = POOL_FREE_HEADER(Wosize_hp(last_free_block)
627: + Wosize_hd(hd) + 1);
636: /* if we're the first free block then set the next_obj pointer for
638: a->next_obj = (value*)p;
644: p += wh * Wosize_hd(hd);
660: /* if all spaces are used then next_obj should be 0 */
661: (all_used && !a->next_obj)
663: || (!all_used && POOL_BLOCK_FREE_HP(a->next_obj))
787: p += wh * Wosize_hd(hd);
1000: for (; i < Wosize_val(v); i++) {
1100: mlsize_t wosz = Wosize_hd(hd);
1124: p += wh * Wosize_hp(p);
1143: mlsize_t wosize = Wosize_val(ephe);
1286: mlsize_t wosize = Wosize_hd(h);
1371: value* new_p = to_pool->next_obj;
1374: mlsize_t wosize = Wosize_hp(new_p);
1385: *next = POOL_FREE_HEADER(wosize - 1);
1387: to_pool->next_obj = next;
1390: to_pool->next_obj = next;
1434: mlsize_t wosize = Wosize_hd(hd);
1560: for (value *v = a->next_obj; v; v = (value*)v[1]) {
1587: s->free += wh * (1 + Wosize_hd(hd));
1588: p += Wosize_hd(hd) * wh;
1618: CAMLassert(p->next_obj == NULL);
[stdout]
53: value* next_obj;
66:#define POOL_FREE_HEADER(wosize) Make_header(wosize, No_scan_tag, NOT_MARKABLE)
301: p += wh * Wosize_hd(hd); /* skip contiguous free blocks */
321: r->next_obj = (value*)p;
324: p[0] = POOL_FREE_HEADER(pool_blocks-1);
368: value* next_obj = r->next_obj;
369: while( next_obj ) {
370: CAMLassert(POOL_BLOCK_FREE_HP(next_obj));
371: next_obj = (value*)next_obj[1];
452: p = r->next_obj;
459: if( Wosize_hp(p) > 0 ) {
462: *next = POOL_FREE_HEADER(Wosize_hp(p) - 1);
463: /* also copy the next_obj pointer from p */
470: r->next_obj = next;
479: (r->next_obj == 0 && local->full_pools[sz] == r)
481: || POOL_BLOCK_FREE_HP(r->next_obj));
560: a->next_obj = 0;
590: *p = POOL_FREE_HEADER(0);
594: for (mlsize_t i = 1, wo = Wosize_whsize(wh); i < wo; i++) {
607: hd = POOL_FREE_HEADER(0);
624: if( last_free_block + (1 + Wosize_hp(last_free_block)) * wh == p ) {
626: *last_free_block = POOL_FREE_HEADER(Wosize_hp(last_free_block)
627: + Wosize_hd(hd) + 1);
636: /* if we're the first free block then set the next_obj pointer for
638: a->next_obj = (value*)p;
644: p += wh * Wosize_hd(hd);
660: /* if all spaces are used then next_obj should be 0 */
661: (all_used && !a->next_obj)
663: || (!all_used && POOL_BLOCK_FREE_HP(a->next_obj))
787: p += wh * Wosize_hd(hd);
1000: for (; i < Wosize_val(v); i++) {
1100: mlsize_t wosz = Wosize_hd(hd);
1124: p += wh * Wosize_hp(p);
1143: mlsize_t wosize = Wosize_val(ephe);
1286: mlsize_t wosize = Wosize_hd(h);
1371: value* new_p = to_pool->next_obj;
1374: mlsize_t wosize = Wosize_hp(new_p);
1385: *next = POOL_FREE_HEADER(wosize - 1);
1387: to_pool->next_obj = next;
1390: to_pool->next_obj = next;
1434: mlsize_t wosize = Wosize_hd(hd);
1560: for (value *v = a->next_obj; v; v = (value*)v[1]) {
1587: s->free += wh * (1 + Wosize_hd(hd));
1588: p += Wosize_hd(hd) * wh;
1618: CAMLassert(p->next_obj == NULL);
[metadata] {"noOutputExpected": false}{
"file_path": "/app/ocaml/VERSION"
}1 5.5.0+dev0-2025-04-28
2
3 # Starting with OCaml 4.14, although the version string that appears above is
4 # still correct and this file can thus still be used to figure it out,
5 # the version itself is actually defined in the build-aux/ocaml_version.m4
6 # file (See the OCAML__VERSION* macros there.)
7 # To update the present VERSION file:
8 # 1. Update build-aux/ocaml_version.m4
9 # 2. Run tools/autogen.
10 # 3. If you are in a context where version control matters,
11 # commit the changes to both build-aux/ocaml_version.m4 and VERSION.
12 # The version string must be in the format described in stdlib/sys.mli
13
[metadata] {"type": "text", "file": {"filePath": "/app/ocaml/VERSION", "content": "5.5.0+dev0-2025-04-28\n\n# Starting with OCaml 4.14, although the version string that appears above is\n# still correct and this file can thus still be used to figure it out,\n# the version itself is actually defined in the build-aux/ocaml_version.m4\n# file (See the OCAML__VERSION* macros there.)\n# To update the present VERSION file:\n# 1. Update build-aux/ocaml_version.m4\n# 2. Run tools/autogen.\n# 3. If you are in a context where version control matters,\n# commit the changes to both build-aux/ocaml_version.m4 and VERSION.\n# The version string must be in the format described in stdlib/sys.mli\n", "numLines": 13, "startLine": 1, "totalLines": 13}}{
"replace_all": false,
"file_path": "/app/ocaml/runtime/shared_heap.c",
"old_string": " /* add the free blocks following this block, skipping over them */\n p += wh * Wosize_hd(hd);\n } else {\n /* there's still a live block, the pool can't be released to the global\n freelist */\n release_to_global_pool = 0;\n }\n p += Whsize_hd(hd);\n } while (p + wh <= end);",
"new_string": " /* add the free blocks following this block, skipping over them */\n p += wh * Wosize_hd(hd);\n } else {\n /* there's still a live block, the pool can't be released to the global\n freelist */\n release_to_global_pool = 0;\n }\n /* Advance to the next block. Note that [wh] (the size class block size)\n must be used here, not [Whsize_hd(hd)]: live blocks may be smaller\n than their size class, and a free run's wosize counts the *extra*\n free blocks that follow (already skipped above). */\n p += wh;\n } while (p + wh <= end);"
}The file /app/ocaml/runtime/shared_heap.c has been updated successfully. (file state is current in your context — no need to Read it back)
[metadata] {"filePath": "/app/ocaml/runtime/shared_heap.c", "oldString": " /* add the free blocks following this block, skipping over them */\n p += wh * Wosize_hd(hd);\n } else {\n /* there's still a live block, the pool can't be released to the global\n freelist */\n release_to_global_pool = 0;\n }\n p += Whsize_hd(hd);\n } while (p + wh <= end);", "newString": " /* add the free blocks following this block, skipping over them */\n p += wh * Wosize_hd(hd);\n } else {\n /* there's still a live block, the pool can't be released to the global\n freelist */\n release_to_global_pool = 0;\n }\n /* Advance to the next block. Note that [wh] (the size class block size)\n must be used here, not [Whsize_hd(hd)]: live blocks may be smaller\n than their size class, and a free run's wosize counts the *extra*\n free blocks that follow (already skipped above). */\n p += wh;\n } while (p + wh <= end);", "originalFile": null, "structuredPatch": [{"oldStart": 647, "oldLines": 7, "newStart": 647, "newLines": 11, "lines": [" freelist */", " release_to_global_pool = 0;", " }", "- p += Whsize_hd(hd);", "+ /* Advance to the next block. Note that [wh] (the size class block size)", "+ must be used here, not [Whsize_hd(hd)]: live blocks may be smaller", "+ than their size class, and a free run's wosize counts the *extra*", "+ free blocks that follow (already skipped above). */", "+ p += wh;", " } while (p + wh <= end);", " CAMLassert(p == end);", " "]}], "userModified": false, "replaceAll": false}{
"command": "grep -n \"pool\\|shared_heap\\|POOL\\|next_obj\\|sz_class\\|sizeclass\" runtime/major_gc.c | head -60",
"description": "Find pool walking in major GC"
}39:#include "caml/shared_heap.h"
55: Sweep changes GARBAGE coloured objects in the domain's own pools to FREE
57: list. No object will have the GARBAGE colour in the domain's own pools since
58: the domain starts with an empty pool with no objects and new objects are
781: heap_size = caml_heap_size(dom_st->shared_heap);
933: that can be in a pool, see POOL_WSIZE */
1069: uintnat local_heap_bsize = caml_heap_size(Caml_state->shared_heap);
1215: * initializing writes in shared_heap.c allocation (#12894) */
1272: * with initializing writes in shared_heap.c allocation (#12894) */
1496: heap_words = s.heap_stats.pool_words + s.heap_stats.large_words;
1497: not_garbage_words = s.heap_stats.pool_live_words
1609: caml_cycle_heap(domain->shared_heap);
1623: caml_collect_heap_stats_sample(Caml_state->shared_heap, &local_stats);
1625: CAML_EV_COUNTER(EV_C_MAJOR_HEAP_POOL_WORDS,
1626: (uintnat)local_stats.pool_words);
1627: CAML_EV_COUNTER(EV_C_MAJOR_HEAP_POOL_LIVE_WORDS,
1628: (uintnat)local_stats.pool_live_words);
1631: CAML_EV_COUNTER(EV_C_MAJOR_HEAP_POOL_FRAG_WORDS,
1632: (uintnat)(local_stats.pool_frag_words));
1633: CAML_EV_COUNTER(EV_C_MAJOR_HEAP_POOL_LIVE_BLOCKS,
1634: (uintnat)local_stats.pool_live_blocks);
1844: intnat left = caml_sweep(domain_state->shared_heap, budget);
2158: if (caml_sweep(Caml_state->shared_heap, 10) > 0) {
[stdout]
39:#include "caml/shared_heap.h"
55: Sweep changes GARBAGE coloured objects in the domain's own pools to FREE
57: list. No object will have the GARBAGE colour in the domain's own pools since
58: the domain starts with an empty pool with no objects and new objects are
781: heap_size = caml_heap_size(dom_st->shared_heap);
933: that can be in a pool, see POOL_WSIZE */
1069: uintnat local_heap_bsize = caml_heap_size(Caml_state->shared_heap);
1215: * initializing writes in shared_heap.c allocation (#12894) */
1272: * with initializing writes in shared_heap.c allocation (#12894) */
1496: heap_words = s.heap_stats.pool_words + s.heap_stats.large_words;
1497: not_garbage_words = s.heap_stats.pool_live_words
1609: caml_cycle_heap(domain->shared_heap);
1623: caml_collect_heap_stats_sample(Caml_state->shared_heap, &local_stats);
1625: CAML_EV_COUNTER(EV_C_MAJOR_HEAP_POOL_WORDS,
1626: (uintnat)local_stats.pool_words);
1627: CAML_EV_COUNTER(EV_C_MAJOR_HEAP_POOL_LIVE_WORDS,
1628: (uintnat)local_stats.pool_live_words);
1631: CAML_EV_COUNTER(EV_C_MAJOR_HEAP_POOL_FRAG_WORDS,
1632: (uintnat)(local_stats.pool_frag_words));
1633: CAML_EV_COUNTER(EV_C_MAJOR_HEAP_POOL_LIVE_BLOCKS,
1634: (uintnat)local_stats.pool_live_blocks);
1844: intnat left = caml_sweep(domain_state->shared_heap, budget);
2158: if (caml_sweep(Caml_state->shared_heap, 10) > 0) {
[metadata] {"noOutputExpected": false}{
"command": "./configure --enable-ocamltest 2>&1 | tail -30",
"description": "Configure OCaml build with ocamltest"
}configure: creating ./config.status
config.status: creating Makefile.build_config
config.status: creating Makefile.config
config.status: creating stdlib/sys.ml
config.status: creating manual/src/version.tex
config.status: creating manual/src/html_processing/src/common.ml
config.status: creating otherlibs/dynlink/dynlink_config.ml
config.status: creating utils/config.common.ml
config.status: creating utils/config.generated.ml
config.status: creating compilerlibs/META
config.status: creating otherlibs/dynlink/META
config.status: creating otherlibs/runtime_events/META
config.status: creating stdlib/META
config.status: creating ocamldoc/META
config.status: creating otherlibs/unix/META
config.status: creating otherlibs/str/META
config.status: creating otherlibs/systhreads/META
config.status: creating ocamltest/ocamltest_config.ml
config.status: creating runtime/caml/exec.h
config.status: creating runtime/caml/m.h
config.status: creating runtime/caml/s.h
config.status: creating runtime/caml/version.h
config.status: linking file_formats/cmo_format.mli to otherlibs/dynlink/dynlink_cmo_format.mli
config.status: linking file_formats/cmxs_format.mli to otherlibs/dynlink/dynlink_cmxs_format.mli
config.status: linking otherlibs/dynlink/dynlink_platform_intf.ml to otherlibs/dynlink/dynlink_platform_intf.mli
config.status: linking otherlibs/unix/unix_unix.ml to otherlibs/unix/unix.ml
config.status: linking ocamltest/ocamltest_unix_real.ml to ocamltest/ocamltest_unix.ml
config.status: executing libtool commands
config.status: executing shebang commands
config.status: executing links commands
[stdout]
configure: creating ./config.status
config.status: creating Makefile.build_config
config.status: creating Makefile.config
config.status: creating stdlib/sys.ml
config.status: creating manual/src/version.tex
config.status: creating manual/src/html_processing/src/common.ml
config.status: creating otherlibs/dynlink/dynlink_config.ml
config.status: creating utils/config.common.ml
config.status: creating utils/config.generated.ml
config.status: creating compilerlibs/META
config.status: creating otherlibs/dynlink/META
config.status: creating otherlibs/runtime_events/META
config.status: creating stdlib/META
config.status: creating ocamldoc/META
config.status: creating otherlibs/unix/META
config.status: creating otherlibs/str/META
config.status: creating otherlibs/systhreads/META
config.status: creating ocamltest/ocamltest_config.ml
config.status: creating runtime/caml/exec.h
config.status: creating runtime/caml/m.h
config.status: creating runtime/caml/s.h
config.status: creating runtime/caml/version.h
config.status: linking file_formats/cmo_format.mli to otherlibs/dynlink/dynlink_cmo_format.mli
config.status: linking file_formats/cmxs_format.mli to otherlibs/dynlink/dynlink_cmxs_format.mli
config.status: linking otherlibs/dynlink/dynlink_platform_intf.ml to otherlibs/dynlink/dynlink_platform_intf.mli
config.status: linking otherlibs/unix/unix_unix.ml to otherlibs/unix/unix.ml
config.status: linking ocamltest/ocamltest_unix_real.ml to ocamltest/ocamltest_unix.ml
config.status: executing libtool commands
config.status: executing shebang commands
config.status: executing links commands
[metadata] {"noOutputExpected": false}{
"command": "make -j$(nproc) 2>&1 | tail -80",
"description": "Build the OCaml compiler",
"timeout": 600000
}OCAMLDOC build/libref/scanf.odoc OCAMLDOC build/libref/semaphore.odoc OCAMLDOC build/libref/seq.odoc OCAMLDOC build/libref/set.odoc OCAMLDOC build/libref/stack.odoc OCAMLDOC build/libref/stdLabels.odoc OCAMLDOC build/libref/stdlib.odoc OCAMLDOC build/libref/str.odoc OCAMLDOC build/libref/string.odoc OCAMLDOC build/libref/stringLabels.odoc OCAMLDOC build/libref/sys.odoc OCAMLDOC build/libref/thread.odoc OCAMLDOC build/libref/type.odoc OCAMLDOC build/libref/uchar.odoc OCAMLDOC build/libref/unit.odoc OCAMLDOC build/libref/unix.odoc OCAMLDOC build/libref/unixLabels.odoc OCAMLDOC build/libref/weak.odoc OCAMLDOC build/libref/camlinternalFormat.odoc OCAMLDOC build/libref/camlinternalFormatBasics.odoc OCAMLDOC build/libref/camlinternalLazy.odoc OCAMLDOC build/libref/camlinternalMod.odoc OCAMLDOC build/libref/camlinternalOO.odoc GEN build/Compiler_libs.mld OCAMLDOC build/compilerlibref/ast_helper.odoc OCAMLDOC build/compilerlibref/ast_invariants.odoc OCAMLDOC build/compilerlibref/ast_iterator.odoc OCAMLDOC build/compilerlibref/ast_mapper.odoc OCAMLDOC build/compilerlibref/asttypes.odoc OCAMLDOC build/compilerlibref/attr_helper.odoc OCAMLDOC build/compilerlibref/builtin_attributes.odoc OCAMLDOC build/compilerlibref/camlinternalMenhirLib.odoc OCAMLDOC build/compilerlibref/depend.odoc OCAMLDOC build/compilerlibref/docstrings.odoc OCAMLDOC build/compilerlibref/lexer.odoc OCAMLDOC build/compilerlibref/location.odoc OCAMLDOC build/compilerlibref/longident.odoc OCAMLDOC build/compilerlibref/parse.odoc OCAMLDOC build/compilerlibref/parser.odoc OCAMLDOC build/compilerlibref/parsetree.odoc OCAMLDOC build/compilerlibref/pprintast.odoc OCAMLDOC build/compilerlibref/printast.odoc OCAMLDOC build/compilerlibref/syntaxerr.odoc OCAMLDOC build/compilerlibref/unit_info.odoc OCAMLDOC build/compilerlibref/arg_helper.odoc OCAMLDOC build/compilerlibref/binutils.odoc OCAMLDOC build/compilerlibref/build_path_prefix_map.odoc OCAMLDOC build/compilerlibref/ccomp.odoc OCAMLDOC build/compilerlibref/clflags.odoc OCAMLDOC build/compilerlibref/compression.odoc OCAMLDOC build/compilerlibref/config.odoc OCAMLDOC build/compilerlibref/config_boot.odoc OCAMLDOC build/compilerlibref/config_main.odoc OCAMLDOC build/compilerlibref/consistbl.odoc OCAMLDOC build/compilerlibref/diffing.odoc OCAMLDOC build/compilerlibref/diffing_with_keys.odoc OCAMLDOC build/compilerlibref/domainstate.odoc OCAMLDOC build/compilerlibref/format_doc.odoc OCAMLDOC build/compilerlibref/identifiable.odoc OCAMLDOC build/compilerlibref/int_replace_polymorphic_compare.odoc OCAMLDOC build/compilerlibref/lazy_backtrack.odoc OCAMLDOC build/compilerlibref/linkdeps.odoc OCAMLDOC build/compilerlibref/load_path.odoc OCAMLDOC build/compilerlibref/local_store.odoc OCAMLDOC build/compilerlibref/misc.odoc OCAMLDOC build/compilerlibref/numbers.odoc OCAMLDOC build/compilerlibref/profile.odoc OCAMLDOC build/compilerlibref/strongly_connected_components.odoc OCAMLDOC build/compilerlibref/targetint.odoc OCAMLDOC build/compilerlibref/terminfo.odoc OCAMLDOC build/compilerlibref/warnings.odoc OCAMLDOC build/compilerlibref/pparse.odoc OCAMLDOC build/libref/Format_tutorial.odoc OCAMLDOC build/libref/Ocaml_operators.odoc OCAMLDOC build/compilerlibref/Compiler_libs.odoc OCAMLDOC build/man/Stdlib.3o make[4]: Leaving directory '/app/ocaml/api_docgen/ocamldoc' make[3]: Leaving directory '/app/ocaml/api_docgen' make[2]: Leaving directory '/app/ocaml' make[1]: Leaving directory '/app/ocaml' [stdout] OCAMLDOC build/libref/scanf.odoc OCAMLDOC build/libref/semaphore.odoc OCAMLDOC build/libref/seq.odoc OCAMLDOC build/libref/set.odoc OCAMLDOC build/libref/stack.odoc OCAMLDOC build/libref/stdLabels.odoc OCAMLDOC build/libref/stdlib.odoc OCAMLDOC build/libref/str.odoc OCAMLDOC build/libref/string.odoc OCAMLDOC build/libref/stringLabels.odoc OCAMLDOC build/libref/sys.odoc OCAMLDOC build/libref/thread.odoc OCAMLDOC build/libref/type.odoc OCAMLDOC build/libref/uchar.odoc OCAMLDOC build/libref/unit.odoc OCAMLDOC build/libref/unix.odoc OCAMLDOC build/libref/unixLabels.odoc OCAMLDOC build/libref/weak.odoc OCAMLDOC build/libref/camlinternalFormat.odoc OCAMLDOC build/libref/camlinternalFormatBasics.odoc OCAMLDOC build/libref/camlinternalLazy.odoc OCAMLDOC build/libref/camlinternalMod.odoc OCAMLDOC build/libref/camlinternalOO.odoc GEN build/Compiler_libs.mld OCAMLDOC build/compilerlibref/ast_helper.odoc OCAMLDOC build/compilerlibref/ast_invariants.odoc OCAMLDOC build/compilerlibref/ast_iterator.odoc OCAMLDOC build/compilerlibref/ast_mapper.odoc OCAMLDOC build/compilerlibref/asttypes.odoc OCAMLDOC build/compilerlibref/attr_helper.odoc OCAMLDOC build/compilerlibref/builtin_attributes.odoc OCAMLDOC build/compilerlibref/camlinternalMenhirLib.odoc OCAMLDOC build/compilerlibref/depend.odoc OCAMLDOC build/compilerlibref/docstrings.odoc OCAMLDOC build/compilerlibref/lexer.odoc OCAMLDOC build/compilerlibref/location.odoc OCAMLDOC build/compilerlibref/longident.odoc OCAMLDOC build/compilerlibref/parse.odoc OCAMLDOC build/compilerlibref/parser.odoc OCAMLDOC build/compilerlibref/parsetree.odoc OCAMLDOC build/compilerlibref/pprintast.odoc OCAMLDOC build/compilerlibref/printast.odoc OCAMLDOC build/compilerlibref/syntaxerr.odoc OCAMLDOC build/compilerlibref/unit_info.odoc OCAMLDOC build/compilerlibref/arg_helper.odoc OCAMLDOC build/compilerlibref/binutils.odoc OCAMLDOC build/compilerlibref/build_path_prefix_map.odoc OCAMLDOC build/compilerlibref/ccomp.odoc OCAMLDOC build/compilerlibref/clflags.odoc OCAMLDOC build/compilerlibref/compression.odoc OCAMLDOC build/compilerlibref/config.odoc OCAMLDOC build/compilerlibref/config_boot.odoc OCAMLDOC build/compilerlibref/config_main.odoc OCAMLDOC build/compilerlibref/consistbl.odoc OCAMLDOC build/compilerlibref/diffing.odoc OC
{
"command": "make -C testsuite one DIR=tests/basic 2>&1 | tail -60",
"description": "Run the basic testsuite",
"timeout": 300000
}make: Entering directory '/app/ocaml/testsuite'
Running tests from 'tests/basic' ...
... testing 'arrays.ml' => passed
... testing 'bigints.ml' => passed
... testing 'boxedints.ml' => passed
... testing 'constprop.ml.c' => passed
... testing 'divint.ml' => passed
... testing 'equality.ml' => passed
... testing 'eval_order_1.ml' => passed
... testing 'eval_order_2.ml' => passed
... testing 'eval_order_3.ml' => passed
... testing 'eval_order_4.ml' => passed
... testing 'eval_order_6.ml' => passed
... testing 'eval_order_7.ml' => passed
... testing 'eval_order_8.ml' => passed
... testing 'eval_order_9.ml' => passed
... testing 'eval_order_pr10283.ml' => passed
... testing 'float.ml' => passed
... testing 'float_physical_equality.ml' => passed
... testing 'includestruct.ml' => passed
... testing 'localexn.ml' => passed
... testing 'localfunction.ml' => passed
... testing 'maps.ml' => passed
... testing 'min_int.ml' => passed
... testing 'objects.ml' => passed
... testing 'opt_variants.ml' => passed
... testing 'patmatch.ml' => passed
... testing 'patmatch_for_multiple.ml' => passed
... testing 'patmatch_incoherence.ml' => passed
... testing 'patmatch_split_no_or.ml' => passed
... testing 'pr7253.ml' => passed
... testing 'pr7533.ml' => passed
... testing 'pr7657.ml' => passed
... testing 'recvalues.ml' => passed
... testing 'sets.ml' => passed
... testing 'stringmatch.ml' => passed
... testing 'switch_opts.ml' => passed
... testing 'tailcalls.ml' => passed
... testing 'trigraph.ml' => passed
... testing 'tuple_match.ml' => passed
... testing 'unit_naming.ml' => passed
... testing 'zero_divided_by_n.ml' => passed
make[1]: Entering directory '/app/ocaml/testsuite'
make[1]: Leaving directory '/app/ocaml/testsuite'
make[1]: Entering directory '/app/ocaml/testsuite'
Summary:
40 tests passed
0 tests skipped
0 tests failed
0 tests not started (parent test skipped or failed)
0 unexpected errors
40 tests considered
make[1]: Leaving directory '/app/ocaml/testsuite'
make: Leaving directory '/app/ocaml/testsuite'
[stdout]
make: Entering directory '/app/ocaml/testsuite'
Running tests from 'tests/basic' ...
... testing 'arrays.ml' => passed
... testing 'bigints.ml' => passed
... testing 'boxedints.ml' => passed
... testing 'constprop.ml.c' => passed
... testing 'divint.ml' => passed
... testing 'equality.ml' => passed
... testing 'eval_order_1.ml' => passed
... testing 'eval_order_2.ml' => passed
... testing 'eval_order_3.ml' => passed
... testing 'eval_order_4.ml' => passed
... testing 'eval_order_6.ml' => passed
... testing 'eval_order_7.ml' => passed
... testing 'eval_order_8.ml' => passed
... testing 'eval_order_9.ml' => passed
... testing 'eval_order_pr10283.ml' => passed
... testing 'float.ml' => passed
... testing 'float_physical_equality.ml' => passed
... testing 'includestruct.ml' => passed
... testing 'localexn.ml' => passed
... testing 'localfunction.ml' => passed
... testing 'maps.ml' => passed
... testing 'min_int.ml' => passed
... testing 'objects.ml' => passed
... testing 'opt_variants.ml' => passed
... testing 'patmatch.ml' => passed
... testing 'patmatch_for_multiple.ml' => passed
... testing 'patmatch_incoherence.ml' => passed
... testing 'patmatch_split_no_or.ml' => passed
... testing 'pr7253.ml' => passed
... testing 'pr7533.ml' => passed
... testing 'pr7657.ml' => passed
... testing 'recvalues.ml' => passed
... testing 'sets.ml' => passed
... testing 'stringmatch.ml' => passed
... testing 'switch_opts.ml' => passed
... testing 'tailcalls.ml' => passed
... testing 'trigraph.ml' => passed
... testing 'tuple_match.ml' => passed
... testing 'unit_naming.ml' => passed
... testing 'zero_divided_by_n.ml' => passed
make[1]: Entering directory '/app/ocaml/testsuite'
make[1]: Leaving directory '/app/ocaml/testsuite'
make[1]: Entering directory '/app/ocaml/testsuite'
Summary:
40 tests passed
0 tests skipped
0 tests failed
0 tests not started (parent test skipped or failed)
0 unexpected errors
40 tests considered
make[1]: Leaving directory '/app/ocaml/testsuite'
make: Leaving directory '/app/ocaml/testsuite'
[metadata] {"noOutputExpected": false}