Changeset 8304
- Timestamp:
- Jan 27, 2008, 8:34:03 AM (17 years ago)
- Location:
- branches/event-ide/ccl
- Files:
-
- 14 edited
-
level-0/l0-io.lisp (modified) (1 diff)
-
level-1/l1-files.lisp (modified) (2 diffs)
-
level-1/l1-readloop-lds.lisp (modified) (2 diffs)
-
level-1/l1-sockets.lisp (modified) (6 diffs)
-
level-1/l1-streams.lisp (modified) (4 diffs)
-
level-1/linux-files.lisp (modified) (3 diffs)
-
lib/backtrace-lds.lisp (modified) (1 diff)
-
lib/backtrace.lisp (modified) (2 diffs)
-
lib/foreign-types.lisp (modified) (1 diff)
-
lib/macros.lisp (modified) (1 diff)
-
library/darwinppc-syscalls.lisp (modified) (1 diff)
-
library/x8664-freebsd-syscalls.lisp (modified) (1 diff)
-
library/x8664-linux-syscalls.lisp (modified) (1 diff)
-
lisp-kernel/x86-macros.s (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
branches/event-ide/ccl/level-0/l0-io.lisp
r8262 r8304 162 162 ;;; write nbytes bytes from buffer buf to file-descriptor fd. 163 163 (defun fd-write (fd buf nbytes) 164 ( syscall syscalls::write fd buf nbytes))164 (ignoring-eintr (syscall syscalls::write fd buf nbytes))) 165 165 166 166 (defun fd-read (fd buf nbytes) 167 (loop 168 (let* ((n (syscall syscalls::read fd buf nbytes))) 169 (unless (eql n (- #$EINTR)) (return n))))) 167 (ignoring-eintr (syscall syscalls::read fd buf nbytes))) 170 168 171 169 -
branches/event-ide/ccl/level-1/l1-files.lisp
r8262 r8304 184 184 185 185 (defun create-file (path &key (if-exists :error) (create-directory t)) 186 ( native-to-pathname(%create-file path :if-exists if-exists186 (let* ((p (%create-file path :if-exists if-exists 187 187 :create-directory create-directory))) 188 (and p 189 (native-to-pathname p)))) 190 188 191 (defun %create-file (path &key 189 192 (if-exists :error) … … 195 198 (assert (or (eql if-exists :overwrite) 196 199 (null if-exists) 200 (eq if-exists :error) 197 201 (not (probe-file path))) () 198 202 "~s ~s not implemented yet" :if-exists if-exists) 199 203 (let* ((unix-name (native-translated-namestring path)) 200 204 (fd (fd-open unix-name (logior #$O_WRONLY #$O_CREAT #$O_TRUNC 201 (if (null if-exists) 205 (if (or (null if-exists) 206 (eq if-exists :error)) 202 207 #$O_EXCL 203 208 0))))) 204 209 (if (< fd 0) 205 (if (eql fd (- #$EEXIST)) ; #$O_EXCL was set and file exists 210 (if (and (null if-exists) 211 (eql fd (- #$EEXIST))) 206 212 (return-from %create-file nil) 207 213 (signal-file-error fd path)) -
branches/event-ide/ccl/level-1/l1-readloop-lds.lisp
r8262 r8304 331 331 (cons keyword params) 332 332 keyword))) 333 (params param)))))))))))333 (params (eval param)))))))))))) 334 334 335 335 ;;; Read a form from the specified stream. … … 414 414 415 415 (defun abnormal-application-exit () 416 (print-call-history) 417 (force-output *debug-io*) 418 (quit -1)) 416 (ignore-errors 417 (print-call-history) 418 (force-output *debug-io*) 419 (quit -1)) 420 (#__exit -1)) 419 421 420 422 (defun break-loop-handle-error (condition error-pointer) -
branches/event-ide/ccl/level-1/l1-sockets.lisp
r8262 r8304 674 674 (fd-close fd)))) 675 675 676 (defun %socket-connect (fd addr addrlen )677 (let* ((err (c_connect fd addr addrlen )))676 (defun %socket-connect (fd addr addrlen &optional timeout) 677 (let* ((err (c_connect fd addr addrlen timeout))) 678 678 (declare (fixnum err)) 679 (when (eql err (- #$EINPROGRESS))680 (process-output-wait fd)681 (setq err (- (int-getsockopt fd #$SOL_SOCKET #$SO_ERROR))))682 679 (unless (eql err 0) (socket-error nil "connect" err)))) 683 680 … … 992 989 993 990 (defun timeval-setsockopt (socket level optname timeout) 994 (multiple-value-bind (seconds mi llis)995 (mi lliseconds timeout)996 (rlet ((valptr :timeval :tv_sec seconds :tv_usec mi llis))991 (multiple-value-bind (seconds micros) 992 (microseconds timeout) 993 (rlet ((valptr :timeval :tv_sec seconds :tv_usec micros)) 997 994 (socket-call socket "setsockopt" 998 995 (c_setsockopt socket level optname valptr (record-length :timeval)))))) … … 1077 1074 (rlet ((hostent :hostent) 1078 1075 (hp (* (struct :hostent))) 1079 (herr :signed ))1076 (herr :signed 0)) 1080 1077 (do* ((buflen 1024 (+ buflen buflen))) () 1081 1078 (declare (fixnum buflen)) … … 1085 1082 (unless (eql res #$ERANGE) 1086 1083 (return 1087 (if (eql res 0) 1084 (let* ((err (pref herr :signed))) 1085 (if (and (eql res 0) (eql err 0)) 1088 1086 (%get-unsigned-long 1089 1087 (%get-ptr (pref (%get-ptr hp) :hostent.h_addr_list))) 1090 (values nil (- (pref herr :signed))))))))))))1088 (values nil (- err)))))))))))) 1091 1089 1092 1090 (defun _getservbyname (name proto) … … 1203 1201 (syscall syscalls::socketcall 2 params)))) 1204 1202 1205 (defun c_connect (sockfd addr len) 1206 #+(or darwin-target linuxx8664-target freebsd-target) 1207 (syscall syscalls::connect sockfd addr len) 1208 #+linuxppc-target 1209 (progn 1210 #+ppc32-target 1211 (%stack-block ((params 12)) 1212 (setf (%get-long params 0) sockfd 1213 (%get-ptr params 4) addr 1214 (%get-long params 8) len) 1215 (syscall syscalls::socketcall 3 params)) 1216 #+ppc64-target 1217 (%stack-block ((params 24)) 1218 (setf (%%get-unsigned-longlong params 0) sockfd 1219 (%get-ptr params 8) addr 1220 (%%get-unsigned-longlong params 16) len) 1221 (syscall syscalls::socketcall 3 params)))) 1203 1204 ;;; If attempts to connnect are interrupted, we basically have to 1205 ;;; wait in #_select (or the equivalent). There's a good rant 1206 ;;; about these issues in: 1207 ;;; <http://www.madore.org/~david/computers/connect-intr.html> 1208 (defun c_connect (sockfd addr len &optional timeout) 1209 (let* ((err 1210 #+(or darwin-target linuxx8664-target freebsd-target) 1211 (syscall syscalls::connect sockfd addr len) 1212 #+linuxppc-target 1213 (progn 1214 #+ppc32-target 1215 (%stack-block ((params 12)) 1216 (setf (%get-long params 0) sockfd 1217 (%get-ptr params 4) addr 1218 (%get-long params 8) len) 1219 (syscall syscalls::socketcall 3 params)) 1220 #+ppc64-target 1221 (%stack-block ((params 24)) 1222 (setf (%%get-unsigned-longlong params 0) sockfd 1223 (%get-ptr params 8) addr 1224 (%%get-unsigned-longlong params 16) len) 1225 (syscall syscalls::socketcall 3 params))))) 1226 (cond ((or (eql err (- #$EINPROGRESS)) (eql err (- #$EINTR))) 1227 (if (process-output-wait sockfd timeout) 1228 (- (int-getsockopt sockfd #$SOL_SOCKET #$SO_ERROR)) 1229 (- #$ETIMEDOUT))) 1230 (t err)))) 1222 1231 1223 1232 (defun c_listen (sockfd backlog) … … 1238 1247 1239 1248 (defun c_accept (sockfd addrp addrlenp) 1240 #+(or darwin-target linuxx8664-target freebsd-target) 1241 (syscall syscalls::accept sockfd addrp addrlenp) 1242 #+linuxppc-target 1243 (progn 1244 #+ppc32-target 1245 (%stack-block ((params 12)) 1246 (setf (%get-long params 0) sockfd 1247 (%get-ptr params 4) addrp 1248 (%get-ptr params 8) addrlenp) 1249 (syscall syscalls::socketcall 5 params)) 1250 #+ppc64-target 1251 (%stack-block ((params 24)) 1252 (setf (%%get-unsigned-longlong params 0) sockfd 1253 (%get-ptr params 8) addrp 1254 (%get-ptr params 16) addrlenp) 1255 (syscall syscalls::socketcall 5 params)))) 1249 (ignoring-eintr 1250 #+(or darwin-target linuxx8664-target freebsd-target) 1251 (syscall syscalls::accept sockfd addrp addrlenp) 1252 #+linuxppc-target 1253 (progn 1254 #+ppc32-target 1255 (%stack-block ((params 12)) 1256 (setf (%get-long params 0) sockfd 1257 (%get-ptr params 4) addrp 1258 (%get-ptr params 8) addrlenp) 1259 (syscall syscalls::socketcall 5 params)) 1260 #+ppc64-target 1261 (%stack-block ((params 24)) 1262 (setf (%%get-unsigned-longlong params 0) sockfd 1263 (%get-ptr params 8) addrp 1264 (%get-ptr params 16) addrlenp) 1265 (syscall syscalls::socketcall 5 params))))) 1256 1266 1257 1267 (defun c_getsockname (sockfd addrp addrlenp) -
branches/event-ide/ccl/level-1/l1-streams.lisp
r8262 r8304 5206 5206 (- #$ETIMEDOUT))) 5207 5207 5208 (defun process-input-wait (fd &optional ti cks)5208 (defun process-input-wait (fd &optional timeout) 5209 5209 "Wait until input is available on a given file-descriptor." 5210 (let* ((wait-end (if ticks (+ (get-tick-count) ticks)))) 5211 (loop 5212 ;; FD-INPUT-AVAILABLE-P can return NIL (e.g., if the 5213 ;; thread receives an interrupt) before a timeout is 5214 ;; reached. 5215 (when (fd-input-available-p fd ticks) 5216 (return t)) 5217 ;; If it returned and a timeout was specified, check 5218 ;; to see if it's been exceeded. If so, return NIL; 5219 ;; otherwise, adjust the remaining timeout. 5220 ;; If there was no timeout, continue to wait forever. 5221 (when ticks 5222 (let* ((now (get-tick-count))) 5223 (if (and wait-end (>= now wait-end)) 5224 (return) 5225 (setq ticks (- wait-end now)))))))) 5210 (rlet ((now :timeval)) 5211 (let* ((wait-end 5212 (if timeout 5213 (multiple-value-bind (seconds millis) (milliseconds timeout) 5214 (#_gettimeofday now +null-ptr+) 5215 (setq timeout (+ (* seconds 1000) millis)) 5216 (+ (timeval->milliseconds now) timeout))))) 5217 (loop 5218 ;; FD-INPUT-AVAILABLE-P can return NIL (e.g., if the 5219 ;; thread receives an interrupt) before a timeout is 5220 ;; reached. 5221 (when (fd-input-available-p fd (or timeout -1)) 5222 (return t)) 5223 ;; If it returned and a timeout was specified, check 5224 ;; to see if it's been exceeded. If so, return NIL; 5225 ;; otherwise, adjust the remaining timeout. 5226 ;; If there was no timeout, continue to wait forever. 5227 (when timeout 5228 (#_gettimeofday now +null-ptr+) 5229 (setq timeout (- wait-end (timeval->milliseconds now))) 5230 (if (<= timeout 0) 5231 (return))))))) 5226 5232 5227 5233 … … 5231 5237 (- #$ETIMEDOUT))) 5232 5238 5233 (defun process-output-wait (fd )5239 (defun process-output-wait (fd &optional timeout) 5234 5240 "Wait until output is possible on a given file descriptor." 5235 (loop 5236 (when (fd-ready-for-output-p fd nil) 5237 (return t)))) 5241 (rlet ((now :timeval)) 5242 (let* ((wait-end 5243 (if timeout 5244 (multiple-value-bind (seconds millis) (milliseconds timeout) 5245 (#_gettimeofday now +null-ptr+) 5246 (setq timeout (+ (* seconds 1000) millis)) 5247 (+ (timeval->milliseconds now) timeout))))) 5248 (loop 5249 ;; FD-INPUT-AVAILABLE-P can return NIL (e.g., if the 5250 ;; thread receives an interrupt) before a timeout is 5251 ;; reached. 5252 (when (fd-ready-for-output-p fd (or timeout -1)) 5253 (return t)) 5254 ;; If it returned and a timeout was specified, check 5255 ;; to see if it's been exceeded. If so, return NIL; 5256 ;; otherwise, adjust the remaining timeout. 5257 ;; If there was no timeout, continue to wait forever. 5258 (when timeout 5259 (#_gettimeofday now +null-ptr+) 5260 (setq timeout (- wait-end (timeval->milliseconds now))) 5261 (if (<= timeout 0) 5262 (return))))))) 5238 5263 5239 5264 … … 5249 5274 (pref tv :timeval.tv_usec) us))))) 5250 5275 5251 (defun fd-input-available-p (fd &optional ticks) 5252 (rletZ ((tv :timeval)) 5253 (ticks-to-timeval ticks tv) 5254 (%stack-block ((infds *fd-set-size*)) 5255 (fd-zero infds) 5256 (fd-set fd infds) 5257 (let* ((res (syscall syscalls::select (1+ fd) infds (%null-ptr) (%null-ptr) 5258 (if ticks tv (%null-ptr))))) 5259 (> res 0))))) 5260 5261 (defun fd-ready-for-output-p (fd &optional ticks) 5262 (rletZ ((tv :timeval)) 5263 (ticks-to-timeval ticks tv) 5264 (%stack-block ((outfds *fd-set-size*)) 5265 (fd-zero outfds) 5266 (fd-set fd outfds) 5267 (let* ((res (#_select (1+ fd) (%null-ptr) outfds (%null-ptr) 5268 (if ticks tv (%null-ptr))))) 5269 (> res 0))))) 5276 (defun fd-input-available-p (fd &optional milliseconds) 5277 (rlet ((pollfds (:array (:struct :pollfd) 1))) 5278 (setf (pref (paref pollfds (:* (:struct :pollfd)) 0) :pollfd.fd) fd 5279 (pref (paref pollfds (:* (:struct :pollfd)) 0) :pollfd.events) #$POLLIN) 5280 (let* ((res (ignoring-eintr (syscall syscalls::poll pollfds 1 (or milliseconds -1))))) 5281 (> res 0)))) 5282 5283 5284 (defun fd-ready-for-output-p (fd &optional milliseconds) 5285 (rlet ((pollfds (:array (:struct :pollfd) 1))) 5286 (setf (pref (paref pollfds (:* (:struct :pollfd)) 0) :pollfd.fd) fd 5287 (pref (paref pollfds (:* (:struct :pollfd)) 0) :pollfd.events) #$POLLOUT) 5288 (let* ((res (ignoring-eintr (syscall syscalls::poll pollfds 1 (or milliseconds -1))))) 5289 (> res 0)))) 5270 5290 5271 5291 (defun fd-urgent-data-available-p (fd &optional ticks) … … 5577 5597 (tem-path (merge-pathnames (make-pathname :name (%integer-to-string date) :type "tem" :defaults nil) path))) 5578 5598 (loop 5579 (when (%create-file tem-path :if-exists nil) (return tem-path)) 5599 (when (%create-file tem-path :if-exists nil) (return tem-path)) 5580 5600 (setf (%pathname-name tem-path) (%integer-to-string (setq date (1+ date))))))) 5581 5601 -
branches/event-ide/ccl/level-1/linux-files.lisp
r8262 r8304 66 66 (setq r 0) 67 67 (setq r (floor (* r 1000)))) 68 (values q r))) 69 70 (defun microseconds (n) 71 (unless (and (typep n 'fixnum) 72 (>= (the fixnum n) 0)) 73 (check-type n (real 0 #xffffffff))) 74 (multiple-value-bind (q r) 75 (floor n) 76 (if (zerop r) 77 (setq r 0) 78 (setq r (floor (* r 1000000)))) 68 79 (values q r))) 69 80 … … 433 444 (pref result :timeval.tv_usec) micros) 434 445 result)) 446 447 ;;; Return T iff the time denoted by the timeval a is not later than the 448 ;;; time denoted by the timeval b. 449 (defun %timeval<= (a b) 450 (let* ((asec (pref a :timeval.tv_sec)) 451 (bsec (pref b :timeval.tv_sec))) 452 (or (< asec bsec) 453 (and (= asec bsec) 454 (< (pref a :timeval.tv_usec) 455 (pref b :timeval.tv_usec)))))) 435 456 436 457 … … 832 853 (signal-semaphore (external-process-completed p)) 833 854 (return)) 834 ( ifin-fd835 (when (fd-input-available-p in-fd *ticks-per-second*)855 (when in-fd 856 (when (fd-input-available-p in-fd 0) 836 857 (%stack-block ((buf 1024)) 837 858 (let* ((n (fd-read in-fd buf 1024))) -
branches/event-ide/ccl/lib/backtrace-lds.lisp
r7255 r8304 39 39 (defun frame-supplied-args (frame lfun pc child context) 40 40 (declare (ignore child)) 41 (let* ((arglist (arglist-from-map lfun)) 42 (args (arguments-and-locals context frame lfun pc)) 43 (state :required)) 44 (collect ((arg-values) 45 (types) 46 (names)) 47 (dolist (arg arglist) 48 (if (or (member arg lambda-list-keywords) 49 (eq arg '&lexpr)) 50 (setq state arg) 51 (let* ((pair (pop args))) 52 (case state 53 (&lexpr 54 (with-list-from-lexpr (rest (cdr pair)) 55 (dolist (r rest) (arg-values r) (names nil) (types nil))) 56 (return)) 57 (&rest 58 (dolist (r (cdr pair)) (arg-values r) (names nil) (types nil)) 59 (return)) 60 (&key 61 (arg-values arg) 62 (names nil) 63 (types nil))) 64 (let* ((value (cdr pair))) 65 (if (eq value (%unbound-marker)) 66 (return)) 67 (names (car pair)) 68 (arg-values value) 69 (types nil))))) 70 (values (arg-values) (types) (names))))) 71 72 ;;; I'm skeptical about a lot of this stuff on the PPC, but if anything it's 73 ;;; pretty PPC-specific 74 #+ppc-target 75 (progn 76 ;;; Act as if VSTACK-INDEX points somewhere where DATA could go & put it there. 77 (defun set-lisp-data (vstack-index data) 78 (let* ((old (%access-lisp-data vstack-index))) 79 (if (closed-over-value-p old) 80 (set-closed-over-value old data) 81 (%store-lisp-data vstack-index data)))) 41 (if (null pc) 42 (values nil nil nil) 43 (if (<= pc target::arg-check-trap-pc-limit) 44 (values (arg-check-call-arguments frame lfun) nil nil) 45 (let* ((arglist (arglist-from-map lfun)) 46 (args (arguments-and-locals context frame lfun pc)) 47 (state :required)) 48 (collect ((arg-values) 49 (types) 50 (names)) 51 (dolist (arg arglist) 52 (if (or (member arg lambda-list-keywords) 53 (eq arg '&lexpr)) 54 (setq state arg) 55 (let* ((pair (pop args))) 56 (case state 57 (&lexpr 58 (with-list-from-lexpr (rest (cdr pair)) 59 (dolist (r rest) (arg-values r) (names nil) (types nil))) 60 (return)) 61 (&rest 62 (dolist (r (cdr pair)) (arg-values r) (names nil) (types nil)) 63 (return)) 64 (&key 65 (arg-values arg) 66 (names nil) 67 (types nil))) 68 (let* ((value (cdr pair))) 69 (if (eq value (%unbound-marker)) 70 (return)) 71 (names (car pair)) 72 (arg-values value) 73 (types nil))))) 74 (values (arg-values) (types) (names))))))) 82 75 83 76 84 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85 ;;86 ;;extensions to let user access and modify values87 88 89 90 91 92 ;;; nth-frame-info, set-nth-frame-info, & frame-lfun are in "inspector;new-backtrace"93 94 95 96 97 98 99 (defparameter *saved-register-count+1*100 (1+ *saved-register-count*))101 102 103 104 (defparameter *saved-register-numbers*105 #+x8664-target #(wrong)106 #+ppc-target #(31 30 29 28 27 26 25 24))107 108 ;;; Don't do unbound checks in compiled code109 (declaim (type t *saved-register-count* *saved-register-count+1*110 *saved-register-names* *saved-register-numbers*))111 112 (defmacro %cons-saved-register-vector ()113 `(make-array (the fixnum *saved-register-count+1*) :initial-element nil))114 115 (defun copy-srv (from-srv &optional to-srv)116 (if to-srv117 (if (eq from-srv to-srv)118 to-srv119 (dotimes (i (uvsize from-srv) to-srv)120 (setf (uvref to-srv i) (uvref from-srv i))))121 (copy-uvector from-srv)))122 123 (defmacro srv.unresolved (saved-register-vector)124 `(svref ,saved-register-vector 0))125 126 (defmacro srv.register-n (saved-register-vector n)127 `(svref ,saved-register-vector (1+ ,n)))128 129 ;;; This isn't quite right - has to look at all functions on stack,130 ;;; not just those that saved VSPs.131 132 133 (defun frame-restartable-p (target &optional context)134 (multiple-value-bind (frame last-catch srv) (last-catch-since-saved-vars target context)135 (when frame136 (loop137 (when (null frame)138 (return-from frame-restartable-p nil))139 (when (eq frame target) (return))140 (multiple-value-setq (frame last-catch srv)141 (ccl::parent-frame-saved-vars context frame last-catch srv srv)))142 (when (and srv (eql 0 (srv.unresolved srv)))143 (setf (srv.unresolved srv) last-catch)144 srv))))145 146 147 ;;; get the saved register addresses for this frame148 ;;; still need to worry about this unresolved business149 ;;; could share some code with parent-frame-saved-vars150 (defun my-saved-vars (frame &optional (srv-out (%cons-saved-register-vector)))151 (let ((unresolved 0))152 (multiple-value-bind (lfun pc) (cfp-lfun frame)153 (if lfun154 (multiple-value-bind (mask where) (registers-used-by lfun pc)155 (when mask156 (if (not where)157 (setq unresolved (%ilogior unresolved mask))158 (let ((vsp (- (frame-vsp frame) where (1- (logcount mask))))159 (j *saved-register-count*))160 (declare (fixnum j))161 (dotimes (i j)162 (declare (fixnum i))163 (when (%ilogbitp (decf j) mask)164 (setf (srv.register-n srv-out i) vsp165 vsp (1+ vsp)166 unresolved (%ilogand unresolved (%ilognot (%ilsl j 1))))))))))167 (setq unresolved (1- (ash 1 *saved-register-count*)))))168 (setf (srv.unresolved srv-out) unresolved)169 srv-out))170 171 (defun parent-frame-saved-vars172 (context frame last-catch srv &optional (srv-out (%cons-saved-register-vector)))173 (copy-srv srv srv-out)174 (let* ((parent (and frame (parent-frame frame context)))175 (grand-parent (and parent (parent-frame parent context))))176 (when grand-parent177 (loop (let ((next-catch (and last-catch (next-catch last-catch))))178 ;(declare (ignore next-catch))179 (if (and next-catch (%stack< (catch-frame-sp next-catch) grand-parent context))180 (progn181 (setf last-catch next-catch182 (srv.unresolved srv-out) 0)183 (dotimes (i *saved-register-count*)184 (setf (srv.register-n srv i) nil)))185 (return))))186 (lookup-registers parent context grand-parent srv-out)187 (values parent last-catch srv-out))))188 189 (defun lookup-registers (parent context grand-parent srv-out)190 (unless (or (eql (frame-vsp grand-parent) 0)191 (let ((gg-parent (parent-frame grand-parent context)))192 (eql (frame-vsp gg-parent) 0)))193 (multiple-value-bind (lfun pc) (cfp-lfun parent)194 (when lfun195 (multiple-value-bind (mask where) (registers-used-by lfun pc)196 (when mask197 (locally (declare (fixnum mask))198 (if (not where)199 (setf (srv.unresolved srv-out) (%ilogior (srv.unresolved srv-out) mask))200 (let* ((grand-parent-vsp (frame-vsp grand-parent)))201 202 (let ((vsp (- grand-parent-vsp where 1))203 (j *saved-register-count*))204 (declare (fixnum j))205 (dotimes (i j)206 (declare (fixnum i))207 (when (%ilogbitp (decf j) mask)208 (setf (srv.register-n srv-out i) vsp209 vsp (1- vsp)210 (srv.unresolved srv-out)211 (%ilogand (srv.unresolved srv-out) (%ilognot (%ilsl j 1))))))))))))))))212 213 ;;; initialization for looping on parent-frame-saved-vars214 (defun last-catch-since-saved-vars (frame context)215 (let* ((parent (parent-frame frame context))216 (last-catch (and parent (last-catch-since parent context))))217 (when last-catch218 (let ((frame (catch-frame-sp last-catch))219 (srv (%cons-saved-register-vector)))220 (setf (srv.unresolved srv) 0)221 (let* ((parent (parent-frame frame context))222 (child (and parent (child-frame parent context))))223 (when child224 (lookup-registers child context parent srv))225 (values child last-catch srv))))))226 227 ;;; Returns 2 values:228 ;;; mask srv229 ;;; The mask says which registers are used at PC in LFUN. srv is a230 ;;; saved-register-vector whose register contents are the register231 ;;; values registers whose bits are not set in MASK or set in232 ;;; UNRESOLVED will be returned as NIL.233 234 (defun saved-register-values235 (lfun pc child last-catch srv &optional (srv-out (%cons-saved-register-vector)))236 (declare (ignore child))237 (cond ((null srv-out) (setq srv-out (copy-uvector srv)))238 ((eq srv-out srv))239 (t (dotimes (i (the fixnum (uvsize srv)))240 (setf (uvref srv-out i) (uvref srv i)))))241 (let ((mask (or (registers-used-by lfun pc) 0))242 (unresolved (srv.unresolved srv))243 (j *saved-register-count*))244 (declare (fixnum j))245 (dotimes (i j)246 (declare (fixnum i))247 (setf (srv.register-n srv-out i)248 (and (%ilogbitp (setq j (%i- j 1)) mask)249 (not (%ilogbitp j unresolved))250 (safe-cell-value (get-register-value (srv.register-n srv i) last-catch j)))))251 (setf (srv.unresolved srv-out) mask)252 (values mask srv-out)))253 254 ; Set the nth saved register to value.255 (defun set-saved-register (value n lfun pc child last-catch srv)256 (declare (ignore lfun pc child) (dynamic-extent saved-register-values))257 (let ((j (- target::node-size n))258 (unresolved (srv.unresolved srv))259 (addr (srv.register-n srv n)))260 (when (logbitp j unresolved)261 (error "Can't set register ~S to ~S" n value))262 (set-register-value value addr last-catch j))263 value)264 265 266 267 268 269 (defun return-from-nth-frame (n &rest values)270 (apply-in-nth-frame n #'values values))271 272 (defun apply-in-nth-frame (n fn arglist)273 (let* ((bt-info (car *backtrace-contexts*)))274 (and bt-info275 (let* ((frame (nth-frame nil (bt.youngest bt-info) n bt-info)))276 (and frame (apply-in-frame frame fn arglist)))))277 (format t "Can't return to frame ~d ." n))278 279 ;;; This method is shadowed by one for the backtrace window.280 (defmethod nth-frame (w target n context)281 (declare (ignore w))282 (and target (dotimes (i n target)283 (declare (fixnum i))284 (unless (setq target (parent-frame target context)) (return nil)))))285 286 ; If this returns at all, it's because the frame wasn't restartable.287 (defun apply-in-frame (frame fn arglist &optional context)288 (let* ((srv (frame-restartable-p frame context))289 (target-sp (and srv (srv.unresolved srv))))290 (if target-sp291 (apply-in-frame-internal context frame fn arglist srv))))292 293 (defun apply-in-frame-internal (context frame fn arglist srv)294 (let* ((tcr (if context (bt.tcr context) (%current-tcr))))295 (if (eq tcr (%current-tcr))296 (%apply-in-frame frame fn arglist srv)297 (let ((process (tcr->process tcr)))298 (if process299 (process-interrupt300 process301 #'%apply-in-frame302 frame fn arglist srv)303 (error "Can't find active process for ~s" tcr))))))304 305 306 307 308 ;;; (srv.unresolved srv) is the last catch frame, left there by309 ;;; frame-restartable-p The registers in srv are locations of310 ;;; variables saved between frame and that catch frame.311 (defun %apply-in-frame (frame fn arglist srv)312 (declare (fixnum frame))313 (let* ((catch (srv.unresolved srv))314 (tsp-count 0)315 (tcr (%current-tcr))316 (parent (parent-frame frame tcr))317 (vsp (frame-vsp parent))318 (catch-top (%catch-top tcr))319 (db-link (%svref catch target::catch-frame.db-link-cell))320 (catch-count 0))321 (declare (fixnum parent vsp db-link catch-count))322 ;; Figure out how many catch frames to throw through323 (loop324 (unless catch-top325 (error "Didn't find catch frame"))326 (incf catch-count)327 (when (eq catch-top catch)328 (return))329 (setq catch-top (next-catch catch-top)))330 ;; Figure out where the db-link should be331 (loop332 (when (or (eql db-link 0) (>= db-link vsp))333 (return))334 (setq db-link (%fixnum-ref db-link)))335 ;; Figure out how many TSP frames to pop after throwing.336 (let ((sp (catch-frame-sp catch)))337 (loop338 (multiple-value-bind (f pc) (cfp-lfun sp)339 (when f (incf tsp-count (active-tsp-count f pc))))340 (setq sp (parent-frame sp tcr))341 (when (eql sp parent) (return))342 (unless sp (error "Didn't find frame: ~s" frame))))343 #+debug344 (cerror "Continue" "(apply-in-frame ~s ~s ~s ~s ~s ~s ~s)"345 catch-count srv tsp-count db-link parent fn arglist)346 (%%apply-in-frame catch-count srv tsp-count db-link parent fn arglist)))347 348 349 350 351 ;;;;;;;;;;;;;;;;;;;;;;;352 ;;;353 ;;; Code to determine how many tsp frames to pop.354 ;;; This is done by parsing the code.355 ;;; active-tsp-count is the entry point below.356 ;;;357 358 #+ppc-target359 (progn360 361 (defstruct (branch-tree (:print-function print-branch-tree))362 first-instruction363 last-instruction364 branch-target ; a branch-tree or nil365 fall-through) ; a branch-tree or nil366 367 (defun print-branch-tree (tree stream print-level)368 (declare (ignore print-level))369 (print-unreadable-object (tree stream :type t :identity t)370 (format stream "~s-~s"371 (branch-tree-first-pc tree)372 (branch-tree-last-pc tree))))373 374 (defun branch-tree-first-pc (branch-tree)375 (let ((first (branch-tree-first-instruction branch-tree)))376 (and first (instruction-element-address first))))377 378 (defun branch-tree-last-pc (branch-tree)379 (let ((last (branch-tree-last-instruction branch-tree)))380 (if last381 (instruction-element-address last)382 (branch-tree-first-pc branch-tree))))383 384 (defun branch-tree-contains-pc-p (branch-tree pc)385 (<= (branch-tree-first-pc branch-tree)386 pc387 (branch-tree-last-pc branch-tree)))388 389 (defvar *branch-tree-hash*390 (make-hash-table :test 'eq :weak :value))391 392 (defun get-branch-tree (function)393 (or (gethash function *branch-tree-hash*)394 (let* ((dll (function-to-dll-header function))395 (tree (dll-to-branch-tree dll)))396 (setf (gethash function *branch-tree-hash*) tree))))397 398 ; Return the number of TSP frames that will be active after throwing out399 ; of all the active catch frames in function at pc.400 ; PC is a byte address, a multiple of 4.401 (defun active-tsp-count (function pc)402 (setq function403 (require-type404 (if (symbolp function)405 (symbol-function function)406 function)407 'compiled-function))408 (let* ((tree (get-branch-tree function))409 (visited nil))410 (labels ((find-pc (branch path)411 (unless (memq branch visited)412 (push branch path)413 (if (branch-tree-contains-pc-p branch pc)414 path415 (let ((target (branch-tree-branch-target branch))416 (fall-through (branch-tree-fall-through branch)))417 (push branch visited)418 (if fall-through419 (or (and target (find-pc target path))420 (find-pc fall-through path))421 (and target (find-pc target path))))))))422 (let* ((path (nreverse (find-pc tree nil)))423 (last-tree (car (last path)))424 (catch-count 0)425 (tsp-count 0))426 (unless path427 (error "Can't find path to pc: ~s in ~s" pc function))428 (dolist (tree path)429 (let ((next (branch-tree-first-instruction tree))430 (last (branch-tree-last-instruction tree)))431 (loop432 (when (and (eq tree last-tree)433 (eql pc (instruction-element-address next)))434 ; If the instruction before the current one is an ff-call,435 ; then callback pushed a TSP frame.436 #| ; Not any more437 (when (ff-call-instruction-p (dll-node-pred next))438 (incf tsp-count))439 |#440 (return))441 (multiple-value-bind (type target fall-through count) (categorize-instruction next)442 (declare (ignore target fall-through))443 (case type444 (:tsp-push445 (when (eql catch-count 0)446 (incf tsp-count count)))447 (:tsp-pop448 (when (eql catch-count 0)449 (decf tsp-count count)))450 ((:catch :unwind-protect)451 (incf catch-count))452 (:throw453 (decf catch-count count))))454 (when (eq next last)455 (return))456 (setq next (dll-node-succ next)))))457 tsp-count))))458 459 460 (defun dll-to-branch-tree (dll)461 (let* ((hash (make-hash-table :test 'eql)) ; start-pc -> branch-tree462 (res (collect-branch-tree (dll-header-first dll) dll hash))463 (did-something nil))464 (loop465 (setq did-something nil)466 (let ((mapper #'(lambda (key value)467 (declare (ignore key))468 (flet ((maybe-collect (pc)469 (when (integerp pc)470 (let ((target-tree (gethash pc hash)))471 (if target-tree472 target-tree473 (progn474 (collect-branch-tree (dll-pc->instr dll pc) dll hash)475 (setq did-something t)476 nil))))))477 (declare (dynamic-extent #'maybe-collect))478 (let ((target-tree (maybe-collect (branch-tree-branch-target value))))479 (when target-tree (setf (branch-tree-branch-target value) target-tree)))480 (let ((target-tree (maybe-collect (branch-tree-fall-through value))))481 (when target-tree (setf (branch-tree-fall-through value) target-tree)))))))482 (declare (dynamic-extent mapper))483 (maphash mapper hash))484 (unless did-something (return)))485 ; To be totally correct, we should fix up the trees containing486 ; the BLR instruction for unwind-protect cleanups, but none487 ; of the users of this code yet care that it appears that the code488 ; stops there.489 res))490 491 (defun collect-branch-tree (instr dll hash)492 (unless (eq instr dll)493 (let ((tree (make-branch-tree :first-instruction instr))494 (pred nil)495 (next instr))496 (setf (gethash (instruction-element-address instr) hash)497 tree)498 (loop499 (when (eq next dll)500 (setf (branch-tree-last-instruction tree) pred)501 (return))502 (multiple-value-bind (type target fall-through) (categorize-instruction next)503 (case type504 (:label505 (when pred506 (setf (branch-tree-last-instruction tree) pred507 (branch-tree-fall-through tree) (instruction-element-address next))508 (return)))509 ((:branch :catch :unwind-protect)510 (setf (branch-tree-last-instruction tree) next511 (branch-tree-branch-target tree) target512 (branch-tree-fall-through tree) fall-through)513 (return))))514 (setq pred next515 next (dll-node-succ next)))516 tree)))517 518 ;;; Returns 4 values:519 ;;; 1) type: one of :regular, :label, :branch, :catch, :unwind-protect, :throw, :tsp-push, :tsp-pop520 ;;; 2) branch target (or catch or unwind-protect cleanup)521 ;;; 3) branch-fallthrough (or catch or unwind-protect body)522 ;;; 4) Count for throw, tsp-push, tsp-pop523 #+ppc-target524 (defun categorize-instruction (instr)525 (etypecase instr526 (lap-label :label)527 (lap-instruction528 (let* ((opcode (lap-instruction-opcode instr))529 (opcode-p (typep opcode 'opcode))530 (name (if opcode-p (opcode-name opcode) opcode))531 (pc (lap-instruction-address instr))532 (operands (lap-instruction-parsed-operands instr)))533 (cond ((equalp name "bla")534 (let ((subprim (car operands)))535 (case subprim536 (.SPmkunwind537 (values :unwind-protect (+ pc 4) (+ pc 8)))538 ((.SPmkcatch1v .SPmkcatchmv)539 (values :catch (+ pc 4) (+ pc 8)))540 (.SPthrow541 (values :branch nil nil))542 ((.SPnthrowvalues .SPnthrow1value)543 (let* ((prev-instr (require-type (lap-instruction-pred instr)544 'lap-instruction))545 (prev-name (opcode-name (lap-instruction-opcode prev-instr)))546 (prev-operands (lap-instruction-parsed-operands prev-instr)))547 ; Maybe we should recognize the other possible outputs of ppc2-lwi, but I548 ; can't imagine we'll ever see them549 (unless (and (equalp prev-name "li")550 (equalp (car prev-operands) "imm0"))551 (error "Can't determine throw count for ~s" instr))552 (values :throw nil (+ pc 4) (ash (cadr prev-operands) (- target::fixnum-shift)))))553 ((.SPprogvsave554 .SPstack-rest-arg .SPreq-stack-rest-arg .SPstack-cons-rest-arg555 .SPmakestackblock .SPmakestackblock0 .SPmakestacklist .SPstkgvector556 .SPstkconslist .SPstkconslist-star557 .SPmkstackv .SPstack-misc-alloc .SPstack-misc-alloc-init558 .SPstkvcell0 .SPstkvcellvsp559 .SPsave-values)560 (values :tsp-push nil nil 1))561 (.SPrecover-values562 (values :tsp-pop nil nil 1))563 (t :regular))))564 ((or (equalp name "lwz") (equalp name "addi"))565 (if (equalp (car operands) "tsp")566 (values :tsp-pop nil nil 1)567 :regular))568 ((equalp name "stwu")569 (if (equalp (car operands) "tsp")570 (values :tsp-push nil nil 1)571 :regular))572 ((member name '("ba" "blr" "bctr") :test 'equalp)573 (values :branch nil nil))574 ; It would probably be faster to determine the branch address by adding the PC and the offset.575 ((equalp name "b")576 (values :branch (branch-label-address instr (car (last operands))) nil))577 ((and opcode-p (eql (opcode-majorop opcode) 16))578 (values :branch (branch-label-address instr (car (last operands))) (+ pc 4)))579 (t :regular))))))580 581 (defun branch-label-address (instr label-name &aux (next instr))582 (loop583 (setq next (dll-node-succ next))584 (when (eq next instr)585 (error "Couldn't find label ~s" label-name))586 (when (and (typep next 'lap-label)587 (eq (lap-label-name next) label-name))588 (return (instruction-element-address next)))))589 590 (defun dll-pc->instr (dll pc)591 (let ((next (dll-node-succ dll)))592 (loop593 (when (eq next dll)594 (error "Couldn't find pc: ~s in ~s" pc dll))595 (when (eql (instruction-element-address next) pc)596 (return next))597 (setq next (dll-node-succ next)))))598 599 ) ; end of #+ppc-target progn600 ) ; end of another #+ppc-target progn601 77 #| 602 78 (setq *save-local-symbols* t) -
branches/event-ide/ccl/lib/backtrace.lisp
r8262 r8304 96 96 (call 'funcall) 97 97 (call `(function ,(concatenate 'string "#<" (%lfun-name-string lfun) ">"))))) 98 (if ( <= pc target::arg-check-trap-pc-limit)98 (if (and pc (<= pc target::arg-check-trap-pc-limit)) 99 99 (append (call) (arg-check-call-arguments cfp lfun)) 100 100 (multiple-value-bind (req opt restp keys) … … 102 102 (when (or (not (eql 0 req)) (not (eql 0 opt)) restp keys) 103 103 (let* ((arglist (arglist-from-map lfun))) 104 (if ( null arglist)104 (if (or (null arglist) (null pc)) 105 105 (call "???") 106 106 (progn -
branches/event-ide/ccl/lib/foreign-types.lisp
r8262 r8304 1701 1701 (canonicalize-foreign-type-ordinal '(:* (:struct :hostent))) 1702 1702 (canonicalize-foreign-type-ordinal '(:array :int 2)) 1703 )))1703 (canonicalize-foreign-type-ordinal '(:array (:struct :pollfd) 1))))) 1704 1704 1705 1705 (defun install-standard-foreign-types (ftd) -
branches/event-ide/ccl/lib/macros.lisp
r8262 r8304 3513 3513 (return ,res)))))) 3514 3514 3515 (defmacro ignoring-eintr (&body body) 3516 (let* ((res (gensym)) 3517 (eintr (symbol-value (read-from-string "#$EINTR")))) 3518 `(loop 3519 (let* ((,res ,@body)) 3520 (unless (eql ,res (- ,eintr)) 3521 (return ,res)))))) 3522 3515 3523 (defmacro basic-stream-ioblock (s) 3516 3524 `(or (basic-stream.state ,s) -
branches/event-ide/ccl/library/darwinppc-syscalls.lisp
r4968 r8304 93 93 (define-syscall (logior platform-os-darwin platform-cpu-ppc) syscalls::ftruncate 201 (:unsigned-fullword :unsigned-doubleword) :signed-fullword ) 94 94 95 (define-syscall (logior platform-os-darwin platform-cpu-ppc) syscalls::poll 230 ((:* (:struct :pollfd)) :int :int) :int) 96 95 97 #+notdefinedyet 96 98 (progn -
branches/event-ide/ccl/library/x8664-freebsd-syscalls.lisp
r7434 r8304 156 156 (define-syscall (logior platform-os-freebsd platform-cpu-x86 platform-word-size-64) syscalls::getcwd 326 (:address :unsigned-fullword) :signed-fullword ) 157 157 158 158 (define-syscall (logior platform-os-freebsd platform-cpu-x86 platform-word-size-64) syscalls::poll 209 ((:* (:struct :pollfd)) :int :int) :int) 159 159 160 160 #+notdefinedyet -
branches/event-ide/ccl/library/x8664-linux-syscalls.lisp
r8262 r8304 34 34 (define-syscall (logior platform-os-linux platform-cpu-x86 platform-word-size-64) syscalls::fstat 5 (:unsigned-fullword :address) :signed-fullword ) 35 35 (define-syscall (logior platform-os-linux platform-cpu-x86 platform-word-size-64) syscalls::lstat 6 (:address :address) :signed-fullword) 36 36 (define-syscall (logior platform-os-linux platform-cpu-x86 platform-word-size-64) syscalls::poll 7 ((:* (:struct :pollfd)) :int :int) :int) 37 37 (define-syscall (logior platform-os-linux platform-cpu-x86 platform-word-size-64) syscalls::lseek 8 (:int :off_t :int) :off_t ) 38 38 -
branches/event-ide/ccl/lisp-kernel/x86-macros.s
r8262 r8304 65 65 .macro zero_dnodes base,disp,nbytes 66 66 .ifgt \nbytes 67 __(movapd %fpzero,\disp(\base))67 movapd %fpzero,\disp(\base) 68 68 zero_dnodes \base,"\disp+dnode_size","\nbytes-dnode_size" 69 69 .endif
Note:
See TracChangeset
for help on using the changeset viewer.
