Ignore:
Timestamp:
Apr 1, 2008, 5:07:25 PM (11 years ago)
Author:
mikel
Message:

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/doc/src/implementation.xml

    r8976 r8981  
    2828      implications of this are discussed elsewhere; this section tries
    2929      to describe how threads look from the lisp kernel's perspective
    30       (and especailly from the GC's point of view.)</para>
     30      (and especially from the GC's point of view.)</para>
    3131      <para>&CCL;'s runtime system tries to use machine-level
    3232      exception mechanisms (conditional traps when available, illegal
     
    9393        thread's value stack, and (on x86-64) RSP is switched to the
    9494        control stack.  A field in the TCR (tcr.valence) is then set
    95         to indicate that the thread is running foreigm code, foreign
     95        to indicate that the thread is running foreign code, foreign
    9696        argument registers are loaded from a frame on the foreign
    9797        stack, and the foreign function is called. (That's a little
     
    115115        execute an illegal instruction or access protected memory.)
    116116        It makes some sense to defer ("block") handling of
    117         aysnchronous signals so that some critical code sequences
     117        asynchronous signals so that some critical code sequences
    118118        complete without interruption; since it's generally not
    119119        possible for a thread to proceed after a synchronous exception
     
    136136        &CCL; uses Mach thread-level exception handling facilities
    137137        which run before GDB or CrashReporter get a chance to confuse
    138         themeselves; &CCL;'s Mach exception handling tries to force
     138        themselves; &CCL;'s Mach exception handling tries to force
    139139        the thread which received a synchronous exception to invoke a
    140140        signal handling function ("as if" signal handling worked more
     
    155155        signals blocked.  (This behavior is specified in the call to
    156156        the sigaction() function which established the signal
    157         handler.)  The signal handler recieves three arguments from
    158         the OS kernel; the first is an intger which identifies the
     157        handler.)  The signal handler receives three arguments from
     158        the OS kernel; the first is an integer which identifies the
    159159        signal, the second is a pointer to an object of type
    160160        "siginfo_t", which may or may not contain a few fields that
     
    173173        <para>On Darwin, the Mach exception thread creates a signal
    174174        context (and maybe a siginfo_t structure), stores the signal
    175         context in the thread's TCR, sets the TCR field wich describes
     175        context in the thread's TCR, sets the TCR field which describes
    176176        the thread's state, and arranges that the thread resume
    177177        execution at its signal handling function (with a signal
     
    193193        signal to be delivered on (and the signal context and siginfo
    194194        to be allocated on) a special stack area (the last few pages
    195         of the thread's cntrol stack, in practice.  When the signal
     195        of the thread's control stack, in practice.  When the signal
    196196        handler runs, it (carefully) copies the signal context and
    197197        siginfo to the thread's control stack and makes RSP point into
     
    233233        signal, then iterates over the list again, waiting for a
    234234        per-thread semaphore that indicates that the thread has
    235         received the "suspend" signal and responded appropriatedly.
     235        received the "suspend" signal and responded appropriately.
    236236        Once all other threads have acknowledged the request to
    237237        suspend themselves, the GC thread can run the GC proper (after
     
    265265            fully atomic.It takes at least a few instructions to
    266266            allocate an object in memory(and slap a header on it if
    267             necesssary); if a thread is interrupted inthe middle of
     267            necessary); if a thread is interrupted in the middle of
    268268            that instruction sequence, the new object may or may
    269             nothave been created or fully initialized at the point in
    270             time that theinterrupt occurred.  (There are actually a
    271             few different states ofpartial initialization)</para>
     269            not have been created or fully initialized at the point in
     270            time that the interrupt occurred.  (There are actually a
     271            few different states of partial initialization)</para>
    272272          </listitem>
    273273          <listitem>
     
    306306        interrupting thread to recognize when the interrupted thread
    307307        is in the middle of such a sequence.  When this is detected,
    308         the interrupting thread modfies the state of the interrupted
     308        the interrupting thread modifies the state of the interrupted
    309309        thread (modifying its PC and other registers) so that it is no
    310         longer in the middle of such a sequenece (it's either backed
     310        longer in the middle of such a sequence (it's either backed
    311311        out of it or the remaining instructions are emulated.)</para>
    312312        <para>This works because (a) many of the troublesome
     
    383383        a <xref linkend="Tagging-scheme"/> describes how the node's
    384384        value and type are encoded in that machine word.</para>
    385         <para>Most of this - so far - has discussed thigs from the
     385        <para>Most of this - so far - has discussed things from the
    386386        GC's very low-level perspective.  From a much higher point of
    387387        view, lisp functions accept nodes as arguments, return nodes
     
    407407        cases where locatives are allowed in &CCL; mostly involve
    408408        the behavior of function call and return instructions.  (To be
    409         technicaly accurate, the other case also arises on x86-64, but
     409        technically accurate, the other case also arises on x86-64, but
    410410        that case isn't as user-visible.)</para>
    411411        <para>On the PowerPC (both PPC32 and PPC64), all machine
    412         instructions are 32 bits wide and all in1struction words are
     412        instructions are 32 bits wide and all instruction words are
    413413        allocated on 32-bit boundaries.  In PPC &CCL;, a CODE-VECTOR
    414414        is a specialized type of vector-like object; its elements are
     
    423423        and aligned on 32-bit boundaries, the low two bits of the PC
    424424        are always 0.  If the function executes a call (simple call
    425         instrucions have the mnemonic "bl" on the PPC, which stands
     425        instructions have the mnemonic "bl" on the PPC, which stands
    426426        for "branch and link"), the address of the next instruction
    427427        (also a word-aligned locative into a code-vector) is copied
     
    434434        <para>&CCL;'s GC understands that certain registers contain
    435435        these special "pc-locatives" (locatives that point into
    436         CODE-VECTOR objects); it contains specal support for finding
     436        CODE-VECTOR objects); it contains special support for finding
    437437        the containing CODE-VECTOR object and for adjusting all of
    438438        these "pc-locatives" if the containing object is moved in
    439439        memory.  The first part of that - finding the containing
    440440        object - is possible and practical on the PPC because of
    441         architectural artifcacts (fixed-width instructions and arcana
     441        architectural artifacts (fixed-width instructions and arcana
    442442        of instruction encoding.)  It's not possible on x86-64, but
    443443        fortunately not necessary either (though the second part -
     
    502502              addresses the top of the value stack when running lisp
    503503              code; that address is saved in the TCR when running
    504               foreign code.  On the PPC, a dedicated regiter (VSP,
     504              foreign code.  On the PPC, a dedicated register (VSP,
    505505              currently r15) is used to address the top of the value
    506506              stack when running lisp code, and the VSP value is saved
     
    532532              x86-64, where temp stack frames always contain nodes,
    533533              the second word is always 0.  The temp stack grows down.
    534               It usually takes several instuctions to allocate and
     534              It usually takes several instructions to allocate and
    535535              safely initialize a temp stack frame that's intended to
    536536              contain nodes, and the GC has to recognize the case
     
    595595              <para>All other registers (RBX, RSI, RDI, and R8-R15)
    596596              are asserted to contain node values at (almost) all
    597               times; legacy "string" operationsthat implicitly use RSI
     597              times; legacy "string" operations that implicitly use RSI
    598598              and/or RDI are not used.</para>
    599599            </listitem>
     
    618618                <listitem>
    619619                  <para>r0 (symbolic name rzero) always contains the
    620                   value 0 when runninglisp code.  Its value is
     620                  value 0 when running lisp code.  Its value is
    621621                  sometimes read as 0 when it's used as the base
    622622                  register in a memory address; keeping the value 0
     
    651651                </listitem>
    652652                <listitem>
    653                   <para>r13 is used to hold the TCR on PPC32 sytems;
     653                  <para>r13 is used to hold the TCR on PPC32 systems;
    654654                  it's not used on PPC64.</para>
    655655                </listitem>
     
    717717        fields of things like CONS cells and structures, it's
    718718        desirable that that the tags chosen for CONS cells and
    719         structures allow the use of these intructions as opposed to
     719        structures allow the use of these instructions as opposed to
    720720        more expensive alternatives.)</para>
    721721        <para>One architecture-dependent tagging trick that works well
     
    755755            usually fairly common.It therefore makes sense to give
    756756            CONS cells their own tag.  Unlike the fixnum case - where a
    757             tag value of 0 had positive implications - theredoesn't
     757            tag value of 0 had positive implications - there doesn't
    758758            seem to be any advantage to using any particular value.
    759759            (A longtime ago - in the case of 68K MCL - the CONS tag
     
    816816            uniformly.There are some disadvantages to that uniform
    817817            treatment as well, and the treatment of "memory-allocated
    818             non-CONS objects" isn't entirely uniform accross all
     818            non-CONS objects" isn't entirely uniform across all
    819819            &CCL; implementations.  Let's first pretend that
    820820            the treatment is uniform, then discuss the ways in which it
    821821            isn't.The "uniform approach" is to treat all
    822             memory-allocated non-CONS objectsas if they were vectors;
     822            memory-allocated non-CONS objects as if they were vectors;
    823823            this use of the term is a little looser than what's implied
    824824            by the CL VECTOR type.  &CCL; actually uses the
     
    880880      <para>Reserving address space that can't (yet) be read or
    881881      written to doesn't cost much; in particular, it doesn't require
    882       that correspinding swap space or physical memory be available.
     882      that corresponding swap space or physical memory be available.
    883883      Marking the address range as being "mapped" helps to ensure that
    884884      other things (results from random calls to malloc(), dynamically
     
    908908        maintained in the current threads's TCR.  (An "empty" heap
    909909        segment is one whose high pointer and low pointer are equal.)
    910         When a thread is not in the midde of allocating something, the
     910        When a thread is not in the middle of allocating something, the
    911911        low 3 or 4 bits of the high and low pointers are clear (the
    912912        pointers are doublenode-aligned.)</para>
     
    974974        <para>If a thread traps while trying to allocate memory, the
    975975        thread goes through the usual exception-handling protocol (to
    976         ensure that any oher thread that GCs "sees" the state of the
     976        ensure that any other thread that GCs "sees" the state of the
    977977        trapping thread and to serialize exception handling.)  When
    978978        the exception handler runs, it determines the nature and size
     
    987987        GC before returning a new segment.  It's worth noting that the
    988988        [E]GC is triggered based on the number of and size of these
    989         segments that've been allocated since the last GC; it doesn't
     989        segments that have been allocated since the last GC; it doesn't
    990990        have much to do with how "full" each of those per-thread
    991991        segments are.  It's possible for a large number of threads to
     
    10161016        condition if lisp is ... out of memory</para>
    10171017        <para>I don't know that I've ever seen an abrupt out-of-memory
    1018         failure that wasn't preceeded by several minutes of excessive
     1018        failure that wasn't preceded by several minutes of excessive
    10191019        paging activity.  The most expedient course in cases like this
    10201020        is to either (a) use less memory or (b) get more memory; it's
     
    10441044          <para>the relocation table, which contains a native word for
    10451045          every 32 or 64 doublenodes in the dynamic heap, plus an
    1046           extra word used to keep trackof the end of the heap.</para>
     1046          extra word used to keep track of the end of the heap.</para>
    10471047        </listitem>
    10481048      </orderedlist>
     
    10551055        <para>Each doublenode in the dynamic heap has a corresponding
    10561056        bit in the markbits vector. (For any doublenode in the heap,
    1057         the index of its mark bit is determined by subtracing the
     1057        the index of its mark bit is determined by subtracting the
    10581058        address of the start of the heap from the address of the
    10591059        object and dividing the result by 8 or 16.) The GC knows the
     
    11151115              , </emphasis>the vector which contains the
    11161116              internal symbols of the current package is marked on
    1117               entry to the mark phasebut the symbols themselves are
     1117              entry to the mark phase, but the symbols themselves are
    11181118              not marked at this time. Near the end of the mark phase,
    11191119              symbols referenced from this vector which are
     
    11501150        precede it>)) or alternately (&lt;the base of the heap> +
    11511151        (size_of_doublenode * &lt;the number of marked markbits that
    1152         preced it &gt;)). Rather than count the number of preceding
     1152        precede it &gt;)). Rather than count the number of preceding
    11531153        markbits each time, the relocation table is used to precompute
    11541154        an approximation of the forwarding addresses for all
     
    12221222        any allocation request that may have triggered the GC, the
    12231223        exception handler returns; otherwise, a "seriously low on
    1224         memory" condition is signalled, possibly after releasing a
     1224        memory" condition is signaled, possibly after releasing a
    12251225        small emergency pool of memory.</para>
    12261226      </sect2>
     
    12481248        <listitem>
    12491249          <para>old objects can only point to newer objects as the
    1250           result of adestructive modification (e.g., via
     1250          result of a destructive modification (e.g., via
    12511251          SETF.)</para>
    12521252        </listitem>
     
    12931293      <itemizedlist>
    12941294        <listitem>
    1295           <para>the "base of the heap" used to determine anobject's
     1295          <para>the "base of the heap" used to determine an object's
    12961296          markbit address is the base of the generation
    12971297          being collected;</para>
     
    13101310        <listitem>
    13111311          <para>the intergenerational references table is used to
    1312           findadditional roots for the mark and forward phases. If a
     1312          find additional roots for the mark and forward phases. If a
    13131313          bit is set inthe intergenerational references table, that
    1314           means that thecorresponding doubleword (in some "old"
    1315           generation, insome "earlier" part of the heap) may have had
    1316           a pointerto an object in a younger generation stored into
     1314          means that the corresponding doubleword (in some "old"
     1315          generation, in some "earlier" part of the heap) may have had
     1316          a pointer to an object in a younger generation stored into
    13171317          it.</para>
    13181318        </listitem>
     
    14291429        that are introduced to the lisp runtime in other ways (as
    14301430        function arguments, return values, SLOT-VALUE results, etc. as
    1431         well as those instances that're created under lisp
     1431        well as those instances that are created under lisp
    14321432        control.)</para>
    14331433        <para>This doesn't all work yet (in fact, not much of it works
Note: See TracChangeset for help on using the changeset viewer.