;;; SHARAB -*-LISP-*- ;;; ************************************************************** ;;; ***** MACLISP ****** Sharable Extensions to LISP ************* ;;; ************************************************************** ;;; ** (C) Copyright 1980 Massachusetts Institute of Technology ** ;;; ****** This is a read-only file! (All writes reserved) ******* ;;; ************************************************************** (eval-when (eval compile) (or (get 'LODBYT 'VERSION) (load '((LISP) LODBYT))) (or (get 'UMLMAC 'VERSION) (load '((LISP) UMLMAC))) (setq ibase 8. base 8.) ) ;;; Following temporary macro is nearly an open-coding of HERALD, but ;;; differs so that the "version" number is available when compiling (defmacro (c-herald defmacro-for-compiling () defmacro-displace-call () ) (group-name &optional (version-number '||) (ofile 'MSGFILES)) (let* ((file (and (filep infile) (cond ((eq (status filesystem-type) 'DEC20) (cadddr (truename infile))) ('t (caddr (truename infile)))))) (v (cond ((and file (fixp (car (errset (readlist (exploden file)) () )))) file) ((symbolp version-number) version-number) ('t '||))) (text (copysymbol (symbolconc '|;Loading | group-name '| | v) () ))) (and (status feature COMPLR) (putprop text `(SPECIAL ,text) 'SPECIAL)) (putprop text 'T '+INTERNAL-STRING-MARKER) (set text text) (putprop group-name v 'C-VERSION) `(PROG2 (COND ((STATUS NOFEATURE NOLDMSG) (TERPRI ,OFILE) (PRINC ,text ,OFILE))) (DEFPROP ,group-name ,v VERSION)))) ;;; WARNING!! You loser, don't ever let the version number run over ;;; two digits. The 2nd filename "JONLxx" will lose, and also the ;;; 2nd filename of the dump file will lose ("SHBDMP xx.yyy" where ;;; "yyy" is the lisp version number over which the SHARABLE is built). (c-herald SHARABLE /38) ;;; Functions for creating heirachical MACLISP dumps on ITS. ;;; PURE-SUSPEND - suspend, but also delete pure pages that are shared with ;;; previous dumps, re-sharing them upon loading. No deletions ;;; are done unless PURE-SUSPEND is non-() and also unless ;;; (status FLUSH) ==> T; but regardless of deletions, starting ;;; up after a call to PURE-SUSPEND will cause sharing with the ;;; previous dumped files. Two arguments required - both passed ;;; to SUSPEND (q.v.) - but the second is analyzed as a file ;;; name and will cause a proceedable break loop if PDUMPing ;;; by SUSPEND will clobber an existing file. ;;; ANNOUNCE-&-LOAD-INIT-FILE - Handy little function for systems that want to ;;; to announce themselves upon loading, and try to load an ;;; "init" file. See the file JONL;SHARAB LISP for an example. ;;; First argument is a symbol, which is the "name" to be ;;; announced (if there is a VERSION property on this symbol, it ;;; will be included in the "announcement"); optional second ;;; argument is either () or a list of characters like returned ;;; by (STATUS JCL) to be parsed as filename to be used instead ;;; of the usual init file. If a third argument is supplied, it ;;; is a "fix" file to be loaded before loading the "name" init ;;; file. ;;; DEPURIFY-SYMBOL - depurifies, so that if pure pages have been deleted ... ;;; The value of DEPURIFY-SYMBOL is a list of symbols which ;;; must never be purified, since they are needed during the ;;; "chilly" load of the system. ;;; Hacked up during February 1980, by JONL, from the NSHARE file of GSB ;;; Comments, complaints, suggestions, etc. to BUG-LISP ;;; For Optimal sharing, this file should be loaded into a nearly fresh ;;; lisp, with PURE bound to T; in this case, *PURE ###must### be ;;; bound to () during the loading of this file. ;;; Then a pure dump is made by loading up other functions and data ;;; with *PURE set to T, and PURE set either to a small fixnum or to T. ;;; When finished loading, you probably want to set *PURE to (), and then ;;; call PURE-SUSPEND (rather than SUSPEND) with 2 arguments - the second ;;; arg is the name of the file to PDUMP into, and the first is passed to ;;; SUSPEND. If the first arg is (), then SUSPEND merely does the PDUMP ;;; and returns; if it is 0, SUSPEND will valret to DDT after PDUMPing. ;;; Hackers note - ;;; This only maps in pure pages from a file, and only pages which are ;;; not absolute. (It does not recognize public pages though.) ;;; It will not clobber an impure page in the job with a pure page from ;;; a file. If, however, an earlier dump has had a patch put into a ;;; pure area and the page has been repurified, then that change will ;;; propagate to all dumps made from that one. ;;; It also tries to distinguish a page which has been patchd and ;;; repurified, but is not part of a dumped file. (declare (special *SHARING-FILE-LIST* |+internal-page-map/|| PURE-SUSPEND COMMUNIZE-SINGLE-FILE COMMUNIZE-FILE-ARRAY) (*expr PURE-SUSPEND COMMUNIZE-SINGLE-FILE) (special JOB-MSG-FILE) (setq USE-STRT7 'T)) ;;; Can only play the FLUSH game if this file is loaded with PURE = T ;;; Otherwise, you may try to "CALL 1 'CONS" during COMMUNIZE, and find ;;; that the plist of CONS was on a pure page which is not yet back! (eval-when (load) (or (eq pure 'T) (error '|PURE must be "T" when loading SHARABLE|)) ) (setq-if-unbound *SHARING-FILE-LIST* () PURE-SUSPEND 'T |+internal-page-map/|| () ) ;;; Information about the purity of pages is stored in a fixnum array, ;;; packed 8 4-bit bytes per word. Meaning of the 4 bits is: ;;; 0 - non-existent page ;;; 1 (1_0) - writeable page ;;; 2 (1_1) - LISP system pure page ;;; 4 (1_2) - other pure page ;;; 8 (1_3) - temporary setting for purity, just before suspension ;;; This array, "|+internal-page-map/||", is set up at the end of this file. (defmacro (LDB-A-BYTE defmacro-for-compiling () defmacro-displace-call () ) (&optional (index 'PAGE-NUMBER) (byte-size 4) (bytes-per-word 8) (ar '|+internal-page-map/||)) `(LOAD-BYTE (ARRAYCALL FIXNUM ,ar (// ,index ,bytes-per-word)) (* ,byte-size (\ ,index ,bytes-per-word)) ,byte-size)) (defmacro (DPB-A-BYTE defmacro-for-compiling () defmacro-displace-call () ) (byte &optional (index 'PAGE-NUMBER) (byte-size 4) (bytes-per-word 8) (ar '|+internal-page-map/||)) `(STORE (ARRAYCALL FIXNUM ,ar (// ,index ,bytes-per-word)) (DEPOSIT-BYTE (ARRAYCALL FIXNUM ,ar (// ,index ,bytes-per-word)) (* ,byte-size (\ ,index ,bytes-per-word)) ,byte-size ,byte))) (comment PURE-SUSPEND) (putprop 'PURE-SUSPEND (lsh bporg -10.) 'BPORG) (defun PURE-SUSPEND (argument-to-suspend file-namelist) (prog (*PURE NORET flushp oni b-low b-hi npurep purepage? tpno tmp file-object file-to-dump-to open-files flstbl flstbl-addr ) (declare (fixnum b-low b-hi npurep purepage? tpno flstbl flstbl-addr)) (setq npurep -1 purepage? 0 tpno 0) (setq b-low (1- (or (get 'PURE-SUSPEND 'BPORG) 1000.)) b-hi (1+ (or (get 'PURE-SUSPEND 'BPEND) -1000.))) (setq flushp (and PURE-SUSPEND (status FLUSH))) FIND-FILE (cond ((probef file-namelist) (terpri) (prin1 file-namelist) (princ '| will :PDUMP over existing file ?/ P to go ahead, or RETURN another file name/î|) (cond ((setq tmp (+internal-fac-break file-namelist)) (setq file-namelist tmp) (go FIND-FILE))))) (setq file-object (open file-namelist '(OUT FIXNUM SINGLE)) file-to-dump-to (truename file-object)) FIND-FLSTBL (cond ((null flushp) () ) ((null (setq tmp (cond ((getddtsym 'FLSTBL)) ((eq (status hactrn) 'DDT) (valret '|:SYMLOD/î:VP |) (getddtsym 'FLSTBL))))) (princ '|/îDDT symbols?|) (+internal-fac-break () ) (go FIND-FLSTBL)) ('T (setq FLSTBL tmp) ;Unpurify symbols of the file's namelist - so can call OPEN ; after dumping, but before pure data pages are loaded in. (mapc 'DEPURIFY-SYMBOL (append (car file-to-dump-to) (cdr file-to-dump-to))))) (cond ((null argument-to-suspend)) ((not (eq (status hactrn) 'DDT)) (setq argument-to-suspend () )) ((symbolp argument-to-suspend) (depurify-symbol argument-to-suspend))) (close file-object) (setq file-object () ) (and (boundp 'JOB-MSG-FILE) ;just in case LDDT is here (filep JOB-MSG-FILE) (setq tmp (status filemo JOB-MSG-FILE)) (push (cons JOB-MSG-FILE tmp) open-files)) ;; First, set up some data passed in thru special variable ;; Since this can do a GC, we must do it before we flush any pages. (setq COMMUNIZE-SINGLE-FILE (*array () 'FIXNUM 256.)) (gctwa) ; Since NORET is bound to NIL, this should minimize BPS pages (gc) ; This GC may close a few "lost" files (do ((l (munkam (examine (getddtsym 'GCMKL))) (cddr l)) (dedsar (getddtsym 'DEDSAR)) (losing-files) ) ((null l) (cond (losing-files (terpri) (prin1 losing-files) (princ '|/îFiles open during PURE-SUSPEND -- P to close them/î|) (+internal-fac-break losing-files) (mapc 'CLOSE losing-files )))) (cond ((or (eq (car l) dedsar) (not (filep (car l))) (null (setq tmp (status filemode (car l)))) ) () ) ((not (memq 'TTY (car tmp))) (push (car l) losing-files)) ((and (not (eq (car l) TYI)) (not (eq (car l) TYO))) (push (cons (car l) (car tmp)) open-files)))) ;; Round up binary program space to a page boundary. (This should ;; not be necessary but user's program may fail to do it.) (pagebporg) ;; Now, do the purification. This purifies all binary program space, ;; a and also list structure etc. which was 'purcopied'. (purify 0 0 'BPORG) ;; Save away the name of the file we are dumping to. (cond (*SHARING-FILE-LIST* (push file-to-dump-to (cdr *SHARING-FILE-LIST*))) ((setq *SHARING-FILE-LIST* (list file-to-dump-to)))) (dolist (x open-files) (close (car x))) ;; The next phase must be indivisible - hence NOINTERRUPT (setq oni (nointerrupt 'T)) (|+internal-call/|| () 'INIT) ;; Remember any newly shared pages, and disconnect others if flushing (dotimes (page-number 256.) (setq npurep (cond ((lessp b-low page-number b-hi) ;; This page needed for restart after SUSPEND, so ;; mark as "other pure", but not cuttable. 1_2) ((zerop (setq tpno (|+internal-call/|| page-number 'CORTYP))) ;; 0 ==> page doesn't exist, negative ==> impure 0) ((< tpno 0) ;; add 1_0 bit, and clr others except 1_1 (bit-set 1_0 (bit-clear #.(bit-clear 1_1 15.) (ldb-a-byte))) ) ('T -1))) (cond ((not (< npurep 0)) (dpb-a-byte npurep)) ;; If npurep = -1, then page is pure, and is a candidate for ;; for cutting out from pdump. ((bit-test (setq tpno (ldb-a-byte)) 1_1) ;; 1_1-bit of internal-page-map says, "LISP" system pure page (setq flstbl-addr (+ flstbl (// page-number 36.))) (and (cond ((null (|+internal-call/|| page-number 'DSK)) ;; But what if it was just patched? Then diddle ;; table SUSPEND uses, so that it isn't flushed (setq purepage? 0) ;; Also mark it as a "newly-shared" page (setq tpno #.(+ 1_3 1_1) ) 'T) ((bit-test tpno 1_2) ;; If dumped in previous round, then permit ;; SUSPEND to flush it in this round (setq purepage? 1) ;; Call it a "system" page, since SUSPEND will ;; flush it in the future (setq tpno 1_1) 'T)) (deposit flstbl-addr (deposit-byte (examine flstbl-addr) (- 35. (\ page-number 36.)) 1 purepage?)) (dpb-a-byte tpno))) ((bit-test tpno #.(+ 1_2 1_3)) ;Try to flush page from this job, if random shared page (and flushp (|+internal-call/|| page-number 'FLUSH))) ('t ;; Otherwise Mark as "newly-purified" page ;; (maybe flush next in next cascade pdump?) (dpb-a-byte 1_3) ))) ;; And finally, suspend. (suspend argument-to-suspend file-to-dump-to) (when flushp (dotimes (page-number 256.) ;Any page that was "newly purified" just before SUSPENDing ; is now a random sharable pure page, and may be cut out on ; subsequent dumps. So mark it in the internal-page-map. (and (bit-test (setq tpno (ldb-a-byte)) 1_3) (dpb-a-byte (bit-set 1_2 (bit-clear 1_3 tpno)))))) (nointerrupt oni) ;; Now, since we are suspended, map in the pages from other files ;; found on *SHARING-FILE-LIST*, which restores the "1_2" pages (mapc 'COMMUNIZE-SINGLE-FILE *SHARING-FILE-LIST*) (*rearray COMMUNIZE-SINGLE-FILE) (dolist (x open-files) (open (car x) (cadr x))) (return 'T))) (defun COMMUNIZE-SINGLE-FILE (file-namelist) (prog (file-page-number entry purepage? tmp) (declare (fixnum entry purepage? file-page-number)) (setq entry 0 file-page-number 1) ;; Unit mode: keeps the file array smaller (no buffer) (cnamef COMMUNIZE-FILE-ARRAY file-namelist) (setq tmp (errset (open COMMUNIZE-FILE-ARRAY '(IN FIXNUM SINGLE)))) (cond ((or (atom tmp) (not (= (in COMMUNIZE-FILE-ARRAY) 0))) (princ '|;File not shared since it | msgfiles) (prin1 file-namelist msgfiles) (cond ((atom tmp) (princ '| could not be opened| msgfiles)) ((princ '| is not in PDUMP format| msgfiles))) ; (princ tmp msgfiles) (return (close COMMUNIZE-FILE-ARRAY)))) ;; Try to COMMUNIZE-SINGLE-FILE here! ;; Get page map from first block of file - 256. words (fillarray COMMUNIZE-SINGLE-FILE COMMUNIZE-FILE-ARRAY) (dotimes (page-number 256.) (setq entry (arraycall fixnum COMMUNIZE-SINGLE-FILE page-number)) (cond ((plusp entry) ;; < 0 ==> absolute page; = 0 ==> non-existent page (setq purepage? (load-byte entry 16. 2)) ;; File contains a page corresponding to PAGE-NUMBER? (or (plusp purepage?) (error 'COMMUNIZE-SINGLE-FILE)) (and ;; Read-only iff bits <2.9,2.8> is 01 (= purepage? 1.) ;; Tbl entry is 1 if page is writeable in most recent dump (not (bit-test 1 (ldb-a-byte))) ;; If not in us, or unpatched-pure in us (not (minusp (|+internal-call/|| page-number 'CORTYP))) ;; then map it in! (setq tmp (fetch-file-page/| page-number COMMUNIZE-FILE-ARRAY file-page-number)) ;; Non-null indicates an error. (error 'CORBLK)) (setq file-page-number (1+ file-page-number))))) (close COMMUNIZE-FILE-ARRAY))) (lap-a-list '( (lap |+internal-call/|| subr) (args |+internal-call/|| (() . 2)) ;a kind of "SYSCALL" (defsym *ruind 23 ; 2nd arg is "message" **rlfi 2 f*chan 11) (defsym immed-info 1000_22 ;arg ptrs for "CALL" uuo get-info 2000_22 get-error 3000_22 immed-control 5000_22 ) (cain 2 'CORTYP) ;"CORTYP" to do a "CORTYP" call (jrst 0 do-cortyp) (cain 2 'FLUSH) ;"FLUSH" to do a "CORBLK" call (jrst 0 do-flush) ; to delete a page from our map (cain 2 'DSK) ;"DSK" to find out if argument (jrst 0 dsk-sharedp) ; page is shared with dsk file (cain 2 'INIT) ;"INIT" to initialize above (jrst 0 dsk-sharedp-init) (cain 2 'FILE) ;"FILE" for finding file which (jrst 0 who-bore-me?) ; was loaded to make this job (lerr 0 (% sixbit |BAD MSG TO +internal-call!|)) do-flush (jsp t fxnv1) (*call 0 flush-request) (*lose) (jrst 0 fix1) flush-request (setz) (sixbit |CORBLK|) (immed-info 0 0) ;delete page (immed-info 0 -1) ;from myself (setz 0 tt) ;just 1 page, found in tt do-cortyp (*call 0 cortyp-request) (*lose) (jrst 0 fix1) cortyp-request (setz) (sixbit |CORTYP|) (0 0 @ a) ((setz get-info) 0 tt) dsk-sharedp-init (move tt (% SQUOZE 0 L)) (*eval tt) (*lose) (*suset 0 (% 0 0 t *ruind)) ;Get our user index (imuli tt 0 t) (move t (% squoze 0 UPGCP)) (*eval t) ;get address of first page map (*lose) (addi tt 0 t) ;get address of our page map (jsp t fxcons) ; circular links (movem A (special *OUR-PAGE-MAP-ADDRESS)) (move tt (% squoze 0 MMPEAD)) (*eval tt) (*lose) (movss 0 tt) (hrri tt tt) (*getloc tt) ;get contents of mmpead (jsp t fxcons) (movem a (special *ITS-VAL-MMPEAD)) (movei a 'T) (popj p) dsk-sharedp (move tt @ (special *OUR-PAGE-MAP-ADDRESS)) (move t 0 a) ;get page number (rot t -1) ;get offset into page table (addi tt 0 t) ;get location of page circular links table (movss 0 tt) ;address from which to fetch in left half (hrri tt tt) ;get result in TT (*getloc tt) ;get word (skipl 0 t) ;is our index even? (movss 0 tt) ;we want the other (left) half (trzn tt 400000) ;is it an MMP/MEMPNT entry? (jrst 0 yes-on-dsk) ; nope, probably not on disk (trze tt 200000) ;Is it a MEMPNT entry? (jrst 0 yes-on-dsk) ; Yes, I don't know what to do with these.. (add tt @ (special *ITS-VAL-MMPEAD)) ;index into mmp table (aos 0 tt) ;we want the second word (movss 0 tt) ;getloc wants absolute address in LH (hrri tt tt) ;we want the result in TT (*getloc tt) ;get the MMP second word (hrrzs 0 tt) ;we just look at the right half (jumpn tt yes-on-dsk) ;not on disk, not in shared-page hash table ret-nil (tdza a a) ;Ha, it's shareable yes-on-dsk (movei a 'T) (popj p) who-bore-me? (movei tt 1 flp) (hrli tt **rlfi) (jsp t (/0*0PUSH -4)) (*break 10. tt) (pushj p take2) (push p 1) (pushj p take2) (pop p 2) (jcall 2 'CONS) take2 (pop flp tt) (pushj p sixatm) (call 1 'NCONS) (push p 1) (pop flp tt) (pushj p sixatm) (pop p 2) (jcall 2 'CONS) (entry fetch-file-page/| subr) (move d ttsar b) (hrrz d f*chan d) (*call 0 fetch-request) (jrst 0 fix1) (jrst 0 ret-nil) fetch-request (setz) (sixbit |CORBLK|) (immed-info 0 1_12.) ;Control - Fail if can't find page (immed-info 0 -1) ;from myself (0 0 @ a) ;just 1 page into core (0 0 d) ;dsk channl number (0 0 @ c) ;just 1 page from file ((setz get-error) 0 tt) () )) (putprop 'PURE-SUSPEND (lsh bporg -10.) 'BPEND) (lap-a-list '((lap DEPURIFY-SYMBOL subr) (args DEPURIFY-SYMBOL (() . 1)) (hlrz t 0 A) (jsp r skipit?) ;Is the SY2 block marked pure? (hrrz t 1 t) (jsp r skipit?) ; or is the pname-list pure? (hlrz t 0 t) (jsp r skipit?) ; or even a pname-word pure? (movei A '() ) (popj p) skipit? (move tt t) ;If item is pure, then copy it (lsh tt -11) (move tt ST tt) (tlnn tt 40) ; unlesss it is alread pure (jrst 0 0 R) copyit (push p a) ;save original symbol (hlrz t 0 A) (hrrz t 1 t) (push p t) ;ptr to pname list (setz a) loop (skipn t @ 0 P) ;depurify the pname list (jrst 0 goon) (move b a) (hlrz a t) (hrrzm t 0 P) (jsp t fxnv1) (jsp t fwcons) (call 2 'CONS) (jrst 0 loop) goon (call 1 'NREVERSE) (sub p (% 0 0 1 1)) (movei b '() ) (call 2 'PNPUT) ;really only interested in sy2 block (move b a) (pop p a) ;original symbol (hlrz r 0 b) ;addr of new sy2 block (hlrz d 0 a) ;addr of old sy2 block (move t 0 d) (tlo t 300) ;CCN bits etc. (movem t 0 r) ;transfer first word of sy2-block (move t 1 d) (hllm t 1 r) ;transfer args property (hrlm r 0 a) ;clobber in new sy2 block (popj p) () )) ;;;; ANNOUNCE-&-LOAD-INIT-FILE ; (program-name &optional jcl-line fix-file) ; "program-name" is the name of the program to be announced. ; It should have a VERSION property. It will also be used ; as the FN2 of the (default) init file to be loaded. ; JCL-LINE should be () or a line of JCL to be parsed as a file ; to use instead of the normal init file. ; FIX-FILE is a file of fixes to be loaded at startup time, just ; before loading the init file. ; This function is grossly hacked to fit in the small amount of ; core we have on this page. (defun ANNOUNCE-&-LOAD-INIT-FILE n (and (not (= n 0)) (let ((INFILE 'T) (ERRSET) (opsys (status OPSYS)) (name (arg 1) ) jclp usn uid ofile file fix-file ) (setq DEFAULTF `((,(cond ((eq opsys 'TOPS-20) 'PS) ('DSK)) ,(status UDIR)) * ,(cond ((eq opsys 'ITS) '>) ('T 'LSP)))) (terpri) (princ name) (cond ((setq uid (get name 'VERSION)) (princ '| |) (princ uid))) (princ '#.(maknam (nconc (exploden '| (in SHARABLE | ) (exploden (get 'SHARABLE 'C-VERSION)) (exploden '|, LISP |)))) (princ (status LISPV)) (tyo #/) ) (terpri) (and (> n 2) (setq fix-file (arg 3))) (cond ((and fix-file (setq fix-file (probef fix-file))) (terpri) (princ '|;Loading FIX file |) (prin1 (namestring fix-file)) (let (FASLOAD) (load fix-file)) (terpri) )) (setq jclp (and (> n 1) (arg 2)) usn (cond ((status status HOMED) (status HOMED)) ((status UDIR))) uid (cond (jclp (maknam (nreverse (cdr (reverse jclp))))) ((status USERID))) ofile (mergef uid `((DSK ,usn) * ,name)) file (probef ofile)) (cond ((cond (file (setq uid (cadr ofile)) 'T) ((eq opsys 'ITS) (rplaca (cdr ofile) '*) (setq uid usn) (setq file (errset (open ofile '(NODEFAULT)) () )) (cond ((and (not (atom file)) (car file)) (setq file (truename (car file))) (and (not (eq (cadr file) '*)) (setq uid (cadr file))) (close file) 'T)))) (princ '|/îLoading |) (princ name) (princ '| INIT file for |) (princ uid) (terpri) (and (atom (errset (load file))) (princ '| **** Errors while loading|))) ('T (setq file () ))) '*))) (eval-when (load) (prog (*rset file-page-table file-namelist x y) ; set up shared pages table (declare (fixnum page-number n i x)) (setq file-page-table (array () FIXNUM 256.) COMMUNIZE-FILE-ARRAY (open (|+internal-call/|| () 'FILE) '(IN FIXNUM SINGLE)) file-namelist (truename COMMUNIZE-FILE-ARRAY)) (cond ((cond ((not (= (in COMMUNIZE-FILE-ARRAY) 0)) (setq y () ) 'T) ((or (not (memq (cadr file-namelist) '(PURQIO PURQIX))) (not (eq (caddr file-namelist) (status LISPV)))) (setq y 'T) 'T)) (princ '|/îFile | msgfiles) (prin1 (namestring file-namelist) msgfiles) (princ '| is not this pdump'd LISP file| msgfiles) (cond ((null y) (error '|LISP| COMMUNIZE-FILE-ARRAY)) ('t (princ '|/îThis has been only a courtesy warning message/î| msgfiles))))) (fillarray file-page-table COMMUNIZE-FILE-ARRAY) (close COMMUNIZE-FILE-ARRAY) (setq y (array () FIXNUM 32.)) (unwind-protect (do ((page-number 0 (1+ page-number)) (x 0) (n 0) (i 0 (+ i 4)) ) ((= page-number 256.) (mapc 'DEPURIFY-SYMBOL (setq DEPURIFY-SYMBOL (append (car file-namelist) (cdr file-namelist) '(COMMUNIZE-SINGLE-FILE COMMMUNIZE-FILE-ARRAY CORBLK DSK |:PDUMPED/î| )))) ; Success! (setq |+internal-page-map/|| y)) (setq x (arraycall FIXNUM file-page-table page-number)) (cond ((and (plusp x) (= (logand 3 (lsh x -16.)) 01)) ; LISP system pure pages, which LISP itself ; will cut out during a suspend (setq n (+ n (lsh 1_1 i))))) (cond ((= i 28.) (store (arraycall FIXNUM y (// page-number 8.)) n) (setq i -4 n 0))) ))) )