Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions changelog.d/9712-receiver-descriptor-counted-loops.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
**Ordinary counted loops now consume the shared receiver descriptor model**
(#9254 phase 3). For a strict, call-free `i < array.length` numeric-array loop,
codegen validates the receiver and element layout once in the preheader, keeps
the boxed receiver precisely rooted, and carries a cached base handle through
the loop. Exact bounded `array[i]` reads select an invariant raw-load arm instead
of repeating the receiver tag, header, integrity, length, capacity, and layout
checks at every use; a failed one-time validation retains the existing guarded
fallback semantics.

Admission is intentionally conservative: the shared region analysis rejects
calls, allocations, coercions, suspensions, unwind edges, and every unmodelled
operation, while fired back-edge GC polls refresh both the rooted receiver and
its derived handle. Regression coverage pins the call-free fast block, the
allocating-region rejection, the guard-miss fallback, and a real rate-1 moving
collection with evacuated from-space protected.
12 changes: 12 additions & 0 deletions changelog.d/9716-receiver-descriptor-table-retirement.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
**Receiver proof state now has one lifecycle owner** (#9254 phase 4). Codegen's
cached array lengths, bounded indices, packed-f64 loop facts, masked-window
facts, and native buffer views now live as typed payloads in the shared receiver
descriptor table. Together with the poll-refreshed receiver addresses migrated
in phases 2 and 3, this retires all six independent mechanisms named by the
receiver-region proposal.

The table now owns nested dynamic extents, lexical-scope teardown, reassignment
invalidation, and non-moving buffer-view address contracts. Existing fast-path
producers and consumers keep their established fallback behavior, while tests
pin nested-loop restoration, shared scope cleanup, temporary view replacement,
and moving-GC refresh behavior.
5 changes: 0 additions & 5 deletions crates/perry-codegen/src/codegen/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1190,11 +1190,7 @@ pub(super) fn compile_closure(
class_keys_slots: HashMap::new(),
class_shape_slots: HashMap::new(),
class_header_images: HashMap::new(),
cached_lengths: HashMap::new(),
array_length_snapshots: HashMap::new(),
bounded_index_pairs: Vec::new(),
packed_f64_loop_facts: Vec::new(),
masked_window_array_facts: Vec::new(),
string_window_array_facts: Vec::new(),
masked_region_scalar_locals: std::collections::HashSet::new(),
suppressed_cleared_shadow_slots: std::collections::HashSet::new(),
Expand Down Expand Up @@ -1298,7 +1294,6 @@ pub(super) fn compile_closure(
property_get_ic_override: None,
typed_parse_rodata: Vec::new(),
buffer_data_slots: HashMap::new(),
buffer_view_slots: HashMap::new(),
native_arena_owner_aliases: HashMap::new(),
native_arena_ambiguous_owner_aliases: HashSet::new(),
disable_buffer_fast_path: cross_module.disable_buffer_fast_path,
Expand Down
10 changes: 0 additions & 10 deletions crates/perry-codegen/src/codegen/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -968,11 +968,7 @@ pub(super) fn compile_module_entry(
class_keys_slots: HashMap::new(),
class_shape_slots: HashMap::new(),
class_header_images: HashMap::new(),
cached_lengths: HashMap::new(),
array_length_snapshots: HashMap::new(),
bounded_index_pairs: Vec::new(),
packed_f64_loop_facts: Vec::new(),
masked_window_array_facts: Vec::new(),
string_window_array_facts: Vec::new(),
masked_region_scalar_locals: std::collections::HashSet::new(),
suppressed_cleared_shadow_slots: std::collections::HashSet::new(),
Expand Down Expand Up @@ -1085,7 +1081,6 @@ pub(super) fn compile_module_entry(
property_get_ic_override: None,
typed_parse_rodata: Vec::new(),
buffer_data_slots: HashMap::new(),
buffer_view_slots: HashMap::new(),
native_arena_owner_aliases: HashMap::new(),
native_arena_ambiguous_owner_aliases: HashSet::new(),
disable_buffer_fast_path: cross_module.disable_buffer_fast_path,
Expand Down Expand Up @@ -1767,11 +1762,7 @@ pub(super) fn compile_module_entry(
class_keys_slots: HashMap::new(),
class_shape_slots: HashMap::new(),
class_header_images: HashMap::new(),
cached_lengths: HashMap::new(),
array_length_snapshots: HashMap::new(),
bounded_index_pairs: Vec::new(),
packed_f64_loop_facts: Vec::new(),
masked_window_array_facts: Vec::new(),
string_window_array_facts: Vec::new(),
masked_region_scalar_locals: std::collections::HashSet::new(),
suppressed_cleared_shadow_slots: std::collections::HashSet::new(),
Expand Down Expand Up @@ -1884,7 +1875,6 @@ pub(super) fn compile_module_entry(
property_get_ic_override: None,
typed_parse_rodata: Vec::new(),
buffer_data_slots: HashMap::new(),
buffer_view_slots: HashMap::new(),
native_arena_owner_aliases: HashMap::new(),
native_arena_ambiguous_owner_aliases: HashSet::new(),
disable_buffer_fast_path: cross_module.disable_buffer_fast_path,
Expand Down
9 changes: 2 additions & 7 deletions crates/perry-codegen/src/codegen/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1137,11 +1137,7 @@ pub(super) fn compile_function(
class_keys_slots: HashMap::new(),
class_shape_slots: HashMap::new(),
class_header_images: HashMap::new(),
cached_lengths: HashMap::new(),
array_length_snapshots: HashMap::new(),
bounded_index_pairs: Vec::new(),
packed_f64_loop_facts: Vec::new(),
masked_window_array_facts: Vec::new(),
string_window_array_facts: Vec::new(),
masked_region_scalar_locals: std::collections::HashSet::new(),
suppressed_cleared_shadow_slots: std::collections::HashSet::new(),
Expand Down Expand Up @@ -1250,7 +1246,6 @@ pub(super) fn compile_function(
property_get_ic_override: None,
typed_parse_rodata: Vec::new(),
buffer_data_slots: HashMap::new(),
buffer_view_slots: HashMap::new(),
native_arena_owner_aliases: HashMap::new(),
native_arena_ambiguous_owner_aliases: HashSet::new(),
disable_buffer_fast_path: cross_module.disable_buffer_fast_path,
Expand Down Expand Up @@ -1319,7 +1314,7 @@ pub(super) fn compile_function(
let scope_idx = ctx.buffer_alias_base + ctx.buffer_data_slots.len() as u32;
ctx.buffer_data_slots
.insert(p.id, (buf_slot.clone(), scope_idx));
ctx.buffer_view_slots.insert(
ctx.receiver_descriptors.materialize_buffer_view(
p.id,
BufferViewSlot {
data_slot: buf_slot,
Expand Down Expand Up @@ -1383,7 +1378,7 @@ pub(super) fn compile_function(
let scope_idx = ctx.buffer_alias_base + ctx.buffer_data_slots.len() as u32;
ctx.buffer_data_slots
.insert(p.id, (data_slot.clone(), scope_idx));
ctx.buffer_view_slots.insert(
ctx.receiver_descriptors.materialize_buffer_view(
p.id,
BufferViewSlot {
data_slot,
Expand Down
10 changes: 0 additions & 10 deletions crates/perry-codegen/src/codegen/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -543,11 +543,7 @@ pub(super) fn compile_method(
class_keys_slots: HashMap::new(),
class_shape_slots: HashMap::new(),
class_header_images: HashMap::new(),
cached_lengths: HashMap::new(),
array_length_snapshots: HashMap::new(),
bounded_index_pairs: Vec::new(),
packed_f64_loop_facts: Vec::new(),
masked_window_array_facts: Vec::new(),
string_window_array_facts: Vec::new(),
masked_region_scalar_locals: std::collections::HashSet::new(),
suppressed_cleared_shadow_slots: std::collections::HashSet::new(),
Expand Down Expand Up @@ -662,7 +658,6 @@ pub(super) fn compile_method(
property_get_ic_override: None,
typed_parse_rodata: Vec::new(),
buffer_data_slots: HashMap::new(),
buffer_view_slots: HashMap::new(),
native_arena_owner_aliases: HashMap::new(),
native_arena_ambiguous_owner_aliases: HashSet::new(),
disable_buffer_fast_path: cross_module.disable_buffer_fast_path,
Expand Down Expand Up @@ -1712,11 +1707,7 @@ pub(super) fn compile_static_method(
class_keys_slots: HashMap::new(),
class_shape_slots: HashMap::new(),
class_header_images: HashMap::new(),
cached_lengths: HashMap::new(),
array_length_snapshots: HashMap::new(),
bounded_index_pairs: Vec::new(),
packed_f64_loop_facts: Vec::new(),
masked_window_array_facts: Vec::new(),
string_window_array_facts: Vec::new(),
masked_region_scalar_locals: std::collections::HashSet::new(),
suppressed_cleared_shadow_slots: std::collections::HashSet::new(),
Expand Down Expand Up @@ -1820,7 +1811,6 @@ pub(super) fn compile_static_method(
property_get_ic_override: None,
typed_parse_rodata: Vec::new(),
buffer_data_slots: HashMap::new(),
buffer_view_slots: HashMap::new(),
native_arena_owner_aliases: HashMap::new(),
native_arena_ambiguous_owner_aliases: HashSet::new(),
disable_buffer_fast_path: cross_module.disable_buffer_fast_path,
Expand Down
5 changes: 4 additions & 1 deletion crates/perry-codegen/src/collectors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,10 @@ pub(crate) use ptr_numarray::{NumArrayDensity, NumArrayLocal};
pub(crate) use ptr_shape::{ptr_shape_locals_enabled, PtrShapeLocal};
pub(crate) use ptr_shape_callbacks::collect_array_callback_shapes;
pub(crate) use ptr_shape_returns::collect_exported_return_shapes;
pub(crate) use receiver_regions::ReceiverDescriptorTable;
pub(crate) use receiver_regions::{
region_enders_in_stmts_with_trusted_operations, ReceiverArrayValidationKind,
ReceiverDescriptorTable, RegionEnder,
};
pub(crate) use refs::{
collect_let_ids, collect_ref_ids_in_expr, collect_ref_ids_in_stmts, is_clamp_call,
};
Expand Down
2 changes: 1 addition & 1 deletion crates/perry-codegen/src/collectors/ptr_numarray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
//! has `int_range` proof `[0, max]` with `max < proven_initial_length`
//! (length can only grow — `pop`-class shrinkers are disqualified — so
//! `idx < initial_length <= current length` holds forever), or the site is
//! a `bounded_index_pairs` loop read. Everything unproven falls back to the
//! a bounded-index receiver descriptor read. Everything unproven falls back to the
//! Phase 4a.1/4a.2 guarded tiers, which maintain the same invariants.
//! * **Hole observability (density gating)**: guard-free READS are emitted
//! only in ToNumber contexts (the Phase 4a number-context reader), where a
Expand Down
Loading
Loading