{
"description": "Explore GC changes",
"prompt": "I need to understand recent changes to the OCaml garbage collector, specifically around run-length compression of free space in the major heap sweeping. Look at the runtime directory, particularly files related to the GC major heap sweeping. \n\nSearch for:\n1. Files in runtime/ related to major GC, sweeping, free space\n2. Any recent modifications or comments about run-length encoding/compression in the GC\n3. The sweep-related code in the runtime\n\nBe very thorough - look at runtime/major_gc.c, runtime/sweep.c or similar files, and any header files that define GC-related structures. Focus on understanding how free space is tracked and swept.",
"subagent_type": "Explore"
}{"type": "text", "text": "Async agent launched successfully. (This tool result is internal metadata — never quote or paste any part of it, including the agentId below, into a user-facing reply.)\nagentId: afb720da37251b063 (internal ID - do not mention to user. Use SendMessage with to: 'afb720da37251b063', summary: '<5-10 word recap>' to continue this agent.)\nThe agent is working in the background. You will be notified automatically when it completes. You know nothing about its results until that notification arrives — do not report, assume, or predict them; continue other work or respond to the user in the meantime.\nDo not duplicate this agent's work — avoid working with the same files or topics it is using.\noutput_file: /tmp/claude-0/-app/9e16eda3-781a-4be3-944a-a8afac6ad098/tasks/afb720da37251b063.output\nDo NOT Read or tail this file via the shell tool — it is the full subagent JSONL transcript and reading it will overflow your context. If the user asks for progress, say the agent is still running; you'll get a completion notification."}
[metadata] {"isAsync": true, "status": "async_launched", "agentId": "afb720da37251b063", "description": "Explore GC changes", "resolvedModel": "mimo-v2.5-pro", "prompt": "I need to understand recent changes to the OCaml garbage collector, specifically around run-length compression of free space in the major heap sweeping. Look at the runtime directory, particularly files related to the GC major heap sweeping. \n\nSearch for:\n1. Files in runtime/ related to major GC, sweeping, free space\n2. Any recent modifications or comments about run-length encoding/compression in the GC\n3. The sweep-related code in the runtime\n\nBe very thorough - look at runtime/major_gc.c, runtime/sweep.c or similar files, and any header files that define GC-related structures. Focus on understanding how free space is tracked and swept.", "outputFile": "/tmp/claude-0/-app/9e16eda3-781a-4be3-944a-a8afac6ad098/tasks/afb720da37251b063.output", "canReadOutputFile": true}{
"file_path": "/app/HACKING.adoc"
}File does not exist. Note: your current working directory is /app. [error] tool reported failure
{
"command": "ls /app/ | head -40",
"description": "List top-level directory contents"
}ocaml
[stdout]
ocaml
[metadata] {"noOutputExpected": false}{
"command": "find /app -name \"HACKING.adoc\" -o -name \"HACKING\" 2>/dev/null | head -5",
"description": "Find HACKING file"
}/app/ocaml/HACKING.adoc
/app/ocaml/typing/HACKING.adoc
/app/ocaml/utils/HACKING.adoc
/app/ocaml/parsing/HACKING.adoc
/app/ocaml/runtime/HACKING.adoc
[stdout]
/app/ocaml/HACKING.adoc
/app/ocaml/typing/HACKING.adoc
/app/ocaml/utils/HACKING.adoc
/app/ocaml/parsing/HACKING.adoc
/app/ocaml/runtime/HACKING.adoc
[metadata] {"noOutputExpected": false}{
"file_path": "/app/ocaml/HACKING.adoc"
}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 log --oneline -20",
"description": "Check recent git history"
}Exit code 128 fatal: not a git repository (or any of the parent directories): .git [error] tool reported failure
{
"command": "git log --oneline -20",
"description": "Check recent git history"
}Exit code 128 fatal: not a git repository (or any of the parent directories): .git [error] tool reported failure
{
"command": "git diff --name-only HEAD~1 2>/dev/null || git diff --stat 2>/dev/null || echo \"checking other ways...\" && git status --short 2>/dev/null",
"description": "Find changed files"
}Exit code 128 checking other ways... [error] tool reported failure
{
"command": "git diff --name-only HEAD~1",
"description": "Find changed files"
}Exit code 129
warning: Not a git repository. Use --no-index to compare two paths outside a working tree
usage: git diff --no-index [<options>] <path> <path>
Diff output format options
-p, --patch generate patch
-s, --no-patch suppress diff output
-u generate patch
-U, --unified[=<n>] generate diffs with <n> lines context
-W, --[no-]function-context
generate diffs with <n> lines context
--raw generate the diff in raw format
--patch-with-raw synonym for '-p --raw'
--patch-with-stat synonym for '-p --stat'
--numstat machine friendly --stat
--shortstat output only the last line of --stat
-X, --dirstat[=<param1,param2>...]
output the distribution of relative amount of changes for each sub-directory
--cumulative synonym for --dirstat=cumulative
--dirstat-by-file[=<param1,param2>...]
synonym for --dirstat=files,param1,param2...
--check warn if changes introduce conflict markers or whitespace errors
--summary condensed summary such as creations, renames and mode changes
--name-only show only names of changed files
--name-status show only names and status of changed files
--stat[=<width>[,<name-width>[,<count>]]]
generate diffstat
--stat-width <width> generate diffstat with a given width
--stat-name-width <width>
generate diffstat with a given name width
--stat-graph-width <width>
generate diffstat with a given graph width
--stat-count <count> generate diffstat with limited lines
--[no-]compact-summary
generate compact summary in diffstat
--binary output a binary diff that can be applied
--[no-]full-index show full pre- and post-image object names on the "index" lines
--[no-]color[=<when>] show colored diff
--ws-error-highlight <kind>
highlight whitespace errors in the 'context', 'old' or 'new' lines in the diff
-z do not munge pathnames and use NULs as output field terminators in --raw or --numstat
--[no-]abbrev[=<n>] use <n> digits to display object names
--src-prefix <prefix> show the given source prefix instead of "a/"
--dst-prefix <prefix> show the given destination prefix instead of "b/"
--line-prefix <prefix>
prepend an additional prefix to every line of output
--no-prefix do not show any source or destination prefix
--default-prefix use default prefixes a/ and b/
--inter-hunk-context <n>
show context between diff hunks up to the specified number of lines
--output-indicator-new <char>
specify the character to indicate a new line instead of '+'
--output-indicator-old <char>
specify the character to indicate an old line instead of '-'
--output-indicator-context <char>
specify the character to indicate a context instead of ' '
Diff rename options
-B, --break-rewrites[=<n>[/<m>]]
break complete rewrite changes into pairs of delete and create
-M, --find-renames[=<n>]
detect renames
-D, --irreversible-delete
omit the preimage for deletes
-C, --find-copies[=<n>]
detect copies
--[no-]find-copies-harder
use unmodified files as source to find copies
--no-renames disable rename detection
--[no-]rename-empty use empty blobs as rename source
--[no-]follow continue listing the history of a file beyond renames
-l <n> prevent rename/copy detection if the number of rename/copy targets exceeds given limit
Diff algorithm options
--minimal produce the smallest possible diff
-w, --ignore-all-space
ignore whitespace when comparing lines
-b, --ignore-space-change
ignore changes in amount of whitespace
--ignore-space-at-eol ignore changes in whitespace at EOL
--ignore-cr-at-eol ignore carrier-return at the end of line
--ignore-blank-lines ignore changes whose lines are all blank
-I, --[no-]ignore-matching-lines <regex>
ignore changes whose all lines match <regex>
--[no-]indent-heuristic
heuristic to shift diff hunk boundaries for easy reading
--patience generate diff using the "patience diff" algorithm
--histogram generate diff using the "histogram diff" algorithm
--diff-algorithm <algorithm>
choose a diff algorithm
--anchored <text> generate diff using the "anchored diff" algorithm
--word-diff[=<mode>] show word diff, using <mode> to delimit changed words
--word-diff-regex <regex>
use <regex> to decide what a word is
--color-words[=<regex>]
equivalent to --word-diff=color --word-diff-regex=<regex>
--[no-]color-moved[=<mode>]
moved lines of code are colored differently
--[no-]color-moved-ws <mode>
how white spaces are ignored in --color-moved
Other diff options
--[no-]relative[=<prefix>]
when run from subdir, exclude changes outside and show relative paths
-a, --[no-]text treat all files as text
-R swap two inputs, reverse the diff
--[no-]exit-code exit with 1 if there were differences, 0 otherwise
--[no-]quiet disable all output of the program
--[no-]ext-diff allow an external diff helper to be executed
--[n{
"command": "git log --oneline -20",
"description": "Check recent git history"
}Exit code 128 fatal: not a git repository (or any of the parent directories): .git [error] tool reported failure
{
"command": "git log --oneline -20",
"description": "Check recent git history in ocaml directory"
}Exit code 128 fatal: not a git repository (or any of the parent directories): .git [error] tool reported failure
{
"command": "git diff --name-only HEAD~1",
"description": "Find changed files in last commit"
}Exit code 129
warning: Not a git repository. Use --no-index to compare two paths outside a working tree
usage: git diff --no-index [<options>] <path> <path>
Diff output format options
-p, --patch generate patch
-s, --no-patch suppress diff output
-u generate patch
-U, --unified[=<n>] generate diffs with <n> lines context
-W, --[no-]function-context
generate diffs with <n> lines context
--raw generate the diff in raw format
--patch-with-raw synonym for '-p --raw'
--patch-with-stat synonym for '-p --stat'
--numstat machine friendly --stat
--shortstat output only the last line of --stat
-X, --dirstat[=<param1,param2>...]
output the distribution of relative amount of changes for each sub-directory
--cumulative synonym for --dirstat=cumulative
--dirstat-by-file[=<param1,param2>...]
synonym for --dirstat=files,param1,param2...
--check warn if changes introduce conflict markers or whitespace errors
--summary condensed summary such as creations, renames and mode changes
--name-only show only names of changed files
--name-status show only names and status of changed files
--stat[=<width>[,<name-width>[,<count>]]]
generate diffstat
--stat-width <width> generate diffstat with a given width
--stat-name-width <width>
generate diffstat with a given name width
--stat-graph-width <width>
generate diffstat with a given graph width
--stat-count <count> generate diffstat with limited lines
--[no-]compact-summary
generate compact summary in diffstat
--binary output a binary diff that can be applied
--[no-]full-index show full pre- and post-image object names on the "index" lines
--[no-]color[=<when>] show colored diff
--ws-error-highlight <kind>
highlight whitespace errors in the 'context', 'old' or 'new' lines in the diff
-z do not munge pathnames and use NULs as output field terminators in --raw or --numstat
--[no-]abbrev[=<n>] use <n> digits to display object names
--src-prefix <prefix> show the given source prefix instead of "a/"
--dst-prefix <prefix> show the given destination prefix instead of "b/"
--line-prefix <prefix>
prepend an additional prefix to every line of output
--no-prefix do not show any source or destination prefix
--default-prefix use default prefixes a/ and b/
--inter-hunk-context <n>
show context between diff hunks up to the specified number of lines
--output-indicator-new <char>
specify the character to indicate a new line instead of '+'
--output-indicator-old <char>
specify the character to indicate an old line instead of '-'
--output-indicator-context <char>
specify the character to indicate a context instead of ' '
Diff rename options
-B, --break-rewrites[=<n>[/<m>]]
break complete rewrite changes into pairs of delete and create
-M, --find-renames[=<n>]
detect renames
-D, --irreversible-delete
omit the preimage for deletes
-C, --find-copies[=<n>]
detect copies
--[no-]find-copies-harder
use unmodified files as source to find copies
--no-renames disable rename detection
--[no-]rename-empty use empty blobs as rename source
--[no-]follow continue listing the history of a file beyond renames
-l <n> prevent rename/copy detection if the number of rename/copy targets exceeds given limit
Diff algorithm options
--minimal produce the smallest possible diff
-w, --ignore-all-space
ignore whitespace when comparing lines
-b, --ignore-space-change
ignore changes in amount of whitespace
--ignore-space-at-eol ignore changes in whitespace at EOL
--ignore-cr-at-eol ignore carrier-return at the end of line
--ignore-blank-lines ignore changes whose lines are all blank
-I, --[no-]ignore-matching-lines <regex>
ignore changes whose all lines match <regex>
--[no-]indent-heuristic
heuristic to shift diff hunk boundaries for easy reading
--patience generate diff using the "patience diff" algorithm
--histogram generate diff using the "histogram diff" algorithm
--diff-algorithm <algorithm>
choose a diff algorithm
--anchored <text> generate diff using the "anchored diff" algorithm
--word-diff[=<mode>] show word diff, using <mode> to delimit changed words
--word-diff-regex <regex>
use <regex> to decide what a word is
--color-words[=<regex>]
equivalent to --word-diff=color --word-diff-regex=<regex>
--[no-]color-moved[=<mode>]
moved lines of code are colored differently
--[no-]color-moved-ws <mode>
how white spaces are ignored in --color-moved
Other diff options
--[no-]relative[=<prefix>]
when run from subdir, exclude changes outside and show relative paths
-a, --[no-]text treat all files as text
-R swap two inputs, reverse the diff
--[no-]exit-code exit with 1 if there were differences, 0 otherwise
--[no-]quiet disable all output of the program
--[no-]ext-diff allow an external diff helper to be executed
--[n{
"command": "git log --oneline -20",
"description": "Check recent git history"
}Exit code 128 fatal: not a git repository (or any of the parent directories): .git [error] tool reported failure
{
"command": "git diff --name-only HEAD~1 2>/dev/null || git status --short",
"description": "Find changed files"
}Exit code 128 fatal: not a git repository (or any of the parent directories): .git [error] tool reported failure
{
"command": "ls -la /app/ocaml/.git 2>/dev/null; ls /app/ocaml/ | head -30",
"description": "Check for git repo in ocaml directory"
}BOOTSTRAP.adoc
CODE_OF_CONDUCT.md
CONTRIBUTING.md
Changes
HACKING.adoc
INSTALL.adoc
LICENSE
Makefile
Makefile.best_binaries
Makefile.build_config.in
Makefile.common
Makefile.config.in
Makefile.config_if_required
Makefile.cross
Makefile.dev
Makefile.menhir
README.adoc
README.win32.adoc
VERSION
aclocal.m4
api_docgen
appveyor.yml
asmcomp
boot
build-aux
bytecomp
compilerlibs
configure
configure.ac
debugger
[stdout]
BOOTSTRAP.adoc
CODE_OF_CONDUCT.md
CONTRIBUTING.md
Changes
HACKING.adoc
INSTALL.adoc
LICENSE
Makefile
Makefile.best_binaries
Makefile.build_config.in
Makefile.common
Makefile.config.in
Makefile.config_if_required
Makefile.cross
Makefile.dev
Makefile.menhir
README.adoc
README.win32.adoc
VERSION
aclocal.m4
api_docgen
appveyor.yml
asmcomp
boot
build-aux
bytecomp
compilerlibs
configure
configure.ac
debugger
[metadata] {"noOutputExpected": false}{
"command": "ls /app/ocaml/runtime/*.c | grep -iE 'sweep|major|gc|free' 2>/dev/null",
"description": "Find GC-related C files"
}/app/ocaml/runtime/gc_ctrl.c
/app/ocaml/runtime/gc_stats.c
/app/ocaml/runtime/major_gc.c
/app/ocaml/runtime/minor_gc.c
[stdout]
/app/ocaml/runtime/gc_ctrl.c
/app/ocaml/runtime/gc_stats.c
/app/ocaml/runtime/major_gc.c
/app/ocaml/runtime/minor_gc.c
[metadata] {"noOutputExpected": false}{
"command": "ls /app/ocaml/runtime/caml/*.h | grep -iE 'sweep|major|gc|free|heap' 2>/dev/null",
"description": "Find GC-related header files"
}/app/ocaml/runtime/caml/gc.h
/app/ocaml/runtime/caml/gc_ctrl.h
/app/ocaml/runtime/caml/gc_stats.h
/app/ocaml/runtime/caml/major_gc.h
/app/ocaml/runtime/caml/minor_gc.h
/app/ocaml/runtime/caml/shared_heap.h
[stdout]
/app/ocaml/runtime/caml/gc.h
/app/ocaml/runtime/caml/gc_ctrl.h
/app/ocaml/runtime/caml/gc_stats.h
/app/ocaml/runtime/caml/major_gc.h
/app/ocaml/runtime/caml/minor_gc.h
/app/ocaml/runtime/caml/shared_heap.h
[metadata] {"noOutputExpected": false}{
"file_path": "/app/ocaml/runtime/major_gc.c"
}1 /**************************************************************************/
2 /* */
3 /* OCaml */
4 /* */
5 /* Damien Doligez, projet Para, INRIA Rocquencourt */
6 /* */
7 /* Copyright 1996 Institut National de Recherche en Informatique et */
8 /* en Automatique. */
9 /* */
10 /* All rights reserved. This file is distributed under the terms of */
11 /* the GNU Lesser General Public License version 2.1, with the */
12 /* special exception on linking described in the file LICENSE. */
13 /* */
14 /**************************************************************************/
15
16 #define CAML_INTERNALS
17
18 #include <stdlib.h>
19 #include <string.h>
20 #include <math.h>
21 #include <stdbool.h>
22
23 #include "caml/addrmap.h"
24 #include "caml/config.h"
25 #include "caml/codefrag.h"
26 #include "caml/domain.h"
27 #include "caml/runtime_events.h"
28 #include "caml/fail.h"
29 #include "caml/fiber.h"
30 #include "caml/finalise.h"
31 #include "caml/globroots.h"
32 #include "caml/gc_stats.h"
33 #include "caml/memory.h"
34 #include "caml/memprof.h"
35 #include "caml/mlvalues.h"
36 #include "caml/platform.h"
37 #include "caml/roots.h"
38 #include "caml/signals.h"
39 #include "caml/shared_heap.h"
40 #include "caml/startup_aux.h"
41 #include "caml/weak.h"
42
43 /* Default speed setting for the major GC. */
44 _Atomic uintnat caml_percent_free = Percent_free_def;
45
46 /* This variable is only written with the world stopped, so it need not be
47 atomic */
48 uintnat caml_major_cycles_completed = 0;
49
50 /* [num_domains_to_sweep] records the number of domains to sweep in the current
51 major cycle. The number is set to the [num_domains_in_stw] at the start of
52 the cycle and _strictly decreases_ to 0.
53
54 Domains created in a given cycle will not have any sweep work in that cycle.
55 Sweep changes GARBAGE coloured objects in the domain's own pools to FREE
56 (not a distinct colour; object header is set to 0) and adds them to the 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
59 allocated with colour MARKED. Hence, they do not affect
60 [num_domains_to_sweep].
61
62 Terminating domains terminate after sweeping is complete for their domain.
63 */
64 static atomic_uintnat num_domains_to_sweep;
65
66 /* [num_domains_to_mark] records the number of domains to mark in the current
67 major cycle. The number is set to the [num_domains_in_stw] at the start of
68 the cycle. The value of [num_domains_to_mark] may decrease or increase.
69
70 [num_domains_to_mark] may grow larger than the value of [num_domains_in_stw]
71 at the start of the cycle. This is because [caml_modify] may push a block
72 into a potentially empty mark stack of the newly spawned domain.
73
74 Terminating domains empty their mark stack before terminating. */
75 static atomic_uintnat num_domains_to_mark;
76
77 /* [num_domains_to_ephe_sweep] is set to the [participating_count] at the start
78 of the [Phase_sweep_ephe] and strictly decreases. */
79 static atomic_uintnat num_domains_to_ephe_sweep;
80
81 /* [num_domains_to_final_update_first] and [num_domains_to_final_update_last]
82 are initialised to [num_domains_in_stw] at the start of the cycle. Whenever
83 a domain finishes processing its first or last finalisers, it decrements the
84 appropriate counter.
85
86 Newly created domains increment both the counters. Terminating domain
87 orphans its finalisers and then decrements the counters. See
88 [caml_final_domain_terminate]. */
89 static atomic_uintnat num_domains_to_final_update_first;
90 static atomic_uintnat num_domains_to_final_update_last;
91
92 /* When domains terminate, they will orphan their finalisers. As mentioned in
93 the comment attached to [num_domains_to_final_update_*] counters, a domain
94 will decrement the counters when the corresponding finalisers are processed
95 for that domain. We would like to preserve this invariant when adopting
96 orphaned finalisers. To this end, we orphan and adopt finalisers only in
97 [Phase_sweep_and_mark_main] when [num_domains_to_final_update_*] counters
98 have not been decremented for the domain yet.
99
100 [num_domains_orphaning_finalisers] keeps a count of the number of domains
101 currently orphaning finalisers. This counter is only used in the
102 [Phase_sweep_and_mark_main] to determine whether to proceed to
103 [Phase_mark_final]. If domains are currently orphaning finalisers, we remain
104 in [Phase_sweep_and_mark_main] so that the orphaned finalisers can be
105 adopted before moving onto [Phase_mark_final] where the [GC.finalise]
106 (finalise first) finalisers are processed. */
107 static atomic_uintnat num_domains_orphaning_finalisers = 0;
108
109 enum global_roots_status{
110 WORK_UNSTARTED,
111 WORK_STARTED
112 };
113 static atomic_uintnat domain_global_roots_started;
114
115 gc_phase_t caml_gc_phase;
116
117 /* The caml_gc_phase global is only ever updated at the end of the STW
118 section, by the last domain leaving a barrier. This means that no
119 synchronization is required on most accesses.
120
121 We know of two situations in the runtime that could run in parallel
122 with a phase update, and cannot safely access the gc phase:
123
124 - The caml_domain_terminate logic runs after th{
"file_path": "/app/ocaml/runtime/caml/shared_heap.h"
}PreToolUse hook did not respond before its timeout (host client may be unreachable). The tool call was not executed; other configured hooks may not have completed. [error] tool reported failure
{
"command": "find /app/ocaml/runtime -name \"*.c\" | xargs grep -l \"run.length\\|rle\\|run_length\\|free_space\\|free_list\\|sweep\" 2>/dev/null | head -20",
"description": "Find files related to sweep and free space"
}PreToolUse hook did not respond before its timeout (host client may be unreachable). The tool call was not executed; other configured hooks may not have completed. [error] tool reported failure
{
"file_path": "/app/ocaml/runtime/caml/shared_heap.h"
}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
17 #ifndef CAML_SHARED_HEAP_H
18 #define CAML_SHARED_HEAP_H
19
20 #ifdef CAML_INTERNALS
21
22 #include "config.h"
23 #include "roots.h"
24 #include "domain.h"
25 #include "misc.h"
26 #include "gc_stats.h"
27
28 CAMLextern atomic_uintnat caml_compactions_count;
29
30 struct caml_heap_state;
31 struct pool;
32
33 struct caml_heap_state* caml_init_shared_heap(void);
34 void caml_adopt_all_orphan_heaps(struct caml_heap_state* heap);
35 void caml_assert_shared_heap_is_empty(struct caml_heap_state *heap);
36
37 // ensures that the shared heap is empty
38 void caml_orphan_shared_heap(struct caml_heap_state* heap);
39
40 // requires that the shared heap is empty
41 void caml_free_shared_heap(struct caml_heap_state* heap);
42
43
44 value* caml_shared_try_alloc(struct caml_heap_state*,
45 mlsize_t, tag_t, reserved_t);
46
47 /* Copy the domain-local heap stats into a heap stats sample. */
48 void caml_collect_heap_stats_sample(
49 struct caml_heap_state* local,
50 struct heap_stats *sample);
51
52 /* Add the global orphaned heap stats into an accumulator. */
53 void caml_accum_orphan_heap_stats(struct heap_stats *acc);
54
55 uintnat caml_heap_size(struct caml_heap_state*);
56 uintnat caml_top_heap_words(struct caml_heap_state*);
57 uintnat caml_heap_blocks(struct caml_heap_state*);
58
59 void caml_compact_heap(caml_domain_state* domain_state,
60 int participating_count,
61 caml_domain_state** participants);
62
63 void caml_shared_unpin(value v);
64
65 /* always readable by all threads
66 written only by a single thread during STW periods */
67 typedef uintnat status;
68 struct global_heap_state {
69 status MARKED, UNMARKED, GARBAGE;
70 };
71 extern struct global_heap_state caml_global_heap_state;
72
73 /* CR mshinwell: ensure this matches [Emitaux] */
74 enum {NOT_MARKABLE = 3 << HEADER_COLOR_SHIFT};
75
76 Caml_inline int Has_status_hd(header_t hd, status s) {
77 return Color_hd(hd) == s;
78 }
79
80 Caml_inline int Has_status_val(value v, status s) {
81 return Has_status_hd(Hd_val(v), s);
82 }
83
84 Caml_inline header_t With_status_hd(header_t hd, status s) {
85 return Hd_with_color(hd, s);
86 }
87
88 Caml_inline int is_garbage(value v) {
89 return Has_status_val(v, caml_global_heap_state.GARBAGE);
90 }
91
92 Caml_inline int is_unmarked(value v) {
93 return Has_status_val(v, caml_global_heap_state.UNMARKED);
94 }
95
96 Caml_inline int is_marked(value v) {
97 return Has_status_val(v, caml_global_heap_state.MARKED);
98 }
99
100 Caml_inline int is_not_markable(value v) {
101 return Has_status_val(v, NOT_MARKABLE);
102 }
103
104 void caml_redarken_pool(struct pool*, scanning_action, void*);
105
106 intnat caml_sweep(struct caml_heap_state*, intnat);
107
108 void caml_cycle_heap_from_stw_single(void);
109
110 /* must be called on each domain
111 (after caml_cycle_heap_from_stw_single) */
112 void caml_cycle_heap(struct caml_heap_state*);
113
114 /* Heap invariant verification (for debugging) */
115 void caml_verify_heap_from_stw(caml_domain_state *domain);
116
117 /* Forces finalisation of all heap-allocated values,
118 disregarding both local and global roots.
119
120 Warning: this function should only be used on runtime shutdown.
121 */
122 void caml_finalise_heap(void);
123
124 void caml_finalise_freelist(void);
125
126 #ifdef DEBUG
127 /* [is_garbage(v)] returns true if [v] is a garbage value */
128 int is_garbage (value);
129 #endif
130
131 #endif /* CAML_INTERNALS */
132
133 #endif /* CAML_SHARED_HEAP_H */
134
[metadata] {"type": "text", "file": {"filePath": "/app/ocaml/runtime/caml/shared_heap.h", "content": "/**************************************************************************/\n/* */\n/* OCaml */\n/* */\n/* KC Sivaramakrishnan, Indian Institute of Technology, Madras */\n/* Stephen Dolan, University of Cambridge */\n/* */\n/* Copyright 2015 Indian Institute of Technology, Madras */\n/* Copyright 2015 University of Cambridge */\n/* */\n/* All rights reserved. This file is distributed under the terms of */\n/* the GNU Lesser General Public License version 2.1, with the */\n/* special exception on linking described in the file LICENSE. */\n/* */\n/{
"command": "ls /app/ocaml/runtime/shared_heap.c",
"description": "Check for shared_heap.c"
}/app/ocaml/runtime/shared_heap.c
[stdout]
/app/ocaml/runtime/shared_heap.c
[metadata] {"noOutputExpected": false}{
"file_path": "/app/ocaml/runtime/shared_heap.c"
}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(!{
"command": "grep -n \"p += wh\\b\\|p += Whsize\" runtime/shared_heap.c",
"description": "Find all pool block advancement patterns"
}Exit code 2 ugrep: warning: runtime/shared_heap.c: No such file or directory [error] tool reported failure
{
"command": "grep -n \"p += wh\\b\\|p += Whsize\" /app/ocaml/runtime/shared_heap.c",
"description": "Find all pool block advancement patterns"
}301: p += wh * Wosize_hd(hd); /* skip contiguous free blocks */
304: p += wh;
644: p += wh * Wosize_hd(hd);
650: p += Whsize_hd(hd);
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;
1438: p += wh;
1590: p += wh;
[stdout]
301: p += wh * Wosize_hd(hd); /* skip contiguous free blocks */
304: p += wh;
644: p += wh * Wosize_hd(hd);
650: p += Whsize_hd(hd);
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;
1438: p += wh;
1590: p += wh;
[metadata] {"noOutputExpected": false}{
"file_path": "/app/ocaml/runtime/shared_heap.c",
"limit": 20,
"offset": 635
}635 } else {
636 /* if we're the first free block then set the next_obj pointer for
637 the pool (which indicates the start of the freelist) */
638 a->next_obj = (value*)p;
639
640 last_free_block = p;
641 }
642
643 /* add the free blocks following this block, skipping over them */
644 p += wh * Wosize_hd(hd);
645 } else {
646 /* there's still a live block, the pool can't be released to the global
647 freelist */
648 release_to_global_pool = 0;
649 }
650 p += Whsize_hd(hd);
651 } while (p + wh <= end);
652 CAMLassert(p == end);
653
654 if( !all_used ) {
[metadata] {"type": "text", "file": {"filePath": "/app/ocaml/runtime/shared_heap.c", "content": " } else {\n /* if we're the first free block then set the next_obj pointer for\n the pool (which indicates the start of the freelist) */\n a->next_obj = (value*)p;\n\n last_free_block = p;\n }\n\n /* 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);\n CAMLassert(p == end);\n\n if( !all_used ) {", "numLines": 20, "startLine": 635, "totalLines": 1684}}{
"replace_all": false,
"file_path": "/app/ocaml/runtime/shared_heap.c",
"old_string": " p += Whsize_hd(hd);\n } while (p + wh <= end);",
"new_string": " 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": " p += Whsize_hd(hd);\n } while (p + wh <= end);", "newString": " p += wh;\n } while (p + wh <= end);", "originalFile": null, "structuredPatch": [{"oldStart": 647, "oldLines": 7, "newStart": 647, "newLines": 7, "lines": [" freelist */", " release_to_global_pool = 0;", " }", "- p += Whsize_hd(hd);", "+ p += wh;", " } while (p + wh <= end);", " CAMLassert(p == end);", " "]}], "userModified": false, "replaceAll": false}{
"command": "ls Makefile.config* config.cache 2>/dev/null; ls configure 2>/dev/null",
"description": "Check if configure has been run already"
}Exit code 2 [error] tool reported failure
{
"command": "ls /app/ocaml/Makefile.config* /app/ocaml/config.cache 2>/dev/null; ls /app/ocaml/configure 2>/dev/null",
"description": "Check for configure and Makefile.config"
}/app/ocaml/Makefile.config.in
/app/ocaml/Makefile.config_if_required
/app/ocaml/configure
[stdout]
/app/ocaml/Makefile.config.in
/app/ocaml/Makefile.config_if_required
/app/ocaml/configure
[metadata] {"noOutputExpected": false}{
"command": "./configure --disable-ocamldoc --disable-ocamltest 2>&1 | tail -20",
"description": "Configure the OCaml build",
"timeout": 120000
}/bin/bash: line 1: ./configure: No such file or directory
[stdout]
/bin/bash: line 1: ./configure: No such file or directory
[metadata] {"noOutputExpected": false}{
"command": "./configure --disable-ocamldoc --disable-ocamltest 2>&1 | tail -30",
"description": "Configure the OCaml build",
"timeout": 120000
}/bin/bash: line 1: ./configure: No such file or directory
[stdout]
/bin/bash: line 1: ./configure: No such file or directory
[metadata] {"noOutputExpected": false}{
"command": "./configure --disable-ocamldoc --disable-ocamltest 2>&1 | tail -30",
"description": "Configure the OCaml build",
"timeout": 120000
}/bin/bash: line 1: ./configure: No such file or directory
[stdout]
/bin/bash: line 1: ./configure: No such file or directory
[metadata] {"noOutputExpected": false}{
"command": "pwd && cd /app/ocaml && ./configure --disable-ocamldoc --disable-ocamltest 2>&1 | tail -30",
"description": "Configure the OCaml build",
"timeout": 120000
}/app
configure: not using frame pointers
checking whether mmap supports huge pages... yes
checking whether mmap supports MAP_STACK... yes
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 otherlibs/unix/META
config.status: creating otherlibs/str/META
config.status: creating otherlibs/systhreads/META
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: executing libtool commands
config.status: executing shebang commands
config.status: executing links commands
[stdout]
/app
configure: not using frame pointers
checking whether mmap supports huge pages... yes
checking whether mmap supports MAP_STACK... yes
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 otherlibs/unix/META
config.status: creating otherlibs/str/META
config.status: creating otherlibs/systhreads/META
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: executing libtool commands
config.status: executing shebang commands
config.status: executing links commands
[metadata] {"noOutputExpected": false}{
"command": "make -j$(nproc) 2>&1 | tail -40",
"description": "Build the OCaml compiler",
"timeout": 600000
}make[4]: Leaving directory '/app/ocaml/otherlibs/unix'
make[4]: Entering directory '/app/ocaml/otherlibs/str'
make[4]: Nothing to be done for 'all'.
make[4]: Leaving directory '/app/ocaml/otherlibs/str'
make[4]: Entering directory '/app/ocaml/otherlibs/systhreads'
make[4]: Nothing to be done for 'all'.
make[4]: Leaving directory '/app/ocaml/otherlibs/systhreads'
make[3]: Leaving directory '/app/ocaml/otherlibs'
OCAMLOPT lex/syntax.cmx
OCAMLOPT lex/parser.cmx
OCAMLOPT lex/lexgen.cmx
LINKC tools/ocamltex
OCAMLOPT lex/lexer.cmx
OCAMLOPT toplevel/topcommon.cmx
OCAMLOPT toplevel/topprinters.cmx
OCAMLOPT lex/compact.cmx
OCAMLOPT lex/common.cmx
OCAMLOPT toplevel/native/tophooks.cmx
OCAMLOPT toplevel/native/topeval.cmx
OCAMLOPT lex/output.cmx
OCAMLOPT lex/outputbis.cmx
OCAMLOPT toplevel/toploop.cmx
OCAMLOPT lex/main.cmx
LINKOPT lex/ocamllex.opt
OCAMLOPT toplevel/topdirs.cmx
OCAMLOPT toplevel/native/topmain.cmx
OCAMLOPT toplevel/topstart.cmx
make[3]: Leaving directory '/app/ocaml'
make tools-allopt.opt
make[3]: Entering directory '/app/ocaml'
OCAMLOPT tools/ocamldep.cmx
LINKOPT compilerlibs/ocamlmiddleend.cmxa
OCAMLOPT tools/objinfo.cmx
LINKOPT compilerlibs/ocamltoplevel.cmxa
LINKOPT tools/ocamldep.opt
LINKOPT ocamlnat
LINKOPT tools/ocamlobjinfo.opt
make[3]: Leaving directory '/app/ocaml'
make[2]: Leaving directory '/app/ocaml'
make[1]: Leaving directory '/app/ocaml'
[stdout]
make[4]: Leaving directory '/app/ocaml/otherlibs/unix'
make[4]: Entering directory '/app/ocaml/otherlibs/str'
make[4]: Nothing to be done for 'all'.
make[4]: Leaving directory '/app/ocaml/otherlibs/str'
make[4]: Entering directory '/app/ocaml/otherlibs/systhreads'
make[4]: Nothing to be done for 'all'.
make[4]: Leaving directory '/app/ocaml/otherlibs/systhreads'
make[3]: Leaving directory '/app/ocaml/otherlibs'
OCAMLOPT lex/syntax.cmx
OCAMLOPT lex/parser.cmx
OCAMLOPT lex/lexgen.cmx
LINKC tools/ocamltex
OCAMLOPT lex/lexer.cmx
OCAMLOPT toplevel/topcommon.cmx
OCAMLOPT toplevel/topprinters.cmx
OCAMLOPT lex/compact.cmx
OCAMLOPT lex/common.cmx
OCAMLOPT toplevel/native/tophooks.cmx
OCAMLOPT toplevel/native/topeval.cmx
OCAMLOPT lex/output.cmx
OCAMLOPT lex/outputbis.cmx
OCAMLOPT toplevel/toploop.cmx
OCAMLOPT lex/main.cmx
LINKOPT lex/ocamllex.opt
OCAMLOPT toplevel/topdirs.cmx
OCAMLOPT toplevel/native/topmain.cmx
OCAMLOPT toplevel/topstart.cmx
make[3]: Leaving directory '/app/ocaml'
make tools-allopt.opt
make[3]: Entering directory '/app/ocaml'
OCAMLOPT tools/ocamldep.cmx
LINKOPT compilerlibs/ocamlmiddleend.cmxa
OCAMLOPT tools/objinfo.cmx
LINKOPT compilerlibs/ocamltoplevel.cmxa
LINKOPT tools/ocamldep.opt
LINKOPT ocamlnat
LINKOPT tools/ocamlobjinfo.opt
make[3]: Leaving directory '/app/ocaml'
make[2]: Leaving directory '/app/ocaml'
make[1]: Leaving directory '/app/ocaml'
[metadata] {"noOutputExpected": false}{
"command": "make -C testsuite one DIR=tests/basic 2>&1 | tail -60",
"description": "Run basic testsuite",
"timeout": 600000
}make: Entering directory '/app/ocaml/testsuite'
Makefile:259: *** ocamltest not found in ../ocamltest. Stop.
make: Leaving directory '/app/ocaml/testsuite'
[stdout]
make: Entering directory '/app/ocaml/testsuite'
Makefile:259: *** ocamltest not found in ../ocamltest. Stop.
make: Leaving directory '/app/ocaml/testsuite'
[metadata] {"noOutputExpected": false}{
"command": "./configure --disable-ocamldoc 2>&1 | tail -10",
"description": "Reconfigure with ocamltest enabled",
"timeout": 120000
}config.status: creating runtime/caml/version.h
config.status: runtime/caml/version.h is unchanged
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]
config.status: creating runtime/caml/version.h
config.status: runtime/caml/version.h is unchanged
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) ocamltest 2>&1 | tail -20",
"description": "Build ocamltest",
"timeout": 600000
}OCAMLC ocamltest/actions_helpers.cmo
OCAMLC ocamltest/builtin_actions.cmo
OCAMLC ocamltest/ocaml_tools.cmo
OCAMLC ocamltest/debugger_actions.cmo
OCAMLC ocamltest/ocaml_tests.cmo
OCAMLC ocamltest/tsl_semantics.cmo
OCAMLC ocamltest/translate.cmo
OCAMLC ocamltest/main.cmo
OCAMLC ocamltest/ocaml_toplevels.cmo
OCAMLC ocamltest/ocaml_actions.cmo
LINKC compilerlibs/ocamlcommon.cma
config.status: linking ocamltest/ocamltest_unix_real.ml to ocamltest/ocamltest_unix.ml
OCAMLC ocamltest/ocamltest_unix.cmo
LINKC testsuite/lib/testing.cma
LINKC ocamlc
LINKC testsuite/tools/expect
File "_none_", line 1:
Error: compilerlibs/ocamlcommon.cma links with C code, so cannot be linked with -use-prims or -use-runtime unless -noautolink is specified
make: *** [Makefile:571: testsuite/tools/expect] Error 2
make: *** Waiting for unfinished jobs....
[stdout]
OCAMLC ocamltest/actions_helpers.cmo
OCAMLC ocamltest/builtin_actions.cmo
OCAMLC ocamltest/ocaml_tools.cmo
OCAMLC ocamltest/debugger_actions.cmo
OCAMLC ocamltest/ocaml_tests.cmo
OCAMLC ocamltest/tsl_semantics.cmo
OCAMLC ocamltest/translate.cmo
OCAMLC ocamltest/main.cmo
OCAMLC ocamltest/ocaml_toplevels.cmo
OCAMLC ocamltest/ocaml_actions.cmo
LINKC compilerlibs/ocamlcommon.cma
config.status: linking ocamltest/ocamltest_unix_real.ml to ocamltest/ocamltest_unix.ml
OCAMLC ocamltest/ocamltest_unix.cmo
LINKC testsuite/lib/testing.cma
LINKC ocamlc
LINKC testsuite/tools/expect
File "_none_", line 1:
Error: compilerlibs/ocamlcommon.cma links with C code, so cannot be linked with -use-prims or -use-runtime unless -noautolink is specified
make: *** [Makefile:571: testsuite/tools/expect] Error 2
make: *** Waiting for unfinished jobs....
[metadata] {"noOutputExpected": false}{
"command": "make -j$(nproc) 2>&1 | tail -20",
"description": "Full build",
"timeout": 600000
}Error: compilerlibs/ocamlcommon.cma links with C code, so cannot be linked with -use-prims or -use-runtime unless -noautolink is specified
File "_none_", line 1:
Error: compilerlibs/ocamlcommon.cma links with C code, so cannot be linked with -use-prims or -use-runtime unless -noautolink is specified
make[4]: *** [Makefile:571: tools/primreq] Error 2
make[4]: *** [Makefile:571: tools/dumpobj] Error 2
File "_none_", line 1:
Error: compilerlibs/ocamlcommon.cma links with C code, so cannot be linked with -use-prims or -use-runtime unless -noautolink is specified
make[4]: *** [Makefile:571: tools/stripdebug] Error 2
make[4]: *** [Makefile:571: tools/cmpbyt] Error 2
File "_none_", line 1:
Error: compilerlibs/ocamlcommon.cma links with C code, so cannot be linked with -use-prims or -use-runtime unless -noautolink is specified
make[4]: *** [Makefile:556: tools/ocamlobjinfo] Error 2
make[4]: Leaving directory '/app/ocaml'
make[3]: *** [Makefile:2294: ocamltools] Error 2
make[3]: Leaving directory '/app/ocaml'
make[2]: *** [Makefile:705: coreall] Error 2
make[2]: Leaving directory '/app/ocaml'
make[1]: *** [Makefile:775: opt.opt] Error 2
make[1]: Leaving directory '/app/ocaml'
make: *** [Makefile:856: world.opt] Error 2
[stdout]
Error: compilerlibs/ocamlcommon.cma links with C code, so cannot be linked with -use-prims or -use-runtime unless -noautolink is specified
File "_none_", line 1:
Error: compilerlibs/ocamlcommon.cma links with C code, so cannot be linked with -use-prims or -use-runtime unless -noautolink is specified
make[4]: *** [Makefile:571: tools/primreq] Error 2
make[4]: *** [Makefile:571: tools/dumpobj] Error 2
File "_none_", line 1:
Error: compilerlibs/ocamlcommon.cma links with C code, so cannot be linked with -use-prims or -use-runtime unless -noautolink is specified
make[4]: *** [Makefile:571: tools/stripdebug] Error 2
make[4]: *** [Makefile:571: tools/cmpbyt] Error 2
File "_none_", line 1:
Error: compilerlibs/ocamlcommon.cma links with C code, so cannot be linked with -use-prims or -use-runtime unless -noautolink is specified
make[4]: *** [Makefile:556: tools/ocamlobjinfo] Error 2
make[4]: Leaving directory '/app/ocaml'
make[3]: *** [Makefile:2294: ocamltools] Error 2
make[3]: Leaving directory '/app/ocaml'
make[2]: *** [Makefile:705: coreall] Error 2
make[2]: Leaving directory '/app/ocaml'
make[1]: *** [Makefile:775: opt.opt] Error 2
make[1]: Leaving directory '/app/ocaml'
make: *** [Makefile:856: world.opt] Error 2
[metadata] {"noOutputExpected": false}{
"command": "make clean 2>&1 | tail -5",
"description": "Clean build artifacts",
"timeout": 120000
}make[1]: Leaving directory '/app/ocaml/otherlibs'
rm -f debugger/ocamldebug debugger/ocamldebug.exe
rm -f debugger/debugger_lexer.ml
rm -f debugger/debugger_parser.ml debugger/debugger_parser.mli debugger/debugger_parser.output
rm -f tools/opnames.ml tools/make_opcodes.ml
[stdout]
make[1]: Leaving directory '/app/ocaml/otherlibs'
rm -f debugger/ocamldebug debugger/ocamldebug.exe
rm -f debugger/debugger_lexer.ml
rm -f debugger/debugger_parser.ml debugger/debugger_parser.mli debugger/debugger_parser.output
rm -f tools/opnames.ml tools/make_opcodes.ml
[metadata] {"noOutputExpected": false}{
"command": "./configure --disable-ocamldoc 2>&1 | tail -5",
"description": "Reconfigure",
"timeout": 120000
}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]
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) world.opt 2>&1 | tail -30",
"description": "Full build with ocamltest",
"timeout": 600000
}OCAMLOPT ocamltest/ocaml_toplevels.cmx
OCAMLOPT ocamltest/ocaml_actions.cmx
OCAMLOPT ocamltest/ocaml_tests.cmx
OCAMLOPT ocamltest/main.cmx
LINKOPT ocamltest/ocamltest.opt
OCAMLOPT lex/compact.cmx
OCAMLOPT lex/common.cmx
OCAMLOPT toplevel/native/tophooks.cmx
OCAMLOPT toplevel/native/topeval.cmx
OCAMLOPT lex/output.cmx
OCAMLOPT lex/outputbis.cmx
OCAMLOPT toplevel/toploop.cmx
OCAMLOPT lex/main.cmx
LINKOPT lex/ocamllex.opt
OCAMLOPT toplevel/topdirs.cmx
OCAMLOPT toplevel/native/topmain.cmx
OCAMLOPT toplevel/topstart.cmx
make[3]: Leaving directory '/app/ocaml'
make tools-allopt.opt
make[3]: Entering directory '/app/ocaml'
OCAMLOPT tools/ocamldep.cmx
LINKOPT compilerlibs/ocamlmiddleend.cmxa
OCAMLOPT tools/objinfo.cmx
LINKOPT tools/ocamldep.opt
LINKOPT compilerlibs/ocamltoplevel.cmxa
LINKOPT ocamlnat
LINKOPT tools/ocamlobjinfo.opt
make[3]: Leaving directory '/app/ocaml'
make[2]: Leaving directory '/app/ocaml'
make[1]: Leaving directory '/app/ocaml'
[stdout]
OCAMLOPT ocamltest/ocaml_toplevels.cmx
OCAMLOPT ocamltest/ocaml_actions.cmx
OCAMLOPT ocamltest/ocaml_tests.cmx
OCAMLOPT ocamltest/main.cmx
LINKOPT ocamltest/ocamltest.opt
OCAMLOPT lex/compact.cmx
OCAMLOPT lex/common.cmx
OCAMLOPT toplevel/native/tophooks.cmx
OCAMLOPT toplevel/native/topeval.cmx
OCAMLOPT lex/output.cmx
OCAMLOPT lex/outputbis.cmx
OCAMLOPT toplevel/toploop.cmx
OCAMLOPT lex/main.cmx
LINKOPT lex/ocamllex.opt
OCAMLOPT toplevel/topdirs.cmx
OCAMLOPT toplevel/native/topmain.cmx
OCAMLOPT toplevel/topstart.cmx
make[3]: Leaving directory '/app/ocaml'
make tools-allopt.opt
make[3]: Entering directory '/app/ocaml'
OCAMLOPT tools/ocamldep.cmx
LINKOPT compilerlibs/ocamlmiddleend.cmxa
OCAMLOPT tools/objinfo.cmx
LINKOPT tools/ocamldep.opt
LINKOPT compilerlibs/ocamltoplevel.cmxa
LINKOPT ocamlnat
LINKOPT tools/ocamlobjinfo.opt
make[3]: Leaving directory '/app/ocaml'
make[2]: Leaving directory '/app/ocaml'
make[1]: Leaving directory '/app/ocaml'
[metadata] {"noOutputExpected": false}{
"command": "make -C testsuite one DIR=tests/basic 2>&1",
"description": "Run basic testsuite",
"timeout": 600000
}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}