X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Faliencomp.lisp;h=4321c3174ba69099d534c5917eba053834626003;hb=ee2d3451514e7b4fa7af68511a22a153b879c8cd;hp=fec6e5bfe89cf0eb21d8019254f6729dd3c71d1e;hpb=0f234877047c56ca945fe54e9e77a9cc2c8141cb;p=sbcl.git diff --git a/src/compiler/aliencomp.lisp b/src/compiler/aliencomp.lisp index fec6e5b..4321c31 100644 --- a/src/compiler/aliencomp.lisp +++ b/src/compiler/aliencomp.lisp @@ -190,6 +190,8 @@ (abort-ir1-transform "too many indices for pointer deref: ~W" (length indices))) (let ((element-type (alien-pointer-type-to alien-type))) + (unless element-type + (give-up-ir1-transform "unable to open code deref of wild pointer type")) (if indices (let ((bits (alien-type-bits element-type)) (alignment (alien-type-alignment element-type))) @@ -332,7 +334,8 @@ (deftransform %heap-alien-addr ((info) * * :important t) (multiple-value-bind (sap type) (heap-alien-sap-and-type info) (/noshow "in DEFTRANSFORM %HEAP-ALIEN-ADDR, creating %SAP-ALIEN") - `(%sap-alien ,sap ',type))) + `(%sap-alien ,sap ',(make-alien-pointer-type :to type)))) + ;;;; support for local (stack or register) aliens @@ -348,26 +351,26 @@ (/noshow (local-alien-info-force-to-memory-p info)) (/noshow alien-type (unparse-alien-type alien-type) (alien-type-bits alien-type)) (if (local-alien-info-force-to-memory-p info) - #!+(or x86 x86-64) `(truly-the system-area-pointer - (%primitive alloc-alien-stack-space - ,(ceiling (alien-type-bits alien-type) - sb!vm:n-byte-bits))) - #!-(or x86 x86-64) `(truly-the system-area-pointer - (%primitive alloc-number-stack-space - ,(ceiling (alien-type-bits alien-type) - sb!vm:n-byte-bits))) - (let* ((alien-rep-type-spec (compute-alien-rep-type alien-type)) - (alien-rep-type (specifier-type alien-rep-type-spec))) - (cond ((csubtypep (specifier-type 'system-area-pointer) - alien-rep-type) - '(int-sap 0)) - ((ctypep 0 alien-rep-type) 0) - ((ctypep 0.0f0 alien-rep-type) 0.0f0) - ((ctypep 0.0d0 alien-rep-type) 0.0d0) - (t - (compiler-error - "Aliens of type ~S cannot be represented immediately." - (unparse-alien-type alien-type)))))))) + #!+(or x86 x86-64) + `(%primitive alloc-alien-stack-space + ,(ceiling (alien-type-bits alien-type) + sb!vm:n-byte-bits)) + #!-(or x86 x86-64) + `(%primitive alloc-number-stack-space + ,(ceiling (alien-type-bits alien-type) + sb!vm:n-byte-bits)) + (let* ((alien-rep-type-spec (compute-alien-rep-type alien-type)) + (alien-rep-type (specifier-type alien-rep-type-spec))) + (cond ((csubtypep (specifier-type 'system-area-pointer) + alien-rep-type) + '(int-sap 0)) + ((ctypep 0 alien-rep-type) 0) + ((ctypep 0.0f0 alien-rep-type) 0.0f0) + ((ctypep 0.0d0 alien-rep-type) 0.0d0) + (t + (compiler-error + "Aliens of type ~S cannot be represented immediately." + (unparse-alien-type alien-type)))))))) (deftransform note-local-alien-type ((info var) * * :important t) ;; FIXME: This test and error occur about a zillion times. They @@ -525,7 +528,7 @@ (count-low-order-zeros (lvar-uses thing)))) (combination (case (let ((name (lvar-fun-name (combination-fun thing)))) - (or (modular-version-info name :unsigned) name)) + (or (modular-version-info name :untagged nil) name)) ((+ -) (let ((min most-positive-fixnum) (itype (specifier-type 'integer))) @@ -582,7 +585,7 @@ (give-up-ir1-transform)) (let ((inside-fun-name (lvar-fun-name (combination-fun value-node)))) (multiple-value-bind (prototype width) - (modular-version-info inside-fun-name :unsigned) + (modular-version-info inside-fun-name :untagged nil) (unless (eq (or prototype inside-fun-name) 'ash) (give-up-ir1-transform)) (when (and width (not (constant-lvar-p amount))) @@ -612,7 +615,36 @@ `(lambda (function ,@names) (alien-funcall (deref function) ,@names)))) -(deftransform alien-funcall ((function &rest args) * * :important t) +;;; Frame pointer, program counter conses. In each thread it's bound +;;; locally or not bound at all. +(defvar *saved-fp-and-pcs*) + +#!+:c-stack-is-control-stack +(declaim (inline invoke-with-saved-fp-and-pc)) +#!+:c-stack-is-control-stack +(defun invoke-with-saved-fp-and-pc (fn) + (declare #-sb-xc-host (muffle-conditions compiler-note) + (optimize (speed 3))) + (let* ((fp-and-pc (cons (%caller-frame) + (sap-int (%caller-pc))))) + (declare (truly-dynamic-extent fp-and-pc)) + (let ((*saved-fp-and-pcs* (if (boundp '*saved-fp-and-pcs*) + (cons fp-and-pc *saved-fp-and-pcs*) + (list fp-and-pc)))) + (declare (truly-dynamic-extent *saved-fp-and-pcs*)) + (funcall fn)))) + +(defun find-saved-fp-and-pc (fp) + (when (boundp '*saved-fp-and-pcs*) + (dolist (x *saved-fp-and-pcs*) + (when (#!+:stack-grows-downward-not-upward + sap> + #!-:stack-grows-downward-not-upward + sap< + (int-sap (get-lisp-obj-address (car x))) fp) + (return (values (car x) (cdr x))))))) + +(deftransform alien-funcall ((function &rest args) * * :node node :important t) (let ((type (lvar-type function))) (unless (alien-type-type-p type) (give-up-ir1-transform "can't tell function type at compile time")) @@ -666,6 +698,12 @@ `(multiple-value-bind ,(temps) ,body (values ,@(results))))) (setf body `(naturalize ,body ',return-type))) + ;; Remember this frame to make sure that we can get back + ;; to it later regardless of how the foreign stack looks + ;; like. + #!+:c-stack-is-control-stack + (when (policy node (<= speed debug)) + (setf body `(invoke-with-saved-fp-and-pc (lambda () ,body)))) (/noshow "returning from DEFTRANSFORM ALIEN-FUNCALL" (params) body) `(lambda (function ,@(params)) ,body))))))) @@ -679,7 +717,8 @@ (error "Something is broken.")) (values-specifier-type (compute-alien-rep-type - (alien-fun-type-result-type type))))) + (alien-fun-type-result-type type) + :result)))) (defoptimizer (%alien-funcall ltn-annotate) ((function type &rest args) node ltn-policy) @@ -700,11 +739,14 @@ (error "Something is broken."))) (lvar (node-lvar call)) (args args) - #!+(or (and (or x86 x86-64) darwin) win32) (stack-pointer (make-stack-pointer-tn))) + #!+x86 + (stack-pointer (make-stack-pointer-tn))) (multiple-value-bind (nsp stack-frame-size arg-tns result-tns) (make-call-out-tns type) - #!+x86 (vop set-fpu-word-for-c call block) - #!+(or (and (or x86 x86-64) darwin) win32) (vop current-stack-pointer call block stack-pointer) + #!+x86 + (progn + (vop set-fpu-word-for-c call block) + (vop current-stack-pointer call block stack-pointer)) (vop alloc-number-stack-space call block stack-frame-size nsp) (dolist (tn arg-tns) ;; On PPC, TN might be a list. This is used to indicate @@ -722,22 +764,22 @@ (unless (= (length move-arg-vops) 1) (error "no unique move-arg-vop for moves in SC ~S" (sc-name sc))) #!+(or x86 x86-64) (emit-move-arg-template call - block - (first move-arg-vops) - (lvar-tn call block arg) - nsp - first-tn) + block + (first move-arg-vops) + (lvar-tn call block arg) + nsp + first-tn) #!-(or x86 x86-64) (progn - (emit-move call - block - (lvar-tn call block arg) - temp-tn) - (emit-move-arg-template call - block - (first move-arg-vops) - temp-tn - nsp - first-tn)) + (emit-move call + block + (lvar-tn call block arg) + temp-tn) + (emit-move-arg-template call + block + (first move-arg-vops) + temp-tn + nsp + first-tn)) #!+(and ppc darwin) (when (listp tn) ;; This means that we have a float arg that we need to @@ -759,7 +801,10 @@ ((lvar-tn call block function) (reference-tn-list arg-tns nil)) ((reference-tn-list result-tns t)))) - #!-(or (and darwin (or x86 x86-64)) win32) (vop dealloc-number-stack-space call block stack-frame-size) - #!+(or (and darwin (or x86 x86-64)) win32) (vop reset-stack-pointer call block stack-pointer) - #!+x86 (vop set-fpu-word-for-lisp call block) + #!-x86 + (vop dealloc-number-stack-space call block stack-frame-size) + #!+x86 + (progn + (vop reset-stack-pointer call block stack-pointer) + (vop set-fpu-word-for-lisp call block)) (move-lvar-result call block result-tns lvar))))