SpyOps.mesa
edited by: Maxwell September 19, 1983 9:21 am
DIRECTORY
BasicTime USING [Pulses],
FastBreak USING [FastBreakProc],
IO USING [STREAM],
PrincOps USING [BytePC, FrameHandle, GFT, GFTIndex, GlobalFrameHandle, PsbIndex],
Process USING [GetCurrent, Priority],
Rope USING [ROPE],
SpyClient USING [DataType, StackType];
SpyOps: DEFINITIONS IMPORTS Process = BEGIN
ROPE: TYPE = Rope.ROPE;
**********************************************************
SpyKernel procedures and data structures
**********************************************************
StartCounting: FastBreak.FastBreakProc;
StopCounting: FastBreak.FastBreakProc;
Record: PROCEDURE[
psbi: PrincOps.PsbIndex ← LOOPHOLE[Process.GetCurrent[]],
frame: PrincOps.FrameHandle ← NIL,
type: StackType ← 0,
count: CARDINAL ← 1];
UserBreak: FastBreak.FastBreakProc; -- calls Record
AllocationBreak: FastBreak.FastBreakProc; -- calls Record
current parameters
spyState: READONLY SpyState;
watching: READONLY DataType;
justMe: READONLY PrincOps.PsbIndex;
statistics
runningTime: BasicTime.Pulses;
active, starts, stops: INTEGER;
pageFaults: LONG CARDINAL;
wordsAllocated: LONG CARDINAL;
wordsReclaimed: LONG CARDINAL;
wakeups, notScheduled, skips: Count;
levelData: LevelData;
data types
DataType: TYPE = SpyClient.DataType;
SpyState: TYPE = {off, on, disabled};
Stack: TYPE = MACHINE DEPENDENT RECORD [
process: PrincOps.PsbIndex,
level: Process.Priority,
type: StackType,
count: CARDINAL,
frame: ARRAY [0..stackLength) OF Frame];
stackLength: CARDINAL = 75;
stackHeader: CARDINAL = Stack.SIZE - stackLength*Frame.SIZE;
StackType: TYPE = SpyClient.StackType;
Frame: TYPE = MACHINE DEPENDENT RECORD[
unused: CARDINAL [0..64),
gfi: PrincOps.GFTIndex, pc: PrincOps.BytePC];
Count: TYPE = INT;
LevelData: TYPE = ARRAY Process.Priority OF Count;
**********************************************************
SpyBreaks and SpyLogReader
**********************************************************
-- SpyBreaks procedures --
PrintBreaks: PROCEDURE[typescript: IO.STREAM];
SetAllocationBreak: PROCEDURE RETURNS[msg: ROPE];
ClearAllocationBreak: PROCEDURE;
-- SpyLogReader procedures --
ZeroLog: PROCEDURE;
DestroyLog: PROCEDURE;
ReadLog: PROCEDURE[typescript: IO.STREAM, datatype: DataType, spyOnSpyLog: BOOLFALSE];
processes: LIST OF ProcessRef;
modules: LIST OF Procedure;
ProcessRef: TYPE = REF ProcessRec;
ProcessRec: TYPE = RECORD[
psb: PrincOps.PsbIndex ← 0,
level: PACKED ARRAY [0..4] OF Process.Priority ← ALL[0],
calls: Count ← 0,
sons: LIST OF Call ← NIL];
Procedure: TYPE = REF ProcRec;
ProcRec: TYPE = RECORD [
unused: BOOLEANFALSE,
marked: BOOLEANFALSE, -- bit for procedures that walk the stack
named: BOOLEANFALSE, -- have we appended the name of the procedure?
symbols: BOOLEANTRUE, -- are the symbols available?
gfi: PrincOps.GFTIndex ← 0, -- gfi for this procedure
name: ROPENIL, -- the name of the procedure
entryPC: CARDINAL ← 0,
exitPC: CARDINALLAST[CARDINAL],
refs: CARDINAL ← 0, -- number of procedures that call this one
count: Count ← 0, -- counts in this procedure
calls: Count ← 0, -- counts in procedures called by this one
container: Procedure ← NIL, -- the procedure that contains all calls to this one
parents: LIST OF Procedure ← NIL, -- procedures that call this one
sons: LIST OF Call ← NIL]; -- procedures called from here
Call: TYPE = RECORD[
pc: CARDINAL ← 0,
calls: Count ← 0,
proc: Procedure ← NIL];
GFHFromGFI: PROCEDURE[gfi: PrincOps.GFTIndex]
RETURNS[PrincOps.GlobalFrameHandle] = INLINE
{RETURN[PrincOps.GFT[gfi].framePtr]};
END . .