more profiling stuff..
..rearranged DCONSING arithmetic in profile wrappers so that
accounting for small amounts of wrapped consing almost
always works without extra consing overhead in the
wrapper
..made calibrate-PROFILE-overhead code run longer
MNA pointed out that bug 59 was fixed a while ago.
MNA comment clarifications sbcl-devel 2001-06-25
removed bogus QUIT from stream.pure.lisp, so that the
subsequent *.pure.lisp tests get executed
CLOS methods, and then expressing the solutions to stuff like this
should become much more straightforward. -- WHN 2001-03-14
-59:
- CL:*DEFAULT-PATHNAME-DEFAULTS* doesn't behave as ANSI suggests (reflecting
- current working directory). And there's no supported way to update
- or query the current working directory (a la Unix "chdir" and "pwd"),
- which is functionality that ILISP needs (and currently gets with low-level
- hacks).
- When this is fixed, probably the more-or-less-parallel Unix-level
- hacks
- DEFAULT-DIRECTORY
- %SET-DEFAULT-DIRECTORY
- etc.?
- should go away. Also we need to figure out what's the proper way to
- deal with the interaction of users assigning new values to
- *DEFAULT-PATHNAME-DEFAULTS* and cores being saved and restored.
- (Perhaps just make restoring from a save always overwrite the old
- value with the new Unix-level default directory?)
-
60:
The debugger LIST-LOCATIONS command doesn't work properly.
* a port to the Compaq/DEC Alpha CPU, thanks to Dan Barlow
* Martin Atzmueller ported Tim Moore's marvellous CMU CL DISASSEMBLE
patch, so that DISASSEMBLE output is much nicer.
-* Pathnames are much more ANSI-compliant, thanks to various fixes
- and tests from Dan Barlow.
-* Hash tables can be printed readably, as inspired by CMU CL code
- of Eric Marsden and SBCL code of Martin Atzmueller.
+* Pathnames and *DEFAULT-DIRECTORY-DEFAULTS* are much more
+ ANSI-compliant, thanks to various fixes and tests from Dan Barlow.
+ Also, at Dan Barlow's suggestion, TRUENAME on a dangling symbolic
+ link now returns the dangling link itself, and for similar
+ reasons, TRUENAME on a cyclic symbolic link returns the cyclic
+ link itself. (In these cases the old code signalled an error and
+ looped endlessly, respectively.) Thus, DIRECTORY now works even
+ in the presence of dangling and cyclic symbolic links.
* Compiler trace output (the :TRACE-FILE option to COMPILE-FILE)
is now a supported extension again, since the consensus on
sbcl-devel was that it can be useful for ordinary development
work, not just for debugging SBCL itself.
+* Hash tables can be printed readably, as inspired by CMU CL code
+ of Eric Marsden and SBCL code of Martin Atzmueller.
* better error handling in CLOS method combination, thanks to
Martin Atzmueller porting Pierre Mai's CMU CL patches
-* At Dan Barlow's suggestion, TRUENAME on a dangling symbolic
- link now returns the dangling link itself, and for similar reasons,
- TRUENAME on a cyclic symbolic link returns the cyclic link itself.
- (In these cases the old code signalled an error and looped
- endlessly, respectively.) As a consequence of this change,
- DIRECTORY now works even in the presence of dangling and cyclic
- symbolic links.
* more overflow fixes for >16Mbyte I/O buffers
* fixed bug 107 (reported as a CMU CL bug by Erik Naggum on
comp.lang.lisp 2001-06-11): (WRITE #*101 :RADIX T :BASE 36) now
cycle for low-level changes to SBCL itself, and a new
:SB-AFTER-XC-CORE target feature to control the generation of
the after-xc.core file needed by slam.sh.
-* Fasl file version numbers are now independent of the target CPU,
- since historically most system changes which required version
- number changes have affected all CPUs equally. Similarly,
- the byte fasl file version is now equal to the ordinary
- fasl file version.
* minor incompatible change: The ENTRY-POINTS &KEY argument to
COMPILE-FILE is no longer supported, so that now every function
gets an entry point, so that block compilation looks a little
i.e. :ALL, :FOLLOW-LINKS, and :CHECK-FOR-SUBDIRS, are no longer
supported. Now DIRECTORY always does the abstract Common-Lisp-y
thing, i.e. :ALL T :FOLLOW-LINKS T :CHECK-FOR-SUBDIRS T.
+* Fasl file version numbers are now independent of the target CPU,
+ since historically most system changes which required version
+ number changes have affected all CPUs equally. Similarly,
+ the byte fasl file version is now equal to the ordinary
+ fasl file version.
planned incompatible changes in 0.7.x:
* The debugger prompt sequence now goes "5]", "5[2]", "5[3]", etc.
"PCOUNTER->INTEGER"
"PCOUNTER-OR-FIXNUM->INTEGER"
"PCOUNTER-P"
+ "*N-BYTES-FREED-OR-PURIFIED-PCOUNTER*"
;; miscellaneous non-standard but handy user-level functions..
"ASSQ" "DELQ" "MEMQ" "POSQ" "NEQ"
;; be a SB-PCL:CLASS under some circumstances? What goes here
;; when the LAYOUT is in fact a PCL::WRAPPER?
:type #-sb-xc sb!xc:class #+sb-xc cl:class)
- ;; The value of this slot can be
+ ;; The value of this slot can be:
;; * :UNINITIALIZED if not initialized yet;
;; * NIL if this is the up-to-date layout for a class; or
;; * T if this layout has been invalidated (by being replaced by
;; * something else (probably a list) if the class is a PCL wrapper
;; and PCL has made it invalid and made a note to itself about it
(invalid :uninitialized :type (or cons (member nil t :uninitialized)))
- ;; The layouts for all classes we inherit. If hierarchical these are
- ;; in order from most general down to (but not including) this
- ;; class.
+ ;; the layouts for all classes we inherit. If hierarchical, i.e. if
+ ;; DEPTHOID >= 0, then these are ordered by ORDER-LAYOUT-INHERITS,
+ ;; so that each inherited layout appears at its expected depth,
+ ;; i.e. at its LAYOUT-DEPTHOID value.
;;
- ;; FIXME: Couldn't this be (SIMPLE-ARRAY LAYOUT 1) instead of
- ;; SIMPLE-VECTOR?
+ ;; Remaining elements are filled by the non-hierarchical layouts or,
+ ;; if they would otherwise be empty, by copies of succeeding layouts.
(inherits #() :type simple-vector)
- ;; If inheritance is hierarchical, this is -1. If inheritance is not
+ ;; If inheritance is not hierarchical, this is -1. If inheritance is
;; hierarchical, this is the inheritance depth, i.e. (LENGTH INHERITS).
;; Note:
;; (1) This turns out to be a handy encoding for arithmetically
); EVAL-WHEN
;;; Arrange the inherited layouts to appear at their expected depth,
-;;; ensuring that hierarchical type tests succeed. Layouts with a
-;;; specific depth are placed first, then the non- hierarchical
-;;; layouts fill remaining elements. Any empty elements are filled
-;;; with layout copies ensuring that all elements have a valid layout.
-;;; This re-ordering may destroy CPL ordering so the inherits should
-;;; not be read as being in CPL order, and further duplicates may be
-;;; introduced.
+;;; ensuring that hierarchical type tests succeed. Layouts with
+;;; DEPTHOID >= 0 (i.e. hierarchical classes) are placed first,
+;;; at exactly that index in the INHERITS vector. Then, non-hierarchical
+;;; layouts are placed in remaining elements. Then, any still-empty
+;;; elements are filled with their successors, ensuring that each
+;;; element contains a valid layout.
+;;;
+;;; This reordering may destroy CPL ordering, so the inherits should
+;;; not be read as being in CPL order.
(defun order-layout-inherits (layouts)
(declare (simple-vector layouts))
(let ((length (length layouts))
;;; is loaded and the class defined.
(!cold-init-forms
(/show0 "about to define temporary STANDARD-CLASSes")
- (dolist (x '(;; FIXME: The mysterious duplication of STREAM in the
- ;; list here here was introduced in sbcl-0.6.12.33, in
- ;; MNA's port of DTC's inline-type-tests patches for
- ;; CMU CL. I'm guessing that it has something to do
- ;; with preallocating just enough space in a table
- ;; later used by the final definition of
- ;; FUNDAMENTAL-STREAM (perhaps for Gray stream stuff?).
- ;; It'd be good to document this weirdness both here
- ;; and in the REGISTER-LAYOUT code which has to do the
- ;; right thing with the duplicates-containing
- ;; INHERITS-LIST.
+ (dolist (x '(;; Why is STREAM duplicated in this list? Because, when
+ ;; the inherits-vector of FUNDAMENTAL-STREAM is set up,
+ ;; a vector containing the elements of the list below,
+ ;; i.e. '(T INSTANCE STREAM STREAM), is created, and
+ ;; this is what the function ORDER-LAYOUT-INHERITS
+ ;; would do, too.
+ ;;
+ ;; So, the purpose is to guarantee a valid layout for
+ ;; the FUNDAMENTAL-STREAM class, matching what
+ ;; ORDER-LAYOUT-INHERITS would do.
+ ;; ORDER-LAYOUT-INHERITS would place STREAM at index 3
+ ;; in the INHERITS(-VECTOR). Index 2 would not be
+ ;; filled, so STREAM is duplicated there (as
+ ;; ORDER-LAYOUTS-INHERITS would do). Maybe the
+ ;; duplicate definition could be removed (removing a
+ ;; STREAM element), because FUNDAMENTAL-STREAM is
+ ;; redefined after PCL is set up, anyway. But to play
+ ;; it safely, we define the class with a valid INHERITS
+ ;; vector.
(fundamental-stream (t instance stream stream))))
(/show0 "defining temporary STANDARD-CLASS")
(let* ((name (first x))
;;;; bytes consed in a profiled function are all examples of such
;;;; quantities. The name is an abbreviation for "Profiling COUNTER".
;;;;
-;;;; It's not one of my more brilliant names, if you have a better
-;;;; suggestion, I might be interested. -- WHN 2001-06-22
+;;;; (This isn't one of my more brilliant names, so if you have a
+;;;; better suggestion, let me know. -- WHN 2001-06-22)
-(in-package "SB!IMPL")
+;;; This stuff is implemented in the SB!PROFILE because the profiling
+;;; code is currently the only code which wants to poke around in the
+;;; implementation details.
+(in-package "SB!PROFILE")
\f
;;;; basic PCOUNTER stuff
;;; inline.
(defmacro fastbig- (x y)
(once-only ((x x) (y y))
- `(if (and (typep ,x 'fixnum)
- (typep ,y 'fixnum))
+ `(if (and (typep ,x '(and fixnum unsigned-byte))
+ (typep ,y '(and fixnum unsigned-byte)))
+ ;; special case: can use fixnum arithmetic and be guaranteed
+ ;; the result is also a fixnum
(- ,x ,y)
+ ;; general case
(- ,x ,y))))
(defmacro fastbig-1+ (x)
(once-only ((x x))
(aver (typep dconsing 'unsigned-byte))
(aver (typep inner-enclosed-profiles 'unsigned-byte))
(multiple-value-prog1
- (let ((start-ticks (get-internal-ticks))
- (start-consing (get-bytes-consed))
- (*enclosed-ticks* 0)
- (*enclosed-consing* 0)
- (*enclosed-profiles* 0))
+ (let* ((start-ticks (get-internal-ticks))
+ (*enclosed-ticks* 0)
+ (*enclosed-consing* 0)
+ (*enclosed-profiles* 0)
+ (nbf-pcounter *n-bytes-freed-or-purified-pcounter*)
+ ;; Typically NBF-PCOUNTER will represent a bignum.
+ ;; In general we don't want to cons up a new bignum for every
+ ;; encapsulated call, so instead we keep track of
+ ;; the PCOUNTER internals, so that as long as we
+ ;; only cons small amounts, we'll almost always
+ ;; just do fixnum arithmetic. (And for encapsulated
+ ;; functions which cons large amounts, then we don't
+ ;; much care about a single extra consed bignum.)
+ (start-consing-integer (pcounter-integer nbf-pcounter))
+ (start-consing-fixnum (pcounter-fixnum nbf-pcounter)))
(declare (inline pcounter-or-fixnum->integer))
(multiple-value-prog1
(multiple-value-call encapsulated-fun
0
arg-count))
(let ((*computing-profiling-data-for* encapsulated-fun))
- (setf dticks (fastbig- (get-internal-ticks) start-ticks)
- dconsing (fastbig- (get-bytes-consed) start-consing))
+ (setf dticks (fastbig- (get-internal-ticks) start-ticks))
+ (setf dconsing
+ (if (eq (pcounter-integer nbf-pcounter)
+ start-consing-integer)
+ (- (pcounter-fixnum nbf-pcounter)
+ start-consing-fixnum)
+ (- (get-bytes-consed)
+ (+ pcounter-integer pcounter-fixnum))))
(setf inner-enclosed-profiles
(pcounter-or-fixnum->integer *enclosed-profiles*))
(let ((net-dticks (fastbig- dticks *enclosed-ticks*)))
;;;; overhead estimation
;;; We average the timing overhead over this many iterations.
-(defconstant +timer-overhead-iterations+
- 50000)
+;;;
+;;; (This is a variable, not a constant, so that it can be set in
+;;; .sbclrc if desired. Right now, that's an unsupported extension
+;;; that I (WHN) use for my own experimentation, but it might
+;;; become supported someday. Comments?)
+(declaim (type unsigned-byte *timer-overhead-iterations*))
+(defvar *timer-overhead-iterations*
+ 500000)
;;; a dummy function that we profile to find profiling overhead
(declaim (notinline compute-overhead-aux))
;;; Return a newly computed OVERHEAD object.
(defun compute-overhead ()
+ (format *debug-io* "~&measuring PROFILE overhead..")
(flet ((frob ()
(let ((start (get-internal-ticks))
(fun (symbol-function 'compute-overhead-aux)))
- (dotimes (i +timer-overhead-iterations+)
+ (dotimes (i *timer-overhead-iterations*)
(funcall fun fun))
(/ (float (- (get-internal-ticks) start))
(float +ticks-per-second+)
- (float +timer-overhead-iterations+)))))
+ (float *timer-overhead-iterations*)))))
(let (;; Measure unprofiled calls to estimate call overhead.
(call-overhead (frob))
total-overhead
(setf internal-overhead
(/ (float time)
(float +ticks-per-second+)
- (float +timer-overhead-iterations+))))
+ (float *timer-overhead-iterations*))))
(unprofile compute-overhead-aux))
- (make-overhead :call call-overhead
- :total total-overhead
- :internal internal-overhead))))
+ (prog1
+ (make-overhead :call call-overhead
+ :total total-overhead
+ :internal internal-overhead)
+ (format *debug-io* "done~%")))))
;;; It would be bad to compute *OVERHEAD*, save it into a .core file,
-;;; then load old *OVERHEAD* value from the .core file into a
+;;; then load the old *OVERHEAD* value from the .core file into a
;;; different machine running at a different speed. We avoid this by
;;; erasing *CALL-OVERHEAD* whenever we save a .core file.
(pushnew (lambda ()
;;; (like being an accessor for a structure which has a doc string).
(print "done with interface.pure.lisp")
-
(unless (= n-actually-read-1 n-to-read)
(assert (< n-actually-read-1 n-to-read))
(return)))))
-
-;;; success
-(quit :unix-status 104)
(nil (or number vector) nil)
(12 (or null vector) nil)
(12 (and (or number vector) real) t))))
-
-
\ No newline at end of file
;;; four numeric fields, is used for versions which aren't released
;;; but correspond only to CVS tags or snapshots.
-"0.6.12.41"
+"0.6.12.42"