java-topology/defects/ruffle-0001/patch/ruffle-0001.patch

39 lines
1.5 KiB
Diff

# UNDF: UNDF-2026-000001155
--- a/core/src/avm2/optimizer/type_aware.rs
+++ b/core/src/avm2/optimizer/type_aware.rs
@@ -1,6 +1,7 @@
+use std::collections::HashSet;
+
// ... existing imports ...
- // Block #0 is the entry block
- let mut worklist = vec![0];
+ // Block #0 is the entry block. Companion HashSet for O(1) dedup (was O(B) Vec::contains).
+ let mut worklist = vec![0usize];
+ let mut worklist_set: HashSet<usize> = [0].into_iter().collect();
while let Some(block_idx) = worklist.pop() {
+ worklist_set.remove(&block_idx);
// In every call to process_jump, pass &mut worklist_set as the new argument.
@@ -702,7 +702,8 @@ fn process_jump<'gc>(
abstract_states: &mut [Option<AbstractState<'gc>>],
current_state: &AbstractStateRef<'_, 'gc>,
op_index_to_block_index_table: &HashMap<usize, usize>,
- worklist: &mut Vec<usize>,
+ worklist: &mut Vec<usize>,
+ worklist_set: &mut HashSet<usize>,
do_optimize: bool,
) -> Result<(), Error<'gc>> {
if do_optimize {
@@ -722,9 +722,8 @@ fn process_jump<'gc>(
abstract_states[target_block_id] = Some(current_state.to_owned());
};
- // FP reschedules blocks to the front of queue (for us, it'd be back of the vec).
- // I don't know if there's any good reason for that, but not doing it is faster.
- if !worklist.contains(&target_block_id) {
+ // O(1) dedup via companion HashSet instead of O(B) Vec::contains scan.
+ if worklist_set.insert(target_block_id) {
worklist.push(target_block_id);
}