(FILECREATED "15-Jan-85 22:00:28" {ERIS}<LISPCORE>LIBRARY>SNOOPY.;67 52526 changes to: (FNS \SAS.INCREMENT.STATS) previous date: " 4-Jan-85 23:45:06" {ERIS}<LISPCORE>LIBRARY>SNOOPY.;66) (* Copyright (c) 1984, 1985 by Xerox Corporation. All rights reserved.) (PRETTYCOMPRINT SNOOPYCOMS) (RPAQQ SNOOPYCOMS ((COMS (* "A lot is used from ABC environment") (DECLARE: EVAL@COMPILE DONTEVAL@LOAD DONTCOPY (P (OR (AND (GETP (QUOTE EXPORTS.ALL) (QUOTE FILE)) (OR (INTERSECTION FILELST (QUOTE (SYSEDIT ABC))))) (HELP (QUOTE ABC))))) (* "Some items culled from LLARRAYELT") (DECLARE: EVAL@COMPILE DONTCOPY (GLOBALVARS \ArraryFrLst)) (* "More items culled from LLFAULT") (DECLARE: EVAL@COMPILE DONTCOPY (PROP DOPVAL TIMES3) (RECORDS VMEMFLAGS RPT) (CONSTANTS \VMAP.DIRTY \VMAP.CLEAN \VMAP.REF \VMAP.VACANT \VMAP.FLAGS) (CONSTANTS \RPT.EMPTY \RPT.UNAVAILABLE \PAGETABLESTOPFLG \RPTENTRYLENGTH) (CONSTANTS \MAXVMPAGE \MAXVMSEGMENT) (GLOBALVARS \REALPAGETABLE \RPTSIZE))) (INITVARS (SNOOPY.ARRAYBLOCKSIZES (QUOTE (1 2 3 4 5 6 7 8 9 10 12 14 16 20 24 28 32 40 48 64 84 128 256 512 1024 2048 4096 8192 16384 NIL))) (SNOOPY.CODEBLOCKSIZES (QUOTE (12 16 20 24 28 32 36 42 50 64 128 256 512 1024 2048 NIL))) (SNOOPY.PTRBLOCKSIZES (QUOTE (4 5 6 7 8 10 12 16 24 32 42 64 128 256 512 1024 2048 4096 8192 16384 NIL))) (SNOOPY.STKMINSIZES (QUOTE (20 24 28 32 36 40 44 48 52 NIL))) (SNOOPY.INITONPAGESIZES (QUOTE (8 10 12 14 16 20 24 28 32 36 40 48 56 64 72 80 90 100 120 NIL))) (SNOOPY.CODEREMNANTS) (SNOOPY.DEFAULT.OUTFILE (QUOTE <LISPSTATS>USERDATE.HISTOGRAPHS)) (MAX.CELLSPERHUNK 64)) (GLOBALVARS SNOOPY.ARRAYBLOCKSIZES SNOOPY.CODEBLOCKSIZES SNOOPY.PTRBLOCKSIZES SNOOPY.STKMINSIZES SNOOPY.INITONPAGESIZES SNOOPY.CODEREMNANTS SNOOPY.DEFAULT.OUTFILE MAX.CELLSPERHUNK) (FNS SHOW.HISTOGRAPHS SHOW.ALL.HISTOGRAPHS \SAS.SHOWINIT \SAS.STORAGE) (COMS (* "Snooping on real memory usage") (FNS SHOW.REALMEMORY.HISTOGRAPHS \SAS.CHECKMEMSTATSARRAY \SAS.GATHER.REALMEMSTATS \SAS.PRINT.REALMEMSTATS) (INITVARS (\MEMUSAGE.STATS)) (GLOBALVARS \MEMUSAGE.STATS)) (COMS (* "Showing data about ARRAYBLOCK sizes") (FNS SHOW.ARRAYBLOCK.HISTOGRAPHS \SAS.CODEBLOCKSTATS \SAS.INDEXINLIST \SAS.INCREMENT.STATS \SAS.HUNKABLE.SIZE \SAS.CALCFRAGCOEFF) (INITVARS (USEDBLOCKS.FREQ) (USEDBLOCKS.CONSUMPTION) (USEDHUNKS.CONSUMPTION) (FREEBLOCKS.FREQ) (FREEBLOCKS.CONSUMPTION) (CODEBLOCKS.FREQ) (CODEBLOCKS.CONSUMPTION) (CODEHUNKS.CONSUMPTION) (PTRBLOCKS.FREQ) (PTRBLOCKS.CONSUMPTION) (PTRHUNKS.CONSUMPTION) (STKMINS.FREQ) (INITONPAGE.FREQ) (INITONPAGE.PERCENT) (STRADDLERMISSES.FREQ) (AUSE.TIMER (SETUPTIMER 0 NIL (QUOTE TICKS)))) (DECLARE: EVAL@COMPILE DONTCOPY (RECORDS CODEARRAYBLOCK)) (GLOBALVARS USEDBLOCKS.FREQ USEDHUNKS.CONSUMPTION FREEBLOCKS.FREQ FREEBLOCKS.CONSUMPTION USEDBLOCKS.CONSUMPTION CODEBLOCKS.FREQ CODEBLOCKS.CONSUMPTION CODEHUNKS.CONSUMPTION PTRBLOCKS.FREQ PTRBLOCKS.CONSUMPTION PTRHUNKS.CONSUMPTION STKMINS.FREQ INITONPAGE.FREQ INITONPAGE.PERCENT STRADDLERMISSES.FREQ AUSE.TIMER) (FNS \SAS.INITIALIZE.STATSARRAYS \SAS.INITIALIZE.PNAMEARRAYS \SAS.INITIALIZEARRAY \SAS.INITIALIZE.CHECKSIZESLST \SAS.NULLORFIXP)) (COMS (* "Snooping on LITATOM and STRINGP statistics") (INITVARS (PNAMEHUNKS.CONSUMPTION)) (GLOBALVARS PNAMEHUNKS.CONSUMPTION) (FNS SHOW.LITATOM.HISTOGRAPHS \SAS.COLLECTLITATOMSTATS \SAS.PRINTLITATOMCELLS \SAS.PRINTLITATOMPNAMES SHOW.STRINGP.HISTOGRAPHS \SAS.INITIALIZE.PNAMESTATS) (GLOBALVARS PNAME.FREQ PNAME.CONSUMPTION VCELLS.FREQ VCELLS.CONSUMPTION)) (FILES (SYSLOAD COMPILED FROM LISPUSERS) CMLARRAY GCHAX) (DECLARE: DONTEVAL@COMPILE DONTEVAL@LOAD DOCOPY (P (\SAS.INITIALIZE.STATSARRAYS))) (COMS (DECLARE: EVAL@COMPILE DONTCOPY (MACROS FORMFEED)) (* "Related to format of statistics printout") (FNS \SAS.PRINTSECTIONHEADER \SAS.STATSOUT) (INITVARS (\SAS.LINEDIVIDER "------------------------------------------------------------------") (\SAS.1-Aug-84% 00:00 490160752)) (* "Random date offset, to make default unique file names shorter") (GLOBALVARS \SAS.LINEDIVIDER \SAS.1-Aug-84% 00:00)) (LOCALVARS . T))) (* "A lot is used from ABC environment") (DECLARE: EVAL@COMPILE DONTEVAL@LOAD DONTCOPY (OR (AND (GETP (QUOTE EXPORTS.ALL) (QUOTE FILE)) (OR (INTERSECTION FILELST (QUOTE (SYSEDIT ABC))))) (HELP (QUOTE ABC))) ) (* "Some items culled from LLARRAYELT") (DECLARE: EVAL@COMPILE DONTCOPY (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS \ArraryFrLst) ) ) (* "More items culled from LLFAULT") (DECLARE: EVAL@COMPILE DONTCOPY (PUTPROPS TIMES3 DOPVAL (1 COPY LLSH1 IPLUS2)) [DECLARE: EVAL@COMPILE (ACCESSFNS VMEMFLAGS ((VACANT (EQ (LOGAND DATUM \VMAP.VACANT) \VMAP.VACANT)) (DIRTY (NEQ (LOGAND DATUM \VMAP.DIRTY) 0)) (REFERENCED (NEQ (LOGAND DATUM \VMAP.REF) 0)))) (BLOCKRECORD RPT ((NEXTRP WORD) (* rp of next entry in page chain) (VP WORD) (* Virtual page number occupying this real page) (LOCKED FLAG) (FILEPAGE BITS 15) (* Page in Lisp.VirtualMem) ) (BLOCKRECORD RPT ((NIL WORD) (UNOCCUPIEDVPBITS BITS 2) (VPONLY BITS 14) (FILEPAGE&LOCK WORD))) (ACCESSFNS RPT ((RPTRBASE (\ADDBASE \REALPAGETABLE (TIMES3 DATUM))) (EMPTY (EQ (fetch (RPT VP) of DATUM) \RPT.EMPTY) (COND (NEWVALUE (replace (RPT VP) of DATUM with \RPT.EMPTY)) (T (ERROR "Invalid replace of RPT.EMPTY" DATUM)))) (UNAVAILABLE (EQ (fetch (RPT VP) of DATUM) \RPT.UNAVAILABLE) (COND (NEWVALUE (replace (RPT VP) of DATUM with \RPT.UNAVAILABLE)) (T (ERROR "Invalid replace of RPT.UNAVAILABLE" DATUM)))) (OCCUPIED (ZEROP (fetch (RPT UNOCCUPIEDVPBITS) of DATUM))))) (* Given a RP, RPTRBASE produces a pointer to its entry in the real page table) ) ] (DECLARE: EVAL@COMPILE (RPAQQ \VMAP.DIRTY 4096) (RPAQQ \VMAP.CLEAN 0) (RPAQQ \VMAP.REF 32768) (RPAQQ \VMAP.VACANT 12288) (RPAQQ \VMAP.FLAGS 61440) (CONSTANTS \VMAP.DIRTY \VMAP.CLEAN \VMAP.REF \VMAP.VACANT \VMAP.FLAGS) ) (DECLARE: EVAL@COMPILE (RPAQQ \RPT.EMPTY 16384) (RPAQQ \RPT.UNAVAILABLE 16640) (RPAQQ \PAGETABLESTOPFLG 0) (RPAQQ \RPTENTRYLENGTH 3) (CONSTANTS \RPT.EMPTY \RPT.UNAVAILABLE \PAGETABLESTOPFLG \RPTENTRYLENGTH) ) (DECLARE: EVAL@COMPILE (RPAQQ \MAXVMPAGE 16383) (RPAQQ \MAXVMSEGMENT 63) (CONSTANTS \MAXVMPAGE \MAXVMSEGMENT) ) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS \REALPAGETABLE \RPTSIZE) ) ) (RPAQ? SNOOPY.ARRAYBLOCKSIZES (QUOTE (1 2 3 4 5 6 7 8 9 10 12 14 16 20 24 28 32 40 48 64 84 128 256 512 1024 2048 4096 8192 16384 NIL))) (RPAQ? SNOOPY.CODEBLOCKSIZES (QUOTE (12 16 20 24 28 32 36 42 50 64 128 256 512 1024 2048 NIL))) (RPAQ? SNOOPY.PTRBLOCKSIZES (QUOTE (4 5 6 7 8 10 12 16 24 32 42 64 128 256 512 1024 2048 4096 8192 16384 NIL))) (RPAQ? SNOOPY.STKMINSIZES (QUOTE (20 24 28 32 36 40 44 48 52 NIL))) (RPAQ? SNOOPY.INITONPAGESIZES (QUOTE (8 10 12 14 16 20 24 28 32 36 40 48 56 64 72 80 90 100 120 NIL))) (RPAQ? SNOOPY.CODEREMNANTS ) (RPAQ? SNOOPY.DEFAULT.OUTFILE (QUOTE <LISPSTATS>USERDATE.HISTOGRAPHS)) (RPAQ? MAX.CELLSPERHUNK 64) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS SNOOPY.ARRAYBLOCKSIZES SNOOPY.CODEBLOCKSIZES SNOOPY.PTRBLOCKSIZES SNOOPY.STKMINSIZES SNOOPY.INITONPAGESIZES SNOOPY.CODEREMNANTS SNOOPY.DEFAULT.OUTFILE MAX.CELLSPERHUNK) ) (DEFINEQ (SHOW.HISTOGRAPHS (LAMBDA (FILE TITLE) (* JonL "20-Nov-84 23:11") (DECLARE (SPECVARS FILE)) (RESETLST (\SAS.SHOWINIT) (\SAS.PRINTLITATOMCELLS FILE T) (\SAS.CALCFRAGCOEFF FILE) (FORMFEED FILE) (\SAS.STORAGE FILE 100)))) (SHOW.ALL.HISTOGRAPHS (LAMBDA (FILE TITLE) (* JonL " 4-Jan-85 23:36") (DECLARE (SPECVARS FILE TITLE)) (RESETLST (\SAS.SHOWINIT) (\SAS.COLLECTLITATOMSTATS) (\SAS.PRINTLITATOMCELLS FILE) (FORMFEED FILE) (\SAS.PRINTLITATOMPNAMES FILE) (SHOW.STRINGP.HISTOGRAPHS FILE) (FORMFEED FILE) (SHOW.ARRAYBLOCK.HISTOGRAPHS FILE) (FORMFEED FILE) (\SAS.STORAGE FILE)))) (\SAS.SHOWINIT (LAMBDA NIL (* JonL " 4-Jan-85 23:36") (* * Before doing anything else, capture the "pages-in-core" statistics, and then print them out after setup. Sets the freevar FILE, and also puts out minimal GC statistics.) (DECLARE (USEDFREE FILE TITLE)) (PROG ((REALMEMSTATS (\SAS.GATHER.REALMEMSTATS))) (RESETSAVE (RADIX 10)) (RESETSAVE (SETQ FILE (OPENFILE (PACKFILENAME (QUOTE BODY) FILE (QUOTE NAME) (PACK* (SUBSTRING USERNAME 1 (PROG NIL (RETURN (SUB1 (OR (FIXP (STRPOS "." USERNAME)) (RETURN)))))) (IDIFFERENCE (IDATE) \SAS.1-Aug-84% 00:00)) (QUOTE BODY) SNOOPY.DEFAULT.OUTFILE) (QUOTE OUTPUT))) (QUOTE (PROGN (CLOSEF? OLDVALUE) (AND (INFILEP OLDVALUE) RESETSTATE (DELFILE OLDVALUE))))) (if TITLE then (\SAS.PRINTSECTIONHEADER TITLE FILE) (printout FILE T T)) (RADIX 8) (printout FILE T "**** SNOOPY statistics for user " USERNAME ", on " (GDATE) .TAB 20 "Machine: " .TAB 40 (OR (ETHERHOSTNAME) (AND (type? NSADDRESS \MY.NSADDRESS) (\PRINTNSADDRESS \MY.NSADDRESS FILE)) (ETHERHOSTNUMBER)) " (" (L-CASE (MACHINETYPE) T) ")" .TAB 20 "Microcode Version: " .TAB 40 (QUOTE %[) (LOADBYTE (MICROCODEVERSION) 8 8) ", " (LOADBYTE (MICROCODEVERSION) 0 8) (QUOTE %]) .TAB 20 "Memory Size: " .TAB 40 (REALMEMORYSIZE) (QUOTE Q) .TAB 20 "Lisp System Date: " .TAB 40 MAKESYSDATE -2 (QUOTE %() (OR (AND (BOUNDP (QUOTE MAKESYSNAME)) MAKESYSNAME) "No MAKESYSNAME") (QUOTE %)) .TAB 20 "LLARRAYELT date:" .TAB 40 (CAAR (GETP (QUOTE LLARRAYELT) (QUOTE FILEDATES))) T T T) (RADIX 10) (TERPRI FILE) (\SAS.PRINT.REALMEMSTATS FILE REALMEMSTATS) (PROG ((COLLS (PROGN (FRPTQ 20 (RECLAIM)) (\#COLLISIONS)))) (\SAS.PRINTSECTIONHEADER "GC Hash Table: Number of Entries and Collisions" FILE) (printout FILE T "Number of entries: " .TAB 24 .I5 (CAR COLLS) ", " .F5.1 (TIMES 100.0 (CADDR COLLS)) "%% in collision chains." T T))))) (\SAS.STORAGE (LAMBDA (FILE PAGETHRESHOLD) (* JonL "20-Nov-84 23:11") (RESETLST (RESETSAVE STORAGE.ARRAYSIZES SNOOPY.ARRAYBLOCKSIZES) (RESETSAVE (OUTPUT FILE)) (\SAS.PRINTSECTIONHEADER "Printout by STORAGE Function") (TERPRI) (TERPRI) (STORAGE NIL PAGETHRESHOLD) (TERPRI)))) ) (* "Snooping on real memory usage") (DEFINEQ (SHOW.REALMEMORY.HISTOGRAPHS (LAMBDA (FILE TYPES) (* JonL "15-Sep-84 16:36") (\SAS.PRINT.REALMEMSTATS FILE (\SAS.GATHER.REALMEMSTATS TYPES)))) (\SAS.CHECKMEMSTATSARRAY (LAMBDA NIL (* JonL "15-Sep-84 16:54") (if (AND (type? CMLARRAY \MEMUSAGE.STATS) (EQUAL (QUOTE (MOD 65536)) (ARRAYELEMENTTYPE \MEMUSAGE.STATS)) (EQ 2 (ARRAYRANK \MEMUSAGE.STATS)) (EQ 5 (ARRAYDIMENSION \MEMUSAGE.STATS 1)) (ILEQ 20 (ARRAYDIMENSION \MEMUSAGE.STATS 0))) then (* Lookin' good!) else (SETQ \MEMUSAGE.STATS (MAKEARRAY (QUOTE (20 5)) (QUOTE ELEMENTTYPE) (QUOTE (MOD 65536))))) T)) (\SAS.GATHER.REALMEMSTATS (LAMBDA (TYPES) (* JonL "18-Sep-84 04:57") (\SAS.CHECKMEMSTATSARRAY) (* The array should have been set up before now, but just in case ...) (OR (LISTP TYPES) (SETQ TYPES (QUOTE (LISTP)))) (PROG ((NTYPES (LENGTH TYPES)) (ROW.INDEX 0) (RP 0) (#LOCKEDPAGES 0) (#AVAILABLEPAGES 0) (HTMAINHI (\HILOC \HTMAIN)) (HTCOLHI (\HILOC \HTCOLL)) (DISPHI (\HILOC \DISPLAYREGION)) (TTHI (\HILOC \MDSTypeTable)) (PMAPHI (\HILOC \PageMapTBL)) (SPMAPHI (\HILOC \PAGEMAP)) TN.TO.ROWINDEX COL.INDEX OTHERDATATYPESROW LITATOMROW STACKROW GCHASH&TYPE.ROW PMAPROW SCREENBITMAPROW UNRECOGNIZEDTYPEROW) (* Column indices on this array are -- 0 is the datatype typenumber, 1 is the number of "present-but-unreferenced" pages for this type, 2 is the number of "read-referenced-only" pages, 3 is the number of "dirty" pages, and 4 is the number of pages with "unknown" map entries.) (* Row indices are: 0'th row is for unknown datatype, n+1'th row is for ARRAYBLOCKs, 1 thru n are for the n datatype numbers found in the TYPES list.) (OR (ILEQ (IPLUS 5 NTYPES) (ARRAYDIMENSION \MEMUSAGE.STATS 0)) (SETQ \MEMUSAGE.STATS (MAKEARRAY (LIST (IPLUS 10 NTYPES) 5) (QUOTE ELEMENTTYPE) (QUOTE (MOD 65536))))) (FILLARRAY \MEMUSAGE.STATS 0) (SETQ TN.TO.ROWINDEX (MAPCONC TYPES (FUNCTION (LAMBDA (X) (if (EQ X (QUOTE ARRAYBLOCK)) then NIL else (PROG ((TYPENO (if (AND (FIXP X) (IGREATERP X 0) (ILEQ X \MaxTypeNumber)) then X elseif (AND (LITATOM X) (FIXP (\TYPENUMBERFROMNAME X))) else (ERROR "Not coercible into a datatype" X)))) (add ROW.INDEX 1) (16ASET TYPENO \MEMUSAGE.STATS ROW.INDEX 0) (RETURN (LIST (CONS TYPENO ROW.INDEX))))))))) (16ASET MAX.SMALLP \MEMUSAGE.STATS 0 0) (* Row zero is reserved for arrayblocks whether or not it is used.) (SETQ OTHERDATATYPESROW (add ROW.INDEX 1)) (SETQ LITATOMROW (add ROW.INDEX 1)) (SETQ STACKROW (add ROW.INDEX 1)) (SETQ GCHASH&TYPE.ROW (add ROW.INDEX 1)) (SETQ PMAPROW (add ROW.INDEX 1)) (SETQ SCREENBITMAPROW (add ROW.INDEX 1)) (SETQ UNRECOGNIZEDTYPEROW (add ROW.INDEX 1)) (* * Note that the above ordering must be maintained between OTHERDATATYPESROW LITATOMROW STACKROW UNRECOGNIZEDTYPEROW) (for RP# from 0 to (SUB1 \RPTSIZE) bind (PNPHI ←(\HILOC \PNPSPACE)) (PLHI ←(\HILOC \PLISTSPACE)) VP# RPTADDR VMFLAGS PTR PTRHI TYPENO do (SETQ RPTADDR (fetch (RPT RPTRBASE) of RP#)) (if (fetch (RPT LOCKED) of RPTADDR) then (add #LOCKEDPAGES 1)) (if (fetch (RPT OCCUPIED) of RPTADDR) then (SETQ VP# (fetch (RPT VP) of RPTADDR)) (SETQ VMFLAGS (LOGAND \VMAP.FLAGS (\READFLAGS VP#))) (SETQ COL.INDEX (if (fetch (VMEMFLAGS VACANT) of VMFLAGS) then (HELP "HHCTB") elseif (BITTEST VMFLAGS \VMAP.DIRTY) then 2 elseif (BITTEST VMFLAGS \VMAP.REF) then 1 elseif (EQ \VMAP.CLEAN VMFLAGS) then 3 else 4)) (SETQ TYPENO (NTYPX (SETQ PTR (create POINTER PAGE# ← VP#)))) (SETQ ROW.INDEX (if (EQ 0 TYPENO) then (if (type? ARRAYBLOCK PTR) then 0 elseif (EQ \STACKHI (SETQ PTRHI (\HILOC PTR))) then STACKROW elseif (AND (ILEQ PNPHI PTRHI) (ILEQ PTRHI PLHI)) then LITATOMROW elseif (EQ PTRHI DISPHI) then SCREENBITMAPROW elseif (OR (EQ PTRHI HTCOLHI) (AND (EQ PTRHI HTMAINHI) (ILEQ (FOLDLO (\LOLOC PTR) WORDSPERPAGE) \HTMAINnpages)) (EQ PTR \HTOVERFLOW) (EQ PTR \HTBIGCOUNT) (AND (EQ PTRHI TTHI) (IGEQ (\LOLOC PTR) (IQUOTIENT WORDSPERSEGMENT 2)))) then GCHASH&TYPE.ROW elseif (OR (AND (EQ PTRHI PMAPHI) (ILESSP (\LOLOC PTR) (IQUOTIENT WORDSPERSEGMENT 2))) (EQ PTRHI SPMAPHI)) then PMAPROW else UNRECOGNIZEDTYPEROW) elseif (CDR (ASSOC TYPENO TN.TO.ROWINDEX)) elseif (ILEQ TYPENO \MaxTypeNumber) then OTHERDATATYPESROW else (HELP TYPENO (QUOTE \MaxTypeNumber)) UNRECOGNIZEDTYPEROW)) (16ASET (ADD1 (16AREF \MEMUSAGE.STATS ROW.INDEX COL.INDEX)) \MEMUSAGE.STATS ROW.INDEX COL.INDEX) elseif (NOT (fetch (RPT UNAVAILABLE) of RPTADDR)) then (add #AVAILABLEPAGES 1))) (RETURN (LIST #LOCKEDPAGES #AVAILABLEPAGES OTHERDATATYPESROW))))) (\SAS.PRINT.REALMEMSTATS (LAMBDA (FILE L) (* JonL "18-Sep-84 04:57") (* * L communicates the results from the stats gathering phase. (#LOCKEDPAGES #AVAILABLEPAGES OTHERDATATYPESROW)) (PROG (#LOCKEDPAGES #AVAILABLEPAGES OTHERDATATYPESROW UNRECOGNIZEDTYPEROW STACKROW GCHASH&TYPE.ROW PMAPROW SCREENBITMAPROW LITATOMROW (TOTALTOTAL 0) (TOTALUNREFERENCED 0) (TOTALREADONLY 0) (TOTALDIRTY 0) (TOTALUNKNOWN 0) TYPENAME UNREFERENCED READONLY DIRTY UNKNOWN TOTAL) (SETQ #LOCKEDPAGES (pop L)) (SETQ #AVAILABLEPAGES (pop L)) (SETQ OTHERDATATYPESROW (pop L)) (SETQ LITATOMROW (ADD1 OTHERDATATYPESROW)) (SETQ STACKROW (ADD1 LITATOMROW)) (SETQ GCHASH&TYPE.ROW (ADD1 STACKROW)) (SETQ PMAPROW (ADD1 GCHASH&TYPE.ROW)) (SETQ SCREENBITMAPROW (ADD1 PMAPROW)) (SETQ UNRECOGNIZEDTYPEROW (ADD1 SCREENBITMAPROW)) (\SAS.PRINTSECTIONHEADER "Histographs for Real Memory Usage" FILE) (printout FILE T "Number of locked pages = " #LOCKEDPAGES ", Number of pages available and free = " #AVAILABLEPAGES T T " Type Name Total# Referenced Dirty Untouched ??" T) (for ROW.INDEX from 0 to UNRECOGNIZEDTYPEROW do (SETQ TYPENAME (if (EQ 0 ROW.INDEX) then "[ArrayBlocks]" elseif (IGEQ ROW.INDEX OTHERDATATYPESROW) then (if (IGEQ ROW.INDEX UNRECOGNIZEDTYPEROW) then (QUOTE "[Unrecognized]") elseif (IGEQ ROW.INDEX SCREENBITMAPROW) then "[ScreenBitMap]" elseif (IGEQ ROW.INDEX PMAPROW) then "[PageMaps]" elseif (IGEQ ROW.INDEX GCHASH&TYPE.ROW) then "[GCHash&TypeTables]" elseif (IGEQ ROW.INDEX STACKROW) then "[StackSpace]" elseif (IGEQ ROW.INDEX LITATOMROW) then "[LitatomCells]" else "[otherDataTypes]") else (\TYPENAMEFROMNUMBER (16AREF \MEMUSAGE.STATS ROW.INDEX 0)))) (if (ILESSP 16 (NCHARS TYPENAME)) then (SETQ TYPENAME (SUBSTRING TYPENAME 1 16))) (add TOTALREADONLY (SETQ READONLY (16AREF \MEMUSAGE.STATS ROW.INDEX 2))) (add TOTALDIRTY (SETQ DIRTY (16AREF \MEMUSAGE.STATS ROW.INDEX 3))) (add TOTALUNREFERENCED (SETQ UNREFERENCED (16AREF \MEMUSAGE.STATS ROW.INDEX 1))) (add TOTALUNKNOWN (SETQ UNKNOWN (16AREF \MEMUSAGE.STATS ROW.INDEX 4))) (add TOTALTOTAL (SETQ TOTAL (IPLUS READONLY DIRTY UNREFERENCED UNKNOWN))) (printout FILE T " " TYPENAME .TAB 20 .I6 TOTAL .TAB 30 .I6 UNREFERENCED .TAB 40 .I6 READONLY .TAB 50 .I6 DIRTY .TAB 60 .I6 UNKNOWN) finally (printout FILE T T "Totals: " .TAB 20 .I6 TOTALTOTAL .TAB 30 .I6 TOTALUNREFERENCED .TAB 40 .I6 TOTALREADONLY .TAB 50 .I6 TOTALDIRTY .TAB 60 .I6 TOTALUNKNOWN)) (TERPRI FILE)))) ) (RPAQ? \MEMUSAGE.STATS ) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS \MEMUSAGE.STATS) ) (* "Showing data about ARRAYBLOCK sizes") (DEFINEQ (SHOW.ARRAYBLOCK.HISTOGRAPHS (LAMBDA (FILE INUSE.ONLY?) (* JonL "16-Sep-84 23:59") (PROG ((PREVIOUSFREEBLOCKSIZE 0) (CURRENTFREEBLOCKSIZE 0) (CURRENTUSEDBLOCKSIZE 0) (FRAGMENTATIONCOEFF 0.0) (BIGESTSTACKLOSER.SIZE 0) (LARGESTONPAGELOSER.SIZE 0) BIGESTSTACKLOSER LARGESTONPAGELOSER CURRENTRUNTYPE N LEN LEN.DATA FNP) (DECLARE (SPECVARS BIGESTSTACKLOSER.SIZE BIGESTSTACKLOSER LARGESTONPAGELOSER.SIZE LARGESTONPAGELOSER)) (SETQ SNOOPY.CODEREMNANTS (NCONC1 (for HUNKSIZE in SNOOPY.CODEBLOCKSIZES until (OR (NULL HUNKSIZE) (IGREATERP HUNKSIZE MAX.CELLSPERHUNK)) collect (IREMAINDER CELLSPERPAGE HUNKSIZE)) NIL)) (\SAS.INITIALIZE.STATSARRAYS) (SETQ AUSE.TIMER (SETUPTIMER \RCLKSECOND AUSE.TIMER (QUOTE TICKS))) (for (ABLOCK ← \ARRAYSPACE) by (\ADDBASE2 ABLOCK (fetch (ARRAYBLOCK ARLEN) of ABLOCK)) repeatuntil (EQ ABLOCK \ArrayFrLst) finally (if (EQ CURRENTRUNTYPE (QUOTE FREE)) then (* This is essentially the same code as in the loop below) (SETQ FRAGMENTATIONCOEFF (FPLUS FRAGMENTATIONCOEFF (FQUOTIENT (SQRT (FTIMES (FLOAT PREVIOUSFREEBLOCKSIZE) (FLOAT CURRENTFREEBLOCKSIZE))) (FLOAT CURRENTUSEDBLOCKSIZE)) ))) do (SETQ LEN.DATA (IDIFFERENCE (SETQ LEN (fetch (ARRAYBLOCK ARLEN) of ABLOCK)) \ArrayBlockOverheadCells)) (if (fetch (ARRAYBLOCK INUSE) of ABLOCK) then (if (NEQ CURRENTRUNTYPE (QUOTE USED)) then (if (EQ CURRENTRUNTYPE (QUOTE FREE)) then (* When we next encounter a used segment, we can calculate the fragmention coefficient generated by the previous used segment) (SETQ FRAGMENTATIONCOEFF (FPLUS FRAGMENTATIONCOEFF (FQUOTIENT (SQRT (FTIMES (FLOAT PREVIOUSFREEBLOCKSIZE) (FLOAT CURRENTFREEBLOCKSIZE))) (FLOAT CURRENTUSEDBLOCKSIZE))))) (SETQ CURRENTRUNTYPE (QUOTE USED)) (SETQ CURRENTUSEDBLOCKSIZE 0)) (SELECTC (fetch (ARRAYBLOCK GCTYPE) of ABLOCK) ((LIST UNBOXEDBLOCK.GCT) (\SAS.INCREMENT.STATS USEDBLOCKS.FREQ USEDBLOCKS.CONSUMPTION LEN.DATA LEN SNOOPY.ARRAYBLOCKSIZES) (\SAS.INCREMENT.STATS NIL USEDHUNKS.CONSUMPTION LEN.DATA (\SAS.HUNKABLE.SIZE LEN.DATA SNOOPY.ARRAYBLOCKSIZES) SNOOPY.ARRAYBLOCKSIZES)) ((LIST CODEBLOCK.GCT) (\SAS.CODEBLOCKSTATS LEN (\ADDBASE ABLOCK \ArrayBlockHeaderWords)) ) ((LIST PTRBLOCK.GCT) (\SAS.INCREMENT.STATS PTRBLOCKS.FREQ PTRBLOCKS.CONSUMPTION LEN.DATA LEN SNOOPY.PTRBLOCKSIZES) (\SAS.INCREMENT.STATS NIL PTRHUNKS.CONSUMPTION LEN.DATA (\SAS.HUNKABLE.SIZE LEN.DATA SNOOPY.PTRBLOCKSIZES) SNOOPY.PTRBLOCKSIZES)) (SHOULDNT)) else (if (NOT INUSE.ONLY?) then (\SAS.INCREMENT.STATS FREEBLOCKS.FREQ FREEBLOCKS.CONSUMPTION LEN LEN SNOOPY.ARRAYBLOCKSIZES)) (if (NEQ CURRENTRUNTYPE (QUOTE FREE)) then (SETQ CURRENTRUNTYPE (QUOTE FREE)) (SETQ PREVIOUSFREEBLOCKSIZE CURRENTFREEBLOCKSIZE) (SETQ CURRENTFREEBLOCKSIZE 0))) (SELECTQ CURRENTRUNTYPE (USED (add CURRENTUSEDBLOCKSIZE LEN)) (FREE (add CURRENTFREEBLOCKSIZE LEN)) (SHOULDNT)) (if (TIMEREXPIRED? AUSE.TIMER) then (* Give a yield every second or so.) (* Don't worry excessively about this disrupting the parsing of array space! Yea, we know that if the ROVER of \PARSEARRAYSPACE just happens to get merged one way or other during the BLOCK ...) (BLOCK) (SETQ AUSE.TIMER (SETUPTIMER \RCLKSECOND AUSE.TIMER (QUOTE TICKS))))) (for I FREQ from 0 to (LENGTH SNOOPY.INITONPAGESIZES) when (NEQ 0 (SETQ FREQ (16AREF INITONPAGE.FREQ I) )) do (PASET (FQUOTIENT (FTIMES 100.0 (PAREF INITONPAGE.PERCENT I)) FREQ) INITONPAGE.PERCENT I)) (* Calculate the average percentage -- currently holds the raw sums of ratios) (printout FILE T \SAS.LINEDIVIDER T "Histographs for ARRAYBLOCK Storage" T \SAS.LINEDIVIDER) (if (NOT INUSE.ONLY?) then (\SAS.STATSOUT FREEBLOCKS.FREQ FREEBLOCKS.CONSUMPTION NIL SNOOPY.ARRAYBLOCKSIZES "ArrayBlocks Free (block size includes overhead cells)" FILE) (printout FILE T "Fragmentation coefficient = " .F10.2 FRAGMENTATIONCOEFF T)) (\SAS.STATSOUT CODEBLOCKS.FREQ CODEBLOCKS.CONSUMPTION CODEHUNKS.CONSUMPTION SNOOPY.CODEBLOCKSIZES "ArrayBlocks in Use (with GCTYPE = CODEBLOCK.GCT)" FILE) (FORMFEED FILE) (\SAS.STATSOUT USEDBLOCKS.FREQ USEDBLOCKS.CONSUMPTION USEDHUNKS.CONSUMPTION SNOOPY.ARRAYBLOCKSIZES "ArrayBlocks in Use (with GCTYPE = UNBOXEDBLOCK.GCT)" FILE) (\SAS.STATSOUT PTRBLOCKS.FREQ PTRBLOCKS.CONSUMPTION PTRHUNKS.CONSUMPTION SNOOPY.PTRBLOCKSIZES "ArrayBlocks in Use (with GCTYPE = PTRBLOCK.GCT)" FILE) (FORMFEED FILE) (\SAS.PRINTSECTIONHEADER "Histographs for CODE Memory Requirements" FILE) (PROGN (\SAS.STATSOUT STKMINS.FREQ NIL NIL SNOOPY.STKMINSIZES "Minimun Stack Sizes (in Cells)" FILE) (printout FILE T "Function with largest STKMIN requirement is: " BIGESTSTACKLOSER T) ) (PROGN (\SAS.STATSOUT INITONPAGE.FREQ INITONPAGE.PERCENT NIL SNOOPY.INITONPAGESIZES "Initial Segment 'on page' Alignment" FILE) (printout FILE T "Function with largest 'on page' requirement is: " LARGESTONPAGELOSER T) (printout FILE T "Ratios of 'INITONPAGE' misses for page-straddling codehunks:" T -3) (for I from 0 as HUNKSIZE in SNOOPY.CODEBLOCKSIZES until (OR (NULL HUNKSIZE) (IGREATERP HUNKSIZE MAX.CELLSPERHUNK)) when (NEQ 0 (SETQ N (16AREF STRADDLERMISSES.FREQ I))) do (printout FILE N (QUOTE /) (16AREF CODEBLOCKS.FREQ I) (QUOTE %[) HUNKSIZE (QUOTE %]) -3))) (TERPRI FILE) (RETURN T)))) (\SAS.CODEBLOCKSTATS (LAMBDA (LEN FNADDR) (* JonL "16-Sep-84 19:30") (DECLARE (USEDFREE BIGESTSTACKLOSER.SIZE BIGESTSTACKLOSER LARGESTONPAGELOSER.SIZE LARGESTONPAGELOSER)) (PROG ((LEN.DATA (IDIFFERENCE LEN \ArrayBlockOverheadCells)) CODEHUNKSIZE STKMINCELLS INITONPAGECELLS) (\SAS.INCREMENT.STATS CODEBLOCKS.FREQ CODEBLOCKS.CONSUMPTION LEN.DATA LEN SNOOPY.CODEBLOCKSIZES) (SETQ CODEHUNKSIZE (\SAS.HUNKABLE.SIZE LEN.DATA SNOOPY.CODEBLOCKSIZES)) (\SAS.INCREMENT.STATS NIL CODEHUNKS.CONSUMPTION LEN.DATA CODEHUNKSIZE SNOOPY.CODEBLOCKSIZES) (* Next few are for statistics on the sizes of stackframes required) (SETQ STKMINCELLS (FOLDHI (fetch (FNHEADER STKMIN) of FNADDR) WORDSPERCELL)) (\SAS.INCREMENT.STATS STKMINS.FREQ NIL STKMINCELLS NIL SNOOPY.STKMINSIZES) (if (IGREATERP STKMINCELLS BIGESTSTACKLOSER.SIZE) then (SETQ BIGESTSTACKLOSER.SIZE STKMINCELLS) (SETQ BIGESTSTACKLOSER (fetch (CODEARRAYBLOCK ABFRAMENAME) of FNADDR))) (* Next few are for statistics on the sizes of header/nametable before the STARTPC which must be kept on the same page.) (SETQ INITONPAGECELLS (CEIL (ADD1 (FOLDHI (fetch (FNHEADER STARTPC) of FNADDR) BYTESPERCELL)) CELLSPERQUAD)) (\SAS.INCREMENT.STATS INITONPAGE.FREQ INITONPAGE.PERCENT INITONPAGECELLS (FQUOTIENT INITONPAGECELLS LEN.DATA) SNOOPY.INITONPAGESIZES) (if (IGREATERP INITONPAGECELLS LARGESTONPAGELOSER.SIZE) then (SETQ LARGESTONPAGELOSER.SIZE INITONPAGECELLS) (SETQ LARGESTONPAGELOSER (fetch (FNHEADER FRAMENAME) of FNADDR))) (if (ILEQ CODEHUNKSIZE MAX.CELLSPERHUNK) then (* INITONPAGECELLS is still the number of initial cells that this code block must keep on a page.) (PROG ((STRADDLER'S.MAXONPAGE (CAR (NTH SNOOPY.CODEREMNANTS (ADD1 (\SAS.INDEXINLIST CODEHUNKSIZE SNOOPY.CODEBLOCKSIZES))))) ) (* These many cells are what a page-straddling hunk of this size would keep on the first page) (if (NULL STRADDLER'S.MAXONPAGE) then (printout T T "STRADDLER'S.MAXONPAGE is NIL on CODEHUNKSIZE = " CODEHUNKSIZE) elseif (AND (NEQ 0 STRADDLER'S.MAXONPAGE) (ILESSP STRADDLER'S.MAXONPAGE INITONPAGECELLS)) then (\SAS.INCREMENT.STATS STRADDLERMISSES.FREQ NIL CODEHUNKSIZE NIL SNOOPY.CODEBLOCKSIZES))))))) (\SAS.INDEXINLIST (LAMBDA (FREQ SIZESLST) (* JonL "13-Sep-84 20:40") (* find the index in SIZESLST such that FREQ is "first" less-than-or-equal to that storagesize) (find I from 0 as X in SIZESLST suchthat (NOT (GREATERP FREQ (OR (NUMBERP X) (RETURN I))))))) (\SAS.INCREMENT.STATS (LAMBDA (FREQA CONSUMPTIONA INDEXSIZE CONSUMPTIONSIZE SIZELST) (* JonL "15-Jan-85 22:00") (* * We acumulate number of items in FREQA and the sizes of the items in CONSUMPTIONA N is the "histogram index" into a frequency array;) (PROG ((N (\SAS.INDEXINLIST INDEXSIZE (\DTEST SIZELST (QUOTE LISTP))))) (if FREQA then (LET ((V (16AREF FREQA N))) (if (ILESSP V MAX.SMALLP) then (16ASET (ADD1 V) FREQA N)))) (if CONSUMPTIONA then (* Yup, sure would have been nice to have had ucoded version of ASET and AREF here!) (if (FIXP CONSUMPTIONSIZE) then (NASET (PLUS CONSUMPTIONSIZE (NAREF CONSUMPTIONA N)) CONSUMPTIONA N) else (PASET (PLUS CONSUMPTIONSIZE (PAREF CONSUMPTIONA N)) CONSUMPTIONA N)))))) (\SAS.HUNKABLE.SIZE (LAMBDA (NCELLS SIZESLST) (* JonL "15-Sep-84 15:33") (* How big is the chunk size needed to store an item of NCELLS number of cells? uses the SIZESLST quantization list) (PROG ((HUNKSIZE (find X in (SETQ SIZESLST (\DTEST SIZESLST (QUOTE LISTP))) suchthat (NOT (GREATERP NCELLS (OR (NUMBERP X) (RETURN))))))) (RETURN (OR (AND HUNKSIZE (ILEQ HUNKSIZE MAX.CELLSPERHUNK) HUNKSIZE) (IPLUS \ArrayBlockOverheadCells NCELLS)))))) (\SAS.CALCFRAGCOEFF (LAMBDA (FILE) (* JonL "20-Nov-84 23:06") (* * Scans arrayblock space merely to calculate the Fragmentation Coefficient) (PROG ((PREVIOUSFREEBLOCKSIZE 0) (CURRENTFREEBLOCKSIZE 0) (CURRENTUSEDBLOCKSIZE 0) (FRAGMENTATIONCOEFF 0.0) CURRENTRUNTYPE N LEN LEN.DATA FNP) (SETQ AUSE.TIMER (SETUPTIMER \RCLKSECOND AUSE.TIMER (QUOTE TICKS))) (for (ABLOCK ← \ARRAYSPACE) by (\ADDBASE2 ABLOCK (fetch (ARRAYBLOCK ARLEN) of ABLOCK)) repeatuntil (EQ ABLOCK \ArrayFrLst) finally (if (EQ CURRENTRUNTYPE (QUOTE FREE)) then (* This is essentially the same code as in the loop below) (SETQ FRAGMENTATIONCOEFF (FPLUS FRAGMENTATIONCOEFF (FQUOTIENT (SQRT (FTIMES (FLOAT PREVIOUSFREEBLOCKSIZE) (FLOAT CURRENTFREEBLOCKSIZE))) (FLOAT CURRENTUSEDBLOCKSIZE)) ))) do (SETQ LEN.DATA (IDIFFERENCE (SETQ LEN (fetch (ARRAYBLOCK ARLEN) of ABLOCK)) \ArrayBlockOverheadCells)) (if (fetch (ARRAYBLOCK INUSE) of ABLOCK) then (if (NEQ CURRENTRUNTYPE (QUOTE USED)) then (if (EQ CURRENTRUNTYPE (QUOTE FREE)) then (* When we next encounter a used segment, we can calculate the fragmention coefficient generated by the previous used segment) (SETQ FRAGMENTATIONCOEFF (FPLUS FRAGMENTATIONCOEFF (FQUOTIENT (SQRT (FTIMES (FLOAT PREVIOUSFREEBLOCKSIZE) (FLOAT CURRENTFREEBLOCKSIZE))) (FLOAT CURRENTUSEDBLOCKSIZE))))) (SETQ CURRENTRUNTYPE (QUOTE USED)) (SETQ CURRENTUSEDBLOCKSIZE 0)) else (if (NEQ CURRENTRUNTYPE (QUOTE FREE)) then (SETQ CURRENTRUNTYPE (QUOTE FREE)) (SETQ PREVIOUSFREEBLOCKSIZE CURRENTFREEBLOCKSIZE) (SETQ CURRENTFREEBLOCKSIZE 0))) (SELECTQ CURRENTRUNTYPE (USED (add CURRENTUSEDBLOCKSIZE LEN)) (FREE (add CURRENTFREEBLOCKSIZE LEN)) (SHOULDNT)) (if (TIMEREXPIRED? AUSE.TIMER) then (* Give a yield every second or so.) (* Don't worry excessively about this disrupting the parsing of array space! Yea, we know that if the ROVER of \PARSEARRAYSPACE just happens to get merged one way or other during the BLOCK ...) (BLOCK) (SETQ AUSE.TIMER (SETUPTIMER \RCLKSECOND AUSE.TIMER (QUOTE TICKS))))) (printout FILE T T \SAS.LINEDIVIDER T "Fragmentation coefficient = " .F10.2 FRAGMENTATIONCOEFF T \SAS.LINEDIVIDER T)))) ) (RPAQ? USEDBLOCKS.FREQ ) (RPAQ? USEDBLOCKS.CONSUMPTION ) (RPAQ? USEDHUNKS.CONSUMPTION ) (RPAQ? FREEBLOCKS.FREQ ) (RPAQ? FREEBLOCKS.CONSUMPTION ) (RPAQ? CODEBLOCKS.FREQ ) (RPAQ? CODEBLOCKS.CONSUMPTION ) (RPAQ? CODEHUNKS.CONSUMPTION ) (RPAQ? PTRBLOCKS.FREQ ) (RPAQ? PTRBLOCKS.CONSUMPTION ) (RPAQ? PTRHUNKS.CONSUMPTION ) (RPAQ? STKMINS.FREQ ) (RPAQ? INITONPAGE.FREQ ) (RPAQ? INITONPAGE.PERCENT ) (RPAQ? STRADDLERMISSES.FREQ ) (RPAQ? AUSE.TIMER (SETUPTIMER 0 NIL (QUOTE TICKS))) (DECLARE: EVAL@COMPILE DONTCOPY [DECLARE: EVAL@COMPILE (BLOCKRECORD CODEARRAYBLOCK ((ABSTKMIN WORD) (NIL WORD) (* The NA field) (NIL WORD) (* The PV field) (ABSTARTPC WORD) (NIL BITS 10) (NIL BITS 2) (* ARGTYPE) (NIL BITS 4) (ABFRAMENAMELO WORD) (ABFRAMENAMEHI BYTE)) (ACCESSFNS CODEARRAYBLOCK ((ABFRAMENAME (\VAG2 (fetch ABFRAMENAMEHI of DATUM) (fetch ABFRAMENAMELO of DATUM)))))) ] ) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS USEDBLOCKS.FREQ USEDHUNKS.CONSUMPTION FREEBLOCKS.FREQ FREEBLOCKS.CONSUMPTION USEDBLOCKS.CONSUMPTION CODEBLOCKS.FREQ CODEBLOCKS.CONSUMPTION CODEHUNKS.CONSUMPTION PTRBLOCKS.FREQ PTRBLOCKS.CONSUMPTION PTRHUNKS.CONSUMPTION STKMINS.FREQ INITONPAGE.FREQ INITONPAGE.PERCENT STRADDLERMISSES.FREQ AUSE.TIMER) ) (DEFINEQ (\SAS.INITIALIZE.STATSARRAYS (LAMBDA NIL (* JonL "16-Sep-84 17:58") (PROG ((LEN (\SAS.INITIALIZE.PNAMEARRAYS)) (CLEN (\SAS.INITIALIZE.CHECKSIZESLST (QUOTE SNOOPY.CODEBLOCKSIZES)))) (\SAS.CHECKMEMSTATSARRAY) (\SAS.INITIALIZEARRAY (QUOTE CODEBLOCKS.FREQ) (QUOTE (MOD 65536)) CLEN) (\SAS.INITIALIZEARRAY (QUOTE CODEBLOCKS.CONSUMPTION) (QUOTE FIXNUM) CLEN) (\SAS.INITIALIZEARRAY (QUOTE CODEHUNKS.CONSUMPTION) (QUOTE FIXNUM) CLEN) (\SAS.INITIALIZEARRAY (QUOTE PTRBLOCKS.FREQ) (QUOTE (MOD 65536)) LEN) (\SAS.INITIALIZEARRAY (QUOTE PTRBLOCKS.CONSUMPTION) (QUOTE FIXNUM) LEN) (\SAS.INITIALIZEARRAY (QUOTE PTRHUNKS.CONSUMPTION) (QUOTE FIXNUM) LEN) (* * Following four are created here, because this function is called at load time in order to do most of the consing before the SHOW functions are run) (\SAS.INITIALIZEARRAY (QUOTE STKMINS.FREQ) (QUOTE (MOD 65536)) (IPLUS 10 (LENGTH SNOOPY.STKMINSIZES))) (\SAS.INITIALIZEARRAY (QUOTE INITONPAGE.FREQ) (QUOTE (MOD 65536)) (IPLUS 10 (LENGTH SNOOPY.INITONPAGESIZES))) (\SAS.INITIALIZEARRAY (QUOTE INITONPAGE.PERCENT) (QUOTE POINTER) (IPLUS 10 (LENGTH SNOOPY.INITONPAGESIZES)) 0.0) (\SAS.INITIALIZEARRAY (QUOTE STRADDLERMISSES.FREQ) (QUOTE (MOD 65536)) CLEN)))) (\SAS.INITIALIZE.PNAMEARRAYS (LAMBDA NIL (* JonL " 2-Sep-84 17:55") (* * Returns the length of the SNOOPY.ARRAYBLOCKSIZES after checking its validity. Ascertains that the arrays AUSE and AFREE are big enough.) (PROG ((LEN (\SAS.INITIALIZE.CHECKSIZESLST (QUOTE SNOOPY.ARRAYBLOCKSIZES)))) (\SAS.INITIALIZEARRAY (QUOTE USEDBLOCKS.FREQ) (QUOTE (MOD 65536)) LEN) (\SAS.INITIALIZEARRAY (QUOTE USEDBLOCKS.CONSUMPTION) (QUOTE FIXNUM) LEN) (\SAS.INITIALIZEARRAY (QUOTE USEDHUNKS.CONSUMPTION) (QUOTE FIXNUM) LEN) (\SAS.INITIALIZEARRAY (QUOTE FREEBLOCKS.FREQ) (QUOTE (MOD 65536)) LEN) (\SAS.INITIALIZEARRAY (QUOTE FREEBLOCKS.CONSUMPTION) (QUOTE FIXNUM) LEN) (RETURN LEN)))) (\SAS.INITIALIZEARRAY (LAMBDA (NAME ARRAYELEMENTTYPE MINSIZE INITELEMENT) (* JonL "16-Sep-84 17:53") (* * Ensures that the array in NAME is big enough, and initializes it to zeros.) (if (NULL MINSIZE) then (SETQ MINSIZE (LENGTH SNOOPY.ARRAYBLOCKSIZES)) elseif (FIXP MINSIZE) elseif (LISTP MINSIZE) then (SETQ MINSIZE (LENGTH MINSIZE)) else (\ILLEGAL.ARG MINSIZE)) (PROG ((A (GETATOMVAL NAME))) (if (AND (type? CMLARRAY A) (EQUAL ARRAYELEMENTTYPE (ARRAYELEMENTTYPE A)) (IGEQ (ARRAYDIMENSION A 0) MINSIZE)) then (* Lookin' good!) else (SETATOMVAL NAME (SETQ A (MAKEARRAY MINSIZE (QUOTE ELEMENTTYPE) ARRAYELEMENTTYPE)))) (FILLARRAY A (OR INITELEMENT 0))))) (\SAS.INITIALIZE.CHECKSIZESLST (LAMBDA (NAME) (* JonL " 2-Sep-84 14:58") (* * Check that NAME is a global variable whose value is a valid quantiztion list) (PROG (TEM (SIZESLST (GETATOMVAL NAME))) (OR (AND (LISTP SIZESLST) (EVERY SIZESLST (FUNCTION \SAS.NULLORFIXP))) (ERROR SIZESLST (CONCAT "Bad value for " NAME))) (OR (AND (SETQ TEM (LISTP (LAST SIZESLST))) (NULL (CAR TEM))) (SETATOMVAL NAME (APPEND SIZESLST (QUOTE (NIL))))) (RETURN (IPLUS (LENGTH SIZESLST) (PROG1 6 (* Little fudge/safety factor))))))) (\SAS.NULLORFIXP (LAMBDA (X) (* JonL "17-Aug-84 22:32") (OR (NULL X) (FIXP X)))) ) (* "Snooping on LITATOM and STRINGP statistics") (RPAQ? PNAMEHUNKS.CONSUMPTION ) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS PNAMEHUNKS.CONSUMPTION) ) (DEFINEQ (SHOW.LITATOM.HISTOGRAPHS (LAMBDA (FILE) (* JonL "15-Sep-84 20:14") (\SAS.COLLECTLITATOMSTATS) (\SAS.PRINTLITATOMCELLS FILE) (\SAS.PRINTLITATOMPNAMES FILE) T)) (\SAS.COLLECTLITATOMSTATS (LAMBDA NIL (* JonL "15-Sep-84 19:56") (\SAS.INITIALIZE.PNAMESTATS) (MAPATOMS (FUNCTION (LAMBDA (ATM) (PROG ((NWORDS (FOLDHI (ADD1 (fetch (LITATOM PNAMELENGTH) of ATM)) BYTESPERCELL)) #CELLSPNAME N #VALCELLS FNP) (* no litatom can have more than 256 characters in its pname) (SETQ #CELLSPNAME (FOLDHI NWORDS WORDSPERCELL)) (\SAS.INCREMENT.STATS PNAME.FREQ PNAME.CONSUMPTION #CELLSPNAME NWORDS SNOOPY.ARRAYBLOCKSIZES) (\SAS.INCREMENT.STATS NIL PNAMEHUNKS.CONSUMPTION #CELLSPNAME (\SAS.HUNKABLE.SIZE #CELLSPNAME SNOOPY.ARRAYBLOCKSIZES) SNOOPY.ARRAYBLOCKSIZES) (SETQ #VALCELLS (IPLUS (if (fetch (LITATOM DEFPOINTER) of ATM) then 1 else 0) (if (NEQ (fetch (LITATOM VALUE) of ATM) (QUOTE NOBIND)) then 1 else 0) (if (fetch (LITATOM PROPLIST) of ATM) then 1 else 0))) (\SAS.INCREMENT.STATS VCELLS.FREQ VCELLS.CONSUMPTION #VALCELLS #VALCELLS (QUOTE (0 1 2 3))) (if (TIMEREXPIRED? AUSE.TIMER) then (* Give a yield every second or so.) (BLOCK) (SETQ AUSE.TIMER (SETUPTIMER \RCLKSECOND AUSE.TIMER (QUOTE TICKS))))) ))) (* * Adjust the totals for CELL comsumption, since the statistics were gathered in WORDs) (for I from 0 to (SUB1 (ARRAYDIMENSION PNAME.CONSUMPTION 0)) do (NASET (FOLDHI (NAREF PNAME.CONSUMPTION I) WORDSPERCELL) PNAME.CONSUMPTION I)))) (\SAS.PRINTLITATOMCELLS (LAMBDA (FILE FLG) (* JonL "20-Nov-84 22:56") (\SAS.PRINTSECTIONHEADER (CONCAT "Highest Litatom number used: " \AtomFrLst) FILE) (if (NOT FLG) then (\SAS.STATSOUT VCELLS.FREQ VCELLS.CONSUMPTION NIL (QUOTE (0 1 2 3 4 NIL)) "Multiplicities of Litatom 'cells'" FILE)))) (\SAS.PRINTLITATOMPNAMES (LAMBDA (FILE) (* JonL "15-Sep-84 20:13") (\SAS.PRINTSECTIONHEADER "Histographs for LITATOM Pname Storage" FILE) (\SAS.STATSOUT PNAME.FREQ PNAME.CONSUMPTION PNAMEHUNKS.CONSUMPTION SNOOPY.ARRAYBLOCKSIZES "Litatom Pname Lengths (in Cells)" FILE) (printout FILE T "Actual number of pages in pname chars space = " \CurPnPage T))) (SHOW.STRINGP.HISTOGRAPHS (LAMBDA (FILE) (* JonL "15-Sep-84 19:44") (* Try to minimize the visibility of garbage.) (MAPC (PROG1 (\COLLECTINUSE (QUOTE STRINGP)) (\SAS.INITIALIZE.PNAMESTATS)) (FUNCTION (LAMBDA (STR) (PROG ((NCELLS (FOLDHI (fetch (STRINGP LENGTH) of STR) BYTESPERCELL))) (\SAS.INCREMENT.STATS PNAME.FREQ PNAME.CONSUMPTION NCELLS (IPLUS NCELLS \ArrayBlockOverheadCells) SNOOPY.ARRAYBLOCKSIZES) (\SAS.INCREMENT.STATS NIL PNAMEHUNKS.CONSUMPTION NCELLS (\SAS.HUNKABLE.SIZE NCELLS SNOOPY.ARRAYBLOCKSIZES) SNOOPY.ARRAYBLOCKSIZES) (if (TIMEREXPIRED? AUSE.TIMER) then (* Give a yield every second or so.) (BLOCK) (SETQ AUSE.TIMER (SETUPTIMER \RCLKSECOND AUSE.TIMER (QUOTE TICKS)))))))) (printout FILE T \SAS.LINEDIVIDER T "Histographs for STRINGP Storage" T \SAS.LINEDIVIDER) (\SAS.STATSOUT PNAME.FREQ PNAME.CONSUMPTION PNAMEHUNKS.CONSUMPTION SNOOPY.ARRAYBLOCKSIZES "String Pname Lengths (in Cells)" FILE))) (\SAS.INITIALIZE.PNAMESTATS (LAMBDA NIL (* JonL " 2-Sep-84 17:55") (\SAS.INITIALIZE.PNAMEARRAYS) (* * Note how we can just share the same histogram arrays used by SHOW.ARRAYBLOCK.HISTOGRAPHS) (SETQ PNAME.FREQ USEDBLOCKS.FREQ) (SETQ PNAME.CONSUMPTION USEDBLOCKS.CONSUMPTION) (SETQ PNAMEHUNKS.CONSUMPTION USEDHUNKS.CONSUMPTION) (SETQ VCELLS.FREQ FREEBLOCKS.FREQ) (SETQ VCELLS.CONSUMPTION FREEBLOCKS.CONSUMPTION) (SETQ AUSE.TIMER (SETUPTIMER \RCLKSECOND AUSE.TIMER (QUOTE TICKS))))) ) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS PNAME.FREQ PNAME.CONSUMPTION VCELLS.FREQ VCELLS.CONSUMPTION) ) (FILESLOAD (SYSLOAD COMPILED FROM LISPUSERS) CMLARRAY GCHAX) (DECLARE: DONTEVAL@COMPILE DONTEVAL@LOAD DOCOPY (\SAS.INITIALIZE.STATSARRAYS) ) (DECLARE: EVAL@COMPILE DONTCOPY (DECLARE: EVAL@COMPILE (PUTPROPS FORMFEED MACRO ((FILE) (PRIN1 (CONSTANT (CHARACTER (CHARCODE FF))) FILE))) ) ) (* "Related to format of statistics printout") (DEFINEQ (\SAS.PRINTSECTIONHEADER (LAMBDA (TITLELINE FILE) (* JonL "20-Aug-84 23:42") (printout FILE T T \SAS.LINEDIVIDER T TITLELINE T \SAS.LINEDIVIDER))) (\SAS.STATSOUT (LAMBDA (FREQA #CELLSA.BLOCKS #CELLSA.HUNKS SIZESLST TITLELINE FILE) (* JonL "16-Sep-84 20:09") (* FREQA is the frequency array; #CELLSA.BLOCKS is the array holding the total number of cells required to store the items as "blocks"; #CELLSA.HUNKS is similar for hunks.) (printout FILE T T .TAB0 (IQUOTIENT (IDIFFERENCE 58 (NCHARS TITLELINE)) 2) TITLELINE T) (PROG ((INITONPAGEP (EQ #CELLSA.BLOCKS INITONPAGE.PERCENT)) (TITEMS 0) (TITEMS.LE.HUNKMAX 0) (TBCELLS 0) (THCELLS 0) TBCELLS.LE.HUNKMAX THCELLS.LE.HUNKMAX FIRST.NONZERO LAST.NONZERO) (* * Accumulate the total number of items in the frequency counts; also the total amount of space specified by the #CELLS arrays.) (for I NITEMS from 0 as X in SIZESLST do (if #CELLSA.HUNKS then (if (AND (NULL TBCELLS.LE.HUNKMAX) (OR (NULL X) (IGREATERP X MAX.CELLSPERHUNK))) then (* Keep a record of the cumulative totals just for those that share in "hunking") (SETQ TITEMS.LE.HUNKMAX TITEMS) (SETQ TBCELLS.LE.HUNKMAX TBCELLS) (SETQ THCELLS.LE.HUNKMAX THCELLS)) (add THCELLS (NAREF #CELLSA.HUNKS I))) (add TITEMS (SETQ NITEMS (16AREF FREQA I))) (if (NEQ 0 NITEMS) then (if (NULL FIRST.NONZERO) then (SETQ FIRST.NONZERO I)) (SETQ LAST.NONZERO I) (if (AND #CELLSA.BLOCKS (NOT INITONPAGEP)) then (add TBCELLS (NAREF #CELLSA.BLOCKS I))))) (* * Back up one, so that, when there is a run of zero-entries, at least one of them will show up.) (OR (ILEQ FIRST.NONZERO 1) (add FIRST.NONZERO -1)) (printout FILE T T "ItemSize" .TAB 12 " Frequency[cum]") (if #CELLSA.BLOCKS then (printout FILE .TAB 34 (if (NOT INITONPAGEP) then " #BlockCells" else "Average %% of codelength"))) (if #CELLSA.HUNKS then (printout FILE .TAB 56 " #HunkCells")) (for I from FIRST.NONZERO as X in (NTH SIZESLST (ADD1 FIRST.NONZERO)) bind #Items #BCells #HCells (TITEMS.DIVISOR ←(TIMES TITEMS .01)) (TBCELLS.DIVISOR ←(TIMES TBCELLS .01)) (THCELLS.DIVISOR ←(TIMES THCELLS .01)) (Cumu#Items ← 0) (CumuBlockCells ← 0) (CumuHunkCells ← 0) until (IGREATERP I LAST.NONZERO) do (add Cumu#Items (SETQ #Items (16AREF FREQA I))) (if #CELLSA.BLOCKS then (if (NOT INITONPAGEP) then (SETQ #BCells (NAREF #CELLSA.BLOCKS I)) (add CumuBlockCells #BCells) else (SETQ #BCells (PAREF #CELLSA.BLOCKS I)))) (if #CELLSA.HUNKS then (add CumuHunkCells (SETQ #HCells (NAREF #CELLSA.HUNKS I)))) (if (FIXP X) then (printout FILE T "le " X) else (printout FILE T "others")) (printout FILE .TAB 12 .I6 #Items " [" .F5.1 (QUOTIENT Cumu#Items TITEMS.DIVISOR) "%%]") (if #CELLSA.BLOCKS then (printout FILE .TAB 34) (if (NOT INITONPAGEP) then (printout FILE .I6 #BCells " [" .F5.1 (QUOTIENT CumuBlockCells TBCELLS.DIVISOR) "%%]") else (printout FILE .F6.2 #BCells))) (if #CELLSA.HUNKS then (printout FILE .TAB 56 .I6 #HCells " [" .F5.1 (QUOTIENT CumuHunkCells THCELLS.DIVISOR) "%%]")) finally (PROGN (printout FILE T T "Totals:" .TAB 12 .I6 TITEMS) (if (AND #CELLSA.BLOCKS (NOT INITONPAGEP)) then (printout FILE .TAB 34 .I6 TBCELLS " (~" (FOLDHI TBCELLS CELLSPERPAGE) " pages)")) (if #CELLSA.HUNKS then (printout FILE .TAB 56 .I6 THCELLS " (~" (FOLDHI THCELLS CELLSPERPAGE) " pages)") (printout FILE T T " (le " MAX.CELLSPERHUNK ")" .TAB 12 .I6 TITEMS.LE.HUNKMAX .TAB 34 .I6 TBCELLS.LE.HUNKMAX " (~" (FOLDHI TBCELLS.LE.HUNKMAX CELLSPERPAGE) " pages)") (printout FILE .TAB 56 .I6 THCELLS.LE.HUNKMAX " (~" (FOLDHI THCELLS.LE.HUNKMAX CELLSPERPAGE) " pages)"))))) (TERPRI FILE))) ) (RPAQ? \SAS.LINEDIVIDER "------------------------------------------------------------------") (RPAQ? \SAS.1-Aug-84% 00:00 490160752) (* "Random date offset, to make default unique file names shorter") (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS \SAS.LINEDIVIDER \SAS.1-Aug-84% 00:00) ) (DECLARE: DOEVAL@COMPILE DONTCOPY (LOCALVARS) ) (PUTPROPS SNOOPY COPYRIGHT ("Xerox Corporation" 1984 1985)) (DECLARE: DONTCOPY (FILEMAP (NIL (8143 12063 (SHOW.HISTOGRAPHS 8153 . 8483) (SHOW.ALL.HISTOGRAPHS 8485 . 8997) ( \SAS.SHOWINIT 8999 . 11663) (\SAS.STORAGE 11665 . 12061)) (12108 21803 (SHOW.REALMEMORY.HISTOGRAPHS 12118 . 12320) (\SAS.CHECKMEMSTATSARRAY 12322 . 12924) (\SAS.GATHER.REALMEMSTATS 12926 . 18652) ( \SAS.PRINT.REALMEMSTATS 18654 . 21801)) (21950 36512 (SHOW.ARRAYBLOCK.HISTOGRAPHS 21960 . 28515) ( \SAS.CODEBLOCKSTATS 28517 . 31416) (\SAS.INDEXINLIST 31418 . 31840) (\SAS.INCREMENT.STATS 31842 . 32876) (\SAS.HUNKABLE.SIZE 32878 . 33514) (\SAS.CALCFRAGCOEFF 33516 . 36510)) (38038 42134 ( \SAS.INITIALIZE.STATSARRAYS 38048 . 39581) (\SAS.INITIALIZE.PNAMEARRAYS 39583 . 40454) ( \SAS.INITIALIZEARRAY 40456 . 41314) (\SAS.INITIALIZE.CHECKSIZESLST 41316 . 41988) (\SAS.NULLORFIXP 41990 . 42132)) (42302 46972 (SHOW.LITATOM.HISTOGRAPHS 42312 . 42553) (\SAS.COLLECTLITATOMSTATS 42555 . 44315) (\SAS.PRINTLITATOMCELLS 44317 . 44716) (\SAS.PRINTLITATOMPNAMES 44718 . 45157) ( SHOW.STRINGP.HISTOGRAPHS 45159 . 46383) (\SAS.INITIALIZE.PNAMESTATS 46385 . 46970)) (47461 52088 ( \SAS.PRINTSECTIONHEADER 47471 . 47669) (\SAS.STATSOUT 47671 . 52086))))) STOP