[PATCH] 8147527: Non-optimal code generated for postfix unary operators
bsrbnd
bsrbnd at gmail.com
Sat Nov 12 16:58:08 UTC 2016
Hi,
2016-11-03 14:45 GMT+01:00 Jan Lahoda <jan.lahoda at oracle.com>:
> Hi Bernard,
>
> Thanks for looking at this. For the avoidance of the modification of
> tree.selected in Lower.visitSelect, what I meant was more that we would
> create a new instance of JCFieldAccess, to carry the new select. Might be
> easier that trying to work with the existing select.
>
> I think it might be useful to have a set of tests covering the usecases, so
> that we can more easily test patches (we will need tests eventually anyway).
> I can look at that, unless you want to.
>
Next is a test (derived from issue 8143388 test, too) for the
optimization of "super" and "this$n".
In this case, the test() method has to be examined instruction by
instruction as explained in comments within the test.
Bernard
diff --git a/test/tools/javac/boxing/BoxedPostOpOpti2.java
b/test/tools/javac/boxing/BoxedPostOpOpti2.java
new file mode 100644
--- /dev/null
+++ b/test/tools/javac/boxing/BoxedPostOpOpti2.java
@@ -0,0 +1,114 @@
+/*
+ * @test
+ * @bug 8147527
+ * @summary "super" and "this$n" code optimization for boxed unary
post-operations.
+ * @library /tools/lib
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ * jdk.compiler/com.sun.tools.javac.main
+ * jdk.jdeps/com.sun.tools.javap
+ * jdk.jdeps/com.sun.tools.classfile
+ * @build toolbox.ToolBox toolbox.JavacTask
+ * @run main BoxedPostOpOpti2
+ */
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.*;
+
+import toolbox.JavacTask;
+import toolbox.ToolBox;
+
+import com.sun.tools.classfile.*;
+
+public class BoxedPostOpOpti2 {
+ public static void main(String... args) throws Exception {
+ new BoxedPostOpOpti2().run();
+ }
+
+ void run() throws Exception {
+ ToolBox tb = new ToolBox();
+
+ Path expected = Paths.get("expected");
+ Files.createDirectories(expected);
+ tb.cleanDirectory(expected);
+ new JavacTask(tb).sources(
+ "package p1;" +
+ "public class P {" +
+ " protected Integer j=20;" +
+ "}",
+ "package p2;" +
+ "class C extends p1.P {" +
+ " private Integer test() {" +
+ " return j++;" +
+ " }" +
+ " class Inner {" +
+ " private Integer test() {" +
+ " return j++;" +
+ " }" +
+ " }" +
+ "}"
+ ).outdir(expected).run();
+
+ Path actual = Paths.get("actual");
+ Files.createDirectories(actual);
+ tb.cleanDirectory(actual);
+ new JavacTask(tb).sources(
+ "package p1;" +
+ "public class P {" +
+ " protected Integer j=20;" +
+ "}",
+ "package p2;" +
+ "class C extends p1.P {" +
+ " private Integer test() {" +
+ " return super.j++;" +
+ " }" +
+ " class Inner {" +
+ " private Integer test() {" +
+ " return C.super.j++;" +
+ " }" +
+ " }" +
+ "}"
+ ).outdir(actual).run();
+
+ String error = "", sep = "";
+ for (Path p1: tb.findFiles(".class", expected)) {
+ for (Path p2: tb.findFiles(p1.getFileName().toString(), actual)) {
+ ClassFile c1 = ClassFile.read(p1);
+ ClassFile c2 = ClassFile.read(p2);
+ Method m1 = test(c1), m2 = test(c2);
+
+ if (m1 != null && m2 != null) {
+ Code_attribute code1 =
(Code_attribute)m1.attributes.get(Attribute.Code);
+ Code_attribute code2 =
(Code_attribute)m2.attributes.get(Attribute.Code);
+
+ Iterator<Instruction> it1 =
code1.getInstructions().iterator();
+ Iterator<Instruction> it2 =
code2.getInstructions().iterator();
+ Instruction i1 = it1.next(), i2 = it2.next();
+ boolean same = true;
+ for (; it1.hasNext() && it2.hasNext();
i1=it1.next(), i2=it2.next()) {
+ // Checks only matching of instruction's opcode since:
+ // - accessor's name might be different
depending on "qualified super" selection.
+ // - accessed field might be different
depending on "super" selection.
+ same &= i1.getOpcode().opcode == i2.getOpcode().opcode;
+ }
+ same &= !it1.hasNext() && !it2.hasNext();
+ if (!same) {
+ error += sep + p1 + " differs from " + p2;
+ sep = ", ";
+ }
+ }
+ }
+ }
+ if (error.length() > 0) throw new Error(error);
+ }
+
+ Method test(ClassFile c) throws ConstantPoolException {
+ for (Method m: c.methods) {
+ if (m.getName(c.constant_pool).equals("test"))
+ return m;
+ }
+ return null;
+ }
+}
More information about the compiler-dev
mailing list