[PATCH] 8147527: Non-optimal code generated for postfix unary operators

bsrbnd bsrbnd at gmail.com
Thu Oct 27 13:33:45 UTC 2016


I've noticed another esoterism in Inner.testParent().

The proposed fix places the accessor for field "i" in Parent:

  private java.lang.Integer testParent();
    Code:
       0: aload_0
       1: getfield      #3                  // Field this$0:LIssue8147527;
       4: invokestatic  #8                  // Method
Parent.access$201:(LParent;)Ljava/lang/Integer;
       7: astore_1

Prior to that, it was placed in Issue8147527:

  private java.lang.Integer testParent();
    Code:
       0: aload_0
       1: getfield      #3                  // Field this$0:LIssue8147527;
       4: invokestatic  #8                  // Method
Issue8147527.access$201:(LIssue8147527;)Ljava/lang/Integer;
       7: astore_1                          // !!! REFERENCE TO VALUE
OF Field Parent.i:Ljava/lang/Integer; !!!

And before issue 8143388 changeset, it was accessed directly:

  private java.lang.Integer testParent();
    Code:
       0: aload_0
       1: getfield      #3                  // Field this$0:LIssue8147527;
       4: astore_1
       5: aload_1
       6: getfield      #8                  // Field
Parent.i:Ljava/lang/Integer;
       9: astore_2

What's the expected accessing way?

Bernard


2016-10-26 12:22 GMT+02:00 bsrbnd <bsrbnd at gmail.com>:
> Hi,
>
> 2016-10-25 14:15 GMT+02:00 Jan Lahoda <jan.lahoda at oracle.com>:
>> On 25.10.2016 10:41, Maurizio Cimadamore wrote:
>>>
>>> Hi Jan,
>>> great analysis. I think (1) could be a safer path - but I admit I'm not
>>> entirely sold on another point; you say:
>>>
>>> "Further desugaring then replaces the "Issue8147527.super" with "this$0"
>>> (see "tree.selected = translate(tree.selected);" in Lower.visitSelect)"
>>>
>>> Isn't this already wrong? The static type of this$0 is Issue8147527,
>>> which is different from the static type of this.super (Parent).
>>> Shouldn't javac at least emit a cast there to preserve typing? While I
>>> don't dispute the other problems you discovered, which are real, I think
>>> the above desugaring doesn't make a lot of sense, and probably only
>>> succeeds because the visitor later fixes up the problem (probably by
>>> realizing that the owner of the symbol 'i' and the symbol of this$0
>>> disagree, therefore adding a cast?)
>>
>>
>> Normally (when the same tree is not reused), this is only a transient state
>> inside the visitSelect method - the method keeps a flag
>> (qualifiedSuperAccess) that the select expression is a the form "X.super",
>> and this will then force generation of an accessor invocation, replacing the
>> whole JCFieldAccess with something like "Issue8147527.access$101(this$0)".
>> But in case of reused trees, this will only correct/replace the first use of
>> the tree, and the subsequent one will remain broken.
>>
> If "tree.selected=..." appears to be a wrong transient state, then
> avoiding it (option 2 that Jan suggested) depending on the
> "qualifiedSuperAccess" flag and forcing the accessor generation could
> be the best approach.
>
> The fix, here below, shows the idea...
>
> I know it is not perfect, but as it corrects this specific case (and
> all test/tools/javac/boxing passed), I would like to know your opinion
> about it.
> Is this a good direction to search?
>
> Bernard
>
> diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java
> b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java
> --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java
> +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java
> @@ -145,6 +145,7 @@
>      /** A hash table mapping local classes to their definitions.
>       */
>      Map<ClassSymbol, JCClassDecl> classdefs;
> +    Map<ClassSymbol, JCClassDecl> allclassdefs = new HashMap<>();
>
>      /** A hash table mapping local classes to a list of pruned trees.
>       */
> @@ -210,6 +211,8 @@
>              classMap.scan(outermostClassDef);
>              def = classdefs.get(c);
>          }
> +        if (def == null)
> +            def = allclassdefs.get(c);
>          return def;
>      }
>
> @@ -1100,6 +1103,7 @@
>              tree = make.at(tree.pos).Ident(sym);
>          }
>          JCExpression base = (tree.hasTag(SELECT)) ? ((JCFieldAccess)
> tree).selected : null;
> +        base = base != null ? translate(base) : null;
>          switch (sym.kind) {
>          case TYP:
>              if (sym.owner.kind != PCK) {
> @@ -1300,7 +1304,9 @@
>                  //odd access codes represent qualified super accesses - need to
>                  //emit reference to the direct superclass, even if the refered
>                  //member is from an indirect superclass (JLS 13.1)
> -
> site.setType(types.erasure(types.supertype(vsym.owner.enclClass().type)));
> +                Type supertype = types.supertype(vsym.owner.enclClass().type);
> +                if (!supertype.equals(syms.objectType))
> +                    site.setType(types.erasure(supertype));
>              }
>              ref = make.Select(site, sym);
>              args = make.Idents(md.params.tail);
> @@ -2413,6 +2419,7 @@
>              attrEnv = prevEnv;
>
>          classdefs.put(currentClass, tree);
> +        allclassdefs.put(currentClass, tree);
>
>          proxies = proxies.dup(currentClass);
>          List<VarSymbol> prevOuterThisStack = outerThisStack;
> @@ -3837,7 +3844,7 @@
>              tree.selected.hasTag(SELECT) &&
>              TreeInfo.name(tree.selected) == names._super &&
>              !types.isDirectSuperInterface(((JCFieldAccess)tree.selected).selected.type.tsym,
> currentClass);
> -        tree.selected = translate(tree.selected);
> +        if (!qualifiedSuperAccess) tree.selected = translate(tree.selected);
>          if (tree.name == names._class) {
>              result = classOf(tree.selected);
>          }


More information about the compiler-dev mailing list