Follow the console libc.prx (PPSA02530) at 0xcb2d0: ignore the argument and throw the static bad_array_new_length object. Star Wars Racer (PPSA28416) imports it.
nanosleep on macOS wakes about 25% late up to roughly 5 ms, then a
roughly constant 2 to 5 ms late for longer waits. Keeping 30% of the wait
as margin made a 100 ms wait spin about 25 ms. The margin is now 30% of the
wait, capped at 5 ms, so long waits spin at most about 5 ms.
fputws and wprintf write a UTF-16 surrogate pair as one four-byte
UTF-8 sequence, but fgetwc decoded that sequence into a single code
point above 0xFFFF, which is not a 16-bit guest wchar_t value, and
fgetws stored it truncated: fputws(u"A\U0001F600\n") read back as
A, U+F600, newline.
fgetwc now returns the high surrogate and keeps the low one in the
stream for the next read, so fgetws stores the pair, also when the
buffer fills between the two halves. A successful seek discards it,
as FreeBSD's fseeko resets the stream's mbstate. Sequences that
decode to an overlong form or above U+10FFFF, and lead bytes F8 to
FF, fail with EILSEQ instead of returning made-up characters; the
three-byte surrogates that fputwc writes for a single unit are still
read back as that unit.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QegaHM5QeCynUQ2ZLWHE4b
Evicting a resident run read every 16 KiB page to find the written ones. On Windows, reading a committed page that was never touched faults in a zeroed page, and 97% of the pages the game releases were never written, so the scan took 2.9 us per page and most of the time the guest-allocation lock was held (Soul Hackers 2: 7.1 s of every 10 s). While the run is write-watched, no collection has cleared the watch and no host import touched it, GetWriteWatch lists the only pages that can be non-zero, so only those are read. Runs that fail any of those conditions are scanned as before.
macOS timer coalescing wakes a nanosleep about 25% late, so the fixed 100 us
spin tail overshoots: PreciseSleepUs(1500) takes about 1.76 ms. On macOS the
sleep now covers 70% of the wait before the spin tail, which leaves that
lateness inside the spin. Linux and Windows compile the same code as before.
Under Rosetta the main thread stack lies at about 12 GiB, inside the guest
arena, where a title can map fixed addresses; a fixed mapping over it
aborts with a host region overlap.
- Aps5StartGuest moves the main thread onto a 16 MiB stack at
0x600000000000 when the old stack overlaps a host region of the arena.
It copies argv, environ, the program name and the initial block off the
old stack, then frees the old stack and releases its range to the arena.
- The guest thread keeps the stack size of the original main thread.
- The arena gets GuestArenaOverlapsHostRegion and
GuestArenaReleaseHostRegion for POSIX hosts.
- guest_main_stack_move starts the guest, then requires the main thread
outside the arena, a fixed mapping where the old stack was, and argv and
the environment intact.
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>