megboyzzandClaude edfa360c0a Map the guest region by permission, not all-RWX: loading 8.3% faster (tasks #53/#54)
CreateConfiguredEngine mapped the whole guest region with one
uc_mem_map_ptr(UC_PROT_ALL). UC_PROT_ALL includes EXEC, and QEMU's
notdirty_write (qemu/accel/tcg/cputlb.c:1199) does this on every write:

    mr = uc->memory_mapping(uc, ...);              // region lookup
    if (mr && (mr->perms & UC_PROT_EXEC) != 0) {
        page_collection_lock(...);
        tb_invalidate_phys_page_fast(...);
    }

So marking memory executable makes EVERY WRITE to it pay a region lookup
plus a translated-block invalidation check. With the whole region
executable, ordinary stack and data writes all took that path.

Found by elimination rather than guesswork. Two counters were written and
both answered zero: writes into .text (across two sessions) and writes into
the trampoline/stub arenas. Since no guest code and no engine-written stub
bytes were dirtying code pages, the writes driving tb_invalidate had to be
ordinary data writes that merely lived in an executable mapping.

The first split (heap RW, everything above heap_end_ RWX) moved the three
symbols by 0.5 points - i.e. nothing - because it left THREAD STACKS
executable. The heap is 768MB, but stores go overwhelmingly to the stack,
once per call frame. "Biggest region" and "most written region" were not the
same region.

Final layout: image RWX; heap RW; trampoline+stub arenas RWX; control and
thread stacks RW; mmap arena RWX (LoadSecondaryImage maps real code there).

    tb_invalidate_phys_page_fast_arm   4.52%  ->  0.04%
    time to first OnCarLoaded, 3 runs each:
        single RWX  40.95 / 39.06 / 38.96 s   (mean 39.66)
        split       36.31 / 35.87 / 36.88 s   (mean 36.35)

Ranges do not overlap: loading is 8.3% faster. Verified end-to-end with an
A/B switch rather than inferred from the profile share, because task #48
established that a share drop is not a speedup. Zero FETCH_PROT/WRITE_PROT
faults, so nothing executes from the now-non-executable spans.

flatview_translate_arm (5.25%) and find_memory_mapping_arm (2.99%) barely
moved, so they have callers beyond notdirty_write - task #53 stays open.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-19 17:25:01 +03:00
2025-09-05 18:38:01 +03:00
2025-09-05 18:38:01 +03:00
2025-09-05 18:38:01 +03:00
2025-09-05 18:38:01 +03:00
2025-09-05 18:38:01 +03:00
S
Description
Мод добавляющий мультиплеер для NFSMW
17 MiB
Languages
C++ 48%
Java 46.1%
Kotlin 4.4%
C 1%
Shell 0.3%
Other 0.2%