From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,9bf8bfc34e223b4d X-Google-Attributes: gid103376,public From: stt@houdini.camb.inmet.com (Tucker Taft) Subject: Re: GNAT controlled types Date: 1998/01/29 Message-ID: #1/1 X-Deja-AN: 320157434 Sender: news@inmet.camb.inmet.com (USENET news) References: X-Nntp-Posting-Host: houdini.camb.inmet.com Organization: Intermetrics, Inc. Newsgroups: comp.lang.ada Date: 1998-01-29T00:00:00+00:00 List-Id: 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