Re: [Sbcl-devel] help: adding a VOP

On Mon, Jan 29, 2001 at 06:59:37AM +0000, Daniel Barlow wrote:
>
> vector-t-p seems to be new since 0.6.5, and relies on the existence
> of complex-vector-p
Yes, it is new. From my notes in NEWS:
* There is now a primitive type predicate VECTOR-T-P
to test for the (VECTOR T) type, so that e.g.
(DEFUN FOO (V) (DECLARE (TYPE (VECTOR T) V)) (AREF V 3))
can now be compiled with some semblance of efficiency. (The old code
turned the type declaration into a full call to %TYPEP at runtime!)
(A minor crusade of mine has been to make non-simple vectors work
without insane amounts of overhead. IMHO the original CMU CL code had
unusable performance on adjustable vectors; and for the applications
I've been working on, if Common Lisp's sequence functions aren't
usable on vectors with FILL-POINTERs, I might as well just give up and
switch to C++/STL right now.)
> On the x86 there's a line in type-vops.lisp:
>
> (def-type-vops complex-vector-p check-complex-vector nil
> object-not-complex-vector-error complex-vector-type)
>
> which obviously doesn't exist in the Alpha backend that I stole from
> cmucl. But I can't see any other stuff in there that's relevant - how
> does it actually _know_ how to check if something is a complex vector?
> Or if I just add the relevant line to type-vops on the Alpha, will it
> all start magically working?
If there's a DEF-TYPE-VOPS macro on the Alpha, check to make sure that
it means the same thing as on the X86. If so, then yes, I think adding
the definition will make everything magically start working. Unless
I've gotten all confused somehow -- happens sometimes! -- the type vop
there just defines something which checks for the COMPLEX-VECTOR-TYPE
code.
If instead it turns out to be very complicated on the Alpha, it should
be OK to temporarily suppress stuff related to the new vop while you
get the rest of your port working. Without the VOP, the problem is
that you can end up with full calls to TYPEP, but although that's
breathtakingly inefficient, it does work.
(Actually, looking at this now, I think I overlooked something:
perhaps I should have defined DEFERR OBJECT-NOT-COMPLEX-VECTOR-ERROR.
I didn't. I'll have to look to see whether it's possible for this
actually to be called. Even if for some reason it doesn't need a
definition, it deserves an explanatory comment.)
> In other news, I've been fiddling with the lowlevel trap stuff
> (interrupt.c and the rest) on the alpha lately, and found out that it
> seems to be basically an accident that the CMUCL alpha/linux port
> works at all ...
>
[..much stuff that I can't understand in any detail at this point, but
sounds in broad outline like the kind of thing that one tends to discover
inside CMU CL/SBCL when one goes looking..]
>
> My alpha architecture manual is in the post, Amazon tell me ...
I'm rather impressed that you can do all this stuff without the manual!
> The informational content in this message is also making its way into
> comments in the source code.
Very good.
--
William Harold Newman <william.newman@...>
software consultant
PGP key fingerprint 85 CE 1C BA 79 8D 51 8C B9 25 FB EE E0 C3 E5 7C

Thread view

vector-t-p seems to be new since 0.6.5, and relies on the existence
of complex-vector-p
On the x86 there's a line in type-vops.lisp:
(def-type-vops complex-vector-p check-complex-vector nil
object-not-complex-vector-error complex-vector-type)
which obviously doesn't exist in the Alpha backend that I stole from
cmucl. But I can't see any other stuff in there that's relevant - how
does it actually _know_ how to check if something is a complex vector?
Or if I just add the relevant line to type-vops on the Alpha, will it
all start magically working?
In other news, I've been fiddling with the lowlevel trap stuff
(interrupt.c and the rest) on the alpha lately, and found out that it
seems to be basically an accident that the CMUCL alpha/linux port
works at all ...
When a function is referenced and hasn't yet been defined it's set up
as a function object with an entry point of 0x10140
("undefined_tramp"). This should be a small piece of assembler that
traps into the C runtime, which notices it's an error, does
machine-dependent stuff to find out what kind, then calls the
(Lisp-based) INTERNAL-ERROR to let the user decide what to do next.
On the Alpha, this code looks like
.text
.globl undefined_tramp
.ent undefined_tramp_offset
undefined_tramp = /* ### undefined_tramp_offset-call_into_lisp_LRA*/ 0x140+call_into_lisp_LRA_page
undefined_tramp_offset:
call_pal PAL_gentrap
.long trap_Error
.byte 4 /* what are these numbers? */
.byte 23
.byte 254
.byte (0xe0 + sc_DescriptorReg)
.byte 2
.align 2
.end undefined_tramp
What's supposed to happen: the pal call punts us into the (C-based)
sigtrap_handler, with sc_pc pointing at the following word. The C
code is expected to pick up trap_Error and say "ah, it wants us to
call the Lisp INTERNAL-ERROR function", then picks off the following
argument count (4) and arguments, then calls INTERNAL-ERROR
What actually happens: "call_pal PAL_gentrap" does nothing. Nothing
that I can see, anyway. trap_Error has the numeric value 10, which
causes SIGILL, so we end up in the same place as we were (SIGILL and
SIGTRAP have the same handler) but with sc_pc not where we expected it
to be.
The CMUCL binary has exactly the same problem, I find by running it
under gdb. I tested the nopitude of PAL_gentrap by (a) writing a
standalone C program that calls it, and (b) by nopping it out inside
lisp and observing no difference in behaviour
(let ((s (int-sap #x10140)))
(setf (sap-ref-32 s 0) #x47ff041f)) ; opcode for 'nop' instruction
(SBCL on the Alpha is now using 'bpt' instead of the PAL call, because
(a) I've been advised against the PAL call by Someone Who Knows, and
(b) bpt actually stops, which is a help. Also it will do the
pseudo-atomic-interrupted test in a way that doesn't involve an
expensive in-kernel operation to fix up unaligned references that
we're not even interested in knowing the answer to)
My alpha architecture manual is in the post, Amazon tell me ...
The informational content in this message is also making its way into
comments in the source code.
-dan
--
http://ww.telent.net/cliki/ - Link farm for free CL-on-Unix resources

On Mon, Jan 29, 2001 at 06:59:37AM +0000, Daniel Barlow wrote:
>
> vector-t-p seems to be new since 0.6.5, and relies on the existence
> of complex-vector-p
Yes, it is new. From my notes in NEWS:
* There is now a primitive type predicate VECTOR-T-P
to test for the (VECTOR T) type, so that e.g.
(DEFUN FOO (V) (DECLARE (TYPE (VECTOR T) V)) (AREF V 3))
can now be compiled with some semblance of efficiency. (The old code
turned the type declaration into a full call to %TYPEP at runtime!)
(A minor crusade of mine has been to make non-simple vectors work
without insane amounts of overhead. IMHO the original CMU CL code had
unusable performance on adjustable vectors; and for the applications
I've been working on, if Common Lisp's sequence functions aren't
usable on vectors with FILL-POINTERs, I might as well just give up and
switch to C++/STL right now.)
> On the x86 there's a line in type-vops.lisp:
>
> (def-type-vops complex-vector-p check-complex-vector nil
> object-not-complex-vector-error complex-vector-type)
>
> which obviously doesn't exist in the Alpha backend that I stole from
> cmucl. But I can't see any other stuff in there that's relevant - how
> does it actually _know_ how to check if something is a complex vector?
> Or if I just add the relevant line to type-vops on the Alpha, will it
> all start magically working?
If there's a DEF-TYPE-VOPS macro on the Alpha, check to make sure that
it means the same thing as on the X86. If so, then yes, I think adding
the definition will make everything magically start working. Unless
I've gotten all confused somehow -- happens sometimes! -- the type vop
there just defines something which checks for the COMPLEX-VECTOR-TYPE
code.
If instead it turns out to be very complicated on the Alpha, it should
be OK to temporarily suppress stuff related to the new vop while you
get the rest of your port working. Without the VOP, the problem is
that you can end up with full calls to TYPEP, but although that's
breathtakingly inefficient, it does work.
(Actually, looking at this now, I think I overlooked something:
perhaps I should have defined DEFERR OBJECT-NOT-COMPLEX-VECTOR-ERROR.
I didn't. I'll have to look to see whether it's possible for this
actually to be called. Even if for some reason it doesn't need a
definition, it deserves an explanatory comment.)
> In other news, I've been fiddling with the lowlevel trap stuff
> (interrupt.c and the rest) on the alpha lately, and found out that it
> seems to be basically an accident that the CMUCL alpha/linux port
> works at all ...
>
[..much stuff that I can't understand in any detail at this point, but
sounds in broad outline like the kind of thing that one tends to discover
inside CMU CL/SBCL when one goes looking..]
>
> My alpha architecture manual is in the post, Amazon tell me ...
I'm rather impressed that you can do all this stuff without the manual!
> The informational content in this message is also making its way into
> comments in the source code.
Very good.
--
William Harold Newman <william.newman@...>
software consultant
PGP key fingerprint 85 CE 1C BA 79 8D 51 8C B9 25 FB EE E0 C3 E5 7C

Community

Help

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

CountryState

JavaScript is required for this form.

I agree to receive quotes, newsletters and other information from sourceforge.net and its partners regarding IT services and products. I understand that I can withdraw my consent at any time. Please refer to our Privacy Policy or Contact Us for more details