-- 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.