-- PcHot.mesa last edit, Bruce July 31, 1980 2:42 PM DIRECTORY Copier USING [Outer], DebugOps USING [ReadCodeWord, ShortREAD], DSyms USING [GFHandle, GFrameMdi], Frames USING [Invalid], Init USING [], Lf USING [GF, PC], MachineDefs USING [BYTE, FHandle, GFHandle, NullGF], Pc USING [BytePC, EVRange, NullPC], PcOps USING [BytePC, CacheBase, CacheCBtiCold, ConvertCbti, EpCold, EpToCBtiCold, FindUserCbti, Item, ItemNull, ParentCbtiCold], PrincOps USING [BytePC, EntryVectorItem, PrefixHeader, SVPointer], State USING [GetGS, GF, GSHandle, LF], Storage USING [Pages], Symbols USING [BTIndex, BTNull, CBTIndex, CBTNull, MDIndex, MDNull], SymbolTable USING [Base, Missing]; PcHot: PROGRAM IMPORTS Copier, DebugOps, DSyms, Frames, Lf, PcOps, State, Storage, SymbolTable EXPORTS Init, Pc, PcOps = BEGIN OPEN PcOps, PrincOps, Symbols; NoBti: ERROR = CODE; BadReason: ERROR = CODE; FHandle: TYPE = MachineDefs.FHandle; GFHandle: TYPE = MachineDefs.GFHandle; EVRange: TYPE = Pc.EVRange; data: State.GSHandle _ State.GetGS[]; cache: PUBLIC CacheBase _ Storage.Pages[1]; Head, Free: PUBLIC Item; Enumerate: PROC [proc: PROC [Item] RETURNS [BOOLEAN], gf: GFHandle] RETURNS [i: Item] = BEGIN next, last: Item; FOR i _ Head, cache[i].link UNTIL i = ItemNull DO IF cache[i].gf = gf AND proc[i] THEN BEGIN IF i = Head THEN RETURN; cache[last].link _ cache[i].link; cache[i].link _ Head; Head _ i; RETURN END; last _ i; ENDLOOP; IF Free # ItemNull THEN RETURN; FOR i _ Head, next UNTIL i = last DO IF (next _ cache[i].link) # last THEN LOOP; cache[i].link _ ItemNull; cache[last].link _ Free; Free _ next; RETURN[ItemNull]; ENDLOOP; END; FindEp: PUBLIC PROC [ep: EVRange, gf: GFHandle] RETURNS [Item] = BEGIN Find: PROC [i: Item] RETURNS [BOOLEAN] = {RETURN[ep = cache[i].ep]}; RETURN[Enumerate[Find, gf]]; END; FindUserCbti: PUBLIC PROC [gf: GFHandle, cbti: CBTIndex] RETURNS [Item] = { Find: PROC [i: Item] RETURNS [BOOLEAN] = { RETURN[gf = cache[i].gf AND cbti = cache[i].userCbti]}; RETURN[Enumerate[Find, gf]]}; FindPC: PROC [pc: BytePC, gf: GFHandle] RETURNS [Item] = BEGIN Find: PROC [i: Item] RETURNS [BOOLEAN] = BEGIN RETURN[ Card[pc] >= Card[cache[i].start] AND Card[pc] <= Card[cache[i].end]] END; RETURN[Enumerate[Find, gf]]; END; FindCbti: PUBLIC PROC [cbti: CBTIndex] RETURNS [i: Item] = BEGIN FOR i _ Head, cache[i].link UNTIL i = ItemNull DO IF cache[i].dCbti = cbti THEN RETURN; ENDLOOP; END; GetPc: PUBLIC PROC [gf: GFHandle, i: EVRange] RETURNS [pc: BytePC] = BEGIN OPEN PrincOps; -- CSegP: TYPE = POINTER TO MachineDefs.CSegPrefix; -- gf, LOOPHOLE[@LOOPHOLE[0,CSegP].entry[i].initialpc]]; InitialPcOffset: CARDINAL = 0; pc _ DebugOps.ReadCodeWord[ gf, SIZE[PrefixHeader]+i*SIZE[EntryVectorItem]+InitialPcOffset]; RETURN[[pc*2]]; END; EvalStackEmpty: PUBLIC PROCEDURE [sp: PrincOps.SVPointer _ NIL] RETURNS [BOOLEAN] = BEGIN SV: TYPE = RECORD [inst,ptr: MachineDefs.BYTE]; sv: SV; IF sp = NIL THEN sp _ data.StatePtr; IF sp = NIL THEN RETURN[TRUE]; sv _ DebugOps.ShortREAD[sp+8]; -- yech RETURN [sv.ptr = 0] END; Son: PUBLIC PROC [cbti: CBTIndex] RETURNS [BOOLEAN] = BEGIN i: Item _ FindCbti[cbti]; IF i = ItemNull THEN ERROR NoBti; RETURN [cache[i].hasSons]; END; Ep: PUBLIC PROC [pc: BytePC, gf: GFHandle] RETURNS [ep: EVRange, start: BytePC] = BEGIN old: Item _ FindPC[pc, gf]; IF old # ItemNull THEN {ep _ cache[old].ep; start _ cache[old].start} ELSE [ep,start] _ PcOps.EpCold[pc,gf]; RETURN; END; EpToCBti: PUBLIC PROC [ ep: EVRange, gf: GFHandle, start: BytePC _ Pc.NullPC] RETURNS [cbti: CBTIndex] = BEGIN old: Item = FindEp[ep, gf]; RETURN[IF old # ItemNull THEN cache[old].dCbti ELSE PcOps.EpToCBtiCold[ep,gf,start]]; END; CacheCBti: PUBLIC PROC [mdi: MDIndex, gf: GFHandle, cbti: CBTIndex] RETURNS [CBTIndex] = BEGIN i: Item = PcOps.FindUserCbti[gf,cbti]; IF i # ItemNull THEN RETURN[cache[i].dCbti]; RETURN[CacheCBtiCold[mdi,gf,cbti]]; END; Fixup: PROC [pc: BytePC, gf: GFHandle] RETURNS [BytePC, GFHandle] = BEGIN IF gf = NIL THEN gf _ State.GF[]; IF pc = Pc.NullPC THEN pc _ GetPc[gf,0]; RETURN[pc,gf]; END; ParentCbti: PUBLIC PROC [pc: BytePC, gf: GFHandle] RETURNS [old: Item, mdi: MDIndex] = BEGIN old _ FindPC[pc,gf]; mdi _ DSyms.GFrameMdi[gf ! SymbolTable.Missing, Frames.Invalid => GOTO noSyms]; IF old = ItemNull THEN old _ PcOps.ParentCbtiCold[pc,gf,mdi]; RETURN; EXITS noSyms => {mdi _ Symbols.MDNull; RETURN}; END; Bti: PUBLIC PROC [pc: BytePC _ Pc.NullPC, gf: GFHandle _ MachineDefs.NullGF] RETURNS [bti: BTIndex] = BEGIN mdi: MDIndex; lpc: BytePC; lgf: GFHandle; i: Item; ClosestBti: PROC [base: SymbolTable.Base] = { bti _ PcOps.ConvertCbti[bti,pc,cache[i].start,base]}; [lpc,lgf] _ Fixup[pc,gf]; [i,mdi] _ ParentCbti[lpc,lgf]; IF mdi = Symbols.MDNull OR i = ItemNull THEN RETURN[BTNull]; IF (bti _ cache[i].userCbti) = BTNull THEN RETURN; IF ~cache[i].hasSons THEN RETURN; Copier.Outer[mdi,ClosestBti]; END; CBti: PUBLIC PROC [ pc: BytePC _ Pc.NullPC, gf: GFHandle _ MachineDefs.NullGF] RETURNS [cbti: CBTIndex] = BEGIN lpc: BytePC; lgf: GFHandle; i: Item; [lpc,lgf] _ Fixup[pc,gf]; IF (i _ ParentCbti[lpc, lgf].old) = ItemNull THEN RETURN[CBTNull]; RETURN[cache[i].dCbti]; END; EntryPC: PUBLIC PROC [ep: EVRange, gf: GFHandle, noSyms: BOOLEAN _ FALSE] RETURNS [pc: BytePC] = BEGIN pc _ GetPc[gf,ep]; END; ExitPC: PUBLIC PROC [cbti: CBTIndex] RETURNS [BytePC] = { i: Item = FindCbti[cbti]; IF i # ItemNull THEN RETURN[cache[i].end] ELSE ERROR SymbolTable.Missing[NIL]}; CbtiItem: PROC [f: FHandle, pc: BytePC] RETURNS [Item, BytePC] = BEGIN SELECT TRUE FROM f = NIL => BEGIN f _ State.LF[]; pc _ Lf.PC[f] END; pc = Pc.NullPC => pc _ Lf.PC[f]; ENDCASE; RETURN[FindCbti[CBti[pc, Lf.GF[f]]], pc]; END; Entry: PUBLIC PROCEDURE [ f: FHandle _ NIL, pc: BytePC _ Pc.NullPC] RETURNS [BOOLEAN] = BEGIN i: Item; [i,pc] _ CbtiItem[f,pc]; IF i = ItemNull THEN ERROR SymbolTable.Missing[NIL]; RETURN[(cache[i].start = pc) OR (cache[i].inner AND Card[cache[i].start]+2 = Card[pc])]; END; Exit: PUBLIC PROCEDURE [ f: FHandle _ NIL, pc: BytePC _ Pc.NullPC] RETURNS [BOOLEAN] = BEGIN i: Item; [i,pc] _ CbtiItem[f,pc]; IF i = ItemNull THEN ERROR SymbolTable.Missing[NIL]; RETURN[cache[i].end = pc]; END; Card: PROC [pc: BytePC] RETURNS [CARDINAL] = INLINE {RETURN[LOOPHOLE[pc]]}; END.