提交 17d41f99 编写于 作者: M morris

Merge

...@@ -138,6 +138,16 @@ bool BCEscapeAnalyzer::is_arg_stack(ArgumentMap vars){ ...@@ -138,6 +138,16 @@ bool BCEscapeAnalyzer::is_arg_stack(ArgumentMap vars){
return false; return false;
} }
// return true if all argument elements of vars are returned
bool BCEscapeAnalyzer::returns_all(ArgumentMap vars) {
for (int i = 0; i < _arg_size; i++) {
if (vars.contains(i) && !_arg_returned.test(i)) {
return false;
}
}
return true;
}
void BCEscapeAnalyzer::clear_bits(ArgumentMap vars, VectorSet &bm) { void BCEscapeAnalyzer::clear_bits(ArgumentMap vars, VectorSet &bm) {
for (int i = 0; i < _arg_size; i++) { for (int i = 0; i < _arg_size; i++) {
if (vars.contains(i)) { if (vars.contains(i)) {
...@@ -166,6 +176,11 @@ void BCEscapeAnalyzer::set_global_escape(ArgumentMap vars, bool merge) { ...@@ -166,6 +176,11 @@ void BCEscapeAnalyzer::set_global_escape(ArgumentMap vars, bool merge) {
if (vars.contains_unknown() || vars.contains_vars()) { if (vars.contains_unknown() || vars.contains_vars()) {
_return_allocated = false; _return_allocated = false;
} }
if (_return_local && vars.contains_vars() && !returns_all(vars)) {
// Return result should be invalidated if args in new
// state are not recorded in return state.
_return_local = false;
}
} }
} }
......
...@@ -80,6 +80,7 @@ class BCEscapeAnalyzer : public ResourceObj { ...@@ -80,6 +80,7 @@ class BCEscapeAnalyzer : public ResourceObj {
void set_returned(ArgumentMap vars); void set_returned(ArgumentMap vars);
bool is_argument(ArgumentMap vars); bool is_argument(ArgumentMap vars);
bool is_arg_stack(ArgumentMap vars); bool is_arg_stack(ArgumentMap vars);
bool returns_all(ArgumentMap vars);
void clear_bits(ArgumentMap vars, VectorSet &bs); void clear_bits(ArgumentMap vars, VectorSet &bs);
void set_method_escape(ArgumentMap vars); void set_method_escape(ArgumentMap vars);
void set_global_escape(ArgumentMap vars, bool merge = false); void set_global_escape(ArgumentMap vars, bool merge = false);
......
...@@ -2305,26 +2305,26 @@ void Matcher::validate_null_checks( ) { ...@@ -2305,26 +2305,26 @@ void Matcher::validate_null_checks( ) {
// atomic instruction acting as a store_load barrier without any // atomic instruction acting as a store_load barrier without any
// intervening volatile load, and thus we don't need a barrier here. // intervening volatile load, and thus we don't need a barrier here.
// We retain the Node to act as a compiler ordering barrier. // We retain the Node to act as a compiler ordering barrier.
bool Matcher::post_store_load_barrier(const Node *vmb) { bool Matcher::post_store_load_barrier(const Node* vmb) {
Compile *C = Compile::current(); Compile* C = Compile::current();
assert( vmb->is_MemBar(), "" ); assert(vmb->is_MemBar(), "");
assert( vmb->Opcode() != Op_MemBarAcquire, "" ); assert(vmb->Opcode() != Op_MemBarAcquire, "");
const MemBarNode *mem = (const MemBarNode*)vmb; const MemBarNode* membar = vmb->as_MemBar();
// Get the Proj node, ctrl, that can be used to iterate forward // Get the Ideal Proj node, ctrl, that can be used to iterate forward
Node *ctrl = NULL; Node* ctrl = NULL;
DUIterator_Fast imax, i = mem->fast_outs(imax); for (DUIterator_Fast imax, i = membar->fast_outs(imax); i < imax; i++) {
while( true ) { Node* p = membar->fast_out(i);
ctrl = mem->fast_out(i); // Throw out-of-bounds if proj not found assert(p->is_Proj(), "only projections here");
assert( ctrl->is_Proj(), "only projections here" ); if ((p->as_Proj()->_con == TypeFunc::Control) &&
ProjNode *proj = (ProjNode*)ctrl; !C->node_arena()->contains(p)) { // Unmatched old-space only
if( proj->_con == TypeFunc::Control && ctrl = p;
!C->node_arena()->contains(ctrl) ) // Unmatched old-space only
break; break;
i++; }
} }
assert((ctrl != NULL), "missing control projection");
for( DUIterator_Fast jmax, j = ctrl->fast_outs(jmax); j < jmax; j++ ) { for (DUIterator_Fast jmax, j = ctrl->fast_outs(jmax); j < jmax; j++) {
Node *x = ctrl->fast_out(j); Node *x = ctrl->fast_out(j);
int xop = x->Opcode(); int xop = x->Opcode();
...@@ -2336,37 +2336,36 @@ bool Matcher::post_store_load_barrier(const Node *vmb) { ...@@ -2336,37 +2336,36 @@ bool Matcher::post_store_load_barrier(const Node *vmb) {
// that a monitor exit operation contains a serializing instruction. // that a monitor exit operation contains a serializing instruction.
if (xop == Op_MemBarVolatile || if (xop == Op_MemBarVolatile ||
xop == Op_FastLock ||
xop == Op_CompareAndSwapL || xop == Op_CompareAndSwapL ||
xop == Op_CompareAndSwapP || xop == Op_CompareAndSwapP ||
xop == Op_CompareAndSwapN || xop == Op_CompareAndSwapN ||
xop == Op_CompareAndSwapI) xop == Op_CompareAndSwapI) {
return true; return true;
}
// Op_FastLock previously appeared in the Op_* list above.
// With biased locking we're no longer guaranteed that a monitor
// enter operation contains a serializing instruction.
if ((xop == Op_FastLock) && !UseBiasedLocking) {
return true;
}
if (x->is_MemBar()) { if (x->is_MemBar()) {
// We must retain this membar if there is an upcoming volatile // We must retain this membar if there is an upcoming volatile
// load, which will be preceded by acquire membar. // load, which will be followed by acquire membar.
if (xop == Op_MemBarAcquire) if (xop == Op_MemBarAcquire) {
return false; return false;
// For other kinds of barriers, check by pretending we } else {
// are them, and seeing if we can be removed. // For other kinds of barriers, check by pretending we
else // are them, and seeing if we can be removed.
return post_store_load_barrier((const MemBarNode*)x); return post_store_load_barrier(x->as_MemBar());
}
} }
// Delicate code to detect case of an upcoming fastlock block
if( x->is_If() && x->req() > 1 &&
!C->node_arena()->contains(x) ) { // Unmatched old-space only
Node *iff = x;
Node *bol = iff->in(1);
// The iff might be some random subclass of If or bol might be Con-Top
if (!bol->is_Bool()) return false;
assert( bol->req() > 1, "" );
return (bol->in(1)->Opcode() == Op_FastUnlock);
}
// probably not necessary to check for these // probably not necessary to check for these
if (x->is_Call() || x->is_SafePoint() || x->is_block_proj()) if (x->is_Call() || x->is_SafePoint() || x->is_block_proj()) {
return false; return false;
}
} }
return false; return false;
} }
......
...@@ -294,25 +294,7 @@ void Parse::do_put_xxx(Node* obj, ciField* field, bool is_field) { ...@@ -294,25 +294,7 @@ void Parse::do_put_xxx(Node* obj, ciField* field, bool is_field) {
// If reference is volatile, prevent following volatiles ops from // If reference is volatile, prevent following volatiles ops from
// floating up before the volatile write. // floating up before the volatile write.
if (is_vol) { if (is_vol) {
// First place the specific membar for THIS volatile index. This first insert_mem_bar(Op_MemBarVolatile); // Use fat membar
// membar is dependent on the store, keeping any other membars generated
// below from floating up past the store.
int adr_idx = C->get_alias_index(adr_type);
insert_mem_bar_volatile(Op_MemBarVolatile, adr_idx, store);
// Now place a membar for AliasIdxBot for the unknown yet-to-be-parsed
// volatile alias indices. Skip this if the membar is redundant.
if (adr_idx != Compile::AliasIdxBot) {
insert_mem_bar_volatile(Op_MemBarVolatile, Compile::AliasIdxBot, store);
}
// Finally, place alias-index-specific membars for each volatile index
// that isn't the adr_idx membar. Typically there's only 1 or 2.
for( int i = Compile::AliasIdxRaw; i < C->num_alias_types(); i++ ) {
if (i != adr_idx && C->alias_type(i)->is_volatile()) {
insert_mem_bar_volatile(Op_MemBarVolatile, i, store);
}
}
} }
// If the field is final, the rules of Java say we are in <init> or <clinit>. // If the field is final, the rules of Java say we are in <init> or <clinit>.
......
/*
* Copyright (c) 2013, 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 8020215
* @summary Different execution plan when using JIT vs interpreter
* @run main Test8020215
*/
import java.util.ArrayList;
import java.util.List;
public class Test8020215 {
public static class NamedObject {
public int id;
public String name;
public NamedObject(int id, String name) {
this.id = id;
this.name = name;
}
}
public static class NamedObjectList {
public List<NamedObject> namedObjectList = new ArrayList<NamedObject>();
public NamedObject getBest(int id) {
NamedObject bestObject = null;
for (NamedObject o : namedObjectList) {
bestObject = id==o.id ? getBetter(bestObject, o) : bestObject;
}
return (bestObject != null) ? bestObject : null;
}
private static NamedObject getBetter(NamedObject p1, NamedObject p2) {
return (p1 == null) ? p2 : (p2 == null) ? p1 : (p2.name.compareTo(p1.name) >= 0) ? p2 : p1;
}
}
static void test(NamedObjectList b, int i) {
NamedObject x = b.getBest(2);
// test
if (x == null) {
throw new RuntimeException("x should never be null here! (i=" + i + ")");
}
}
public static void main(String[] args) {
// setup
NamedObjectList b = new NamedObjectList();
for (int i = 0; i < 10000; i++) {
b.namedObjectList.add(new NamedObject(1, "2012-12-31"));
}
b.namedObjectList.add(new NamedObject(2, "2013-12-31"));
// execution
for (int i = 0; i < 12000; i++) {
test(b, i);
}
System.out.println("PASSED");
}
}
/*
* Copyright 2013 SAP AG. 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 8007898
* @summary Incorrect optimization of Memory Barriers in Matcher::post_store_load_barrier().
* @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest
* @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest
* @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest
* @author Martin Doerr martin DOT doerr AT sap DOT com
*
* Run 3 times since the failure is intermittent.
*/
public class DekkerTest {
/*
Read After Write Test (basically a simple Dekker test with volatile variables)
Derived from the original jcstress test, available at:
http://hg.openjdk.java.net/code-tools/jcstress/file/6c339a5aa00d/
tests-custom/src/main/java/org/openjdk/jcstress/tests/volatiles/DekkerTest.java
*/
static final int ITERATIONS = 1000000;
static class TestData {
public volatile int a;
public volatile int b;
}
static class ResultData {
public int a;
public int b;
}
TestData[] testDataArray;
ResultData[] results;
volatile boolean start;
public DekkerTest() {
testDataArray = new TestData[ITERATIONS];
results = new ResultData[ITERATIONS];
for (int i = 0; i < ITERATIONS; ++i) {
testDataArray[i] = new TestData();
results[i] = new ResultData();
}
start = false;
}
public void reset() {
for (int i = 0; i < ITERATIONS; ++i) {
testDataArray[i].a = 0;
testDataArray[i].b = 0;
results[i].a = 0;
results[i].b = 0;
}
start = false;
}
int actor1(TestData t) {
t.a = 1;
return t.b;
}
int actor2(TestData t) {
t.b = 1;
return t.a;
}
class Runner1 extends Thread {
public void run() {
do {} while (!start);
for (int i = 0; i < ITERATIONS; ++i) {
results[i].a = actor1(testDataArray[i]);
}
}
}
class Runner2 extends Thread {
public void run() {
do {} while (!start);
for (int i = 0; i < ITERATIONS; ++i) {
results[i].b = actor2(testDataArray[i]);
}
}
}
void testRunner() {
Thread thread1 = new Runner1();
Thread thread2 = new Runner2();
thread1.start();
thread2.start();
do {} while (!thread1.isAlive());
do {} while (!thread2.isAlive());
start = true;
Thread.yield();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
System.out.println("interrupted!");
System.exit(1);
}
}
boolean printResult() {
int[] count = new int[4];
for (int i = 0; i < ITERATIONS; ++i) {
int event_kind = (results[i].a << 1) + results[i].b;
++count[event_kind];
}
if (count[0] == 0 && count[3] == 0) {
System.out.println("[not interesting]");
return false; // not interesting
}
String error = (count[0] == 0) ? " ok" : " disallowed!";
System.out.println("[0,0] " + count[0] + error);
System.out.println("[0,1] " + count[1]);
System.out.println("[1,0] " + count[2]);
System.out.println("[1,1] " + count[3]);
return (count[0] != 0);
}
public static void main(String args[]) {
DekkerTest test = new DekkerTest();
final int runs = 30;
int failed = 0;
for (int c = 0; c < runs; ++c) {
test.testRunner();
if (test.printResult()) {
failed++;
}
test.reset();
}
if (failed > 0) {
throw new InternalError("FAILED. Got " + failed + " failed ITERATIONS");
}
System.out.println("PASSED.");
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册