Re: [RFC] [Discussion] Bound-Erased Generic Types
| From: | Seifeddine Gmati | Date: | Sun, 24 May 2026 06:29:08 +0000 |
| Subject: | Re: [RFC] [Discussion] Bound-Erased Generic Types | ||
| References: | 1 2 3 4 5 6 7 8 9 10 11 12 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-131003@lists.php.net to get a copy of this message | ||
Hi Rob
> I'm curious how you'd fix it. The fix has to be either (a) per-child bytecode
> specialization (which the RFC explicitly says it doesn't do), (b) runtime indirection at every
> entry (which adds dispatch cost the RFC doesn't acknowledge), or (c) something else not
> described. The architecture section makes a specific claim about where parameter checks happen; the
> bug-fix commitment implies something different.
it's option (b), with measured cost. landed in v0.22.
The mechanism: when
class IntBox extends Box<int> links, the engine
produces a substituted clone of each inherited method that has T in
its signature. The clone shares the parent's bytecode but carries its
own arg_info with T substituted to int. That part predated
this
change (It existed for reflections). What changed is that the runtime
check sites now read from the clone's arg_info rather than from
compile-time-baked values.
Cost: non-generic code pays nothing at the bake/strip sites, the gates
check op_array->generic_types, which is NULL for non-generic
functions. The only cross-cutting change is RECV_INIT's
verify-after-default, which adds one helper call per default usage;
the helper short-circuits for already-validated defaults. Generic code
pays one helper dispatch per T-bearing parameter per call and one
extra verify opcode per T-bearing return path. Bench drift is within
the ±0.1% band documented in the Performance section.
Cheers,
Seifeddine.