sclass PersistentManagedObjects_v1 { replace Addr with int. replace BoxedAddr with Int. ManagedIntObjects_v1 mem; IF1 makeUserObject; // user needs to fill this Root root; final static int TYPE_STRING = -1, TYPE_INTARRAY = -2, TYPE_ROOT = -3; class Root extends AbstractManagedObject { final static int ofs_type = 0, ofs_version = 1, ofs_freeListPtr = 2, ofs_userDataPtr = 3; final static int objectSize = ofs_userDataPtr+1; // initialize as wrapper for existing object // or create new when addr == 0 *(Addr addr) { if (addr != 0) setAddr(addr); else create(); } // initialize as new object *() { create(); } void create { setAddr(mem.alloc(objectSize)); init(); } void init { type(TYPE_ROOT); version(1); } // getters + setters int type() { ret mem.get(addr+ofs_type); } void type(int x) { mem.set(addr+ofs_type, x); } int version() { ret mem.get(addr+ofs_version); } void version(int x) { mem.set(addr+ofs_version, x); } Addr freeListPtr() { ret mem.get(addr+ofs_freeListPtr); } void freeListPtr(Addr x) { mem.set(addr+ofs_freeListPtr, x); } Addr userDataPtr() { ret mem.get(addr+ofs_userDataPtr); } void userDataPtr(Addr x) { mem.set(addr+ofs_userDataPtr, x); } A userData() { ret makeUserObject.get(userDataPtr()); } void userData(A userData) { userDataPtr(userData == null ? 0 : userData.addr); } void setAddr(Addr newAddr) { addr = newAddr; mem.setRootField(addr); } // GC handling public void scanForCollection(IManagedObjectCollector gc) { gc.noteObject(addr, objectSize, lambda1 setAddr); gc.notePointer(addr+ofs_freeListPtr); gc.notePointer(addr+ofs_userDataPtr); gc.noteIntArray(freeListPtr()); var userData = userData(); userData?.scanForCollection(gc); } } *(ManagedIntObjects_v1 *mem, IF1 *makeUserObject) { Addr rootPtr = mem.getRootField(); print(+rootPtr); root = new Root(rootPtr); mem.freeList = FreeList.fromIntArray(mem.readIntArray(root.freeListPtr())); } void persist { mem.freeIntArray(root.freeListPtr()); root.freeListPtr(mem.newIntArray(mem.freeList.toIntArray())); } A get aka getUserData() { ret root.userData(); } void set aka setUserData(A userData) { root.userData(userData); } }