FA-90526 / Garbage collector invariants / Open access
Card marking: cards rebuilt only for newly promoted objects · case 01
Old-to-young references recorded before a minor collection are forgotten afterwards.
ROOT CAUSE
After clearing the card table, only promoted objects are rescanned for young references.
VERIFIED REPAIR
Rebuild cards from every old object that still points at a young one.
Unsuccessful approach: Skipping promoted objects forgets references from freshly tenured objects to younger ones.
Case contract
Two generations. objs maps id -> [generation, address, fields]; a field slot i of an old object lives at address + 8*i and belongs to card (slot address // 64). store writes a field and, when an old object receives a young reference, dirties that slot's card. minor: roots plus young referents of old slots in dirty cards seed a trace through young objects; unreached young objects are freed; survivors age by one and are promoted (addresses from 4096 in 64-byte steps) when age >= tenure; the card set is then rebuilt from every old slot that still references a young object. alloc id creates a young object with one null field; root/unroot edit the root list. Return per-minor {freed, promoted, cards}; following a freed object reports {"dangling": id}.
Why this case matters
Minor collections are only correct if the remembered set covers every old-to-young pointer.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(objs, roots, events, tenure):
objs = {k: {'gen': v[0], 'addr': v[1], 'fields': list(v[2]), 'age': 0} for k, v in objs.items()}
roots = list(roots)
cards = set()
log = []
next_addr = 4096
def slot_card(o, i):
return (objs[o]['addr'] + 8 * i) // 64
try:
for ev in events:
if ev[0] == 'store':
_, src, i, dst = ev
objs[src]['fields'][i] = dst
if objs[src]['gen'] == 'old' and dst is not None and objs[dst]['gen'] == 'young':
cards.add(slot_card(src, i))
elif ev[0] == 'alloc':
objs[ev[1]] = {'gen': 'young', 'addr': 0, 'fields': [None], 'age': 0}
elif ev[0] == 'root':
roots.append(ev[1])
elif ev[0] == 'unroot':
roots.remove(ev[1])
else:
grey = [r for r in roots if objs[r]['gen'] == 'young']
for o, ob in objs.items():
if ob['gen'] == 'old':
for i, f in enumerate(ob['fields']):
if slot_card(o, i) in cards and f is not None and objs[f]['gen'] == 'young':
grey.append(f)
live = set()
while grey:
y = grey.pop()
if y in live:
continue
live.add(y)
for f in objs[y]['fields']:
if f is not None and objs[f]['gen'] == 'young':
grey.append(f)
dead = sorted(k for k, ob in objs.items() if ob['gen'] == 'young' and k not in live)
for k in dead:
del objs[k]
promoted = []
for k in sorted(live):
objs[k]['age'] += 1
if objs[k]['age'] >= tenure:
objs[k]['gen'] = 'old'
objs[k]['addr'] = next_addr
next_addr += 64
promoted.append(k)
cards = set()
for o in promoted:
for i, f in enumerate(objs[o]['fields']):
if f is not None and objs[f]['gen'] == 'young':
cards.add(slot_card(o, i))
log.append({'freed': dead, 'promoted': promoted, 'cards': sorted(cards)})
except KeyError as e:
log.append({'dangling': e.args[0]})
return log
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression: old-to-young edge survives two minor collections',
({1: ['old', 56, [None, None]],
2: ['old', 192, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[],
[['store', 1, 1, 11], ['minor'], ['minor']],
5),
[{'cards': [1], 'freed': [13, 14], 'promoted': []}, {'cards': [1], 'freed': [], 'promoted': []}]),
('edge stored after the target survived once',
({1: ['old', 56, [None, None]],
2: ['old', 192, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[13],
[['minor'], ['store', 2, 0, 13], ['unroot', 13], ['minor']],
5),
[{'cards': [], 'freed': [11, 12, 14], 'promoted': []}, {'cards': [3], 'freed': [], 'promoted': []}]),
('promotion at the tenuring threshold',
({1: ['old', 56, [None, None]],
2: ['old', 192, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[11],
[['minor'], ['minor'], ['minor']],
2),
[{'cards': [], 'freed': [13, 14], 'promoted': []},
{'cards': [], 'freed': [], 'promoted': [11, 12]},
{'cards': [], 'freed': [], 'promoted': []}]),
('promoted object pointing at a younger object',
({1: ['old', 56, [None, None]],
2: ['old', 192, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[11],
[['minor'], ['alloc', 15], ['store', 11, 0, 15], ['minor'], ['minor']],
2),
[{'cards': [], 'freed': [13, 14], 'promoted': []},
{'cards': [64], 'freed': [12], 'promoted': [11]},
{'cards': [], 'freed': [], 'promoted': [15]}]),
('card of a slot in the next card',
({1: ['old', 56, [None, None]],
2: ['old', 192, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[],
[['store', 1, 0, 13], ['store', 1, 1, 14], ['minor']],
4),
[{'cards': [0, 1], 'freed': [11, 12], 'promoted': []}]),
('control: unreferenced young objects die',
({1: ['old', 56, [None, None]],
2: ['old', 192, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[12],
[['minor']],
3),
[{'cards': [], 'freed': [11, 13, 14], 'promoted': []}])],
[('regression: old-to-young edge survives two minor collections',
({1: ['old', 120, [None, None]],
2: ['old', 256, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[],
[['store', 1, 1, 11], ['minor'], ['minor']],
5),
[{'cards': [2], 'freed': [13, 14], 'promoted': []}, {'cards': [2], 'freed': [], 'promoted': []}]),
('edge stored after the target survived once',
({1: ['old', 120, [None, None]],
2: ['old', 256, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[13],
[['minor'], ['store', 2, 0, 13], ['unroot', 13], ['minor']],
5),
[{'cards': [], 'freed': [11, 12, 14], 'promoted': []}, {'cards': [4], 'freed': [], 'promoted': []}]),
('promotion at the tenuring threshold',
({1: ['old', 120, [None, None]],
2: ['old', 256, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[11],
[['minor'], ['minor'], ['minor']],
2),
[{'cards': [], 'freed': [13, 14], 'promoted': []},
{'cards': [], 'freed': [], 'promoted': [11, 12]},
{'cards': [], 'freed': [], 'promoted': []}]),
('promoted object pointing at a younger object',
({1: ['old', 120, [None, None]],
2: ['old', 256, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[11],
[['minor'], ['alloc', 15], ['store', 11, 0, 15], ['minor'], ['minor']],
2),
[{'cards': [], 'freed': [13, 14], 'promoted': []},
{'cards': [64], 'freed': [12], 'promoted': [11]},
{'cards': [], 'freed': [], 'promoted': [15]}]),
('card of a slot in the next card',
({1: ['old', 120, [None, None]],
2: ['old', 256, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[],
[['store', 1, 0, 13], ['store', 1, 1, 14], ['minor']],
4),
[{'cards': [1, 2], 'freed': [11, 12], 'promoted': []}]),
('control: unreferenced young objects die',
({1: ['old', 120, [None, None]],
2: ['old', 256, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[12],
[['minor']],
3),
[{'cards': [], 'freed': [11, 13, 14], 'promoted': []}])],
[('regression: old-to-young edge survives two minor collections',
({1: ['old', 184, [None, None]],
2: ['old', 320, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[],
[['store', 1, 1, 11], ['minor'], ['minor']],
5),
[{'cards': [3], 'freed': [13, 14], 'promoted': []}, {'cards': [3], 'freed': [], 'promoted': []}]),
('edge stored after the target survived once',
({1: ['old', 184, [None, None]],
2: ['old', 320, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[13],
[['minor'], ['store', 2, 0, 13], ['unroot', 13], ['minor']],
5),
[{'cards': [], 'freed': [11, 12, 14], 'promoted': []}, {'cards': [5], 'freed': [], 'promoted': []}]),
('promotion at the tenuring threshold',
({1: ['old', 184, [None, None]],
2: ['old', 320, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[11],
[['minor'], ['minor'], ['minor']],
2),
[{'cards': [], 'freed': [13, 14], 'promoted': []},
{'cards': [], 'freed': [], 'promoted': [11, 12]},
{'cards': [], 'freed': [], 'promoted': []}]),
('promoted object pointing at a younger object',
({1: ['old', 184, [None, None]],
2: ['old', 320, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[11],
[['minor'], ['alloc', 15], ['store', 11, 0, 15], ['minor'], ['minor']],
2),
[{'cards': [], 'freed': [13, 14], 'promoted': []},
{'cards': [64], 'freed': [12], 'promoted': [11]},
{'cards': [], 'freed': [], 'promoted': [15]}]),
('card of a slot in the next card',
({1: ['old', 184, [None, None]],
2: ['old', 320, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[],
[['store', 1, 0, 13], ['store', 1, 1, 14], ['minor']],
4),
[{'cards': [2, 3], 'freed': [11, 12], 'promoted': []}]),
('control: unreferenced young objects die',
({1: ['old', 184, [None, None]],
2: ['old', 320, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[12],
[['minor']],
3),
[{'cards': [], 'freed': [11, 13, 14], 'promoted': []}])],
[('regression: old-to-young edge survives two minor collections',
({1: ['old', 248, [None, None]],
2: ['old', 384, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[],
[['store', 1, 1, 11], ['minor'], ['minor']],
5),
[{'cards': [4], 'freed': [13, 14], 'promoted': []}, {'cards': [4], 'freed': [], 'promoted': []}]),
('edge stored after the target survived once',
({1: ['old', 248, [None, None]],
2: ['old', 384, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[13],
[['minor'], ['store', 2, 0, 13], ['unroot', 13], ['minor']],
5),
[{'cards': [], 'freed': [11, 12, 14], 'promoted': []}, {'cards': [6], 'freed': [], 'promoted': []}]),
('promotion at the tenuring threshold',
({1: ['old', 248, [None, None]],
2: ['old', 384, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[11],
[['minor'], ['minor'], ['minor']],
2),
[{'cards': [], 'freed': [13, 14], 'promoted': []},
{'cards': [], 'freed': [], 'promoted': [11, 12]},
{'cards': [], 'freed': [], 'promoted': []}]),
('promoted object pointing at a younger object',
({1: ['old', 248, [None, None]],
2: ['old', 384, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[11],
[['minor'], ['alloc', 15], ['store', 11, 0, 15], ['minor'], ['minor']],
2),
[{'cards': [], 'freed': [13, 14], 'promoted': []},
{'cards': [64], 'freed': [12], 'promoted': [11]},
{'cards': [], 'freed': [], 'promoted': [15]}]),
('card of a slot in the next card',
({1: ['old', 248, [None, None]],
2: ['old', 384, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[],
[['store', 1, 0, 13], ['store', 1, 1, 14], ['minor']],
4),
[{'cards': [3, 4], 'freed': [11, 12], 'promoted': []}]),
('control: unreferenced young objects die',
({1: ['old', 248, [None, None]],
2: ['old', 384, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[12],
[['minor']],
3),
[{'cards': [], 'freed': [11, 13, 14], 'promoted': []}])],
[('regression: old-to-young edge survives two minor collections',
({1: ['old', 312, [None, None]],
2: ['old', 448, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[],
[['store', 1, 1, 11], ['minor'], ['minor']],
5),
[{'cards': [5], 'freed': [13, 14], 'promoted': []}, {'cards': [5], 'freed': [], 'promoted': []}]),
('edge stored after the target survived once',
({1: ['old', 312, [None, None]],
2: ['old', 448, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[13],
[['minor'], ['store', 2, 0, 13], ['unroot', 13], ['minor']],
5),
[{'cards': [], 'freed': [11, 12, 14], 'promoted': []}, {'cards': [7], 'freed': [], 'promoted': []}]),
('promotion at the tenuring threshold',
({1: ['old', 312, [None, None]],
2: ['old', 448, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[11],
[['minor'], ['minor'], ['minor']],
2),
[{'cards': [], 'freed': [13, 14], 'promoted': []},
{'cards': [], 'freed': [], 'promoted': [11, 12]},
{'cards': [], 'freed': [], 'promoted': []}]),
('promoted object pointing at a younger object',
({1: ['old', 312, [None, None]],
2: ['old', 448, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[11],
[['minor'], ['alloc', 15], ['store', 11, 0, 15], ['minor'], ['minor']],
2),
[{'cards': [], 'freed': [13, 14], 'promoted': []},
{'cards': [64], 'freed': [12], 'promoted': [11]},
{'cards': [], 'freed': [], 'promoted': [15]}]),
('card of a slot in the next card',
({1: ['old', 312, [None, None]],
2: ['old', 448, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[],
[['store', 1, 0, 13], ['store', 1, 1, 14], ['minor']],
4),
[{'cards': [4, 5], 'freed': [11, 12], 'promoted': []}]),
('control: unreferenced young objects die',
({1: ['old', 312, [None, None]],
2: ['old', 448, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[12],
[['minor']],
3),
[{'cards': [], 'freed': [11, 13, 14], 'promoted': []}])]]
for label, args, expected in cases[N - 1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: old-to-young edge survives two minor collections | [{'cards': [], 'freed': [13, 14], 'promoted': []}, {'cards': [], 'freed': [11, 12], 'promoted': []}] | [{'cards': [1], 'freed': [13, 14], 'promoted': []}, {'cards': [1], 'freed': [], 'promoted': []}] | Failed |
| edge stored after the target survived once | [{'cards': [], 'freed': [11, 12, 14], 'promoted': []}, {'cards': [], 'freed': [], 'promoted': []}] | [{'cards': [], 'freed': [11, 12, 14], 'promoted': []}, {'cards': [3], 'freed': [], 'promoted': []}] | Failed |
| promotion at the tenuring threshold | [{'cards': [], 'freed': [13, 14], 'promoted': []}, {'cards': [], 'freed': [], 'promoted': [11, 12]}, {'cards': [], 'freed': [], 'promoted': []}] | [{'cards': [], 'freed': [13, 14], 'promoted': []}, {'cards': [], 'freed': [], 'promoted': [11, 12]}, {'cards': [], 'freed': [], 'promoted': []}] | Passed |
| promoted object pointing at a younger object | [{'cards': [], 'freed': [13, 14], 'promoted': []}, {'cards': [64], 'freed': [12], 'promoted': [11]}, {'cards': [], 'freed': [], 'promoted': [15]}] | [{'cards': [], 'freed': [13, 14], 'promoted': []}, {'cards': [64], 'freed': [12], 'promoted': [11]}, {'cards': [], 'freed': [], 'promoted': [15]}] | Passed |
| card of a slot in the next card | [{'cards': [], 'freed': [11, 12], 'promoted': []}] | [{'cards': [0, 1], 'freed': [11, 12], 'promoted': []}] | Failed |
| control: unreferenced young objects die | [{'cards': [], 'freed': [11, 13, 14], 'promoted': []}] | [{'cards': [], 'freed': [11, 13, 14], 'promoted': []}] | Passed |
SHA-256 / 14ff3fdfa02517480bf0235b56b73f473e1a2456bd084e34f9a007855d8139c6
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(objs, roots, events, tenure):
objs = {k: {'gen': v[0], 'addr': v[1], 'fields': list(v[2]), 'age': 0} for k, v in objs.items()}
roots = list(roots)
cards = set()
log = []
next_addr = 4096
def slot_card(o, i):
return (objs[o]['addr'] + 8 * i) // 64
try:
for ev in events:
if ev[0] == 'store':
_, src, i, dst = ev
objs[src]['fields'][i] = dst
if objs[src]['gen'] == 'old' and dst is not None and objs[dst]['gen'] == 'young':
cards.add(slot_card(src, i))
elif ev[0] == 'alloc':
objs[ev[1]] = {'gen': 'young', 'addr': 0, 'fields': [None], 'age': 0}
elif ev[0] == 'root':
roots.append(ev[1])
elif ev[0] == 'unroot':
roots.remove(ev[1])
else:
grey = [r for r in roots if objs[r]['gen'] == 'young']
for o, ob in objs.items():
if ob['gen'] == 'old':
for i, f in enumerate(ob['fields']):
if slot_card(o, i) in cards and f is not None and objs[f]['gen'] == 'young':
grey.append(f)
live = set()
while grey:
y = grey.pop()
if y in live:
continue
live.add(y)
for f in objs[y]['fields']:
if f is not None and objs[f]['gen'] == 'young':
grey.append(f)
dead = sorted(k for k, ob in objs.items() if ob['gen'] == 'young' and k not in live)
for k in dead:
del objs[k]
promoted = []
for k in sorted(live):
objs[k]['age'] += 1
if objs[k]['age'] >= tenure:
objs[k]['gen'] = 'old'
objs[k]['addr'] = next_addr
next_addr += 64
promoted.append(k)
cards = set()
for o in [k for k, ob in objs.items() if ob['gen'] == 'old' and k not in promoted]:
for i, f in enumerate(objs[o]['fields']):
if f is not None and objs[f]['gen'] == 'young':
cards.add(slot_card(o, i))
log.append({'freed': dead, 'promoted': promoted, 'cards': sorted(cards)})
except KeyError as e:
log.append({'dangling': e.args[0]})
return log
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression: old-to-young edge survives two minor collections',
({1: ['old', 56, [None, None]],
2: ['old', 192, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[],
[['store', 1, 1, 11], ['minor'], ['minor']],
5),
[{'cards': [1], 'freed': [13, 14], 'promoted': []}, {'cards': [1], 'freed': [], 'promoted': []}]),
('edge stored after the target survived once',
({1: ['old', 56, [None, None]],
2: ['old', 192, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[13],
[['minor'], ['store', 2, 0, 13], ['unroot', 13], ['minor']],
5),
[{'cards': [], 'freed': [11, 12, 14], 'promoted': []}, {'cards': [3], 'freed': [], 'promoted': []}]),
('promotion at the tenuring threshold',
({1: ['old', 56, [None, None]],
2: ['old', 192, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[11],
[['minor'], ['minor'], ['minor']],
2),
[{'cards': [], 'freed': [13, 14], 'promoted': []},
{'cards': [], 'freed': [], 'promoted': [11, 12]},
{'cards': [], 'freed': [], 'promoted': []}]),
('promoted object pointing at a younger object',
({1: ['old', 56, [None, None]],
2: ['old', 192, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[11],
[['minor'], ['alloc', 15], ['store', 11, 0, 15], ['minor'], ['minor']],
2),
[{'cards': [], 'freed': [13, 14], 'promoted': []},
{'cards': [64], 'freed': [12], 'promoted': [11]},
{'cards': [], 'freed': [], 'promoted': [15]}]),
('card of a slot in the next card',
({1: ['old', 56, [None, None]],
2: ['old', 192, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[],
[['store', 1, 0, 13], ['store', 1, 1, 14], ['minor']],
4),
[{'cards': [0, 1], 'freed': [11, 12], 'promoted': []}]),
('control: unreferenced young objects die',
({1: ['old', 56, [None, None]],
2: ['old', 192, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[12],
[['minor']],
3),
[{'cards': [], 'freed': [11, 13, 14], 'promoted': []}])],
[('regression: old-to-young edge survives two minor collections',
({1: ['old', 120, [None, None]],
2: ['old', 256, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[],
[['store', 1, 1, 11], ['minor'], ['minor']],
5),
[{'cards': [2], 'freed': [13, 14], 'promoted': []}, {'cards': [2], 'freed': [], 'promoted': []}]),
('edge stored after the target survived once',
({1: ['old', 120, [None, None]],
2: ['old', 256, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[13],
[['minor'], ['store', 2, 0, 13], ['unroot', 13], ['minor']],
5),
[{'cards': [], 'freed': [11, 12, 14], 'promoted': []}, {'cards': [4], 'freed': [], 'promoted': []}]),
('promotion at the tenuring threshold',
({1: ['old', 120, [None, None]],
2: ['old', 256, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[11],
[['minor'], ['minor'], ['minor']],
2),
[{'cards': [], 'freed': [13, 14], 'promoted': []},
{'cards': [], 'freed': [], 'promoted': [11, 12]},
{'cards': [], 'freed': [], 'promoted': []}]),
('promoted object pointing at a younger object',
({1: ['old', 120, [None, None]],
2: ['old', 256, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[11],
[['minor'], ['alloc', 15], ['store', 11, 0, 15], ['minor'], ['minor']],
2),
[{'cards': [], 'freed': [13, 14], 'promoted': []},
{'cards': [64], 'freed': [12], 'promoted': [11]},
{'cards': [], 'freed': [], 'promoted': [15]}]),
('card of a slot in the next card',
({1: ['old', 120, [None, None]],
2: ['old', 256, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[],
[['store', 1, 0, 13], ['store', 1, 1, 14], ['minor']],
4),
[{'cards': [1, 2], 'freed': [11, 12], 'promoted': []}]),
('control: unreferenced young objects die',
({1: ['old', 120, [None, None]],
2: ['old', 256, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[12],
[['minor']],
3),
[{'cards': [], 'freed': [11, 13, 14], 'promoted': []}])],
[('regression: old-to-young edge survives two minor collections',
({1: ['old', 184, [None, None]],
2: ['old', 320, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[],
[['store', 1, 1, 11], ['minor'], ['minor']],
5),
[{'cards': [3], 'freed': [13, 14], 'promoted': []}, {'cards': [3], 'freed': [], 'promoted': []}]),
('edge stored after the target survived once',
({1: ['old', 184, [None, None]],
2: ['old', 320, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[13],
[['minor'], ['store', 2, 0, 13], ['unroot', 13], ['minor']],
5),
[{'cards': [], 'freed': [11, 12, 14], 'promoted': []}, {'cards': [5], 'freed': [], 'promoted': []}]),
('promotion at the tenuring threshold',
({1: ['old', 184, [None, None]],
2: ['old', 320, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[11],
[['minor'], ['minor'], ['minor']],
2),
[{'cards': [], 'freed': [13, 14], 'promoted': []},
{'cards': [], 'freed': [], 'promoted': [11, 12]},
{'cards': [], 'freed': [], 'promoted': []}]),
('promoted object pointing at a younger object',
({1: ['old', 184, [None, None]],
2: ['old', 320, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[11],
[['minor'], ['alloc', 15], ['store', 11, 0, 15], ['minor'], ['minor']],
2),
[{'cards': [], 'freed': [13, 14], 'promoted': []},
{'cards': [64], 'freed': [12], 'promoted': [11]},
{'cards': [], 'freed': [], 'promoted': [15]}]),
('card of a slot in the next card',
({1: ['old', 184, [None, None]],
2: ['old', 320, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[],
[['store', 1, 0, 13], ['store', 1, 1, 14], ['minor']],
4),
[{'cards': [2, 3], 'freed': [11, 12], 'promoted': []}]),
('control: unreferenced young objects die',
({1: ['old', 184, [None, None]],
2: ['old', 320, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[12],
[['minor']],
3),
[{'cards': [], 'freed': [11, 13, 14], 'promoted': []}])],
[('regression: old-to-young edge survives two minor collections',
({1: ['old', 248, [None, None]],
2: ['old', 384, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[],
[['store', 1, 1, 11], ['minor'], ['minor']],
5),
[{'cards': [4], 'freed': [13, 14], 'promoted': []}, {'cards': [4], 'freed': [], 'promoted': []}]),
('edge stored after the target survived once',
({1: ['old', 248, [None, None]],
2: ['old', 384, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[13],
[['minor'], ['store', 2, 0, 13], ['unroot', 13], ['minor']],
5),
[{'cards': [], 'freed': [11, 12, 14], 'promoted': []}, {'cards': [6], 'freed': [], 'promoted': []}]),
('promotion at the tenuring threshold',
({1: ['old', 248, [None, None]],
2: ['old', 384, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[11],
[['minor'], ['minor'], ['minor']],
2),
[{'cards': [], 'freed': [13, 14], 'promoted': []},
{'cards': [], 'freed': [], 'promoted': [11, 12]},
{'cards': [], 'freed': [], 'promoted': []}]),
('promoted object pointing at a younger object',
({1: ['old', 248, [None, None]],
2: ['old', 384, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[11],
[['minor'], ['alloc', 15], ['store', 11, 0, 15], ['minor'], ['minor']],
2),
[{'cards': [], 'freed': [13, 14], 'promoted': []},
{'cards': [64], 'freed': [12], 'promoted': [11]},
{'cards': [], 'freed': [], 'promoted': [15]}]),
('card of a slot in the next card',
({1: ['old', 248, [None, None]],
2: ['old', 384, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[],
[['store', 1, 0, 13], ['store', 1, 1, 14], ['minor']],
4),
[{'cards': [3, 4], 'freed': [11, 12], 'promoted': []}]),
('control: unreferenced young objects die',
({1: ['old', 248, [None, None]],
2: ['old', 384, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[12],
[['minor']],
3),
[{'cards': [], 'freed': [11, 13, 14], 'promoted': []}])],
[('regression: old-to-young edge survives two minor collections',
({1: ['old', 312, [None, None]],
2: ['old', 448, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[],
[['store', 1, 1, 11], ['minor'], ['minor']],
5),
[{'cards': [5], 'freed': [13, 14], 'promoted': []}, {'cards': [5], 'freed': [], 'promoted': []}]),
('edge stored after the target survived once',
({1: ['old', 312, [None, None]],
2: ['old', 448, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[13],
[['minor'], ['store', 2, 0, 13], ['unroot', 13], ['minor']],
5),
[{'cards': [], 'freed': [11, 12, 14], 'promoted': []}, {'cards': [7], 'freed': [], 'promoted': []}]),
('promotion at the tenuring threshold',
({1: ['old', 312, [None, None]],
2: ['old', 448, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[11],
[['minor'], ['minor'], ['minor']],
2),
[{'cards': [], 'freed': [13, 14], 'promoted': []},
{'cards': [], 'freed': [], 'promoted': [11, 12]},
{'cards': [], 'freed': [], 'promoted': []}]),
('promoted object pointing at a younger object',
({1: ['old', 312, [None, None]],
2: ['old', 448, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[11],
[['minor'], ['alloc', 15], ['store', 11, 0, 15], ['minor'], ['minor']],
2),
[{'cards': [], 'freed': [13, 14], 'promoted': []},
{'cards': [64], 'freed': [12], 'promoted': [11]},
{'cards': [], 'freed': [], 'promoted': [15]}]),
('card of a slot in the next card',
({1: ['old', 312, [None, None]],
2: ['old', 448, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[],
[['store', 1, 0, 13], ['store', 1, 1, 14], ['minor']],
4),
[{'cards': [4, 5], 'freed': [11, 12], 'promoted': []}]),
('control: unreferenced young objects die',
({1: ['old', 312, [None, None]],
2: ['old', 448, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[12],
[['minor']],
3),
[{'cards': [], 'freed': [11, 13, 14], 'promoted': []}])]]
for label, args, expected in cases[N - 1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: old-to-young edge survives two minor collections | [{'cards': [1], 'freed': [13, 14], 'promoted': []}, {'cards': [1], 'freed': [], 'promoted': []}] | [{'cards': [1], 'freed': [13, 14], 'promoted': []}, {'cards': [1], 'freed': [], 'promoted': []}] | Passed |
| edge stored after the target survived once | [{'cards': [], 'freed': [11, 12, 14], 'promoted': []}, {'cards': [3], 'freed': [], 'promoted': []}] | [{'cards': [], 'freed': [11, 12, 14], 'promoted': []}, {'cards': [3], 'freed': [], 'promoted': []}] | Passed |
| promotion at the tenuring threshold | [{'cards': [], 'freed': [13, 14], 'promoted': []}, {'cards': [], 'freed': [], 'promoted': [11, 12]}, {'cards': [], 'freed': [], 'promoted': []}] | [{'cards': [], 'freed': [13, 14], 'promoted': []}, {'cards': [], 'freed': [], 'promoted': [11, 12]}, {'cards': [], 'freed': [], 'promoted': []}] | Passed |
| promoted object pointing at a younger object | [{'cards': [], 'freed': [13, 14], 'promoted': []}, {'cards': [], 'freed': [12], 'promoted': [11]}, {'dangling': 15}] | [{'cards': [], 'freed': [13, 14], 'promoted': []}, {'cards': [64], 'freed': [12], 'promoted': [11]}, {'cards': [], 'freed': [], 'promoted': [15]}] | Failed |
| card of a slot in the next card | [{'cards': [0, 1], 'freed': [11, 12], 'promoted': []}] | [{'cards': [0, 1], 'freed': [11, 12], 'promoted': []}] | Passed |
| control: unreferenced young objects die | [{'cards': [], 'freed': [11, 13, 14], 'promoted': []}] | [{'cards': [], 'freed': [11, 13, 14], 'promoted': []}] | Passed |
SHA-256 / c896412f3b3567846720f2ff28b613f120048923b01f7ea08f9e93208b068f0a
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(objs, roots, events, tenure):
objs = {k: {'gen': v[0], 'addr': v[1], 'fields': list(v[2]), 'age': 0} for k, v in objs.items()}
roots = list(roots)
cards = set()
log = []
next_addr = 4096
def slot_card(o, i):
return (objs[o]['addr'] + 8 * i) // 64
try:
for ev in events:
if ev[0] == 'store':
_, src, i, dst = ev
objs[src]['fields'][i] = dst
if objs[src]['gen'] == 'old' and dst is not None and objs[dst]['gen'] == 'young':
cards.add(slot_card(src, i))
elif ev[0] == 'alloc':
objs[ev[1]] = {'gen': 'young', 'addr': 0, 'fields': [None], 'age': 0}
elif ev[0] == 'root':
roots.append(ev[1])
elif ev[0] == 'unroot':
roots.remove(ev[1])
else:
grey = [r for r in roots if objs[r]['gen'] == 'young']
for o, ob in objs.items():
if ob['gen'] == 'old':
for i, f in enumerate(ob['fields']):
if slot_card(o, i) in cards and f is not None and objs[f]['gen'] == 'young':
grey.append(f)
live = set()
while grey:
y = grey.pop()
if y in live:
continue
live.add(y)
for f in objs[y]['fields']:
if f is not None and objs[f]['gen'] == 'young':
grey.append(f)
dead = sorted(k for k, ob in objs.items() if ob['gen'] == 'young' and k not in live)
for k in dead:
del objs[k]
promoted = []
for k in sorted(live):
objs[k]['age'] += 1
if objs[k]['age'] >= tenure:
objs[k]['gen'] = 'old'
objs[k]['addr'] = next_addr
next_addr += 64
promoted.append(k)
cards = set()
for o in [k for k, ob in objs.items() if ob['gen'] == 'old']:
for i, f in enumerate(objs[o]['fields']):
if f is not None and objs[f]['gen'] == 'young':
cards.add(slot_card(o, i))
log.append({'freed': dead, 'promoted': promoted, 'cards': sorted(cards)})
except KeyError as e:
log.append({'dangling': e.args[0]})
return log
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression: old-to-young edge survives two minor collections',
({1: ['old', 56, [None, None]],
2: ['old', 192, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[],
[['store', 1, 1, 11], ['minor'], ['minor']],
5),
[{'cards': [1], 'freed': [13, 14], 'promoted': []}, {'cards': [1], 'freed': [], 'promoted': []}]),
('edge stored after the target survived once',
({1: ['old', 56, [None, None]],
2: ['old', 192, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[13],
[['minor'], ['store', 2, 0, 13], ['unroot', 13], ['minor']],
5),
[{'cards': [], 'freed': [11, 12, 14], 'promoted': []}, {'cards': [3], 'freed': [], 'promoted': []}]),
('promotion at the tenuring threshold',
({1: ['old', 56, [None, None]],
2: ['old', 192, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[11],
[['minor'], ['minor'], ['minor']],
2),
[{'cards': [], 'freed': [13, 14], 'promoted': []},
{'cards': [], 'freed': [], 'promoted': [11, 12]},
{'cards': [], 'freed': [], 'promoted': []}]),
('promoted object pointing at a younger object',
({1: ['old', 56, [None, None]],
2: ['old', 192, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[11],
[['minor'], ['alloc', 15], ['store', 11, 0, 15], ['minor'], ['minor']],
2),
[{'cards': [], 'freed': [13, 14], 'promoted': []},
{'cards': [64], 'freed': [12], 'promoted': [11]},
{'cards': [], 'freed': [], 'promoted': [15]}]),
('card of a slot in the next card',
({1: ['old', 56, [None, None]],
2: ['old', 192, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[],
[['store', 1, 0, 13], ['store', 1, 1, 14], ['minor']],
4),
[{'cards': [0, 1], 'freed': [11, 12], 'promoted': []}]),
('control: unreferenced young objects die',
({1: ['old', 56, [None, None]],
2: ['old', 192, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[12],
[['minor']],
3),
[{'cards': [], 'freed': [11, 13, 14], 'promoted': []}])],
[('regression: old-to-young edge survives two minor collections',
({1: ['old', 120, [None, None]],
2: ['old', 256, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[],
[['store', 1, 1, 11], ['minor'], ['minor']],
5),
[{'cards': [2], 'freed': [13, 14], 'promoted': []}, {'cards': [2], 'freed': [], 'promoted': []}]),
('edge stored after the target survived once',
({1: ['old', 120, [None, None]],
2: ['old', 256, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[13],
[['minor'], ['store', 2, 0, 13], ['unroot', 13], ['minor']],
5),
[{'cards': [], 'freed': [11, 12, 14], 'promoted': []}, {'cards': [4], 'freed': [], 'promoted': []}]),
('promotion at the tenuring threshold',
({1: ['old', 120, [None, None]],
2: ['old', 256, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[11],
[['minor'], ['minor'], ['minor']],
2),
[{'cards': [], 'freed': [13, 14], 'promoted': []},
{'cards': [], 'freed': [], 'promoted': [11, 12]},
{'cards': [], 'freed': [], 'promoted': []}]),
('promoted object pointing at a younger object',
({1: ['old', 120, [None, None]],
2: ['old', 256, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[11],
[['minor'], ['alloc', 15], ['store', 11, 0, 15], ['minor'], ['minor']],
2),
[{'cards': [], 'freed': [13, 14], 'promoted': []},
{'cards': [64], 'freed': [12], 'promoted': [11]},
{'cards': [], 'freed': [], 'promoted': [15]}]),
('card of a slot in the next card',
({1: ['old', 120, [None, None]],
2: ['old', 256, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[],
[['store', 1, 0, 13], ['store', 1, 1, 14], ['minor']],
4),
[{'cards': [1, 2], 'freed': [11, 12], 'promoted': []}]),
('control: unreferenced young objects die',
({1: ['old', 120, [None, None]],
2: ['old', 256, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[12],
[['minor']],
3),
[{'cards': [], 'freed': [11, 13, 14], 'promoted': []}])],
[('regression: old-to-young edge survives two minor collections',
({1: ['old', 184, [None, None]],
2: ['old', 320, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[],
[['store', 1, 1, 11], ['minor'], ['minor']],
5),
[{'cards': [3], 'freed': [13, 14], 'promoted': []}, {'cards': [3], 'freed': [], 'promoted': []}]),
('edge stored after the target survived once',
({1: ['old', 184, [None, None]],
2: ['old', 320, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[13],
[['minor'], ['store', 2, 0, 13], ['unroot', 13], ['minor']],
5),
[{'cards': [], 'freed': [11, 12, 14], 'promoted': []}, {'cards': [5], 'freed': [], 'promoted': []}]),
('promotion at the tenuring threshold',
({1: ['old', 184, [None, None]],
2: ['old', 320, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[11],
[['minor'], ['minor'], ['minor']],
2),
[{'cards': [], 'freed': [13, 14], 'promoted': []},
{'cards': [], 'freed': [], 'promoted': [11, 12]},
{'cards': [], 'freed': [], 'promoted': []}]),
('promoted object pointing at a younger object',
({1: ['old', 184, [None, None]],
2: ['old', 320, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[11],
[['minor'], ['alloc', 15], ['store', 11, 0, 15], ['minor'], ['minor']],
2),
[{'cards': [], 'freed': [13, 14], 'promoted': []},
{'cards': [64], 'freed': [12], 'promoted': [11]},
{'cards': [], 'freed': [], 'promoted': [15]}]),
('card of a slot in the next card',
({1: ['old', 184, [None, None]],
2: ['old', 320, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[],
[['store', 1, 0, 13], ['store', 1, 1, 14], ['minor']],
4),
[{'cards': [2, 3], 'freed': [11, 12], 'promoted': []}]),
('control: unreferenced young objects die',
({1: ['old', 184, [None, None]],
2: ['old', 320, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[12],
[['minor']],
3),
[{'cards': [], 'freed': [11, 13, 14], 'promoted': []}])],
[('regression: old-to-young edge survives two minor collections',
({1: ['old', 248, [None, None]],
2: ['old', 384, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[],
[['store', 1, 1, 11], ['minor'], ['minor']],
5),
[{'cards': [4], 'freed': [13, 14], 'promoted': []}, {'cards': [4], 'freed': [], 'promoted': []}]),
('edge stored after the target survived once',
({1: ['old', 248, [None, None]],
2: ['old', 384, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[13],
[['minor'], ['store', 2, 0, 13], ['unroot', 13], ['minor']],
5),
[{'cards': [], 'freed': [11, 12, 14], 'promoted': []}, {'cards': [6], 'freed': [], 'promoted': []}]),
('promotion at the tenuring threshold',
({1: ['old', 248, [None, None]],
2: ['old', 384, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[11],
[['minor'], ['minor'], ['minor']],
2),
[{'cards': [], 'freed': [13, 14], 'promoted': []},
{'cards': [], 'freed': [], 'promoted': [11, 12]},
{'cards': [], 'freed': [], 'promoted': []}]),
('promoted object pointing at a younger object',
({1: ['old', 248, [None, None]],
2: ['old', 384, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[11],
[['minor'], ['alloc', 15], ['store', 11, 0, 15], ['minor'], ['minor']],
2),
[{'cards': [], 'freed': [13, 14], 'promoted': []},
{'cards': [64], 'freed': [12], 'promoted': [11]},
{'cards': [], 'freed': [], 'promoted': [15]}]),
('card of a slot in the next card',
({1: ['old', 248, [None, None]],
2: ['old', 384, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[],
[['store', 1, 0, 13], ['store', 1, 1, 14], ['minor']],
4),
[{'cards': [3, 4], 'freed': [11, 12], 'promoted': []}]),
('control: unreferenced young objects die',
({1: ['old', 248, [None, None]],
2: ['old', 384, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[12],
[['minor']],
3),
[{'cards': [], 'freed': [11, 13, 14], 'promoted': []}])],
[('regression: old-to-young edge survives two minor collections',
({1: ['old', 312, [None, None]],
2: ['old', 448, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[],
[['store', 1, 1, 11], ['minor'], ['minor']],
5),
[{'cards': [5], 'freed': [13, 14], 'promoted': []}, {'cards': [5], 'freed': [], 'promoted': []}]),
('edge stored after the target survived once',
({1: ['old', 312, [None, None]],
2: ['old', 448, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[13],
[['minor'], ['store', 2, 0, 13], ['unroot', 13], ['minor']],
5),
[{'cards': [], 'freed': [11, 12, 14], 'promoted': []}, {'cards': [7], 'freed': [], 'promoted': []}]),
('promotion at the tenuring threshold',
({1: ['old', 312, [None, None]],
2: ['old', 448, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[11],
[['minor'], ['minor'], ['minor']],
2),
[{'cards': [], 'freed': [13, 14], 'promoted': []},
{'cards': [], 'freed': [], 'promoted': [11, 12]},
{'cards': [], 'freed': [], 'promoted': []}]),
('promoted object pointing at a younger object',
({1: ['old', 312, [None, None]],
2: ['old', 448, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[11],
[['minor'], ['alloc', 15], ['store', 11, 0, 15], ['minor'], ['minor']],
2),
[{'cards': [], 'freed': [13, 14], 'promoted': []},
{'cards': [64], 'freed': [12], 'promoted': [11]},
{'cards': [], 'freed': [], 'promoted': [15]}]),
('card of a slot in the next card',
({1: ['old', 312, [None, None]],
2: ['old', 448, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[],
[['store', 1, 0, 13], ['store', 1, 1, 14], ['minor']],
4),
[{'cards': [4, 5], 'freed': [11, 12], 'promoted': []}]),
('control: unreferenced young objects die',
({1: ['old', 312, [None, None]],
2: ['old', 448, [None]],
11: ['young', 0, [12]],
12: ['young', 0, []],
13: ['young', 0, []],
14: ['young', 0, [None]]},
[12],
[['minor']],
3),
[{'cards': [], 'freed': [11, 13, 14], 'promoted': []}])]]
for label, args, expected in cases[N - 1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: old-to-young edge survives two minor collections | [{'cards': [1], 'freed': [13, 14], 'promoted': []}, {'cards': [1], 'freed': [], 'promoted': []}] | [{'cards': [1], 'freed': [13, 14], 'promoted': []}, {'cards': [1], 'freed': [], 'promoted': []}] | Passed |
| edge stored after the target survived once | [{'cards': [], 'freed': [11, 12, 14], 'promoted': []}, {'cards': [3], 'freed': [], 'promoted': []}] | [{'cards': [], 'freed': [11, 12, 14], 'promoted': []}, {'cards': [3], 'freed': [], 'promoted': []}] | Passed |
| promotion at the tenuring threshold | [{'cards': [], 'freed': [13, 14], 'promoted': []}, {'cards': [], 'freed': [], 'promoted': [11, 12]}, {'cards': [], 'freed': [], 'promoted': []}] | [{'cards': [], 'freed': [13, 14], 'promoted': []}, {'cards': [], 'freed': [], 'promoted': [11, 12]}, {'cards': [], 'freed': [], 'promoted': []}] | Passed |
| promoted object pointing at a younger object | [{'cards': [], 'freed': [13, 14], 'promoted': []}, {'cards': [64], 'freed': [12], 'promoted': [11]}, {'cards': [], 'freed': [], 'promoted': [15]}] | [{'cards': [], 'freed': [13, 14], 'promoted': []}, {'cards': [64], 'freed': [12], 'promoted': [11]}, {'cards': [], 'freed': [], 'promoted': [15]}] | Passed |
| card of a slot in the next card | [{'cards': [0, 1], 'freed': [11, 12], 'promoted': []}] | [{'cards': [0, 1], 'freed': [11, 12], 'promoted': []}] | Passed |
| control: unreferenced young objects die | [{'cards': [], 'freed': [11, 13, 14], 'promoted': []}] | [{'cards': [], 'freed': [11, 13, 14], 'promoted': []}] | Passed |
SHA-256 / 368786931ca48a50ec0f2c4b6eb27f930ea9fb21625955d14701473326201cf7
Verification & scope
A deterministic, bounded teaching model of one garbage-collector mechanism with stipulated rules; it is not a production collector and claims no conformance to any particular runtime. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:51:27.660472+00:00.
Case digest / 710e0662c6dbf1379e7c5e41b5771424fc6e3d6a1982b9d82190c293d49ad1cd