This is an automated email from the ASF dual-hosted git repository. chaokunyang pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/fory-site.git
commit e559ab23393d2687a50e18fdee5b4003586ea2a2 Author: chaokunyang <[email protected]> AuthorDate: Sat Jul 4 18:12:45 2026 +0000 🔄 synced local 'docs/specification/' with remote 'docs/specification/' --- docs/specification/xlang_implementation_guide.md | 61 ++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/docs/specification/xlang_implementation_guide.md b/docs/specification/xlang_implementation_guide.md index d8fb205012..0484ef408b 100644 --- a/docs/specification/xlang_implementation_guide.md +++ b/docs/specification/xlang_implementation_guide.md @@ -388,9 +388,9 @@ chunk, nullability, reference, and type-dispatch semantics. It is still the right allocation proof for count-based preallocation: after validating a non-empty count and reading any serializer-owned header or type metadata that precedes allocation, call `checkReadableBytes(logicalCount)` before allocating, -reserving, or size-hinting from that count. The byte owner handles buffer versus -stream readiness; the container serializer then allocates with the declared -count and reads elements through its normal owner path. +reserving backing capacity, or size-hinting from that count. The byte owner +handles buffer versus stream readiness; the container serializer then allocates +with the declared count and reads elements through its normal owner path. This check is not a full container-body validation. It only prevents a small or truncated input from causing a large count-based preallocation. Chunk sizes, @@ -398,6 +398,61 @@ duplicate keys, element value semantics, and protocol strictness remain owned by the container/map serializer and should be validated only when they protect a real owner invariant. +Materializing readers should also reserve a root-operation estimated graph +memory budget before allocation or size hinting. The budget state belongs to +`ReadContext` or the equivalent root read state, not to ambient thread-local +state. Root facades set or reset the per-operation budget only; they must not +pre-reserve root type or root self bytes. `maxGraphMemoryBytes` defaults to a +fixed `128 MiB`; positive configuration overrides the default; explicit +non-positive configuration is invalid and must be rejected when the runtime is +created. Do not derive this budget from root input size, and do not add dynamic +stream bytes-read accounting for this budget. +Because the budget is fixed per root, read state should not mirror the +configured maximum into a second active-limit field. Use the existing +configuration, or one configured maximum field when the config is not otherwise +available, plus the mutable remaining budget. + +Read context or equivalent read state owns only raw byte reservation. It must +not expose counted arithmetic helpers or collection, map, array, struct, or +object semantic reservation APIs. Concrete serializers and generated serializer +owners compute the storage constants and formulas for the owner path they +allocate, including counted-byte overflow checks. +Read state must not grow non-memory-budget APIs for this feature, including +ref-publication controls, temporary-owner controls, serializer-owner controls, +conversion helpers, or APIs that encode the kind of value being materialized. +Concrete serializers and generated serializers own those decisions. + +The budget is an approximate gate for materialized graph owners, mainly +collections, maps, arrays, structs, and objects. It does not measure exact heap +bytes, and actual process memory can be higher. Reserve self storage exactly +once at the owner that stores or allocates the value. Root facades reset the +budget only and must not reserve root value storage. Reference-backed +containers, maps, sets, and +object/reference arrays reserve nonzero owner self cost plus reference slots; +each referenced heap owner then reserves its own shallow self cost when +materialized. Inline/value containers reserve element storage; inline/value maps +reserve key plus value storage; pointer, box, and dynamic materialization owners +reserve the heap or boxed storage they allocate. Value serializers, including +root and generated struct/product read paths, do not reserve their own self +storage. Struct/record/POJO/tuple, compatible, generated, and dynamic object +owners reserve a nonzero shallow self cost plus shallow field storage only in +reference-object runtimes or dynamic/boxed materialization paths. +Parents must not recursively include child object, collection, map, string, +binary, or primitive dense-array contents. Skip enum/union as separate owners and +skip dedicated string, binary, primitive scalar, primitive array, and primitive +dense-array leaf owners, but do not skip general inline-value containers such as +vectors or lists of value objects. If reference slot size is not cheap or +reliable to query, use a 4-byte reference slot. Native runtimes may use +conservative lower-bound estimates instead of guessing non-portable object, +container, allocator, table, node, entry, or debug-layout details. Reject +arithmetic overflow before budget comparison or allocation, and keep the +existing `checkReadableBytes` proof before backing +allocation or capacity reservation. +Skipped leaf owners must still be gated by remaining input bytes. If unread +bytes are insufficient for a string, binary value, primitive scalar, primitive +array, or primitive dense array, the runtime must not read or create that leaf +value. + For TypeDef or TypeMeta bodies, first prove that the encoded metadata body bytes are readable through the byte owner. Field-list allocation should happen after that body readability check and should not use a separate small initial-capacity --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
