Repository navigation
Conversation
Sparse integer writes on untyped array properties and locals now promote to a hash instead of filling the hole. Locals whose keys are only proven at runtime become packed-or-hash arrays, typed clones carry them across direct calls, and int|float counter keys stay in frame cells so the promoted paths do not allocate per iteration.
Range analysis now narrows `$j = $i - 1` to a raw isub whose acquire boxes it into the int|float counter slot. Treat that acquire as a numeric box so the seed reuses the frame cell instead of allocating per entry.
… them once A float variable key past the end of a non-promotable packed local now promotes it to a hash instead of zero-filling. A boxed float key on a promotable local no longer repeats its precision deprecation on the hash write after the range probe.
…static slots A counter-key read of an array<int> local takes the ?int view only when the local can hold a promotable array (written by element, or recorded promotable); an unwritten local reads as mixed again, so buffer indexes and int reassignments compile. The skipping-key hash promotion applies to instance properties only, since a static slot's ??= stores boxed values.
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
An integer key that skips a slot (
k > count($a)ork < 0) must give PHP's hash shape. elephc instead zero-filled the gap in packed storage in several places:class H { public $items = []; }with$h->items[1] = 6on a fresh object printed[0,6]instead of{"1":6}(found while fixing A ?: on truthy nullable-int parameter with a null default SIGSEGVs #1944);$a = [1]; $a[$k] = $n;printed[1,0,0,6]);array<int>locals passed to user functions, where the fix must not box every slot.What changes
0is typed as hash storage, and appends on a promoted hash are supported. Static properties share the same rule throughupdated_array_property_assign_type.ArrayToHash+HashSet). The literal-key rule from perf(core): close the native and builtin speed gap #2090 (nonempty_array_key_forces_hash_storage) is kept; the broad unproven-key clause it added is replaced by the per-site logic below, so packed storage survives where the key really stays in range.src/types/checker/promotable_arrays.rs): a candidatearray<int>local (no references, nounset, no by-reference or dynamic calls, and so on) keeps typed raw slots. Its element operations dispatch on the heap kind (one header byte). It is promoted to a hash in place only when a key really skips a slot at run time, and whole-value reads see the kind-awarearray<mixed>view.?intvalues andnullentries keep PHP'snull.src/generics/promotable_clones.rs): a direct call that passes a promotable local to an undeclared by-value parameter gets a clone that declares that parameterarray<int>, so the array crosses the call raw instead of being boxed into themixedABI. Clone bodies carry their own source identity, so span-keyed checker tables stay apart and warnings are not duplicated.src/codegen/stack_numeric.rs,src/ir_passes/peephole/tagged_box.rs):int|floatcounter keys such as$j + 1and$j--stay in frame-local numeric cells when used as array or hash keys. The key materializer reads the cell inline.?intboxes that only feed an ordering comparison, or nothing at all, are removed.All five targets get the same codegen (aarch64 and x86_64 emitters), with asm tests that run on every target.
Performance
Insertion sort over 6000 elements keyed by
$j + 1and$j--:Tests
tests/codegen/arrays/sparse_int_keys.rsandtests/codegen/objects/property_access/sparse_int_keys.rs: PHP shapes for property and local writes, packed-or-hash promotion, clones,nullentries, leak checks.tests/codegen/optimizer/stack_numeric/counter_keys.rs: allocation counts that do not grow with iterations, PHP semantics of nullable ordering, float and negative counter keys, asm checks on all five targets.src/ir_lower/tests/sparse_key_writes.rsandsrc/ir_passes/tests/tagged_box_test.rs: lowering and peephole unit tests.Docs:
docs/php/arrays.md,docs/internals/the-codegen.md,docs/internals/memory-model.md.