Skip to content

Savestate: compact BlockAllocator serialization (section v2) - #21990

Open
Arkadyzja wants to merge 1 commit into
hrydgard:masterfrom
Arkadyzja:savestate-compact-blockallocator
Open

Savestate: compact BlockAllocator serialization (section v2)#21990
Arkadyzja wants to merge 1 commit into
hrydgard:masterfrom
Arkadyzja:savestate-compact-blockallocator

Conversation

@Arkadyzja

Copy link
Copy Markdown

What

Bumps the BlockAllocator savestate section to v2 with a compact per-block serialization form, and zero-pads block tags at write time instead of on every save.

Why

Serializing the kernel memory block lists (userMemory, kernelMemory, volatileMemory) currently pays two per-block costs on every save:

  1. A full Section("Block", 1) header per block — games keep on the order of a thousand blocks alive, so this is a thousand section headers of pure overhead in time and payload bytes.
  2. A strlen + memset per block to zero the tag padding before writing it (needed because truncate_cpy leaves the padding uninitialized).

How

  • Block's constructor and SetAllocated() now memset the whole tag before writing it, so tag padding is always zero by construction and can be stored raw. Every path that writes a tag clears it first, so uninitialized bytes still never reach the stream.
  • The v2 form stores each block as raw start, size, taken, tag — no per-block section machinery, no per-save tag scrubbing.

Compatibility

  • v1 states load exactly as before — the old per-block-Section read path is kept unchanged, selected by the section version.
  • States written by this build won't load on older builds — standard section-bump consequence.

Serializing the kernel memory block lists (userMemory, kernelMemory,
volatileMemory) wrote a full Section header per block and re-zeroed
each block's tag padding with strlen+memset on every save. Games keep
on the order of a thousand blocks alive, so the per-block overhead is
both measurable save time and wasted payload bytes.

Zero-pad tags once at write time instead (Block constructor and
SetAllocated), so the v2 form can store blocks raw: start, size, taken,
tag - no per-block section machinery, no per-save tag scrubbing.
Uninitialized padding still never reaches the stream, since every path
that writes a tag now clears it first.

v1 states still load through the old per-block-Section form, which is
kept unchanged.
@hrydgard hrydgard added this to the v1.21 milestone Jul 27, 2026
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.

2 participants