diff options
| author | blasty <blasty@local> | 2026-08-07 04:41:42 +0200 |
|---|---|---|
| committer | blasty <blasty@local> | 2026-08-07 04:41:42 +0200 |
| commit | f763c97e4bea39a85b17b7a57b6b7c7923ed4ed6 (patch) | |
| tree | f3fce47f4113598b26d81e6ccaaaf304913e92de | |
| parent | Confirmation re-run of #27, no code change: 17700 -> 17465, the best v5 readi... (diff) | |
| download | ida-tui-f763c97e4bea39a85b17b7a57b6b7c7923ed4ed6.tar.gz ida-tui-f763c97e4bea39a85b17b7a57b6b7c7923ed4ed6.tar.xz ida-tui-f763c97e4bea39a85b17b7a57b6b7c7923ed4ed6.zip | |
bench: cover the split view ('s'), whose decomp_map cost was entirely unmeasured
| -rw-r--r-- | .auto/bench.py | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/.auto/bench.py b/.auto/bench.py index 5d135f7..4074838 100644 --- a/.auto/bench.py +++ b/.auto/bench.py @@ -275,6 +275,53 @@ async def phase_graph(app, pilot, funcs): note("graph_blocks", blocks) +async def phase_split(app, pilot, funcs): + """`s` — listing and pseudocode side by side, cursor-linked. + + The link is driven by ``decomp_map``: for every pseudocode line, the set of + instructions the decompiler attributes to it. That is the whole cost of the + feature and the bench did not cover it at all. + """ + dv = app.query_one(DecompView) + lst = app.query_one(ListingView) + ok = mapped = 0 + spent = 0.0 + for fn in funcs: + app._open_function(fn.addr, fn.name) + if not await _wait(pilot, lambda fn=fn: app._cur is not None + and app._cur.ea == fn.addr and lst.total > 0 + and lst._cursor_ea() == fn.addr, 120): + fail(f"split:open:{fn.name}") + continue + app._active = "listing" + app._show_active() + lst.focus() + await pilot.pause(0.02) + t0 = time.perf_counter() + app.action_toggle_split() + got = await _wait(pilot, lambda fn=fn: app._split and lst.display + and dv.display and dv.loaded_ea == fn.addr, 120) + # The region map is what the split view is FOR; wait for it, not just + # for two panes to appear. + m = app.program.decomp_map(fn.addr) + spent += (time.perf_counter() - t0) * 1000 + if not got: + fail(f"split:{fn.name}") + else: + ok += 1 + mapped += sum(1 for eas in m if eas) + _paint(lst) + _paint(dv) + if app._split: + app.action_toggle_split() + await _wait(pilot, lambda: not app._split, 30) + TIMES.setdefault(PREFIX + "split_ms", []).append(spent) + app._active = "listing" + app._show_active() + note("split_ok", ok) + note("split_mapped_lines", mapped) + + async def phase_search(app, pilot, funcs, terms): """The real incremental-search path: search_begin, then one search_update per typed character, exactly as the Input's on_changed drives it.""" @@ -453,6 +500,7 @@ async def run_target(binary, reps, nfuncs, pages, frames, terms, skip=0): await phase_decomp(app, pilot, big) await phase_graph(app, pilot, big) if first: + await phase_split(app, pilot, big) await phase_search(app, pilot, big, terms) await phase_index(app, pilot, big) await phase_hex(app, pilot, big, frames // 5) |
