summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authoruser <user@clank>2026-08-07 02:07:28 +0200
committeruser <user@clank>2026-08-07 02:07:28 +0200
commit8b40fd299827d3685499392cce27d20451e94211 (patch)
tree21569e9881909f9660ecb1538ce291906d388095 /server
parentIncremental search narrows instead of rescanning. Typing a character onto the... (diff)
downloadida-tui-8b40fd299827d3685499392cce27d20451e94211.tar.gz
ida-tui-8b40fd299827d3685499392cce27d20451e94211.tar.xz
ida-tui-8b40fd299827d3685499392cce27d20451e94211.zip
Three micro-wins on the listing-row path: merge the colour-tag and operand-tag dicts into one lookup, skip both isspace() probes when a span needs no whitespace collapsing at all (the common case), and give Head slots=True. Spans 11.07 -> 10.18 us/line; Head construction 3.18 -> 2.53 us/row.
Result: {"status":"keep","total_ms":20412.8,"lg_boot_ms":752.9,"lg_decomp_ms":2418.6,"lg_graph_ms":811.6,"lg_hex_ms":1020.1,"lg_index_ms":73.2,"lg_listing_cold_ms":573.7,"lg_listing_warm_ms":456.7,"lg_nav_ms":6640.1,"lg_palette_ms":4.8,"lg_render_ms":237.6,"lg_search_ms":3210.2,"pure_graph_ms":242.5,"sm_boot_ms":536.5,"sm_decomp_ms":643.1,"sm_graph_ms":689.8,"sm_hex_ms":866.6,"sm_index_ms":0,"sm_listing_cold_ms":262.9,"sm_listing_warm_ms":265.9,"sm_nav_ms":330.1,"sm_palette_ms":0.3,"sm_render_ms":265.2,"sm_search_ms":110.5,"fails":0}
Diffstat (limited to 'server')
-rw-r--r--server/patch_server.py22
1 files changed, 18 insertions, 4 deletions
diff --git a/server/patch_server.py b/server/patch_server.py
index a1ec1ef..fe16ede 100644
--- a/server/patch_server.py
+++ b/server/patch_server.py
@@ -391,6 +391,10 @@ def _idatui_tag_map():
_IDATUI_TAGS = None
_IDATUI_OPND_TAGS = None
_IDATUI_CTL = None # re: a tag = one of three control chars plus its argument
+#: {tag character: (kind, operand index or None)} -- the two maps above merged,
+#: because the span walker wants both for the same tag and a dict lookup per
+#: tag per line is one of the few things it does often enough to matter.
+_IDATUI_TAGINFO = None
def _idatui_opnd_tag_map():
@@ -420,7 +424,7 @@ def _idatui_spans(line):
Unknown tags become 'text' rather than being dropped: a processor module can
emit a colour we don't classify, and losing the characters would corrupt the
line."""
- global _IDATUI_TAGS, _IDATUI_OPND_TAGS, _IDATUI_CTL
+ global _IDATUI_TAGS, _IDATUI_OPND_TAGS, _IDATUI_CTL, _IDATUI_TAGINFO
import ida_lines
if _IDATUI_TAGS is None:
_IDATUI_TAGS = _idatui_tag_map()
@@ -434,7 +438,12 @@ def _idatui_spans(line):
# characters but only ~13 tags -- everything between two tags is already
# exactly one span's worth of text.
_IDATUI_CTL = _re.compile("([\\x01\\x02\\x03](?s:.))")
- tags, opnds = _IDATUI_TAGS, _IDATUI_OPND_TAGS
+ if _IDATUI_TAGINFO is None:
+ _IDATUI_TAGINFO = {
+ tag: (_IDATUI_TAGS.get(tag, "text"), _IDATUI_OPND_TAGS.get(tag))
+ for tag in set(_IDATUI_TAGS) | set(_IDATUI_OPND_TAGS)}
+ taginfo = _IDATUI_TAGINFO
+ plain_tag = ("text", None)
on, off, esc = "\x01", "\x02", "\x03"
addr_tag = chr(getattr(ida_lines, "COLOR_ADDR", 0x28))
addr_len = int(getattr(ida_lines, "COLOR_ADDR_SIZE", 16))
@@ -478,8 +487,7 @@ def _idatui_spans(line):
pend = ""
if ch == on:
stack.append((kind, opnd))
- kind = tags.get(tag, "text")
- o = opnds.get(tag)
+ kind, o = taginfo.get(tag, plain_tag)
if o is not None:
opnd = o # operands nest: an inner colour keeps the operand
elif stack:
@@ -497,6 +505,12 @@ def _idatui_spans(line):
out, prev_space = [], False
for kind, txt, opnd in spans:
core = " ".join(txt.split())
+ if core == txt:
+ # Nothing to collapse and no edge whitespace -- which is the common
+ # case ("mov", "rax", ", ") and skips both isspace() probes below.
+ prev_space = False
+ out.append([kind, txt, opnd])
+ continue
if not core: # the span is nothing but padding
if not prev_space:
prev_space = True