handle non-standard slot allocations when updating classes
[sbcl.git] / src / compiler / sparc / call.lisp
index 428f6dd..a4784b1 100644 (file)
       (when nfp
         (inst add val nfp (bytes-needed-for-non-descriptor-stack-frame))))))
 
+;;; Accessing a slot from an earlier stack frame is definite hackery.
+(define-vop (ancestor-frame-ref)
+  (:args (frame-pointer :scs (descriptor-reg))
+         (variable-home-tn :load-if nil))
+  (:results (value :scs (descriptor-reg any-reg)))
+  (:policy :fast-safe)
+  (:generator 4
+    (aver (sc-is variable-home-tn control-stack))
+    (loadw value frame-pointer (tn-offset variable-home-tn))))
+(define-vop (ancestor-frame-set)
+  (:args (frame-pointer :scs (descriptor-reg))
+         (value :scs (descriptor-reg any-reg)))
+  (:results (variable-home-tn :load-if nil))
+  (:policy :fast-safe)
+  (:generator 4
+    (aver (sc-is variable-home-tn control-stack))
+    (storew value frame-pointer (tn-offset variable-home-tn))))
 
 (define-vop (xep-allocate-frame)
   (:info start-lab copy-more-arg-follows)
   (:generator 1
     ;; Make sure the function is aligned, and drop a label pointing to this
     ;; function header.
-    (align n-lowtag-bits)
+    (emit-alignment n-lowtag-bits)
     (trace-table-entry trace-table-fun-prologue)
     (emit-label start-lab)
     ;; Allocate function header.
@@ -380,6 +397,15 @@ default-value-8
               nvals)
   (:temporary (:scs (non-descriptor-reg)) temp))
 
+\f
+;;; This hook in the codegen pass lets us insert code before fall-thru entry
+;;; points, local-call entry points, and tail-call entry points.  The default
+;;; does nothing.
+(defun emit-block-header (start-label trampoline-label fall-thru-p alignp)
+  (declare (ignore fall-thru-p alignp))
+  (when trampoline-label
+    (emit-label trampoline-label))
+  (emit-label start-label))
 
 \f
 ;;;; Local call with unknown values convention return:
@@ -624,10 +650,7 @@ default-value-8
 
      (:ignore
       ,@(unless (or variable (eq return :tail)) '(arg-locs))
-      ,@(unless variable '(args))
-      ;; Step instrumentation for full calls not implemented yet.
-      ;; See the PPC backend for an example.
-      step-instrumenting)
+      ,@(unless variable '(args)))
 
      (:temporary (:sc descriptor-reg
                   :offset ocfp-offset
@@ -667,6 +690,8 @@ default-value-8
      ,@(when (eq return :fixed)
          '((:temporary (:scs (descriptor-reg) :from :eval) move-temp)))
 
+     (:temporary (:scs (descriptor-reg) :to :eval) stepping)
+
      ,@(unless (eq return :tail)
          '((:temporary (:scs (non-descriptor-reg)) temp)
            (:temporary (:sc control-stack :offset nfp-save-offset) nfp-save)))
@@ -680,6 +705,7 @@ default-value-8
        (let* ((cur-nfp (current-nfp-tn vop))
               ,@(unless (eq return :tail)
                   '((lra-label (gen-label))))
+              (step-done-label (gen-label))
               (filler
                (remove nil
                        (list :load-nargs
@@ -741,7 +767,26 @@ default-value-8
                                     '(if (> nargs register-arg-count)
                                          (move cfp-tn new-fp)
                                          (move cfp-tn csp-tn))))))
-                      ((nil))))))
+                      ((nil)))))
+                (insert-step-instrumenting (callable-tn)
+                  ;; Conditionally insert a conditional trap:
+                  (when step-instrumenting
+                    ;; Get the symbol-value of SB!IMPL::*STEPPING*
+                    (load-symbol-value stepping sb!impl::*stepping*)
+                    (inst cmp stepping null-tn)
+                    ;; If it's not null, trap.
+                    (inst b :eq step-done-label)
+                    (inst nop)
+                    ;; FIXME: this doesn't look right.
+                    (note-this-location vop :step-before-vop)
+                    ;; Construct a trap code with the low bits from
+                    ;; SINGLE-STEP-AROUND-TRAP and the high bits from
+                    ;; the register number of CALLABLE-TN.
+                    (inst unimp (logior single-step-around-trap
+                                        (ash (reg-tn-encoding callable-tn)
+                                             5)))
+                    (emit-label step-done-label))))
+
 
            ,@(if named
                  `((sc-case name
@@ -753,6 +798,7 @@ default-value-8
                       (loadw name-pass code-tn (tn-offset name)
                              other-pointer-lowtag)
                       (do-next-filler)))
+                   (insert-step-instrumenting name-pass)
                    (loadw function name-pass fdefn-raw-addr-slot
                           other-pointer-lowtag)
                    (do-next-filler))
@@ -767,7 +813,8 @@ default-value-8
                       (do-next-filler)))
                    (loadw function lexenv closure-fun-slot
                           fun-pointer-lowtag)
-                   (do-next-filler)))
+                   (do-next-filler)
+                   (insert-step-instrumenting function)))
            (loop
              (if filler
                  (do-next-filler)
@@ -1073,9 +1120,6 @@ default-value-8
   (:translate %more-arg))
 
 ;;; Turn more arg (context, count) into a list.
-(defoptimizer (%listify-rest-args stack-allocate-result) ((&rest args))
-  t)
-
 (define-vop (listify-rest-args)
   (:args (context-arg :target context :scs (descriptor-reg))
          (count-arg :target count :scs (any-reg)))
@@ -1208,8 +1252,14 @@ default-value-8
 ;;; Single-stepping
 
 (define-vop (step-instrument-before-vop)
+  (:temporary (:scs (descriptor-reg)) stepping)
   (:policy :fast-safe)
   (:vop-var vop)
   (:generator 3
-    ;; Stub! See the PPC backend for an example.
-    (note-this-location vop :step-before-vop)))
+    (load-symbol-value stepping sb!impl::*stepping*)
+    (inst cmp stepping null-tn)
+    (inst b :eq DONE)
+    (inst nop)
+    (note-this-location vop :step-before-vop)
+    (inst unimp single-step-before-trap)
+    DONE))