source: trunk/source/doc/src/modifying.xml @ 8981

Last change on this file since 8981 was 8981, checked in by mikel, 11 years ago

additions to ObjC and ffi docs; many mechanical edits; some standardization of XML elements and formatting

File size: 21.9 KB
Line 
1<?xml version="1.0" encoding="utf-8"?>
2<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
3<!ENTITY rest "<varname>&amp;rest</varname>">
4<!ENTITY key "<varname>&amp;key</varname>">
5<!ENTITY optional "<varname>&amp;optional</varname>">
6<!ENTITY body "<varname>&amp;body</varname>">
7<!ENTITY aux "<varname>&amp;aux</varname>">
8<!ENTITY allow-other-keys "<varname>&amp;allow-other-keys</varname>">
9<!ENTITY CCL "Clozure CL">
10]>
11
12  <chapter id="Modifying-CCL">
13    <title>Modifying &CCL;</title>
14
15    <sect1 id="Contributing-Code-Back-to-the-CCL-Project">
16      <title>Contributing Code Back to the &CCL; Project</title>
17      <para>This section is a placeholder, added as of August 2004.  The
18      full text is being written, and will be added as soon as it is
19      available.</para>
20    </sect1>
21
22    <sect1 id="Using-CCL-in--development--and-in--user--mode">
23      <title>Using &CCL; in "development" and in  "user" mode</title>
24
25      <para>As it's distributed, &CCL; starts up with *PACKAGE* set
26      to the CL-USER package and with most predefined functions and
27      methods protected against accidental redefinition.  The package
28      setting is of course a requirement of ANSI CL, while the
29      protection protection is intended to catch certain types of
30      programming errors (accidentally redefining a CL or CCL
31      function) before those errors have a chance to do much
32      damage.</para>
33      <para>These settings may make using &CCL; to develop &CCL; a
34      bit more awkward, since much of that process assumes that the
35      CCL package is current (and a primary purpose of that process is
36      to redefine some "predefined, builtin functions".) The standard,
37      "routine" ways of building &CCL; from sources (see ) -
38      COMPILE-CCL, XCOMPILE-CCL, and XLOAD-LEVEL-0 - bind *PACKAGE* to
39      the "CCL" package and enable the redefinition of predefined
40      functions; the symbols COMPILE-CCL, XCOMPILE-CCL, and
41      XLOAD-LEVEL-0 are additionally now exported from the "CCL"
42      package.</para>
43      <para>Some other (more ad-hoc) ways of doing development on
44      &CCL; - compiling and/or loading individual files,
45      incrementally redefining individual functions - may be awkward
46      unless one reverts to the mode of operation which was
47      traditionally offered in &CCL;. (Some &CCL; source files -
48      especially those that comprise the bootstrapping image sources
49      and the first few files in the "cold load" sequence - are
50      compiled and loaded in the "CCL" package but don't contain
51      (IN-PACKAGE "CCL") forms, since IN-PACKAGE doesn't work until
52      later in the cold load sequence.)</para>
53      <para>The somewhat bizarre behavior of both SET-USER-ENVIRONMENT
54      and SET-DEVELOPMENT-ENVIRONMENT with respect to the special
55      variables they affect is intended to allow those constructs to
56      take effect when the read-eval-print loop next returns to a
57      top-level '? ' prompt; the constructs can meaningfully be used
58      inside LOAD, for instance (recall that LOAD binds *PACKAGE*),
59      though using both constructs within the same LOAD call would
60      likely be pretty confusing.</para>
61      <para>"user" and "development" are otherwise very generic terms;
62      here they're intended to enforce the distinction between "using"
63      &CCL; and "developing" it.</para>
64      <para>The initial environment from which &CCL; images are
65      saved is one where (SET-USER-ENVIRONMENT T) has just been
66      called; in previous versions, it was effectively as if
67      (SET-DEVELOPMENT-ENVIRONMENT T) had just been called.</para>
68      <para>Hopefully, most users of &CCL; can safely ignore these
69      issues most of the time. Note that doing (SET-USER-ENVIRONMENT
70      T) after loading one's own code (or 3rd-party code) into &CCL;
71      would protect that code (as well as &CCL;'s) from accidental
72      redefinition; that may be useful in some cases.</para>
73    </sect1>
74
75    <sect1 id="Debugging-facilities-in-the-lisp-kernel">
76      <title>Debugging facilities in the lisp kernel</title>
77      <para> In a perfect world, something like this couldn't
78      happen:</para>
79      <programlisting>
80Welcome to &CCL; Version x.y!
81? (defun foo (x)
82    (declare (cons x))
83    (cdr x))
84FOO
85
86? (foo -1) ;Oops. Too late ...
87Unhandled exception 11 at 0x300e90c8, context->regs at #x7ffff6b8
88Continue/Debugger/eXit &lt;enter&gt;?
89</programlisting>
90
91      <para>As you may have noticed, it's not a perfect world; it's rare
92        that the cause (attempting to reference the CDR of -1, and therefore
93        accessing unmapped memory near location 0) of this effect (an
94        "Unhandled exception ..." message) is so obvious.</para>
95      <para>The addresses printed in the message above aren't very useful
96        unless you're debugging the kernel with GDB (and they're often
97        very useful if you are.)</para>
98      <para>Aside from causing an exception that the lisp kernel doesn't
99        know how to handle, one can also enter the kernel debugger (more)
100        deliberately:</para>
101
102      <programlisting>
103? (defun classify (n)
104     (cond ((&gt; n 0) "Greater")
105           ((&lt; n 0) "Less")
106           (t
107            ;;; Sheesh ! What else could it be ?
108            (ccl::bug "I give up. How could this happen ?"))))
109CLASSIFY
110
111? (classify 0)
112Bug in &CCL; system code:
113I give up. How could this happen ?
114? for help
115[12345] &CCL; kernel debugger:
116      </programlisting>
117
118      <para>CCL::BUG isn't quite the right tool for this example (a
119        call to BREAK or PRINT might do a better job of clearing up the
120        mystery), but it's sometimes helpful when those other tools
121        can't be used.  The lisp error system notices, for instance, if
122        attempts to signal errors themselves cause errors to be
123        signaled; this sort of thing can happen if CLOS or the I/O
124        system are broken or missing. After some small number of
125        recursive errors, the error system gives up and calls
126        CCL::BUG.</para>
127      <para>If one enters a '?' at the kernel debugger prompt, one
128        will see output like:</para>
129
130      <programlisting>
131(S)  Find and describe symbol matching specified name
132(B)  Show backtrace
133(X)  Exit from this debugger, asserting that any exception was handled
134(K)  Kill &CCL; process
135(?)  Show this help
136      </programlisting>
137
138      <para>CCL::BUG just does an FF-CALL into the lisp kernel.  If
139        the kernel debugger was invoked because of an unhandled
140        exception (such as an illegal memory reference) the OS kernel
141        saves the machine state ("context") in a data structure for us,
142        and in that case some additional options can be used to display
143        the contents of the registers at the point of the
144        exception. Another function - CCL::DBG - causes a special
145        exception to be generated and enters the lisp kernel debugger
146        with a non-null "context":</para>
147
148      <programlisting>
149? (defun classify2 (n)
150  (cond ((&gt; n 0) "Greater")
151        ((&lt; n 0) "Less")
152        (t (dbg n))))
153CLASSIFY2
154
155? (classify2 0)
156Lisp Breakpoint
157 While executing: #&lt;Function CLASSIFY2 #x08476cfe>
158? for help
159[12345] &CCL; kernel debugger: ?
160(G)  Set specified GPR to new value
161(A)  Advance the program counter by one instruction (use with caution!)
162(D)  Describe the current exception in greater detail
163(R)  Show raw GPR/SPR register values
164(L)  Show Lisp values of tagged registers
165(F)  Show FPU registers
166(S)  Find and describe symbol matching specified name
167(B)  Show backtrace
168(X)  Exit from this debugger, asserting that any exception was handled
169(P)  Propagate the exception to another handler (debugger or OS)
170(K)  Kill &CCL; process
171(?)  Show this help
172</programlisting>
173
174      <para>CCL::DBG takes an argument, whose value is copied into the register
175        that &CCL; uses to return a function's primary value (arg_z, which
176        is r23 on the PowerPC). If we were to choose the (L) option at this point,
177        we'd see a dislay like:</para>
178
179      <programlisting>
180rnil = 0x01836015
181nargs = 0
182r16 (fn) = #&lt;Function CLASSIFY2 #x30379386>
183r23 (arg_z) = 0
184r22 (arg_y) = 0
185r21 (arg_x) = 0
186r20 (temp0) = #&lt;26-element vector subtag = 2F @#x303793ee>
187r19 (temp1/next_method_context) = 6393788
188r18 (temp2/nfn) = #&lt;Function CLASSIFY2 #x30379386>
189r17 (temp3/fname) = CLASSIFY2
190r31 (save0) = 0
191r30 (save1) = *TERMINAL-IO*
192r29 (save2) = 0
193r28 (save3) = (#&lt;RESTART @#x01867f2e> #&lt;RESTART @#x01867f56>)
194r27 (save4) = ()
195r26 (save5) = ()
196r25 (save6) = ()
197r24 (save7) = ()
198      </programlisting>
199
200      <para>From this we can conclude that the problematic argument to CLASSIFY2
201        was 0 (see r23/arg_z), and that I need to work on a better example.</para>
202      <para>The R option shows the values of the ALU (and PPC branch unit)
203        registers in hex; the F option shows the values of the FPU registers.</para>
204      <para>The (B) option shows a raw stack backtrace; it'll try to
205        identify foreign functions as well as lisp functions. (Foreign function
206        names are guesses based on the nearest preceding exported symbol.)</para>
207      <para>If you ever unexpectedly find yourself in the "lisp kernel
208        debugger", the output of the (L) and (B) options are often the most
209        helpful things to include in a bug report.</para>
210    </sect1>
211
212    <sect1 id="Using-AltiVec-in-CCL-LAP-functions">
213      <title>Using AltiVec in &CCL; LAP functions</title>
214
215      <sect2 id="Overview--16-">
216        <title>Overview</title>
217    <para>It's now possible to use AltiVec instructions in PPC LAP
218      (assembler) functions.</para>
219    <para>The lisp kernel detects the presence or absence of
220      AltiVec and preserves AltiVec state on lisp thread switch and
221      in response to exceptions, but the implementation doesn't
222      otherwise use vector operations.</para>
223    <para>This document doesn't document PPC LAP programming in
224      general.  Ideally, there would be some document that
225      did.</para>
226    <para>This document does explain AltiVec register-usage
227      conventions in &CCL; and explains the use of some lap macros
228      that help to enforce those conventions.</para>
229    <para>All of the global symbols described below are exported
230      from the CCL package. Note that lap macro names, ppc
231      instruction names, and (in most cases) register names are
232      treated as strings, so this only applies to functions and
233      global variable names.</para>
234    <para>Much of the &CCL; support for AltiVec LAP programming
235      is based on work contributed to MCL by Shannon Spires.</para>
236      </sect2>
237
238      <sect2 id="Register-usage-conventions">
239        <title>Register usage conventions</title>
240    <para>&CCL; LAP functions that use AltiVec instructions must
241      interoperate with each other and with C functions; that
242      suggests that they follow C AltiVec register usage
243      conventions. (vr0-vr1 scratch, vr2-vr13 parameters/return
244      value, vr14-vr19 temporaries, vr20-vr31 callee-save
245      non-volatile registers.)</para>
246    <para>The EABI (Embedded Application Binary Interface) used in
247      LinuxPPC doesn't ascribe particular significance to the vrsave
248      special-purpose register; on other platforms (notably MacOS),
249      it's used as a bitmap which indicates to system-level code
250      which vector registers contain meaningful values.</para>
251    <para>The WITH-ALTIVEC-REGISTERS lapmacro generates code which
252      which saves, updates, and restores VRSAVE on platforms where
253      this is required (as indicated by the value of the special
254      variable which controls this) and ignores VRSAVE on platforms
255      that don't require it to be maintained.</para>
256    <para>On all PPC platforms, it's necessary to save any non-volatile
257      vector registers (vr20 .. vr31) before assigning to them and to restore
258      such registers before returning to the caller.</para>
259    <para>On platforms that require that VRSAVE be maintained, it's not
260      necessary to mention the "use" of vector registers that are
261      used as incoming parameters. It's not incorrect to mention their use
262      in a WITH-ALTIVEC-REGISTERS form, but it may be unnecessary in many
263      interesting cases. One can likewise assume that the caller of any function
264      that returns a vector value (in vr2 has already set the appropriate bit in
265      VRSAVE to indicate that this register is live. One could therefore write a
266      leaf function that added the bytes in vr3 and vr2 and returned the result
267      in vr2 as:</para>
268
269        <programlisting>
270(defppclapfunction vaddubs ((y vr3) (z vr2))
271  (vaddubs z y z)
272  (blr))
273</programlisting>
274
275        <para>When vector registers that aren't incoming parameters are used
276          in a LAP function, WITH-ALTIVEC-REGISTERS takes care of maintaining VRSAVE
277          and of saving/restoring any non-volatile vector registers:</para>
278
279        <programlisting>
280(defppclapfunction load-array ((n arg_z))
281  (check-nargs 1)
282  (with-altivec-registers (vr1 vr2 vr3 vr27) ; Clobbers imm0
283    (li imm0 arch::misc-data-offset)
284    (lvx vr1 arg_z imm0) ; load MSQ
285    (lvsl vr27 arg_z imm0) ; set the permute vector
286    (addi imm0 imm0 16) ; address of LSQ
287    (lvx vr2 arg_z imm0) ; load LSQ
288    (vperm vr3 vr1 vr2 vr27) ; aligned result appears in VR3
289    (dbg t)) ; Look at result in some debugger
290  (blr))
291        </programlisting>
292
293        <para>AltiVec registers are not preserved by CATCH and UNWIND-PROTECT.
294          Since AltiVec is only accessible from LAP in &CCL; and since LAP
295          functions rarely use high- level control structures, this should rarely be
296          a problem in practice.</para>
297        <para>LAP functions which use non-volatile vector registers and which call
298          (Lisp ?) code which may use CATCH or UNWIND-PROTECT should save those
299          vector registers before such a call and restore them on return. This is
300          one of the intended uses of the WITH-VECTOR-BUFFER lap macro.</para>
301      </sect2>
302    </sect1>
303
304    <sect1 id="Development-Mode-Dictionary">
305      <title>Development-Mode Dictionary</title>
306
307      <refentry id="v_warn-if-redefine-kernel">
308            <indexterm zone="v_warn-if-redefine-kernel">
309              <primary>*warn-if-redefine-kernel</primary>
310            </indexterm>
311
312            <refnamediv>
313              <refname>*WARN-IF-REDEFINE-KERNEL*</refname>
314              <refpurpose></refpurpose>
315              <refclass>Variable</refclass>
316            </refnamediv>
317
318            <refsect1>
319              <title>Description</title>
320
321              <para>When true, attempts to redefine (via DEFUN or DEFMETHOD)
322                functions and methods that are marked as being
323                &#34;predefined&#34; signal continuable errors.</para>
324
325              <para>Note that these are CERRORs, not warnings, and that
326                no lisp functions or methods have been defined in the kernel
327                in MCL or &CCL; since 1987 or so.</para>
328            </refsect1>
329      </refentry>
330
331      <refentry id="f_set-development-environment">
332            <indexterm zone="f_set-development-environment">
333              <primary>set-development-environment</primary>
334            </indexterm>
335
336            <refnamediv>
337              <refname>SET-DEVELOPMENT-ENVIRONMENT</refname>
338              <refpurpose></refpurpose>
339              <refclass>Function</refclass>
340            </refnamediv>
341
342            <refsynopsisdiv>
343              <synopsis><function>set-development-environment</function>
344                &optional;
345                unmark-builtin-functions</synopsis>
346            </refsynopsisdiv>
347
348            <refsect1>
349              <title>Description</title>
350
351              <para>Arranges that the outermost special bindings of *PACKAGE*
352                and *WARN-IF-REDEFINE-KERNEL* restore values of the &#34;CCL&#34;
353                package and NIL to these variables, respectively. If the optional
354                argument is true, marks all globally defined functions and methods
355                as being &#34;not predefined&#34; (this is a fairly expensive
356                operation.)</para>
357            </refsect1>
358      </refentry>
359
360      <refentry id="f_set-user-environment">
361            <indexterm zone="f_set-user-environment">
362              <primary>set-user-environment</primary>
363            </indexterm>
364
365            <refnamediv>
366              <refname>SET-USER-ENVIRONMENT</refname>
367              <refpurpose></refpurpose>
368              <refclass>Function</refclass>
369            </refnamediv>
370
371            <refsynopsisdiv>
372              <synopsis><function>set-user-environment</function>
373                &optional; mark-builtin-functions</synopsis>
374            </refsynopsisdiv>
375
376            <refsect1>
377              <title>Description</title>
378
379              <para>Arranges that the outermost special bindings of *PACKAGE*
380                and *WARN-IF-REDEFINE-KERNEL* restore values of the
381                &#34;CL-USER&#34; package and T to these variables, respectively.
382                If the optional argument is true, marks all globally defined
383                functions and methods as being &#34;predefined&#34; (this is a
384                fairly expensive operation.)</para>
385            </refsect1>
386      </refentry>
387      <refentry id="v_altivec-available">
388            <indexterm zone="v_altivec-available">
389              <primary>*altivec-available*</primary>
390            </indexterm>
391
392            <refnamediv>
393              <refname>*ALTIVEC-AVAILABLE*</refname>
394              <refpurpose></refpurpose>
395              <refclass>Variable</refclass>
396            </refnamediv>
397
398            <refsect1>
399              <title>Description</title>
400              <para>This variable is initialized each time an &CCL; session
401                starts based on information provided by the lisp kernel. Its value
402                is true if AltiVec is present and false otherwise. This variable
403                shouldn't be set by user code.</para>
404            </refsect1>
405      </refentry>
406
407      <refentry id="f_altivec-available-p">
408            <indexterm zone="f_altivec-available-p">
409              <primary>altivec-available-p</primary>
410            </indexterm>
411
412            <refnamediv>
413              <refname>ALTIVEC-AVAILABLE-P</refname>
414              <refpurpose></refpurpose>
415              <refclass>Function</refclass>
416            </refnamediv>
417           
418            <refsynopsisdiv>
419              <synopsis><function>altivec-available-p</function></synopsis>
420            </refsynopsisdiv>
421
422            <refsect1>
423              <title>Description</title>
424
425              <para>Returns non-NIL if AltiVec is available.</para>
426            </refsect1>
427      </refentry>
428
429      <refentry id="v_altivec-lapmacros-maintain-vrsave-p">
430            <indexterm zone="v_altivec-lapmacros-maintain-vrsave-p">
431              <primary>*altivec-lapmacros-maintain-vrsave-p*</primary>
432            </indexterm>
433
434            <refnamediv>
435              <refname>*ALTIVEC-LAPMACROS-MAINTAIN-VRSAVE-P*</refname>
436              <refpurpose></refpurpose>
437              <refclass>Variable</refclass>
438            </refnamediv>
439           
440            <refsect1>
441              <title>Description</title>
442
443              <para>Intended to control the expansion of certain lap macros.
444                Initialized to NIL on LinuxPPC; initialized to T on platforms
445                (such as MacOS X/Darwin) that require that the VRSAVE SPR contain
446                a bitmask of active vector registers at all times.</para>
447            </refsect1>
448      </refentry>
449
450      <refentry id="lapm_with-altivec-registers">
451            <indexterm zone="lapm_with-altivec-registers">
452              <primary>with-altivec-registers</primary>
453            </indexterm>
454
455            <refnamediv>
456              <refname>WITH-ALTIVEC-REGISTERS</refname>
457              <refpurpose></refpurpose>
458              <refclass>LAP Macro</refclass>
459            </refnamediv>
460
461            <refsynopsisdiv>
462              <synopsis><function>with-altivec-registers</function>
463                reglist &body; body</synopsis>
464            </refsynopsisdiv>
465
466            <refsect1>
467              <title>Arguments and Values</title>
468
469              <variablelist>
470                <varlistentry>
471                  <term>reglist</term>
472
473                  <listitem>
474                        <para>A list of vector register names (vr0 .. vr31).</para>
475                  </listitem>
476                </varlistentry>
477
478                <varlistentry>
479                  <term>body</term>
480
481                  <listitem>
482                        <para>A sequence of PPC LAP instructions.</para>
483                  </listitem>
484                </varlistentry>
485              </variablelist>
486            </refsect1>
487
488            <refsect1>
489              <title>Description</title>
490
491              <para>Specifies the set of AltiVec registers used in body. If
492                *altivec-lapmacros-maintain-vrsave-p* is true when the macro is
493                expanded, generates code to save the VRSAVE SPR and updates VRSAVE
494                to include a bitmask generated from the specified register list.
495                Generates code which saves any non-volatile vector registers which
496                appear in the register list, executes body, and restores the saved
497                non-volatile vector registers (and, if
498                *altivec-lapmacros-maintain-vrsave-p* is true, restores VRSAVE as
499                well. Uses the IMM0 register (r3) as a temporary.</para>
500            </refsect1>
501      </refentry>
502
503      <refentry id="lapm_with-vector-buffer">
504            <indexterm zone="lapm_with-vector-buffer">
505              <primary>with-vector-buffer</primary>
506            </indexterm>
507
508            <refnamediv>
509              <refname>WITH-VECTOR-BUFFER</refname>
510              <refpurpose></refpurpose>
511              <refclass>LAP Macro</refclass>
512            </refnamediv>
513           
514            <refsynopsisdiv>
515              <synopsis>with-vector-buffer base n &body; body</synopsis>
516            </refsynopsisdiv>
517
518            <refsect1>
519              <title>Arguments and Values</title>
520
521              <variablelist>
522                <varlistentry>
523                  <term>base</term>
524
525                  <listitem>
526                        <para>Any available general-purpose register.</para>
527                  </listitem>
528                </varlistentry>
529
530                <varlistentry>
531                  <term>n</term>
532
533                  <listitem>
534                        <para>An integer between 1 and 254, inclusive. (Should
535                          typically be much, much closer to 1.) Specifies the size of
536                          the buffer, in 16-byte units.</para>
537                  </listitem>
538                </varlistentry>
539
540                <varlistentry>
541                  <term>body</term>
542
543                  <listitem>
544                        <para>A sequence of PPC LAP instructions.</para>
545                  </listitem>
546                </varlistentry>
547              </variablelist>
548            </refsect1>
549
550            <refsect1>
551              <title>Description</title>
552              <para>Generates code which allocates a 16-byte aligned buffer
553                large enough to contain N vector registers; the GPR base points to
554                the lowest address of this buffer. After processing body, the
555                buffer will be deallocated. The body should preserve the value of
556                base as long as it needs to reference the buffer. It's
557                intended that base be used as a base register in stvx and lvx
558                instructions within the body.</para>
559            </refsect1>
560      </refentry>
561    </sect1>
562  </chapter>
Note: See TracBrowser for help on using the repository browser.