;;; -*- Mode: Lisp; Base: 8; Package: moby-file-system; Readtable: ZL -*- ; COPYRIGHT LISP MACHINE INC 1985 ; CONFIDENTIAL ; This file contains trade secret information of Lisp Machine Inc. ; (However, I (RG) and LMI (to some extent) state their intention of making ; this technique "OPEN" at an appropriate time.) ;;; The virtual memory (defvar *n-vmem-pages* 16.) (defvar *moby-cached-dataspace-page* -1) ;find this guy fast. (defvar *moby-cached-vmem-idx* -1) ;associated vmem-idx. Dont reuse this one. ;(i,0) is dataspace-page-number-with-offset ;(i,1) is rqb ;(i,2) is mapping-alist elem ;(i,3) is modified flag. ;(i,4) is lock count. reuse this vmem-page entry only if 0. ;(i,5) is 16b rqb-buffer. (defvar *vmem-pages* (make-array (list *n-vmem-pages* 6))) (defvar *vmem-page-reuse-pointer*) (defun vmem-initialize () (setq *vmem-page-reuse-pointer* 0) (setq *moby-cached-dataspace-page* -1 *moby-cached-vmem-idx* -1) (dotimes (i *n-vmem-pages*) (aset -1 *vmem-pages* i 0) (aset nil *vmem-pages* i 1) (aset nil *vmem-pages* i 2) (aset nil *vmem-pages* i 3) (aset 0 *vmem-pages* i 4) (aset nil *vmem-pages* i 5))) ;fields in ph-root-dataspace-map-fields: ;(defconst %%ph-root-dataspace-map-fields-number-alts (byte 6 0)) ;defined mapping codes: ; 1: straight moby, 2 qs-per-q. ; 2: section relative, 1 q per q, no moby-format info. ; interpretation of 25 bit address: ; positive: relative address within section ; leading bits 10: other section, my offset to exit structure in root-section ; leading bits 11: root-section ; 3: section relative with moby-format, 1 q per q, 8 bits per q moby format stored at end. (defconst *mapping-code-description* #("Mapping code 0, invalid" "Straight moby, 2 Qs per Q" "Section relative, 1 Q per Q, no moby format info" "Section relative, 1 Q per Q, moby format stored separately at end")) (defconst *mapping-code-qs-per-lispm-q* #( nil 2.0 1.0 1.25)) ;mapping-code vectors ;-- obsolete ;layout of of low numbered blocks of moby partition. ; header 1 block partition-header defstruct. ; namespace-glob-table ; base, high, allocating ; dataspace-usage-count-array as necessary to accomodate ART-4B array for each block ; prime root-dataspace-map namespace used this namespace normally dataspace mapped to ; one of the below slots. ; * (defvar *root-section-region-size-in-pages* (ash 400000 -8.)) ;size of new regions in root-section (defvar *vmem-moby-partition-alist* nil) ;indexed by DATASPACE-WITH-OFFSET frobs. (defvar *vmem-moby-dataspace-offset-allocator* 0) (defun mpa-association-of-partition-header (partition-header) (dolist (e *vmem-moby-partition-alist*) (cond ((eq partition-header (mpa-partition-header e)) (return e))))) ;(defun vmem-find-mapping-for-partition (part-name) ; (dolist (e *vmem-moby-partition-alist*) ; (cond ((equal part-name (mpa-partition-name e)) ; (return e))))) ;--not used now. Hack for explorer.-- (defun moby-activate-partitions (&optional reboot partition-name (unit 0)) (if (not (boundp '*vmem-page-reuse-pointer*)) (vmem-initialize)) (if (not (boundp '*moby-page-association*)) (moby-initialize-transforms)) (if (null partition-name) (setq partition-name (nth (if (boundp 'si:*my-proc-number*) si:*my-proc-number* 0) '("MOBY" "MBY1" "MBY2")))) (let ((partition-list (si:partition-list nil unit))) (dolist (e partition-list) (cond ((equal (first e) partition-name) (vmem-activate-partition-explicit (second e) (third e) unit reboot)))) )) (defun vmem-initialize-partition (part-name partition-host-name moby-base-namespace-page moby-namespace-pages mapping-code &optional (unit 0) (percentage-double-mapped .25s0) (usage-count-array-type 'art-4b)) (format t "~%Use this only when partition is unique!") (multiple-value-bind (part-base part-length) (si:find-disk-partition part-name nil unit) (if (null part-base) (ferror nil "Partition ~s not found" part-name) (cond ((yes-or-no-p "Do you really want to initialize moby partition ~s on unit ~s, moby namespace page ~o, ~o moby namespace pages with storage code ~d,(~a)?" part-name unit moby-base-namespace-page moby-namespace-pages mapping-code (aref *mapping-code-description* mapping-code)) (vmem-initialize-partition-explicit part-base part-length partition-host-name moby-base-namespace-page moby-namespace-pages mapping-code unit percentage-double-mapped usage-count-array-type) (setq *moby-local-package-host* partition-host-name)))))) (defun vmem-initialize-partition-explicit (part-base part-length partition-host-name &optional moby-base-namespace-page moby-namespace-pages mapping-code (unit 0) (percentage-double-mapped .25s0) (usage-count-array-type 'art-4b) (partition-header-namespace-length-in-pages 64.) (root-mapping-namespace-length-in-pages 100) ;pages root-mapping-section region ;can expand to. Thus, root-area can grow approximately to this shifted by 16. Qs, ;since root-mapping area is limited to this single region. (size-of-root-mapping-section-map 6) (initial-size-of-root-section-map 4) &aux mpa partition-header-area partition-header root-mapping-area root-area) ;compute dataspace-length-in-pages (let* ((host-index (moby-assign-host-index (list 'initializing))) ;reserve ... (partition-header-area-name (moby-partition-header-area-name-for-partition-host partition-host-name)) (root-mapping-area-name (moby-root-mapping-area-name-for-partition-host partition-host-name)) (root-area-name (moby-root-area-name-for-partition-host partition-host-name)) (qs-per-q (aref *mapping-code-qs-per-lispm-q* mapping-code)) (total-blocks (truncate part-length qs-per-q)) (number-double-mapped-blocks (fix (* percentage-double-mapped (truncate total-blocks (+ 1.0 percentage-double-mapped))))) (dataspace-length-in-pages (- total-blocks number-double-mapped-blocks)) (usage-count-array-entry-number-values (expt 2 (cdr (assq usage-count-array-type array-bits-per-element)))) (base-dataspace-page-with-offset *vmem-moby-dataspace-offset-allocator*) (high-dataspace-page-with-offset+1 (+ base-dataspace-page-with-offset dataspace-length-in-pages)) (fake-partition-header-map ;just like real thing but in working-storage. (moby-make-fake-map partition-header-area-name moby-base-namespace-page 1 partition-header-namespace-length-in-pages (dpb 1 %%area-moby-option-double-mapped 0))) ) (incf *vmem-moby-dataspace-offset-allocator* dataspace-length-in-pages) (setq partition-header-area (moby-setup-area partition-header-area-name 'partition-header nil nil host-index)) (moby-store-map-for-area partition-header-area fake-partition-header-map 'all nil host-index) (if (not (boundp root-mapping-area-name)) (moby-setup-area root-mapping-area-name 'root-mapping nil nil host-index)) (setq root-mapping-area (symeval root-mapping-area-name)) (if (not (boundp root-area-name)) (moby-setup-area root-area-name 'root nil nil host-index)) (setq root-area (symeval root-area-name)) ;add to *vmem-moby-partition-alist* (push (setq mpa (make-mpa-element :dataspace-origin base-dataspace-page-with-offset :dataspace-highest-+1 high-dataspace-page-with-offset+1 :mapping-code mapping-code :physical-unit unit :partition-origin part-base :partition-length part-length :partition-header-area partition-header-area ;:partition-header filled in below. :root-mapping-area root-mapping-area :root-area root-area :single-mapped-dataspace-usage-occurance-counts (make-array usage-count-array-entry-number-values :initial-element 0) :double-mapped-dataspace-usage-occurance-counts (make-array usage-count-array-entry-number-values :initial-element 0) :local-host-index host-index)) *vmem-moby-partition-alist*) ;wipe whole partition. This is necessary to initialize moby bits, among other things. (let* ((i (vmem-find-page base-dataspace-page-with-offset nil))) (do ((mp base-dataspace-page-with-offset (1+ mp)) (rqb (aref *vmem-pages* i 1)) (c 0 (1+ c))) ((= c dataspace-length-in-pages)) ;should hack double-mapped area. (vmem-disk-io rqb mp t (aref *vmem-pages* i 2)))) (setq partition-header (make-partition-header :MAKE-ARRAY (:AREA PARTITION-HEADER-AREA) :code 1 :mapping-code mapping-code :magic-number *moby-partition-header-magic-number* :partition-header-low-namespace-page moby-base-namespace-page :partition-header-high-namespace-page (+ moby-base-namespace-page partition-header-namespace-length-in-pages) :dataspace-length-in-pages dataspace-length-in-pages :number-double-mapped-blocks number-double-mapped-blocks ; :root-section-options ; (dpb 1 %%section-option-update-on-request-only ; (dpb 1 %%section-option-reconcile-on-swapin ; (dpb 1 %%section-option-self-relative 0))) ; :root-section-namespace-length-in-pages ; local-region-length-in-pages ; :root-dataspace-map-length-in-pages ; root-dataspace-map-length-in-pages ; :root-dataspace-map-fields ; (dpb number-root-alternates ; %%ph-root-dataspace-map-fields-number-alts ; 0) ; :root-dataspace-map-base-relative-page ; root-dataspace-map-base-relative-page )) (setf (mpa-partition-header mpa) partition-header) ;now cons "real" partition-header map in partition-header-area, to replace fake one. (let ((real-partition-header-map (moby-make-section-map partition-header-area nil nil partition-header-area 1 (dpb 1 %%area-moby-option-double-mapped 0)))) (array-push real-partition-header-map (let ((default-cons-area partition-header-area)) (si:copy-object (aref fake-partition-header-map 0)))) (let ((real-region-map (aref real-partition-header-map 0)) (real-region (one-and-only-region-of-area partition-header-area))) (setf (aref *region-to-region-map* ;update to pointer at real thing, not fake. real-region) real-region-map) (setf (aref *region-fresh-cons-boundary* real-region) (rm-free-pointer real-region-map)) (setf (rm-locally-mapped-region real-region-map) real-region)) (setf (ph-partition-header-section-map partition-header) real-partition-header-map) (moby-store-map-for-area partition-header-area real-partition-header-map 'all nil host-index)) ; ;map-moby-handle is set right by moby-make-section-map, even here. ; (let ((msa (aref *area-to-msa* partition-header-area))) ; (setf (msa-map-moby-handle msa) ; (local-to-moby-corresondance real-partition-header-map))) ;now root-mapping-section-map can be CONSed in partition-header-area. (let ((root-mapping-section-map (moby-make-section-map partition-header-area nil nil root-mapping-area size-of-root-mapping-section-map (dpb 1 %%area-moby-option-double-mapped 0)))) (setf (ph-root-mapping-section-map partition-header) root-mapping-section-map) (let ((region-map (moby-make-region-map nil partition-header-area (+ moby-base-namespace-page ;area where bignum cons happens doesnt matter since moby-form is immediate. partition-header-namespace-length-in-pages) root-mapping-namespace-length-in-pages))) (array-push root-mapping-section-map region-map)) ;this will actually add an appropriate region to root-mapping-area. Now it can be consed in. (moby-store-map-for-area root-mapping-area root-mapping-section-map 'all nil host-index)) (moby-store-partition-header-for-area partition-header-area partition-header) (moby-store-partition-header-for-area root-mapping-area partition-header) (moby-store-partition-header-for-area root-area partition-header) (let ((namespace-allocation-structure (make-namespace-allocation-structure :make-array (:area root-mapping-area) :allocation-pointer (+ moby-base-namespace-page partition-header-namespace-length-in-pages root-mapping-namespace-length-in-pages) :allocation-limit (+ moby-base-namespace-page moby-namespace-pages) :allocation-alist nil))) ;fill in with cons from root-area (setf (ph-namespace-allocation-structure partition-header) namespace-allocation-structure)) (let ((double-mapped-usage-count-array (make-usage-count-array :make-array (:area root-mapping-area :length number-double-mapped-blocks :type usage-count-array-type) :fill-pointer number-double-mapped-blocks :base-dataspace-page 0 :ascending-count 0 :scan-pointer 0))) (setf (ph-double-mapped-usage-count-array partition-header) double-mapped-usage-count-array) (setf (aref (mpa-double-mapped-dataspace-usage-occurance-counts mpa) 0) number-double-mapped-blocks)) (let* ((number-single-mapped-blocks (- dataspace-length-in-pages number-double-mapped-blocks)) (single-mapped-usage-count-array (make-usage-count-array :make-array (:area root-mapping-area :length number-single-mapped-blocks :type usage-count-array-type) :fill-pointer number-double-mapped-blocks :base-dataspace-page number-double-mapped-blocks :ascending-count 0 :scan-pointer 0))) (setf (ph-single-mapped-usage-count-array partition-header) single-mapped-usage-count-array) (setf (aref (mpa-single-mapped-dataspace-usage-occurance-counts mpa) 0) number-single-mapped-blocks)) ;it is critical that no dataspace has been assigned up to here. So these go ;at the beginning of the partition, which is what the activating bootstrapper assumes. (moby-assign-dataspace-to-area partition-header-area t) ;assign dataspace to whole thing. (moby-assign-dataspace-to-area root-mapping-area t) ;likewise ;now assigning local-cells in region-maps can win. (moby-declare-local-cells-for-area partition-header-area) (moby-declare-local-cells-for-area root-mapping-area ) ;cons root-section-map in root-mapping-section (let ((root-section-map (moby-make-section-map root-mapping-area nil nil root-area initial-size-of-root-section-map (dpb 1 %%area-moby-option-double-mapped 0)))) (setf (ph-root-section-map partition-header) root-section-map) (moby-add-region-to-map-and-allocate-namespace root-section-map nil *root-section-region-size-in-pages* partition-header) (moby-store-map-for-area root-area root-section-map 'all nil host-index)) (setf (ph-partition-host-name partition-header) (let ((default-cons-area partition-header-area)) (string-append partition-host-name))) ;by the time we try to read root-area in the bootstrap process, the dataspace mapping ; mechanisms are active. So this does not necessarily have to go in consecutive dataspace ; following the partition-header and root-mapping-area. However, we arrange that at least ; the first region does so for efficiency (or something). (moby-assign-dataspace-to-area root-area nil) ;only assign dataspace to root as used. ;initialize section header (moby-cons-section-directory-header partition-host-name mpa) ;declare local cells in usage-count-arrays. (moby-declare-local-cell (locf (uc-lock (ph-double-mapped-usage-count-array partition-header)))) (moby-declare-local-cell (locf (uc-lock (ph-single-mapped-usage-count-array partition-header)))) (let ((partition-host (define-moby-file-system-host partition-host-name mpa host-index))) (format t "~%Defined host ~s" partition-host-name) (moby-package-root partition-host) ;assure root;package-root.mby exists. (writeout-moby-package-root partition-host) (moby-writeout-root partition-host)) t)) (defun moby-writeout-all (&optional even-if-clean) (dolist (msa *moby-section-area-and-region-associations*) (moby-writeout-area (msa-area msa) even-if-clean))) (defun moby-writeout-root (partition-host &optional even-if-clean) (let ((mpa (send partition-host :mpa-defstruct)) (package-root-area (%area-number *moby-package-root*))) ;write them in this order since writing one can change the others. (do-forever (cond (*moby-package-root* (moby-writeout-area package-root-area))) ;root-area, root-maping-area and partition-header-area are hierarchial in that ; writing one cannot affect previous ones in that list. (moby-writeout-area (mpa-root-area mpa) even-if-clean) (moby-writeout-area (mpa-root-mapping-area mpa) even-if-clean) (moby-writeout-area (mpa-partition-header-area mpa) even-if-clean) (cond ((or (null *moby-package-root*) (moby-area-clean-p package-root-area)) (return t)))) (vmem-force-all))) (defun vmem-activate-partition (part-name unit) (multiple-value-bind (part-base part-length) (si:find-disk-partition part-name nil unit) (if part-base (vmem-activate-partition-explicit part-base part-length unit)))) ;values (partition-header root-dataspace-map section-root) (defun vmem-activate-partition-explicit (part-base part-length unit &aux mpa) (let* ((rqb (sys:get-disk-rqb 2)) (buf (sys:rqb-buffer rqb))) (sys:disk-read rqb unit part-base) (let* ((host-index (moby-assign-host-index (list 'activating))) (partition-header-area-placeholder '*moby-partition-header-area-placeholder*) (partition-header-area nil) ;temporarily (root-mapping-area nil) (root-area nil) ;q0 is array-header ;unfortunately, with the array-header q in there, the hack of assuming ; qs-per-lispm-q is 1 initially doesnt win.. could be hacked. *** (code (vmem-get-fix-unsigned 2 buf (1+ (get-defstruct-slot-index 'ph-code)))) (mapping-code (vmem-get-fix-unsigned 2 buf (1+ (get-defstruct-slot-index 'ph-mapping-code)))) (qs-per-lispm-q (fix (aref *mapping-code-qs-per-lispm-q* mapping-code))) (magic-number (vmem-get-fix-unsigned qs-per-lispm-q buf (1+ (get-defstruct-slot-index 'ph-magic-number)))) (partition-header-low-namespace-page (vmem-get-fix-unsigned qs-per-lispm-q buf (1+ (get-defstruct-slot-index 'ph-partition-header-low-namespace-page)))) (partition-header-high-namespace-page (vmem-get-fix-unsigned qs-per-lispm-q buf (1+ (get-defstruct-slot-index 'ph-partition-header-high-namespace-page)))) (partition-header-free-pointer (vmem-get-fix-unsigned qs-per-lispm-q buf (1+ (get-defstruct-slot-index 'ph-partition-header-free-pointer)))) (partition-header-length-in-pages (- partition-header-high-namespace-page partition-header-low-namespace-page)) (dataspace-length-in-pages (vmem-get-fix-unsigned qs-per-lispm-q buf (1+ (get-defstruct-slot-index 'ph-dataspace-length-in-pages)))) (number-double-mapped-blocks (vmem-get-fix-unsigned qs-per-lispm-q buf (1+ (get-defstruct-slot-index 'ph-number-double-mapped-blocks)))) (base-dataspace-page-with-offset *vmem-moby-dataspace-offset-allocator*) (high-dataspace-page-with-offset+1 (+ base-dataspace-page-with-offset dataspace-length-in-pages)) ) (sys:return-disk-rqb (prog1 rqb (setq rqb nil))) (incf *vmem-moby-dataspace-offset-allocator* dataspace-length-in-pages) ;check header (if (not (= magic-number *moby-partition-header-magic-number*)) (ferror nil "Header magic number does not check")) (makunbound partition-header-area-placeholder) ;just to make sure. (moby-setup-area partition-header-area-placeholder 'partition-header nil nil host-index) (setq partition-header-area (symeval partition-header-area-placeholder)) ;add to *vmem-moby-partition-alist* (push (setq mpa (make-mpa-element :dataspace-origin base-dataspace-page-with-offset :dataspace-highest-+1 high-dataspace-page-with-offset+1 :mapping-code mapping-code :physical-unit unit :partition-origin part-base :partition-length part-length :partition-header-area partition-header-area ;below have to be filled in later. ;:partition-header ;:root-mapping-area ;:root-area ;:single-mapped-dataspace-usage-occurance-counts ;:double-mapped-dataspace-usage-occurance-counts :local-host-index host-index )) *vmem-moby-partition-alist*) (format t"~%Activating partition header at namespace ~s, ~d moby pages, ~d disk-pages on unit ~s starting at ~s, partition-header-area ~s, mapping code ~d(~a)" partition-header-low-namespace-page dataspace-length-in-pages part-length unit part-base partition-header-area mapping-code (aref *mapping-code-description* mapping-code)) (let ((msa (aref *area-to-msa* partition-header-area))) (setf (msa-mpa msa) mpa)) ;normally gotten via association on partition-header ;this needs to be set up earlier here for bootstrapping. ;-- new plan ; make fake map from info bootstrapped info. ; recover partition-host-name ; create root-mapping-area and root-area with correct names. ; install root-mapping-area. ; install root-area. ;to successfully bootstrap partition-header-area ; local-to-moby-correspondance has to work -> #'sys:region-namespace-origin set up. ; moby-local-page-to-dataspace-page -> *region-to-region-map* set up. ; *region-to-msa*, msa-to-mpa, mpa-dataspace-origin. (let* ((fake-partition-header-map (moby-make-fake-map partition-header-area-placeholder partition-header-low-namespace-page 1 partition-header-length-in-pages (dpb 1 %%area-moby-option-double-mapped 0))) (fake-region-map (aref fake-partition-header-map 0))) (setf (rm-free-pointer fake-region-map) partition-header-free-pointer) (dotimes (p partition-header-length-in-pages) (setf (aref fake-region-map p) p)) ;direct map the partition-header. (setf (rm-fill-pointer fake-region-map) partition-header-length-in-pages) (moby-store-map-for-area partition-header-area fake-partition-header-map 'all nil host-index) (let* ((partition-header (moby-typed-pointer dtp-array-pointer (ash partition-header-low-namespace-page 8))) (partition-host-name (ph-partition-host-name partition-header))) (setf (mpa-partition-header mpa) partition-header) (moby-store-partition-header-for-area partition-header-area partition-header) (moby-smash-area-name partition-header-area-placeholder (moby-partition-header-area-name-for-partition-host partition-host-name)) ;touch Qs in real map now to reconcile them. This avoids the infinite recursive ; loop which would happen if an unreconciled trap was taken in ; moby-local-page-to-dataspace-page. Also touch rm-fill-pointer ; which is touched there. As long as we are using the fake map, there is no ; problem. (let ((real-partition-header-map (ph-partition-header-section-map partition-header))) (dotimes (i (array-length real-partition-header-map)) (let ((rm (aref real-partition-header-map i))) (cond (rm (dotimes (p (rm-fill-pointer rm)) (aref rm p)) (dotimes (p (array-leader-length rm)) (array-leader rm p)))))) ;touch array leader of section map. (dotimes (i (array-leader-length real-partition-header-map)) (array-leader real-partition-header-map i)) ;store real map over fake one. (moby-store-map-for-area partition-header-area real-partition-header-map 'all nil host-index) ; ;correct map-moby-handle ; (let ((msa (aref *area-to-msa* partition-header-area))) ; (setf (msa-map-moby-handle msa) ; (local-to-moby-correspondance real-partition-header-map))) ) (let ((root-mapping-area-name (moby-root-mapping-area-name-for-partition-host partition-host-name)) (root-area-name (moby-root-area-name-for-partition-host partition-host-name))) (moby-setup-area root-mapping-area-name 'root-mapping nil partition-header host-index) (setq root-mapping-area (symeval root-mapping-area-name)) (setf (mpa-root-mapping-area mpa) root-mapping-area) (moby-store-map-for-area root-mapping-area (ph-root-mapping-section-map partition-header) 'all nil host-index) (moby-setup-area root-area-name 'root nil partition-header host-index) (setq root-area (symeval root-area-name)) (setf (mpa-root-area mpa) root-area) (moby-store-map-for-area root-area (ph-root-section-map partition-header) 'all nil host-index)) (let* ((double-uc (ph-double-mapped-usage-count-array partition-header)) (double-ua-occur (make-array (cadr (array-element-type double-uc))))) (setf (mpa-double-mapped-dataspace-usage-occurance-counts mpa) double-ua-occur) (moby-count-occurances double-ua-occur double-uc)) (let* ((single-uc (ph-single-mapped-usage-count-array partition-header)) (single-ua-occur (make-array (cadr (array-element-type single-uc))))) (setf (mpa-single-mapped-dataspace-usage-occurance-counts mpa) single-ua-occur) (moby-count-occurances single-ua-occur single-uc)) (let ((sdh (ph-root-section-directory-header partition-header))) (when (null sdh) (format t "~%The partition-host of this partition has not been initialized.")) (define-moby-file-system-host partition-host-name mpa host-index) (format t "~%Defined host ~s" partition-host-name) (moby-walk-hierarchy-storing-moby-to-section sdh)) (setq *moby-local-package-host* partition-host-name) (values partition-header)))))) (defun moby-smash-area-name (old-name-symbol new-name-symbol) (set new-name-symbol (symeval old-name-symbol)) (setf (aref #'sys:area-name (symeval old-name-symbol)) new-name-symbol) ;(fset new-name-symbol (fsymeval old-name-symbol)) (do ((p (si:current-area-list) (cdr p))) ((null p) (ferror nil "Cant find ~s on current-area-list" old-name-symbol)) (cond ((eq (car p) old-name-symbol) (rplaca p new-name-symbol) (return nil)))) (do ((p si:room (cdr p))) ((null p)) (cond ((eq (car p) old-name-symbol) (rplaca p new-name-symbol) (return nil))))) (defun moby-cons-section-directory-header (name mpa) ;the section-directory-header is a somewhat specially distinguished section-item ... (let* ((partition-header (mpa-partition-header mpa)) (root-area (mpa-root-area mpa))) (let ((section-directory-header (make-moby-file :make-array (:area root-area) ))) (moby-declare-local-cell (locf (mfile-lock section-directory-header))) (setf (ph-root-section-directory-header partition-header) section-directory-header) (let* ((default-cons-area root-area) (moby-name (string-append name))) (setf (mfile-name section-directory-header) moby-name)) section-directory-header))) (defun lookup-section-directory-header (partition-host-name) (dolist (e *vmem-moby-partition-alist*) (let ((sdh (ph-root-section-directory-header (mpa-partition-header e)))) (cond ((string-equal partition-host-name (mfile-name sdh)) (return sdh)))))) (defun lookup-root-directory-files (partition-host-name) (let ((sdh (lookup-section-directory-header partition-host-name))) (if (null sdh) (ferror nil "Root not found") (mfile-files sdh)))) (defun find-root-directory (partition-host-name) (lookup-section-directory-header partition-host-name)) (defun root-area-of-partition-host (partition-host) (mpa-root-area (send partition-host :mpa-defstruct)) ; (dolist (e *vmem-moby-partition-alist*) ; (let ((sdh (ph-root-section-directory-header (mpa-partition-header e)))) ; (cond ((string-equal partition-host-name (mfile-name sdh)) ; (return (mpa-root-area e)))))) ) (defun mpa-of-partition-host (partition-host) (send partition-host :mpa-defstruct) ; (dolist (e *vmem-moby-partition-alist*) ; (let ((sdh (ph-root-section-directory-header (mpa-partition-header e)))) ; (cond ((string-equal partition-host-name (mfile-name sdh)) ; (return e))))) ) (defun mpa-of-partition-header (partition-header) (dolist (e *vmem-moby-partition-alist*) (cond ((eq partition-header (mpa-partition-header e)) (return e))))) (defun partition-header-of-partition-host (partition-host) (mpa-partition-header (send partition-host :mpa-defstruct)) ; (dolist (e *vmem-moby-partition-alist*) ; (let ((sdh (ph-root-section-directory-header (mpa-partition-header e)))) ; (cond ((string-equal partition-host-name (mfile-name sdh)) ; (return (mpa-partition-header e)))))) ) (defun moby-local-partition-host-name (localp) (let* ((region (%region-number localp)) (msa (aref *region-to-msa* region))) (cond ((msa-partition-header msa) (ph-partition-host-name (msa-partition-header msa))) (t *moby-local-package-host* ;(ferror nil "Need partition host for non local moby area") )) )) (defun moby-local-partition-host (localp) (let* ((region (%region-number localp)) (msa (aref *region-to-msa* region))) (aref *moby-host-index* (msa-host-index msa)))) (defun moby-mpa-double-mapped-dataspace-usage-occurance-counts (partition-host) (let ((mpa (send partition-host :mpa-defstruct))) (mpa-double-mapped-dataspace-usage-occurance-counts mpa))) (defun moby-mpa-single-mapped-dataspace-usage-occurance-counts (partition-host) (let ((mpa (send partition-host :mpa-defstruct))) (mpa-single-mapped-dataspace-usage-occurance-counts mpa))) (defun moby-dataspace-offset-of-partition-header (partition-header) (dolist (e *vmem-moby-partition-alist* (ferror nil "partition-header not found")) (cond ((eq partition-header (mpa-partition-header e)) (return (mpa-dataspace-origin e)))))) ;Return a positive integer, possibly a bignum. (defun vmem-get-fix-unsigned (qs-per-lispm-q buf idx) (let ((base-idx (* qs-per-lispm-q 2 idx))) (if (not (= dtp-fix (ldb (byte 5 9.) (aref buf (1+ base-idx))))) (ferror nil "Data type in section header not DTP-FIX")) (+ (ash (ldb (byte 9. 0) (aref buf (1+ base-idx))) 16.) (aref buf base-idx) (ash (aref buf (+ base-idx 2)) 25.) (ash (ldb (byte 9 0) (aref buf (+ 3 base-idx))) 41.)))) ;;Return a 50. positive bignum stored as two consecutive 25. bit fixnums. ;;(each of those fixnums occupies QS-PER-LISPM-Q). A few things are ;;stored this way in the header for the convenience of single mapped partitions. ;(defun vmem-get-double-fix-unsigned (qs-per-lispm-q buf idx) ; (let ((base-idx (* qs-per-lispm-q 2 idx))) ; (if (not (= dtp-fix (ldb (byte 5 9.) (aref buf (1+ base-idx))))) ; (ferror nil "Data type in section header not DTP-FIX")) ; (let ((w1 (+ (ash (ldb (byte 9. 0) (aref buf (1+ base-idx))) 16.) ; (aref buf base-idx)))) ; (cond ((> qs-per-lispm-q 1) ; (if (not (= dtp-fix (ldb (byte 5 9.) (aref buf (+ 5 base-idx))))) ; (ferror nil "Data type in section header (high word) not DTP-FIX")) ; (let ((w2 (+ (ash (ldb (byte 9. 0) (aref buf (+ 5 base-idx))) 16.) ; (aref buf (+ 4 base-idx))))) ; (+ w1 (ash w2 25.)))) ; (t ; (if (not (= dtp-fix (ldb (byte 5 9.) (aref buf (+ 3 base-idx))))) ; (ferror nil "Data type in section header (high word) not DTP-FIX")) ; (let ((w2 (+ (ash (ldb (byte 9. 0) (aref buf (+ 3 base-idx))) 16.) ; (aref buf (+ 2 base-idx))))) ; (+ w1 (ash w2 25.)))))))) (defun vmem-get-mapping (dataspace-page-with-offset) (do ((p *vmem-moby-partition-alist* (cdr p))) ((null p) (ferror nil "unable to map moby page")) (cond ((and (not (< dataspace-page-with-offset (mpa-dataspace-origin (car p)))) (< dataspace-page-with-offset (mpa-dataspace-highest-+1 (car p)))) (return (car p)))))) ;Write out all the buffered pages and return the rqb's (defun vmem-finish (&optional no-write &aux rqb) (setq *moby-cached-dataspace-page* -1 *moby-cached-vmem-idx* -1) (dotimes (i *n-vmem-pages*) (cond ((setq rqb (aref *vmem-pages* i 1)) (cond ((and (null no-write) (aref *vmem-pages* i 3)) (vmem-disk-io rqb (aref *vmem-pages* i 0) t (aref *vmem-pages* i 2)))) (sys:return-disk-rqb rqb) (aset -1 *vmem-pages* i 0) (aset nil *vmem-pages* i 1) (aset nil *vmem-pages* i 2) (aset nil *vmem-pages* i 3) (aset 0 *vmem-pages* i 4) (aset nil *vmem-pages* i 5))))) (defun vmem-force-all (&aux rqb) (dotimes (i *n-vmem-pages*) (cond ((setq rqb (aref *vmem-pages* i 1)) (cond ((aref *vmem-pages* i 3) (vmem-disk-io rqb (aref *vmem-pages* i 0) t (aref *vmem-pages* i 2)))) (aset nil *vmem-pages* i 3))))) (defun vmem-force-write (dataspace-page-with-offset) (dotimes (i *n-vmem-pages*) (cond ((= (aref *vmem-pages* i 0) dataspace-page-with-offset) (cond ((aref *vmem-pages* i 3) (vmem-disk-io (aref *vmem-pages* i 1) dataspace-page-with-offset t (aref *vmem-pages* i 2)) (setf (aref *vmem-pages* i 3) nil))))))) (defun vmem-disk-io (rqb dataspace-page-with-offset writep mapping-elem) (funcall (if writep #'sys:disk-write #'sys:disk-read) rqb (mpa-physical-unit mapping-elem) (+ (mpa-partition-origin mapping-elem) ;below gets the main frob for section relative with moby format info mapping code. (* (fix (aref *mapping-code-qs-per-lispm-q* (mpa-mapping-code mapping-elem))) (- dataspace-page-with-offset (mpa-dataspace-origin mapping-elem)))))) ;Given address returns art-16b array containing that page. With second arg of nil ;initializes to dtp-trap instead of reading in from disk. (defun vmem-find-page (dataspace-page-with-offset &optional (get-from-disk-p t)) (do ((i 0 (1+ i)) (rqb) (buf)) (( i *n-vmem-pages*) (let ((mapping-elem (vmem-get-mapping dataspace-page-with-offset))) (do-forever (setq i *vmem-page-reuse-pointer*) (setq *vmem-page-reuse-pointer* (\ (1+ i) *n-vmem-pages*)) (cond ((and (zerop (aref *vmem-pages* i 4)) (not (= i *moby-cached-vmem-idx*))) (return)))) (cond ((setq rqb (aref *vmem-pages* i 1)) ;Swap this guy out (cond ((aref *vmem-pages* i 3) (vmem-disk-io rqb (aref *vmem-pages* i 0) t (aref *vmem-pages* i 2)) (setf (aref *vmem-pages* i 3) nil)))) (t (setq rqb (sys:get-disk-rqb 2)) (aset rqb *vmem-pages* i 1) (setf (aref *vmem-pages* i 3) nil) (setf (aref *vmem-pages* i 5) (sys:rqb-buffer rqb)))) (aset dataspace-page-with-offset *vmem-pages* i 0) (aset mapping-elem *vmem-pages* i 2) (setq buf (sys:rqb-buffer rqb)) (cond (get-from-disk-p (vmem-disk-io rqb dataspace-page-with-offset nil mapping-elem) (setf (aref *vmem-pages* i 3) nil)) (t (do ((j 0 (1+ j)) (high (dpb 1 %%moby-starts-object (ash dtp-trap (- 25. 16.)))) (idx-step (* 2 (fix (aref *mapping-code-qs-per-lispm-q* (mpa-mapping-code mapping-elem))))) (base-idx 0 (+ base-idx idx-step))) (( j si:page-size) (setf (aref *vmem-pages* i 3) t)) (aset 0 buf base-idx) (aset high buf (1+ base-idx)) (cond ((> idx-step 2) (aset 0 buf (+ 2 base-idx)) (aset 0 buf (+ 3 base-idx))))))) i)) (cond ((= (aref *vmem-pages* i 0) dataspace-page-with-offset) ;Already swapped in (and (= *vmem-page-reuse-pointer* i) (setq *vmem-page-reuse-pointer* (\ (1+ i) *n-vmem-pages*))) (return i))))) (defun print-vmem-status () (dotimes (i *n-vmem-pages*) (format t "~%Buffer index ~s: dataspace page with offset ~s, rqb ~s, mapping ~s, modified ~s, lock ~s, buffer ~s" i (aref *vmem-pages* i 0) (aref *vmem-pages* i 1) (aref *vmem-pages* i 2) (aref *vmem-pages* i 3) (aref *vmem-pages* i 4) (aref *vmem-pages* i 5)))) ;like LDB, but can load fields bigger than fixnum size. (DEFUN LDB-BIG (FLD WD) (PROG (ANS BITS BITS-OVER SHIFT) (SETQ SHIFT 0 ANS 0 BITS (LDB 0006 FLD) BITS-OVER (LDB 0620 FLD)) L (SETQ ANS (LOGIOR ANS (ASH (LDB (DPB BITS-OVER 0620 (MIN BITS 24.)) WD) SHIFT))) (IF ( (SETQ BITS (- BITS 24.)) 0) (RETURN ANS)) (SETQ SHIFT (+ SHIFT 24.) BITS-OVER (+ BITS-OVER 24.)) (GO L))) (DEFUN DPB-BIG (QUAN FLD WD) (PROG (ANS BITS BITS-OVER Q) (SETQ ANS WD BITS (LDB 0006 FLD) BITS-OVER (LDB 0620 FLD) Q QUAN) L (SETQ ANS (DPB (logand 77777777 Q) (DPB BITS-OVER 0620 (MIN BITS 24.)) ANS)) (IF ( (SETQ BITS (- BITS 24.)) 0) (RETURN ANS)) (SETQ Q (ASH Q -24.) BITS-OVER (+ BITS-OVER 24.)) (GO L))) (defun i () (inspect *vmem-moby-partition-alist*)) (defun e () (moby-exhibit *vmem-moby-partition-alist*)) (defun m () (inspect *moby-section-area-and-region-associations*)) (pushnew :moby *features*) ;not used currently. (defun moby-fetch-quarters (local-address) (let ((idx (ash (logand local-address 377) 2)) (dataspace-page (moby-local-page-to-dataspace-page (lsh local-address -8)))) (cond ((not (= dataspace-page *moby-cached-dataspace-page*)) (setq *moby-cached-vmem-idx* (vmem-find-page dataspace-page) *moby-cached-dataspace-page* dataspace-page))) (let ((buf (aref *vmem-pages* *moby-cached-vmem-idx* 5))) (values (aref buf idx) (aref buf (1+ idx)) (aref buf (+ 2 idx)) (aref buf (+ 3 idx)))))) (defun moby-fetch-q3 (local-address) (let ((idx (ash (logand local-address 377) 2)) (dataspace-page (moby-local-page-to-dataspace-page (lsh local-address -8)))) (cond ((not (= dataspace-page *moby-cached-dataspace-page*)) (setq *moby-cached-vmem-idx* (vmem-find-page dataspace-page) *moby-cached-dataspace-page* dataspace-page))) (let ((buf (aref *vmem-pages* *moby-cached-vmem-idx* 5))) (aref buf (+ 3 idx))))) ;not used currently. (defun moby-store-quarters (local-address q0 q1 q2 q3) (let ((idx (ash (logand local-address 377) 2)) (dataspace-page (moby-local-page-to-dataspace-page (lsh local-address -8)))) (cond ((not (= dataspace-page *moby-cached-dataspace-page*)) (setq *moby-cached-vmem-idx* (vmem-find-page dataspace-page) *moby-cached-dataspace-page* dataspace-page))) (let ((buf (aref *vmem-pages* *moby-cached-vmem-idx* 5))) (setf (aref buf idx) q0) (setf (aref buf (1+ idx)) q1) (setf (aref buf (+ 2 idx)) q2) (setf (aref buf (+ 3 idx)) q3) (setf (aref *vmem-pages* *moby-cached-vmem-idx* 3) t) nil))) ;component formats: ; unboxed: low 16 bits in q0, high 16 in q2. ; pointer: 50 bit moby pointer (as a positive integer, maybe big), 7 bit cc-and-dt, ; 5 bit moby-format. ; used for dtp-symbol, dtp-list, dtp-array-pointer ; direct: 25 bits for %pointer field, 7 bit cc-and-dt, 5 bit moby-format ; used for dtp-character, dtp-header, dtp-array-header, dtp-small-flonum ; fixnum dt: 50 bit signed integer, 7 bit cc-and-dt, 5 bit moby format. ; (values format-symbol moby-format-bits v1 v2) ;currently not used. ;(defun moby-fetch-parsed-components (local-address) ; (declare (values moby-pointer cdr-code-and-data-type moby-format)) ; (let ((idx (ash (logand local-address 377) 2)) ; (dataspace-page (moby-local-page-to-dataspace-page (lsh local-address -8)))) ; (cond ((not (= dataspace-page *moby-cached-dataspace-page*)) ; (setq *moby-cached-vmem-idx* ; (vmem-find-page dataspace-page) ; *moby-cached-dataspace-page* dataspace-page))) ; (let ((buf (aref *vmem-pages* *moby-cached-vmem-idx* 5))) ; (moby-parse-components (aref buf idx) (aref buf (1+ idx)) ; (aref buf (+ 2 idx)) (aref buf (+ 3 idx)))))) (defun moby-parse-components-and-moby-bits (q0 q1 q2 q3) (declare (values type-symbol moby-bits moby-pointer cdr-code-and-data-type)) (let* ((moby-bits (logior %moby-region-valid (ldb %%moby-internal-bits q3))) (boxed-code (ldb %%%moby-boxed moby-bits))) (cond ((= boxed-code 2) (values 'local-cell moby-bits nil (ldb (byte 7 9) q1))) ((zerop boxed-code) (values 'unboxed moby-bits q0 q2)) (t (let ((moby-dt (ldb (byte 5 9) q1)) (ccdt (ldb (byte 7 9) q1))) (cond ((%pointer-type-p moby-dt) (values 'pointer moby-bits (dpb-big (dpb q3 (byte 9 16.) q2) (byte 25. 25.) (dpb q1 ;value of this dbp is bottom 25. (byte 9 16.) q0)) ccdt)) ((= moby-dt dtp-fix) ;moby fixnum might be bignum in local form.. (let* ((si:NUMBER-CONS-AREA WORKING-STORAGE-AREA) ;avoid screwws due to consing number in extra-pdl-area. (ans (cond ((zerop (ldb (byte 1 8) q3)) ;positive number (dpb q3 (byte 9 41.) (dpb q2 (byte 16. 25.) (dpb q1 (byte 9. 16.) q0)))) (t ;negative number (dpb q3 (byte 9 41.) (dpb q2 (byte 16. 25.) (dpb q1 (byte 9. 16.) (dpb q0 (byte 16. 0) -1)))))))) (cond ((fixp ans)) ((not (= (%area-number ans) working-storage-area)) (ferror nil "failed to number cons in working-storage-area")) ) (values 'fixnum moby-bits ans ccdt))) (t (values 'direct moby-bits (dpb q1 (byte 9 16.) q0) ccdt)))))))) (defun moby-pointer-type-p (data-type-code) "T if DATA-TYPE-CODE is a the code for a data type that points to storage." (NOT (MEMQ DATA-TYPE-CODE '(#.DTP-FIX #.DTP-SMALL-FLONUM #.DTP-CHARACTER #.DTP-TRAP #.DTP-SELF-REF-POINTER ;note that DTP-INSTANCE-HEADER IS a pointer!. #.DTP-HEADER #.DTP-ARRAY-HEADER ;note that DTP-HEADER-FORWARD IS a pointer!. )))) (defun moby-parse-components (q0 q1 q2 q3) (declare (values type-symbol moby-pointer cdr-code-and-data-type)) (let* ((boxed-code (ldb %%moby-boxed q3))) (cond ((= boxed-code 2) (values 'local-cell nil (ldb (byte 7 9) q1))) ((zerop boxed-code) (values 'unboxed q0 q2)) (t (let ((moby-dt (ldb (byte 5 9) q1)) (ccdt (ldb (byte 7 9) q1))) (cond ((moby-pointer-type-p moby-dt) (values 'pointer (dpb-big (dpb q3 (byte 9 16.) q2) (byte 25. 25.) (dpb q1 ;value of this dbp is bottom 25. (byte 9 16.) q0)) ccdt)) ((= moby-dt dtp-fix) ;moby fixnum might be bignum in local form.. (let* ((si:NUMBER-CONS-AREA WORKING-STORAGE-AREA) ;avoid screwws due to consing number in extra-pdl-area. (ans (cond ((zerop (ldb (byte 1 8) q3)) ;positive number (dpb q3 (byte 9 41.) (dpb q2 (byte 16. 25.) (dpb q1 (byte 9. 16.) q0)))) (t ;negative number (dpb q3 (byte 9 41.) (dpb q2 (byte 16. 25.) (dpb q1 (byte 9. 16.) (dpb q0 (byte 16. 0) -1)))))))) (cond ((fixp ans)) ((not (= (%area-number ans) working-storage-area)) (ferror nil "failed to number cons in working-storage-area")) ) (values 'fixnum ans ccdt))) (t (values 'direct (dpb q1 (byte 9 16.) q0) ccdt)))))))) ;not currently used. (defun moby-fetch-components (local-address) (declare (values moby-pointer cdr-code-and-data-type moby-bits)) (let ((idx (ash (logand local-address 377) 2)) (dataspace-page (moby-local-page-to-dataspace-page (lsh local-address -8)))) (cond ((not (= dataspace-page *moby-cached-dataspace-page*)) (setq *moby-cached-vmem-idx* (vmem-find-page dataspace-page) *moby-cached-dataspace-page* dataspace-page))) (let* ((buf (aref *vmem-pages* *moby-cached-vmem-idx* 5)) (q1 (aref buf (1+ idx))) (q3 (aref buf (+ 3 idx)))) (values (dpb-big (dpb q3 (byte 9 16.) (aref buf (+ idx 2))) (byte 25. 25.) (dpb q1 ;value of this dbp is bottom 25. (byte 9 16.) (aref buf idx))) (ldb (byte 7 9) q1) (ldb %%moby-internal-bits q3))))) ;flush external bits. (defun moby-fetch-all (local-address) ;this one used for debugging, not time optimized. (declare (values full-value moby-bits cdr-code-and-data-type moby-pointer)) (let ((idx (ash (logand local-address 377) 2)) (dataspace-page (moby-local-page-to-dataspace-page (lsh local-address -8) t))) (cond ((null dataspace-page) (return-from moby-fetch-all nil)) ((not (= dataspace-page *moby-cached-dataspace-page*)) (setq *moby-cached-vmem-idx* (vmem-find-page dataspace-page) *moby-cached-dataspace-page* dataspace-page))) (let* ((buf (aref *vmem-pages* *moby-cached-vmem-idx* 5))) (values (dpb (aref buf (+ idx 3)) 6020 (dpb (aref buf (+ idx 2)) 4020 (dpb (aref buf (+ idx 1)) 2020 (aref buf idx)))) (ldb %%moby-internal-bits (aref buf (+ idx 3))) (ldb (byte 7 9) (aref buf (+ idx 1))) ;cdr-code and data-type (dpb-big (dpb (aref buf (+ idx 3)) (byte 9 16.) (aref buf (+ idx 2))) (byte 25. 25.) (dpb (aref buf (+ idx 1)) ;value of this dbp is bottom 25. (byte 9 16.) (aref buf idx))))))) ;not used, currently (defun moby-store-components (local-address moby-pointer cdr-code-and-data-type moby-bits) (let ((idx (ash (logand local-address 377) 2)) (dataspace-page (moby-local-page-to-dataspace-page (lsh local-address -8)))) (cond ((not (= dataspace-page *moby-cached-dataspace-page*)) (setq *moby-cached-vmem-idx* (vmem-find-page dataspace-page) *moby-cached-dataspace-page* dataspace-page))) (let ((buf (aref *vmem-pages* *moby-cached-vmem-idx* 5))) (aset (ldb (byte 16. 0) moby-pointer) buf idx) ;low 16 bits. (aset (dpb cdr-code-and-data-type (byte 7 9) (ldb (byte 9. 16.) moby-pointer)) buf (1+ idx)) ;next 9 (aset (ldb (byte 16. 25.) moby-pointer) buf (+ idx 2)) ;next 16 (aset (dpb (ldb %%moby-external-bits (aref buf (+ idx 3))) ;preserve external bits. %%moby-external-bits (dpb moby-bits %%moby-internal-bits (ldb (byte 9 41.) moby-pointer))) ;highest 9 buf (+ idx 3)) (setf (aref *vmem-pages* *moby-cached-vmem-idx* 3) t) nil))) (defun moby-declare-local-cell (local-address) "Declare local-address to be a local cell. This means it does not get dereconciled, and always gets reconciled as NIL. The CDR-CODE is still meaningful." (let* ((area-number (%area-number local-address)) (local-p (%pointer local-address)) (local-page (lsh local-p -8))) (cond ((aref *area-to-msa* area-number) ;do nothing if local area. (let ((vp (aref #'system:virtual-page-data local-page))) (cond ((zerop (ldb si:%%virtual-page-moby-bits-complete vp)) ;;;do the whole thing, both from moby space and freshly consed. (moby-validate-moby-bits local-p nil)))) (let* ((region (%region-number local-p)) (region-moby-bits-array (aref #'sys:region-moby-bits-array region)) (region-origin (si:%region-origin region)) (region-relative-local-address (%pointer-difference local-p region-origin)) (moby-bits (aref region-moby-bits-array region-relative-local-address)) (boxed-code (ldb %%%moby-boxed moby-bits))) (cond ((zerop (logand %moby-region-valid moby-bits)) (ferror nil "moby bits not valid for local cell")) ((not (= boxed-code 2)) (setf (aref region-moby-bits-array region-relative-local-address) (dpb 2 %%%moby-boxed moby-bits)) (setf (ldb si:%%virtual-page-clean ;make sure page gets written next time. (aref #'system:virtual-page-data local-page)) 0) ; (let ((idx (ash (logand local-p #o377) 2)) ; (dataspace-page (moby-local-page-to-dataspace-page local-page))) ; (cond ((not (= dataspace-page *moby-cached-dataspace-page*)) ; (setq *moby-cached-vmem-idx* ; (vmem-find-page dataspace-page) ; *moby-cached-dataspace-page* dataspace-page))) ; (let ((buf (aref *vmem-pages* *moby-cached-vmem-idx* 5))) ; (aset 0 buf idx) ; (aset (ash (dpb (%p-ldb-offset %%q-cdr-code 0 local-p) ; (byte 2 5) ; dtp-fix) ; 9) ; buf ; (1+ idx)) ; (aset 0 buf (+ idx 2)) ; (aset (dpb 2 %%moby-boxed (aref buf (+ idx 3))) ; buf ; (+ idx 3)) ; (setf (aref *vmem-pages* *moby-cached-vmem-idx* 3) t))) ))))))) (defun moby-structure-handle-of-local-address (local-address) ;this one used for debugging, not time optimized. (declare (values structure-handle)) (let ((dataspace-page (moby-local-page-to-dataspace-page (lsh local-address -8)))) (cond ((not (= dataspace-page *moby-cached-dataspace-page*)) (setq *moby-cached-vmem-idx* (vmem-find-page dataspace-page) *moby-cached-dataspace-page* dataspace-page))) (let ((buf (aref *vmem-pages* *moby-cached-vmem-idx* 5))) (moby-read-structure-handle-from-external-bits buf)))) (defun moby-store-structure-handle-into-external-bits (sh buf) ;structure-handle is 18. bits. store them in external bits of first 9 MOBY-Qs of buf. (if (> (ldb si:%%virtual-page-initial-qs sh) 400) (ferror nil "Initial Qs too big in structure handle")) (if (> (ldb si:%%virtual-page-first-header sh) 400) (ferror nil "First header too big in structure handle")) (do ((s sh (ash s -2)) (c 0 (1+ c)) (idx 3 (+ idx 4))) ((= c 9)) (aset (dpb s %%moby-external-bits (aref buf idx)) buf idx))) (defun moby-read-structure-handle-from-external-bits (buf) (do ((s 0) (p (byte 2 0) (+ p (byte 0 2))) (idx 3 (+ idx 4)) (c 0 (1+ c))) ((= c 9) (if (> (ldb si:%%virtual-page-initial-qs s) 400) (ferror nil "Initial Qs too big in structure handle")) (if (> (ldb si:%%virtual-page-first-header s) 400) (ferror nil "First header too big in structure handle")) s) (setq s (dpb (ldb %%moby-external-bits (aref buf idx)) p s))))