39 lines
1.5 KiB
Diff
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);
|
|
}
|