game engines/web frameworks: 27 CWE-407 defects + 3 CLEAN; 194 sites, 78 ecosystems
This commit is contained in:
parent
547a9f5738
commit
4d3fcc8e73
76 changed files with 6216 additions and 17 deletions
|
|
@ -0,0 +1,66 @@
|
|||
Fixes bevy-0001: slab_allocator — O(E×L×S) Vec::iter().position() in free_empty_slabs().
|
||||
|
||||
--- a/crates/bevy_render/src/slab_allocator.rs
|
||||
+++ b/crates/bevy_render/src/slab_allocator.rs
|
||||
|
||||
@@ DEFECT bevy-0001: free_empty_slabs() — Vec::iter().position() inside nested loop
|
||||
@@ Called every frame from DeallocationStage::commit() for every freed GPU slab.
|
||||
@@ No reverse map slab_id→layout; must scan all layout buckets to find the slab.
|
||||
|
||||
pub struct SlabAllocator<I>
|
||||
where
|
||||
I: SlabItem,
|
||||
{
|
||||
pub slabs: HashMap<SlabId<I>, Slab<I>>,
|
||||
next_slab_id: SlabId<I>,
|
||||
pub key_to_slab: HashMap<I::Key, SlabId<I>>,
|
||||
slab_layouts: HashMap<I::Layout, Vec<SlabId<I>>>,
|
||||
+ /// FIX bevy-0001: reverse map — slab_id → layout for O(1) lookup in free_empty_slabs
|
||||
+ slab_id_to_layout: HashMap<SlabId<I>, I::Layout>,
|
||||
}
|
||||
|
||||
// In SlabAllocator::new() / Default impl — initialize the new field:
|
||||
- SlabAllocator {
|
||||
+ SlabAllocator {
|
||||
slabs: HashMap::default(),
|
||||
next_slab_id: SlabId { ... },
|
||||
key_to_slab: HashMap::default(),
|
||||
slab_layouts: HashMap::default(),
|
||||
+ slab_id_to_layout: HashMap::default(),
|
||||
}
|
||||
|
||||
// In allocate_general() — when a new slab is created, record its layout:
|
||||
self.slabs.insert(new_slab_id, Slab::General(new_slab));
|
||||
candidate_slabs.push(new_slab_id);
|
||||
+ // FIX bevy-0001: maintain reverse map for O(1) free_empty_slabs lookup
|
||||
+ self.slab_id_to_layout.insert(new_slab_id, layout.clone());
|
||||
|
||||
// Replace the O(E×L×S) implementation:
|
||||
- fn free_empty_slabs(&mut self, empty_slabs: impl Iterator<Item = SlabId<I>>) {
|
||||
- for empty_slab in empty_slabs {
|
||||
- self.slab_layouts.values_mut().for_each(|slab_ids| {
|
||||
- let idx = slab_ids.iter().position(|&slab_id| slab_id == empty_slab);
|
||||
- // O(S) linear scan per layout bucket — CWE-407
|
||||
- if let Some(idx) = idx {
|
||||
- slab_ids.remove(idx);
|
||||
- }
|
||||
- });
|
||||
- self.slabs.remove(&empty_slab);
|
||||
- }
|
||||
- }
|
||||
+ fn free_empty_slabs(&mut self, empty_slabs: impl Iterator<Item = SlabId<I>>) {
|
||||
+ for empty_slab in empty_slabs {
|
||||
+ // FIX bevy-0001: O(1) layout lookup via reverse map
|
||||
+ if let Some(layout) = self.slab_id_to_layout.remove(&empty_slab) {
|
||||
+ if let Some(slab_ids) = self.slab_layouts.get_mut(&layout) {
|
||||
+ if let Some(pos) = slab_ids.iter().position(|&id| id == empty_slab) {
|
||||
+ slab_ids.swap_remove(pos); // O(1) swap-remove (order irrelevant)
|
||||
+ }
|
||||
+ if slab_ids.is_empty() {
|
||||
+ self.slab_layouts.remove(&layout);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ self.slabs.remove(&empty_slab);
|
||||
+ }
|
||||
+ }
|
||||
Loading…
Add table
Add a link
Reference in a new issue