[PATCH] 8147527: Non-optimal code generated for postfix unary operators
bsrbnd
bsrbnd at gmail.com
Fri Nov 18 15:52:45 UTC 2016
Hi,
2016-11-16 11:18 GMT+01:00 bsrbnd <bsrbnd at gmail.com>:
> Hi Jan,
>
> 2016-11-15 16:59 GMT+01:00 Jan Lahoda <jan.lahoda at oracle.com>:
>> Hi Bernard,
>>
>> Sorry for delayed answer.
>>
>> I don't think there's a precedent in the current code in using
>> JCTree.clone(), but I quite like it. I incline to think the shallow clones
>> fit the needs here.
>>
>> I am attaching a patch that includes your patch, the original test broken by
>> JDK-8143388 and a test that I tried to write to verify the desugaring
>> (checks the trees after Lower). I'd like to go through the other tests to
>> see which should be added, do some more testing (in particular the code in
>> lowerBoxedPostop seems a little bit suspicious, as the newly-created type
>> cast may be cloned) and send a request for review.
> When I wrote this patch, I was more thinking of making a deep copy of
> the tree. But I realized that a shallow copy could be enough in our
> situation and would be a safer fix. In such a configuration, cloning
> only a type-cast doesn't make any sense, of course. The updated fix
> below is probably better even if this has no impact in our precise
> example.
>
The following test shows the problem if the type-cast is cloned
instead of "tmp1". Thus the updated fix I send previously seems to be
important (I think).
Bernard
diff --git a/test/tools/javac/boxing/QualBoxedPostOp2.java
b/test/tools/javac/boxing/QualBoxedPostOp2.java
new file mode 100644
--- /dev/null
+++ b/test/tools/javac/boxing/QualBoxedPostOp2.java
@@ -0,0 +1,33 @@
+/*
+ * @test
+ * @bug 8147527
+ * @summary Qualified "super" boxed unary post-operation using a type variable.
+ */
+public class QualBoxedPostOp2<T> extends Parent2<Integer> {
+ public static void main(String[] args) {
+ new QualBoxedPostOp2().testAll();
+ }
+
+ private void testAll() {
+ super.i = 10;
+
+ equals(new Inner().testParent(), 10);
+ equals(super.i, 11);
+ }
+
+ private void equals(int a, int b) {
+ if (a != b) throw new Error();
+ }
+
+ T i;
+
+ class Inner {
+ private Integer testParent() {
+ return QualBoxedPostOp2.super.i++;
+ }
+ }
+}
+
+class Parent2<T> {
+ protected T i;
+}
>> Please let me know if
>> there are some tests that should definitely be included, or if you'd have
>> any other comments.
> "BoxedPostOpOpti" and "BoxedPostOpOpti2" verify the optimization of
> the generated code by comparing it with what's generated for "i++".
> I've thought of specifying explicitly the expected generated code,
> instead; but I thought it was too precise as it might perhaps change
> in the future. Thus, your solution of comparing the desugared code is
> probably better.
>
> Another difference is that you put "Parent" in the same package while
> I put it in another one as it was the subject of issue 8143388 (but
> this isn't really important for the optimization, I think).
>
> "BoxedPostOpOpti" tests also the optimization of "C.this.i++" which
> implies the correct handling of "this$0" without generating any
> accessor.
>
> "BoxedPostOpOpti2" verifies also the optimization of "super.j++" (with
> "P" in a separate package) which was done by issue 8143388 changset.
>
> "BoxedPostOpOpti3" checks the runtime behavior of issue 8143388
> changset as the associated test verifies only the success of the
> compilation. This isn't absolutely necessary since the problem was not
> at runtime, but I thought it was safer to do so.
>
>> Thank you for your work on this,
>> Jan
>>
> Thank you, too.
>
> 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
> @@ -2218,7 +2218,7 @@
> return builder.build(rval);
> }
> Name name = TreeInfo.name(rval);
> - if (name == names._super)
> + if (name == names._super || name == names._this)
> return builder.build(rval);
> VarSymbol var =
> new VarSymbol(FINAL|SYNTHETIC,
> @@ -3205,7 +3205,7 @@
> newTag,
>
> tree.type,
>
> tree.rhs.type);
> - JCExpression expr = lhs;
> + JCExpression expr = (JCExpression)lhs.clone();
> if (expr.type != tree.type)
> expr = make.TypeCast(tree.type, expr);
> JCBinary opResult = make.Binary(newTag, expr,
> tree.rhs);
> @@ -3288,9 +3288,10 @@
> public JCExpression build(final
> JCExpression tmp2) {
> JCTree.Tag opcode = (tree.hasTag(POSTINC))
> ? PLUS_ASG : MINUS_ASG;
> - JCTree lhs = cast
> - ? make.TypeCast(tree.arg.type, tmp1)
> - : tmp1;
> + JCExpression lhs = (JCExpression)tmp1.clone();
> + lhs = cast
> + ? make.TypeCast(tree.arg.type, lhs)
> + : lhs;
> JCExpression update = makeAssignop(opcode,
> lhs,
> make.Literal(1));
More information about the compiler-dev
mailing list