summaryrefslogtreecommitdiffstats
path: root/server/patch_server.py
diff options
context:
space:
mode:
authoruser <user@clank>2026-08-07 08:32:31 +0200
committeruser <user@clank>2026-08-07 08:32:31 +0200
commit853d90c9866f3996a8ce66ac70f0559ccfad21c5 (patch)
treeb46febfe454fb7ad17da4c7f822ff949d53c1513 /server/patch_server.py
parentThe page-freshness check carries the digest the client already holds (heads(e... (diff)
downloadida-tui-853d90c9866f3996a8ce66ac70f0559ccfad21c5.tar.gz
ida-tui-853d90c9866f3996a8ce66ac70f0559ccfad21c5.tar.xz
ida-tui-853d90c9866f3996a8ce66ac70f0559ccfad21c5.zip
decomp_map: memoise obj_id -> ea for the whole function instead of only comparing against the previous column. dstr() was 79% of the tool (24us a call) and items interleave, so foo(a, b) flips call->arg->call and re-formatted an item already seen: 106594 calls for 15417 lines of bash. Also corrects run #30's claim that the duplicate ida_hexrays.decompile is what costs -- a warm decompile is 0.01ms.
Result: {"status":"keep","total_ms":24513.8,"lg_boot_ms":693.2,"lg_decomp_ms":2347.3,"lg_graph_ms":931.2,"lg_hex_ms":460.3,"lg_index_ms":69.1,"lg_listing_cold_ms":434.2,"lg_listing_warm_ms":462.4,"lg_nav_ms":6639.6,"lg_palette_ms":4.7,"lg_rename_ms":699.9,"lg_render_ms":219.7,"lg_search_ms":3441.1,"lg_split_ms":2218,"pure_graph_ms":216.5,"sm_boot_ms":436.9,"sm_decomp_ms":1264.9,"sm_graph_ms":758.2,"sm_hex_ms":437.9,"sm_index_ms":2.3,"sm_listing_cold_ms":256.8,"sm_listing_warm_ms":256,"sm_nav_ms":309.5,"sm_palette_ms":0.3,"sm_rename_ms":379.1,"sm_render_ms":249.5,"sm_search_ms":59.2,"sm_split_ms":1266,"fails":0}
Diffstat (limited to 'server/patch_server.py')
-rw-r--r--server/patch_server.py42
1 files changed, 28 insertions, 14 deletions
diff --git a/server/patch_server.py b/server/patch_server.py
index e860676..6667e12 100644
--- a/server/patch_server.py
+++ b/server/patch_server.py
@@ -983,13 +983,19 @@ def decomp_map(
# read, so don't ask for them at all.
# * sweep the TAGGED length. ``x`` is a screen column but ``sl.line`` still
# carries IDA's colour tags, so a 23-column line was swept 124 times.
- # * call dstr() per column. It formats a whole 'EA: description' string, and
- # consecutive columns are nearly always the same ctree item -- so ask the
- # item for its id first and only format when it changes. (The result is
- # deduped by ``seen`` anyway, so skipping a repeat cannot change it.)
+ # * call dstr() per column. It formats a whole 'EA: description' string --
+ # 24us a call, which is 79% of this tool. Comparing against the PREVIOUS
+ # column's item id is not enough: items interleave, so `foo(a, b)` flips
+ # call -> arg -> call -> arg and every flip re-formats an item already
+ # seen (106 594 calls for 15 417 lines of bash). Memoise id -> ea for the
+ # whole function instead: obj_id is unique within a cfunc, so the same id
+ # always yields the same string, and the result is deduped by ``seen``
+ # anyway. Items with no ctree node (it is None) have no id to key on and
+ # still pay per occurrence.
item = ida_hexrays.ctree_item_t()
tag_remove = ida_lines.tag_remove
get_line_item = cfunc.get_line_item
+ ea_of_id = {}
lines = []
for sl in cfunc.get_pseudocode():
line = sl.line
@@ -1004,21 +1010,29 @@ def decomp_map(
if oid == prev_id:
continue
prev_id = oid
+ if oid in ea_of_id:
+ e = ea_of_id[oid]
+ if e is not None and e not in seen:
+ seen.add(e)
+ eas.append(hex(e))
+ continue
else:
+ oid = None
prev_id = None
# Match the /*ea*/ marker's source (decompile_function_safe): the
# item's dstr() is 'EA: description'; get_ea() reports a different ea.
+ e = None
dstr = item.dstr()
- if not dstr:
- continue
- parts = dstr.split(": ", 1)
- if len(parts) != 2:
- continue
- try:
- e = int(parts[0], 16)
- except ValueError:
- continue
- if e not in seen:
+ if dstr:
+ parts = dstr.split(": ", 1)
+ if len(parts) == 2:
+ try:
+ e = int(parts[0], 16)
+ except ValueError:
+ e = None
+ if oid is not None:
+ ea_of_id[oid] = e
+ if e is not None and e not in seen:
seen.add(e)
eas.append(hex(e))
lines.append({"ea": eas[0] if eas else None, "eas": eas})