(:ignore name)
(:results)
(:generator 1
- (if (sc-is value immediate)
- (let ((val (tn-value value)))
- (etypecase val
- (integer
- (inst mov
- (make-ea :dword :base object
- :disp (- (* offset n-word-bytes) lowtag))
- (fixnumize val)))
- (symbol
- (inst mov
- (make-ea :dword :base object
- :disp (- (* offset n-word-bytes) lowtag))
- (+ nil-value (static-symbol-offset val))))
- (character
- (inst mov
- (make-ea :dword :base object
- :disp (- (* offset n-word-bytes) lowtag))
- (logior (ash (char-code val) n-widetag-bits)
- character-widetag)))))
- ;; Else, value not immediate.
- (storew value object offset lowtag))))
-\f
-
+ (storew (encode-value-if-immediate value) object offset lowtag)))
+(define-vop (compare-and-swap-slot)
+ (:args (object :scs (descriptor-reg) :to :eval)
+ (old :scs (descriptor-reg any-reg) :target eax)
+ (new :scs (descriptor-reg any-reg)))
+ (:temporary (:sc descriptor-reg :offset eax-offset
+ :from (:argument 1) :to :result :target result)
+ eax)
+ (:info name offset lowtag)
+ (:ignore name)
+ (:results (result :scs (descriptor-reg any-reg)))
+ (:generator 5
+ (move eax old)
+ #!+sb-thread
+ (inst lock)
+ (inst cmpxchg (make-ea :dword :base object
+ :disp (- (* offset n-word-bytes) lowtag))
+ new)
+ (move result eax)))
+\f
;;;; symbol hacking VOPs
+(define-vop (%compare-and-swap-symbol-value)
+ (:translate %compare-and-swap-symbol-value)
+ (:args (symbol :scs (descriptor-reg) :to (:result 1))
+ (old :scs (descriptor-reg any-reg) :target eax)
+ (new :scs (descriptor-reg any-reg)))
+ (:temporary (:sc descriptor-reg :offset eax-offset) eax)
+ #!+sb-thread
+ (:temporary (:sc descriptor-reg) tls)
+ (:results (result :scs (descriptor-reg any-reg)))
+ (:policy :fast-safe)
+ (:vop-var vop)
+ (:generator 15
+ ;; This code has to pathological cases: NO-TLS-VALUE-MARKER
+ ;; or UNBOUND-MARKER as NEW: in either case we would end up
+ ;; doing possible damage with CMPXCHG -- so don't do that!
+ (let ((unbound (generate-error-code vop unbound-symbol-error symbol))
+ (check (gen-label)))
+ (move eax old)
+ #!+sb-thread
+ (progn
+ (loadw tls symbol symbol-tls-index-slot other-pointer-lowtag)
+ ;; Thread-local area, no LOCK needed.
+ (inst fs-segment-prefix)
+ (inst cmpxchg (make-ea :dword :base tls) new)
+ (inst cmp eax no-tls-value-marker-widetag)
+ (inst jmp :ne check)
+ (move eax old)
+ (inst lock))
+ (inst cmpxchg (make-ea :dword :base symbol
+ :disp (- (* symbol-value-slot n-word-bytes)
+ other-pointer-lowtag))
+ new)
+ (emit-label check)
+ (move result eax)
+ (inst cmp result unbound-marker-widetag)
+ (inst jmp :e unbound))))
+
;;; these next two cf the sparc version, by jrd.
;;; FIXME: Deref this ^ reference.
(let ((global-val (gen-label))
(done (gen-label)))
(loadw tls symbol symbol-tls-index-slot other-pointer-lowtag)
- (inst or tls tls)
- (inst jmp :z global-val)
(inst fs-segment-prefix)
(inst cmp (make-ea :dword :base tls) no-tls-value-marker-widetag)
(inst jmp :z global-val)
(:args (val :scs (any-reg descriptor-reg))
(symbol :scs (descriptor-reg)))
(:temporary (:sc descriptor-reg :offset eax-offset) eax)
- (:temporary (:sc unsigned-reg) tls-index temp bsp)
+ (:temporary (:sc unsigned-reg) tls-index bsp)
(:generator 10
(let ((tls-index-valid (gen-label))
(get-tls-index-lock (gen-label))
(inst or tls-index tls-index)
(inst jmp :ne tls-index-valid)
+ ;; FIXME:
+ ;; * We should ensure the existence of TLS index for LET-bound specials
+ ;; at compile/load time, and use write a FAST-BIND for use with those.
+ ;; * PROGV will need to do this, but even there this should not be inline.
+ ;; This is probably best moved to C, since dynbind.c also needs to do this.
(pseudo-atomic
(emit-label get-tls-index-lock)
- (inst mov temp 1)
+ (inst mov tls-index 1)
(inst xor eax eax)
(inst lock)
- (inst cmpxchg (make-ea-for-symbol-value *tls-index-lock*) temp)
+ (inst cmpxchg (make-ea-for-symbol-value *tls-index-lock*) tls-index)
(inst jmp :ne get-tls-index-lock)
;; now with the lock held, see if the symbol's tls index has
;; been set in the meantime
(inst jmp :ne release-tls-index-lock)
;; allocate a new tls-index
(load-symbol-value tls-index *free-tls-index*)
- (inst add tls-index 4) ;XXX surely we can do this more
- (store-symbol-value tls-index *free-tls-index*) ;succintly
- (inst sub tls-index 4)
+ (inst add (make-ea-for-symbol-value *free-tls-index*) 4) ; fixnum + 1
(storew tls-index symbol symbol-tls-index-slot other-pointer-lowtag)
(emit-label release-tls-index-lock)
(store-symbol-value 0 *tls-index-lock*))
(emit-label tls-index-valid)
(inst fs-segment-prefix)
- (inst mov temp (make-ea :dword :base tls-index))
- (storew temp bsp (- binding-value-slot binding-size))
+ (inst mov eax (make-ea :dword :base tls-index))
+ (storew eax bsp (- binding-value-slot binding-size))
(storew symbol bsp (- binding-symbol-slot binding-size))
(inst fs-segment-prefix)
(inst mov (make-ea :dword :base tls-index) val))))
(loadw symbol bsp (- binding-symbol-slot binding-size))
(inst or symbol symbol)
(inst jmp :z skip)
+ ;; Bind stack debug sentinels have the unbound marker in the symbol slot
+ (inst cmp symbol unbound-marker-widetag)
+ (inst jmp :eq skip)
(loadw value bsp (- binding-value-slot binding-size))
#!-sb-thread (storew value symbol symbol-value-slot other-pointer-lowtag)
(store-binding-stack-pointer bsp)
DONE))
+
+(define-vop (bind-sentinel)
+ (:temporary (:sc unsigned-reg) bsp)
+ (:generator 1
+ (load-binding-stack-pointer bsp)
+ (inst add bsp (* binding-size n-word-bytes))
+ (storew unbound-marker-widetag bsp (- binding-symbol-slot binding-size))
+ (storew ebp-tn bsp (- binding-value-slot binding-size))
+ (store-binding-stack-pointer bsp)))
+
+(define-vop (unbind-sentinel)
+ (:temporary (:sc unsigned-reg) bsp)
+ (:generator 1
+ (load-binding-stack-pointer bsp)
+ (storew 0 bsp (- binding-value-slot binding-size))
+ (storew 0 bsp (- binding-symbol-slot binding-size))
+ (inst sub bsp (* binding-size n-word-bytes))
+ (store-binding-stack-pointer bsp)))
\f
\f
(loadw res struct 0 instance-pointer-lowtag)
(inst shr res n-widetag-bits)))
-(define-full-reffer instance-index-ref * instance-slots-offset
- instance-pointer-lowtag (any-reg descriptor-reg) * %instance-ref)
-
-(define-full-setter instance-index-set * instance-slots-offset
- instance-pointer-lowtag (any-reg descriptor-reg) * %instance-set)
-
-
-(defknown %instance-set-conditional (instance index t t) t
- (unsafe))
-
-(define-vop (instance-set-conditional)
- (:translate %instance-set-conditional)
- (:args (object :scs (descriptor-reg) :to :eval)
- (slot :scs (any-reg) :to :result)
- (old-value :scs (descriptor-reg any-reg) :target eax)
- (new-value :scs (descriptor-reg any-reg)))
- (:arg-types instance positive-fixnum * *)
- (:temporary (:sc descriptor-reg :offset eax-offset
- :from (:argument 2) :to :result :target result) eax)
- (:results (result :scs (descriptor-reg any-reg)))
- ;(:guard (backend-featurep :i486))
- (:policy :fast-safe)
- (:generator 5
- (move eax old-value)
- (inst lock)
- (inst cmpxchg (make-ea :dword :base object :index slot :scale 1
- :disp (- (* instance-slots-offset n-word-bytes)
- instance-pointer-lowtag))
- new-value)
- (move result eax)))
+(define-full-reffer instance-index-ref *
+ instance-slots-offset instance-pointer-lowtag
+ (any-reg descriptor-reg) *
+ %instance-ref)
+(define-full-setter instance-index-set *
+ instance-slots-offset instance-pointer-lowtag
+ (any-reg descriptor-reg) *
+ %instance-set)
+(define-full-compare-and-swap %compare-and-swap-instance-ref instance
+ instance-slots-offset instance-pointer-lowtag
+ (any-reg descriptor-reg) *
+ %compare-and-swap-instance-ref)
\f
;;;; code object frobbing
(define-full-setter code-header-set * 0 other-pointer-lowtag
(any-reg descriptor-reg) * code-header-set)
-
-
\f
;;;; raw instance slot accessors