8006960: hotspot, "impossible" assertion failure
Escape state of allocated object should be always adjusted after it was passed to a method. Reviewed-by: kvn
This commit is contained in:
parent
25a0458907
commit
b4420f1516
@ -43,7 +43,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
|
||||
@ -319,14 +319,16 @@ void BCEscapeAnalyzer::invoke(StateInfo &state, Bytecodes::Code code, ciMethod*
|
||||
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);
|
||||
|
@ -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.");
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user