SpyOps.mesa
Copyright © 1985, 1986 by Xerox Corporation. All rights reserved.
Maxwell September 19, 1983 9:21 am
Russ Atkinson (RRA) February 16, 1987 11:51:34 am PST
Pier, December 12, 1985 10:37:38 am PST
McCreight, April 11, 1986 2:16:04 pm PST
Mike Spreitzer September 19, 1986 9:03:36 pm PDT
Eric Nickell, November 25, 1986 2:38:01 pm PST
DIRECTORY
BasicTime USING [Pulses],
FastBreak USING [FastBreakProc],
IO USING [STREAM],
PrincOps USING [BytePC, FrameHandle, GlobalFrameHandle, PsbIndex],
Process USING [GetCurrent, Priority],
Rope USING [ROPE],
SpyClient USING [DataType, StackType];
SpyOps: DEFINITIONS IMPORTS Process = BEGIN OPEN IO, Rope;
SpyKernel procedures and data structures
StartCounting: FastBreak.FastBreakProc;
StopCounting: FastBreak.FastBreakProc;
Record: PROC [
psbi: PrincOps.PsbIndex ← LOOPHOLE[Process.GetCurrent[]],
frame: PrincOps.FrameHandle ← NIL,
type: StackType ← ready,
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;
freqDivisor: READONLY NAT;
statistics
runningTime: BasicTime.Pulses;
active, starts, stops: INTEGER;
pageFaults: CARD;
wordsAllocated: CARD;
wordsReclaimed: CARD;
wakeups, notScheduled, skips: Count;
levelData: LevelData;
data types
DataType: TYPE = SpyClient.DataType;
SpyState: TYPE = {off, on, disabled};
Stack: TYPE = RECORD [
process: PrincOps.PsbIndex,
level: Process.Priority,
type: StackType,
count: CARDINAL,
frame: ARRAY [0..stackLength) OF Frame];
stackLength: CARDINAL = 200;
stackHeader: CARDINAL = Stack.SIZE - stackLength*Frame.SIZE;
StackType: TYPE = SpyClient.StackType;
Frame: TYPE = RECORD [
gfh: PrincOps.GlobalFrameHandle,
pc: PrincOps.BytePC];
Count: TYPE = INT;
LevelData: TYPE = ARRAY Process.Priority OF Count;
SpyBreaks procedures
PrintBreaks: PROC [typescript: STREAM];
SetAllocationBreak: PROC RETURNS[msg: ROPE];
ClearAllocationBreak: PROC;
SpyLogReader procedures
ZeroLog: PROC;
DestroyLog: PROC;
ReadLog: PROC [typescript: STREAM, datatype: DataType, spyOnSpyLog: BOOLFALSE];
PrintCount: PROC [stream: STREAM, c, sonC: Count, total: Count];
PerCent: PROC [stream: STREAM, x, y: Count]; -- prints x/y as "(dd.d%)"
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: BOOLFALSE,
marked: BOOLFALSE, -- bit for procedures that walk the stack
named: BOOLFALSE, -- have we appended the name of the procedure?
symbols: BOOLTRUE, -- are the symbols available?
gfh: PrincOps.GlobalFrameHandle ← NIL, -- gfh 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
countLocs: LIST OF Call ← NIL, --counts of locs in this proc
S(.countLocs.*.calls)=(.count) and (.countLocs.*.proc)=NIL
sons: LIST OF Call ← NIL]; -- procedures called from here
Call: TYPE = RECORD [
pc: CARDINAL ← 0,
calls: Count ← 0,
proc: Procedure ← NIL];
END . .