Repository navigation
runtime: split/join/concat slice 4 (string-build -12.6% I) - #13459
Merged
Merged
Conversation
…rray length region, fixed-count concat) D: String.prototype.split births each piece through a no-collect old/young allocation and keeps the source and result addresses live across it; only a refusal roots and reloads. F: a loop reading array[i].length of a declared string[] runs as one call-free region after a single scan of the slots. G: array join tests the heap-string tag first and copies short pieces inline. Count-specialized js_string_concat_parts_2..5 with unrolled operand classification and copy.
|
Caution Review failedThe pull request is closed. Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
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
Slice 4 of the string-build work (follows #13450). 30-string-build: 7.195B -> 6.291B instructions (-12.6%); the remaining gap to scriptc is split old birth and GC.
arena_alloc_gc_old_no_collect(and the existing nursery no-collect form throughstring_storage_alloc_for_no_collect) serve a piece from a swept same-size hole or from the block that is already open and never reachgc_check_triggeror a block reservation: a non-null return proves nothing moved, sosplit_by_delimiterkeeps the source and result addresses live across the piece allocation. A refusal takes the unchanged rooted, collecting allocation and refreshes both addresses from their handles, so the collection decision is the one the unconditional call would have made..lengthloops.for (i < a.length) s += a[i].lengthover a declaredstring[]is admitted by the indexed-owner region: ordinary unforwarded array without element descriptors,length <= capacity, one preheader scan that every slot is a heap string or an inline ASCII string (a hole,undefined, an object or a non-ASCII inline string declines the whole region before any body effect), then a call-free body (tag test + header load per element). The effect-gated entry poll stays (slice-2 lesson).u64totals and copy short pieces inline.js_string_concat_parts_2..5. Count-specialized entries for the operand counts the compiler knows; the operand classification and the copy are unrolled with constant indices (generic over N, selected byn, no per-program code). The generic entry dispatches to them.Results (qb9, x86-64-v3, KEEP_SYMBOLS, main 88ed1e5 vs head 304a32b)
All other js-compiled benchmarks: instructions within 0.02% (43-generators -0.30%). n5 cycle deltas on unchanged-instruction benchmarks reach +/-9% on this shared host (n11 re-run: 24-map-set -6.2%, 32-regex +2.2%, same instruction counts), so cycles carry host noise; instructions are exact.
GC_LOG schedule (same kinds, freed/old bytes) and stdout identical on 30, 24, 31. RSS n5 median (KiB): 30-string-build 238,720 -> 238,768, 24-map-set 28,240 -> 28,296, 31-json 149,908 -> 149,880 (no allocation count, size, capacity or generation changes; timing-free).
.text: 30-string-build -1,428 B, 24-map-set +2,152 B, 31-json +27,256 B (+0.43%: the four unrolled concat entries, 2.8-5.9 KB each, replace one 6.1 KB generic entry; reported, not hidden).
Startup, exact callgrind Ir, n3 per arm, deterministic, ASLR off:
memcmp/bcmppreload on both arms. Controlled head <= main on all five. The raw positives are layout artifacts: with the JMS control alone commander was +153, all of it in glibc__memcmp_avx2_movbe(13,943 calls from the same callers in both arms; the delta sits in the `(aTests
test-files/test_gap_jst6_split_join.tsagainst Node: split of empty strings/separators/unicode/lone surrogates/very long/20k pieces, join of holey arrays and non-string elements with toString/Symbol, string-array length loops over holes, undefined, null, objects, a Proxy, an accessor element, a subclass, a shifted array, concat with 2..6 operands across every value kind. Passes on main and head.