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 *(Addr addr) { if (addr != 0) setAddr(addr); else init(); } // initialize as new object *() { 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); } 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()); if (userDataPtr() != 0) makeUserObject.get(userDataPtr()).scanForCollection(gc); } } *(ManagedIntObjects_v1 *mem, IF1 *makeUserObject) { root = new Root(mem.getRootField()); mem.freeList = FreeList.fromIntArray(mem.readIntArray(root.freeListPtr())); } void persist { mem.freeIntArray(root.freeListPtr()); root.freeListPtr(mem.newIntArray(mem.freeList.toIntArray())); } }