A perry Uint8Array is a BufferHeader in the buffer registries — lookup_typed_array_kind can never contain it. Any consumer that treats a kind-registry miss as "no element / not indexable / no length" gives wrong answers for u8 receivers, not slow paths.
Two confirmed-and-fixed instances (branch perf/9342-u8-inline-read): js_typed_array_read_f64 (returned undefined per read) and js_typed_array_read_int32 (returned 0 per read — the worse one: zero is plausible in |0 contexts, corrupting arithmetic silently). Both were #8617-era additions; every OLDER consumer carries a buffer arm beside the TA arm (the js_uint8array_index_get_value pattern), which is what the new code failed to copy.
The audit
197 call sites (site list below, generated from the fix branch). The question per site: what does this code do when the receiver is a registered buffer and the lookup misses? Three answer classes:
Highest-density files: array/iter_methods.rs (13), typedarray/mod.rs (9), proxy.rs (7), array/indexing.rs (7), typedarray/access.rs (6, two fixed), typed_feedback.rs (6), object/field_get_set/enumeration.rs (6), value/dyn_index.rs (5), object/polymorphic_index.rs (5), array/from_concat.rs (5).
Heuristic from the two found: prioritize sites younger than #8617 and sites that RETURN a value on miss (rather than dispatching). A minimized u8 fixture per suspicious site (module-global new Uint8Array(n) receiver) settles each in one run.
Full site list (file:line, 197)
crates/perry-runtime/src/atomics.rs:213
crates/perry-runtime/src/atomics.rs:237
crates/perry-runtime/src/registry_latch_probes.rs:35
crates/perry-runtime/src/registry_latch_probes.rs:64
crates/perry-runtime/src/registry_latch_probes.rs:72
crates/perry-runtime/src/registry_latch_probes.rs:81
crates/perry-runtime/src/registry_latch_probes.rs:277
crates/perry-runtime/src/registry_latch_probes.rs:288
crates/perry-runtime/src/proxy.rs:771
crates/perry-runtime/src/proxy.rs:1288
crates/perry-runtime/src/proxy.rs:1405
crates/perry-runtime/src/proxy.rs:1495
crates/perry-runtime/src/proxy.rs:1857
crates/perry-runtime/src/proxy.rs:2094
crates/perry-runtime/src/proxy.rs:2114
crates/perry-runtime/src/validators.rs:248
crates/perry-runtime/src/node_v8.rs:133
crates/perry-runtime/src/typedarray_props.rs:36
crates/perry-runtime/src/typedarray_props.rs:1028
crates/perry-runtime/src/node_stream_readwrite.rs:1424
crates/perry-runtime/src/node_stream_constructors/introspection.rs:122
crates/perry-runtime/src/node_stream_constructors/introspection.rs:137
crates/perry-runtime/src/node_stream_constructors/introspection.rs:160
crates/perry-runtime/src/text.rs:309
crates/perry-runtime/src/text.rs:364
crates/perry-runtime/src/text.rs:513
crates/perry-runtime/src/array/from_concat.rs:347
crates/perry-runtime/src/array/from_concat.rs:592
crates/perry-runtime/src/array/from_concat.rs:890
crates/perry-runtime/src/array/from_concat.rs:909
crates/perry-runtime/src/array/from_concat.rs:1058
crates/perry-runtime/src/array/generic.rs:242
crates/perry-runtime/src/webassembly.rs:83
crates/perry-runtime/src/typed_feedback.rs:521
crates/perry-runtime/src/typed_feedback.rs:615
crates/perry-runtime/src/typed_feedback.rs:702
crates/perry-runtime/src/typed_feedback.rs:1645
crates/perry-runtime/src/typed_feedback.rs:2225
crates/perry-runtime/src/typed_feedback.rs:2562
crates/perry-runtime/src/typedarray/bigint.rs:129
crates/perry-runtime/src/value/dynamic_arith.rs:227
crates/perry-runtime/src/value/dynamic_object.rs:114
crates/perry-runtime/src/value/dynamic_object.rs:227
crates/perry-runtime/src/value/dynamic_object.rs:442
crates/perry-runtime/src/value/dynamic_object.rs:528
crates/perry-runtime/src/symbol/get.rs:1006
crates/perry-runtime/src/bun_ffi/call.rs:382
crates/perry-runtime/src/builtins/arithmetic.rs:790
crates/perry-runtime/src/array/header.rs:777
crates/perry-runtime/src/array/header.rs:808
crates/perry-runtime/src/array/header.rs:852
crates/perry-runtime/src/array/header.rs:1036
crates/perry-runtime/src/array/alloc.rs:342
crates/perry-runtime/src/array/reduce_right.rs:47
crates/perry-runtime/src/array/splice_slice.rs:220
crates/perry-runtime/src/array/indexing.rs:119
crates/perry-runtime/src/array/indexing.rs:578
crates/perry-runtime/src/array/indexing.rs:614
crates/perry-runtime/src/array/indexing.rs:809
crates/perry-runtime/src/array/indexing.rs:863
crates/perry-runtime/src/array/indexing.rs:1222
crates/perry-runtime/src/array/indexing.rs:1450
crates/perry-runtime/src/array/join.rs:746
crates/perry-runtime/src/array/iter_object.rs:275
crates/perry-runtime/src/array/fill_extend.rs:45
crates/perry-runtime/src/array/fill_extend.rs:124
crates/perry-runtime/src/array/fill_extend.rs:161
crates/perry-runtime/src/array/fill_extend.rs:229
crates/perry-runtime/src/array/flat_clone.rs:616
crates/perry-runtime/src/json/stringify.rs:555
crates/perry-runtime/src/json/stringify.rs:831
crates/perry-runtime/src/json/stringify.rs:979
crates/perry-runtime/src/json/stringify.rs:1655
crates/perry-runtime/src/node_api_host/buffers.rs:329
crates/perry-runtime/src/node_api_host/buffers.rs:344
crates/perry-runtime/src/typedarray/access.rs:138
crates/perry-runtime/src/typedarray/access.rs:204
crates/perry-runtime/src/typedarray/access.rs:448
crates/perry-runtime/src/typedarray/access.rs:652
crates/perry-runtime/src/typedarray/access.rs:704
crates/perry-runtime/src/typedarray/access.rs:737
crates/perry-runtime/src/typedarray/mod.rs:536
crates/perry-runtime/src/typedarray/mod.rs:631
crates/perry-runtime/src/typedarray/mod.rs:693
crates/perry-runtime/src/typedarray/mod.rs:717
crates/perry-runtime/src/typedarray/mod.rs:808
crates/perry-runtime/src/typedarray/mod.rs:917
crates/perry-runtime/src/typedarray/mod.rs:960
crates/perry-runtime/src/typedarray/mod.rs:977
crates/perry-runtime/src/typedarray/mod.rs:1407
crates/perry-runtime/src/object/instanceof.rs:854
crates/perry-runtime/src/object/instanceof.rs:1536
crates/perry-runtime/src/object/instanceof.rs:1589
crates/perry-runtime/src/object/field_set_by_name.rs:595
crates/perry-runtime/src/object/polymorphic_index.rs:191
crates/perry-runtime/src/object/polymorphic_index.rs:248
crates/perry-runtime/src/object/polymorphic_index.rs:387
crates/perry-runtime/src/object/polymorphic_index.rs:399
crates/perry-runtime/src/object/polymorphic_index.rs:446
crates/perry-runtime/src/object/typed_array_define.rs:58
crates/perry-runtime/src/object/buffer_dispatch.rs:62
crates/perry-runtime/src/builtins/console.rs:83
crates/perry-runtime/src/object/native_call_method.rs:1012
crates/perry-runtime/src/array/concat_reverse.rs:108
crates/perry-runtime/src/array/search.rs:76
crates/perry-runtime/src/array/iter_methods.rs:258
crates/perry-runtime/src/array/iter_methods.rs:329
crates/perry-runtime/src/array/iter_methods.rs:523
crates/perry-runtime/src/array/iter_methods.rs:613
crates/perry-runtime/src/array/iter_methods.rs:675
crates/perry-runtime/src/array/iter_methods.rs:722
crates/perry-runtime/src/array/iter_methods.rs:765
crates/perry-runtime/src/array/iter_methods.rs:809
crates/perry-runtime/src/array/iter_methods.rs:867
crates/perry-runtime/src/array/iter_methods.rs:929
crates/perry-runtime/src/array/iter_methods.rs:1020
crates/perry-runtime/src/array/iter_methods.rs:1170
crates/perry-runtime/src/array/iter_methods.rs:1456
crates/perry-runtime/src/typedarray/slice_ops.rs:224
crates/perry-runtime/src/array/iterator.rs:1080
crates/perry-runtime/src/typedarray/construct.rs:68
crates/perry-runtime/src/typedarray/construct.rs:120
crates/perry-runtime/src/typedarray/construct.rs:281
crates/perry-runtime/src/typedarray/construct.rs:410
crates/perry-runtime/src/object/native_module_dispatch.rs:222
crates/perry-runtime/src/value/dyn_index.rs:188
crates/perry-runtime/src/value/dyn_index.rs:278
crates/perry-runtime/src/value/dyn_index.rs:587
crates/perry-runtime/src/value/dyn_index.rs:673
crates/perry-runtime/src/value/dyn_index.rs:723
crates/perry-runtime/src/builtins/formatting.rs:877
crates/perry-runtime/src/builtins/formatting.rs:1106
crates/perry-runtime/src/builtins/formatting.rs:1669
crates/perry-runtime/src/value/to_string.rs:526
crates/perry-runtime/src/value/to_string.rs:1161
crates/perry-runtime/src/object/descriptor_state.rs:511
crates/perry-runtime/src/object/descriptor_state.rs:748
crates/perry-runtime/src/object/util_types.rs:57
crates/perry-runtime/src/object/reflect_support.rs:31
crates/perry-runtime/src/object/reflect_support.rs:62
crates/perry-runtime/src/object/native_module_crypto_random.rs:78
crates/perry-runtime/src/builtins/numbers.rs:588
crates/perry-runtime/src/builtins/formatting/collections.rs:146
crates/perry-runtime/src/builtins/table.rs:276
crates/perry-runtime/src/builtins/formatting/typed_array_equality.rs:21
crates/perry-runtime/src/object/object_ops/prototype.rs:348
crates/perry-runtime/src/object/field_get_set/get_field_by_name_tail.rs:441
crates/perry-runtime/src/object/field_get_set/ic_miss.rs:603
crates/perry-runtime/src/object/field_get_set/enumeration.rs:270
crates/perry-runtime/src/object/field_get_set/enumeration.rs:646
crates/perry-runtime/src/object/field_get_set/enumeration.rs:756
crates/perry-runtime/src/object/field_get_set/enumeration.rs:1123
crates/perry-runtime/src/object/field_get_set/enumeration.rs:1503
crates/perry-runtime/src/object/field_get_set/enumeration.rs:1687
crates/perry-runtime/src/node_submodules/zlib.rs:267
crates/perry-runtime/src/json/replacer.rs:125
crates/perry-runtime/src/json/replacer.rs:264
crates/perry-runtime/src/json/replacer.rs:818
crates/perry-runtime/src/object/native_call_method/typed_array.rs:261
crates/perry-runtime/src/object/arguments.rs:636
crates/perry-runtime/src/object/typed_array_proto_thunks.rs:176
crates/perry-runtime/src/child_process/sync_run.rs:83
crates/perry-runtime/src/object/map_set_subclass.rs:72
crates/perry-runtime/src/object/to_string_tag.rs:80
crates/perry-runtime/src/object/to_string_tag.rs:219
crates/perry-runtime/src/object/object_ops_frozen.rs:153
crates/perry-runtime/src/object/object_ops_frozen.rs:267
crates/perry-runtime/src/object/object_ops_frozen.rs:362
crates/perry-runtime/src/object/object_ops_frozen.rs:617
crates/perry-runtime/src/object/object_ops/define_property.rs:1421
crates/perry-runtime/src/object/object_ops/has_own.rs:307
crates/perry-runtime/src/object/object_ops/has_own.rs:680
crates/perry-runtime/src/object/native_call_method/object_proto.rs:244
crates/perry-runtime/src/object/field_get_set/has_property.rs:601
crates/perry-runtime/src/object/field_get_set/get_field_by_name.rs:635
crates/perry-runtime/src/object/field_get_set/get_field_by_name.rs:1575
crates/perry-runtime/src/object/native_call_method/handle_methods.rs:149
crates/perry-runtime/src/object/native_call_method/primitive_methods.rs:861
crates/perry-runtime/src/promise/subclass.rs:64
crates/perry-runtime/src/child_process/v8_serde.rs:260
crates/perry-runtime/src/object/global_this/typed_array.rs:214
crates/perry-runtime/src/object/global_this/typed_array.rs:276
crates/perry-runtime/src/dgram/net.rs:206
crates/perry-runtime/src/child_process/value_util.rs:137
crates/perry-runtime/src/fs/stream/write_file_input.rs:73
crates/perry-runtime/src/buffer/query.rs:51
crates/perry-runtime/src/buffer/query.rs:219
crates/perry-runtime/src/buffer/access.rs:54
crates/perry-runtime/src/buffer/access.rs:94
crates/perry-runtime/src/buffer/access.rs:145
crates/perry-runtime/src/buffer/transcode.rs:115
crates/perry-runtime/src/buffer/from.rs:626
crates/perry-runtime/src/buffer/copy_bytes.rs:156
crates/perry-runtime/src/buffer/validate.rs:160
crates/perry-runtime/src/fs/stream.rs:243
crates/perry-runtime/src/fs/stream.rs:272
crates/perry-runtime/src/fs/mod.rs:291
Filed per review discussion on #9342 (audit scope statement moved out of the PR so the remainder stays claimable).
Context (#9342)
A perry
Uint8Arrayis aBufferHeaderin the buffer registries —lookup_typed_array_kindcan never contain it. Any consumer that treats a kind-registry miss as "no element / not indexable / no length" gives wrong answers for u8 receivers, not slow paths.Two confirmed-and-fixed instances (branch
perf/9342-u8-inline-read):js_typed_array_read_f64(returnedundefinedper read) andjs_typed_array_read_int32(returned0per read — the worse one: zero is plausible in|0contexts, corrupting arithmetic silently). Both were #8617-era additions; every OLDER consumer carries a buffer arm beside the TA arm (thejs_uint8array_index_get_valuepattern), which is what the new code failed to copy.The audit
197 call sites (site list below, generated from the fix branch). The question per site: what does this code do when the receiver is a registered buffer and the lookup misses? Three answer classes:
Highest-density files:
array/iter_methods.rs(13),typedarray/mod.rs(9),proxy.rs(7),array/indexing.rs(7),typedarray/access.rs(6, two fixed),typed_feedback.rs(6),object/field_get_set/enumeration.rs(6),value/dyn_index.rs(5),object/polymorphic_index.rs(5),array/from_concat.rs(5).Heuristic from the two found: prioritize sites younger than #8617 and sites that RETURN a value on miss (rather than dispatching). A minimized u8 fixture per suspicious site (module-global
new Uint8Array(n)receiver) settles each in one run.Full site list (file:line, 197)
Filed per review discussion on #9342 (audit scope statement moved out of the PR so the remainder stays claimable).