Host colectable GC references#55
Draft
andreaTP wants to merge 4 commits into
Draft
Conversation
Replace GcRefStore integer-ID indirection with direct Java Object references in the interpreter path. Java's GC now handles liveness of Wasm GC structs, arrays, and i31 values naturally. Core design: MStack gains a lazy Object[] refs array (null until first pushRef). push()/pop() are unchanged — zero overhead for non-GC workloads. GC refs use pushRef()/popRef() to store actual WasmStruct/WasmArray/WasmI31Ref objects. Key changes: - MStack: lazy Object[] with pushRef/popRef/peekRef/clearRefsTo - StackFrame: Object[] localRefs parallel to long[] locals - WasmStruct/WasmArray: dual long[]+Object[] for fields/elements - GlobalInstance: Object refValue for ref-typed globals - TableInstance: Object[] objRefs for GC-typed tables - ValType.isGcReference(): distinguishes any-hierarchy from func/extern - StorageType.isReference()/isGcReference(): field type helpers - Instance.heapTypeMatchRef(Object,...): type matching on Objects - ConstantEvaluators: ConstantResult carries both long[] and Object - InterpreterMachine: ~30 GC instructions updated - Machine.call(int,long[],Object[]): overload for ref args - WasmI31Ref: equals/hashCode for ref.eq value equality GcRefStore is NOT yet removed — the compiler still uses it (Phase 2). Compiler GC tests are expected to fail until Phase 2.
Add callGc/applyGc methods to Machine, ExportFunction, and WasmFunctionHandle for passing real Java Objects as Wasm GC refs. Users can now receive WasmStruct/WasmArray/WasmI31Ref directly from exported functions, and Java GC manages their lifecycle. Key changes: - Machine.callGc(int, Object[]) / ExportFunction.applyGc(Object...) - InterpreterMachine overrides callGc with native Object path - WasmFunctionHandle.applyGc for GC-aware host functions - WasmExternRef can wrap either long or Object (for extern.convert_any) - ValType.isGcReference() cached during resolve() — zero-cost check - isGcReference correctly classifies concrete func types as non-GC - Table init populates objRefs for GC-typed tables - Instance.registerGcRef/gcRef/array deprecated - OpcodeImpl.boxForTable/unboxFromTable deprecated - Compiler: GC refs use Object.class, call bridge threads Object[] Compiler Phase 2: GC refs flow as Objects in generated bytecode. CompilerUtil maps GC ref types to Object.class/OBJECT_TYPE. Shaded helpers take/return Object for GC refs. Generated call_N bridges accept Object[] refArgs. BR_ON_NULL/NON_NULL checks distinguish GC (ifnull) from funcref (if_icmpeq). Non-GC code paths are completely unchanged — zero overhead.
Delete GcRefStore and its epoch-based mark-sweep collector. Wasm GC references (structs, arrays, i31) are now managed entirely by Java's garbage collector through the Object[] refs arrays in MStack, StackFrame, WasmStruct, WasmArray, GlobalInstance, and TableInstance. Changes: - Delete GcRefStore.java and GcRefStoreTest.java - Instance: remove gcRefs field, gcSafePoint() - Instance.registerGcRef/gcRef/array: throw UnsupportedOperationException - ExportFunction.apply(long...) throws on functions with GC params/returns directing users to applyGc(Object...) instead - Remove gcSafePoint() calls from Instance.Exports and initialization Users must migrate from apply(long...) to applyGc(Object...) for functions that use GC reference types (structs, arrays, i31, anyref). Non-GC functions (funcref, externref, numeric types) continue to work with apply(long...) unchanged.
Fix all remaining interpreter GC reference bugs: - MStack.popRef/peekRef: handle null refs array gracefully - REF_TEST/CAST_TEST/BR_ON_CAST: dispatch based on source type (popRef for GC refs, pop for funcref/externref) - ARRAY_GET/SET: use isGcReference() not isReference() for field type checks — funcref/externref elements stay in long[] path - ARRAY_NEW_DEFAULT: fill with REF_NULL_VALUE for non-GC ref types - ConstantEvaluators ARRAY_NEW_DEFAULT: same fix for global init - callGc: convert REF_NULL_VALUE to null for all ref return types - apply(long...): throw UnsupportedOperationException only after execution succeeds (traps propagate correctly) - WasmExternRef: can wrap Object for extern.convert_any round-trips Test generator (JavaTestGen): - Emit applyGc() for functions with GC params/returns - Null ref assertions use assertNull() for all ref types - WasmValue: toGcArgsValue, toGcResultValue, toGcAssertion methods - WasmValueType.isGcReference() helper
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.
WIP to fix #36