mirror of
git://git.code.sf.net/p/sbcl/sbcl
synced 2026-09-10 07:26:40 -04:00
It's now a macrolet provided by DEFINE-ALLOCATOR which lets the vop author omit boilerplate args. Same with ALLOCATION and INSTRUMENT-ALLOC.
166 lines
6.8 KiB
Common Lisp
166 lines
6.8 KiB
Common Lisp
;;;; This software is part of the SBCL system. See the README file for
|
|
;;;; more information.
|
|
;;;;
|
|
;;;; While most of SBCL is derived from the CMU CL system, the test
|
|
;;;; files (like this one) were written from scratch after the fork
|
|
;;;; from CMU CL.
|
|
;;;;
|
|
;;;; This software is in the public domain and is provided with
|
|
;;;; absolutely no warranty. See the COPYING and CREDITS files for
|
|
;;;; more information.
|
|
|
|
#-(and x86-64 sb-thread (not win32)) (invoke-restart 'run-tests::skip-file) ;; not implemented elsewhere
|
|
|
|
(defstruct fruitbasket x y z)
|
|
(with-test (:name :aprof-smoketest-struct
|
|
:skipped-on :darwin
|
|
;; reverse-engineering the allocation instructions fails but should not
|
|
:fails-on (and (not :immobile-space) (not :mark-region-gc)))
|
|
(let ((nbytes
|
|
(sb-aprof:aprof-run
|
|
(checked-compile
|
|
'(sb-int:named-lambda "test" ()
|
|
(declare (inline make-fruitbasket)
|
|
(optimize sb-c::instrument-consing))
|
|
(loop repeat 50 collect (make-fruitbasket))))
|
|
:stream nil)))
|
|
(assert (= nbytes
|
|
(* 50 (+ (sb-ext:primitive-object-size (make-fruitbasket))
|
|
(* 2 sb-vm:n-word-bytes))))))) ; cons cells
|
|
|
|
(with-test (:name :aprof-smoketest-non-constant-size-vector)
|
|
(let ((nbytes
|
|
(sb-aprof:aprof-run
|
|
(checked-compile
|
|
'(sb-int:named-lambda "test" (&optional (n 10))
|
|
(declare (optimize sb-c::instrument-consing))
|
|
(make-array (the (mod 64) n))))
|
|
:stream nil)))
|
|
(assert (= nbytes (* 12 sb-vm:n-word-bytes)))))
|
|
|
|
;;; The profiler's disassembler expected to see a store at alloc-ptr
|
|
;;; or that + n-word-bytes, when in fact the code might write to 1 byte
|
|
;;; positioned anywhere in the word after the object header.
|
|
(with-test (:name :aprof-smoketest-bit-vector)
|
|
(let ((nbytes
|
|
(sb-aprof:aprof-run
|
|
(checked-compile
|
|
'(sb-int:named-lambda "test" ()
|
|
(declare (optimize sb-c::instrument-consing))
|
|
(make-array (* 128 16) :element-type 'bit)))
|
|
:stream nil)))
|
|
(assert (= nbytes (sb-ext:primitive-object-size
|
|
(make-array (* 128 16) :element-type 'bit))))))
|
|
|
|
(with-test (:name :aprof-smoketest-large-vector)
|
|
(let ((nbytes
|
|
(sb-aprof:aprof-run
|
|
(checked-compile
|
|
'(sb-int:named-lambda "test" ()
|
|
(declare (optimize sb-c::instrument-consing))
|
|
(make-array 45000)))
|
|
:stream nil)))
|
|
(assert (= nbytes (* (+ 45000 sb-vm:vector-data-offset)
|
|
8)))))
|
|
sb-vm::
|
|
(define-vop (cl-user::alloc-to-r8)
|
|
(:temporary (:sc any-reg :offset r8-offset :from :eval) result)
|
|
(:node-var node)
|
|
(:generator 1
|
|
(let* ((bytes large-object-size) ; payload + header total
|
|
(temp sb-vm::r11-tn)
|
|
(words (- (/ bytes n-word-bytes) vector-data-offset)))
|
|
(emit-instrument-alloc node thread-tn nil bytes temp)
|
|
(pseudo-atomic ()
|
|
(emit-allocation node sb-vm::thread-tn nil bytes 0 result temp)
|
|
(storew* simple-array-unsigned-byte-64-widetag result 0 0 t)
|
|
(storew* (fixnumize words) result vector-length-slot 0 t)
|
|
(inst or :byte result other-pointer-lowtag)))))
|
|
|
|
(with-test (:name :aprof-smoketest-large-vector-to-upper-register)
|
|
(let ((nbytes
|
|
(sb-aprof:aprof-run
|
|
(checked-compile
|
|
'(sb-int:named-lambda "test" ()
|
|
(declare (optimize sb-c::instrument-consing))
|
|
(sb-sys:%primitive cl-user::alloc-to-r8)
|
|
nil))
|
|
:stream nil)))
|
|
(assert (= nbytes sb-vm:large-object-size))))
|
|
|
|
;; this moves an immediate-to-memory, then a load + store, then a store
|
|
(defun f1 (&optional x)
|
|
(declare (optimize sb-c::instrument-consing))
|
|
(list* :if-exists (load-time-value(gensym)) x))
|
|
;; this reverses the first two operations relative to the preceding
|
|
(defun f2 (&optional x)
|
|
(declare (optimize sb-c::instrument-consing))
|
|
(list* (load-time-value(gensym)) :if-exists x))
|
|
|
|
(import '(sb-vm::rcx-tn sb-vm::rbp-tn sb-vm::r9-tn sb-vm::r10-tn sb-vm::rsi-tn
|
|
sb-vm:cons-size sb-vm:n-word-bytes
|
|
sb-vm::ea sb-vm:nil-value
|
|
sb-vm:list-pointer-lowtag sb-vm:bignum-widetag))
|
|
|
|
(defstruct this-struct)
|
|
(defstruct that-struct)
|
|
(declaim (inline make-this-struct make-that-struct))
|
|
(defun make-structs ()
|
|
(declare (optimize sb-c::instrument-consing))
|
|
(values (make-this-struct) (make-that-struct)))
|
|
(compile 'make-structs)
|
|
(with-test (:name :aprof-instance :skipped-on (not :compact-instance-header))
|
|
(let (seen-this seen-that)
|
|
(dolist (line (split-string
|
|
(with-output-to-string (s)
|
|
(sb-aprof:aprof-run #'make-structs :stream s))
|
|
#\newline))
|
|
(when (search "THIS-STRUCT" line) (setq seen-this t))
|
|
(when (search "THAT-STRUCT" line) (setq seen-that t)))
|
|
(assert (and seen-this seen-that))))
|
|
|
|
(defun my-list (&rest x)
|
|
(declare (optimize sb-c::instrument-consing))
|
|
x)
|
|
(compile 'my-list)
|
|
|
|
(with-test (:name :listify-rest-arg)
|
|
(let ((nbytes (let ((*standard-output* (make-broadcast-stream)))
|
|
(sb-aprof:aprof-run #'my-list :arguments '(a b c)))))
|
|
(assert (= nbytes (* sb-vm:n-word-bytes 6)))))
|
|
|
|
(defun make-new-code (n)
|
|
(let ((f
|
|
(compile nil
|
|
'(lambda (n)
|
|
(declare (optimize sb-c::instrument-consing))
|
|
(make-array (the fixnum n))))))
|
|
(sb-aprof:aprof-reset) ; In case the counts are already nonzero
|
|
(loop for i below n
|
|
do (funcall f i))
|
|
f))
|
|
(with-test (:name :make-new-code)
|
|
(let* ((n 20)
|
|
(nbytes (sb-aprof:aprof-run #'make-new-code :arguments n
|
|
:stream (make-broadcast-stream)
|
|
;; FIXME: need to return nbytes with or without a report
|
|
#|:report nil|#
|
|
)))
|
|
;; If the lisp image was compiled with cons profiling, then the COMPILE
|
|
;; inside MAKE-NEW-CODE was also instrumented, messing up the result.
|
|
;; (The compiler conses about ~128Kb but there's no way to predict how much)
|
|
(unless (sb-c:policy nil (> sb-c:instrument-consing 0))
|
|
(assert (= (loop for i below n
|
|
sum (sb-ext:primitive-object-size (make-array i)))
|
|
nbytes)))))
|
|
|
|
(with-test (:name :aprof-brutal-test)
|
|
(with-scratch-file (fasl "fasl")
|
|
;; Just compile anything that exercises the compiler.
|
|
;; This is only useful if the compiler was compiled with cons profiling.
|
|
(sb-aprof:aprof-run #'compile-file
|
|
:stream (make-broadcast-stream)
|
|
:arguments `("../src/code/shaketree"
|
|
:output-file ,fasl
|
|
:print nil :verbose nil))))
|