feat(memory): JVM/Android Storage bindings — SegmentStorage (FFM), MappedFileStorage, DirectBufferStorage, MappedBufferStorage (SKEEP-003 P2, S1.1b) - #1063
Merged
Conversation
…ppedFileStorage (FileChannel.map), DirectBufferStorage, MappedBufferStorage (SKEEP-003 P2) Milestone M1 (#1002), PRD M1-F1. SKEEP-003 §4.8.1 / §4.8.2: where bytes live is a policy decision; these are the JVM and Android bindings of the OffHeap and Mapped storage kinds. - jvmMain SegmentStorage : Storage.OffHeap — a MemorySegment in an Arena; allocate(bytes, scope, arena?) owns a private Arena.ofShared() and frees it on close, or takes the scope's arena (the Forward bump-slab pattern of #1021); borrow(segment) / borrow(FloatArray) via MemorySegment.ofArray — zero-copy, never freed by us; slice() = asSlice alias; segment() accessor throws StorageClosedException after close. - jvmMain MappedFileStorage : Storage.Mapped — FileChannel.map READ_ONLY into an Arena.ofShared(); closing unmaps; path + fileOffset kept for describe(); slices carry their file offset. - jvmAndroidMain DirectBufferStorage : Storage.OffHeap (direct ByteBuffer, outside the ART heap — #922) and MappedBufferStorage : Storage.Mapped (MappedByteBuffer, SKEEP-002 / #921); little-endian duplicates handed out per call; close marks the storage dead. - Allocation / Free trace events; MemoryDomain HOST_OFFHEAP / MMAP_FILE. - JvmStorageTest (arena ownership vs caller arena, alias over the same bytes, borrowed array zero-copy, mapped file read + unmap, direct and mapped buffers). BCV: lang-core jvm dump regenerated (additions only). Closes #1019 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
Author
|
Local gate Targeted: lang-core |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
SKEEP-003 slice S1.1b (milestone M1 #1002, PRD M1-F1): the JVM and Android bindings of the
OffHeapandMappedstorage kinds (§4.8.1 / §4.8.2) — where bytes live is a policy decision; these are the concrete kinds the planner and scopes pick from.SegmentStorage : Storage.OffHeap(jvmMain, FFM): aMemorySegmentin anArena.allocate(bytes, scope, arena?)owns a privateArena.ofShared()and frees it onclose(), or takes the scope's arena (theForwardbump-slab pattern of [S1.2] P2:ScopeModel/Forward/Ambient — JVM Arena bump allocator,reset(),retain(), escape check; ExecutionContext opt-in #1021);borrow(segment)/borrow(FloatArray)viaMemorySegment.ofArray— zero-copy, never freed by us (the GGUF DEQUANTIZE_TO_FP32 over-allocates: 1.1B Q4_K_M needs >12 GB heap transiently (~4.4 GB legit) #782 pattern);slice()=asSlicealias;segment()is the once-per-call accessor and throwsStorageClosedExceptionafter close.MappedFileStorage : Storage.Mapped(jvmMain):FileChannel.map(READ_ONLY)into anArena.ofShared(); closing unmaps;path+fileOffsetkept fordescribe(); slices carry their file offset.DirectBufferStorage : Storage.OffHeapandMappedBufferStorage : Storage.Mapped(jvmAndroidMain): directByteBufferoutside the ART heap (createRandomAccessSourcereturns null on Android: full-file heap load OOMs on a 138 MiB GGUF (working ~40-line fix included) #922) andMappedByteBuffer(SKEEP-002 / Android tensor storage is ART-heap-bound: no off-heap / mmap path outside jvmMain caps practical model size (SKEEP candidate) #921); little-endian duplicates handed out per call;close()marks the storage dead.Allocation/Freetrace events for all kinds;MemoryDomain.HOST_OFFHEAP/MMAP_FILE.ByteBuffer.position/limitreturnBufferunder the Android (Java 8) signatures, so the slice path keeps aByteBuffer-typed local —compileAndroidMainis part of the gate'sassemble.JvmStorageTest: arena ownership vs caller arena, alias over the same bytes, borrowed array zero-copy, mapped file read + unmap, direct and mapped buffers, distinct ids across kinds.Scope[S1.2] P2:ScopeModel/Forward/Ambient — JVM Arena bump allocator,reset(),retain(), escape check; ExecutionContext opt-in #1021, façades [S1.4a] P2: denseTensorDataimplementations become façades overTensorView(bit-identical) #1023/[S1.4b] P2: packedTensorDataimplementations (Q4_0…Q8_0, Q4_K/Q5_K/Q6_K, ternary, TurboQuant) become façades overTensorView#1024, loader config [S2.4] P5: IO as a pipeline —quantPolicy×staging = MAPPED|HEAPin one loader;suspendRandomAccessSource in io-core #1037/[S2.5] P5: Android mmap as a loader configuration (SKEEP-002, #921, #922) onStorage.Mapped#1038).Stacked on #1061 (
TraceSink+Storage, after #1062 merged into that branch); retarget todevelopafter it merges.Test plan
Full local gate (
scripts/pr-gate.sh, JDK 25); results in the first comment. Targeted: lang-coresk.ainet.lang.memory.*44/44 (jvmTest).Closes #1019
🤖 Generated with Claude Code