8134031: Incorrect JIT compilation of complex code with inlining and escape analysis
Summary: Bad rewiring of memory edges when we split unique types during EA
Reviewed-by: kvn
--- a/hotspot/src/share/vm/opto/escape.cpp Wed Sep 02 15:11:22 2015 -0700
+++ b/hotspot/src/share/vm/opto/escape.cpp Mon Aug 31 17:20:08 2015 +0200
@@ -3241,7 +3241,7 @@
// Note 2: MergeMem may already contains instance memory slices added
// during find_inst_mem() call when memory nodes were processed above.
igvn->hash_delete(nmm);
- uint nslices = nmm->req();
+ uint nslices = MIN2(nmm->req(), new_index_start);
for (uint i = Compile::AliasIdxRaw+1; i < nslices; i++) {
Node* mem = nmm->in(i);
Node* cur = NULL;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/escapeAnalysis/TestEABadMergeMem.java Mon Aug 31 17:20:08 2015 +0200
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8134031
+ * @summary Bad rewiring of memory edges when we split unique types during EA
+ * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:CompileCommand=dontinline,TestEABadMergeMem::m_notinlined TestEABadMergeMem
+ *
+ */
+
+public class TestEABadMergeMem {
+
+ static class Box {
+ int i;
+ }
+
+ static void m_notinlined() {
+ }
+
+ static float dummy1;
+ static float dummy2;
+
+ static int test(Box a, Box c, int i, int j, int k, boolean flag1, boolean flag2) {
+ Box b = new Box(); // non escaping
+ a.i = i;
+ b.i = j;
+ c.i = k;
+
+ m_notinlined();
+
+ boolean flag3 = false;
+ if (flag1) {
+ for (int ii = 0; ii < 100; ii++) {
+ if (flag2) {
+ dummy1 = (float)ii;
+ } else {
+ dummy2 = (float)ii;
+ }
+ }
+ flag3 = true;
+ }
+ // Memory Phi here with projection of not inlined call as one edge, MergeMem as other
+
+ if (flag3) { // will split through Phi during loopopts
+ int res = c.i + b.i;
+ m_notinlined(); // prevents split through phi during igvn
+ return res;
+ } else {
+ return 44 + 43;
+ }
+ }
+
+ static public void main(String[] args) {
+ for (int i = 0; i < 20000; i++) {
+ // m(2);
+ Box a = new Box();
+ Box c = new Box();
+ int res = test(a, c, 42, 43, 44, (i%2) == 0, (i%3) == 0);
+ if (res != 44 + 43) {
+ throw new RuntimeException("Bad result " + res);
+ }
+ }
+ }
+
+}