Skip to content

Conversation

jserv
Copy link
Contributor

@jserv jserv commented Oct 5, 2025

ThreadSanitizer (TSAN) can now detect race conditions across the entire multi-threaded JIT pipeline with full 4GB address space emulation. This enables testing of the tier-2 LLVM compilation thread while maintaining production memory layout.

Memory Layout (TSAN-compatible):

  • Main memory: MAP_FIXED at 0x7d0000000000 (4GB)
  • JIT buffer: MAP_FIXED at 0x7d1000000000
  • Both allocations within TSAN app range (0x7cf-0x7ff trillion)
  • Prevents conflicts with TSAN shadow memory (0x02a-0x7ce trillion)

ASLR Mitigation:

  • Added setarch -R wrapper for TSAN test execution
  • Disables ASLR to prevent random allocations in shadow memory
  • Only affects test runs, not production builds

SDL Conflict Resolution:

  • SDL (uninstrumented system library) creates threads TSAN cannot track
  • Disabled SDL when TSAN enabled to focus on built-in race detection
  • Production builds still fully support SDL

Summary by cubic

Enables ThreadSanitizer across the multi-threaded JIT pipeline with FULL4G memory emulation, including tier-2 compilation thread support. Uses fixed mappings and ASLR-disabled test runs to avoid TSAN shadow conflicts while keeping the production layout.

  • New Features

    • TSAN build mode with -fsanitize=thread; tests run via setarch -R; SDL and LTO disabled only when TSAN is enabled.
    • Fixed x86-64 mappings for FULL4G memory (0x7d0000000000) and JIT buffer (0x7d1000000000) using MAP_FIXED within TSAN’s app range.
    • TSAN runtime defaults added to reduce noise and keep tests running after reports.
  • Bug Fixes

    • Correct race handling in T2C: atomic load/store for hot2, compiled, n_invoke; acquire/release semantics around func/hot2.
    • Background compiler uses a condition variable and cache key lookup to avoid busy waits and use-after-free; signals on enqueue and shutdown with SATP verification.

ThreadSanitizer (TSAN) can now detect race conditions across the entire
multi-threaded JIT pipeline with full 4GB address space emulation. This
enables testing of the tier-2 LLVM compilation thread while maintaining
production memory layout.

Memory Layout (TSAN-compatible):
- Main memory: MAP_FIXED at 0x7d0000000000 (4GB)
- JIT buffer: MAP_FIXED at 0x7d1000000000
- Both allocations within TSAN app range (0x7cf-0x7ff trillion)
- Prevents conflicts with TSAN shadow memory (0x02a-0x7ce trillion)

ASLR Mitigation:
- Added setarch -R wrapper for TSAN test execution
- Disables ASLR to prevent random allocations in shadow memory
- Only affects test runs, not production builds

SDL Conflict Resolution:
- SDL (uninstrumented system library) creates threads TSAN cannot track
- Disabled SDL when TSAN enabled to focus on built-in race detection
- Production builds still fully support SDL
Copy link
Contributor Author

@jserv jserv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmarks

Benchmark suite Current: 0e4850e Previous: a5863f1 Ratio
Dhrystone 1331 Average DMIPS over 10 runs 1720 Average DMIPS over 10 runs 1.29
Coremark 969.672 Average iterations/sec over 10 runs 1020.849 Average iterations/sec over 10 runs 1.05

This comment was automatically generated by workflow using github-action-benchmark.

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 8 files

Prompt for AI agents (all 1 issues)

Understand the root cause of the following 1 issues and fix them.


<file name="src/jit.c">

<violation number="1" location="src/jit.c:2350">
When TSAN is enabled on macOS x86_64, this mmap call loses the MAP_JIT flag that the standard path uses, so hardened macOS failures return MAP_FAILED and the JIT never initializes. Please keep MAP_JIT on macOS even in the TSAN path.</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.

* 0x7ffffffff000) and prevents overlap with main memory or TSAN shadow.
*/
void *jit_addr = (void *) 0x7d1000000000UL;
state->buf = mmap(jit_addr, size, PROT_READ | PROT_WRITE | PROT_EXEC,
Copy link

@cubic-dev-ai cubic-dev-ai bot Oct 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When TSAN is enabled on macOS x86_64, this mmap call loses the MAP_JIT flag that the standard path uses, so hardened macOS failures return MAP_FAILED and the JIT never initializes. Please keep MAP_JIT on macOS even in the TSAN path.

Prompt for AI agents
Address the following comment on src/jit.c at line 2350:

<comment>When TSAN is enabled on macOS x86_64, this mmap call loses the MAP_JIT flag that the standard path uses, so hardened macOS failures return MAP_FAILED and the JIT never initializes. Please keep MAP_JIT on macOS even in the TSAN path.</comment>

<file context>
@@ -2336,6 +2336,25 @@ struct jit_state *jit_state_init(size_t size)
+     * 0x7ffffffff000) and prevents overlap with main memory or TSAN shadow.
+     */
+    void *jit_addr = (void *) 0x7d1000000000UL;
+    state-&gt;buf = mmap(jit_addr, size, PROT_READ | PROT_WRITE | PROT_EXEC,
+                      MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
+    if (state-&gt;buf == MAP_FAILED) {
</file context>

✅ Addressed in f915bc2

@jserv jserv changed the title Enable TSAN with FULL4G and T2C support Enable ThreadSanitizer across the entire multi-threaded JIT pipeline Oct 5, 2025
This commit adds ThreadSanitizer (TSAN) support for ARM64/Apple Silicon
and fixes critical JIT instruction cache coherency issues.

ARM64 TSAN Support:
- Extended TSAN-compatible memory allocation to ARM64 architecture
- Main memory allocated at fixed address 0x150000000000 (21TB)
- JIT buffer allocated at 0x151000000000 with MAP_JIT for Apple Silicon
- Both allocations avoid TSAN shadow memory and enable race detection
- Note: Requires ASLR disabled on macOS (SIP restrictions may apply)

JIT Cache Coherency Fixes:
1. Fixed pthread_jit_write_protect_np() ordering in update_branch_imm
2. Added sys_icache_invalidate() in update_branch_imm
3. Added cache invalidation in resolve_jumps() for x86_64
This introduces debug-level logging throughout the JITC to facilitate
troubleshooting of intermittent compilation and execution failures on
Arm64.
jserv added 4 commits October 6, 2025 00:22
The diagnostic logging added in the previous commit uses DEBUG level,
which was being displayed because the default log level was set to TRACE.
This caused CI test failures as the excessive debug output interfered
with test output validation.
Replace left shift of potentially negative value with multiplication to
avoid undefined behavior detected by UBSan.

In update_branch_imm(), the immediate value (imm) is right-shifted by 2
and can be negative. The diagnostic logging attempted to restore the
original value using left shift (imm << 2), which is undefined behavior
when imm is negative.
This upgrades code_cache_flush logging from DEBUG to INFO level to make
this critical event visible in CI test logs.
This resolves critical bugs in update_branch_imm causing intermittent
test failures (~13-20% failure rate) on macOS/Arm64:
1. MAP_JIT memory corruption: Reading MAP_JIT memory while in write mode
   returns corrupted data on Apple Silicon. Fixed by moving
   pthread_jit_write_protect_np(false) to after the read operation.
2. Branch offset bit accumulation: When branches are patched multiple
   times, old offset bits were not cleared before OR-ing new values.
   Added bit masking to clear old offsets before setting new ones.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant