comp.lang.ada
 help / color / mirror / Atom feed
From: stt@houdini.camb.inmet.com (Tucker Taft)
Subject: Re: GNAT controlled types
Date: 1998/01/29
Date: 1998-01-29T00:00:00+00:00	[thread overview]
Message-ID: <EnIzsA.9C9.0.-s@inmet.camb.inmet.com> (raw)
In-Reply-To: Pine.BSF.3.96.980128145319.2158A-100000@shell5.ba.best.com


Brian Rogoff (bpr@shell5.ba.best.com) wrote:

: On Wed, 28 Jan 1998, Tucker Taft wrote:
: > 
: > The decision to base controlled types on type extension was an attempt
: > to ensure a relatively straightforward implementation, where the
: > root controlled type would contain links for inserting the controlled
: > object on a linked list.  Ultimately, other considerations (such as
: > "mutable" discriminated types) pushed us to abandon the 
: > links-through-the-object implementation model in our Ada 95 front end,
: > but I believe other compilers have taken advantage of the type
: > extension approach.

: Could you elaborate a bit more on why you switched implementation models, 
: and how your front end implements them now? 

We originally planned to link all controlled objects, including components
of other objects, together in a linked list hanging off a per-stack-frame
list header.  Now we create separate objects called "cleanup records",
which point to objects with any components requiring cleanup.  There
are several different kinds of cleanup records, one for a simple
controlled object, one for an array of controlled objects, one for
a heap of controlled objects, etc.  If a single local variable contains
multiple controlled components, the compiler synthesizes an overall
cleanup routine, and the cleanup record points to the local variable,
and to the synthesized cleanup routine.

There were two main reasons we went away from having each individual
controlled object or subcomponent on a linked list.  The first
had to do with "mutable" discriminated objects.  With mutable
discriminated object, such as a variant record with defaulted
discriminants, and assignment can have the effect of causing some
(potentially controlled) components go away, and others to come
into existence.  This meant that an assignment statement might
involve an arbitrary amount of delinking and relinking of
controlled subcomponents.  It also implied that the list of
controlled objects would have to be doubly linked rather than singly
linked, since we would have to remove and insert objects at
the middle of the list.

The second reason is that we decided that interoperability with
C++ would be reduced if every individual controlled object needed
to be linked onto a list.  "Early" C++ lacked exceptions, and
I'm not sure what C++ does with unions containing objects
with destructors, meaning that there were relatively easy
mechanisms for knowing what destructors needed to be
performed.  In any case, most C++ compilers still use "external"
information to keep track of what destructors need to be executed
at any given time, rather than linking the individual objects together.
This "external" information might be a linked list of something
like our cleanup records, or it might be mechanisms based on
counters which keep track of which destructors need to be performed.
objects, nor standard multithreading.
(still not part of the standard).
Probably the major rea

: ... I used to hold the same view 
: as Nick, i.e. that this conflation of Controlled-ness and tagged-ness was
: a flaw, and I changed my mind after trying to figure out alternative
: approaches. 

When we almost had everything working (now we really almost have everything
working ;-), we looked at the complexity of our cleanup record management,
and we pined for the "simplicity" of linking individual objects.
However, our cleanup record mechanism is now quite
robust, and we have found it able to handle all of the various
feature interactions involving exceptions, finalization, functions 
with unconstrained result subtypes, protected types, classwide types 
in the heap, abort and async transfer of control, etc.  It is fairly 
efficient, though there are probably even more complex schemes that 
could be cooked up which would be somewhat more efficient.

We definitely take advantage of the fact that all user-defined
finalization routines are library-level procedures.  If we had
to worry about static links or global displays for user-defined
finalization routines, it could really do us in.  So even though
we don't take advantage of type extension directly, we do take
advantage of the requirement that all controlled types be defined
at the library level.  The benefit of that requirement is reduced
somewhat by the fact that record types requiring compiler-synthesized
cleanup routines can be defined at a nested level.  However, we have
more control over those and we can avoid the need for a static link
parameter or a properly managed global display in the synthesized routines.

: -- Brian

--
-Tucker Taft   stt@inmet.com   http://www.inmet.com/~stt/
Intermetrics, Inc.  Burlington, MA  USA




  reply	other threads:[~1998-01-29  0:00 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1998-01-25  0:00 GNAT errormessage question Haug Buerger
     [not found] ` <EnCrzw.EHw@world.std.com>
1998-01-26  0:00   ` GNAT controlled types Nick Roberts
1998-01-26  0:00     ` Jon S Anthony
     [not found]     ` <EnEu4B.6rr@world.std.com>
1998-01-27  0:00       ` Nick Roberts
1998-01-28  0:00         ` Tucker Taft
1998-01-28  0:00           ` Brian Rogoff
1998-01-29  0:00             ` Tucker Taft [this message]
1998-02-01  0:00               ` Robert Dewar
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox