[armedbear-cvs] r13154 - branches/unsafe-p-removal/abcl/src/org/armedbear/lisp
Erik Huelsmann
ehuelsmann at common-lisp.net
Mon Jan 17 21:19:38 UTC 2011
Author: ehuelsmann
Date: Mon Jan 17 16:19:33 2011
New Revision: 13154
Log:
Provide better infrastructure for operand accumulation.
Modified:
branches/unsafe-p-removal/abcl/src/org/armedbear/lisp/compiler-pass2.lisp
Modified: branches/unsafe-p-removal/abcl/src/org/armedbear/lisp/compiler-pass2.lisp
==============================================================================
--- branches/unsafe-p-removal/abcl/src/org/armedbear/lisp/compiler-pass2.lisp (original)
+++ branches/unsafe-p-removal/abcl/src/org/armedbear/lisp/compiler-pass2.lisp Mon Jan 17 16:19:33 2011
@@ -667,17 +667,40 @@
(declaim (special *saved-operands* *operand-representations*))
-(defmacro with-operand-accumulation ((&body argument-buildup-body)
- &body funcall-body)
+(defmacro with-operand-accumulation ((&body argument-accumulation-body)
+ &body call-body)
+ "Macro used to operand-stack-safely collect arguments in the
+`argument-accumulation-body' to be available on the stack upon entry of the
+`call-body'. The argument-accumulation-body code may not assume arguments
+are actually on the stack while accumulating.
+
+This macro closes over a code-generating block. Operands can be collected
+using the `accumulate-operand', `compile-operand', `emit-variable-operand'
+and `emit-load-externalized-object-operand'."
`(let (*saved-operands*
- *operand-representations*
- (*register* *register*)
+ *operand-representations*
+ (*register* *register*)
) ;; hmm can we do this?? either body
;; could allocate registers ...
- , at argument-buildup-body
+ , at argument-accumulation-body
(load-saved-operands)
, at funcall-body))
+(defmacro accumulate-operand ((representation &key unsafe-p)
+ &body body)
+ "Macro used to collect a single operand.
+
+This macro closes over a code-generating block. The generated code should
+leave a single operand on the stack, with representation `representation'.
+The value `unsafe-p', when provided, is an expression evaluated at run time
+to indicate if the body is opstack unsafe."
+ `(progn
+ ,@(when unsafe-p
+ `((when ,unsafe-p
+ (save-existing-operands))))
+ , at body
+ (save-operand ,representation)))
+
(defun load-saved-operands ()
"Load any operands which have been saved into registers
back onto the stack in preparation of the execution of the opcode."
@@ -688,31 +711,42 @@
(defun save-existing-operands ()
"If any operands have been compiled to the stack,
save them in registers."
- (dolist (representation *operand-representations*)
+ (when (null *saved-operands*)
+ (dolist (representation *operand-representations*)
+ (let ((register (allocate-register)))
+ (push register *saved-operands*)
+ (emit-move-from-stack register representation)))
+
+ (setf *saved-operands* (nreverse *saved-operands*))))
+
+(defun save-operand (representation)
+ "Saves an operand from the stack (with `representation') to
+a register and updates associated operand collection variables."
+ (push representation *operand-representations*)
+
+ (when *saved-operands*
(let ((register (allocate-register)))
(push register *saved-operands*)
- (emit-move-from-stack register representation)))
-
- (setf *saved-operands* (nreverse *saved-operands*)))
+ (emit-move-from-stack register representation))))
(defun compile-operand (form representation &optional cast)
- "Compiles `form` into `representation`, storing the resulting value
+ "Compiles `form' into `representation', storing the resulting value
on the operand stack, if it's safe to do so. Otherwise stores the value
in a register"
(let ((unsafe (or *saved-operands*
- (some-nested-block #'node-opstack-unsafe-p
- (find-enclosed-blocks form)))))
+ (some-nested-block #'node-opstack-unsafe-p
+ (find-enclosed-blocks form)))))
(when (and unsafe (null *saved-operands*))
(save-existing-operands))
-
+
(compile-form form 'stack representation)
(when cast
(emit-checkcast cast))
(when unsafe
(let ((register (allocate-register)))
- (push register *saved-operands*)
- (emit-move-from-stack register representation)))
-
+ (push register *saved-operands*)
+ (emit-move-from-stack register representation)))
+
(push representation *operand-representations*)))
(defun emit-variable-operand (variable)
@@ -721,7 +755,7 @@
(push (variable-representation variable) *operand-representations*)
(cond
((and *saved-operands*
- (variable-register variable))
+ (variable-register variable))
;; we're in 'safe mode' and the variable is in a register,
;; instead of binding a new register, just load the existing one
(push (variable-register variable) *saved-operands*))
@@ -729,26 +763,24 @@
(emit-push-variable variable)
(when *saved-operands* ;; safe-mode
(let ((register (allocate-register)))
- (push register *saved-operands*)
- (assert (null (variable-representation variable)))
- (emit 'astore register))))))
+ (push register *saved-operands*)
+ (emit-move-from-stack register (variable-representation variable)))))))
(defun emit-thread-operand ()
(push nil *operand-representations*)
(emit-push-current-thread)
(when *saved-operands*
(let ((register (allocate-register)))
- (push register *saved-operands*)
- (emit 'astore register))))
-
+ (push register *saved-operands*)
+ (emit 'astore register))))
(defun emit-load-externalized-object-operand (object)
(push nil *operand-representations*)
(emit-load-externalized-object object)
(when *saved-operands* ;; safe-mode
(let ((register (allocate-register)))
- (push register *saved-operands*)
- (emit 'astore register))))
+ (push register *saved-operands*)
+ (emit 'astore register))))
(defknown emit-unbox-fixnum () t)
(defun emit-unbox-fixnum ()
@@ -1928,7 +1960,7 @@
(unless (single-valued-p arg)
(setf must-clear-values t)))))
(t
- (let (;(*register* *register*) ;; ### FIXME: this doesn't work, but why not?
+ (let* ((*register* *register*) ;; ### FIXME: this doesn't work, but why not?
(array-register (allocate-register))
saved-stack)
(when unsafe-args
More information about the armedbear-cvs
mailing list