Changes in / [02a43ff:6312b1c]


Ignore:
Files:
2 added
3 deleted
20 edited

Legend:

Unmodified
Added
Removed
  • doc/theses/andrew_beach_MMath/cfalab.sty

    r02a43ff r6312b1c  
    11% Package for CFA Research Lab.
    2 % (Now more a personal collection and testing grounds for common.sty.)
    32%
    43% This is a collection of commands everyone working on CFA related documents
     
    2423% space and '{}<whatever-follows>' to force remove one.
    2524%
    26 % \CFA
    2725% Cforall with the forall symbol.
    2826\newrobustcmd\CFA{\textsf{C\raisebox{\depth}{\rotatebox{180}{A}}}\xspace}
    29 % \Cpp[<std>]
    30 % C++ symbol name. You may optionally provide <std> to specify a standard.
     27% C++ with kerning. You may optionally append a standard number.
    3128\newrobustcmd\Cpp[1][\xspace]{C++#1}
    3229
     
    4845\newcommand*\colour[2]{{\color{#1}#2}}
    4946
    50 % \code{<language>}{<code>}
    51 % Use the listings package to format the snipit of <code> in <language>.
    52 \newrobustcmd*\code[2]{\lstinline[language=#1]{#2}}
     47% \code*{<code>}
     48% Use the listings package to format a snipit of <code>.
     49\newrobustcmd*\codeCFA[1]{\lstinline[language=CFA]{#1}}
     50\newrobustcmd*\codeC[1]{\lstinline[language=C]{#1}}
     51\newrobustcmd*\codeCpp[1]{\lstinline[language=C++]{#1}}
     52\newrobustcmd*\codePy[1]{\lstinline[language=Python]{#1}}
    5353
    54 % \begin{cfa}[<options>]
    55 % \end{cfa}
    5654% Use the listings package to format a block of CFA code.
    5755% Extra listings options can be passed in as an optional argument.
  • doc/theses/andrew_beach_MMath/features.tex

    r02a43ff r6312b1c  
    2424
    2525Some well known examples include the @throw@ statements of \Cpp and Java and
    26 the \code{Python}{raise} statement from Python. In real systems a raise may
    27 preform some other work (such as memory management) but for the
    28 purposes of this overview that can be ignored.
     26the \codePy{raise} statement from Python. In real systems a raise may preform
     27some other work (such as memory management) but for the purposes of this
     28overview that can be ignored.
    2929
    3030\subparagraph{Handle}
     
    9393A handler labelled with any given exception can handle exceptions of that
    9494type or any child type of that exception. The root of the exception hierarchy
    95 (here \code{C}{exception}) acts as a catch-all, leaf types catch single types
     95(here \codeC{exception}) acts as a catch-all, leaf types catch single types
    9696and the exceptions in the middle can be used to catch different groups of
    9797related exceptions.
     
    182182While much of the virtual infrastructure is created, it is currently only used
    183183internally for exception handling. The only user-level feature is the virtual
    184 cast, which is the same as the \Cpp \code{C++}{dynamic_cast}.
     184cast, which is the same as the \Cpp \codeCpp{dynamic_cast}.
    185185\label{p:VirtualCast}
    186186\begin{cfa}
  • doc/theses/andrew_beach_MMath/implement.tex

    r02a43ff r6312b1c  
    1515\subsection{Virtual Type}
    1616Virtual types only have one change to their structure: the addition of a
    17 pointer to the virtual table, which is called the \emph{virtual-table pointer}.
    18 Internally, the field is called @virtual_table@.
    19 The field is fixed after construction. It is always the first field in the
    20 structure so that its location is always known.
    21 \todo{Talk about constructors for virtual types (after they are working).}
    22 
    23 This is what binds an instance of a virtual type to a virtual table. This
    24 pointer can be used as an identity check. It can also be used to access the
    25 virtual table and the virtual members there.
    26 
    27 \subsection{Type Id}
    28 Every virtual type has a unique id.
    29 Type ids can be compared for equality (the types reperented are the same)
    30 or used to access the type's type information.
    31 The type information currently is only the parent's type id or, if the
    32 type has no parent, zero.
    33 
    34 The id's are implemented as pointers to the type's type information instance.
    35 Derefencing the pointer gets the type information.
    36 By going back-and-forth between the type id and
    37 the type info one can find every ancestor of a virtual type.
    38 It also pushes the issue of creating a unique value (for
    39 the type id) to the problem of creating a unique instance (for type
    40 information) which the linker can solve.
    41 
    42 Advanced linker support is required because there is no place that appears
    43 only once to attach the type information to. There should be one structure
    44 definition but it is included in multiple translation units. Each virtual
    45 table definition should be unique but there are an arbitrary number of thoses.
    46 So the special section prefix \texttt{.gnu.linkonce} is used.
    47 With a unique suffix (making the entire section name unique) the linker will
    48 remove multiple definition making sure only one version exists after linking.
    49 Then it is just a matter of making sure there is a unique name for each type.
    50 
    51 This is done in three phases.
    52 The first phase is to generate a new structure definition to store the type
    53 information. The layout is the same in each case, just the parent's type id,
    54 but the types are changed.
    55 The structure's name is change, it is based off the virtual type's name, and
    56 the type of the parent's type id.
    57 If the virtual type is polymorphic then the type information structure is
    58 polymorphic as well, with the same polymorphic arguments.
    59 
    60 The second phase is to generate an instance of the type information with a
    61 almost unique name, generated by mangling the virtual type name.
    62 
    63 The third phase is implicit with \CFA's overloading scheme. \CFA mangles
    64 names with type information so that all of the symbols exported to the linker
    65 are unique even if in \CFA code they are the same. Having two declarations
    66 with the same name and same type is forbidden because it is impossible for
    67 overload resolution to pick between them. This is why a unique type is
    68 generated for each virtual type.
    69 Polymorphic information is included in this mangling so polymorphic
    70 types will have seperate instances for each set of polymorphic arguments.
    71 
     17pointer to the virtual table, called the \emph{virtual-table pointer}.
     18Internally, the field is called
     19@virtual_table@.
     20This constant pointer is always the first field of the table so when
     21casting to a supertype, the field's location is always known.
     22The field is initialized as part of all generated constructors.
     23\todo{They only come as part exceptions and don't work.}
     24%After the object is created the field is constant.
     25Dereferencing it gives the virtual table and access to the
     26type's virtual members.
     27
     28\subsection{Virtual Table}
     29% PAB: These 2 paragraphs are repeated below, and maybe some of the paragraph above, too.
     30\begin{comment}
     31Every time a virtual type is defined, a new virtual table-type is
     32instantiated.
     33The uniqueness of the virtual-table
     34instance is important because its address
     35is used as the identifier for the virtual type. Hence, a pointer to the
     36virtual table and the ID for the virtual type are interchangeable.
     37\todo{Unique instances might be going so we will have to talk about the new
     38system instead.}
     39
     40The first step is creating the virtual-table type.
     41The virtual-table type is a structure and is described in terms of
     42its fields. The first field contains the parent-type ID (or a pointer to
     43the parent virtual-table) or 0 (null pointer).
     44Next are repeated fields from on the parent virtual-table.
     45Finally, the fields used to store any new virtual members of the new
     46the virtual type.
     47\end{comment}
     48
     49%The virtual system is accessed through a private constant field inserted at the
     50%beginning of every virtual type. This field
     51The virtual-table pointer
     52points at a type's virtual table (see Figure~\vref{f:VirtualTableLayout}).
     53%and is assigned during the object's
     54%construction.
     55The address of a virtual table acts as the unique identifier for
     56the virtual type, and the first field of a virtual table is a pointer to the
     57parent virtual-table or @0p@ (null pointer). The remaining fields are duplicated from the
     58parent tables in this type's inheritance chain, followed by any fields this type
     59introduces. Parent fields are duplicated so they can be changed, \ie all virtual
     60members are overridable, while the parent pointer allows access to the original values.
     61Hence, references to the dispatched type
     62are replaced with the current virtual type.
     63% These are always taken by pointer or reference.
     64
     65\begin{figure}
     66% Simple ascii diragram:
    7267\begin{cfa}
    73 struct /* type name */ {
    74         /* parent type name */ const * parent;
    75 };
    76 
    77 __attribute__((section(".gnu.linkonce./* instance name */")))
    78 /* type name */ const /* instance name */ = {
    79         &/* parent instance name */,
    80 };
    81 \end{cfa}
    82 
    83 \subsection{Virtual Table}
    84 Each virtual type has a virtual table type that stores its type id and
    85 virtual members.
    86 Each virtual type instance is bound to a table instance that is filled with
    87 the values of virtual members.
    88 Both the layout of the fields and their value are decided by the rules given
    89 below.
    90 
    91 The layout always comes in three parts.
    92 The first section is just the type id at the head of the table. It is always
    93 there to ensure that
    94 The second section are all the virtual members of the parent, in the same
    95 order as they appear in the parent's virtual table. Note that the type may
    96 change slightly as references to the ``this" will change. This is limited to
    97 inside pointers/references and via function pointers so that the size (and
    98 hence the offsets) are the same.
    99 The third section is similar to the second except that it is the new virtual
    100 members introduced at this level in the hierarchy.
    101 
    102 \begin{figure}
    103 \begin{cfa}
    104 type_id
    105 parent_field0
     68parent_pointer  // \C{parent pointer to access its fields}
     69parent_field0   // \C{same layout as parent to allow replacement}
    10670...
    10771parent_fieldN
    108 child_field0
     72child_field0    // \C{new types for this virtual table}
    10973...
    11074child_fieldN
     75size
     76alignment
    11177\end{cfa}
     78%\todo{Refine the diagram}
    11279\caption{Virtual Table Layout}
    11380\label{f:VirtualTableLayout}
    114 \todo*{Improve the Virtual Table Layout diagram.}
    11581\end{figure}
    11682
    117 The first and second sections together mean that every virtual table has a
    118 prefix that has the same layout and types as its parent virtual table.
    119 This, combined with the fixed offset to the virtual table pointer, means that
    120 for any virtual type it doesn't matter if we have it or any of its
    121 descendants, it is still always safe to access the virtual table through
    122 the virtual table pointer.
    123 From there it is safe to check the type id to identify the exact type of the
    124 underlying object, access any of the virtual members and pass the object to
    125 any of the method-like virtual members.
    126 \todo{Introduce method-like virtual members.}
    127 
    128 When a virtual table is declared the user decides where to declare it and its
    129 name. The initialization of the virtual table is entirely automatic based on
    130 the context of the declaration.
    131 
    132 The type id is always fixed, each virtual table type will always have one
    133 exactly one possible type id.
    134 The virtual members are usually filled in by resolution. The best match for
    135 a given name and type at the declaration site is filled in.
    136 There are two exceptions to that rule: the @size@ field is the type's size
    137 and is set to the result of a @sizeof@ expression, the @align@ field is the
    138 type's alignment and similarly uses an @alignof@ expression.
    139 
    140 \subsubsection{Concurrency Integration}
     83% For each virtual type, a virtual table is constructed. This is both a new type
     84% and an instance of that type. Other instances of the type could be created
     85% but the system doesn't use them. So this section will go over the creation of
     86% the type and the instance.
     87
     88\begin{comment}
     89PAB: seems to be said already.
     90A virtual table is created when a virtual type is created. The name of the
     91type is created by mangling the name of the base type. The name of the instance
     92is also generated by name mangling. The fields are initialized automatically.
     93The parent field is initialized by getting the type of the parent field and
     94using that to calculate the mangled name of the parent's virtual-table type.
     95\end{comment}
     96There are two special fields that are included like normal fields but have
     97special initialization rules: the @size@ field is the type's size and is
     98initialized with a @sizeof@ expression, the @align@ field is the type's
     99alignment and uses an @alignof@ expression. The remaining fields are resolved
     100to a name matching the field's name and type using the normal visibility and
     101overload resolution rules of the type system.
     102
     103These operations are split up into several groups depending on where they take
     104place, which varies for monomorphic and polymorphic types. The first devision is
     105between the declarations and the definitions. Declarations, such as a function
     106signature or an aggregate's name, must always be visible but may be repeated in
     107the form of forward declarations in headers. Definitions, such as function
     108bodies and a aggregate's layout, can be separately compiled but must occur
     109exactly once in a source file.
     110
     111The declarations include the virtual-type definition and forward declarations
     112of the virtual-table instance, constructor, message function and
     113@get_exception_vtable@. The definition includes the storage and initialization
     114of the virtual table instance and the bodies of the three functions.
     115
     116Monomorphic instances put all of these two groups in one place.
     117Polymorphic instances split out the core declarations and definitions from
     118the per-instance information. The virtual-table type and most of the functions
     119are polymorphic so they are all part of the core. The virtual-table instance
     120and the @get_exception_vtable@ function \PAB{ are ...}.
     121
    141122Coroutines and threads need instances of @CoroutineCancelled@ and
    142123@ThreadCancelled@ respectively to use all of their functionality. When a new
    143 data type is declared with @coroutine@ or @thread@ the forward declaration for
     124data type is declared with @coroutine@ or @thread@, the forward declaration for
    144125the instance is created as well. The definition of the virtual table is created
    145126at the definition of the main function.
    146 \todo{Add an example with code snipits.}
     127
     128\PAB{You need an example here to show what happens for this case.}
     129
    147130
    148131\subsection{Virtual Cast}
     
    151134% The C-cast is just to make sure the generated code is correct so the rest of
    152135% the section is about that function.
    153 The function is implemented in the standard library and has the following
    154 signature:
     136The function is
    155137\begin{cfa}
    156 void * __cfa__virtual_cast(
    157         struct __cfa__parent_vtable const * parent,
     138void * __cfa__virtual_cast( struct __cfa__parent_vtable const * parent,
    158139        struct __cfa__parent_vtable const * const * child );
    159140\end{cfa}
    160 \todo{Get rid of \_\_cfa\_\_parent\_vtable in the standard library and then
    161 the document.}
    162 The type id of target type of the virtual cast is passed in as @parent@ and
    163 the cast target is passed in as @child@.
    164 
    165 For C generation both arguments and the result are wrapped with type casts.
    166 There is also an internal store inside the compiler to make sure that the
    167 target type is a virtual type.
    168 % It also checks for conflicting definitions.
    169 
    170 The virtual cast either returns the original pointer as a new type or null.
    171 So the function just does the parent check and returns the approprate value.
    172 The parent check is a simple linear search of child's ancestors using the
    173 type information.
     141and it is implemented in the standard library. The structure represents the
     142head of a virtual table, which is the pointer to the parent virtual table. The
     143@parent@ points directly at the parent-type virtual-table, while the @child@
     144points at the object of the (possible) child type.
     145
     146\PAB{Need a figure to show this relationship.}
     147
     148In terms of the virtual-cast expression, @parent@ comes from looking up the
     149type being cast to and @child@ is the result of the expression being cast.
     150Because the complier outputs C code, some C-type casts are also used.
     151The last bit of glue is a map that saves every virtual type the compiler
     152sees. This table is used to check the type used in a virtual cast is a virtual
     153type and to get its virtual table.
     154(It also checks for conflicting definitions.)
     155
     156\PAB{Can this be rolled into the figure above?}
     157
     158Inside the function is a simple conditional. If the type represented by
     159@parent@ is an ancestor of the type represented by @*child@ (it
     160requires one more level of dereference to pass through the object) then @child@
     161is returned, otherwise the null pointer is returned.
     162
     163The check is a simple linear search (like \Cpp RTTI). If the child
     164virtual table or any of its ancestors (which are retrieved through the first
     165field of every virtual table) are the same as the parent virtual-table then
     166the cast succeeds.
    174167
    175168\section{Exceptions}
     
    181174% resumption doesn't as well.
    182175
    183 % Many modern languages work with an interal stack that function push and pop
     176% Many modern languages work with an internal stack that function push and pop
    184177% their local data to. Stack unwinding removes large sections of the stack,
    185178% often across functions.
    186179
    187180Stack unwinding is the process of removing stack frames (activations) from the
    188 stack. On function entry and return, unwinding is handled directly by the
    189 call/return code embedded in the function.
    190 In many cases the position of the instruction pointer (relative to parameter
    191 and local declarations) is enough to know the current size of the stack
    192 frame.
    193 
    194 Usually, the stack-frame size is known statically based on parameter and
    195 local variable declarations. Even with dynamic stack-size the information
    196 to determain how much of the stack has to be removed is still contained
    197 within the function.
     181stack. On function entry and return, unwinding is handled directly by the call/return code
     182embedded in a function. Usually, the stack-frame size is known statically
     183based on parameter and local variable declarations. For dynamically-sized
     184local variables.
     185(Often called a variable-length array or VLA, even when the variable type is an aggregate.)
     186For VLAs, a runtime computation is necessary to know the frame
     187size. Finally, a function's frame-size may change during execution as local
     188variables (static or dynamic sized) go in and out of scope, which is a form of VLA.
    198189Allocating/deallocating stack space is usually an $O(1)$ operation achieved by
    199190bumping the hardware stack-pointer up or down as needed.
    200 Constructing/destructing values on the stack takes longer put in terms of
    201 figuring out what needs to be done is of similar complexity.
    202 
    203 Unwinding across multiple stack frames is more complex because that
    204 information is no longer contained within the current function.
    205 With seperate compilation a function has no way of knowing what its callers
    206 are so it can't know how large those frames are.
    207 Without altering the main code path it is also hard to pass that work off
    208 to the caller.
     191
     192Unwinding across multiple stack frames is more complex because individual stack-management
     193code associated with each frame can be bypassed. That is, the location
     194of a function's frame-management code is largely unknown and dispersed
     195throughout the function, hence the current frame size managed by that code is
     196also unknown. Hence, code unwinding across frames does not have direct
     197knowledge about what is on the stack, and hence, how much of the stack needs to
     198be removed.
     199
     200% At a very basic level this can be done with @setjmp@ \& @longjmp@ which simply
     201% move the top of the stack, discarding everything on the stack above a certain
     202% point. However this ignores all the cleanup code that should be run when
     203% certain sections of the stack are removed (for \CFA these are from destructors
     204% and finally clauses) and also requires that the point to which the stack is
     205% being unwound is known ahead of time. libunwind is used to address both of
     206% these problems.
    209207
    210208The traditional unwinding mechanism for C is implemented by saving a snap-shot
     
    213211reseting to a snap-shot of an arbitrary but existing function frame on the
    214212stack. It is up to the programmer to ensure the snap-shot is valid when it is
    215 reset and that all required clean-up from the unwound stacks is preformed.
    216 This approach is fragile and forces a work onto the surounding code.
    217 
    218 With respect to that work forced onto the surounding code,
    219 many languages define clean-up actions that must be taken when certain
    220 sections of the stack are removed. Such as when the storage for a variable
    221 is removed from the stack or when a try statement with a finally clause is
    222 (conceptually) popped from the stack.
    223 None of these should be handled by the user, that would contradict the
    224 intention of these features, so they need to be handled automatically.
    225 
    226 To safely remove sections of the stack the language must be able to find and
    227 run these clean-up actions even when removing multiple functions unknown at
    228 the beginning of the unwinding.
     213reset and that unwound frames do not have side-effects.
     214Hence, this unwinding approach is fragile with potential errors that are
     215difficult to debug because the stack becomes corrupted.
     216
     217With respect to stack side-effects, many languages define cleanup actions that must be taken when objects
     218are deallocated from the stack, when the function of blocks within the function end, such as running a variable's
     219destructor or a @try@ statement's @finally@ clause.
     220The purpose of these side-effects is to reestablish the global state of the program, such as dynamic memory-allocation or file access.
     221Handling these side-effect mechanisms
     222requires walking the stack and checking each stack frame for these potential
     223actions, where a frame can be any block with declarations.
     224
     225In languages like \Cpp and Java, it must be possible to walk the stack frames in search of @try@
     226statements to match and execute a handler. For termination exceptions, it must
     227also be possible to unwind all stack frames from the throw to the matching
     228catch (including the @try@ block), and each of these frames must be checked for cleanup actions. Stack
     229walking is where most of the complexity and expense of exception handling
     230appears.
    229231
    230232One of the most popular tools for stack management is libunwind, a low-level
     
    259261
    260262The GCC compilation flag @-fexceptions@ causes the generation of an LSDA and
    261 attaches a personality function to each function.
    262 In plain C (which \CFA currently compiles down to) this
     263attaches its personality function.
     264It attaches a series of opaque directives (@.cfi_personality@ directive)
     265used internally and not part of this work.
     266However, this
    263267flag only handles the cleanup attribute:
    264268\begin{cfa}
     
    266270int avar __attribute__(( cleanup(clean_up) ));
    267271\end{cfa}
    268 The attribue is used on a variable and specifies a function,
    269 in this case @clean_up@, run when the variable goes out of scope.
    270 This is enough to mimic destructors, but not try statements which can effect
    271 the unwinding.
    272 
    273 To get full unwinding support all of this has to be done directly with
    274 assembly and assembler directives. Partiularly the cfi directives
    275 \texttt{.cfi\_lsda} and \texttt{.cfi\_personality}.
     272that is used on a variable and specifies a function, in this case @clean_up@,
     273run when the variable goes out of scope, which is used to mimic destructors.
     274However, this feature cannot be used to mimic @try@ statements as it cannot
     275control the unwinding.
    276276
    277277\subsection{Personality Functions}
     
    279279section covers some of the important parts of the interface.
    280280
    281 A personality function can preform different actions depending on how it is
     281A personality function can perform different actions depending on how it is
    282282called.
    283283\begin{lstlisting}[language=C,{moredelim=**[is][\color{red}]{@}{@}}]
     
    313313@_UA_FORCE_UNWIND@ specifies a forced unwind call. Forced unwind only performs
    314314the cleanup phase and uses a different means to decide when to stop
    315 (see \vref{s:ForcedUnwind}).
     315(see Section~\vref{s:ForcedUnwind}).
    316316\end{enumerate}
    317317
    318318The @exception_class@ argument is a copy of the
    319 \code{C}{exception}'s @exception_class@ field.
    320 This a number that identifies the exception handling mechanism that created
    321 the
    322 
    323 The \code{C}{exception} argument is a pointer to the user
    324 provided storage object. It has two public fields: the @exception_class@,
    325 which is described above, and the @exception_cleanup@ function.
    326 The clean-up function is used by the EHM to clean-up the exception if it
    327 should need to be freed at an unusual time, it takes an argument that says
    328 why it had to be cleaned up.
     319\lstinline[language=C]|exception|'s @exception_class@ field.
     320\PAB{Say more.}
     321
     322The \lstinline[language=C]|exception| argument is a pointer to the user
     323provided storage object. It has two public fields, the exception class, which
     324is just a number, identifying the exception handling mechanism that
     325created it, and the cleanup function. The cleanup function is called if
     326required by the exception.
    329327
    330328The @context@ argument is a pointer to an opaque type passed to helper
     
    349347@_URC_END_OF_STACK@.
    350348
    351 Second, when a handler is matched, raise exception moves to the clean-up
    352 phase and walks the stack a second time.
     349Second, when a handler is matched, raise exception walks the stack again performing the cleanup
     350phase.
    353351Once again, it calls the personality functions of each stack frame from newest
    354352to oldest. This pass stops at the stack frame containing the matching handler.
     
    405403Each stack must have its own exception context. In a sequential \CFA program,
    406404there is only one stack with a single global exception-context. However, when
    407 the library @libcfathread@ is linked, there are multiple stacks and each
     405the library @libcfathread@ is linked, there are multiple stacks, where each
    408406needs its own exception context.
    409407
    410 The exception context should be retrieved by calling the function
    411 @this_exception_context@. For sequential execution, this function is defined as
     408The function @this_exception_context@ provides general access to the exception context.
     409For sequential execution, this function is defined as
    412410a weak symbol in the \CFA system-library, @libcfa@. When a \CFA program is
    413411concurrent, it links with @libcfathread@, where this function is defined with a
     
    424422% catches. Talk about GCC nested functions.
    425423
    426 \CFA termination exceptions use libunwind heavily because they match \Cpp
     424Termination exceptions use libunwind heavily because \CFA termination exceptions match
    427425\Cpp exceptions closely. The main complication for \CFA is that the
    428426compiler generates C code, making it very difficult to generate the assembly to
     
    432430The first step of a termination raise is to copy the exception into memory
    433431managed by the exception system. Currently, the system uses @malloc@, rather
    434 than reserved memory or the stack top. The exception handling mechanism manages
     432than reserved memory or the stack top. The exception-handling mechanism manages
    435433memory for the exception as well as memory for libunwind and the system's own
    436434per-exception storage.
     
    448446\label{f:ExceptionLayout}
    449447\end{figure}
    450 \todo*{Convert the exception layout to an actual diagram.}
    451 
    452 Exceptions are stored in variable-sized blocks (see \vref{f:ExceptionLayout}).
    453 The first component is a fixed-sized data structure that contains the
     448
     449Exceptions are stored in variable-sized blocks (see Figure~\vref{f:ExceptionLayout}).
     450The first component is a fixed-sized data-structure that contains the
    454451information for libunwind and the exception system. The second component is an
    455452area of memory big enough to store the exception. Macros with pointer arthritic
     
    457454@_Unwind_Exception@ to the entire node.
    458455
    459 Multipe exceptions can exist at the same time because exceptions can be
    460 raised inside handlers, destructors and finally blocks.
    461 Figure~\vref{f:MultipleExceptions} shows a program that has multiple
    462 exceptions active at one time.
    463 Each time an exception is thrown and caught the stack unwinds and the finally
    464 clause runs. This will throw another exception (until @num_exceptions@ gets
    465 high enough) which must be allocated. The previous exceptions may not be
    466 freed because the handler/catch clause has not been run.
    467 So the EHM must keep them alive while it allocates exceptions for new throws.
     456Multiple exceptions can exist because handlers can call functions that raise
     457exceptions.  Figure~\vref{f:MultipleExceptions} shows a \Cpp program where
     458exceptions are handled, and then a function is called from the handler that
     459raises a new exception. The previous exception must persist because it is
     460unhandled, and hence, control can return to the handler and that exception is
     461reraised.
    468462
    469463\begin{figure}
    470464\centering
    471 % Andrew: Figure out what these do and give them better names.
    472465\newsavebox{\myboxA}
    473466\newsavebox{\myboxB}
    474467\begin{lrbox}{\myboxA}
    475 \begin{lstlisting}[language=CFA,{moredelim=**[is][\color{red}]{@}{@}}]
    476 unsigned num_exceptions = 0;
    477 void throws() {
    478     try {
    479         try {
    480             ++num_exceptions;
    481             throw (Example){table};
    482         } finally {
    483             if (num_exceptions < 3) {
    484                 throws();
    485             }
    486         }
    487     } catch (exception_t *) {
    488         --num_exceptions;
    489     }
     468\begin{lstlisting}[language=C++,{moredelim=**[is][\color{red}]{@}{@}}]
     469struct E {};
     470int cnt = 3;
     471void f( int i ) {
     472        if ( i == 0 ) @throw E();@
     473        try {
     474                @f( i - 1 );@
     475        } catch( E ) { // handler h
     476                cnt -= 1;
     477                if ( cnt > 0 ) @f( 2 );@
     478        }
    490479}
    491 int main() {
    492     throws();
    493 }
     480int main() { @f( 2 );@ }
    494481\end{lstlisting}
    495482\end{lrbox}
     
    497484\begin{lrbox}{\myboxB}
    498485\begin{lstlisting}
     486h  $\makebox[0pt][l]{\textbackslash}f$
     487   f
     488   f
     489h  $\makebox[0pt][l]{\textbackslash}f$  throw E$\(_2\)$
     490   f
     491   f
     492h  $\makebox[0pt][l]{\textbackslash}f$  throw E$\(_1\)$
     493   f
     494   f
    499495\end{lstlisting}
    500496\end{lrbox}
     
    507503\label{f:MultipleExceptions}
    508504\end{figure}
    509 \todo*{Work on multiple exceptions code sample.}
    510 
    511 All exceptions are stored in nodes which are then linked together in lists,
    512 one list per stack, with the
     505
     506In this case, the exception nodes are linked together in a list, one list per stack, with the
    513507list head stored in the exception context. Within each linked list, the most
    514508recently thrown exception is at the head followed by older thrown
     
    521515exception, the copy function, and the free function, so they are specific to an
    522516exception type. The size and copy function are used immediately to copy an
    523 exception into managed memory. After the exception is handled, the free
    524 function is used to clean up the exception and then the entire node is
    525 passed to free so the memory can be given back to the heap.
     517exception into managed memory. After the exception is handled, the free function
     518is used to clean up the exception and then the entire node is passed to free
     519so the memory can be given back to the heap.
    526520
    527521\subsection{Try Statements and Catch Clauses}
    528522The try statement with termination handlers is complex because it must
    529 compensate for the lack of assembly-code generated from \CFA. Libunwind
     523compensate for the lack of assembly code generated from \CFA. Libunwind
    530524requires an LSDA and personality function for control to unwind across a
    531525function. The LSDA in particular is hard to mimic in generated C code.
     
    536530calls them.
    537531Because this function is known and fixed (and not an arbitrary function that
    538 happens to contain a try statement), the LSDA can be generated ahead
     532happens to contain a try statement), this means the LSDA can be generated ahead
    539533of time.
    540534
    541535Both the LSDA and the personality function are set ahead of time using
    542 embedded assembly. This assembly code is handcrafted using C @asm@ statements
    543 and contains
    544 enough information for the single try statement the function repersents.
     536embedded assembly. This assembly code is handcrafted using C @asm@ statements and contains
     537enough information for the single try statement the function represents.
    545538
    546539The three functions passed to try terminate are:
     
    570563nested functions and all other functions besides @__cfaehm_try_terminate@ in
    571564\CFA use the GCC personality function and the @-fexceptions@ flag to generate
    572 the LSDA.
    573 Using this pattern, \CFA implements destructors with the cleanup attribute.
    574 \todo{Add an example of the conversion from try statement to functions.}
     565the LSDA. Through this mechanism, \CFA destructors are implemented via the cleanup attribute.
     566
     567\PAB{Try to put together an example try statement illustrating these components.}
    575568
    576569\section{Resumption}
    577570% The stack-local data, the linked list of nodes.
    578571
    579 Resumption simpler to implement than termination
    580 because there is no stack unwinding.
    581 Instead of storing the data in a special area using assembly,
    582 there is just a linked list of possible handlers for each stack,
    583 with each node on the list reperenting a try statement on the stack.
    584 
    585 The head of the list is stored in the exception context.
    586 The nodes are stored in order, with the more recent try statements closer
    587 to the head of the list.
    588 Instead of traversing the stack resumption handling traverses the list.
    589 At each node the EHM checks to see if the try statement the node repersents
    590 can handle the exception. If it can, then the exception is handled and
    591 the operation finishes, otherwise the search continues to the next node.
    592 If the search reaches the end of the list without finding a try statement
    593 that can handle the exception the default handler is executed and the
    594 operation finishes.
    595 
    596 In each node is a handler function which does most of the work there.
    597 The handler function is passed the raised the exception and returns true
    598 if the exception is handled and false if it cannot be handled here.
    599 
    600 For each @catchResume@ clause the handler function will:
    601 check to see if the raised exception is a descendant type of the declared
    602 exception type, if it is and there is a conditional expression then it will
    603 run the test, if both checks pass the handling code for the clause is run
    604 and the function returns true, otherwise it moves onto the next clause.
    605 If this is the last @catchResume@ clause then instead of moving onto
    606 the next clause the function returns false as no handler could be found.
    607 
    608 \todo{Diagram showing a try statement being converted into resumption handlers.}
     572Resumption is simpler to implement than termination because there is no stack
     573unwinding.  \PAB{You need to explain how the \lstinline{catchResume} clauses are
     574handled. Do you use the personality mechanism in libunwind or do you roll your
     575own mechanism?}
     576
     577The
     578resumption raise uses a list of nodes for its stack traversal. The head of the
     579list is stored in the exception context. The nodes in the list have a pointer
     580to the next node and a pointer to the handler function.
     581A resumption raise traverses this list. At each node the handler function is
     582called, passing the exception by pointer. It returns true if the exception is
     583handled and false otherwise.
     584
     585The handler function does both the matching and handling. It computes the
     586condition of each @catchResume@ in top-to-bottom order, until it finds a
     587handler that matches. If no handler matches then the function returns
     588false. Otherwise the matching handler is run; if it completes successfully, the
     589function returns true. Rethrowing, through the @throwResume;@ statement,
     590causes the function to return true.
    609591
    610592% Recursive Resumption Stuff:
     
    621603the other handler checked up to this point are not checked again.
    622604
    623 This structure also supports new handler added while the resumption is being
     605This structure also supports new handlers added while the resumption is being
    624606handled. These are added to the front of the list, pointing back along the
    625607stack -- the first one points over all the checked handlers -- and the ordering
    626608is maintained.
    627 \todo{Add a diagram for resumption marking.}
     609
     610\PAB{Again, a figure to show how this works would be helpful.}
    628611
    629612\label{p:zero-cost}
     
    640623% that unwind is required knowledge for that chapter.
    641624
     625\PAB{This paragraph needs to be moved to the start of this Section, where I have have my other comment.}
     626
    642627\section{Finally}
    643628% Uses destructors and GCC nested functions.
    644 A finally clause is placed into a GCC nested-function with a unique name,
    645 and no arguments or return values.
    646 This nested function is then set as the cleanup
     629A finally clause is placed into a GCC nested-function with a unique mangled name, and no
     630arguments or return values. This nested function is then set as the cleanup
    647631function of an empty object that is declared at the beginning of a block placed
    648 around the context of the associated @try@ statement.
     632around the context of an associated @try@ statement.
    649633
    650634The rest is handled by GCC. The try block and all handlers are inside this
     
    656640
    657641Cancellation also uses libunwind to do its stack traversal and unwinding,
    658 however it uses a different primary function: @_Unwind_ForcedUnwind@. Details
    659 of its interface can be found in the Section~\vref{s:ForcedUnwind}.
     642however it uses a different primary function, @_Unwind_ForcedUnwind@. Details
     643of its interface can be found in Section~\vref{s:ForcedUnwind}.
    660644
    661645The first step of cancellation is to find the cancelled stack and its type:
    662 coroutine or thread. Fortunately, the thread library stores the main thread
    663 pointer and the current thread pointer, and every thread stores a pointer to
    664 its main coroutine and the coroutine it is currently executing.
    665 \todo*{Consider adding a description of how threads are coroutines.}
    666 
    667 If a the current thread's main and current coroutines are the same then the
    668 current stack is a thread stack. Furthermore it is easy to compare the
    669 current thread to the main thread to see if they are the same. And if this
    670 is not a thread stack then it must be a coroutine stack.
    671 
     646coroutine or thread. Fortunately, the thread library stores the program-main thread
     647pointer and the current-thread pointer, and every thread stores a pointer to
     648the current coroutine it is executing.
     649
     650\PAB{I don't know if my corrections in the previous paragraph are correct.}
     651
     652When the active thread and coroutine are the same, the current stack is the thread stack, otherwise it is a coroutine
     653stack.
     654% PAB: repeated?
     655% If it is a thread stack, then an equality check with the stored main
     656% thread pointer and current thread pointer is enough to tell if the current
     657% thread is the main thread or not.
    672658However, if the threading library is not linked, the sequential execution is on
    673659the main stack. Hence, the entire check is skipped because the weak-symbol
     
    677663Regardless of how the stack is chosen, the stop function and parameter are
    678664passed to the forced-unwind function. The general pattern of all three stop
    679 functions is the same: they continue unwinding until the end of stack and
    680 then preform their transfer.
    681 
     665functions is the same: continue unwinding until the end of stack.
     666%when they
     667%do there primary work.
    682668For main stack cancellation, the transfer is just a program abort.
    683669
    684 For coroutine cancellation, the exception is stored on the coroutine's stack,
     670For coroutine cancellation, the exception is stored in the coroutine's stack,
    685671and the coroutine context switches to its last resumer. The rest is handled on
    686672the backside of the resume, which check if the resumed coroutine is
  • doc/theses/andrew_beach_MMath/uw-ethesis.tex

    r02a43ff r6312b1c  
    9393% Removes large sections of the document.
    9494\usepackage{comment}
    95 % Adds todo commands.
    96 \usepackage{todo}
     95% Adds todos (Must be included after comment.)
     96\usepackage{todonotes}
    9797% cfa macros used in the document
    9898\usepackage{cfalab}
     
    145145
    146146% Exception to the rule of hyperref being the last add-on package
    147 \usepackage[toc,abbreviations]{glossaries-extra}
     147\usepackage[automake,toc,abbreviations]{glossaries-extra}
    148148% If glossaries-extra is not in your LaTeX distribution, get it from CTAN
    149149% (http://ctan.org/pkg/glossaries-extra), although it's supposed to be in
     
    235235% Tip: Putting each sentence on a new line is a way to simplify later editing.
    236236%----------------------------------------------------------------------
    237 \input{intro}
    238237\input{existing}
    239238\input{features}
    240239\input{implement}
     240%\input{unwinding}
    241241\input{future}
    242242
     
    298298\phantomsection         % allows hyperref to link to the correct page
    299299
    300 \todos
    301 
    302300%----------------------------------------------------------------------
    303301\end{document} % end of logical document
  • doc/theses/mubeen_zulfiqar_MMath/allocator.tex

    r02a43ff r6312b1c  
     1
    12\chapter{Allocator}
    2 
    3 ====================
    4 
    5 Writing Points:
    6 
    7 Objective of uHeapLmmm.
    8 Design philosophy.
    9 Background and previous design of uHeapLmmm.
    10 
    11 Distributed design of uHeapLmmm.
    12 ----- SHOULD WE GIVE IMPLEMENTATION DETAILS HERE? -----
    13 > figure.
    14 > Advantages of distributed design.
    15 
    16 The new features added to uHeapLmmm (incl. malloc_size routine)
    17 CFA alloc interface with examples.
    18 > Why did we need it?
    19 > The added benefits.
    20 ----- SHOULD WE GIVE PERFORMANCE AND USABILITY COMPARISON OF DIFFERENT INTERFACES THAT WE TRIED? -----
    21 
    22 Performance evaluation using u-benchmark suite.
    23 
    24 ====================
    253
    264\newpage
  • doc/theses/mubeen_zulfiqar_MMath/background.tex

    r02a43ff r6312b1c  
    11\chapter{Background}
    22
    3 ====================
    4 
    5 Writing Points:
    6 
    7 Classification of benchmarks.
    8 Literature review of current benchmarks.
    9 Features and limitations.
    10 
    11 Literature review of current memory allocators.
    12 Breakdown of memory allocation techniques.
    13 Fetures and limitations.
    14 
    15 ====================
    16 
    173\cite{Wasik08}
  • doc/theses/mubeen_zulfiqar_MMath/benchmarks.tex

    r02a43ff r6312b1c  
    11\chapter{Benchmarks}
    2 
    3 ====================
    4 
    5 Writing Points:
    6 
    7 Performance matrices of memory allocation.
    8 
    9 Aim of micro benchmark suite.
    10 ----- SHOULD WE GIVE IMPLEMENTATION DETAILS HERE? -----
    11 A complete list of benchmarks in micro benchmark suite.
    12 
    13 One detailed section for each benchmark in micro benchmark suite including:
    14 > The introduction of the benchmark.
    15 > Figure.
    16 > Results with popular memory allocators.
    17 
    18 Summarize performance of current memory allocators.
    19 
    20 ====================
  • doc/theses/mubeen_zulfiqar_MMath/conclusion.tex

    r02a43ff r6312b1c  
    11\chapter{Conclusion}
    2 
    3 ====================
    4 
    5 Writing Points:
    6 
    7 Summarize u-benchmark suite.
    8 Summarize uHeapLmmm.
    9 Make recommendations on memory allocator design.
    10 
    11 ====================
  • doc/theses/mubeen_zulfiqar_MMath/intro.tex

    r02a43ff r6312b1c  
    11\chapter{Introduction}
    2 
    3 ====================
    4 
    5 Writing Points:
    6 
    7 Introduce dynamic memory allocation with brief background.
    8 Scope of the thesis.
    9 Importance of memory allocation and micro benhmark suite.
    10 
    11 Research problem.
    12 Research objectives.
    13 The vision behind cfa-malloc.
    14 
    15 An outline of the thesis.
    16 
    17 ====================
  • libcfa/src/concurrency/alarm.cfa

    r02a43ff r6312b1c  
    5555        this.period  = period;
    5656        this.thrd = thrd;
    57         this.timeval = __kernel_get_time() + alarm;
    5857        set = false;
    5958        type = User;
     
    6463        this.period  = period;
    6564        this.proc = proc;
    66         this.timeval = __kernel_get_time() + alarm;
    6765        set = false;
    6866        type = Kernel;
    6967}
    7068void ?{}( alarm_node_t & this, Alarm_Callback callback, Duration alarm, Duration period ) with( this ) {
    71         this.callback = callback;
    7269        this.initial = alarm;
    7370        this.period  = period;
    74         this.timeval = __kernel_get_time() + alarm;
     71        this.callback = callback;
    7572        set = false;
    7673        type = Callback;
     
    113110        lock( event_kernel->lock __cfaabi_dbg_ctx2 );
    114111        {
     112                Time curr = __kernel_get_time();
     113                this->timeval = curr + this->initial;
     114
    115115                /* paranoid */ verify( validate( alarms ) );
    116116
    117                 Time curr = __kernel_get_time();
    118117                __cfadbg_print_safe( preemption, " KERNEL: alarm inserting %p (%lu -> %lu).\n", this, curr.tn, this->timeval.tn );
    119118                insert( &alarms, this );
    120                 __kernel_set_timer( this->timeval - curr);
     119                __kernel_set_timer( this->initial );
    121120                this->set = true;
    122121        }
  • libcfa/src/concurrency/locks.cfa

    r02a43ff r6312b1c  
    188188                alarm_node_t alarm_node;
    189189                condition_variable(L) * cond;
    190                 info_thread(L) * info_thd;
     190                info_thread(L) * i;
    191191        };
    192192
     
    194194                this.alarm_node{ callback, alarm, period };
    195195                this.cond = c;
    196                 this.info_thd = i;
     196                this.i = i;
    197197        }
    198198
     
    206206                //      may still be called after a thread has been removed from the queue but
    207207                //      before the alarm is unregistered
    208                 if ( listed(info_thd) ) {       // is thread on queue
    209                         info_thd->signalled = false;
     208                if ( listed(i) ) {      // is thread on queue
     209                        i->signalled = false;
    210210                        // remove this thread O(1)
    211                         remove( cond->blocked_threads, *info_thd );
     211                        remove( cond->blocked_threads, *i );
    212212                        cond->count--;
    213                         if( info_thd->lock ) {
     213                        if( i->lock ) {
    214214                                // call lock's on_notify if a lock was passed
    215                                 on_notify(*info_thd->lock, info_thd->t);
     215                                on_notify(*i->lock, i->t);
    216216                        } else {
    217217                                // otherwise wake thread
    218                                 unpark( info_thd->t );
     218                                unpark( i->t );
    219219                        }
    220220                }
  • libcfa/src/exception.c

    r02a43ff r6312b1c  
    4848
    4949// Base Exception type id:
    50 struct __cfavir_type_info __cfatid_exception_t = {
     50struct __cfa__parent_vtable __cfatid_exception_t = {
    5151        NULL,
    5252};
  • libcfa/src/exception.h

    r02a43ff r6312b1c  
    2929struct __cfaehm_base_exception_t;
    3030typedef struct __cfaehm_base_exception_t exception_t;
    31 struct __cfavir_type_info;
     31struct __cfa__parent_vtable;
    3232struct __cfaehm_base_exception_t_vtable {
    33         const struct __cfavir_type_info * __cfavir_typeid;
     33        const struct __cfa__parent_vtable * __cfavir_typeid;
    3434        size_t size;
    3535        void (*copy)(struct __cfaehm_base_exception_t *this,
     
    4141        struct __cfaehm_base_exception_t_vtable const * virtual_table;
    4242};
    43 extern struct __cfavir_type_info __cfatid_exception_t;
     43extern struct __cfa__parent_vtable __cfatid_exception_t;
    4444
    4545
  • libcfa/src/exception.hfa

    r02a43ff r6312b1c  
    157157#define _EHM_TYPE_ID_STRUCT(exception_name, forall_clause) \
    158158        forall_clause _EHM_TYPE_ID_TYPE(exception_name) { \
    159                 __cfavir_type_info const * parent; \
     159                __cfa__parent_vtable const * parent; \
    160160        }
    161161
  • libcfa/src/iostream.cfa

    r02a43ff r6312b1c  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat May 15 09:39:21 2021
    13 // Update Count     : 1342
     12// Last Modified On : Tue Apr 27 18:01:03 2021
     13// Update Count     : 1330
    1414//
    1515
     
    659659                        int exp10, len2; \
    660660                        eng( f.val, f.pc, exp10 );                                      /* changes arguments */ \
    661                         /* printf( "%g %d %d %d %s\n", f.val, f.wd, f.pc, exp10, format ); */ \
    662661                        if ( ! f.flags.left && f.wd > 1 ) { \
    663                                 /* Exponent size: 'e', optional minus sign, number of digits: log10(0) => undefined */ \
    664                                 f.wd -= 1 + (exp10 < 0 ? 1 : 0) + lrint( floor( exp10 == 0 ? 0 : log10( abs( exp10 ) ) ) ) + 1; \
     662                                /* Exponent size (number of digits, 'e', optional minus sign) */ \
     663                                f.wd -= lrint( floor( log10( abs( exp10 ) ) ) ) + 1 + 1 + (exp10 < 0 ? 1 : 0); \
    665664                                if ( f.wd < 1 ) f.wd = 1; \
    666665                        } /* if */ \
     
    709708                if ( ! f.flags.pc ) {                                                   /* no precision */ \
    710709                        fmtstr[sizeof(DFMTNP)-2] = f.base;                      /* sizeof includes '\0' */ \
    711                         /* printf( "%g %d %s\n", f.val, f.wd, &fmtstr[star] ); */ \
     710                        /* printf( "%g %d %s\n", f.val, f.wd, &fmtstr[star]); */ \
    712711                        PrintWithDP2( os, &fmtstr[star], f.wd, f.val ) \
    713712                } else {                                                                                /* precision */ \
  • libcfa/src/virtual.c

    r02a43ff r6312b1c  
    1010// Created On       : Tus Jul 11 15:10:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Mon May 17 11:01:00 2021
    13 // Update Count     : 2
     12// Last Modified On : Wed Jul 26 14:24:00 2017
     13// Update Count     : 1
    1414//
    1515
     
    1717#include "assert.h"
    1818
    19 int __cfavir_is_parent(
    20                 __cfavir_type_id parent,
    21                 __cfavir_type_id child ) {
     19int __cfa__is_parent( struct __cfa__parent_vtable const * parent,
     20        struct __cfa__parent_vtable const * child ) {
    2221        assert( child );
    2322        do {
     
    2928}
    3029
    31 void * __cfavir_virtual_cast(
    32                 __cfavir_type_id parent,
    33                 __cfavir_type_id const * child ) {
     30void * __cfa__virtual_cast( struct __cfa__parent_vtable const * parent,
     31        struct __cfa__parent_vtable const * const * child ) {
    3432        assert( child );
    35         return (__cfavir_is_parent(parent, *child)) ? (void *)child : (void *)0;
     33        return (__cfa__is_parent(parent, *child)) ? (void *)child : (void *)0;
    3634}
  • libcfa/src/virtual.h

    r02a43ff r6312b1c  
    1010// Created On       : Tus Jul 11 15:08:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Mon May 17 11:03:00 2021
    13 // Update Count     : 2
     12// Last Modified On : Wed Jul 26 14:18:00 2017
     13// Update Count     : 1
    1414//
    1515
     
    2020#endif
    2121
    22 // Information on a type for the virtual system.
    23 // There should be exactly one instance per type and there should be a
    24 // pointer to it at the head of every virtual table.
    25 struct __cfavir_type_info {
    26         // Type id of parent type, null if this is a root type.
    27     struct __cfavir_type_info const * const parent;
     22// All strict/explicate vtables should have this head, showing their parent.
     23struct __cfa__parent_vtable {
     24    struct __cfa__parent_vtable const * const parent;
    2825};
    2926
    30 // A pointer to type information acts as the type id.
    31 typedef struct __cfavir_type_info const * __cfavir_type_id;
    32 
    33 // Takes in two non-null type ids.
    34 int __cfavir_is_parent(
    35                 __cfavir_type_id parent, __cfavir_type_id child );
     27// Takes in two non-null pointers to type_objects.
     28int __cfa__is_parent( struct __cfa__parent_vtable const * parent,
     29                struct __cfa__parent_vtable const * child );
    3630
    3731// If parent is a parent of child then return child, otherwise return NULL.
    3832// Input pointers are none-null, child's first level should be an object with
    3933// a vtable
    40 void * __cfavir_virtual_cast(
    41                 __cfavir_type_id parent, __cfavir_type_id const * child );
     34void * __cfa__virtual_cast( struct __cfa__parent_vtable const * parent,
     35                struct __cfa__parent_vtable const * const * child );
    4236
    4337#ifdef __cforall
  • src/Virtual/ExpandCasts.cc

    r02a43ff r6312b1c  
    105105        void VirtualCastCore::premutate( FunctionDecl * functionDecl ) {
    106106                if ( (! vcast_decl) &&
    107                      functionDecl->get_name() == "__cfavir_virtual_cast" ) {
     107                     functionDecl->get_name() == "__cfa__virtual_cast" ) {
    108108                        vcast_decl = functionDecl;
    109109                }
     
    113113                if ( pvt_decl || ! structDecl->has_body() ) {
    114114                        return;
    115                 } else if ( structDecl->get_name() == "__cfavir_type_info" ) {
     115                } else if ( structDecl->get_name() == "__cfa__parent_vtable" ) {
    116116                        pvt_decl = structDecl;
    117117                }
  • tests/exceptions/virtual-cast.cfa

    r02a43ff r6312b1c  
    1616// Hand defined alpha virtual type:
    1717struct __cfatid_struct_alpha {
    18         __cfavir_type_info parent;
     18        __cfa__parent_vtable const * parent;
    1919};
    2020
    21 __attribute__(( cfa_linkonce ))
     21__attribute__(( section(".gnu.linkonce.__cfatid_alpha") ))
    2222struct __cfatid_struct_alpha __cfatid_alpha = {
    23         (__cfavir_type_info *)0,
     23        (__cfa__parent_vtable *)0,
    2424};
    2525
  • tests/exceptions/virtual-poly.cfa

    r02a43ff r6312b1c  
    1010
    1111struct __cfatid_struct_mono_base {
    12     __cfavir_type_info const * parent;
     12    __cfa__parent_vtable const * parent;
    1313};
    1414
    15 __attribute__(( cfa_linkonce ))
     15__attribute__(( section(".gnu.linkonce.__cfatid_mono_base") ))
    1616struct __cfatid_struct_mono_base __cfatid_mono_base = {
    17     (__cfavir_type_info *)0,
     17    (__cfa__parent_vtable *)0,
    1818};
    1919
     
    5858forall(U)
    5959struct __cfatid_struct_poly_base {
    60     __cfavir_type_info const * parent;
     60    __cfa__parent_vtable const * parent;
    6161};
    6262
     
    8787
    8888__cfatid_struct_poly_base(int) __cfatid_poly_base @= {
    89         (__cfavir_type_info *)0,
     89        (__cfa__parent_vtable *)0,
    9090};
    9191__cfatid_struct_poly_child(int) __cfatid_poly_child = {
Note: See TracChangeset for help on using the changeset viewer.