;; -*- Mode:LISP; Package:SYSTEM-INTERNALS; Base:10; Readtable:CL -*- ;This stuff used to be largely in sys;qmisc ; (defun describe (frob) (send frob :describe 0)) Sigh... (defvar *describe-print-level* 2 "Value of *PRINT-LEVEL* to use in DESCRIBE") (defvar *describe-print-length* 3 "Value of *PRINT-LENGTH* to use in DESCRIBE") ;(defvar *describe-print-pretty* nil ; "Value of *PRINT-PRETTY* to use in DESCRIBE") ;; plebian-lisp says that this should return (values). Tough. ;;; Describe anything (defun describe (anything &optional no-complaints) "Describe the value or components of any Lisp object. This is a good way to find out more than the printed representation says." (unless (and (named-structure-p anything) (cond ((and (get (named-structure-p anything) 'named-structure-invoke) (memq ':describe (named-structure-invoke anything :which-operations))) (named-structure-invoke anything :describe) anything) ((get (named-structure-p anything) 'defstruct-description) (describe-defstruct anything) anything) (t nil))) (typecase anything ((or entity instance) (send anything :describe)) (array (describe-array anything)) (closure (describe-closure anything)) (compiled-function (describe-fef anything)) (symbol (describe-symbol anything)) (cons (describe-cons anything)) (stack-group (describe-stack-group anything)) (short-float (describe-small-flonum anything)) (single-float (describe-flonum anything)) (select (describe-select-method anything)) (character (describe-character anything)) (bignum (describe-bignum anything)) (fixnum (format t "~%~R is ~:[even~;odd~]~&It is ~B in binary" anything (oddp anything) anything)) (ratio (describe-rational-number anything)) (complex (describe-complex-number anything)) (locative (describe-locative anything)) (microcode-function (describe-microcode-function anything)) (t (unless no-complaints (format t "~%I don't know how to describe ~S" anything))))) (send *standard-output* :fresh-line) anything) (defun describe-1 (thing) ;An internal subroutine (unless (or (null thing) ;Don't recursively describe boring things (numberp thing) (symbolp thing) (stringp thing) (consp thing)) (send *standard-output* :fresh-line) (let ((*standard-output* ;Arrange for indentation by 5 spaces ;;>> this loses. (loses recursively) (closure '(*standard-output*) #'(lambda (&rest args) (and (eq (send *standard-output* :send-if-handles :read-cursorpos) 0) (send *standard-output* :string-out " ")) (lexpr-send *standard-output* args))))) (describe thing t)))) (DEFUN DESCRIBE-FEF-ADL (FEF &AUX (ADL (GET-MACRO-ARG-DESC-POINTER FEF))) (PROG (OPT-Q INIT-OPTION (ARGNUM 0) (LOCALNUM 0) ARGP ARG-SYNTAX) L (IF (NULL ADL) (RETURN NIL)) (SETQ OPT-Q (CAR ADL) ADL (CDR ADL)) (SETQ ARG-SYNTAX (NTH (LDB %%FEF-ARG-SYNTAX OPT-Q) FEF-ARG-SYNTAX)) (SETQ ARGP (MEMQ ARG-SYNTAX '(FEF-ARG-REQ FEF-ARG-OPT FEF-ARG-REST))) (COND ((NOT (ZEROP (LOGAND OPT-Q %FEF-NAME-PRESENT))) (SETQ ADL (CDR ADL)))) (COND ((EQ (NTH (LDB %%FEF-ARG-SYNTAX OPT-Q) FEF-ARG-SYNTAX) 'FEF-ARG-REST) (FORMAT T "~&Rest arg (~A) is " (EH:REST-ARG-NAME FEF)) (INCF LOCALNUM)) (ARGP (FORMAT T "~&Arg ~D (~A) is " ARGNUM (EH:ARG-NAME FEF ARGNUM)) (INCF ARGNUM)) ((EQ ARG-SYNTAX 'FEF-ARG-FREE) (GO L)) ((EQ ARG-SYNTAX 'FEF-ARG-INTERNAL-AUX) (RETURN NIL)) (T (FORMAT T "~&Local ~D (~A) is " LOCALNUM (EH:LOCAL-NAME FEF LOCALNUM)) (INCF LOCALNUM))) (PRINC (OR (NTH (LDB %%FEF-ARG-SYNTAX OPT-Q) '("required, " "optional, ")) "")) (IF (EQ (NTH (LDB %%FEF-QUOTE-STATUS OPT-Q) FEF-QUOTE-STATUS) 'FEF-QT-QT) (PRINC "quoted, ")) (PRINC (NTH (LDB %%FEF-SPECIALNESS OPT-Q) '("local, " "special, " "" "remote, "))) ; (PRINC (NTH (LDB %%FEF-DES-DT OPT-Q) ; FEF-DES-DT)) (SETQ INIT-OPTION (NTH (LDB %%FEF-INIT-OPTION OPT-Q) FEF-INIT-OPTION)) (CASE INIT-OPTION (FEF-INI-NIL (FORMAT T "initialized to NIL.")) (FEF-INI-NONE (FORMAT T "not initialized.")) (FEF-INI-SELF (FORMAT T "initialized by binding it to itself.")) (FEF-INI-COMP-C (FORMAT T "initialized by execution of the function.")) (FEF-INI-PNTR (PRINC "initialized to ") (LET ((COMPILER::DISASSEMBLE-OBJECT-OUTPUT-FUN NIL)) (COMPILER::DISASSEMBLE-POINTER FEF (%POINTER-DIFFERENCE ADL FEF) 0)) (PRINC ".") (POP ADL)) (FEF-INI-C-PNTR (LET ((LOC (CAR ADL)) (STR (%FIND-STRUCTURE-HEADER (CAR ADL)))) (COND ((SYMBOLP STR) (FORMAT T "initialized to the ~A of ~S." (CASE (%POINTER-DIFFERENCE LOC STR) (1 "value") (2 "function definition") (3 "property list") (4 "package")) STR)) ((CONSP STR) (FORMAT T "initialized to the function definition of ~S." (CAR STR))) (T (FORMAT T "initialized to the contents of ~S." (CAR ADL))))) (POP ADL)) (FEF-INI-EFF-ADR (FORMAT T "initialized to the value of ") (LET ((SLOT (LOGAND #o77 (CAR ADL)))) (IF (= (LOGAND #o700 (CAR ADL)) (GET 'COMPILER::local 'COMPILER::QLVAL)) (FORMAT T "local ~D (~S)." SLOT (EH:LOCAL-NAME FEF SLOT)) (FORMAT T "arg ~D (~S)." SLOT (EH:ARG-NAME FEF SLOT)))) (POP ADL)) (FEF-INI-OPT-SA (FORMAT T "initialized by the code up to pc ~D." (CAR ADL)) (POP ADL))) (GO L) )) (DEFUN DESCRIBE-STACK-GROUP (SG &AUX TEM) (FORMAT T "~%Stack Group; name is ~S, current state ~S" (SG-NAME SG) (NTH (SG-CURRENT-STATE SG) SG-STATES)) (COND ((NOT (ZEROP (SG-IN-SWAPPED-STATE SG))) (FORMAT T "~% Variables currently swapped out"))) (COND ((NOT (ZEROP (SG-FOOTHOLD-EXECUTING-FLAG SG))) (FORMAT T "~% Foothold currently executing"))) (COND ((NOT (ZEROP (SG-PROCESSING-ERROR-FLAG SG))) (FORMAT T "~% Currently processing an error"))) (COND ((NOT (ZEROP (SG-PROCESSING-INTERRUPT-FLAG SG))) (FORMAT T "~% Currently processing an interrupt"))) (FORMAT T "~%ERROR-MODE:") (PRINT-ERROR-MODE (SG-SAVED-M-FLAGS SG)) (FORMAT T "~%SG-SAFE ~D, SG-SWAP-SV-ON-CALL-OUT ~D, SG-SWAP-SV-OF-SG-THAT-CALLS-ME ~D" (SG-SAFE SG) (SG-SWAP-SV-ON-CALL-OUT SG) (SG-SWAP-SV-OF-SG-THAT-CALLS-ME SG)) (FORMAT T "~%SG-INST-DISP: ~D (~:*~[Normal~;Debug~;Single-step~;Single-step done~])" (SG-INST-DISP SG)) (FORMAT T "~%SG-PREVIOUS-STACK-GROUP ~S, SG-CALLING-ARGS-NUMBER ~S, SG-CALLING-ARGS-POINTER ~S" (SG-PREVIOUS-STACK-GROUP SG) (SG-CALLING-ARGS-NUMBER SG) (SG-CALLING-ARGS-POINTER SG)) (FORMAT T "~%Regular PDL pointer ~D, ~D available, ~D limit" (SG-REGULAR-PDL-POINTER SG) (ARRAY-LENGTH (SG-REGULAR-PDL SG)) (SG-REGULAR-PDL-LIMIT SG)) (FORMAT T "~%Special PDL pointer ~D, ~D available, ~D limit" (SG-SPECIAL-PDL-POINTER SG) (ARRAY-LENGTH (SG-SPECIAL-PDL SG)) (SG-SPECIAL-PDL-LIMIT SG)) (COND ((SETQ TEM (SG-RECOVERY-HISTORY SG)) (FORMAT T "~%Recovery history ~S" TEM))) (COND ((SETQ TEM (SG-PLIST SG)) (FORMAT T "~%SG-PLIST ~S" TEM)))) (DEFUN PRINT-ERROR-MODE (&OPTIONAL (EM %MODE-FLAGS) (STREAM *STANDARD-OUTPUT*)) "Prints the current error mode." (FORMAT STREAM "~&CAR of a number is ~A. CDR of a number is ~A. CAR of a symbol is ~A. CDR of a symbol is a ~A. Trapping is ~A.~%" (CASE (LDB %%M-FLAGS-CAR-NUM-MODE EM) (0 "an error") (1 "NIL") (OTHERWISE "in an unknown state")) (CASE (LDB %%M-FLAGS-CDR-NUM-MODE EM) (0 "an error") (1 "NIL") (OTHERWISE "in an unknown state")) (CASE (LDB %%M-FLAGS-CAR-SYM-MODE EM) (0 "an error") (1 "NIL if the symbol is NIL, otherwise an error") (2 "NIL") (3 "its print-name")) (CASE (LDB %%M-FLAGS-CDR-SYM-MODE EM) (0 "an error") (1 "NIL if the symbol is NIL, otherwise an error") (2 "NIL") (3 "its property list")) (CASE (LDB %%M-FLAGS-TRAP-ENABLE EM) (0 "disabled") (1 "enabled")) )) (DEFUN DESCRIBE-FEF (FEF &OPTIONAL DONT-MENTION-DEBUGGING-INFO &AUX HEADER HEADER-TYPE NAME FAST-ARG SV MISC LENGTH NO-ADL-EXISTS FAST-ARG-ACTIVE) (COND ((SYMBOLP FEF) (DESCRIBE-FEF (SYMBOL-FUNCTION FEF))) ((NOT (COMPILED-FUNCTION-P FEF)) (FERROR "~S is not a FEF (a compiled function)" FEF)) (T (SETQ HEADER (%P-LDB-OFFSET %%HEADER-REST-FIELD FEF %FEFHI-IPC)) (SETQ HEADER-TYPE (%P-LDB-OFFSET %%HEADER-TYPE-FIELD FEF %FEFHI-IPC)) (SETQ LENGTH (%P-CONTENTS-OFFSET FEF %FEFHI-STORAGE-LENGTH)) (SETQ NAME (%P-CONTENTS-OFFSET FEF %FEFHI-FCTN-NAME)) (SETQ FAST-ARG (%P-CONTENTS-OFFSET FEF %FEFHI-FAST-ARG-OPT)) (SETQ SV (%P-CONTENTS-OFFSET FEF %FEFHI-SV-BITMAP)) (SETQ MISC (%P-CONTENTS-OFFSET FEF %FEFHI-MISC)) (FORMAT T "~%FEF for function ~S~%" NAME) (FORMAT T "Initial relative PC: ~S halfwords.~%" (LDB %%FEFH-PC HEADER)) (cond ((= header-type %header-type-fef) (SETQ NO-ADL-EXISTS (LDB %%FEFH-NO-ADL HEADER) FAST-ARG-ACTIVE (LDB %%FEFH-FAST-ARG HEADER)) (UNLESS (ZEROP (%P-LDB %%FEFH-GET-SELF-MAPPING-TABLE FEF)) (FORMAT T "This is a method of flavor ~S.~%" (%P-CONTENTS-OFFSET FEF (1- (%P-LDB-OFFSET %%FEFHI-MS-ARG-DESC-ORG FEF %FEFHI-MISC))))) ; -- Special variables (COND ((ZEROP (LDB %%FEFH-SV-BIND HEADER)) (PRINC "There are no special variables present.")) (T (PRINC "There are special variables, ") (TERPRI) (COND ((ZEROP (LDB %%FEFHI-SVM-ACTIVE SV)) (PRINC "but the S-V bit map is not active. ")) (T (FORMAT T "and the S-V bit map is active and contains: ~O" (LDB %%FEFHI-SVM-BITS SV)))))) (TERPRI)) ((= header-type %HEADER-TYPE-FAST-FEF-FIXED-ARGS-NO-LOCALS) (setq no-adl-exists (%p-ldb-offset %%fefsl-no-adl fef %fefhi-storage-length)) (FORMAT T "The fast-fef option FIXED-ARGS-NO-LOCALS is selected.~%") (FORMAT T "It says there are ~s args.~%" (ldb %%fefh-args-for-fanl header))) ((= header-type %HEADER-TYPE-FAST-FEF-VAR-ARGS-NO-LOCALS) (setq no-adl-exists (%p-ldb-offset %%fefsl-no-adl fef %fefhi-storage-length)) (FORMAT T "The fast-fef option VAR-ARGS-NO-LOCALS is selected.~%") (format t "It says there are between ~s and ~s args.~%" (%p-ldb-offset %%fefh-min-args-for-vanl fef %fefhi-ipc) ;cdr-code (ldb %%fefh-max-args-for-vanl header))) ((= header-type %HEADER-TYPE-FAST-FEF-FIXED-ARGS-WITH-LOCALS) (setq no-adl-exists (%p-ldb-offset %%fefsl-no-adl fef %fefhi-storage-length)) (format t "The fast-fef option FIXED-ARGS-WITH-LOCALS is selected.~%") (format t "It says there are ~s args and ~s locals.~%" (%p-ldb-offset %%fefh-args-for-fawl fef %fefhi-ipc) ;cdr-code (ldb %%fefh-locals-for-fawl header))) ((= header-type %HEADER-TYPE-FAST-FEF-VAR-ARGS-WITH-LOCALS) (setq no-adl-exists (%p-ldb-offset %%fefsl-no-adl fef %fefhi-storage-length)) (format t "The fast-fef option VAR-ARGS-WITH-LOCALS is selected.~%") (format t "It says there are between ~s and ~s args and ~s locals.~%" (%p-ldb-offset %%fefh-min-args-for-vawl fef %fefhi-ipc) ;cdr-code (ldb %%fefh-max-args-for-vawl header) (ldb %%fefh-locals-for-vawl header))) (t (format t "The header type field (~s) is not a known code.~%" header-type) (setq no-adl-exists (%p-ldb-offset %%fefsl-no-adl fef %fefhi-storage-length)))) ;; -- Print out the fast arg option (FORMAT T "The Fast Argument Option is ~A" (IF (ZEROP (LDB %%FEFH-FAST-ARG HEADER)) "not active, but here it is anyway:" "active:")) (DESCRIBE-NUMERIC-DESCRIPTOR-WORD FAST-ARG) ; -- ADL. (COND ((ZEROP NO-ADL-EXISTS) (FORMAT T "There is an ADL: It is ~S long, and starts at ~S" (LDB %%FEFHI-MS-BIND-DESC-LENGTH MISC) (LDB %%FEFHI-MS-ARG-DESC-ORG MISC)) (DESCRIBE-FEF-ADL FEF) ) (T (PRINC "There is no ADL."))) (TERPRI) ;; -- Randomness. (FORMAT T "~%The length of the local block is ~S~%" (LDB %%FEFHI-MS-LOCAL-BLOCK-LENGTH MISC)) (FORMAT T "The total storage length of the FEF is ~S~%" LENGTH) (UNLESS DONT-MENTION-DEBUGGING-INFO (LET ((DBI (FEF-DEBUGGING-INFO FEF))) (WHEN DBI (FORMAT T "Debugging info:~%") (DOLIST (ITEM DBI) (FORMAT T " ~S~%" ITEM))))) ))) (DEFUN DESCRIBE-NUMERIC-DESCRIPTOR-WORD (N &AUX (MIN (LDB %%ARG-DESC-MIN-ARGS N)) (MAX (LDB %%ARG-DESC-MAX-ARGS N))) (FORMAT T "~& ") (IF (BIT-TEST %ARG-DESC-QUOTED-REST N) (PRINC "Quoted rest arg, ")) (IF (BIT-TEST %ARG-DESC-EVALED-REST N) (PRINC "Evaluated rest arg, ")) (IF (BIT-TEST %ARG-DESC-FEF-QUOTE-HAIR N) (PRINC "Some args quoted, ")) (IF (BIT-TEST %ARG-DESC-INTERPRETED N) (PRINC "Interpreted function, ")) (IF (BIT-TEST %ARG-DESC-FEF-BIND-HAIR N) (PRINC "Linear enter must check ADL, ")) (FORMAT T "Takes ~:[between ~D and ~D~;~D~] args.~%" (= MAX MIN) MIN MAX)) (defun describe-microcode-function (u-entry) (if (not (= (%data-type u-entry) dtp-u-entry)) (ferror nil "~s is not a dtp-u-entry" u-entry)) (format t "~&~s:~&entry-area index = ~s" u-entry (%pointer u-entry)) (let ((symbol-area-index (aref #'micro-code-entry-area (%pointer u-entry)))) (format t "~&entry-area contains ~s" symbol-area-index) (cond ((fixp symbol-area-index) (format t "~&symbol-area contains ~s" (aref #'micro-code-symbol-area symbol-area-index)))))) (defun describe-array (array) (let ((rank (array-rank array)) (long-length-flag (%p-ldb-offset %%array-long-length-flag array 0))) (format t "~%This is an ~S type array. (element-type ~S)~%" (array-type array) (array-element-type array)) (case rank (0 (format T "It is of zero rank.")) (1 (format t "It is a vector, with a total size of ~S elements" (array-total-size array))) (t (format T "It is ~S-dimensional, with dimensions " rank) (dotimes (d rank) (format t "~S " (array-dimension array d))) (format t ". Total size ~S elements" (array-total-size array)))) (when (array-has-leader-p array) (let ((length (array-leader-length array))) (cond ((and (eq rank 1) (eq length 1) (fixnump (array-leader array 0))) (format t "~%It has a fill-pointer: ~S" (fill-pointer array))) (t (format t "~%It has a leader, of length ~S. Contents:" length) (format t "~% Leader 0~:[~; (fill-pointer)~]: ~S" (and (eq rank 1) (fixnump (array-leader array 0))) (array-leader array 0)) (dotimes (i (1- length)) (format t "~% Leader ~S: ~S" (1+ i) (array-leader array (1+ i)))))))) (when (array-displaced-p array) (cond ((array-indirect-p array) (format t "~%The array is indirected to ~S" (%p-contents-offset array (+ rank long-length-flag))) (and (array-indexed-p array) (format T ", with index-offset ~S" (%p-contents-offset array (+ rank long-length-flag 2)))) (format t "~%Description of that array:") (describe-1 (%p-contents-offset array (+ rank long-length-flag)))) (t (format t "~%The array is displaced to ~S" (%p-contents-offset array (+ rank long-length-flag)))))))) (defun describe-symbol (sym) (let ((symbol-package (symbol-package sym))) (format t "~%Symbol ~S is in ~:[no~;the ~:*~A~] package." sym (symbol-package sym)) (let ((tem nil)) (dolist (p *all-packages*) (unless (eq p symbol-package) (multiple-value-bind (s flag) (find-symbol sym p) (when (and flag (eq s sym) ;; are we talking about the same symbol ? (not (eq flag :inherited))) (push p tem))))) (when tem (format t "~% It is ~:[strangely~;also~] interned in package~P ~{~A~^, ~}" symbol-package (length tem) tem)))) (when (and (boundp sym) (not (keywordp sym))) (let ((*print-level* *describe-print-level*) (*print-length* *describe-print-length*)) (format t "~%The value of ~S is ~S" sym (symbol-value sym))) (describe-1 (symbol-value sym))) (when (fboundp sym) (let ((*print-level* *describe-print-level*) (*print-length* *describe-print-length*)) (ignore-errors (format t "~%The function definition of ~S is ~S: ~S" sym (symbol-function sym) (arglist sym)))) (describe-1 (symbol-function sym))) (do ((pl (symbol-plist sym) (cddr pl)) (*print-level* *describe-print-level*) (*print-length* *describe-print-length*)) ((null pl)) (format t "~%~S has property ~S: ~S" sym (car pl) (cadr pl)) (describe-1 (cadr pl))) (if (not (or (boundp sym) (fboundp sym) (symbol-plist sym))) (format t "~%It has no value, definition or properties")) nil) (defun describe-cons (l &aux (*print-circle* t)) (format t "~%~S is a cons" l)) (DEFUN DESCRIBE-LOCATIVE (X) (LET ((AREA (%AREA-NUMBER X))) (cond ((NULL AREA) (FORMAT T "~%~S is a locative pointer not into any area." X)) (t (FORMAT T "~%~S is a locative pointer into area ~S" X (AREA-NAME AREA)) (when (>= area (min si:working-storage-area si:nr-sym)) ;the first area which is not fixed. ; don't go through this trouble if the area might be dangerous ; to do %find-structure-header in. (LET* ((STRUC (%FIND-STRUCTURE-HEADER X)) (BASEP (%MAKE-POINTER DTP-LOCATIVE (%FIND-STRUCTURE-LEADER STRUC))) (BOUND (%MAKE-POINTER-OFFSET DTP-LOCATIVE BASEP (%STRUCTURE-TOTAL-SIZE STRUC)))) (IF (AND (OR (EQ BASEP X) (%POINTER-LESSP BASEP X)) (%POINTER-LESSP X BOUND)) (FORMAT T "~%It points to word ~D. of ~S~%" (%POINTER-DIFFERENCE X STRUC) STRUC) (FORMAT T "at some sort of forwarded version of ~S~%" STRUC)) (DESCRIBE-1 STRUC))))))) (DEFUN DESCRIBE-DEFSTRUCT (X &OPTIONAL DEFSTRUCT-TYPE) "Prints out a description of X, including the contents of each of its slots. DEFSTRUCT-TYPE should be the name of the structure so DESCRIBE-DEFSTRUCT can figure out the names of the slots of X. If X is a named structure, you don't have to provide DEFSTRUCT-TYPE. Normally the DESCRIBE function will call DESCRIBE-DEFSTRUCT if asked to describe a named structure; however, some named structures have their own way of describing themselves." (LET ((DESCRIPTION (GET (OR DEFSTRUCT-TYPE (IF (CONSP X) (CAR X) (NAMED-STRUCTURE-P X))) 'DEFSTRUCT-DESCRIPTION))) (FORMAT T "~%~S is a ~S~%" X (DEFSTRUCT-DESCRIPTION-NAME DESCRIPTION)) (DOLIST (L (DEFSTRUCT-DESCRIPTION-SLOT-ALIST DESCRIPTION)) (FORMAT T " ~S:~30T~S~%" (CAR L) (EVAL `(,(DEFSTRUCT-SLOT-DESCRIPTION-REF-MACRO-NAME (CDR L)) ',X)))) X)) ; also si::describe-defstruct-description in sys2;struct (defun describe-instance (instance) "Prints out each of the slots of INSTANCE. This bypasses the :DESCRIBE method of the instance." (let* ((flavor (%instance-flavor instance)) (ivars (flavor-all-instance-variables flavor))) (format t "~%~S is an instance of flavour ~S" instance flavor) (loop for v in ivars for n from 1 do (format t " ~S:~30T~S~%" v (%instance-ref instance n)))) instance) (defun describe-closure (cl) (if (interpreter-environment-closure-p cl) (describe-interpreter-closure cl) ;defined in sys; eval (let ((bindings (closure-bindings cl)) (sym nil) (offset nil)) (format t "~%~S is a closure of ~S~%" cl (closure-function cl)) (case (length bindings) (0 (format t "(No bindings)")) (1 (describe-lexical-closure-bindings bindings (closure-function cl) *standard-output*)) (t (do ((bindings bindings (cddr bindings))) ((null bindings)) (setq sym (%find-structure-header (car bindings)) offset (%pointer-difference (car bindings) sym)) (if (not (symbolp sym)) (format t " ~S" (car bindings)) (format t " ~[Print name~;Value~;Function~;Property list~;Package~] cell of ~S" offset sym)) (format t ":~40T~:[void~;~S~]~%" (location-boundp (cadr bindings)) (and (location-boundp (cadr bindings)) (contents (cadr bindings))))))) (unless (consp (closure-function cl)) ;don't describe interpreted functions. (describe-1 (closure-function cl)))))) (defun describe-lexical-closure-bindings (bindings function stream) (format t "Lexical environment:~%") (let ((map ())) (labels ((frob (fn depth) (let* ((di (debugging-info fn)) (m (cdr (assq 'compiler::lexical-ref-map di))) (o (cdr (assq ':internal-fef-offsets di)))) (dolist (x m) (let ((n (dpb (- (ldb (byte 12. 12.) (car x)) depth) (byte 12. 12.) (ldb (byte 12. 0) (car x))))) (unless (assq n map) (push (cons n (cadr x)) map)))) (dolist (x o) (frob (%p-contents-offset fn x) (1+ depth)))))) (frob function 0)) (loop for frame in (car bindings) for f from 0 when (eq frame 't) do (format stream " (Context ~D empty.)~%" f) else do (format stream " Context ~D~%" f) (loop for x in frame for i from 0 as code = (dpb f (byte 12. 12.) i) as name = (cdr (assq code map)) do (format stream " Slot ~D~:[ :~8@T~; (~:*~S)~]~1,8@T~S~%" i name x))))) (DEFUN DESCRIBE-SELECT-METHOD (M) (FORMAT T "~%~S handles:" M) (DO ((ML (%MAKE-POINTER DTP-LIST M) (CDR ML))) ((ATOM ML) (UNLESS (NULL ML) (FORMAT T "~% anything else to ~S" ML) (IF (AND (SYMBOLP ML) (BOUNDP ML)) (FORMAT T " -> ~S" (SYMBOL-VALUE ML))))) (cond ((ATOM (CAR ML)) (FORMAT T "~% subroutine ~S" (CAR ML))) (t (FORMAT T "~% ~S: ~34T" (CAAR ML)) (OR (EQ (FUNCTION-NAME (CDAR ML)) (CDAR ML)) (PRINC "#'")) (PRIN1 (FUNCTION-NAME (CDAR ML))))))) (defun describe-all-areas () (dolist (a (current-area-list)) (describe-area a))) (defun describe-area (area) "Describe area AREA and all of its regions." (ctypecase area (area-name (setq area (symbol-value area))) (area-number)) (multiple-value-bind (length used regions) (room-get-area-length-used area) (declare (ignore length used)) (format t "~&Area #~A: ~S has:~ ~% volatility ~A~ ~% region-size #o~O~ ~% map-status #o~O ~:[(WRITE-READ)~;(READ-ONLY)~]~ ~% swap quantum ~D.~%" area (area-name area) (%area-volatility area) (%area-region-size area) (%area-map-status area) (= (%area-map-status area) %pht-map-status-read-only) (%area-swap-recommendations area)) (when (area-temporary-p area) (format t "It is a temporary area.~%")) (format t "It has ~D. region~P:~%" regions regions) (for-every-region-in-area (region area) (describe-region region)) t)) (DEFUN DESCRIBE-ALL-REGIONS NIL "Tell all about all regions." (DO ((REGION (1- NUMBER-OF-REGIONS) (1- REGION))) ((MINUSP REGION)) (DESCRIBE-REGION REGION))) (defun describe-region (region) "Tell all about the region number REGION." (let ((h (ldb si:%%virtual-page-structure-handle (aref #'system:virtual-page-data (lsh (%region-origin region) -8)))) (area-from-region-area-map (aref #'system:region-area-map region))) (format t " Region #~A: Origin ~O, Length ~O, Used ~O, region-area-map ~O " region (%pointer-unsigned (%region-origin region)) (%region-length region) (%region-free-pointer region) area-from-region-area-map) (cond ((not (zerop (logand #o377 (ldb si:%%virtual-page-first-header h)))) (format t "~2% The initial header begins on word ~o, not ZERO!!!" (ldb si:%%virtual-page-first-header h)) (if (not (minusp area-from-region-area-map)) ;dont bomb on inactive regions. (let ((w0-dt (%p-data-type (%region-origin region)))) (format t "~% The data type of word 0 is ~s. ~2%" (nth w0-dt q-data-types)) (if (= w0-dt dtp-header) (format t "Header type is ~s. ~2%" (nth (%p-ldb %%header-type-field (%region-origin region)) q-header-types))))))) (cond ((not (zerop (ldb si:%%virtual-page-initial-qs h))) (format t "~2% Initial-boxed-qs for the first page is ~o, not ZERO!!! ~2%" (ldb si:%%virtual-page-initial-qs h))))) (let ((used (%region-free-pointer region)) (scavenged (%region-gc-pointer region))) (if (zerop (%region-scavenge-enable region)) (format t "Scavenger off, ") (cond ((= used scavenged) (format t "Scavenge done, ")) ((= used 0) (format t "Scavenged 0%, ")) (t (format t "Scavenged ~D%, " (truncate (* 100. (cl:/ (float scavenged) (float used))))))))) (format t "~A space, Vol=~D.~%" (nth (%region-type region) '(free old new new1 new2 new3 new4 new5 new6 static fixed extra-pdl copy moby-fixed moby-new)) (%region-volatility region)) (format t " Scavenge-enable ~s, Scavenge-carefully ~s, Flip enable ~s, Swapin quantum ~D~%" (%region-scavenge-enable region) (%region-scavenge-carefully region) (%region-flip-enable region) (%region-swap-recommendations region)) ) (defun describe-rational-number (number) (format t "~&~S is a rational number with numerator ~S and denominator ~S" number (numerator number) (denominator number))) (defun describe-complex-number (number) (format t "~&~S is a complex number with real part ~S and imaginary part ~S." number (realpart number) (imagpart number))) (defun describe-character (character) (setq character (cl:character character)) (format t "~&~S is a character with integer representation ~D, and code ~D Its control-bits are ~D~:[~4*~; (~@[Control~*~]~@[Meta~*~]~@[Super~*~]~@[Hyper~*~])~]. Its font is ~D" character (char-int character) (char-code character) (char-bits character) ( 0 (char-bits character)) (char-bit character :control) (char-bit character :meta) (char-bit character :super) (char-bit character :hyper) (char-font character)) character) ;;;; Room (DEFVAR ROOM '(WORKING-STORAGE-AREA MACRO-COMPILED-PROGRAM) "Areas to mention when ROOM is called with no args.") (defun room-get-area-length-used (area &aux (regions 0) (length 0) (used 0)) (for-every-region-in-area (region area) (incf regions) (incf length (%region-length region)) (incf used (%region-free-pointer region))) (values length used regions)) ;>> *print-package* (defun room-print-area (area) (let ((*package* (pkg-find-package "SYSTEM"))) (unless (null (area-name area)) (multiple-value-bind (length used regions) (room-get-area-length-used area) (if (= (%area-type area) %region-space-fixed) (format t "~51,1,1,'.<~S~;(~D region~:P)~> ~O/~O used. ~D% free.~%" (area-name area) regions used length (cond ((zerop length) 0) ((< length #o40000) (truncate (* 100. (- length used)) length)) (t (truncate (- length used) (truncate length 100.))))) (format t "~51,1,1,'.<~S~;(~D region~:P)~> ~DK allocated, ~DK used.~%" (area-name area) regions (ceiling length #o2000) (ceiling used #o2000)))))) t) ;;; (ROOM) tells about the default areas ;;; (ROOM area1 area2...) tells about those areas ;;; (ROOM T) tells about all areas ;;; (ROOM NIL) prints only the header, does not do any areas (DEFUN ROOM (&REST ARGS) "Print size and free space of some areas. ARGS can be areas, or T as arg means all areas. No args means use the areas whose names are members of the value of ROOM. NIL as arg means print a header but mention no areas." (LET ((FREE-SIZE (GET-FREE-SPACE-SIZE)) (PHYS-SIZE (SYSTEM-COMMUNICATION-AREA %SYS-COM-MEMORY-SIZE))) (FORMAT T "~&Physical memory: #o~O (~DK), Free space: #o~O (~DK)" PHYS-SIZE (TRUNCATE PHYS-SIZE #o2000) FREE-SIZE (TRUNCATE FREE-SIZE #o2000))) (MULTIPLE-VALUE-BIND (N-WIRED-PAGES N-FIXED-WIRED-PAGES) (COUNT-WIRED-PAGES) (FORMAT T ", Wired pages ~D+~D (~D~[~;.25~;.5~;.75~]K)~%" N-FIXED-WIRED-PAGES (- N-WIRED-PAGES N-FIXED-WIRED-PAGES) (TRUNCATE N-WIRED-PAGES (TRUNCATE #o2000 PAGE-SIZE)) (CL:REM N-WIRED-PAGES (TRUNCATE #o2000 PAGE-SIZE)))) (COND ((NULL ARGS) (SETQ ARGS ROOM)) ((EQUAL ARGS '(T)) (FORMAT T "Unless otherwise noted, area names are in the SYSTEM package~%") (SETQ ARGS (CURRENT-AREA-LIST)))) (COND ((NOT (EQUAL ARGS '(NIL))) (DOLIST (AREA ARGS) (ROOM-PRINT-AREA (IF (SYMBOLP AREA) (SYMEVAL AREA) AREA)))))) (DEFUN PRINT-AREAS-OF-WIRED-PAGES () (DO ((ADR (%REGION-ORIGIN PAGE-TABLE-AREA) (+ ADR 2)) (N (TRUNCATE (SYSTEM-COMMUNICATION-AREA %SYS-COM-PAGE-TABLE-SIZE) 2) (1- N))) ((ZEROP N)) (WHEN (AND (NOT (ZEROP (%P-LDB %%PHT1-VALID-BIT ADR))) (= (%P-LDB %%PHT1-SWAP-STATUS-CODE ADR) %PHT-SWAP-STATUS-WIRED)) (FORMAT T "~S " (AREF (SYMBOL-FUNCTION 'SYS:AREA-NAME) (%AREA-NUMBER (ASH (%P-LDB %%PHT1-VIRTUAL-PAGE-NUMBER ADR) 8))))))) (DEFUN COUNT-PAGES-IN-POSITION-FOR-FAST-CACHE () (DO ((ADR (%REGION-ORIGIN PAGE-TABLE-AREA) (+ ADR 2)) (N (TRUNCATE (SYSTEM-COMMUNICATION-AREA %SYS-COM-PAGE-TABLE-SIZE) 2) (1- N)) (IN-POSITION 0) (TOTAL 0)) ((ZEROP N) (FORMAT T "~%~D pages in position out of ~D total" IN-POSITION TOTAL)) (COND ((NOT (ZEROP (%P-LDB %%PHT1-VALID-BIT ADR))) (SETQ TOTAL (1+ TOTAL)) (COND ((= (LDB (BYTE 4 0) (%P-LDB %%PHT1-VIRTUAL-PAGE-NUMBER ADR)) (LDB (BYTE 4 0) (%P-LDB %%PHT2-PHYSICAL-PAGE-NUMBER (1+ ADR)))) (SETQ IN-POSITION (1+ IN-POSITION)))))))) (DEFUN count-unused-physical-pages () (DO ((ADR (%REGION-ORIGIN PAGE-TABLE-AREA) (+ ADR 2)) (N (TRUNCATE (SYSTEM-COMMUNICATION-AREA %SYS-COM-PAGE-TABLE-SIZE) 2) (1- N)) (total 0) (unused 0)) ((ZEROP N) (FORMAT T "~%~D pages out of ~D have never been used (~d%)" unused total (round (* 100. (cl:/ (float unused) total))))) (COND ((NOT (ZEROP (%P-LDB %%PHT1-VALID-BIT ADR))) (incf total) (if (= (%p-ldb %%pht1-virtual-page-number adr) %pht-dummy-virtual-address) (incf unused)))))) (defun show-virtual-memory-fragmentation (&optional (window tv:selected-window)) (unless (send window :operation-handled-p :draw-point) (ferror nil "Window does not support graphics operations")) (let* ((blinkers (tv:sheet-blinker-list window)) (visibility-list (mapcar #'(lambda (blinker) (send blinker :visibility)) blinkers))) (unwind-protect (progn (dolist (blinker blinkers) (send blinker :set-visibility nil)) (send window :clear-screen) (do* ((region 0 (add1 region)) (current-y 0) (current-x 0) (inside-width (send window :inside-width)) (vpage 0) region-fill region-size) ((= region 256) (multiple-value-bind (final-y final-x) (floor vpage inside-width) (send window :draw-triangle final-x final-y (- final-x 10) (+ final-y 10) (+ final-x 10) (+ final-y 10)) (cursorpos (+ (ceiling final-y (send window :line-height)) 2) 0))) (setq region-fill (ash (%region-free-pointer region) -8) region-size (ash (%region-length region) -8)) (cond ((<= region-fill (- inside-width current-x)) (send window :draw-line current-x current-y (+ current-x region-fill) current-y)) (t (send window :draw-line current-x current-y inside-width current-y) (send window :draw-line 0 (add1 current-y) (- region-fill (- inside-width current-x)) (add1 current-y)))) (if (<= region-size (- inside-width current-x)) (incf current-x region-size) (setq current-x (- region-size (- inside-width current-x)) current-y (add1 current-y))) (incf vpage region-size))) (mapcar #'(lambda (blinker vis) (send blinker :set-visibility vis)) blinkers visibility-list)))) ;(DEFCONST NUMERIC-ARG-DESC-INFO '( ;; %%ARG-DESC-QUOTED-REST 2501 ;; %%ARG-DESC-EVALED-REST 2401 ;; %%ARG-DESC-ANY-REST 2402 ;NON-ZERO IF HAS EITHER KIND OF REST ARG ;; %%ARG-DESC-FEF-QUOTE-HAIR 2301 ; CALLER MUST CHECK A-D-L FOR FULL INFO ;; %%ARG-DESC-INTERPRETED 2201 ; NO INFORMATION AVAILABLE (VAL=1000077) ;; %%ARG-DESC-FEF-BIND-HAIR 2101 ; LINEAR ENTER MUST CHECK A-D-L ; %%ARG-DESC-MIN-ARGS 0606 ;MINIMUM NUMBER OF REQUIRED ARGS ; %%ARG-DESC-MAX-ARGS 0006 ;MAXIMUM NUMBER OF REQUIRED+OPTIONAL ; ; ARGS. REST ARGS NOT COUNTED. ; )) (defun describe-args-info (args-info) (unless (fixnump args-info) (setq args-info (args-info args-info))) (dolist (x '((%%arg-desc-interpreted . "~%~:[C~;ompiled~;Non-c~]ompiled function") (%%arg-desc-any-rest . "~@[~%Has rest argument~]") (%%arg-desc-quoted-rest . "~@[~% Has quoted rest arg~]") (%%arg-desc-evaled-rest . "~@[~% Has evalled rest arg~]") (%%arg-desc-fef-quote-hair . "~@[~%Hairy fef arg quoting (caller must check FEF ADL)~]") (%%arg-desc-fef-bind-hair . "~@[~%Hairy fef binding~]") (%%arg-desc-min-args . "~*~%Minimum ~D. args.") (%%arg-desc-max-args . "~*~%Maximum ~D. args."))) (let ((tem (ldb (symbol-value (car x)) args-info))) (format t (cdr x) (not (zerop tem)) tem))) (fresh-line)) (defun describe-small-flonum (x) (format t "~%~S is a small flonum.~% " x) (format t "Excess-~O exponent #o~O, ~D-bit mantissa #o~O (~:[including sign bit~;with sign bit deleted~])" short-float-exponent-offset (%short-float-exponent x) short-float-mantissa-length (%short-float-mantissa x) short-float-implicit-sign-bit-p)) (defun describe-flonum (x) (format t "~%~S is a flonum.~% " x) (format t "Excess-~O exponent #o~O, ~D-bit mantissa #o~O (~:[including sign bit~;with sign bit deleted~])" single-float-exponent-offset (%single-float-exponent x) single-float-mantissa-length (%single-float-mantissa x) single-float-implicit-sign-bit-p)) (defun describe-bignum (x) (let ((len (%p-ldb-offset #o0022 x 0)) (barf nil)) (format t "~&~S is a bignum.~&It is ~R word~:P long. It is ~[positive~;negative~]. ~ It is stored starting at location: #o~O~&Its contents:~2%" x len (%p-ldb-offset #o2201 x 0) (%pointer x)) (do ((i 1 (1+ i))) ((> i len)) (unless (zerop (%p-ldb-offset #o3701 x i)) (setq barf t)) (format t "~&~3O: ~[ ~;*~]" i (%p-ldb-offset #o3701 x i)) (do ((ppss #o3601 (- ppss #o0100))) ((< ppss #o0001)) (write-char (digit-char (%p-ldb-offset ppss x i)))) (format t " ~O," (%p-ldb-offset #o3601 x i)) (do ((ppss #o3303 (- ppss #o0300))) ((< ppss #o0003)) (write-char (digit-char (%p-ldb-offset ppss x i)))) (princ " ") (do ((ppss #o3403 (- ppss #o0300))) ((< ppss #o0103)) (write-char (digit-char (%p-ldb-offset ppss x i)))) (format t ",~O ~O," (%p-ldb-offset #o0001 x i) (%p-ldb-offset #o3502 x i)) (do ((ppss #o3203 (- ppss #o0300))) ((< ppss #o0203)) (write-char (digit-char (%p-ldb-offset ppss x i)))) (format t ",~O" (%p-ldb-offset #o0002 x i))) (if barf (format t "~2&* = high order bit illegally 1, bug in bignum microcode?")) (terpri)) x)