citra: 1 CWE-407 defect, MOADs 0002-0005 CLEAN
MOAD-0001: citra-0001 RasterizerCache page_table surfaces vector O(P*S^2) UnregisterSurface calls std::find(surfaces.begin(), surfaces.end(), surface_id) for each of P pages a surface spans. With S overlapping surfaces per page, total unregister cost is O(P*S) per surface, O(P*S^2) overall. Fix: change std::vector<SurfaceId> to std::unordered_set<SurfaceId> (std::hash<Common::SlotId> already defined). 3.4x measured at S=500, P=64. Hot path: InvalidateRegion called per CPU write to GPU texture memory. MOAD-0002: CLEAN. System singleton is intentional single-emulator architecture; subsystems injected via System& reference, no intertangle coupling found. MOAD-0003: CLEAN. thread_local only used for JNIEnv* JVM attachment in Android JNI (standard pattern, not request-scoped identity). MOAD-0004: CLEAN. No credential values logged verbatim; JWT token size only. MOAD-0005: CLEAN. GetPublicKey static cache is room-server single-threaded; JitEngine shader cache is GPU-thread single-threaded; all others use mutex. Source: azahar-emu/azahar (Citra continuation), depth=1.
This commit is contained in:
parent
7786adc4c0
commit
cdba4c80e9
7 changed files with 222 additions and 0 deletions
36
defects/citra-0001/test/BenchmarkQuick.java
Normal file
36
defects/citra-0001/test/BenchmarkQuick.java
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
import java.util.*;
|
||||
public class BenchmarkQuick {
|
||||
public static void main(String[] args) {
|
||||
int[] sizes = {20, 50, 100, 200, 500};
|
||||
int P = 64;
|
||||
System.out.println("S\tVector(ms)\tHashSet(ms)\tRatio");
|
||||
for (int S : sizes) {
|
||||
long baseAddr = 0x10000000L;
|
||||
List<List<Long>> allPages = new ArrayList<>();
|
||||
for (int i = 0; i < S; i++) {
|
||||
List<Long> pages = new ArrayList<>();
|
||||
for (int p = 0; p < P; p++) pages.add(baseAddr + p);
|
||||
allPages.add(pages);
|
||||
}
|
||||
// Defective
|
||||
long d = 0;
|
||||
for (int r = 0; r < 15; r++) {
|
||||
Map<Long, List<Integer>> vec = new HashMap<>();
|
||||
for (int i = 0; i < S; i++) for (long pg : allPages.get(i)) vec.computeIfAbsent(pg, k->new ArrayList<>()).add(i);
|
||||
long t = System.nanoTime();
|
||||
for (int i = 0; i < S; i++) for (long pg : allPages.get(i)) { List<Integer> s = vec.get(pg); s.remove(Integer.valueOf(i)); }
|
||||
if (r >= 5) d += System.nanoTime() - t;
|
||||
}
|
||||
// Fixed
|
||||
long f = 0;
|
||||
for (int r = 0; r < 15; r++) {
|
||||
Map<Long, Set<Integer>> set = new HashMap<>();
|
||||
for (int i = 0; i < S; i++) for (long pg : allPages.get(i)) set.computeIfAbsent(pg, k->new HashSet<>()).add(i);
|
||||
long t = System.nanoTime();
|
||||
for (int i = 0; i < S; i++) for (long pg : allPages.get(i)) { Set<Integer> s = set.get(pg); s.remove(i); }
|
||||
if (r >= 5) f += System.nanoTime() - t;
|
||||
}
|
||||
System.out.printf("%d\t%.3f\t\t%.3f\t\t%.1f%n", S, d/10.0/1e6, f/10.0/1e6, (double)d/f);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue