;;; -*- Mode:LISP; Package:SYSTEM-INTERNALS; Base:8; Readtable:CL -*- ;;; (c) Copyright 1985, Lisp Machine Incorporated (LMI). (defsubst page-number (address) (ldb (byte #o21 #o10) (%pointer address))) (defsubst page-index (address) (ldb (byte #o10 #o00) (%pointer address))) (defsubst page-volatility (page) (aref #'virtual-page-volatility page)) (defsubst page-structure-handle (page) (%p-pointer (%pointer-plus (%region-origin virtual-page-data) page))) (defsubst page-first-header (page) (%p-ldb (byte #o11 #o11) (%pointer-plus (%region-origin virtual-page-data) page))) (defsubst page-initial-qs (page) (%p-ldb (byte #o11 #o00) (%pointer-plus (%region-origin virtual-page-data) page))) ;;; Area table accessors. (defsubst %area-region-bits (area) (aref #'area-region-bits area)) (defsubst %area-region-list (area) (aref #'area-region-list area)) (defsubst %region-list-thread (region) (aref #'region-list-thread region)) (defsubst %area-region-size (area) (aref #'area-region-size area)) (defsubst %area-type (region) (%logldb #.%%region-space-type (%area-region-bits region))) (defsubst %area-flip-enable (region) (%logldb #.%%region-flip-enable (%area-region-bits region))) (defsubst %area-scavenge-enable (region) (%logldb #.%%region-scavenge-enable (%area-region-bits region))) (defsubst %area-scavenge-carefully (region) (%logldb #.%%region-scavenge-carefully (%area-region-bits region))) (defsubst %area-volatility (region) (%logldb #.%%region-volatility (%area-region-bits region))) (defsubst %area-swap-recommendations (region) (%logldb #.%%region-swapin-quantum (%area-region-bits region))) (defsubst %area-map-status (region) (%logldb #.%%region-map-status-code (%area-region-bits region))) ;;; Region table accessors. (defsubst %region-origin (region) (aref #'region-origin region)) (defsubst %region-area (region) (aref #'region-area-map region)) (defsubst %region-bits (region) (aref #'region-bits region)) (defsubst %region-length (region) (aref #'region-length region)) (defsubst %region-gc-pointer (region) (aref #'region-gc-pointer region)) (defsubst %region-type (region) (%logldb #.%%region-space-type (%region-bits region))) (defsubst %region-representation-type (region) (%logldb #.%%region-representation-type (%region-bits region))) (defsubst %region-flip-enable (region) (%logldb #.%%region-flip-enable (%region-bits region))) (defsubst %region-scavenge-enable (region) (%logldb #.%%region-scavenge-enable (%region-bits region))) (defsubst %region-scavenge-carefully (region) (%logldb #.%%region-scavenge-carefully (%region-bits region))) (defsubst %region-volatility (region) (%logldb #.%%region-volatility (%region-bits region))) (defsubst %region-swap-recommendations (region) (%logldb #.%%region-swapin-quantum (%region-bits region))) (defsetf %region-free-pointer set-%region-free-pointer) (make-obsolete region-origin "use %REGION-ORIGIN") (make-obsolete region-size "use %REGION-SIZE") (make-obsolete region-free-pointer "use %REGION-FREE-POINTER") (make-obsolete region-bits "use %REGION-BITS") (make-obsolete region-length "use %REGION-LENGTH") (defsubst %pointer-volatility (pointer) "Volatility of the object pointer to by POINTER, as a fixnum from 0 to 3" (%region-volatility (%region-number pointer))) (defmacro for-every-structured-area ((area) &body body) "Execute BODY interatively with AREA bound to every area that contains lisp objects." `(do ((,area 0 (1+ ,area))) ((>= ,area number-of-areas)) (when (and (area-name ,area) (= (ldb %%region-representation-type (%area-region-bits area)) %region-representation-type-lisp)) ,@body))) (defmacro for-every-region-in-area ((region area) &body body) "Execute BODY iteratively with REGION bound to every region in AREA." (once-only (area) `(do ((,region (%area-region-list ,area) (%region-list-thread ,region))) ((minusp ,region)) ,@body))) (defmacro for-every-region ((region) &body body) (let ((bound (gensym))) `(do ((,bound sys:number-of-regions) (,region 0 (1+ ,region))) (( ,region ,bound)) ,@body))) (defun last-object-in-region (region) (%pointer-info (%pointer-plus (%region-origin region) (%make-pointer-offset dtp-fix (%region-free-pointer region) -1))) (%find-structure-leader (%pop))) (defun map-over-all-objects-in-newspace-region (region fun &aux last-object) (gc:without-flipping (select (ldb %%region-space-type (%region-bits region)) ((%REGION-SPACE-FREE %REGION-SPACE-OLD %REGION-SPACE-EXTRA-PDL %REGION-SPACE-MOBY-FIXED %REGION-SPACE-MOBY-NEW) (ferror nil "can't handle this region space type" )) ((%REGION-SPACE-NEW %REGION-SPACE-STATIC %REGION-SPACE-FIXED %REGION-SPACE-COPY)) (t (ferror nil "unknown region space type"))) (cond ((zerop (%region-free-pointer region))) (t (setq last-object (%make-pointer dtp-locative (last-object-in-region region))) (do-named main-loop ((adr (%make-pointer dtp-locative (%region-origin region)))) (()) ;;skip over list headers ;; find-structure-header doesn't currently work on them, but ;; structure-info says they are 1 word long (do () ((not (and (= (%p-data-type adr) dtp-header) (= (%p-ldb %%header-type-field adr) %header-type-list)))) (when (eq last-object adr) (return-from main-loop nil)) (setq adr (%make-pointer-offset dtp-locative adr 1))) ;;if this is a pointer to an array leader, skip to array header word (cond ((and (= (%p-data-type adr) dtp-header) (= (%p-ldb %%header-type-field adr) %header-type-array-leader)) (funcall fun (%make-pointer-offset dtp-array-pointer adr (%p-ldb %%array-leader-length adr)))) (t (funcall fun (%find-structure-header adr)))) (when (eq last-object adr) (return-from main-loop nil)) (setq adr (%make-pointer-offset dtp-locative adr (%structure-total-size adr)))))))) (defun map-over-all-objects-in-area (area fun) (when (not (= area wireable-structures-area)) (gc:without-flipping (gc:reclaim-oldspace) (for-every-region-in-area (region area) (select (ldb %%region-space-type (%region-bits region)) ((%REGION-SPACE-FREE %REGION-SPACE-OLD %REGION-SPACE-EXTRA-PDL %REGION-SPACE-MOBY-FIXED %REGION-SPACE-MOBY-NEW) ) ((%REGION-SPACE-NEW %REGION-SPACE-STATIC %REGION-SPACE-FIXED %REGION-SPACE-COPY) (map-over-all-objects-in-newspace-region region fun)) (t (ferror nil "unknown region space type"))))))) ;;; this should be used rarely, and should probably not remain ;;; in the system for long. Right now it needs to exist to ;;; fix 3.0 band for Beta release. -dg (defun bash-objects-in-every-pdl (data-type new-data-type new-pointer &key silent &aux pdl-list) (gc:without-flipping (gc:without-scavenging (map-over-all-objects-in-area pdl-area #'(lambda (object) (pushnew object pdl-list))) (dolist (pdl pdl-list) (dotimes (c (array-length pdl)) (let* ((locative (%make-pointer-offset dtp-locative pdl c)) (obj-data-type (%p-data-type locative))) (when (= obj-data-type data-type) (unless silent (format t "~&Bashing data type ~a found in ~s" (nth data-type q-data-types) (array-leader pdl 0))) (%p-store-tag-and-pointer locative new-data-type new-pointer)))))))) (defmacro with-quick-region-area-accessors (&body body) "This is a generalized version of an idiom I've been using to speed up region-table hacking inside loops. The basic idea is to keep the origins of the tables in local variables for the duration of the loop, and to use %p-pointer to get at the elements. This scheme is 4-5 times faster than doing arefs on the displaced arrays in the function cells of the area names. The syntax for all the accessors is the same (i.e. (%region-length region-number)), and setf works on them." ;; If you don't like the infringements on your namespace, fix this to use gensyms. ;; I for one don't really care, since I never use dots in my names. `(let ((.origins. (%region-origin sys:region-origin))) ;; There are two constraints that this code depends on for speed. First, for these ;; low areas, the region number is the same as the area number, so we can find the ;; base addresses just by looking in sys:region-origin (quickly). Second, all of ;; these addresses are very low, so we can use + instead of %pointer-plus without ;; fear of bignum ultra-lossage. (let ((region-bits.origin (%p-pointer (+ .origins. sys:region-bits))) (region-free-pointer.origin (%p-pointer (+ .origins. sys:region-free-pointer))) (region-gc-pointer.origin (%p-pointer (+ .origins. sys:region-gc-pointer))) (region-length.origin (%p-pointer (+ .origins. sys:region-length))) (region-area.origin (%p-pointer (+ .origins. sys:region-area-map))) (area-region-list.origin (%p-pointer (+ .origins. sys:area-region-list))) (region-list-thread.origin (%p-pointer (+ .origins. sys:region-list-thread)))) region-bits.origin region-free-pointer.origin region-gc-pointer.origin region-length.origin region-area.origin area-region-list.origin region-list-thread.origin (macrolet ((%region-bits (region) `(%p-pointer (+ region-bits.origin ,region))) (%region-free-pointer (region) `(%p-pointer (+ region-free-pointer.origin ,region))) (%region-gc-pointer (region) `(%p-pointer (+ region-gc-pointer.origin ,region))) (%region-length (region) `(%p-pointer (+ region-length.origin ,region))) (%region-area (region) `(%p-pointer (+ region-area.origin ,region))) (%area-region-list (area) `(%p-pointer (+ area-region-list.origin ,area))) (%region-list-thread (region) `(%p-pointer (+ region-list-thread.origin ,region)))) ,@body))))