Mercurial > hg > graal-jvmci-8
changeset 22876:364f6c28effb
8006960: hotspot, "impossible" assertion failure
Summary: Escape state of allocated object should be always adjusted after it was passed to a method.
Reviewed-by: kvn
author | thartmann |
---|---|
date | Mon, 02 Mar 2015 13:40:40 +0100 |
parents | deddcc0c31e3 |
children | d68158e12cea |
files | src/share/vm/ci/bcEscapeAnalyzer.cpp test/compiler/escapeAnalysis/TestEscapeThroughInvoke.java |
diffstat | 2 files changed, 79 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/vm/ci/bcEscapeAnalyzer.cpp Tue Mar 03 19:42:09 2015 +0000 +++ b/src/share/vm/ci/bcEscapeAnalyzer.cpp Mon Mar 02 13:40:40 2015 +0100 @@ -42,7 +42,7 @@ #define TRACE_BCEA(level, code) #endif -// Maintain a map of which aguments a local variable or +// Maintain a map of which arguments a local variable or // stack slot may contain. In addition to tracking // arguments, it tracks two special values, "allocated" // which represents any object allocated in the current @@ -318,14 +318,16 @@ bool must_record_dependencies = false; for (i = arg_size - 1; i >= 0; i--) { ArgumentMap arg = state.raw_pop(); - if (!is_argument(arg)) + // Check if callee arg is a caller arg or an allocated object + bool allocated = arg.contains_allocated(); + if (!(is_argument(arg) || allocated)) continue; for (int j = 0; j < _arg_size; j++) { if (arg.contains(j)) { _arg_modified[j] |= analyzer._arg_modified[i]; } } - if (!is_arg_stack(arg)) { + if (!(is_arg_stack(arg) || allocated)) { // arguments have already been recognized as escaping } else if (analyzer.is_arg_stack(i) && !analyzer.is_arg_returned(i)) { set_method_escape(arg);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/escapeAnalysis/TestEscapeThroughInvoke.java Mon Mar 02 13:40:40 2015 +0100 @@ -0,0 +1,74 @@ +/* + * 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 8073956 + * @summary Tests C2 EA with allocated object escaping through a call. + * @run main/othervm -XX:CompileCommand=dontinline,TestEscapeThroughInvoke::create TestEscapeThroughInvoke + */ +public class TestEscapeThroughInvoke { + private A a; + + public static void main(String[] args) { + TestEscapeThroughInvoke test = new TestEscapeThroughInvoke(); + test.a = new A(42); + // Make sure run gets compiled by C2 + for (int i = 0; i < 100_000; ++i) { + test.run(); + } + } + + private void run() { + // Allocate something to trigger EA + new Object(); + // Create a new escaping instance of A and + // verify that it is always equal to 'a.saved'. + A escapingA = create(42); + a.check(escapingA); + } + + // Create and return a new instance of A that escaped through 'A::saveInto'. + // The 'dummy' parameters are needed to avoid EA skipping the methods. + private A create(Integer dummy) { + A result = new A(dummy); + result.saveInto(a, dummy); // result escapes into 'a' here + return result; + } +} + +class A { + private A saved; + + public A(Integer dummy) { } + + public void saveInto(A other, Integer dummy) { + other.saved = this; + } + + public void check(A other) { + if (this.saved != other) { + throw new RuntimeException("TEST FAILED: Objects not equal."); + } + } +}