WVMBackingMap.mesa: Map of VM backing file
Copyright © 1985 by Xerox Corporation. All rights reserved.
Andrew Birrell December 2, 1983 1:16 pm
Russ Atkinson (RRA) February 6, 1985 9:28:10 pm PST
DIRECTORY
DebuggerFormat USING[ ExternalStateVector, Run, SwapInfo, VersionID, VMRunTable ],
PrincOps USING[ PDA ],
WorldVM USING[Address, CopyRead, World],
WVMPrivate;
WVMBackingMap: MONITOR
IMPORTS WorldVM, WVMPrivate
EXPORTS WVMPrivate, WorldVM = {
VMBackingMapObject: PUBLIC TYPE = RECORD[
found: CARDINAL ← 0, -- maplog entries read in so far --
entries: REF DebuggerFormat.VMRunTable];
VMBackingMap: TYPE = REF VMBackingMapObject;
CreateVMBackingMap: PUBLIC PROC[world: WorldVM.World] RETURNS[ VMBackingMap ] = {
RETURN[NEW[VMBackingMapObject ← [0,NIL]]]
};
ReadVMBackingMap: PUBLIC PROC[world: WorldVM.World, log: VMBackingMap] RETURNS[basic, real: WorldVM.Address] = {
swapInfo: DebuggerFormat.SwapInfo;
swapInfoAddr: WorldVM.Address = LOOPHOLE[@PrincOps.PDA.available];
esv: DebuggerFormat.ExternalStateVector;
esvAddr: WorldVM.Address;
WorldVM.CopyRead[world, swapInfoAddr, SIZE[DebuggerFormat.SwapInfo],
@swapInfo];
esvAddr ← LOOPHOLE[swapInfo.externalStateVector];
WorldVM.CopyRead[world, esvAddr, SIZE[DebuggerFormat.ExternalStateVector],
@esv];
basic ← WVMPrivate.PageAddress[esv.loadstatepage];
real ← LOOPHOLE[esv.loadState];
SELECT esv.versionident FROM
DebuggerFormat.VersionID => {
IF esv.vmRunTable # NIL THEN {
temp: ARRAY [0..SIZE[DebuggerFormat.VMRunTable[0]]) OF WORD;
cheat: POINTER TO DebuggerFormat.VMRunTable = LOOPHOLE[@temp];
WorldVM.CopyRead[world,
LOOPHOLE[esv.vmRunTable, WorldVM.Address],
SIZE[DebuggerFormat.VMRunTable[0]],
@temp ];
log.entries ← NEW[DebuggerFormat.VMRunTable[cheat.length]];
WorldVM.CopyRead[world,
LOOPHOLE[esv.vmRunTable, WorldVM.Address],
SIZE[DebuggerFormat.VMRunTable[cheat.length]],
LOOPHOLE[log.entries, LONG POINTER] ];
log.found ← log.entries.nRuns;
};
};
ENDCASE => NULL; -- treat as if there was no maplog
};
AddressFault: PUBLIC ERROR[mempage: WVMPrivate.PageNumber] = CODE;
lastEntryIndex: CARDINAL ← 0; -- hint for log entry to try first --
GetVMBackingMapEntry: PUBLIC ENTRY PROC[log: VMBackingMap, mempage: WVMPrivate.PageNumber] RETURNS[ WVMPrivate.DiskAddress ] = {
ENABLE UNWIND => NULL;
entry: LONG POINTER TO DebuggerFormat.Run ←
IF lastEntryIndex IN [0..log.found) -- lastEntryIndex may be for another log!
THEN @log.entries[lastEntryIndex]
ELSE NIL;
IF entry = NIL
OR mempage NOT IN [entry.page..entry.page+entry.count)
THEN {
sigh! Need to search for it. --
FOR i: CARDINAL IN [0..log.found) DO
entry ← @log.entries[lastEntryIndex←i];
IF mempage IN [entry.page..entry.page+entry.count) THEN EXIT;
REPEAT FINISHED => ERROR AddressFault[mempage]
ENDLOOP;
};
RETURN[[entry.deviceType, entry.deviceOrdinal, entry.diskPage, mempage-entry.page, entry.labelCheck]];
};
}.