Changeset b51e389c


Ignore:
Timestamp:
Jun 15, 2021, 4:17:05 PM (16 months ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
6071efc
Parents:
2f19e03
Message:

Revert "proofread Andrew's implement, performance and future chapters", changes saved locally.

This reverts commit b6749fdf08185c0beb48a79dbf340a15f5b3b943.

Location:
doc/theses/andrew_beach_MMath
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • doc/theses/andrew_beach_MMath/future.tex

    r2f19e03 rb51e389c  
    77that I had to workaround while building an exception handling system largely in
    88the \CFA language (some C components).  The following are a few of these
    9 issues, and once implemented/fixed, how they would affect the exception system.
     9issues, and once implemented/fixed, how this would affect the exception system.
    1010\begin{itemize}
    1111\item
     
    1313hand-crafted assembly statements. These sections must be ported by hand to
    1414support more hardware architectures, such as the ARM processor.
    15 \PAB{I think this is a straw-man problem because the hand-coded assembler code
    16 has to be generated somewhere, and that somewhere is hand-coded.}
    1715\item
    1816Due to a type-system problem, the catch clause cannot bind the exception to a
    1917reference instead of a pointer. Since \CFA has a very general reference
    2018capability, programmers will want to use it. Once fixed, this capability should
    21 result in little or no change in the exception system but simplify usage.
     19result in little or no change in the exception system.
    2220\item
    2321Termination handlers cannot use local control-flow transfers, \eg by @break@,
     
    3028There is no detection of colliding unwinds. It is possible for clean-up code
    3129run during an unwind to trigger another unwind that escapes the clean-up code
    32 itself, \eg, a termination exception caught further down the stack or a
    33 cancellation. There do exist ways to handle this issue, but currently they are not
    34 even detected and the first unwind is simply dropped, often leaving
    35 it in a bad state. \Cpp terminates the program in this case, and Java picks the ...
     30itself; such as a termination exception caught further down the stack or a
     31cancellation. There do exist ways to handle this but currently they are not
     32even detected and the first unwind will simply be forgotten, often leaving
     33it in a bad state.
    3634\item
    3735Also the exception system did not have a lot of time to be tried and tested.
     
    4341The virtual system should be completed. It was not supposed to be part of this
    4442project, but was thrust upon it to do exception inheritance; hence, only
    45 minimal work is done. A draft for a complete virtual system is available but
     43minimal work was done. A draft for a complete virtual system is available but
    4644it is not finalized.  A future \CFA project is to complete that work and then
    4745update the exception system that uses the current version.
     
    6967bad software engineering.
    7068
    71 Non-local/concurrent raise requires more coordination between the concurrency system
     69Non-local/concurrent requires more coordination between the concurrency system
    7270and the exception system. Many of the interesting design decisions centre
    73 around masking, \ie controlling which exceptions may be thrown at a stack. It
     71around masking (controlling which exceptions may be thrown at a stack). It
    7472would likely require more of the virtual system and would also effect how
    7573default handlers are set.
     
    8785
    8886\section{Checked Exceptions}
    89 Checked exceptions make exceptions part of a function's type by adding an
     87Checked exceptions make exceptions part of a function's type by adding the
    9088exception signature. An exception signature must declare all checked
    91 exceptions that could propagate from the function (either because they were
     89exceptions that could propogate from the function (either because they were
    9290raised inside the function or came from a sub-function). This improves safety
    9391by making sure every checked exception is either handled or consciously
    9492passed on.
    9593
    96 However checked exceptions were never seriously considered for this project because
    97 they have significant usability and reuse trade-offs in
     94However checked exceptions were never seriously considered for this project
     95for two reasons. The first is due to time constraints, even copying an
     96existing checked exception system would be pushing the remaining time and
     97trying to address the second problem would take even longer. The second
     98problem is that checked exceptions have some real usability trade-offs in
    9899exchange for the increased safety.
     100
    99101These trade-offs are most problematic when trying to pass exceptions through
    100102higher-order functions from the functions the user passed into the
    101103higher-order function. There are no well known solutions to this problem
    102 that were satisfactory for \CFA (which carries some of C's flexibility
    103 over safety design) so additional research is needed.
     104that were statifactory for \CFA (which carries some of C's flexability
     105over safety design) so one would have to be researched and developed.
    104106
    105 Follow-up work might find a compromise design for checked exceptions in \CFA, possibly using
    106 polymorphic exception signatures, a form of tunneling\cite{Zhang19}, or
     107Follow-up work might add checked exceptions to \CFA, possibly using
     108polymorphic exception signatures, a form of tunneling\cite{Zhang19} or
    107109checked and unchecked raises.
    108110
     
    148150For instance, resumption could be extended to cover this use by allowing local
    149151control flow out of it. This approach would require an unwind as part of the
    150 transition as there are stack frames that have to be removed back to the resumption handler.  This approach
    151 means no special statement is required in the handler to continue after it.
    152 Currently, \CFA allows a termination exception to be thrown from within any resumption handler so
    153 there is already a way to partially mimic signal exceptions.
     152transition as there are stack frames that have to be removed.  This approach
     153means there is no notify raise, but because \CFA does not have exception
     154signatures, a termination can be thrown from within any resumption handler so
     155there is already a way to do mimic this in existing \CFA.
    154156
    155157% Maybe talk about the escape; and escape CONTROL_STMT; statements or how
  • doc/theses/andrew_beach_MMath/implement.tex

    r2f19e03 rb51e389c  
    22\label{c:implement}
    33
    4 The implementation work for this thesis covers the two components: virtual
     4The implementation work for this thesis covers two components: the virtual
    55system and exceptions. Each component is discussed in detail.
    66
     
    1717pointer to the virtual table, which is called the \emph{virtual-table pointer}.
    1818Internally, the field is called \snake{virtual_table}.
    19 The field is fixed after construction and is the first field in the
     19The field is fixed after construction. It is always the first field in the
    2020structure so that its location is always known.
    2121\todo{Talk about constructors for virtual types (after they are working).}
    2222
    23 The virtual-table pointer is what binds an instance of a virtual type to its virtual table. This
    24 pointer is used as an identity check, and to access the
     23This is what binds an instance of a virtual type to a virtual table. This
     24pointer can be used as an identity check. It can also be used to access the
    2525virtual table and the virtual members there.
    2626
    2727\subsection{Type Id}
    2828Every virtual type has a unique id.
    29 Type ids can be compared for equality (\ie the types represented are the same)
     29Type ids can be compared for equality (the types reperented are the same)
    3030or used to access the type's type information.
    3131The type information currently is only the parent's type id or, if the
    32 type has no parent, @0p@.
     32type has no parent, zero.
    3333
    3434The id's are implemented as pointers to the type's type information instance.
    35 Dereferencing the pointer gets the type information.
    36 The ancestors of a virtual type are found by traversing the type id through
    37 the type information.
    38 An id also pushes the issue of creating a unique value (for
     35Derefencing the pointer gets the type information.
     36By going back-and-forth between the type id and
     37the type info one can find every ancestor of a virtual type.
     38It also pushes the issue of creating a unique value (for
    3939the type id) to the problem of creating a unique instance (for type
    40 information), which the linker can solve.
     40information) which the linker can solve.
    4141
    4242Advanced linker support is required because there is no place that appears
    4343only once to attach the type information to. There should be one structure
    44 definition but it is included in multiple translation units because of separate compilation. Each virtual
    45 table definition should be unique but there are an arbitrary number of these,
    46 so the special section prefix \texttt{.gnu.linkonce} is used.
    47 With a generated unique suffix (making the entire section name unique) the linker
    48 removes multiple definition ensuring only one version exists after linking.
     44definition but it is included in multiple translation units. Each virtual
     45table definition should be unique but there are an arbitrary number of thoses.
     46So the special section prefix \texttt{.gnu.linkonce} is used.
     47With a unique suffix (making the entire section name unique) the linker will
     48remove multiple definition making sure only one version exists after linking.
    4949Then it is just a matter of making sure there is a unique name for each type.
    5050
    51 These steps are done in three phases.
    52 \begin{enumerate}
    53 \item
     51This is done in three phases.
    5452The first phase is to generate a new structure definition to store the type
    5553information. The layout is the same in each case, just the parent's type id,
     
    5755The structure's name is change, it is based off the virtual type's name, and
    5856the type of the parent's type id.
    59 If the virtual type is polymorphic, then the type information structure is
     57If the virtual type is polymorphic then the type information structure is
    6058polymorphic as well, with the same polymorphic arguments.
    61 \item
     59
    6260The second phase is to generate an instance of the type information with a
    6361almost unique name, generated by mangling the virtual type name.
    64 \item
     62
    6563The third phase is implicit with \CFA's overloading scheme. \CFA mangles
    6664names with type information so that all of the symbols exported to the linker
    67 are unique even if in the \CFA code they are the same. Having two declarations
     65are unique even if in \CFA code they are the same. Having two declarations
    6866with the same name and same type is forbidden because it is impossible for
    69 overload resolution to pick between them. This is the reason why a unique type is
     67overload resolution to pick between them. This is why a unique type is
    7068generated for each virtual type.
    7169Polymorphic information is included in this mangling so polymorphic
    72 types have separate instances for each set of polymorphic arguments.
    73 \end{enumerate}
    74 The following example shows the components for a generated virtual type.
     70types will have seperate instances for each set of polymorphic arguments.
     71
    7572\begin{cfa}
    7673struct TYPE_ID_TYPE {
     
    8481\end{cfa}
    8582
    86 \subsubsection{\lstinline{cfa_linkonce} Attribute}
     83\subsubsection{cfa\_linkonce Attribute}
    8784Another feature added to \CFA is a new attribute: \texttt{cfa\_linkonce}.
    88 This attribute is attached to an object or function definition
    89 (any global declaration with a name and a type)
    90 allowing it to be defined multiple times.
    91 All matching definitions must have the link-once attribute on them and should
     85This attribute can be put on an object or function definition
     86(any global declaration with a name and a type).
     87This allows you to define that object or function multiple times.
     88All definitions should have the link-once attribute on them and all should
    9289be identical.
    93 This attributed prototype is placed in a header file with other
    94 forward declaration.
    95 
    96 This technique is used for type-id instances, as there is no unique location
    97 associated with a type, except for the type definition in a header.
    98 The result is the unique type-id object generated by the linker.
    99 
    100 Internally, @cfa_linkonce@ is replaced with
     90
     91The simplist way to use it is to put a definition in a header where the
     92forward declaration would usually go.
     93This is how it is used for type-id instances. There was is no unique location
     94associated with a type except for the type definition which is in a header.
     95This allows the unique type-id object to be generated there.
     96
     97Internally @cfa_linkonce@ removes all @section@ attributes
     98from the declaration (as well as itself) and replaces them with
    10199@section(".gnu.linkonce.NAME")@ where \texttt{NAME} is replaced by the
    102100mangled name of the object.
    103 Any other @section@ attributes are also removed from the declaration.
    104101The prefix \texttt{.gnu.linkonce} in section names is recognized by the
    105 linker. If two of these sections appear with the same name, including everything
    106 that comes after the special prefix, then only one is used and the other
    107 discarded.
     102linker. If two of these sections with the same name, including everything
     103that comes after the special prefix, then only one will be used and the other
     104will be discarded.
    108105
    109106\subsection{Virtual Table}
     
    115112below.
    116113
    117 Figure~\ref{f:VirtualTableLayout} shows the layout is in three parts.
    118 \PAB{Number the parts in the figure.}
    119 \begin{enumerate}
    120 \item
     114The layout always comes in three parts.
    121115The first section is just the type id at the head of the table. It is always
    122 there to ensure that \PAB{... missing text to end this sentence}
    123 \item
     116there to ensure that
    124117The second section are all the virtual members of the parent, in the same
    125118order as they appear in the parent's virtual table. Note that the type may
    126 change slightly as references to the @this@ change. This structure is limited to
     119change slightly as references to the ``this" will change. This is limited to
    127120inside pointers/references and via function pointers so that the size (and
    128121hence the offsets) are the same.
    129 \item
    130122The third section is similar to the second except that it is the new virtual
    131123members introduced at this level in the hierarchy.
    132 \end{enumerate}
    133124
    134125\begin{figure}
     
    142133prefix that has the same layout and types as its parent virtual table.
    143134This, combined with the fixed offset to the virtual table pointer, means that
    144 for any virtual type, it or any of its
    145 descendants can be accessed through
     135for any virtual type it doesn't matter if we have it or any of its
     136descendants, it is still always safe to access the virtual table through
    146137the virtual table pointer.
    147 From there, it is safe to check the type id to identify the exact type of the
    148 underlying object, access any of the virtual members, and pass the object to
     138From there it is safe to check the type id to identify the exact type of the
     139underlying object, access any of the virtual members and pass the object to
    149140any of the method-like virtual members.
    150141
    151 When a virtual table is declared, the user decides where to declare it and its
     142When a virtual table is declared the user decides where to declare it and its
    152143name. The initialization of the virtual table is entirely automatic based on
    153144the context of the declaration.
    154145
    155 The type id is always fixed with each virtual table type having
     146The type id is always fixed, each virtual table type will always have one
    156147exactly one possible type id.
    157 The virtual members are usually filled in during type resolution. The best match for
    158 a given name and type at the declaration site is used.
     148The virtual members are usually filled in by resolution. The best match for
     149a given name and type at the declaration site is filled in.
    159150There are two exceptions to that rule: the @size@ field is the type's size
    160 set using a @sizeof@ expression, and the @align@ field is the
    161 type's alignment set using an @alignof@ expression.
     151and is set to the result of a @sizeof@ expression, the @align@ field is the
     152type's alignment and similarly uses an @alignof@ expression.
    162153
    163154\subsubsection{Concurrency Integration}
    164155Coroutines and threads need instances of @CoroutineCancelled@ and
    165156@ThreadCancelled@ respectively to use all of their functionality. When a new
    166 data type is declared with @coroutine@ or @thread@, a forward declaration for
     157data type is declared with @coroutine@ or @thread@ the forward declaration for
    167158the instance is created as well. The definition of the virtual table is created
    168159at the definition of the main function.
    169 
    170 Figure~\ref{f:ConcurrencyTransformations} shows ...
    171 \todo{Improve Concurrency Transformations figure.}
    172160
    173161\begin{figure}
     
    206194\label{f:ConcurrencyTransformations}
    207195\end{figure}
     196\todo{Improve Concurrency Transformations figure.}
    208197
    209198\subsection{Virtual Cast}
     
    222211the cast target is passed in as @child@.
    223212
    224 The generated C code wraps both arguments and the result with type casts.
    225 There is also an internal check inside the compiler to make sure that the
     213For C generation both arguments and the result are wrapped with type casts.
     214There is also an internal store inside the compiler to make sure that the
    226215target type is a virtual type.
    227216% It also checks for conflicting definitions.
    228217
    229 The virtual cast either returns the original pointer as a new type or 0p.
    230 So the function just does the parent check and returns the appropriate value.
     218The virtual cast either returns the original pointer as a new type or null.
     219So the function just does the parent check and returns the approprate value.
    231220The parent check is a simple linear search of child's ancestors using the
    232221type information.
     
    240229% resumption doesn't as well.
    241230
    242 % Many modern languages work with an internal stack that function push and pop
     231% Many modern languages work with an interal stack that function push and pop
    243232% their local data to. Stack unwinding removes large sections of the stack,
    244233% often across functions.
     
    247236stack. On function entry and return, unwinding is handled directly by the
    248237call/return code embedded in the function.
    249 In many cases, the position of the instruction pointer (relative to parameter
     238In many cases the position of the instruction pointer (relative to parameter
    250239and local declarations) is enough to know the current size of the stack
    251240frame.
    252241
    253242Usually, the stack-frame size is known statically based on parameter and
    254 local variable declarations. Even with dynamic stack-size, the information
    255 to determine how much of the stack has to be removed is still contained
     243local variable declarations. Even with dynamic stack-size the information
     244to determain how much of the stack has to be removed is still contained
    256245within the function.
    257246Allocating/deallocating stack space is usually an $O(1)$ operation achieved by
    258247bumping the hardware stack-pointer up or down as needed.
    259 In fact, constructing/destructing values within a stack frame is of similar complexity but often takes longer.
     248Constructing/destructing values on the stack takes longer put in terms of
     249figuring out what needs to be done is of similar complexity.
    260250
    261251Unwinding across multiple stack frames is more complex because that
    262252information is no longer contained within the current function.
    263 With separate compilation a function has no way of knowing what its callers
    264 so it can not know how large those frames are.
    265 Without altering the main code path, it is also hard to pass that work off
     253With seperate compilation a function has no way of knowing what its callers
     254are so it can't know how large those frames are.
     255Without altering the main code path it is also hard to pass that work off
    266256to the caller.
    267257
     
    271261reseting to a snap-shot of an arbitrary but existing function frame on the
    272262stack. It is up to the programmer to ensure the snap-shot is valid when it is
    273 reset and that all required clean-up from the unwound stacks is performed.
    274 This approach is fragile and forces extra work in the surrounding code.
    275 
    276 With respect to the extra work in the surrounding code,
     263reset and that all required clean-up from the unwound stacks is preformed.
     264This approach is fragile and forces a work onto the surounding code.
     265
     266With respect to that work forced onto the surounding code,
    277267many languages define clean-up actions that must be taken when certain
    278268sections of the stack are removed. Such as when the storage for a variable
    279 is removed from the stack or when a @try@ statement with a finally clause is
     269is removed from the stack or when a try statement with a finally clause is
    280270(conceptually) popped from the stack.
    281 None of these should be handled explicitly by the user --- that would contradict the
    282 intention of these features --- so they need to be handled automatically.
    283 
    284 To safely remove sections of the stack, the language must be able to find and
     271None of these should be handled by the user, that would contradict the
     272intention of these features, so they need to be handled automatically.
     273
     274To safely remove sections of the stack the language must be able to find and
    285275run these clean-up actions even when removing multiple functions unknown at
    286276the beginning of the unwinding.
     
    304294current stack frame, and what handlers should be checked. Theoretically, the
    305295LSDA can contain any information but conventionally it is a table with entries
    306 representing regions of a function and what has to be done there during
     296representing regions of the function and what has to be done there during
    307297unwinding. These regions are bracketed by instruction addresses. If the
    308298instruction pointer is within a region's start/end, then execution is currently
    309299executing in that region. Regions are used to mark out the scopes of objects
    310 with destructors and @try@ blocks.
     300with destructors and try blocks.
    311301
    312302% Libunwind actually does very little, it simply moves down the stack from
     
    324314int avar __attribute__(( cleanup(clean_up) ));
    325315\end{cfa}
    326 The attribute is used on a variable and specifies a function,
     316The attribue is used on a variable and specifies a function,
    327317in this case @clean_up@, run when the variable goes out of scope.
    328 This capability is enough to mimic destructors, but not @try@ statements which can effect
     318This is enough to mimic destructors, but not try statements which can effect
    329319the unwinding.
    330320
    331 To get full unwinding support, all of these components must done directly with
    332 assembly and assembler directives, particularly the cfi directives
    333 \snake{.cfi_Leda} and \snake{.cfi_personality}.
     321To get full unwinding support all of this has to be done directly with
     322assembly and assembler directives. Partiularly the cfi directives
     323\snake{.cfi_lsda} and \snake{.cfi_personality}.
    334324
    335325\subsection{Personality Functions}
     
    337327section covers some of the important parts of the interface.
    338328
    339 A personality function can perform different actions depending on how it is
     329A personality function can preform different actions depending on how it is
    340330called.
    341331\begin{lstlisting}
     
    374364
    375365The @exception_class@ argument is a copy of the
    376 \code{C}{exception}'s @exception_class@ field,
    377 which is a number that identifies the exception handling mechanism that created
    378 the \PAB{... missing text to end this sentence}
    379 
    380 The \code{C}{exception} argument is a pointer to a user
     366\code{C}{exception}'s @exception_class@ field.
     367This a number that identifies the exception handling mechanism that created
     368the
     369
     370The \code{C}{exception} argument is a pointer to the user
    381371provided storage object. It has two public fields: the @exception_class@,
    382372which is described above, and the @exception_cleanup@ function.
    383 The clean-up function is used by the EHM to clean-up the exception, if it
     373The clean-up function is used by the EHM to clean-up the exception if it
    384374should need to be freed at an unusual time, it takes an argument that says
    385375why it had to be cleaned up.
     
    392382messages for special cases (some of which should never be used by the
    393383personality function) and error codes. However, unless otherwise noted, the
    394 personality function always return @_URC_CONTINUE_UNWIND@.
     384personality function should always return @_URC_CONTINUE_UNWIND@.
    395385
    396386\subsection{Raise Exception}
    397 Raising an exception is the central function of libunwind and it performs the
     387Raising an exception is the central function of libunwind and it performs a
    398388two-staged unwinding.
    399389\begin{cfa}
     
    482472% catches. Talk about GCC nested functions.
    483473
    484 \CFA termination exceptions use libunwind heavily because they match
     474\CFA termination exceptions use libunwind heavily because they match \Cpp
    485475\Cpp exceptions closely. The main complication for \CFA is that the
    486476compiler generates C code, making it very difficult to generate the assembly to
    487 form the LSDA for @try@ blocks or destructors.
     477form the LSDA for try blocks or destructors.
    488478
    489479\subsection{Memory Management}
     
    495485
    496486\begin{figure}
    497 \centering
    498487\input{exception-layout}
    499488\caption{Exception Layout}
     
    502491\todo*{Convert the exception layout to an actual diagram.}
    503492
    504 Exceptions are stored in variable-sized blocks (see Figure~\vref{f:ExceptionLayout}).
     493Exceptions are stored in variable-sized blocks (see \vref{f:ExceptionLayout}).
    505494The first component is a fixed-sized data structure that contains the
    506495information for libunwind and the exception system. The second component is an
     
    509498@_Unwind_Exception@ to the entire node.
    510499
    511 Multiple exceptions can exist at the same time because exceptions can be
     500Multipe exceptions can exist at the same time because exceptions can be
    512501raised inside handlers, destructors and finally blocks.
    513502Figure~\vref{f:MultipleExceptions} shows a program that has multiple
    514503exceptions active at one time.
    515504Each time an exception is thrown and caught the stack unwinds and the finally
    516 clause runs. This handler throws another exception (until @num_exceptions@ gets
    517 high enough), which must be allocated. The previous exceptions may not be
     505clause runs. This will throw another exception (until @num_exceptions@ gets
     506high enough) which must be allocated. The previous exceptions may not be
    518507freed because the handler/catch clause has not been run.
    519 Therefore, the EHM must keep all of these exceptions alive while it allocates exceptions for new throws.
     508So the EHM must keep them alive while it allocates exceptions for new throws.
    520509
    521510\begin{figure}
     
    570559\todo*{Work on multiple exceptions code sample.}
    571560
    572 All exceptions are stored in nodes, which are then linked together in lists
     561All exceptions are stored in nodes which are then linked together in lists,
    573562one list per stack, with the
    574563list head stored in the exception context. Within each linked list, the most
     
    577566exception is being handled. The exception at the head of the list is currently
    578567being handled, while other exceptions wait for the exceptions before them to be
    579 handled and removed.
     568removed.
    580569
    581570The virtual members in the exception's virtual table provide the size of the
     
    584573exception into managed memory. After the exception is handled, the free
    585574function is used to clean up the exception and then the entire node is
    586 passed to free so the memory is returned to the heap.
     575passed to free so the memory can be given back to the heap.
    587576
    588577\subsection{Try Statements and Catch Clauses}
    589 The @try@ statement with termination handlers is complex because it must
    590 compensate for the C code-generation versus assembly-code generation from \CFA. Libunwind
     578The try statement with termination handlers is complex because it must
     579compensate for the lack of assembly-code generated from \CFA. Libunwind
    591580requires an LSDA and personality function for control to unwind across a
    592581function. The LSDA in particular is hard to mimic in generated C code.
    593582
    594583The workaround is a function called @__cfaehm_try_terminate@ in the standard
    595 library. The contents of a @try@ block and the termination handlers are converted
     584library. The contents of a try block and the termination handlers are converted
    596585into functions. These are then passed to the try terminate function and it
    597586calls them.
    598587Because this function is known and fixed (and not an arbitrary function that
    599 happens to contain a @try@ statement), the LSDA can be generated ahead
     588happens to contain a try statement), the LSDA can be generated ahead
    600589of time.
    601590
     
    603592embedded assembly. This assembly code is handcrafted using C @asm@ statements
    604593and contains
    605 enough information for a single @try@ statement the function represents.
     594enough information for the single try statement the function repersents.
    606595
    607596The three functions passed to try terminate are:
    608597\begin{description}
    609 \item[try function:] This function is the @try@ block, where all the code inside the
    610 @try@ block is wrapped inside the function. It takes no parameters and has no
     598\item[try function:] This function is the try block, all the code inside the
     599try block is placed inside the try function. It takes no parameters and has no
    611600return value. This function is called during regular execution to run the try
    612601block.
     
    620609handler that matches the exception.
    621610
    622 \item[handler function:] This function handles the exception, where the code inside
    623 is constructed by stitching together the bodies of
    624 each handler of a @try@ statement and dispatches to the selected handler.
    625 It takes a
     611\item[handler function:] This function handles the exception. It takes a
    626612pointer to the exception and the handler's id and returns nothing. It is called
    627 after the cleanup phase.
     613after the cleanup phase. It is constructed by stitching together the bodies of
     614each handler and dispatches to the selected handler.
    628615\end{description}
    629616All three functions are created with GCC nested functions. GCC nested functions
    630 can be used to create closures, \ie functions that can refer to the state of other
     617can be used to create closures, functions that can refer to the state of other
    631618functions on the stack. This approach allows the functions to refer to all the
    632619variables in scope for the function containing the @try@ statement. These
     
    636623Using this pattern, \CFA implements destructors with the cleanup attribute.
    637624
    638 Figure~\ref{f:TerminationTransformation} shows an example transformation for a \CFA @try@
    639 statement with  @catch@ clauses into corresponding C functions. \PAB{Walk the reader through the example code.}
    640 
    641625\begin{figure}
    642626\begin{cfa}
     
    649633}
    650634\end{cfa}
    651 
    652 \medskip
    653 \hrule
    654 \medskip
    655635
    656636\begin{cfa}
     
    703683% The stack-local data, the linked list of nodes.
    704684
    705 Resumption is simpler to implement than termination
     685Resumption simpler to implement than termination
    706686because there is no stack unwinding.
    707687Instead of storing the data in a special area using assembly,
    708688there is just a linked list of possible handlers for each stack,
    709 with each list node representing a @try@ statement on the stack.
     689with each node on the list reperenting a try statement on the stack.
    710690
    711691The head of the list is stored in the exception context.
    712 The nodes are stored in order, with the more recent @try@ statements closer
     692The nodes are stored in order, with the more recent try statements closer
    713693to the head of the list.
    714 Instead of traversing the stack, resumption handling traverses the list.
    715 At each node, the EHM checks to see if the @try@ statement it represents
     694Instead of traversing the stack resumption handling traverses the list.
     695At each node the EHM checks to see if the try statement the node repersents
    716696can handle the exception. If it can, then the exception is handled and
    717697the operation finishes, otherwise the search continues to the next node.
    718 If the search reaches the end of the list without finding a @try@ statement
    719 that can handle the exception, the default handler is executed and the
     698If the search reaches the end of the list without finding a try statement
     699that can handle the exception the default handler is executed and the
    720700operation finishes.
    721701
    722 Each node has a handler function that does most of the work.
    723 The handler function is passed the raised exception and returns true
    724 if the exception is handled and false otherwise.
    725 
    726 For each @catchResume@ clause, the handler function:
    727 \begin{itemize}
    728 \item
    729 checks to see if the raised exception is a descendant type of the declared
    730 exception type,
    731 \item
    732 if it is and there is a conditional expression then it
    733 runs the test,
    734 \item
    735 if both checks pass the handling code for the clause is run and the function returns true,
    736 \item
    737 otherwise it moves onto the next clause.
    738 \end{itemize}
     702In each node is a handler function which does most of the work there.
     703The handler function is passed the raised the exception and returns true
     704if the exception is handled and false if it cannot be handled here.
     705
     706For each @catchResume@ clause the handler function will:
     707check to see if the raised exception is a descendant type of the declared
     708exception type, if it is and there is a conditional expression then it will
     709run the test, if both checks pass the handling code for the clause is run
     710and the function returns true, otherwise it moves onto the next clause.
    739711If this is the last @catchResume@ clause then instead of moving onto
    740712the next clause the function returns false as no handler could be found.
    741 
    742 Figure~\ref{f:ResumptionTransformation} shows an example transformation for a \CFA @try@
    743 statement with @catchResume@ clauses into corresponding C functions. \PAB{Walk the reader through the example code.}
    744713
    745714\begin{figure}
     
    784753
    785754% Recursive Resumption Stuff:
    786 Figure~\ref{f:ResumptionMarking} shows the search skipping (see \vpageref{s:ResumptionMarking}), which ignores parts of
     755Search skipping (see \vpageref{s:ResumptionMarking}), which ignores parts of
    787756the stack
    788757already examined, is accomplished by updating the front of the list as the
     
    790759is updated to the next node of the current node. After the search is complete,
    791760successful or not, the head of the list is reset.
     761
    792762This mechanism means the current handler and every handler that has already
    793763been checked are not on the list while a handler is run. If a resumption is
    794 thrown during the handling of another resumption, the active handlers and all
     764thrown during the handling of another resumption the active handlers and all
    795765the other handler checked up to this point are not checked again.
    796 This structure also supports new handlers added while the resumption is being
     766
     767This structure also supports new handler added while the resumption is being
    797768handled. These are added to the front of the list, pointing back along the
    798769stack -- the first one points over all the checked handlers -- and the ordering
    799770is maintained.
    800 \PAB{Maybe number the figure and use the numbers in the description to help the reader follow.}
    801771
    802772\begin{figure}
     
    808778
    809779\label{p:zero-cost}
    810 Finally, the resumption implementation has a cost for entering/exiting a @try@
     780Note, the resumption implementation has a cost for entering/exiting a @try@
    811781statement with @catchResume@ clauses, whereas a @try@ statement with @catch@
    812782clauses has zero-cost entry/exit. While resumption does not need the stack
     
    828798around the context of the associated @try@ statement.
    829799
    830 The rest is handled by GCC. The @try@ block and all handlers are inside this
     800The rest is handled by GCC. The try block and all handlers are inside this
    831801block. At completion, control exits the block and the empty object is cleaned
    832802up, which runs the function that contains the finally code.
     
    842812coroutine or thread. Fortunately, the thread library stores the main thread
    843813pointer and the current thread pointer, and every thread stores a pointer to
    844 its coroutine and the coroutine it is currently executing.
    845 If the current thread's main and current coroutines are the same then the
    846 current stack is a thread stack, otherwise it is a coroutine stack.
    847 Note, the runtime considers a thread as a coroutine with an associated user-level thread;
    848 hence, for many operations a thread and coroutine are treated uniformly.
    849 %\todo*{Consider adding a description of how threads are coroutines.}
    850 
    851 % Furthermore it is easy to compare the
    852 % current thread to the main thread to see if they are the same. And if this
    853 % is not a thread stack then it must be a coroutine stack.
     814its main coroutine and the coroutine it is currently executing.
     815\todo*{Consider adding a description of how threads are coroutines.}
     816
     817If a the current thread's main and current coroutines are the same then the
     818current stack is a thread stack. Furthermore it is easy to compare the
     819current thread to the main thread to see if they are the same. And if this
     820is not a thread stack then it must be a coroutine stack.
    854821
    855822However, if the threading library is not linked, the sequential execution is on
    856823the main stack. Hence, the entire check is skipped because the weak-symbol
    857 function is loaded. Therefore, main thread cancellation is unconditionally
     824function is loaded. Therefore, a main thread cancellation is unconditionally
    858825performed.
    859826
    860827Regardless of how the stack is chosen, the stop function and parameter are
    861828passed to the forced-unwind function. The general pattern of all three stop
    862 functions is the same: continue unwinding until the end of stack and
    863 then perform the appropriate transfer.
     829functions is the same: they continue unwinding until the end of stack and
     830then preform their transfer.
    864831
    865832For main stack cancellation, the transfer is just a program abort.
     
    867834For coroutine cancellation, the exception is stored on the coroutine's stack,
    868835and the coroutine context switches to its last resumer. The rest is handled on
    869 the backside of the resume, which checks if the resumed coroutine is
     836the backside of the resume, which check if the resumed coroutine is
    870837cancelled. If cancelled, the exception is retrieved from the resumed coroutine,
    871838and a @CoroutineCancelled@ exception is constructed and loaded with the
    872839cancelled exception. It is then resumed as a regular exception with the default
    873840handler coming from the context of the resumption call.
    874 This semantics allows a cancellation to cascade through an arbitrary set of resumed
    875 coroutines back to the thread's coroutine, performing cleanup along the way.
    876841
    877842For thread cancellation, the exception is stored on the thread's main stack and
     
    883848null (as it is for the auto-generated joins on destructor call), the default is
    884849used, which is a program abort.
    885 This semantics allows a cancellation to cascade through an arbitrary set of joining
    886 threads back to the program's main, performing cleanup along the way.
    887850%; which gives the required handling on implicate join.
  • doc/theses/andrew_beach_MMath/performance.tex

    r2f19e03 rb51e389c  
    66
    77Performance has been of secondary importance for most of this project.
    8 Instead, the goal has been to get the features working.
    9 The only performance
    10 requirements is to ensure the exception tests for correctness ran in a reasonable
     8The driving for has been to get the features working, the only performance
     9requirements were to make sure the tests for correctness rain in a reasonable
    1110amount of time.
    12 Much of the implementation is still reasonable and could be used for similar prototypes.
    13 Hence,
    14 the work still has some use.
    15 To get a rough idea about the \CFA implementation, tests are run on \CFA, C++ and Java, which have similar termination-handling exceptions.
    16 Tests are also run on \CFA and uC++, which has similar resumption-handling exceptions.
     11Still this is an implementation others could use for similar prototypes and
     12so the results still have some use.
    1713
    18 \section{Termination Comparison}
     14\section{Test Set-Up}
     15Tests will be run on \CFA, C++ and Java.
     16
    1917C++ is the most comparable language because both it and \CFA use the same
    2018framework, libunwind.
    21 In fact, the comparison is almost entirely a quality of implementation
     19In fact the comparison is almost entirely a quality of implementation
    2220comparison. \CFA's EHM has had significantly less time to be optimized and
    2321does not generate its own assembly. It does have a slight advantage in that
    2422there are some features it does not handle.
    2523
    26 The Java comparison is an opportunity to compare a managed memory model with unmanaged,
    27 to see if there are any effects related to the exception model.
     24% Some languages I left out:
     25% Python: Its a scripting language, different
     26% uC++: Not well known and should the same results as C++, except for
     27%   resumption which should be the same.
     28\todo{Can we find a good language to compare resumptions in.}
    2829
    29 \subsection{Test Set-Up}
    30 All tests are run inside a main loop that performs the test
    31 repeatedly. This design avoids start-up or tear-down time from
     30All tests will be run inside a main loop which will perform the test
     31repeatedly. This is to avoid letting and start-up or tear-down time from
    3232affecting the timing results.
    33 A consequence is that tests cannot terminate the program, which does limit
     33This also means that tests cannot terminate the program, which does limit
    3434how tests can be implemented. There are catch-alls to keep unhandled
    35 exceptions from terminating tests.
     35exceptions from terminating the program.
    3636
    37 The exceptions used in this test are always a new exception based off of
    38 the base exception. This requirement minimizes performance differences based
     37The exceptions used in this test will always be a new exception based off of
     38the base exception. This should minimize and preformance differences based
    3939on the object model.
    40 Catch-alls are done by catching the root exception type (not using \Cpp's
     40Catch-alls will be done by catching the root exception type (not using \Cpp's
    4141\code{C++}{catch(...)}).
    4242
     
    4444hot.
    4545
    46 \subsection{Tests}
    47 The following tests capture the most important aspects of exception handling and should provide
    48 a reasonable guide to programmers of where EHM costs occur.
    49 
     46\section{Tests}
    5047\paragraph{Raise/Handle}
    5148What is the basic cost to raise and handle an exception?
    5249
    53 There are a number of factors that can effect this.
    54 For \CFA this includes
     50There are a number of factors that can effect this, for \CFA this includes
    5551the type of raise,
    5652
     
    6561This has the same set-up as the raise/handle test except the intermediate
    6662stack frames contain either an object declaration with a destructor or a
    67 @try@ statement with no handlers except and a @finally@ clause.
     63try statement with no handlers except for a finally clause.
    6864
    6965\paragraph{Enter/Leave}
     
    7167is thrown?
    7268
    73 The test is a simple matter of entering
     69This is the simplist pattern to test as it is a simple matter of entering
    7470and leaving a try statement.
    7571
     
    7874
    7975\paragraph{Re-throw and Conditional-Catch}
    80 How expensive it is to run a non-exception type check for a handler?
     76How expencive it is to run a non-exception type check for a handler?
    8177
    8278In this case different languages approach this problem differently, either
    8379through a re-throw or a conditional-catch.
    84 Where \CFA uses its condition, other languages must unconditionally
     80Where \CFA uses its condition other languages will have to unconditionally
    8581catch the exception then re-throw if the condition if the condition is false.
    8682
     
    9086% We could do a Cforall test without the catch all and a new default handler
    9187% that does a catch all.
    92 As a point of comparison, one of the raise/handle tests (which one?) has
     88As a point of comparison one of the raise/handle tests (which one?) has
    9389same layout but never catches anything.
    9490
     
    104100%(I haven't actually figured out how to compare this, probably using something
    105101%related to -fexceptions.)
    106 
    107 
    108 \section{Resumption Comparison}
    109 % Some languages I left out:
    110 % Python: Its a scripting language, different
    111 % uC++: Not well known and should the same results as C++, except for
    112 %   resumption which should be the same.
    113 \todo{Can we find a good language to compare resumptions in.}
Note: See TracChangeset for help on using the changeset viewer.