;;; -*- Mode:LISP; Package:REGION-DATA; Base:10.; Readtable:CL -*- ;(in-package 'region-data) (export '( make-region def-region-accessor free-region initialize-region-data region-allocation-status region-end region-free-pointer region-gc-pointer region-origin unsafe-region-free-pointer )) ;(defsubst region-free-pointer-unsafe (region) ; (region-table-ref gr::*region-free-pointer* region)) (defmacro def-region-accessor (name table) `(PROGN ;; This should be a defsubst, but macroexpansion and defsetf happen in ;; a bad order. This causes us to try to setf REGION-TABLE-REF which ;; has no setf method. (DEFUN ,name (REGION) (REGION-TABLE-REF ,table REGION)) (DEFSETF ,name (REGION) (VALUE) `(REGION-TABLE-STORE ,',table ,region ,value)))) (def-region-accessor unsafe-region-free-pointer gr::*region-free-pointer*) (def-region-accessor region-end gr::*region-end*) (def-region-accessor region-gc-pointer gr::*region-gc-pointer*) (defun region-free-pointer (region) (cond ((= region gr::*cons-cache-region*) gr::*cons-cache-free*) ((= region gr::*structure-cons-cache-region*) gr::*structure-cons-cache-free*) ; ((= region gr::*copy-cons-cache-region*) gr::*copy-cons-cache-free*) ; ((= region gr::*copy-structure-cons-cache-region*) gr::*copy-structure-cons-cache-free*) (t (unsafe-region-free-pointer region)))) (defun set-region-free-pointer (region value) (cond ((= region gr::*cons-cache-region*) (setq gr::*cons-cache-free* value)) ((= region gr::*structure-cons-cache-region*) (setq gr::*structure-cons-cache-free* value)) ; ((= region gr::*copy-cons-cache-region*) ; (setq gr::*copy-cons-cache-free* value)) ; ((= region gr::*copy-structure-cons-cache-region*) ; (setq gr::*copy-structure-cons-cache-free* value)) ) (setf (unsafe-region-free-pointer region) value)) (defsetf region-free-pointer set-region-free-pointer) (defun cons-cache-invalid? () (= gr:*cons-cache-region* -1)) (defun structure-cons-cache-invalid? () (= gr:*structure-cons-cache-region* -1)) (defun invalidate-cons-cache () (unless (cons-cache-invalid?) (setf (unsafe-region-free-pointer gr:*cons-cache-region*) gr:*cons-cache-free*)) (setq gr:*cons-cache-region* -1) (setq gr:*cons-cache-free* (hw:32- trap:*magic-garbage-location* 1)) ; (setq gr:*cons-cache-limit* -1) ) (defun invalidate-structure-cons-cache () (unless (structure-cons-cache-invalid?) (setf (unsafe-region-free-pointer gr:*structure-cons-cache-region*) gr:*structure-cons-cache-free*)) (setq gr:*structure-cons-cache-region* -1) (setq gr:*structure-cons-cache-free* (hw:32- trap:*magic-garbage-location* 1)) (setq gr:*structure-cons-cache-limit* gr:*structure-cons-cache-free*)) (defun make-region (size region-bits volatility) (let* ((region (region-bits:make-region size region-bits volatility)) (origin (region-origin region))) ;; Regions start out empty. (setf (region-free-pointer region) origin) (setf (region-end region) (hw:24+ (quantum->address size) origin)) (setf (region-gc-pointer region) origin) region)) (defun free-region (region) ; (trap::illop "freeing region") (region-bits:free-region region) (when (= region gr:*cons-cache-region*) (invalidate-cons-cache)) (let ((region-start (region-origin region))) (setf (region-free-pointer region) region-start) (setf (region-end region) region-start) (setf (region-gc-pointer region) region-start))) (defun advance-free-pointer (region how-far) (let ((free-pointer (region-free-pointer region)) (end (region-end region))) (let ((new-pointer (hw:32+ (hw:ldb how-far vinc:%%pointer (hw:unboxed-constant 0)) free-pointer))) (if (hw:32> (hw:ldb new-pointer vinc:%%pointer (hw:unboxed-constant 0)) (hw:ldb end vinc:%%pointer (hw:unboxed-constant 0))) (trap::illop "Advanced free pointer beyond end of region.") (setf (region-free-pointer region) new-pointer))))) (defun zap-all-regions (count) (if (= count *number-of-regions*) '() (progn (setf (region-free-pointer count) (hw:unboxed-constant 0)) (setf (region-gc-pointer count) (hw:unboxed-constant 0)) (setf (region-end count) (hw:unboxed-constant 0)) (zap-all-regions (1+ count))))) (defun find-region (scan) (cond ((= scan *number-of-regions*) '()) ((not (quantum-map:valid-quantum? scan)) (find-region (1+ scan))) (t (accumulate-region-data scan (1+ scan))))) (defun accumulate-region-data (start scan) (if (= scan *number-of-regions*) (record-initial-region-data start scan) (let ((space-type (region-bits:region-space-type (region-bits:read-region-bits scan)))) (if (= space-type region-bits:$$region-space-invalid) (accumulate-region-data start (1+ scan)) (progn (record-initial-region-data start scan) (if (= space-type region-bits:$$region-space-free) (find-region (1+ scan)) (accumulate-region-data scan (1+ scan)))))))) (defun record-initial-region-data (begin end) (setf (region-free-pointer begin) (quantum->address end)) (setf (region-gc-pointer begin) (quantum->address begin)) (setf (region-end begin) (quantum->address end))) (defun initialize-region-data () (zap-all-regions 0) (find-region 0) nil) ;;; This is what I would like to use, but the compiler can't hack it yet. ;(defun initialize-region-data () ; ;; We scan the region bits table to find regions. Each region ; ;; is presumed to be full. ; (labels ((zap-all-regions (count) ; (if (= count *number-of-regions*) ; '() ; (progn (setf (region-free-pointer count) (hw:unboxed-constant 0)) ; (setf (region-gc-pointer count) (hw:unboxed-constant 0)) ; (setf (region-end count) (hw:unboxed-constant 0)) ; (zap-all-regions (1+ count))))) ; (find-region (scan) ; (cond ((= scan *number-of-regions*) '()) ; ((not (quantum-map:valid-quantum? scan)) (find-region (1+ scan))) ; (t (accumulate-region-data scan (1+ scan))))) ; (accumulate-region-data (start scan) ; (if (= scan *number-of-regions*) ; (record-initial-region-data start scan) ; (let ((space-type (region-bits:region-space-type (region-bits:read-region-bits scan)))) ; (if (= space-type region-bits:$$region-space-invalid) ; (accumulate-region-data start (1+ scan)) ; (progn (record-initial-region-data start scan) ; (if (= space-type region-bits:$$region-space-free) ; (find-region (1+ scan)) ; (accumulate-region-data scan (1+ scan)))))))) ; (record-initial-region-data (begin end) ; (setf (region-free-pointer begin) (quantum->address end)) ; (setf (region-gc-pointer begin) (hw:unboxed-constant 0)) ; (setf (region-end begin) (quantum->address end))) ; ) ; (zap-all-regions 0) ; (find-region 0) ; nil)) ;