# HG changeset patch # User roland # Date 1485247205 -3600 # Node ID 17e7b1ef5a83d49035422b11707e5e036ca7733f # Parent 7417485c50f9011ae1d66b9dd78cc2178d891ef2 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 diff -r 7417485c50f9 -r 17e7b1ef5a83 hotspot/src/share/vm/opto/macro.cpp --- 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. diff -r 7417485c50f9 -r 17e7b1ef5a83 hotspot/src/share/vm/opto/macro.hpp --- 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) { diff -r 7417485c50f9 -r 17e7b1ef5a83 hotspot/test/compiler/arraycopy/TestArrayCopyUNCBadMem.java --- /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); + } +}