From alex.buckley at oracle.com Wed Sep 12 17:42:06 2012 From: alex.buckley at oracle.com (Alex Buckley) Date: Wed, 12 Sep 2012 17:42:06 -0700 Subject: Welcome! Message-ID: <50512BDE.5050700@oracle.com> Experts, Welcome to the new, publicly archived EG mailing list! We should use this list for all new topics, except for confidential topics like dissemination of phone numbers. You will recall I sent a couple of significant emails to the old list in the past few weeks; I will send them to the new list to get it started. Alex From alex.buckley at oracle.com Thu Sep 13 12:29:06 2012 From: alex.buckley at oracle.com (Alex Buckley) Date: Thu, 13 Sep 2012 12:29:06 -0700 Subject: Type Annotations in core reflection + language model APIs Message-ID: <50523402.9040400@oracle.com> Experts, JSR 308 must model annotations on type uses in both of the reflection APIs supported by Java SE: core reflection (java.lang and java.lang.reflect) and the language model (javax.lang.model.** defined by JSR 269). Both reflection APIs are limited to _declarations_ outside code blocks. For example, they allow reflection over the declarations of a method's formal parameters, but not over the declarations of local variables within a method. Even though JSR 308 is positioned as concerning type _uses_, many type uses occur within declarations outside code blocks! For example, a method declaration includes a return type, on which JSR 308 allows an annotation separate from an annotation on the method declaration itself. In other words, the use of a type is often made in the context of a declaration. It is relatively straightforward to extend the reflection APIs so that existing entities which represent declarations - such as java.lang.reflect.Method and javax.lang.model.element.TypeElement - expose more information about types used within the declarations. Namely, any annotations on those type uses. This mail proposes such extensions without upsetting the overall structure of the reflection APIs. Your comments are most welcome. In what follows, it is useful to know that: a) By policy, core reflection does not depend on the rest of the Java SE API, and so uses array types as aggregates. The language model has no such constraint, and uses java.util.List and java.util.Set widely. b) The locations where JSR 308 allows annotations are summarized at http://types.cs.washington.edu/jsr308/specification/java-annotation-design.html#class-file:ext:target_type. The "externally visible" targets are precisely the contexts representing declarations. c) Where reference is made to repeating annotations, the relevant specification is http://cr.openjdk.java.net/~abuckley/8misc.pdf as discussed on the comment-and-evaluation-licensed (not GPL) mailing list "enhanced-metadata-spec-discuss" at openjdk.java.net. * Core reflection Core reflection offers a number of methods for exposing types, such as Class.getSuperclass(), Field.getType(), and Method.getReturnType(). All return Class objects, and Class implements AnnotatedElement. Unfortunately, this is not helpful for JSR 308. A Class object represents a class declaration, so its AnnotatedElement methods expose annotations on that declaration. For example, suppose a field is declared as "@Foo String f;" where Foo is a TYPE_USE annotation. You call Field.getType() to obtain a Class object which represents the String class. Since the declaration of java.lang.String has no annotations, calling getAnnotations() on this Class object will return nothing. The _use_ of String's name as a type in a field declaration is not known to the Class object. Let us turn to the "Generic" methods in core reflection: Class.getGenericSuperclass(), Field.getGenericType(), Method.getGenericReturnType(). All return Type objects. Perhaps Type should implement AnnotatedElement? Again, not helpful for JSR 308. Type objects are essentially wrappers for Class objects, so can expose only annotations on class declarations. For example, suppose a field is declared as "List" where Foo is a TYPE_USE annotation. You call Field.getGenericType() to obtain a Type object, then downcast to ParameterizedType to call further methods which return Type objects, and so on, until eventually you obtain a Type object which is instanceof Class (specifically, the String class). Again, the annotations available from this Type object (when downcast to Class) are annotations on the declaration of java.lang.String, not on uses of String's name in the field declaration. (Sidebar: It would be possible for Type to implement AnnotatedElement so that Field.getGenericType() et al could be used to obtain declaration-site annotations. Type has not been retrofitted in this way because the Class objects returned by Field.getType() et al already do the job.) Since Class and Type are not suitable locations for methods that directly expose annotations on type uses, there must instead be new methods on Class, Field, Method, and Constructor that return objects which in turn expose annotations on type uses. Here are those methods: // Class extends/implements Class.getAnnotatedSuperclass() -> AnnotatedType Class.getAnnotatedInterfaces() -> AnnotatedType[] // Field type Field.getAnnotatedType() -> AnnotatedType // Method return / receiver / parameter / exception types Method.getAnnotatedReturnType() -> AnnotatedType Method.getAnnotatedReceiverType() -> AnnotatedType Method.getAnnotatedParameterTypes() -> AnnotatedType[] Method.getAnnotatedExceptionTypes() -> AnnotatedType[] // Constructor result / receiver / parameter / exception types Constructor.getAnnotatedReturnType() -> AnnotatedType Constructor.getAnnotatedReceiverType() -> AnnotatedType Constructor.getAnnotatedParameterTypes() -> AnnotatedType[] Constructor.getAnnotatedExceptionTypes() -> AnnotatedType[] What is AnnotatedType? First, we recognize that AnnotatedElement has grown more complex thanks to repeating annotations, so we should always prefer to inherit from AnnotatedElement than duplicate its methods. Then, each kind of java.lang.reflect.Type entity which may appear in a declaration (e.g. as a superclass, or a type parameter bound, etc) gets a friend, Annotated*Type*, which exposes annotations: package java.lang.reflect; interface AnnotatedType extends AnnotatedElement {} interface AnnotatedGenericArrayType extends AnnotatedType { AnnotatedType getAnnotatedGenericComponentType(); } interface AnnotatedParameterizedType extends AnnotatedType { AnnotatedType[] getAnnotatedActualTypeArguments(); } interface AnnotatedTypeVariable extends AnnotatedType { AnnotatedType[] getAnnotatedBounds(); } interface AnnotatedWildcardType extends AnnotatedType { AnnotatedType[] getAnnotatedLowerBounds(); AnnotatedType[] getAnnotatedUpperBounds(); } In addition to annotations on type uses, JSR 308 allows annotations on the declarations of type parameters of generic classes and methods. Core reflection already exposes the declarations of type parameters: Class.getTypeParameters() -> TypeVariable[] Method.getTypeParameters() -> TypeVariable[] so it is appropriate to make TypeVariable implement AnnotatedElement in order to expose annotations on the declaration. In fact, TypeVariable has implemented AnnotatedElement since early builds of JDK8, though the implementation is currently a no-op. Finally, JSR 308 allows annotations on the bounds of type parameters. This is a true "type use" location, in contrast to the declaration of the type parameter itself. Since TypeVariable.getBounds() returns Type objects, we add a new method which returns AnnotatedType objects: TypeVariable.getAnnotatedBounds() -> AnnotatedType[] * Language model (In what follows, the following "equivalences" between core reflection and the language model may be helpful: j.l.Class ~ javax.lang.model.element.TypeElement j.l.r.Field ~ javax.lang.model.element.VariableElement j.l.r.Method/Ctor ~ javax.lang.model.element.ExecutableElement j.l.r.TypeVariable ~ javax.lang.model.element.TypeParameterElement j.l.r.Annotation ~ javax.lang.model.element.AnnotationMirror j.l.r.Type ~ javax.lang.model.type.TypeMirror j.l.r.AnnotatedType ~ javax.lang.model.type.AnnotatedTypeMirror ) As in core reflection, we add methods to Element subclasses to reveal the annotations on type uses which occur within declarations. While it is attractive to add methods to TypeMirror and its subclasses to expose annotations on type uses, we cannot be sure about the identities of TypeMirror objects. For example, two field declarations "@Foo String f1; @Bar String f2;" are represented as two VariableElement objects, but their asType() methods may return the same TypeMirror object for "String". Therefore, we introduce AnnotatedTypeMirror as a parallel hierarchy to TypeMirror, similar to how j.l.r.AnnotatedType is parallel to j.l.r.Type. AnnotatedTypeMirror exposes annotation mirrors on a ground type, similar to how j.l.r.AnnotatedType offers getAnnotations() for a ground type. The subtypes of AnnotatedTypeMirror represent Java's structural types - parameterized types, array types, type variables, and wildcard types - similar to the subtypes of j.l.r.AnnotatedType. // Notation: ATM == AnnotatedTypeMirror // Notation: L == List // Class extends/implements TypeElement.getAnnotatedSuperclass() -> ATM TypeElement.getAnnotatedInterfaces() -> L // Field type VariableElement.getAnnotatedType() -> ATM // Method/ctor return / receiver / parameter / exception types ExecutableElement.getAnnotatedReturnType() -> ATM ExecutableElement.getAnnotatedReceiverType() -> ATM ExecutableElement.getAnnotatedParameterTypes() -> L ExecutableElement.getAnnotatedThrownTypes() -> L package javax.lang.model.type; interface AnnotatedTypeMirror { List getAnnotationMirrors(); } interface AnnotatedArrayTypeMirror extends AnnotatedTypeMirror { AnnotatedArrayTypeMirror getAnnotatedComponentType(); } interface AnnotatedDeclaredTypeMirror extends AnnotatedTypeMirror { List getAnnotatedTypeArguments(); } interface AnnotatedTypeVariableMirror extends AnnotatedTypeMirror { List getAnnotatedLowerBound(); List getAnnotatedUpperBound(); } interface AnnotatedWildcardTypeMirror extends AnnotatedTypeMirror { List getAnnotatedExtendsBound(); List getAnnotatedSuperBound(); } (Notice that ExecutableType, NoType, NullType, and PrimitiveType have no counterpart in this hierarchy. First, ExecutableType is obtained from ExecutableElement.asType(), but we are not adding ExecutableElement.asAnnotatedType() which would necessitate AnnotatedExecutableTypeMirror. Second, NoType and NullType represent pseudo-types which cannot be annotated. Third, PrimitiveType has no structural elements, so an annotation on a primitive type is simply retrieved with AnnotatedTypeMirror.getAnnotationMirrors().) For annotations on declarations of type parameters, the language model already exposes the declarations of type parameters: TypeElement.getTypeParameters() -> L ExecutableElement.getTypeParameters() -> L TypeParameterElement has getAnnotationMirrors() from Element, and the implementation just needs to be filled in. (Contrast with core reflection, we needed to make TypeVariable implement AnnotatedElement.) Finally, annotations on the bounds of type parameters are exposed by a new method on TypeParameterElement, akin to that on j.l.r.TypeVariable: TypeParameterElement.getAnnotatedBounds() -> L * End * From alex.buckley at oracle.com Thu Sep 13 12:31:04 2012 From: alex.buckley at oracle.com (Alex Buckley) Date: Thu, 13 Sep 2012 12:31:04 -0700 Subject: Improving the format of type annotation attributes Message-ID: <50523478.7050006@oracle.com> Experts, John Rose at Oracle owns the Pack200 spec and has generously given of his time to analyze JSR 308's ClassFile attributes from a Pack200 point of view. His analysis is below. Please review it carefully. With regard to target_type, the change from u1 to u2 was my fault. I was concerned that the number of contexts in the Java language where annotations may appear will grow significantly in future, e.g. for annotations on expressions. However, it seems likely that a u1 will suffice to classify contexts, as indeed a u1 suffices for JVM bytecodes. target_type will therefore be changed back to a u1. Then we must make a choice. The low-risk approach is simply to move the location information earlier in the type_annotation structure. The high-risk approach is to drop the "counted" approach to location information and adopt the "nested" location approach. In either case, the physical content in type_annotations will be hidden by the reflection APIs I proposed recently. Annotation consumers will never see a location array _or_ a type_location tree. OTOH, it is fairly clear that a strongly-typed type_location tree is more "beautiful" than an untyped location array. Readability and ease of understanding are as important for ClassFile attributes as for Java language features. Your comments on which approach to take will be most welcome. Alex --- Mail from John Rose follows --- I just read the updated type annotation spec (dated 7/03/2012) here: http://types.cs.washington.edu/jsr308/specification/java-annotation-design.html I also read the change log. On the whole, the project is clearly converging toward a good design. The annotation format is cleaner, as is the type annotation syntax. The new receiver syntax is a good simplifying stroke, in my opinion, and the detailed disambiguation rules about whole-method vs. return type annotations feel clean and user-friendly. In the light of the updated design, I'd like adjust the comments I made last November. 1. I am still not certain whether Pack200 can handle the new attribute layout proposed by JSR 308. In order to test this in a timely manner, we will need a good sample of class files that exercises most or all the degrees of freedom in the new attribute format. I think the best way for us to get this is to piggy-back on whatever unit tests you have, perhaps in the jsr308-langtools repository. Please advise. 2. The change of target_type from u1 to u2 seems like premature optimization to me. The class file format is so relentlessly byte-oriented that it is very hard to make use of any larger alignment. In my 15 years of working with class files, I think I have seen only a few cases where a regular u2 type was technically helpful to class file parsing. I don't think JSR 308 will be one of those cases, because not every element of the layout has an even byte count (parameter_index and typearg_target are examples). Regarding future extensions, I don't think the extra 8 bits matters even slightly: You are using 18*2 code points out of a possible 256, which leaves 220 remaining, and in the unlikely event that you need up to 50,000 new code points, you could define a secondary target_type_2 field of 8 bits, present only when the original target_type is not one of the original allowed values. It seems to me that adding those extra 8 bits to every type annotation does not buy any tangible benefit. (Pack200 will make them disappear, but they will make class files slightly larger.) 3. I see that you still use the odd/even trick to handle nesting; essentially the low bit of the target_type field gates whether or not there is a trailing location record. I would like to critique the location record format, which records a tree branch within an occurrence of a complex type expression tree: 1. The length (tree depth) field is absurdly long at 16 bits. No type expression tree has ever been so deep. 2. It is a "design smell" that the location_length field is never zero. The natural "zero condition" is redundantly encoded elsewhere, making for a confusing design. 3. The nodes in the tree branch are unlabeled. This means that the source code must be inspected to determine whether the location is within a wildcard, array type, etc. 4. Because the nodes in the branch are unlabeled, the 8-bit location index must carry *either* branch depth *or* parameter index information; in the case of nested types it refers to *both* kinds of information. This leads to the fragile rule about imputing type parameters to erased types. 5. The location array and its length are orphan fields, not belonging to any particular structure. This requires an informal "hand wavey" account of where they occur, which makes the design harder to understand and implement. Using a nested instead of a counted branch location format would remedy flaws 1, 2, and 5, and would also remove the strange (from 2) asymmetry by which zero-length branches are denoted by the even/odd hack instead of by a zero count. By "nested" I mean the format called "nested_target" below, where each node in the type tree branch is introduced by a label (wildcard, array, nested type, type bound) and an index (which could be elided for arrays). I understand that even if a nested location format is theoretically the best, the weight of existing implementations is committed to the counted location format, and it would be awkward to change. In this case, I would like to suggest a more modest change that would be slightly more compact than your present design, and would be simpler to describe and to parse by tools, including Pack200. Specifically: Reduce the target_type field to 8 bits. Add the location array immediately after the target_type field, with an 8-bit count (usually zero). Put the polymorphic part of the target after both. The result would be to move the low bit of the target_type into its own byte, which would serve as the location array count (if non-zero, of course). The new JSR 308 fields would then look like this: u1 target_type; // the type of the targeted program element, see Section 3.2 u1 location_length; // ++ADDED u1 location[location_length]; // ++ADDED union { typeparam_target; supertype_target; typeparam_bound_target; empty_target; methodparam_target; exception_target; localvar_target; catch_target; offset_target; typearg_target; } target_info; // uniquely identifies the targeted program element, see Section 3.3 The odd/even hack would be unnecessary in this case, although it could be present redundantly in the target_type field. In that case, the invariant would apply that the low bit of target_type is zero if and only if the location_length byte is zero. Note that in this design the location_length and location array are no longer disembodied fields tacked onto a bunch of other layouts, but are first-class members of the type_annotation structure. They could also be moved after the target_info structure (which is where they are now, de facto), although I think they are slightly easier to work with in the place suggested above. I guess my minimum request, from a viewpoint centered only on Pack200, is to consider making the location_length field be either non-optional, or else to have it gated by a smaller number of target_type tag values (not the full 18, more like 1-4, as described below). But I believe that, given the importance of type annotations as a technology for enhancing static type checkers, it is worth all of our time to remove as many design smells as possible. Best wishes, ? John Rose P.S. For completeness, here is what a fully nested (non-counted) layout would look like, fixing problems 3 and 4 also: // New field in JSR 308: type_location location; } struct type_location { // ++ADDED recursive structure u1 target_type; // the type of the targeted program element, see Section 3.2 union { typeparam_target; supertype_target; typeparam_bound_target; empty_target; methodparam_target; exception_target; localvar_target; catch_target; offset_target; typearg_target; // ++ADDED four more target_type values // (but deleted the 18 odd ones from the July spec): array_component_target = struct { type_location outer_array_type; }; type_argument_target = struct { u1 parameter_index; type_location outer_type_expression; }; nested_type_qualifier_target = struct { u1 qualifier_index; type_location qualified_type; }; wildcard_bound_target = struct { type_location outer_wildcard_expression; }; } target_info; // uniquely identifies the targeted program // element, see Section 3.3 } The type_location structure is recursive in a way that naturally corresponds to the various location syntaxes. Note that only type parameter edges absolutely require an extra index. The others can select the proper level of structure (in array rank or nested type pathname) simply by repeating edges; I kept qualifier index to show the other option. The ordering of data in this scheme is the reverse of that with a counted location, since the outermost location (such as a field type) must come last, since its target_info is non-recursive. Each occurrence of array_component_target selects a nested component type (of exactly one less rank) from the enclosing array type. Each occurrence of nested_type_qualifier selects one enclosing (qualifying) type, selected by the qualifier index (origin and direction not specified here). From dl at cs.oswego.edu Thu Sep 13 13:12:15 2012 From: dl at cs.oswego.edu (Doug Lea) Date: Thu, 13 Sep 2012 16:12:15 -0400 Subject: Improving the format of type annotation attributes In-Reply-To: <50523478.7050006@oracle.com> References: <50523478.7050006@oracle.com> Message-ID: <50523E1F.1040908@cs.oswego.edu> On 09/13/12 15:31, Alex Buckley wrote: > Then we must make a choice. The low-risk approach is simply to move the location > information earlier in the type_annotation structure. The high-risk approach is > to drop the "counted" approach to location information and adopt the "nested" > location approach. Where "risk" amounts to throwing away and redoing part of the current reference implementation that encodes and decodes annotations? I'm not sure that anyone not involved in encoding/decoding (not me) can give much guidance, but offhand, the nested approach looks more amenable to addressing some of the comments posted by Eric Bruneton? -Doug From alex.buckley at oracle.com Thu Sep 13 13:50:56 2012 From: alex.buckley at oracle.com (Alex Buckley) Date: Thu, 13 Sep 2012 13:50:56 -0700 Subject: Improving the format of type annotation attributes In-Reply-To: <50523E1F.1040908@cs.oswego.edu> References: <50523478.7050006@oracle.com> <50523E1F.1040908@cs.oswego.edu> Message-ID: <50524730.6010607@oracle.com> On 9/13/2012 1:12 PM, Doug Lea wrote: > On 09/13/12 15:31, Alex Buckley wrote: >> Then we must make a choice. The low-risk approach is simply to >> move the location information earlier in the type_annotation >> structure. The high-risk approach is to drop the "counted" approach >> to location information and adopt the "nested" location approach. > > Where "risk" amounts to throwing away and redoing part of the > current reference implementation that encodes and decodes > annotations? Yes, and also fitting the implementation of the core reflection + language model APIs around the new ClassFile encoder/decoder. We have only a few months remaining; JDK 8 is scheduled to be Feature Complete in January 2013, per http://openjdk.java.net/projects/jdk8/. > I'm not sure that anyone not involved in encoding/decoding (not me) > can give much guidance, but offhand, the nested approach looks more > amenable to addressing some of the comments posted by Eric Bruneton? Eric's issue with the location field is that it encodes nested types inside-out. Outside-in would be more congruent with Signature attributes. John's nested approach is actually inside-out for _all_ kinds of type constructors: - the . nested type constructor - the [] array type constructor - the <...> non-wildcard type argument constructor - the ? ... wildcard type argument constructor because the final enclosing target_info is the logical location where the annotated type appears (type parameter, field type, method return type, etc). Alex From dl at cs.oswego.edu Fri Sep 14 05:23:46 2012 From: dl at cs.oswego.edu (Doug Lea) Date: Fri, 14 Sep 2012 08:23:46 -0400 Subject: Type Annotations in core reflection + language model APIs In-Reply-To: <50523402.9040400@oracle.com> References: <50523402.9040400@oracle.com> Message-ID: <505321D2.1090506@cs.oswego.edu> On 09/13/12 15:29, Alex Buckley wrote: > > This mail proposes such extensions without upsetting the overall structure of > the reflection APIs. Your comments are most welcome. Looks good to me. On a first-pass reading, I don't see any technical problems. I like the idea of "externally visible" being a free variable of sorts. -Doug From mernst at cs.washington.edu Tue Sep 18 12:52:28 2012 From: mernst at cs.washington.edu (Michael Ernst) Date: Tue, 18 Sep 2012 12:52:28 -0700 (PDT) Subject: Improving the format of type annotation attributes In-Reply-To: <50523478.7050006@oracle.com> References: <50523478.7050006@oracle.com> Message-ID: <20120918.125228.1286743832767519949.mernst@cs.washington.edu> Alex- Thanks for forwarding this to the mailing list. > We must make a choice. The low-risk approach is simply to move the > location information earlier in the type_annotation structure. The > high-risk approach is to drop the "counted" approach to location > information and adopt the "nested" location approach. > > In either case, the physical content in type_annotations will be hidden by > the reflection APIs I proposed recently. Annotation consumers will never > see a location array _or_ a type_location tree. OTOH, it is fairly clear > that a strongly-typed type_location tree is more "beautiful" than an > untyped location array. Readability and ease of understanding are as > important for ClassFile attributes as for Java language features. > > Your comments on which approach to take will be most welcome. I have a slight preference for the "nested" location approach, primarily for aesthetic reasons and because I believe that those few consumers who have to deal with it directly will be less likely to make errors. I don't see any show-stoppers in the "counted" approach, and it might end up being the only practical way to go forward in the amount of time we have available. -Mike From mernst at cs.washington.edu Fri Sep 21 02:28:25 2012 From: mernst at cs.washington.edu (Michael Ernst) Date: Fri, 21 Sep 2012 02:28:25 -0700 (PDT) Subject: typo in Runtime[In]VisibleTypeAnnotations_attribute definition? In-Reply-To: <50516B6C.3070708@free.fr> References: <50516B6C.3070708@free.fr> Message-ID: <20120921.022825.2082496107255455127.mernst@cs.washington.edu> Eric Bruneton suggested: > I think "u2 attribute_length;" should be replaced with "u4 > attribute_length;" in the definition of the > Runtime[In]VisibleTypeAnnotations_attribute structure, in Section 3, in > order to comply with the general format of attributes > (http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7). I agree, and I have made this change. Expert Group, let me know if you have any concerns. Eric, thanks very much for noticing this inconsistency! -Mike From mernst at cs.washington.edu Fri Sep 21 02:34:59 2012 From: mernst at cs.washington.edu (Michael Ernst) Date: Fri, 21 Sep 2012 02:34:59 -0700 (PDT) Subject: Type annotations for non-Java languages? In-Reply-To: <50516BE4.6010102@free.fr> References: <50516BE4.6010102@free.fr> Message-ID: <20120921.023459.1917898732817166537.mernst@cs.washington.edu> Eric Bruneton suggested: > currently Section 3 has some restrictions that are specific to the > Java language, and I think it would be useful to remove them: > - in Section 3.2, in the caption of Figure 1, I think "elements marked * will > never appear" should be removed, because non Java languages may allow these > constructs. I have updated this text to: Enumeration elements marked * will never be generated from Java source code as of Java SE 8. However, they may appear in the class file. > - in Section 3.3.10, nothing is said about invokedynamic. I think this should > be fixed. This is a simple oversight (the text was written before invokedynamic existed), and I have corrected it. Expert Group, let me know if you have any concerns. Eric, thanks for noticing these issues and making the suggestions! -Mike From mernst at cs.washington.edu Fri Sep 21 03:15:37 2012 From: mernst at cs.washington.edu (Michael Ernst) Date: Fri, 21 Sep 2012 03:15:37 -0700 (PDT) Subject: Classfile format changes for more efficient processing In-Reply-To: <50516CF6.6050400@free.fr> References: <50516CF6.6050400@free.fr> Message-ID: <20120921.031537.857440125198746700.mernst@cs.washington.edu> Eric Bruneton suggests some classfile format changes that will make it more efficient to process (e.g., read and write) class files. See below for his full message. I plan to accept all of these suggestions. Here are my comments, in a slightly different order than Eric's: (c) Putting instruction annotations on the Code attribute rather than the method_info structure is logical; the current design was an oversight. (a) I hadn't considered requiring instruction annotations to be sorted, but I have no objection to this and I am inclined to trust Eric's concerns about speed. (b) Changing the order of fields in the "type_annotation" structure, so that the new JSR 308 fields come before the original fields inherited from the "annotation" structure, puts the most interesting and relevant information first. I am willing to make this change. I should note that this suggestion is orthogonal to those made by John Rose, which we are also planning to implement in whole or in part, so the "type_annotation" structure will change slightly again. Expert Group, let me know if you have any further comments or concerns. Eric, thanks for trying an implementation and making these suggestions based on it! -Mike > Subject: prototype implementation of JSR 308 in OW2 ASM > From: Eric Bruneton > To: type-annotations-spec-comments at openjdk.java.net, FORAX > Date: Thu, 13 Sep 2012 07:19:50 +0200> > > Hi, > > For your information, I added a prototype "implementation" of JSR 308 in > the ASM_5_FUTURE branch of the OW2 ASM repository: > > http://websvn.ow2.org/listing.php?repname=asm&path=%2Fbranches%2FASM_5_FUTURE%2F > > Added code compared to HEAD: > > http://websvn.ow2.org/comp.php?repname=asm&compare[]=%2Fbranches%2FASM_5_FUTURE at 1642&compare[]=%2Fbranches%2FASM_5_FUTURE at 1643 > > This prototype does not implement the exact specification in its current > state. I used 3 modifications to make the implementation easier and more > efficient. They are the following: > > a) in Section 3, I assumed that the elements in the "annotations" array of > the Runtime[In]VisibleTypeAnnotations_attribute are sorted by increasing > order of bytecode offset (for target_type >= 0x86; the others can be in any > order, and also interleaved with instruction annotations). > b) in Section 3.1, in the type_annotation structure, I put the target_type > and target_info fields *before* the original fields from the "annotation" > structure. > c) in sections 3.3.7 to 3.3.10, I replaced "A > Runtime[In]visibleTypeAnnotations attribute containing a ***_target appears > in the attributes table of a method_info structure." with "... in the > attributes table of a Code attribute.". I also replaced, in Section 3, "A > type annotation is stored in a Runtime[In]visibleTypeAnnotations attribute > on the smallest enclosing class, field, or method." with "... class, field, > method, or > Code structure.". > > Changes a) and c) improve the performance of class parsing in ClassReader, > by avoiding multiple parsing of the annotations structure, and also by > avoiding sorting passes. Also change c) seems more natural, independently > of any implementation consideration, since existing attributes that refer > to bytecode are currently stored as attributes of the Code attribute (like > LineNumberTable, LocalVariableTable, LocalVariableTypeTable and > StackMapTable). > > Change b) improves the performance of class generation in > ClassWriter. Indeed, with the proposed ASM 5 API, the target is known > before the annotation, and so it is easier to store it first in the > type_annotation structure. This change also improves the parsing > performance in ClassReader. > > Do you think it would be possible to make these changes in the > specification? Especially change b), which is really critical to get good > class generation performance with ASM? > > Eric