Cedar Remote Debugging: cache of client pages
WVMLoadState.mesa
Andrew Birrell December 2, 1983 3:08 pm
DIRECTORY
BasicLoadStateFormat USING[ LoadStateObject ],
PrincOps USING[ GlobalFrameHandle ],
LoadState USING[ Handle ],
LoadStateFormat,
WorldVM USING[ Address, CopyRead, LongRead, Read ],
WVMPrivate USING[ WorldObject ];
WVMLoadState: MONITOR
IMPORTS WorldVM
EXPORTS LoadState--opaque type--, WorldVM--opaque type--, WVMPrivate =
BEGIN
World: TYPE = REF WorldObject;
WorldObject: PUBLIC TYPE = WVMPrivate.WorldObject;
GetLoadState: PUBLIC PROC[world: World, basic, real: WorldVM.Address] =
BEGIN
IF real # 0 THEN CopyRealLoadState[world, real] ELSE CopyBasicLoadState[world, basic];
END;
--LoadState.--Object: PUBLIC TYPE = LoadStateFormat.Object;
CopyRealLoadState: PROC[world: World, real: WorldVM.Address] =
BEGIN
loadState: REF Object = NEW[Object];
loadState.useCount ← 0;
loadState.changeCount ← LOOPHOLE[WorldVM.LongRead[
world: world,
addr: real + (LOOPHOLE[@loadState.changeCount,WorldVM.Address]-LOOPHOLE[loadState,WorldVM.Address])
]];
loadState.configTable ← CopyConfigTable[
world: world,
from: WorldVM.LongRead[world,
real + (LOOPHOLE[@loadState.configTable,WorldVM.Address]-LOOPHOLE[loadState,WorldVM.Address])]
];
loadState.copyTable ← CopyCopyTable[
world: world,
from: WorldVM.LongRead[world,
real + (LOOPHOLE[@loadState.copyTable,WorldVM.Address]-LOOPHOLE[loadState,WorldVM.Address])]
];
loadState.collisionTable ← CopyCollisionTable[
world: world,
from: WorldVM.LongRead[world,
real + (LOOPHOLE[@loadState.collisionTable,WorldVM.Address]-LOOPHOLE[loadState,WorldVM.Address])]
];
WorldVM.CopyRead[
world: world,
from: real + (LOOPHOLE[@loadState.gfht,WorldVM.Address]-LOOPHOLE[loadState,WorldVM.Address]),
to: @loadState.gfht,
nwords: SIZE[ARRAY LoadStateFormat.HashIndex OF LoadStateFormat.Entry]
];
world.loadState ← loadState;
END;
CopyConfigTable: PROC[world: World, from: WorldVM.Address] RETURNS[to: REF LoadStateFormat.ConfigTable] =
BEGIN
minSize: CARDINAL = SIZE[LoadStateFormat.ConfigTable[0]];
temp: ARRAY [0..minSize) OF WORD;
cheat: POINTER TO LoadStateFormat.ConfigTable = LOOPHOLE[@temp];
WorldVM.CopyRead[
world: world,
from: from,
to: @temp,
nwords: minSize];
to ← NEW[LoadStateFormat.ConfigTable[cheat.length]];
to.nConfigs ← cheat.nConfigs;
FOR i: NAT IN [0..to.nConfigs)
DO to[i] ← CopyConfig[
world: world,
from: WorldVM.LongRead[world,
from + (LOOPHOLE[@to[i],WorldVM.Address]-LOOPHOLE[to,WorldVM.Address])]
];
ENDLOOP;
END;
CopyCopyTable: PROC[world: World, from: WorldVM.Address] RETURNS[to: REF LoadStateFormat.CopyTable] =
BEGIN
minSize: CARDINAL = SIZE[LoadStateFormat.CopyTable[0]];
temp: ARRAY [0..minSize) OF WORD;
cheat: POINTER TO LoadStateFormat.CopyTable = LOOPHOLE[@temp];
WorldVM.CopyRead[
world: world,
from: from,
to: @temp,
nwords: minSize];
to ← NEW[LoadStateFormat.CopyTable[cheat.length]];
to.nCopies ← cheat.nCopies;
FOR i: NAT IN [0..to.nCopies)
DO to[i].parent ← LOOPHOLE[WorldVM.Read[world,
from + (LOOPHOLE[@to[i].parent,WorldVM.Address]-LOOPHOLE[to,WorldVM.Address])]];
to[i].copies ← CopyCopiesList[
world: world,
from: WorldVM.LongRead[world,
from + (LOOPHOLE[@to[i].copies,WorldVM.Address]-LOOPHOLE[to,WorldVM.Address])]
];
ENDLOOP;
END;
CopyCollisionTable: PROC[world: World, from: WorldVM.Address] RETURNS[to: REF LoadStateFormat.CollisionTable]=
BEGIN
minSize: CARDINAL = SIZE[LoadStateFormat.CollisionTable[0]];
temp: ARRAY [0..minSize) OF WORD;
cheat: POINTER TO LoadStateFormat.CollisionTable = LOOPHOLE[@temp];
WorldVM.CopyRead[
world: world,
from: from,
to: @temp,
nwords: minSize];
to ← NEW[LoadStateFormat.CollisionTable[cheat.length]];
to.nCollisions ← cheat.nCollisions;
FOR i: NAT IN [0..to.nCollisions)
DO to[i] ← CopyCollisionList[
world: world,
from: WorldVM.LongRead[world,
from + (LOOPHOLE[@to[i],WorldVM.Address]-LOOPHOLE[to,WorldVM.Address])]
];
ENDLOOP;
END;
CopyConfig: PROC[world: World, from: WorldVM.Address] RETURNS[to: REF LoadStateFormat.ConfigObject]=
BEGIN
minSize: CARDINAL = SIZE[LoadStateFormat.ConfigObject[0]];
temp: ARRAY [0..minSize) OF WORD;
cheat: POINTER TO LoadStateFormat.ConfigObject = LOOPHOLE[@temp];
WorldVM.CopyRead[
world: world,
from: from,
to: @temp,
nwords: minSize];
to ← NEW[LoadStateFormat.ConfigObject[cheat.length]];
to.bcd ← cheat.bcd;
to.ref ← NIL;
to.nModules ← cheat.nModules;
WorldVM.CopyRead[
world: world,
from: from + (LOOPHOLE[@to[0],WorldVM.Address]-LOOPHOLE[to,WorldVM.Address]),
to: @to[0],
nwords: to.nModules * SIZE[LoadStateFormat.ModuleEntry]
];
END;
CopyCopiesList: PROC[world: World, from: WorldVM.Address] RETURNS[to: LIST OF PrincOps.GlobalFrameHandle ← NIL]=
BEGIN
fromPos: WorldVM.Address ← from;
toPos: LIST OF PrincOps.GlobalFrameHandle ← NIL;
dummy: LIST OF PrincOps.GlobalFrameHandle = CONS[first: NULL, rest: NIL];
firstOffset: CARDINAL =
LOOPHOLE[@dummy.first,WorldVM.Address]-LOOPHOLE[dummy,WorldVM.Address];
restOffset: CARDINAL =
LOOPHOLE[@dummy.rest,WorldVM.Address]-LOOPHOLE[dummy,WorldVM.Address];
UNTIL fromPos = 0--NIL-- DO
this: PrincOps.GlobalFrameHandle = LOOPHOLE[WorldVM.Read[world, fromPos + firstOffset]];
new: LIST OF PrincOps.GlobalFrameHandle = CONS[first: this, rest: NIL];
IF to = NIL THEN to ← new ELSE toPos.rest ← new;
toPos ← new;
fromPos ← WorldVM.LongRead[world, fromPos + restOffset];
ENDLOOP;
END;
CopyCollisionList: PROC[world: World, from: WorldVM.Address] RETURNS[to: LIST OF LoadStateFormat.Entry ← NIL]=
BEGIN
fromPos: WorldVM.Address ← from;
toPos: LIST OF LoadStateFormat.Entry ← NIL;
dummy: LIST OF LoadStateFormat.Entry = CONS[first: NULL, rest: NIL];
firstOffset: CARDINAL =
LOOPHOLE[@dummy.first,WorldVM.Address]-LOOPHOLE[dummy,WorldVM.Address];
restOffset: CARDINAL =
LOOPHOLE[@dummy.rest,WorldVM.Address]-LOOPHOLE[dummy,WorldVM.Address];
UNTIL fromPos = 0--NIL-- DO
this: LoadStateFormat.Entry;
new: LIST OF LoadStateFormat.Entry;
WorldVM.CopyRead[
world: world,
from: fromPos + firstOffset,
to: @this,
nwords: SIZE[LoadStateFormat.Entry]];
new ← CONS[first: this, rest: NIL];
IF to = NIL THEN to ← new ELSE toPos.rest ← new;
toPos ← new;
fromPos ← WorldVM.LongRead[world, fromPos + restOffset];
ENDLOOP;
END;
CopyBasicLoadState: PROC[world: World, basic: WorldVM.Address] =
BEGIN
minSize: CARDINAL = SIZE[BasicLoadStateFormat.LoadStateObject[0]];
temp: ARRAY [0..minSize) OF WORD;
cheat: POINTER TO BasicLoadStateFormat.LoadStateObject = LOOPHOLE[@temp];
WorldVM.CopyRead[world: world,
to: @temp,
from: basic,
nwords: minSize];
IF world.basicLoadState = NIL OR cheat.length # world.basicLoadState.length
THEN world.basicLoadState ← NEW[BasicLoadStateFormat.LoadStateObject[cheat.length]];
WorldVM.CopyRead[world: world,
to: LOOPHOLE[world.basicLoadState,LONG POINTER],
from: basic,
nwords: SIZE[BasicLoadStateFormat.LoadStateObject[cheat.length]]
];
world.loadState ← ERROR -- to be implemented! --;
END;
END.