Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions Makefile.cbm
Original file line number Diff line number Diff line change
Expand Up @@ -1053,10 +1053,12 @@ MIMALLOC_OBJ_TEST = $(BUILD_DIR)/mimalloc.o
MIMALLOC_OBJ_TSAN = $(BUILD_DIR)/tsan_mimalloc.o
MIMALLOC_OBJ_PROD = $(BUILD_DIR)/prod_mimalloc.o

$(BUILD_DIR)/mimalloc.o: $(MIMALLOC_SRC) | $(BUILD_DIR)
$(BUILD_DIR)/mimalloc.o: $(MIMALLOC_SRC) $(wildcard vendored/mimalloc/src/*.c) \
$(wildcard vendored/mimalloc/include/*.h) Makefile.cbm | $(BUILD_DIR)
$(CC) $(MIMALLOC_CFLAGS_TEST) -c -o $@ $<

$(BUILD_DIR)/tsan_mimalloc.o: $(MIMALLOC_SRC) | $(BUILD_DIR)
$(BUILD_DIR)/tsan_mimalloc.o: $(MIMALLOC_SRC) $(wildcard vendored/mimalloc/src/*.c) \
$(wildcard vendored/mimalloc/include/*.h) Makefile.cbm | $(BUILD_DIR)
$(CC) $(MIMALLOC_CFLAGS_TEST) $(TSAN_SANITIZE) -c -o $@ $<

# static.c is an AMALGAMATION: it #includes options.c and friends, none of which
Expand Down
4 changes: 3 additions & 1 deletion internal/cbm/callable_sig.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ static void sig_raw(sig_ctx_t *c, const char *s, size_t n) {
c->overflow = true;
return;
}
memcpy(grown, c->buf, c->len);
if (c->len != 0) {
memcpy(grown, c->buf, c->len);
}
c->buf = grown;
c->cap = cap;
}
Expand Down
7 changes: 6 additions & 1 deletion internal/cbm/doclink_perl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1538,6 +1538,9 @@ static int pl_pkg_order_cmp(const void *a, const void *b) {
/* Give every declaration the index of its name's P record (names in order of
* their first declaration) and write the P records. */
static void pl_number_packages(pl_walk_t *w, pl_sb_t *sb) {
if (w->npkgs == 0) {
return;
}
qsort(w->pkgs, (size_t)w->npkgs, sizeof(pl_pkg_t), pl_pkg_name_cmp);
for (int i = 0; i < w->npkgs; i++) { /* index = order of the name's first declaration */
bool repeat =
Expand Down Expand Up @@ -1572,7 +1575,9 @@ static int pl_subdecl_cmp(const void *a, const void *b) {
/* One S record per sub definition of the file, with the package the tree
* places it in. */
static void pl_put_subs(CBMExtractCtx *ctx, pl_walk_t *w, pl_sb_t *sb) {
qsort(w->subs, (size_t)w->nsubs, sizeof(pl_subdecl_t), pl_subdecl_cmp);
if (w->nsubs > SKIP_ONE) {
qsort(w->subs, (size_t)w->nsubs, sizeof(pl_subdecl_t), pl_subdecl_cmp);
}
const CBMDefArray *defs = &ctx->result->defs;
for (int i = 0; i < defs->count; i++) {
const CBMDefinition *d = &defs->items[i];
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion internal/cbm/vendored/grammars/objectscript_udl/scanner.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions scripts/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,7 @@ fi
# release artifacts free of it; scripts/ci/check-binary-composition.sh proves
# they stay that way.
echo "=== Step 5: parent-death watchdog regression (#406/#407) ==="
CC="$CC" bash "$ROOT/tests/test_mimalloc_preinit.sh"
make -j"$NPROC" -f Makefile.cbm cbm TEST_SEAMS=1 ${MAKE_ARGS[@]+"${MAKE_ARGS[@]}"}
WATCHDOG_BINARY="$ROOT/$BUILD_DIR/codebase-memory-mcp"
CBM_TEST_BINARY="$WATCHDOG_BINARY" bash "$ROOT/tests/test_parent_watchdog.sh"
Expand Down
6 changes: 3 additions & 3 deletions scripts/vendored-checksums.txt
Original file line number Diff line number Diff line change
Expand Up @@ -525,14 +525,14 @@ c5fa4d1d5820cc59f39cb3cb9a9a171e5144b2f63d285cf3450be0a8e549ede8 internal/cbm/v
85b458dc150c4d17873dd5e73d01cfa23c797997a09d841884e08378242e929c internal/cbm/vendored/grammars/objectscript_routine/LICENSE
f3a047fba6d238da258c0370878e703504b347aad13add09a021935daa891bd3 internal/cbm/vendored/grammars/objectscript_routine/objectscript_common.h
fb9320a77f7c3c110540e9a569c2a8dd7ff74784ae05aac962f4bcbab1343640 internal/cbm/vendored/grammars/objectscript_routine/parser.c
2fde85097c7df0180b7a204eeae97c32a541f1fcc1b44a3837a57f26ac9966fa internal/cbm/vendored/grammars/objectscript_routine/scanner.c
1da66e46ba02fcf2f9ca42b2a80c8658e150ae7b5154d81b8968117b959b5af7 internal/cbm/vendored/grammars/objectscript_routine/scanner.c
b29c1c9fb7cc82f58c84b376df1297d6e2737a1d655fd356db0859e3c29c2fea internal/cbm/vendored/grammars/objectscript_routine/tree_sitter/alloc.h
31e60a1bff6f715afacce03b5b70efe42b58371b4f9595dd4af52a577ff9608c internal/cbm/vendored/grammars/objectscript_routine/tree_sitter/array.h
180b893c8734778fd32f372dfbc27bd6ad1cd2221f26150b31256ff6716320d2 internal/cbm/vendored/grammars/objectscript_routine/tree_sitter/parser.h
85b458dc150c4d17873dd5e73d01cfa23c797997a09d841884e08378242e929c internal/cbm/vendored/grammars/objectscript_udl/LICENSE
f3a047fba6d238da258c0370878e703504b347aad13add09a021935daa891bd3 internal/cbm/vendored/grammars/objectscript_udl/objectscript_common.h
2003ffb1a07ec30a2f7176c65aae958b804074af8356a81a3d42417a240f2e15 internal/cbm/vendored/grammars/objectscript_udl/parser.c
2e80c4939726948b0ebf8af56103a9c0278a038eeb5be0b769c59d2b4e2d36b1 internal/cbm/vendored/grammars/objectscript_udl/scanner.c
537be452c5079531e08edc302b65c63f45956510f6ee96ec88c1d7531d203f1e internal/cbm/vendored/grammars/objectscript_udl/scanner.c
b29c1c9fb7cc82f58c84b376df1297d6e2737a1d655fd356db0859e3c29c2fea internal/cbm/vendored/grammars/objectscript_udl/tree_sitter/alloc.h
31e60a1bff6f715afacce03b5b70efe42b58371b4f9595dd4af52a577ff9608c internal/cbm/vendored/grammars/objectscript_udl/tree_sitter/array.h
180b893c8734778fd32f372dfbc27bd6ad1cd2221f26150b31256ff6716320d2 internal/cbm/vendored/grammars/objectscript_udl/tree_sitter/parser.h
Expand Down Expand Up @@ -1016,7 +1016,7 @@ eca1fe77d72ab2aaccc447c8119056e9c4e8851bda9a95472b573539f76107ad vendored/mimal
ebd95b475f15d5387e6ef3c88a9cb47b88e64d7e55998ae1dc656614676a443b vendored/mimalloc/src/libc.c
192ce06ac9076445d223205fb340d8a1fc818dbf2b4c4a801dfd2c10bc6c1162 vendored/mimalloc/src/options.c
011e965f28c0e2c885a6834d51bd756a458dd37ebfed6fd4d9ad6607ce0390ed vendored/mimalloc/src/os.c
1be3a208c678fc34187c2a8ffb75f3fe1eecc674bbf8b2af4d1f329506b1fad5 vendored/mimalloc/src/page-map.c
e68eee14cb53e13eb1b7e003cfe747c353e3bac849afd0242a6d1862b8f0b895 vendored/mimalloc/src/page-map.c
7ec275805c9f00eb66710ffa99817b3ed1dba9826435d08f4866f7935152f6ae vendored/mimalloc/src/page-queue.c
d3614a59f2407a32e75b051deb1aff31b233f587d325dcc5420ba508551b687e vendored/mimalloc/src/page.c
7488e9e562ca85d2d757ec48e4d334935263a2333aa05b6061d8520f427c5890 vendored/mimalloc/src/prim/emscripten/prim.c
Expand Down
12 changes: 8 additions & 4 deletions src/mcp/mcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -19018,13 +19018,17 @@ static char *handle_detect_changes(cbm_mcp_server_t *srv, const char *args) {
char hunk_cmd[CBM_SZ_2K];
#ifdef _WIN32
snprintf(hunk_cmd, sizeof(hunk_cmd),
"git -C \"%s\" diff --relative --unified=0 \"%s\" \"%s\" -- 2>NUL && "
"git -C \"%s\" diff --relative --unified=0 -- 2>NUL",
"git -C \"%s\" " CBM_TEST_IMPACT_GIT_PINS
" diff --relative " CBM_TEST_IMPACT_DIFF_FLAGS " \"%s\" \"%s\" -- 2>NUL && "
"git -C \"%s\" " CBM_TEST_IMPACT_GIT_PINS
" diff --relative " CBM_TEST_IMPACT_DIFF_FLAGS " -- 2>NUL",
root_path, merge_base, head_oid, root_path);
#else
snprintf(hunk_cmd, sizeof(hunk_cmd),
"git -C '%s' diff --relative --unified=0 '%s' '%s' -- 2>/dev/null && "
"git -C '%s' diff --relative --unified=0 -- 2>/dev/null",
"git -C '%s' " CBM_TEST_IMPACT_GIT_PINS
" diff --relative " CBM_TEST_IMPACT_DIFF_FLAGS " '%s' '%s' -- 2>/dev/null && "
"git -C '%s' " CBM_TEST_IMPACT_GIT_PINS
" diff --relative " CBM_TEST_IMPACT_DIFF_FLAGS " -- 2>/dev/null",
root_path, merge_base, head_oid, root_path);
#endif
char hunk_output_path[CBM_SZ_2K] = {0};
Expand Down
4 changes: 3 additions & 1 deletion src/pipeline/doc_links_perl.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,9 @@ static bool pr_index_packages(pr_index_t *ix, const cbm_doclink_build_in_t *in)
if (ix->oom) {
return false;
}
qsort(ix->decls, (size_t)ix->ndecls, sizeof(pr_decl_t), pr_decl_cmp);
if (ix->ndecls > SKIP_ONE) {
qsort(ix->decls, (size_t)ix->ndecls, sizeof(pr_decl_t), pr_decl_cmp);
}
ix->pkg = cbm_ht_create_in(CBM_MEM_CLASS_OTHER, (uint32_t)(ix->ndecls + SKIP_ONE));
if (!ix->pkg) {
return false;
Expand Down
3 changes: 3 additions & 0 deletions src/pipeline/doc_links_rst.c
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,9 @@ static void rr_destroy(void *index) {
/* The documentation set a document belongs to: the nearest conf.py at or
* above its directory; NULL for none. */
static const rr_conf_t *rr_conf_for(const rr_index_t *x, const char *doc) {
if (x->nconfs == 0) {
return NULL;
}
char dir[RR_PATH_CAP];
const char *b = rr_base(doc);
size_t dl = b > doc ? (size_t)(b - doc - SKIP_ONE) : 0;
Expand Down
6 changes: 6 additions & 0 deletions tests/test_extraction.c
Original file line number Diff line number Diff line change
Expand Up @@ -10250,6 +10250,12 @@ TEST(doc_perl_module_doc_is_the_pod_no_sub_holds) {
ASSERT_NOT_NULL(r);
ASSERT_NULL(r->module_doc);
cbm_free_result(r);
/* POD without any declarations leaves both scope sort inputs empty. */
r = extract("=head1 NAME\n\nStandalone module.\n\n=cut\n", CBM_LANG_PERL, "t", "Standalone.pm");
ASSERT_NOT_NULL(r);
ASSERT_EQ(count_defs_with_label(r, "Function"), 0);
ASSERT_STR_EQ(r->module_doc, "=head1 NAME\n\nStandalone module.\n\n=cut");
cbm_free_result(r);
PASS();
}

Expand Down
12 changes: 5 additions & 7 deletions tests/test_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,14 +211,12 @@ static void tf_cleanup_cache_sentinel(void) {
}
}

/* Client home overrides the CLI honours BEFORE $HOME, so redirecting HOME alone
* does not isolate them: cbm_codex_config_dir() and its siblings return the
* ambient path and the suite resolves against the developer's real config —
* reading its state and writing to it. Same inventory the shell fixtures are
* already required to neutralize (tests/test_smoke_fixture_contract.sh), kept
* in one place so a new client cannot be isolated in the smoke scripts and
* forgotten here. A test that exercises one of these sets it after setup. */
/* These paths take precedence over HOME and can escape the private fixture.
* A test that exercises an override sets it after setup. */
static const char *const tf_client_home_overrides[] = {
"XDG_CONFIG_HOME",
"XDG_DATA_HOME",
"XDG_CACHE_HOME",
"CLAUDE_CONFIG_DIR",
"CODEX_HOME",
"KIRO_HOME",
Expand Down
3 changes: 2 additions & 1 deletion tests/test_mcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -17735,7 +17735,8 @@ static bool dc_walk_fixture_open(dc_walk_fixture_t *fx) {
}
/* Same git invocation rules as the #1363 fixture above. */
char cmd[1200];
const char *steps[] = {"init -q", "add -A", "commit -q -m init"};
const char *steps[] = {"init -q", "config diff.mnemonicPrefix true", "add -A",
"commit -q -m init"};
for (size_t s = 0; s < sizeof(steps) / sizeof(steps[0]); s++) {
snprintf(cmd, sizeof(cmd),
"git -C \"%s\" -c user.name=t -c user.email=t@t.io -c init.defaultBranch=main "
Expand Down
31 changes: 31 additions & 0 deletions tests/test_mimalloc_preinit.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env bash
set -euo pipefail

# ELF preinitializers run before allocator constructors, independent of libc version.
if [[ "$(uname -s)" != Linux ]]; then
echo "mimalloc pre-init regression: ELF-only check not applicable"
exit 0
fi
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
probe_dir="$(mktemp -d "${TMPDIR:-/tmp}/cbm-mi-preinit.XXXXXX")"
trap 'rm -rf "$probe_dir"' EXIT

cat >"$probe_dir/probe.c" <<'C'
#include <stddef.h>
#include "mimalloc.h"
static void before_init(void) { mi_free(NULL); }
__attribute__((used, section(".preinit_array")))
static void (*const preinit)(void) = before_init;
int main(void) {
void *p = mi_malloc(16);
if (!p) return 1;
mi_free(p);
return 0;
}
C
"${CC:-cc}" -O2 -DMI_DEBUG=0 -DMI_OVERRIDE=0 \
-I"$ROOT/vendored/mimalloc/include" -I"$ROOT/vendored/mimalloc/src" \
"$probe_dir/probe.c" "$ROOT/vendored/mimalloc/src/static.c" \
-lpthread -lm -o "$probe_dir/probe"
"$probe_dir/probe"
echo "mimalloc pre-init free(NULL) regression passed"
4 changes: 3 additions & 1 deletion tests/test_smoke_fixture_contract.sh
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,9 @@ CLIENT_HOME_OVERRIDES = (
# so it needs the same neutralization — otherwise a green run on a developer
# machine only proves the ambient config happened to be writable.
test_main = read("tests/test_main.c")
for variable in CLIENT_HOME_OVERRIDES:
for variable in CLIENT_HOME_OVERRIDES + (
"XDG_CONFIG_HOME", "XDG_DATA_HOME", "XDG_CACHE_HOME"
):
require(
f'"{variable}"' in test_main,
f"tests/test_main.c must neutralize ambient {variable}",
Expand Down
2 changes: 1 addition & 1 deletion tests/test_venue_parity_contract.sh
Original file line number Diff line number Diff line change
Expand Up @@ -409,9 +409,9 @@ test-infrastructure/vm/vm-run-tests.sh
test-infrastructure/vm/win.sh
"
for entry in $HELP_ENTRIES; do
out=$(cd "$ROOT" && bash "$entry" --help 2>&1) && rc=0 || rc=$?
case "$entry" in
*.py) out=$(cd "$ROOT" && python3 "$entry" --help 2>&1) && rc=0 || rc=$? ;;
*) out=$(cd "$ROOT" && bash "$entry" --help 2>&1) && rc=0 || rc=$? ;;
esac
# Substring test in-shell: piping into `grep -q` is unsafe under
# `set -o pipefail` because grep exits at the first match and the
Expand Down
12 changes: 10 additions & 2 deletions vendored/mimalloc/src/page-map.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ static void mi_page_map_cannot_commit(void) {
// A full 256 TiB address space (48 bit) needs a 4 GiB page map.
// A full 4 GiB address space (32 bit) needs only a 64 KiB page map.

mi_decl_cache_align uint8_t* _mi_page_map = NULL;
// Use an initial empty page map so `free(NULL)` works even if mimalloc is not yet initialized (issue #1341)
static uint8_t mi_page_map_empty[1] = { 1 }; // _mi_ptr_page(NULL) == NULL

mi_decl_cache_align uint8_t* _mi_page_map = mi_page_map_empty;
static void* mi_page_map_max_address = NULL;
static mi_memid_t mi_page_map_memid;

Expand Down Expand Up @@ -198,7 +201,11 @@ mi_decl_nodiscard mi_decl_export bool mi_is_in_heap_region(const void* p) mi_att
#define MI_PAGE_MAP_SUB_SIZE (MI_PAGE_MAP_SUB_COUNT * sizeof(mi_page_t*))
#define MI_PAGE_MAP_ENTRIES_PER_CBIT (MI_PAGE_MAP_COUNT < MI_BFIELD_BITS ? 1 : (MI_PAGE_MAP_COUNT / MI_BFIELD_BITS))

mi_decl_cache_align _Atomic(mi_submap_t)* _mi_page_map;
// Use an initial empty page map so `free(NULL)` works even if mimalloc is not yet initialized (issue #1341)
static mi_page_t* mi_submap_empty[1] = { NULL };
static _Atomic(mi_submap_t) mi_page_map_empty[1] = { MI_ATOMIC_VAR_INIT(mi_submap_empty) };

mi_decl_cache_align _Atomic(mi_submap_t)* _mi_page_map = mi_page_map_empty;
static size_t mi_page_map_count;
static void* mi_page_map_max_address;
static mi_memid_t mi_page_map_memid;
Expand Down Expand Up @@ -261,6 +268,7 @@ bool _mi_page_map_init(void) {
_mi_page_map = (_Atomic(mi_page_t**)*)_mi_os_alloc_aligned(reserve_size, 1, commit, true /* allow large */, &mi_page_map_memid);
if (_mi_page_map==NULL) {
_mi_error_message(ENOMEM, "unable to reserve virtual memory for the page map (%zu KiB)\n", page_map_size / MI_KiB);
_mi_page_map = mi_page_map_empty;
return false;
}
if (mi_page_map_memid.initially_committed && !mi_page_map_memid.initially_zero) {
Expand Down
Loading