-- RTRefAccounting.Mesa
-- last edited 2-Sep-81 16:28:12 by Willie-Sue Haugeland
-- last edited 8-Feb-82 11:47:23 by Paul Rovner
DIRECTORY
Inline USING[LongNumber, BITXOR, BITSHIFT, LowHalf, HighHalf],
RTRefCounts,
Runtime USING[GlobalFrame],
SpecialSpace USING[MakeCodeResident, MakeGlobalFrameResident];
RTRefAccounting: PROGRAM
IMPORTS RTRefCounts, Inline, SpecialSpace, Runtime
= BEGIN
OPEN RTRefCounts;
RCEntriesSummary: TYPE =
RECORD [empty: CARDINAL← 0, normal: CARDINAL← 0, overflow: CARDINAL← 0];
distributionSummary: TYPE = RECORD
[ LTrcFinalize: CARDINAL← 0,
EQrcFinalize: CARDINAL← 0,
rcFinalizePlus1: CARDINAL← 0,
rcFinalizePlus2: CARDINAL← 0,
rcFinalizePlus3: CARDINAL← 0,
rcFinalizePlus4: CARDINAL← 0,
rcFinalizePlus5: CARDINAL← 0,
rcFinalizePlus5Plus: CARDINAL← 0,
rcCountPegged: CARDINAL← 0
];
oiLengthsSummary: TYPE = RECORD
[ two: CARDINAL← 0,
threeTo5: CARDINAL← 0,
sixTo9: CARDINAL← 0,
tenTo29: CARDINAL← 0,
GEThirty: CARDINAL← 0
];
chainHead: TYPE = RECORD [ pi: ProbeIndex← 0, length: INTEGER← 0];
longOiChainsSummary: TYPE = ARRAY (0..5] OF chainHead;
RefCountsSummary: TYPE = RECORD
[ nRCEntries: RCEntriesSummary,
distribution: distributionSummary,
oiLengths: oiLengthsSummary,
firstNormalEntry: ProbeIndex← 0,
firstOiEntry: ProbeIndex← 0,
numOiInUse: INTEGER← 0,
longOiChains: longOiChainsSummary
];
chainEntries: TYPE = ARRAY (0..10] OF LONG POINTER;
OverflowChain: TYPE = RECORD [num: INTEGER← 0, cEntries: chainEntries];
mappirce: LONG POINTER TO AMapPiRce← RTRefCounts.GetMapPiRce[];
mapoioe: LONG POINTER TO AMapOiOe← RTRefCounts.GetMapOiOe[];
SummarizeCounts: PROC RETURNS[SummaryOfRefCounts: RefCountsSummary] =
BEGIN
firstNormalSeen: BOOLEAN← FALSE;
firstOiSeen: BOOLEAN← FALSE;
longOiIndex: INTEGER← 0;
lowestOi: INTEGER← LAST[INTEGER];
SummaryOfRefCounts← [,,,,,,];
FOR pi: ProbeIndex IN [0..LAST[ProbeIndex]] DO
{ rce: RCEntry ← mappirce[pi];
IF rce = rceEmpty THEN
SummaryOfRefCounts.nRCEntries.empty← SummaryOfRefCounts.nRCEntries.empty+1
ELSE
WITH rce: rce SELECT FROM
normal =>
{ SummaryOfRefCounts.nRCEntries.normal← SummaryOfRefCounts.nRCEntries.normal+1;
DoRCaccounting[@SummaryOfRefCounts, rce];
IF ~firstNormalSeen THEN {SummaryOfRefCounts.firstNormalEntry← pi; firstNormalSeen← TRUE};
};
overflow =>
{ len: INTEGER← 0;
oiFirst: MapOiOeIndex ← rce.oi;
pOe: LONG POINTER TO OverflowEntry;
oi: MapOiOeIndex ← oiFirst;
SummaryOfRefCounts.nRCEntries.overflow← SummaryOfRefCounts.nRCEntries.overflow+1;
IF ~firstOiSeen THEN {SummaryOfRefCounts.firstOiEntry← pi; firstOiSeen← TRUE};
DO
BEGIN
pOe← @mapoioe[oi];
len← len + 1;
DoRCaccounting[@SummaryOfRefCounts, pOe.rce];
WITH rce: pOe.oe1 SELECT FROM
normal => {len← len + 1; DoRCaccounting[@SummaryOfRefCounts, rce]; EXIT};
overflow => oi ← rce.oi;
ENDCASE;
END;
ENDLOOP;
SummaryOfRefCounts.numOiInUse← SummaryOfRefCounts.numOiInUse + len;
DoOiLengthAccounting[@SummaryOfRefCounts, len];
IF longOiIndex < 5 THEN
{ longOiIndex← longOiIndex+ 1;
SummaryOfRefCounts.longOiChains[longOiIndex]← [pi: pi, length: len];
IF len < lowestOi THEN lowestOi← len;
}
ELSE
{ IF len > lowestOi THEN
FOR i: INTEGER IN (0..5] DO
IF SummaryOfRefCounts.longOiChains[i].length = lowestOi THEN
{ SummaryOfRefCounts.longOiChains[i]← [pi: pi, length: len];
FOR j: INTEGER IN (i..5] DO
IF SummaryOfRefCounts.longOiChains[j].length = lowestOi THEN GO TO done; ENDLOOP;
lowestOi← len; EXIT;
};
REPEAT
done => NULL;
ENDLOOP;
};
};
ENDCASE;
};
ENDLOOP;
END;
FollowOiChain: PROC[pi: ProbeIndex] RETURNS[OiChain: OverflowChain] =
{ len: INTEGER← 0;
nrce: RCEntry← mappirce[pi];
pOe: LONG POINTER TO OverflowEntry;
oi: MapOiOeIndex;
OiChain← [,];
FOR i: INTEGER IN (0..10] DO OiChain.cEntries[i]← NIL; ENDLOOP;
WITH nrce: nrce SELECT FROM
overflow =>
{ oi← nrce.oi;
DO
{ pOe← @mapoioe[oi];
len← len + 1;
OiChain.cEntries[len]← LOOPHOLE[RcePiToRef[pOe.rce, pi], LONG POINTER];
IF len > 10 THEN EXIT;
WITH nrce: pOe.oe1 SELECT FROM
normal => -- end of chain
{ OiChain.cEntries[len]← LOOPHOLE[RcePiToRef[pOe.oe1, pi], LONG POINTER];
EXIT;
};
overflow => oi ← nrce.oi;
ENDCASE;
};
ENDLOOP;
};
ENDCASE;
OiChain.num← len;
};
DoRCaccounting: PROC[SummaryOfRefCounts: LONG POINTER TO RefCountsSummary, rce: RCEntry] =
{ nrce: nRCEntry← LOOPHOLE[rce, nRCEntry];
SELECT nrce.rc FROM
0,1,2 => SummaryOfRefCounts.distribution.LTrcFinalize←
SummaryOfRefCounts.distribution.LTrcFinalize+1;
rcFinalize => SummaryOfRefCounts.distribution.EQrcFinalize←
SummaryOfRefCounts.distribution.EQrcFinalize+1;
rcFinalize+1 => SummaryOfRefCounts.distribution.rcFinalizePlus1←
SummaryOfRefCounts.distribution.rcFinalizePlus1+1;
rcFinalize+2 => SummaryOfRefCounts.distribution.rcFinalizePlus2←
SummaryOfRefCounts.distribution.rcFinalizePlus2+1;
rcFinalize+3 => SummaryOfRefCounts.distribution.rcFinalizePlus3←
SummaryOfRefCounts.distribution.rcFinalizePlus3+1;
rcFinalize+4 => SummaryOfRefCounts.distribution.rcFinalizePlus4←
SummaryOfRefCounts.distribution.rcFinalizePlus4+1;
rcFinalize+5 => SummaryOfRefCounts.distribution.rcFinalizePlus5←
SummaryOfRefCounts.distribution.rcFinalizePlus5+1;
LAST[RefCt] => SummaryOfRefCounts.distribution.rcCountPegged←
SummaryOfRefCounts.distribution.rcCountPegged+1;
ENDCASE => SummaryOfRefCounts.distribution.rcFinalizePlus5Plus←
SummaryOfRefCounts.distribution.rcFinalizePlus5Plus+1;
};
DoOiLengthAccounting: PROC[SummaryOfRefCounts: LONG POINTER TO RefCountsSummary, len: INTEGER] =
{ SELECT len FROM
0,1,2 => SummaryOfRefCounts.oiLengths.two←
SummaryOfRefCounts.oiLengths.two+1;
IN [3..5] => SummaryOfRefCounts.oiLengths.threeTo5←
SummaryOfRefCounts.oiLengths.threeTo5+1;
IN [6..9] => SummaryOfRefCounts.oiLengths.sixTo9←
SummaryOfRefCounts.oiLengths.sixTo9+1;
IN [10..29] => SummaryOfRefCounts.oiLengths.tenTo29←
SummaryOfRefCounts.oiLengths.tenTo29+1;
ENDCASE => SummaryOfRefCounts.oiLengths.GEThirty←
SummaryOfRefCounts.oiLengths.GEThirty+1;
};
RefToPiRes: PROC[ref: LONG CARDINAL] RETURNS [pi: ProbeIndex, res: Residue] =
{ OPEN Inline;
res← RefToRes[ref];
pi← LOOPHOLE[BITXOR[BITSHIFT[LowHalf[ref],-1], res], ProbeIndex]};
RefToRes: PROC[ref: LONG CARDINAL] RETURNS [Residue] =
{ RETURN[Inline.HighHalf[ref]]};
RcePiToRef: PROC[rce: RCEntry, pi: ProbeIndex] RETURNS[REF] =
{ OPEN Inline;
nrce: nRCEntry← LOOPHOLE[rce, nRCEntry];
res: Residue = nrce.res;
RETURN[LOOPHOLE[LongNumber[num[highbits: res,
lowbits: BITSHIFT[BITXOR[pi, res], 1]]]]]};
PiToRef: PROC[pi: ProbeIndex] RETURNS[REF] =
{ rce: RCEntry ← mappirce[pi];
WITH rce SELECT FROM
normal => RETURN[RcePiToRef[rce, pi]];
ENDCASE => RETURN[NIL];
};
-- *****************************
SpecialSpace.MakeCodeResident[Runtime.GlobalFrame[SummarizeCounts]];
SpecialSpace.MakeGlobalFrameResident[RTRefAccounting];
END.