changeset 43483:17e7b1ef5a83

8173147: [ctw] fails during compilation of sun.security.krb5.internal.crypto.RsaMd5DesCksumType::calculateKeyedChecksum with " graph should be schedulable" Summary: Loads generated at uncommon trap from eliminated arraycopy have incorrect memory state Reviewed-by: thartmann
author roland
date Tue, 24 Jan 2017 09:40:05 +0100
parents 7417485c50f9
children 9c95dd31d0da
files hotspot/src/share/vm/opto/macro.cpp hotspot/src/share/vm/opto/macro.hpp hotspot/test/compiler/arraycopy/TestArrayCopyUNCBadMem.java
diffstat 3 files changed, 68 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/hotspot/src/share/vm/opto/macro.cpp	Wed Jan 25 07:05:38 2017 +0100
+++ b/hotspot/src/share/vm/opto/macro.cpp	Tue Jan 24 09:40:05 2017 +0100
@@ -426,7 +426,7 @@
 
 // Generate loads from source of the arraycopy for fields of
 // destination needed at a deoptimization point
-Node* PhaseMacroExpand::make_arraycopy_load(ArrayCopyNode* ac, intptr_t offset, Node* ctl, BasicType ft, const Type *ftype, AllocateNode *alloc) {
+Node* PhaseMacroExpand::make_arraycopy_load(ArrayCopyNode* ac, intptr_t offset, Node* ctl, Node* mem, BasicType ft, const Type *ftype, AllocateNode *alloc) {
   BasicType bt = ft;
   const Type *type = ftype;
   if (ft == T_NARROWOOP) {
@@ -438,8 +438,7 @@
     Node* base = ac->in(ArrayCopyNode::Src)->in(AddPNode::Base);
     Node* adr = _igvn.transform(new AddPNode(base, base, MakeConX(offset)));
     const TypePtr* adr_type = _igvn.type(base)->is_ptr()->add_offset(offset);
-    Node* m = ac->in(TypeFunc::Memory);
-    res = LoadNode::make(_igvn, ctl, m, adr, adr_type, type, bt, MemNode::unordered, LoadNode::Pinned);
+    res = LoadNode::make(_igvn, ctl, mem, adr, adr_type, type, bt, MemNode::unordered, LoadNode::Pinned);
   } else {
     if (ac->modifies(offset, offset, &_igvn, true)) {
       assert(ac->in(ArrayCopyNode::Dest) == alloc->result_cast(), "arraycopy destination should be allocation's result");
@@ -454,8 +453,7 @@
       Node* base = ac->in(ArrayCopyNode::Src);
       Node* adr = _igvn.transform(new AddPNode(base, base, off));
       const TypePtr* adr_type = _igvn.type(base)->is_ptr()->add_offset(offset);
-      Node* m = ac->in(TypeFunc::Memory);
-      res = LoadNode::make(_igvn, ctl, m, adr, adr_type, type, bt, MemNode::unordered, LoadNode::Pinned);
+      res = LoadNode::make(_igvn, ctl, mem, adr, adr_type, type, bt, MemNode::unordered, LoadNode::Pinned);
     }
   }
   if (res != NULL) {
@@ -544,7 +542,7 @@
         assert(false, "Object is not scalar replaceable if a LoadStore node accesses its field");
         return NULL;
       } else if (val->is_ArrayCopy()) {
-        Node* res = make_arraycopy_load(val->as_ArrayCopy(), offset, val->in(0), ft, phi_type, alloc);
+        Node* res = make_arraycopy_load(val->as_ArrayCopy(), offset, val->in(0), val->in(TypeFunc::Memory), ft, phi_type, alloc);
         if (res == NULL) {
           return NULL;
         }
@@ -657,11 +655,13 @@
       }
     } else if (mem->is_ArrayCopy()) {
       Node* ctl = mem->in(0);
+      Node* m = mem->in(TypeFunc::Memory);
       if (sfpt_ctl->is_Proj() && sfpt_ctl->as_Proj()->is_uncommon_trap_proj(Deoptimization::Reason_none)) {
         // pin the loads in the uncommon trap path
         ctl = sfpt_ctl;
+        m = sfpt_mem;
       }
-      return make_arraycopy_load(mem->as_ArrayCopy(), offset, ctl, ft, ftype, alloc);
+      return make_arraycopy_load(mem->as_ArrayCopy(), offset, ctl, m, ft, ftype, alloc);
     }
   }
   // Something go wrong.
--- a/hotspot/src/share/vm/opto/macro.hpp	Wed Jan 25 07:05:38 2017 +0100
+++ b/hotspot/src/share/vm/opto/macro.hpp	Tue Jan 24 09:40:05 2017 +0100
@@ -200,7 +200,7 @@
                             Node* old_eden_top, Node* new_eden_top,
                             Node* length);
 
-  Node* make_arraycopy_load(ArrayCopyNode* ac, intptr_t offset, Node* ctl, BasicType ft, const Type *ftype, AllocateNode *alloc);
+  Node* make_arraycopy_load(ArrayCopyNode* ac, intptr_t offset, Node* ctl, Node* mem, BasicType ft, const Type *ftype, AllocateNode *alloc);
 
 public:
   PhaseMacroExpand(PhaseIterGVN &igvn) : Phase(Macro_Expand), _igvn(igvn), _has_locks(false) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/arraycopy/TestArrayCopyUNCBadMem.java	Tue Jan 24 09:40:05 2017 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2017, Red Hat, Inc. 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 8173147
+ * @summary Loads generated at uncommon trap from eliminated arraycopy have incorrect memory state
+ * @run main/othervm -XX:CompileOnly=TestArrayCopyUNCBadMem::test -Xcomp TestArrayCopyUNCBadMem
+ *
+ */
+
+
+public class TestArrayCopyUNCBadMem {
+
+    volatile static int field;
+
+    static class unloaded {
+        static int dummy;
+    }
+
+    static int test(int[] input) {
+        int[] alloc = new int[10];
+        System.arraycopy(input, 0, alloc, 0, 10);
+
+        // membars to have anti-dependence edges and make scheduling
+        // fail
+        field = 0x42;
+
+        // uncommon trap
+        unloaded.dummy = 0x42;
+
+        return alloc[0] + alloc[1];
+    }
+
+    public static void main(String[] args) {
+        int[] array = new int[10];
+        System.arraycopy(array, 0, array, 0, 0); // load System class
+        test(array);
+    }
+}