re: the trailing data table is a per-phase TIMELINE of scheduled routines

Decodes the table found at the end of every phase region.  Layout:

    int  N
    N x [ int offset ; float t ; int kind ]      -- 8-byte typed records,
                                                    tag 0x19 int, 0x1A float

1 + 3N matches the record count in every phase measured (Stage 02: 76/40/55
records for N = 25/13/18).

Checks, all independent of each other:
  schedule entries disc-wide                675
  0x1A float records disc-wide              675   (counted by a different route)
  offsets landing on the instruction stream 675/675 = 100.0%
  control, random 4-aligned offsets                  33.3%

The floats are seconds -- 0, 0.5, 1, 4, 5, 30, 50, 60, 90, 120, 150, 170, 180, 210,
240, 270, 300, 330, 360, 420, 570, 1020, 1080, 1140, 1170 -- and the targets are small
one-shot coroutines that set arguments, call one built-in and end_coroutine.  kind is
0 (556) or 5 (119) and is not identified.

Runtime cross-check, recorded as consistency rather than confirmation: the closed
REMAINING OB work measured Stage 02's squadron arrivals at t = 0, 120 and 210 s over
n=5 emulator runs, and all three appear in phase 1's static schedule, with 120 and 210
each appearing TWICE.  These are round numbers and phase 1 has ~22 distinct times over
0-1170, so presence alone is not unlikely; the doubling is the sharper detail and was
not predicted in advance.

New artefacts data/isl-stage02-schedule.txt and data/isl-schedule-all.txt with a
committed generator (isl_report.py schedule).  calls, phase-ends, conditions and
phase-guards all regenerate byte-identical.

Not settled and said so: kind is unread; the consumer is unread, so the decode rests
on the structural checks above; whether the clock is per-phase or per-mission is an
inference from the layout; and this is NOT what starts the unreachable code -- 0 of
the 675 targets are unreached run-starts, so that ~15% gap stands.
This commit is contained in:
Sylpheed RE agent
2026-08-27 07:07:35 +00:00
parent 02d3c9c82b
commit 2463748a71
6 changed files with 1236 additions and 2 deletions

View File

@@ -12,6 +12,7 @@ generator in the tree is the point of this file.
isl_report.py <StageNN.ssb> conditions -> every condition site, comparand resolved
isl_report.py <StageNN.ssb> phase-guards -> the NECESSARY conditions for each exit
isl_report.py <dir> phase-guards -> the same for every Stage*.ssb it holds
isl_report.py <StageNN.ssb> schedule -> the phase timeline tables
The "needs the coroutine entry points" blocker recorded here is REFUTED: the
instruction stream is FLAT and `isl.linear_offsets` reaches 25705/25705 call
@@ -169,6 +170,23 @@ def emit_phase_guards(b, path):
print(' %s0x%06X %s %s %s' % (tag, c['off'], lhs, c['rel'], rhs))
def emit_schedule(b, path):
"""The per-phase timeline: what the script launches, and when."""
sch = isl.schedule(b)
print('# %s — phase timelines' % path)
print()
print('Generated by `tools/re-capture/isl_report.py schedule`.')
print()
print('Each phase ends with a table of `(routine offset, time in seconds, kind)`.')
print('%d entries.' % len(sch))
for ph in sorted({p for p, _o, _t, _k in sch}):
rows = [r for r in sch if r[0] == ph]
print()
print('## phase %d — %d scheduled routines' % (ph, len(rows)))
for _p, off, t, k in sorted(rows, key=lambda r: (r[2], r[1])):
print(' t=%-8g kind=%d -> 0x%06X' % (t, k, off))
def main():
# The dominator pass over a large stage is memory-hungry and once OOM-KILLED
# a run on this 15 GB box. Cap the address space so a bad input fails this
@@ -186,14 +204,16 @@ def main():
if i: print(); print('-' * 72); print()
{'calls': emit_calls, 'phase-ends': emit_phase_ends,
'conditions': emit_conditions,
'phase-guards': emit_phase_guards}[sys.argv[2]](
'phase-guards': emit_phase_guards,
'schedule': emit_schedule}[sys.argv[2]](
isl.load(f), os.path.basename(f))
return
b = isl.load(path)
name = path.replace('\\', '/').split('/')[-1]
{'calls': emit_calls, 'phase-ends': emit_phase_ends,
'conditions': emit_conditions,
'phase-guards': emit_phase_guards}[sys.argv[2]](b, name)
'phase-guards': emit_phase_guards,
'schedule': emit_schedule}[sys.argv[2]](b, name)
if __name__ == '__main__':