qvm: allocator capacity and registration
Browse files- docs/ASSET_PIPELINE_TODO.md +3 -0
- docs/FINDINGS.md +3 -0
- docs/PROVISIONAL_TODO.md +3 -0
- docs/RESEARCH_LEDGER.md +5 -0
- docs/REVERSE_ENGINEERING_TODO.md +3 -0
- docs/research/QVM_ENTITY_ALLOCATE.md +7 -0
- docs/research/README.md +3 -0
- docs/research/qvm-entity-allocate.json +0 -0
- scripts/analyze_qvm_entity_allocate.py +36 -0
- scripts/test_qvm_entity_allocate.py +17 -0
docs/ASSET_PIPELINE_TODO.md
CHANGED
|
@@ -496,3 +496,6 @@ Research progress: RE-604 [report](research/QVM_ENTITY_INIT.md); remaining nativ
|
|
| 496 |
|
| 497 |
|
| 498 |
Research progress: RE-605 [report](research/QVM_ENTITY_REUSE.md); remaining native/content/runtime/platform scope stays open.
|
|
|
|
|
|
|
|
|
|
|
|
| 496 |
|
| 497 |
|
| 498 |
Research progress: RE-605 [report](research/QVM_ENTITY_REUSE.md); remaining native/content/runtime/platform scope stays open.
|
| 499 |
+
|
| 500 |
+
|
| 501 |
+
Research progress: RE-606 [report](research/QVM_ENTITY_ALLOCATE.md); remaining native/content/runtime/platform scope stays open.
|
docs/FINDINGS.md
CHANGED
|
@@ -854,3 +854,6 @@ Bounded qagame paths recover bomb-plant/inactivity correction requests, direct f
|
|
| 854 |
|
| 855 |
|
| 856 |
**RE-605 — Entity allocator reuse and recent-free guard:** The allocator scans from slot64, skips in-use records and delays recent frees only when freeTime>start+2000 and now−freeTime<1000. [Evidence](research/QVM_ENTITY_REUSE.md).
|
|
|
|
|
|
|
|
|
|
|
|
| 854 |
|
| 855 |
|
| 856 |
**RE-605 — Entity allocator reuse and recent-free guard:** The allocator scans from slot64, skips in-use records and delays recent frees only when freeTime>start+2000 and now−freeTime<1000. [Evidence](research/QVM_ENTITY_REUSE.md).
|
| 857 |
+
|
| 858 |
+
|
| 859 |
+
**RE-606 — Allocator capacity retry and native registration request:** Full-pool retry relaxes the recent-free guard; source count1022 enters diagnostics while1023 may extend to1024. Native−16 publishes entity/client layout. [Evidence](research/QVM_ENTITY_ALLOCATE.md).
|
docs/PROVISIONAL_TODO.md
CHANGED
|
@@ -816,3 +816,6 @@ Research progress: RE-604 [report](research/QVM_ENTITY_INIT.md); remaining nativ
|
|
| 816 |
|
| 817 |
|
| 818 |
Research progress: RE-605 [report](research/QVM_ENTITY_REUSE.md); remaining native/content/runtime/platform scope stays open.
|
|
|
|
|
|
|
|
|
|
|
|
| 816 |
|
| 817 |
|
| 818 |
Research progress: RE-605 [report](research/QVM_ENTITY_REUSE.md); remaining native/content/runtime/platform scope stays open.
|
| 819 |
+
|
| 820 |
+
|
| 821 |
+
Research progress: RE-606 [report](research/QVM_ENTITY_ALLOCATE.md); remaining native/content/runtime/platform scope stays open.
|
docs/RESEARCH_LEDGER.md
CHANGED
|
@@ -712,3 +712,8 @@ RE-602 additional regression:19 related reports from RE-582–591 and RE-593–6
|
|
| 712 |
## 2026-10-20 — RE-605 Entity allocator reuse and recent-free guard (separate task commit)
|
| 713 |
|
| 714 |
The allocator scans from slot64, skips in-use records and delays recent frees only when freeTime>start+2000 and now−freeTime<1000. Nineteen fixtures independently check first-fit order, strict timing boundaries, retained canaries and actual initializer calls. Full suite: 925 tests pass. Report regenerates byte-identically (574361 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 712 |
## 2026-10-20 — RE-605 Entity allocator reuse and recent-free guard (separate task commit)
|
| 713 |
|
| 714 |
The allocator scans from slot64, skips in-use records and delays recent frees only when freeTime>start+2000 and now−freeTime<1000. Nineteen fixtures independently check first-fit order, strict timing boundaries, retained canaries and actual initializer calls. Full suite: 925 tests pass. Report regenerates byte-identically (574361 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
|
| 715 |
+
|
| 716 |
+
|
| 717 |
+
## 2026-10-20 — RE-606 Allocator capacity retry and native registration request (separate task commit)
|
| 718 |
+
|
| 719 |
+
Full-pool retry relaxes the recent-free guard; source count1022 enters diagnostics while1023 may extend to1024. Native−16 publishes entity/client layout. Seven allocator fixtures cover reuse, extension, retry and both source error boundaries with independent expected slots/counts/ABI. Full suite: 929 tests pass. Report regenerates byte-identically (102931 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
|
docs/REVERSE_ENGINEERING_TODO.md
CHANGED
|
@@ -859,3 +859,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
|
|
| 859 |
|
| 860 |
|
| 861 |
- [x] RE-605 Entity allocator reuse and recent-free guard ([report](research/QVM_ENTITY_REUSE.md)).
|
|
|
|
|
|
|
|
|
|
|
|
| 859 |
|
| 860 |
|
| 861 |
- [x] RE-605 Entity allocator reuse and recent-free guard ([report](research/QVM_ENTITY_REUSE.md)).
|
| 862 |
+
|
| 863 |
+
|
| 864 |
+
- [x] RE-606 Allocator capacity retry and native registration request ([report](research/QVM_ENTITY_ALLOCATE.md)).
|
docs/research/QVM_ENTITY_ALLOCATE.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Allocator capacity retry and native registration request
|
| 2 |
+
|
| 3 |
+
RE-606. Reproduce with `python3 scripts/analyze_qvm_entity_allocate.py`; check with `python3 scripts/test_qvm_entity_allocate.py`. The [machine report](qvm-entity-allocate.json) retains source identity and bounded fixtures.
|
| 4 |
+
|
| 5 |
+
The bounded driver interprets actual277166–277344, dispatches actual277125 and captures native−16 without engine effects. It allows enough instructions for two scans of960 slots and rejects unexpected calls. Exhaustion at index1024 increments retry and repeats once; pass1 ignores the recent-free delay. All-in-use count1024 increments count to1025 and stops before fatal2319. Exhaustion at1022 instead stops before the1024-entry2294 diagnostic loop. These asymmetric literal limits are evidence, not corrected assumptions. Count1023 can extend to1024, request−16(pool,count,880,clientBase,6336), initialize and return the final legal slot. No clearing occurs. The unusual1022 diagnostic path and whether2319 ever returns require native/reference confirmation. Reports omit enormous pool dumps but retain complete selected records and trace hashes.
|
| 6 |
+
|
| 7 |
+
No original executable/full QVM/native collision/physics/rendering executes. Native responses and legal input domains are supplied or unverified where stated; full runtime/macOS/Linux Rust/Bevy/Solari gameplay remains open.
|
docs/research/README.md
CHANGED
|
@@ -417,3 +417,6 @@ The extension collector adds five focused tests for native tail calls, command-r
|
|
| 417 |
|
| 418 |
|
| 419 |
[RE-605: Entity allocator reuse and recent-free guard](QVM_ENTITY_REUSE.md). Reproduce with `python3 scripts/analyze_qvm_entity_reuse.py`; check with `python3 scripts/test_qvm_entity_reuse.py`.
|
|
|
|
|
|
|
|
|
|
|
|
| 417 |
|
| 418 |
|
| 419 |
[RE-605: Entity allocator reuse and recent-free guard](QVM_ENTITY_REUSE.md). Reproduce with `python3 scripts/analyze_qvm_entity_reuse.py`; check with `python3 scripts/test_qvm_entity_reuse.py`.
|
| 420 |
+
|
| 421 |
+
|
| 422 |
+
[RE-606: Allocator capacity retry and native registration request](QVM_ENTITY_ALLOCATE.md). Reproduce with `python3 scripts/analyze_qvm_entity_allocate.py`; check with `python3 scripts/test_qvm_entity_allocate.py`.
|
docs/research/qvm-entity-allocate.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
scripts/analyze_qvm_entity_allocate.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""Bounded allocator with actual scan, retry and initializer; capture native−16."""
|
| 3 |
+
from pathlib import Path
|
| 4 |
+
from analyze_deferred_auth import trace_slice
|
| 5 |
+
from analyze_bsp_references import trace_fields
|
| 6 |
+
from qvm_research_support import source
|
| 7 |
+
from analyze_qvm_entity_init import initialize,POOL,STRIDE
|
| 8 |
+
from analyze_qvm_entity_reuse import fixture
|
| 9 |
+
from analyze_qvm_temp_event import record
|
| 10 |
+
from analyze_qvm import write_json
|
| 11 |
+
LOCAL=0x79200000
|
| 12 |
+
|
| 13 |
+
def allocate(ins,m):
|
| 14 |
+
m=dict(m);count=m[34992508];pc=277166;trace=[];calls=[];children=[];registrations=[];ret=None;boundaries=[277269,277315];points=[277224,277285,277300,277320,277336,277342]+boundaries
|
| 15 |
+
for _ in range(8):
|
| 16 |
+
t=trace_slice(ins,277166,277346,m,{},resume_at=pc,stop_targets=[p for p in points if p!=pc],local_base=LOCAL,halt_on_leave=True,capture_stack=True,limit=131072)
|
| 17 |
+
m=t['memory'];trace+=t['trace'];calls+=t['calls'];pc=t['stop']
|
| 18 |
+
for c in t['calls']:
|
| 19 |
+
if c['target']==277125:m,r=initialize(ins,m,c['args'][8]);children.append(r)
|
| 20 |
+
elif c['target']==-16:registrations.append({'arguments':c['args'],'native_effect_not_executed':True})
|
| 21 |
+
else:raise ValueError('Unrecovered allocator child '+str(c['target']))
|
| 22 |
+
if trace and ins[trace[-1]]['opcode']=='LEAVE':ret=t['stack'][-1];break
|
| 23 |
+
if pc in boundaries:break
|
| 24 |
+
else:raise ValueError('Allocator call bound')
|
| 25 |
+
return m,{'initial_count':count,'count':m[34992508],'selected':ret,'retry':m[LOCAL+36],'scan_index':m[LOCAL+32],'status':'returned' if ret is not None else ('diagnostic-loop-pending' if pc==277269 else 'fatal-error-pending'),'execution':{'calls':calls,**trace_fields({'trace':trace},False)},'initializers':children,'registrations':registrations,'record':record(m,ret) if ret is not None else None}
|
| 26 |
+
|
| 27 |
+
def main():
|
| 28 |
+
q,raw,h,ins=source();rows=[]
|
| 29 |
+
cases=[('first-extension',fixture(64)),('reuse',fixture(slots=[(64,0,0)])),('recent-extends',fixture(slots=[(64,0,4999)])),('diagnostic-1022',fixture(1022)),('last-legal-extension',fixture(1023)),('full-in-use',fixture(1024)),('full-recent-retry',fixture(1024,slots=[(65,0,4999)]))]
|
| 30 |
+
for label,m in cases:
|
| 31 |
+
p=POOL+m[34992508]*STRIDE
|
| 32 |
+
for o in range(0,STRIDE,4):m.setdefault(p+o,0x12345678)
|
| 33 |
+
_,r=allocate(ins,m);r['label']=label;rows.append(r)
|
| 34 |
+
strings={str(a):raw[h['data_offset']+a:].split(b'\0',1)[0].decode() for a in [97208,97234]}
|
| 35 |
+
write_json(Path('docs/research/qvm-entity-allocate.json'),{'source':q['source'],'sha256':q['sha256'],'strings':strings,'probes':rows,'limits':'Actual allocator scan/retry/count/initializer. Native−16 request captured, no engine registration. Stops before2294 diagnostic loop and2319 fatal call; source1022/1024 distinction preserved.'})
|
| 36 |
+
if __name__=='__main__':main()
|
scripts/test_qvm_entity_allocate.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json,unittest
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
class EntityAllocateTests(unittest.TestCase):
|
| 4 |
+
@classmethod
|
| 5 |
+
def setUpClass(cls):cls.r=json.loads(Path('docs/research/qvm-entity-allocate.json').read_text());cls.p={p['label']:p for p in cls.r['probes']}
|
| 6 |
+
def test_first_fit_and_extensions(self):
|
| 7 |
+
for label,index,count in [('first-extension',64,65),('reuse',64,66),('recent-extends',66,67),('last-legal-extension',1023,1024),('full-recent-retry',65,1024)]:
|
| 8 |
+
p=self.p[label];self.assertEqual(p['selected'],34091368+880*index);self.assertEqual(p['count'],count);self.assertEqual(p['record']['0'],index);self.assertEqual(p['record']['520'],0x12345678)
|
| 9 |
+
def test_source_capacity_asymmetry(self):
|
| 10 |
+
p=self.p['diagnostic-1022'];self.assertEqual(p['status'],'diagnostic-loop-pending');self.assertEqual(p['count'],1022);self.assertEqual(p['execution']['calls'],[])
|
| 11 |
+
p=self.p['full-in-use'];self.assertEqual(p['status'],'fatal-error-pending');self.assertEqual(p['count'],1025);self.assertEqual(p['retry'],2);self.assertEqual(p['registrations'],[])
|
| 12 |
+
def test_retry_releases_recent_free_guard(self):
|
| 13 |
+
p=self.p['full-recent-retry'];self.assertEqual(p['retry'],1);self.assertEqual(p['scan_index'],65);self.assertEqual(p['registrations'],[])
|
| 14 |
+
def test_native_registration_abi_and_order(self):
|
| 15 |
+
for label in ['first-extension','recent-extends','last-legal-extension']:
|
| 16 |
+
p=self.p[label];self.assertEqual([c['target'] for c in p['execution']['calls']],[-16,277125]);self.assertEqual(p['registrations'],[{'arguments':{'8':34091368,'12':p['count'],'16':880,'20':65536,'24':6336},'native_effect_not_executed':True}])
|
| 17 |
+
if __name__=='__main__':unittest.main()
|