Queries and patch for JDK-8034854: outer_class_info_index of synthetic class is not zero

Jan Lahoda jan.lahoda at oracle.com
Thu Feb 20 12:34:38 PST 2014

As far as I was able to determine, these are the cases where and why the 
auxiliary classes are generated/used:
-as tags for access constructors for private constructors. An existing 
anonymous innerclass is reused as a tag, if available, otherwise at most 
one class is synthesized per top-level type.
-for target levels whose ldc instruction does not support references to 
classes, desugared code for class literals (a "getter" and cache for the 
Class objects) is placed into a "cache" class. Depending on the 
circumstances, a top-level class or an existing anonymous innerclass is 
reused if possible, otherwise at most one class is synthesized per 
top-level type.
-for switch-over-enum, a lazy map between enum constants and ordinals is 
placed into a cache class. An existing anonymous innerclass is reused, 
if available, otherwise at most one class is synthesized per top-level type.
-for interfaces, to hold their assertions enabled status. At most one 
class is synthesized per top-level type.


On 02/20/2014 08:14 PM, Alex Buckley wrote:
> It would make sense to consider the full range of reasons why these
> auxiliary classes are generated. You indicated one reason - tags for
> accessing private ctors - and it makes sense to generate a "true"
> anonymous class there (outer_class_info_index=0, inner_name_index=0).
> But perhaps other reasons would justify auxiliary classes with
> meaningful "owners" - again, your word - and there it would be sensible
> to consider them as member classes rather than anonymous classes.
> Alex
> On 2/20/2014 3:11 AM, Jan Lahoda wrote:
>> Hi Alex,
>> Thanks for the comments.
>> I was briefly considering filling some inner_name for the synthetic
>> classes, but using zeroing outer_class_info_index seemed somewhat
>> cleaner, safer (no risk of name clashes or misinterpretation of the
>> name) and simpler. But if generating an inner_name for the synthetic
>> classes would be (strongly) preferred, I can investigate it.
>> Jan
>> On 02/19/2014 08:13 PM, Alex Buckley wrote:
>>> Hi Jan,
>>> The requirement that outer_class_info_index must agree with
>>> inner_name_index w.r.t. an anonymous class was added in JVMS7 because we
>>> saw class files where they disagreed and it simply made no sense. The
>>> requirement was conditioned on 51.0 class files because we didn't want
>>> to break pre-7 class files with insensible InnerClasses.
>>> The auxiliary classes generated by javac appear to have a meaningful
>>> "owner" - your word - so it would seem appropriate to have a non-zero
>>> outer_class_info_index. Just generate a random name for
>>> inner_name_index. (The 4.7.6 text assumes the "original simple name" can
>>> be derived from source code, but that's not applicable for synthetic
>>> classes.) This change could reasonably affect all target levels, since
>>> no-one should be relying on the value of inner_name_index for these
>>> auxiliary classes.
>>> OTOH, your proposal to represent the auxiliary classes as true anonymous
>>> classes in InnerClasses is attractive because it exposes even less
>>> information than at present. This change could reasonably affect all
>>> target levels too, since no-one should be relying on the value of
>>> outer_class_info_index for these auxiliary classes.
>>> Alex
>>> On 2/19/2014 4:34 AM, Jan Lahoda wrote:
>>>> Hello,
>>>> I have a few questions about JDK-8034854 and a possible patch/fix for
>>>> it. The bug URL:
>>>> https://bugs.openjdk.java.net/browse/JDK-8034854
>>>> The problem is that while JVMS 7, 4.7.6. (The InnerClasses Attribute)
>>>> mandates that:
>>>>   If a class file has a version number that is greater than or equal to
>>>>   51.0, and has an InnerClasses attribute in its attributes table, then
>>>>   for all entries in the classes array of the InnerClasses attribute,
>>>>   the value of the outer_class_info_index item must be zero if the
>>>> value
>>>>   of the inner_name_index item is zero.
>>>> javac in some cases produces non-zero "outer_class_info_index" even if
>>>> "inner_name_index" is zero. This happens for synthetically generated
>>>> auxiliary classes. These classes are generated for a number of reasons,
>>>> for example to be used as tags when accessing private constructors. The
>>>> synthetic classes internally have an empty name, so the generated
>>>> "inner_name_index" is zero, but their owner is a class, so they get the
>>>> non-zero "outer_class_info_index".
>>>> I've sketched out a simple fix for this problem, which ensures that
>>>> "outer_class_info_index" is zero for classes that have empty name:
>>>> http://cr.openjdk.java.net/~jlahoda/8034854/webrev.00/
>>>> After this change, the generated synthetic classes look a lot like
>>>> anonymous classes defined in an initializer of the given class
>>>> (based on
>>>> the InnerClasses attribute and the EnclosingMethod attribute). That
>>>> seems reasonable to me.
>>>> My questions are:
>>>> -does the fix above make sense?
>>>> -the change affects all target levels. It seems to me that the new
>>>> behavior makes sense even for pre-7 classfiles, but I'll gladly limit
>>>> the new behavior to only some minimal target level if desired.
>>>> Any comments welcome.
>>>> Thanks,
>>>>     Jan

More information about the compiler-dev mailing list