CVS difference for ai05s/ai05-0111-3.txt
--- ai05s/ai05-0111-3.txt 2010/10/14 06:43:25 1.1
+++ ai05s/ai05-0111-3.txt 2010/10/19 03:51:17 1.2
@@ -1,4 +1,4 @@
-!standard 4.8(2) 10-10-13 AI05-0111-3/01
+!standard 4.8(2) 10-10-14 AI05-0111-3/02
!standard 4.8(3/2)
!standard 4.8(10.3/2)
!standard 13.11(16/3)
@@ -83,8 +83,17 @@
If the allocator includes a subpool_handle_name, the allocator raises
Program_Error if the subpool is non-null and does not *belong* (see 13.11.4)
- to any storage pool.
+ to the storage pool of the access type of the allocator.
+ AARM Implementation Note: This can be implemented by comparing the result of
+ Pool_of_Subpool to a reference to the storage pool object.
+
+ AARM Reason: This detects cases where the subpool belongs to another pool, or to
+ no pool at all. This includes detecting dangling subpool handles so long as the
+ subpool object (the object designated by the handle) still exists. (If the
+ subpool object has been deallocated, execution is erroneous; it is likely that
+ this check will still detect the problem, but there cannot be a guarentee.)
+
Modify 13.11(16/3):
An allocator of type T {without a subpool_specification} allocates
@@ -120,6 +129,7 @@
-- to clients.
type Subpool_Handle is access all Root_Subpool'Class;
+ for Subpool_Handle'Storage_Size use 0;
-- This provides a reference to a subpool, and serves to identify
-- the subpool within the program.
@@ -177,7 +187,8 @@
which is a storage pool whose type is descended from Root_Storage_Pool_with_Subpools.
When an allocator with a subpool_specification is evaluated, a call is made on
Allocate_From_Subpool passing in the given Subpool_Handle, in addition to the
-parameters as defined for calls on Allocate (see 13.11).
+parameters as defined for calls on Allocate (see 13.11). All requirements on
+the Allocate procedure also apply to Allocate_from_Subpool.
[Redundant: There is a master associated with the execution of certain
constructs (see 7.6.1),] called a *construct master*. In addition, each
@@ -221,15 +232,25 @@
[Editor's note: Tucker had this rule here, but I suspect that we have
to put it into 3.10.2. That would make it more complicated; I've left it
-here for now.]
+here for now.
+Editor's note for version /2: I'm not sure that we really need this rule.
+I left it for now, but note that it makes it impossible to use anonyomous
+access types to work around the ordering rule. As this is intended to
+be exactly as safe as Unchecked_Deallocation (for which there is no
+special restriction), I don't off-hand know of any need for it.]
+
The *latest subtype with a non-static constraint* of a subtype S is:
- * S; if S is a first subtype;
+ * the completion of S; if S is the first subtype of an incomplete type;
+ * S; if S is some other first subtype;
* the latest subtype with a non-static constraint of the subtype_mark
- of a subtype_indication if the constraint of the subtype_indication
- is static (see 4.9) Redundant[; including when there is no constraint];
+ of the subtype_indication defining S if the constraint of the
+ subtype_indication is static (see 4.9) Redundant[; including when there
+ is no constraint];
* S; otherwise.
+AARM Ramification: S includes anonymous subtypes.
+
A check is made that the elaboration of the latest subtype with a non-static
constraint of the designated type of a subpool access type S occurs before the
elaboration of the storage pool object of S and that the elaboration is executed
@@ -242,9 +263,9 @@
There is more on this check in the discussion section.]
AARM Reason:
- This check ensures that the type (and any constraints) of the allocated objects
- exists longer than the storage pool object, so that the subpools are finalized
- (which finalizes any remaining allocated object) before the type of the objects
+ This check ensures that the type and any constraints of the allocated objects
+ exist longer than the storage pool object, so that the subpools are finalized
+ (which finalizes any remaining allocated objects) before the type of the objects
ceases to exist. The access type itself will cease to exist before the storage
pool. The check excludes subtypes with static constraints (or no constraints)
as these cannot depend on any elaboration; excluding them gives a longer
@@ -336,6 +357,30 @@
subpool objects (as in the example below).
+DANGLING SUBPOOL HANDLES
+
+It is possible for the designated object of a subpool handle to cease to
+exist, for instance because it was destroyed by a call to an instance of
+Unchecked_Deallocation. We don't need special rules to handle these cases,
+as a subpool handle is a normal Ada access type, and the implementation
+of the pool is written by the programmer in Ada. Thus the existing rules
+for access types cover all needed rules.
+
+However, those rules just mean that execution may become erroneous. To help
+prevent that, we've taken several measures:
+
+* We null the provided subpool handle when calling Unchecked_Deallocate_Subpool
+ to minimize the cases of dangling subpool handles.
+
+* We make a check on the provided subpool handle in an allocator that it
+ actually belongs to the appropriate pool. If it does not, Program_Error
+ is raised. This check will catch all cases of dangling subpool handles
+ when the designated subpool object still exists, and will catch a
+ large percentage in practice even when the object was deallocated (as
+ it is unlikely that a reused object will have a pointer at the right
+ pool in the right place).
+
+
FINALIZATION MODEL
The model used here is that subpools are really part of the pool object;
@@ -366,21 +411,45 @@
going to have a significant effect on usability, and it simplifies the
implementation of the check. (This restriction also makes it possible to
implement this check as a post-compilation check.)
-
-
-DANGLING SUBPOOL HANDLES
-It is possible for the designated object of a subpool handle to cease to
-exist, for instance because it was destroyed by a call to an instance of
-Unchecked_Deallocation. We don't need special rules to handle these cases,
-as a subpool handle is a normal Ada access type, and the implementation
-of the pool is written by the programmer in Ada. Thus the existing rules
-for access types cover all needed rules.
+Alternatives
-We null the provided subpool handle when calling Unchecked_Deallocate_Subpool
-to minimize the cases of dangling subpool handles. Pool implementations are
-encouraged to detect dangling handles if possible. This is easy to do if the
-subpool objects are actually part of the pool object (as in the example below).
+This check does make structuring code that uses subpools harder. We considered
+doing without the check by adding an additional runtime rule that the finalization
+of a collection for an access type also finalizes any objects allocated from
+a subpool for that access type. (Along with a similar rule for task dependence.)
+
+This eliminates any problems with ordering and would allow subpools to be used
+on access types with nested designated types and the like.
+
+However, the implementation would be complex. An obvious implementation would
+put subpool allocated objects on both a chain for the collection and a chain
+for the subpool (removing it from both when it is finalized). However, this
+would appear to have a distributed space overhead, as there would need to be
+links to put an object on two lists for any controlled type that could be allocated
+(which would seem to be any such type), as well as a small distributed time overhead
+to initialize the second set of pointers and to remove the object from the second
+list when it is finalized.
+
+However, it is possible to do better (with some complexity). If the subpool keeps
+a separate finalization list for each access type, then only the subpool need
+be put on the access type's collection list. This would complicate finalization
+somewhat, but only when subpools are used. This would require some unique way
+to identify the access type to the subpool; this could be done by assigning at
+elaboration time a unique serial number to each access type that uses a storage pool
+that supports subpools.
+
+Similar implementation complexity would also apply to task dependence. Because of
+this complexity, we chose the simpler model. But we do need to look at some real
+examples to see if the proposed check is too restrictive in practice (for instance,
+access to incomplete types deferred to a body cannot use subpools with this check).
+
+The other alternative would be to decouple subpools from the underlying pool. The
+subpool could be required to have a shorter lifetime than the access type (or the
+designated type), which eliminates the finalization problem. However, it makes
+dangling subpool handles much more likely. That could be solved with reference
+counting -- but of course that brings us back to the more complex proposal of
+AI05-0111-2. So this option was rejected.
Questions? Ask the ACAA Technical Agent