source: release/1.4/source/level-0/X86/X8632/x8632-utils.lisp

Last change on this file was 13075, checked in by R. Matthew Emerson, 15 years ago

Merge trunk changes r13066 through r13067.
(copyright notices)

File size: 15.6 KB
RevLine 
[13075]1;;; Copyright 2009 Clozure Associates
2;;; This file is part of Clozure CL.
3;;;
4;;; Clozure CL is licensed under the terms of the Lisp Lesser GNU
5;;; Public License , known as the LLGPL and distributed with Clozure
6;;; CL as the file "LICENSE". The LLGPL consists of a preamble and
7;;; the LGPL, which is distributed with Clozure CL as the file "LGPL".
8;;; Where these conflict, the preamble takes precedence.
9;;;
10;;; Clozure CL is referenced in the preamble as the "LIBRARY."
11;;;
12;;; The LLGPL is also available online at
13;;; http://opensource.franz.com/preamble.html
14
[8077]15(in-package "CCL")
16
17(defx8632lapfunction %address-of ((arg arg_z))
18 ;; %address-of a fixnum is a fixnum, just for spite.
19 ;; %address-of anything else is the address of that thing as an integer.
20 (testb ($ x8632::fixnummask) (%b arg))
21 (je @done)
22 (movl (% arg) (% imm0))
23 (jmp-subprim .SPmakeu32)
24 @done
25 (single-value-return))
26
27;;; "areas" are fixnum-tagged and, for the most part, so are their
28;;; contents.
29
30;;; The nilreg-relative global all-areas is a doubly-linked-list header
31;;; that describes nothing. Its successor describes the current/active
32;;; dynamic heap. Return a fixnum which "points to" that area, after
33;;; ensuring that the "active" pointers associated with the current thread's
34;;; stacks are correct.
35
36(defx8632lapfunction %normalize-areas ()
37 (let ((address temp0)
38 (temp temp1))
39
40 ; update active pointer for tsp area.
[10575]41 (movl (:rcontext x8632::tcr.ts-area) (% address))
42 (movl (:rcontext x8632::tcr.save-tsp) (% temp))
[8077]43 (movl (% temp) (@ x8632::area.active (% address)))
44
45 ;; Update active pointer for vsp area.
[10575]46 (movl (:rcontext x8632::tcr.vs-area) (% address))
[8077]47 (movl (% esp) (@ x8632::area.active (% address)))
48
49 (ref-global all-areas arg_z)
50 (movl (@ x8632::area.succ (% arg_z)) (% arg_z))
51
52 (single-value-return)))
53
54(defx8632lapfunction %active-dynamic-area ()
55 (ref-global all-areas arg_z)
56 (movl (@ x8632::area.succ (% arg_z)) (% arg_z))
57 (single-value-return))
58
59(defx8632lapfunction %object-in-stack-area-p ((object arg_y) (area arg_z))
60 (rcmp (% object) (@ x8632::area.active (% area)))
61 (movl ($ nil) (% temp0))
62 (movl ($ t) (% imm0))
63 (jb @done)
64 (rcmp (% object) (@ x8632::area.high (% area)))
65 (cmovbl (% imm0) (% temp0))
66 @done
67 (movl (% temp0) (% arg_z))
68 (single-value-return))
69
70(defx8632lapfunction %object-in-heap-area-p ((object arg_y) (area arg_z))
71 (rcmp (% object) (@ x8632::area.low (% area)))
72 (movl ($ nil) (% temp0))
73 (movl ($ t) (% imm0))
74 (jb @done)
75 (rcmp (% object) (@ x8632::area.active (% area)))
76 (cmovbl (% imm0) (% temp0))
77 @done
78 (movl (% temp0) (% arg_z))
79 (single-value-return))
80
[8746]81;;; In these heap-walking functions, all other threads should be
82;;; suspended; the only consing that should happen is any consing
83;;; that the function (the "f" argument) does when we call it.
84;;;
85;;; We can therefore basically walk dnode-aligned addresses (but we
86;;; have to be careful, especially in the %WALK-DYNAMIC-AREA case,
87;;; to hold onto only tagged pointers when we call the funtion, since
88;;; consing by the called function could cause a gc).
[8077]89
[8746]90(defx8632lapfunction walk-static-area ((a arg_y) (f arg_z))
91 (let ((obj temp0)
92 (fun -4)
93 (limit -8))
94 (save-simple-frame)
95 (push (% f))
96 (pushl (@ x8632::area.active (% a)))
97 (movl (@ x8632::area.low (% a)) (% obj))
98 (jmp @test)
99 @loop
100 (movb (@ (% obj)) (% imm0.b))
101 (andb ($ x8632::fulltagmask) (% imm0.b))
102 (cmpb ($ x8632::fulltag-immheader) (% imm0.b))
103 (je @misc)
104 (cmpb ($ x8632::fulltag-nodeheader) (% imm0.b))
105 (je @misc)
106 ;; not a header, so must be a cons
107 (add ($ x8632::fulltag-cons) (% obj))
108 (mov (% obj) (% arg_z))
109 (set-nargs 1)
110 (push (% obj))
111 (:talign 5)
112 (call (@ fun (% ebp)))
113 (recover-fn)
114 (pop (% obj))
115 (add ($ (- x8632::cons.size x8632::fulltag-cons)) (% obj))
116 (jmp @test)
117 @misc
[11077]118 (lea (@ x8632::fulltag-misc (% obj)) (% arg_z))
[8746]119 (set-nargs 1)
120 (push (% obj))
121 (:talign 5)
122 (call (@ fun (% ebp)))
123 (recover-fn)
124 (pop (% obj))
[9271]125 (mov (@ (% obj)) (% imm0))
[8746]126 (andb ($ x8632::fulltagmask) (% imm0.b))
127 (cmpb ($ x8632::fulltag-nodeheader) (% imm0.b))
[9271]128 (mov (@ (% obj)) (% imm0))
[8746]129 (je @32)
130 (cmpb ($ x8632::max-32-bit-ivector-subtag) (% imm0.b))
[11363]131 (jbe @32)
[8746]132 (cmpb ($ x8632::max-8-bit-ivector-subtag) (% imm0.b))
[11363]133 (jbe @8)
[8746]134 (cmpb ($ x8632::max-16-bit-ivector-subtag) (% imm0.b))
[11363]135 (jbe @16)
[8746]136 (cmpb ($ x8632::subtag-double-float-vector) (% imm0.b))
137 (je @double-float)
138 ;; if we get here, it's a bit vector
139 (shrl ($ x8632::num-subtag-bits) (% imm0))
140 (add ($ 7) (% imm0))
141 (shrl ($ 3) (% imm0))
142 (jmp @uvector-next)
143 @double-float
144 (shrl ($ x8632::num-subtag-bits) (% imm0))
145 (shll ($ 3) (% imm0))
146 (jmp @uvector-next)
147 @8
148 (shrl ($ x8632::num-subtag-bits) (% imm0))
149 (jmp @uvector-next)
150 @16
151 (shrl ($ x8632::num-subtag-bits) (% imm0))
152 (shll ($ 1) (% imm0))
153 (jmp @uvector-next)
154 @32
155 (shrl ($ x8632::num-subtag-bits) (% imm0))
156 (shll ($ 2) (% imm0))
157 ;; size of obj in bytes (without header or alignment padding)
158 ;; is in imm0
159 @uvector-next
160 (add ($ (+ x8632::node-size (1- x8632::dnode-size))) (% imm0))
161 (andb ($ (lognot (1- x8632::dnode-size))) (% imm0.b))
162 (add (% imm0) (% obj))
163 @test
164 (cmpl (@ limit (% ebp)) (% obj))
165 (jb @loop)
[10959]166 (movl ($ (target-nil-value)) (% arg_z))
[8746]167 (restore-simple-frame)
168 (single-value-return)))
[8077]169
[8746]170;;; This walks the active "dynamic" area. Objects might be moving around
171;;; while we're doing this, so we have to be a lot more careful than we
172;;; are when walking a static area.
173;;; There are a couple of approaches to termination:
174;;; a) Allocate a "sentinel" cons, and terminate when we run into it.
175;;; b) Check the area limit (which is changing if we're consing) and
176;;; terminate when we hit it.
177;;; (b) loses if the function conses. (a) conses. I can't think of anything
178;;; better than (a).
179;;; This, of course, assumes that any GC we're doing does in-place compaction
180;;; (or at least preserves the relative order of objects in the heap.)
[8077]181
[8746]182(defx8632lapfunction %walk-dynamic-area ((a arg_y) (f arg_z))
183 (let ((obj temp0)
184 (fun -4)
185 (sentinel -8))
186 (save-simple-frame)
187 (push (% f))
188 (subl ($ (- x8632::cons.size x8632::fulltag-cons))
[10575]189 (:rcontext x8632::tcr.save-allocptr))
190 (movl (:rcontext x8632::tcr.save-allocptr) (% allocptr)) ;aka temp0
191 (cmpl (:rcontext x8632::tcr.save-allocbase) (% allocptr))
[11556]192 (ja @ok)
[8746]193 (uuo-alloc)
194 @ok
195 (andb ($ (lognot x8632::fulltagmask))
[10575]196 (:rcontext x8632::tcr.save-allocptr))
[8746]197 (push (% allocptr)) ;sentinel
198 (ref-global tenured-area a)
199 (movl (@ x8632::area.low (% a)) (% obj))
200 (jmp @test)
201 @loop
202 (movb (@ (% obj)) (% imm0.b))
203 (andb ($ x8632::fulltagmask) (% imm0.b))
204 (cmpb ($ x8632::fulltag-immheader) (% imm0.b))
205 (je @misc)
206 (cmpb ($ x8632::fulltag-nodeheader) (% imm0.b))
207 (je @misc)
208 ;; not a header, so must be a cons
209 (add ($ x8632::fulltag-cons) (% obj))
210 (mov (% obj) (% arg_z))
211 (set-nargs 1)
212 (push (% obj))
213 (:talign 5)
214 (call (@ fun (% ebp)))
215 (recover-fn)
216 (pop (% obj))
217 (add ($ (- x8632::cons.size x8632::fulltag-cons)) (% obj))
218 (jmp @test)
219 @misc
220 (add ($ x8632::fulltag-misc) (% obj))
221 (mov (% obj) (% arg_z))
222 (set-nargs 1)
223 (push (% obj))
224 (:talign 5)
225 (call (@ fun (% ebp)))
226 (recover-fn)
227 (pop (% obj))
228 (sub ($ x8632::fulltag-misc) (% obj))
[9271]229 (mov (@ (% obj)) (% imm0))
[8746]230 (andb ($ x8632::fulltagmask) (% imm0.b))
[10741]231 (cmpb ($ x8632::fulltag-nodeheader) (% imm0.b))
[9271]232 (mov (@ (% obj)) (% imm0))
[8746]233 (je @32)
234 (cmpb ($ x8632::max-32-bit-ivector-subtag) (% imm0.b))
[11363]235 (jbe @32)
[8746]236 (cmpb ($ x8632::max-8-bit-ivector-subtag) (% imm0.b))
[11363]237 (jbe @8)
[8746]238 (cmpb ($ x8632::max-16-bit-ivector-subtag) (% imm0.b))
[11363]239 (jbe @16)
[8746]240 (cmpb ($ x8632::subtag-double-float-vector) (% imm0.b))
241 (je @double-float)
242 ;; if we get here, it's a bit vector
243 (shrl ($ x8632::num-subtag-bits) (% imm0))
244 (add ($ 7) (% imm0))
245 (shrl ($ 3) (% imm0))
246 (jmp @uvector-next)
247 @double-float
248 (shrl ($ x8632::num-subtag-bits) (% imm0))
249 (shll ($ 3) (% imm0))
250 (jmp @uvector-next)
251 @8
252 (shrl ($ x8632::num-subtag-bits) (% imm0))
253 (jmp @uvector-next)
254 @16
255 (shrl ($ x8632::num-subtag-bits) (% imm0))
256 (shll ($ 1) (% imm0))
257 (jmp @uvector-next)
258 @32
259 (shrl ($ x8632::num-subtag-bits) (% imm0))
260 (shll ($ 2) (% imm0))
261 ;; size of obj in bytes (without header or alignment padding)
262 ;; is in imm0
263 @uvector-next
264 (add ($ (+ x8632::node-size (1- x8632::dnode-size))) (% imm0))
265 (andb ($ (lognot (1- x8632::dnode-size))) (% imm0.b))
266 (add (% imm0) (% obj))
267 @test
268 (cmpl (@ sentinel (% ebp)) (% obj))
269 (jb @loop)
270 @done
[10959]271 (movl ($ (target-nil-value)) (% arg_z))
[8746]272 (restore-simple-frame)
273 (single-value-return)))
274
275;;; xxx duplicated in level-0/x86-utils.lisp
276(defun walk-dynamic-area (area func)
277 (with-other-threads-suspended
278 (%walk-dynamic-area area func)))
279
[9126]280(defx8632lapfunction %class-of-instance ((i arg_z))
281 (svref i instance.class-wrapper arg_z)
282 (svref arg_z %wrapper-class arg_z)
283 (single-value-return))
284
285(defx8632lapfunction class-of ((x arg_z))
286 (check-nargs 1)
287 (extract-fulltag x imm0)
288 (cmpb ($ x8632::fulltag-misc) (% imm0.b))
[9312]289 (movl (% arg_z) (% imm0))
[9126]290 (jne @have-tag)
291 (extract-subtag x imm0)
292 @have-tag
293 (movl (@ '*class-table* (% fn)) (% temp1))
294 (movl (@ x8632::symbol.vcell (% temp1)) (% temp1))
295 (movzbl (% imm0.b) (% imm0))
296 (movl (@ x8632::misc-data-offset (% temp1) (% imm0) 4) (% temp0))
[10959]297 (cmpl ($ (target-nil-value)) (% temp0))
[9126]298 (je @bad)
299 ;; functionp?
300 (extract-typecode temp0 imm0)
301 (cmpb ($ x8632::subtag-function) (% imm0.b))
302 (jne @ret)
303 ;; jump to the function
304 (set-nargs 1)
305 (jmp (% temp0))
306 @bad
307 (load-constant no-class-error fname)
308 (set-nargs 1)
309 (jmp (@ x8632::symbol.fcell (% fname)))
310 @ret
311 (movl (% temp0) (% arg_z)) ;return frob from table
312 (single-value-return))
313
314(defx8632lapfunction gc ()
[9369]315 (check-nargs 0)
316 (movl ($ arch::gc-trap-function-gc) (% imm0))
317 (uuo-gc-trap)
318 (movl ($ nil) (% arg_z))
319 (single-value-return))
[9126]320
321(defx8632lapfunction full-gccount ()
[9369]322 (ref-global tenured-area arg_z)
323 (test (% arg_z) (% arg_z))
[10959]324 (cmovel (@ (+ (target-nil-value) (x8632::%kernel-global 'gc-count))) (% arg_z))
[9369]325 (cmovnel (@ x8632::area.gc-count (% arg_z)) (% arg_z))
326 (single-value-return))
[9126]327
328(defx8632lapfunction egc ((arg arg_z))
[9369]329 "Enable the EGC if arg is non-nil, disables the EGC otherwise. Return
330the previous enabled status. Although this function is thread-safe (in
331the sense that calls to it are serialized), it doesn't make a whole lot
332of sense to be turning the EGC on and off from multiple threads ..."
[9474]333 (check-nargs 1)
334 (clrl imm0)
335 (cmp-reg-to-nil arg)
336 (setne (% imm0.b))
337 (movd (% imm0) (% mm0))
338 (movl ($ arch::gc-trap-function-egc-control) (% imm0))
339 (uuo-gc-trap)
[9369]340 (single-value-return))
[9126]341
342(defx8632lapfunction %configure-egc ((e0size 4)
343 #|(ra 0)|#
344 (e1size arg_y)
345 (e2size arg_z))
[9369]346 (check-nargs 3)
347 (movl (@ e0size (% esp)) (% temp0))
348 (movl ($ arch::gc-trap-function-configure-egc) (% imm0))
349 (uuo-gc-trap)
350 (single-value-return 3))
[9126]351
352(defx8632lapfunction purify ()
[9369]353 (check-nargs 0)
354 (movl ($ arch::gc-trap-function-purify) (% imm0))
355 (uuo-gc-trap)
356 (movl ($ nil) (% arg_z))
357 (single-value-return))
[9126]358
359(defx8632lapfunction impurify ()
[9369]360 (check-nargs 0)
361 (movl ($ arch::gc-trap-function-impurify) (% imm0))
362 (uuo-gc-trap)
363 (movl ($ nil) (% arg_z))
364 (single-value-return))
[9126]365
[9474]366(defx8632lapfunction lisp-heap-gc-threshold ()
367 "Return the value of the kernel variable that specifies the amount
368of free space to leave in the heap after full GC."
369 (check-nargs 0)
370 (movl ($ arch::gc-trap-function-get-lisp-heap-threshold) (% imm0))
371 (uuo-gc-trap)
372 (jmp-subprim .SPmakeu32))
373
374(defx8632lapfunction set-lisp-heap-gc-threshold ((new arg_z))
375 "Set the value of the kernel variable that specifies the amount of free
376space to leave in the heap after full GC to new-value, which should be a
377non-negative fixnum. Returns the value of that kernel variable (which may
378be somewhat larger than what was specified)."
379 (check-nargs 1)
380 (save-simple-frame)
381 (call-subprim .SPgetu32)
382 (movd (% imm0) (% mm0))
383 (movl ($ arch::gc-trap-function-set-lisp-heap-threshold) (% imm0))
384 (uuo-gc-trap)
385 (restore-simple-frame)
386 (jmp-subprim .SPmakeu32))
387
[8077]388(defx8632lapfunction use-lisp-heap-gc-threshold ()
389 "Try to grow or shrink lisp's heap space, so that the free space is (approximately) equal to the current heap threshold. Return NIL"
390 (check-nargs 0)
391 (movl ($ arch::gc-trap-function-use-lisp-heap-threshold) (% imm0))
392 (uuo-gc-trap)
[10959]393 (movl ($ (target-nil-value)) (%l arg_z))
[8077]394 (single-value-return))
395
[10450]396(defx8632lapfunction freeze ()
397 "Do a full GC, then consider all heap-allocated objects which survive to be non-relocatable."
398 (movl ($ arch::gc-trap-function-freeze) (% imm0))
399 (uuo-gc-trap)
400 (jmp-subprim .SPmakeu32))
401
[11523]402(defx8632lapfunction flash-freeze ()
403 "Like FREEZE, without the GC."
404 (movl ($ arch::gc-trap-function-flash-freeze) (% imm0))
405 (uuo-gc-trap)
406 (jmp-subprim .SPmakeu32))
407
[12797]408(defx8632lapfunction %watch ((uvector arg_z))
409 (check-nargs 1)
410 (movl ($ arch::watch-trap-function-watch) (%l imm0))
411 (uuo-watch-trap)
412 (single-value-return))
413
[12837]414(defx8632lapfunction %unwatch ((watched arg_y) (new arg_z))
415 (check-nargs 2)
[12797]416 (movl ($ arch::watch-trap-function-unwatch) (%l imm0))
417 (uuo-watch-trap)
418 (single-value-return))
419
[11521]420(defx8632lapfunction %allocate-list ((initial-element arg_y) (nconses arg_z))
421 (check-nargs 2)
422 (save-simple-frame)
423 (ud2a)
424 (:byte 10)
425 (push (% arg_z))
426 (push (% allocptr))
427 (set-nargs 2)
428 (jmp-subprim .SPnvalret))
429
[8077]430;;; offset is a fixnum, one of the x8632::kernel-import-xxx constants.
431;;; Returns that kernel import, a fixnum.
432(defx8632lapfunction %kernel-import ((offset arg_z))
[8633]433 (unbox-fixnum arg_z imm0)
[10959]434 (addl (@ (+ (target-nil-value) (x8632::%kernel-global 'kernel-imports))) (% imm0))
[8633]435 (movl (@ (% imm0)) (% imm0))
436 (box-fixnum imm0 arg_z)
[8077]437 (single-value-return))
438
439(defx8632lapfunction %get-unboxed-ptr ((macptr arg_z))
440 (macptr-ptr arg_z imm0)
441 (movl (@ (% imm0)) (% arg_z))
442 (single-value-return))
443
444(defx8632lapfunction %revive-macptr ((p arg_z))
445 (movb ($ x8632::subtag-macptr) (@ x8632::misc-subtag-offset (% p)))
446 (single-value-return))
447
448(defx86lapfunction %macptr-type ((p arg_z))
449 (check-nargs 1)
450 (trap-unless-typecode= p x8632::subtag-macptr)
451 (svref p x8632::macptr.type-cell imm0)
452 (box-fixnum imm0 arg_z)
453 (single-value-return))
454
455(defx86lapfunction %macptr-domain ((p arg_z))
456 (check-nargs 1)
457 (trap-unless-typecode= p x8632::subtag-macptr)
458 (svref p x8632::macptr.domain-cell imm0)
459 (box-fixnum imm0 arg_z)
460 (single-value-return))
461
462(defx8632lapfunction %set-macptr-type ((p arg_y) (new arg_z))
463 (check-nargs 2)
464 (trap-unless-typecode= p x8632::subtag-macptr)
465 (unbox-fixnum new imm0)
466 (svset p x8632::macptr.type-cell imm0)
467 (single-value-return))
468
469(defx8632lapfunction %set-macptr-domain ((p arg_y) (new arg_z))
470 (check-nargs 2)
471 (trap-unless-typecode= p x8632::subtag-macptr)
472 (unbox-fixnum new imm0)
473 (svset p x8632::macptr.domain-cell imm0)
474 (single-value-return))
475
476(defx8632lapfunction true ()
[9821]477 (pop (% temp0))
[8998]478 (subl ($ '2) (% nargs))
479 (leal (@ '2 (% esp) (% nargs)) (% imm0))
[8077]480 (cmoval (% imm0) (% esp))
[10959]481 (movl ($ (target-t-value)) (% arg_z))
[9821]482 (push (% temp0))
[8077]483 (single-value-return))
484
485(defx8632lapfunction false ()
[9821]486 (pop (% temp0))
[8998]487 (subl ($ '2) (% nargs))
488 (leal (@ '2 (% esp) (% nargs)) (% imm0))
[8077]489 (cmoval (% imm0) (% esp))
[10959]490 (movl ($ (target-nil-value)) (% arg_z))
[9821]491 (push (% temp0))
[8077]492 (single-value-return))
[9126]493
494(defx8632lapfunction int3 ()
495 (int ($ 3))
[10959]496 (single-value-return))
Note: See TracBrowser for help on using the repository browser.