mirror of
https://github.com/openjdk/jdk.git
synced 2026-04-24 13:51:12 +00:00
8333791: Fix memory barriers for @Stable fields
Reviewed-by: liach, vlivanov
This commit is contained in:
parent
da7311bbe3
commit
74fdd6868d
@ -1563,7 +1563,7 @@ void GraphBuilder::method_return(Value x, bool ignore_return) {
|
||||
// The conditions for a memory barrier are described in Parse::do_exits().
|
||||
bool need_mem_bar = false;
|
||||
if (method()->name() == ciSymbols::object_initializer_name() &&
|
||||
(scope()->wrote_final() ||
|
||||
(scope()->wrote_final() || scope()->wrote_stable() ||
|
||||
(AlwaysSafeConstructors && scope()->wrote_fields()) ||
|
||||
(support_IRIW_for_not_multiple_copy_atomic_cpu && scope()->wrote_volatile()))) {
|
||||
need_mem_bar = true;
|
||||
@ -1741,15 +1741,17 @@ void GraphBuilder::access_field(Bytecodes::Code code) {
|
||||
}
|
||||
}
|
||||
|
||||
if (field->is_final() && (code == Bytecodes::_putfield)) {
|
||||
scope()->set_wrote_final();
|
||||
}
|
||||
|
||||
if (code == Bytecodes::_putfield) {
|
||||
scope()->set_wrote_fields();
|
||||
if (field->is_volatile()) {
|
||||
scope()->set_wrote_volatile();
|
||||
}
|
||||
if (field->is_final()) {
|
||||
scope()->set_wrote_final();
|
||||
}
|
||||
if (field->is_stable()) {
|
||||
scope()->set_wrote_stable();
|
||||
}
|
||||
}
|
||||
|
||||
const int offset = !needs_patching ? field->offset_in_bytes() : -1;
|
||||
|
||||
@ -146,6 +146,7 @@ IRScope::IRScope(Compilation* compilation, IRScope* caller, int caller_bci, ciMe
|
||||
_wrote_final = false;
|
||||
_wrote_fields = false;
|
||||
_wrote_volatile = false;
|
||||
_wrote_stable = false;
|
||||
_start = nullptr;
|
||||
|
||||
if (osr_bci != -1) {
|
||||
|
||||
@ -149,6 +149,7 @@ class IRScope: public CompilationResourceObj {
|
||||
bool _wrote_final; // has written final field
|
||||
bool _wrote_fields; // has written fields
|
||||
bool _wrote_volatile; // has written volatile field
|
||||
bool _wrote_stable; // has written @Stable field
|
||||
BlockBegin* _start; // the start block, successsors are method entries
|
||||
|
||||
ResourceBitMap _requires_phi_function; // bit is set if phi functions at loop headers are necessary for a local variable
|
||||
@ -187,6 +188,8 @@ class IRScope: public CompilationResourceObj {
|
||||
bool wrote_fields () const { return _wrote_fields; }
|
||||
void set_wrote_volatile() { _wrote_volatile = true; }
|
||||
bool wrote_volatile () const { return _wrote_volatile; }
|
||||
void set_wrote_stable() { _wrote_stable = true; }
|
||||
bool wrote_stable() const { return _wrote_stable; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -358,7 +358,7 @@ class Parse : public GraphKit {
|
||||
bool _wrote_volatile; // Did we write a volatile field?
|
||||
bool _wrote_stable; // Did we write a @Stable field?
|
||||
bool _wrote_fields; // Did we write any field?
|
||||
Node* _alloc_with_final; // An allocation node with final field
|
||||
Node* _alloc_with_final_or_stable; // An allocation node with final or @Stable field
|
||||
|
||||
// Variables which track Java semantics during bytecode parsing:
|
||||
|
||||
@ -403,10 +403,10 @@ class Parse : public GraphKit {
|
||||
void set_wrote_stable(bool z) { _wrote_stable = z; }
|
||||
bool wrote_fields() const { return _wrote_fields; }
|
||||
void set_wrote_fields(bool z) { _wrote_fields = z; }
|
||||
Node* alloc_with_final() const { return _alloc_with_final; }
|
||||
void set_alloc_with_final(Node* n) {
|
||||
assert((_alloc_with_final == nullptr) || (_alloc_with_final == n), "different init objects?");
|
||||
_alloc_with_final = n;
|
||||
Node* alloc_with_final_or_stable() const { return _alloc_with_final_or_stable; }
|
||||
void set_alloc_with_final_or_stable(Node* n) {
|
||||
assert((_alloc_with_final_or_stable == nullptr) || (_alloc_with_final_or_stable == n), "different init objects?");
|
||||
_alloc_with_final_or_stable = n;
|
||||
}
|
||||
|
||||
Block* block() const { return _block; }
|
||||
|
||||
@ -412,7 +412,7 @@ Parse::Parse(JVMState* caller, ciMethod* parse_method, float expected_uses)
|
||||
_wrote_volatile = false;
|
||||
_wrote_stable = false;
|
||||
_wrote_fields = false;
|
||||
_alloc_with_final = nullptr;
|
||||
_alloc_with_final_or_stable = nullptr;
|
||||
_block = nullptr;
|
||||
_first_return = true;
|
||||
_replaced_nodes_for_exceptions = false;
|
||||
@ -988,8 +988,8 @@ void Parse::do_exits() {
|
||||
// Figure out if we need to emit the trailing barrier. The barrier is only
|
||||
// needed in the constructors, and only in three cases:
|
||||
//
|
||||
// 1. The constructor wrote a final. The effects of all initializations
|
||||
// must be committed to memory before any code after the constructor
|
||||
// 1. The constructor wrote a final or a @Stable field. All these
|
||||
// initializations must be ordered before any code after the constructor
|
||||
// publishes the reference to the newly constructed object. Rather
|
||||
// than wait for the publication, we simply block the writes here.
|
||||
// Rather than put a barrier on only those writes which are required
|
||||
@ -1014,34 +1014,23 @@ void Parse::do_exits() {
|
||||
// exceptional returns, since they cannot publish normally.
|
||||
//
|
||||
if (method()->is_object_initializer() &&
|
||||
(wrote_final() ||
|
||||
(wrote_final() || wrote_stable() ||
|
||||
(AlwaysSafeConstructors && wrote_fields()) ||
|
||||
(support_IRIW_for_not_multiple_copy_atomic_cpu && wrote_volatile()))) {
|
||||
Node* recorded_alloc = alloc_with_final_or_stable();
|
||||
_exits.insert_mem_bar(UseStoreStoreForCtor ? Op_MemBarStoreStore : Op_MemBarRelease,
|
||||
alloc_with_final());
|
||||
recorded_alloc);
|
||||
|
||||
// If Memory barrier is created for final fields write
|
||||
// and allocation node does not escape the initialize method,
|
||||
// then barrier introduced by allocation node can be removed.
|
||||
if (DoEscapeAnalysis && alloc_with_final()) {
|
||||
AllocateNode* alloc = AllocateNode::Ideal_allocation(alloc_with_final());
|
||||
if (DoEscapeAnalysis && (recorded_alloc != nullptr)) {
|
||||
AllocateNode* alloc = AllocateNode::Ideal_allocation(recorded_alloc);
|
||||
alloc->compute_MemBar_redundancy(method());
|
||||
}
|
||||
if (PrintOpto && (Verbose || WizardMode)) {
|
||||
method()->print_name();
|
||||
tty->print_cr(" writes finals and needs a memory barrier");
|
||||
}
|
||||
}
|
||||
|
||||
// Any method can write a @Stable field; insert memory barriers
|
||||
// after those also. Can't bind predecessor allocation node (if any)
|
||||
// with barrier because allocation doesn't always dominate
|
||||
// MemBarRelease.
|
||||
if (wrote_stable()) {
|
||||
_exits.insert_mem_bar(Op_MemBarRelease);
|
||||
if (PrintOpto && (Verbose || WizardMode)) {
|
||||
method()->print_name();
|
||||
tty->print_cr(" writes @Stable and needs a memory barrier");
|
||||
tty->print_cr(" writes finals/@Stable and needs a memory barrier");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -236,22 +236,25 @@ void Parse::do_put_xxx(Node* obj, ciField* field, bool is_field) {
|
||||
set_wrote_fields(true);
|
||||
|
||||
// If the field is final, the rules of Java say we are in <init> or <clinit>.
|
||||
// Note the presence of writes to final non-static fields, so that we
|
||||
// If the field is @Stable, we can be in any method, but we only care about
|
||||
// constructors at this point.
|
||||
//
|
||||
// Note the presence of writes to final/@Stable non-static fields, so that we
|
||||
// can insert a memory barrier later on to keep the writes from floating
|
||||
// out of the constructor.
|
||||
// Any method can write a @Stable field; insert memory barriers after those also.
|
||||
if (field->is_final()) {
|
||||
set_wrote_final(true);
|
||||
if (field->is_final() || field->is_stable()) {
|
||||
if (field->is_final()) {
|
||||
set_wrote_final(true);
|
||||
}
|
||||
if (field->is_stable()) {
|
||||
set_wrote_stable(true);
|
||||
}
|
||||
if (AllocateNode::Ideal_allocation(obj) != nullptr) {
|
||||
// Preserve allocation ptr to create precedent edge to it in membar
|
||||
// generated on exit from constructor.
|
||||
// Can't bind stable with its allocation, only record allocation for final field.
|
||||
set_alloc_with_final(obj);
|
||||
set_alloc_with_final_or_stable(obj);
|
||||
}
|
||||
}
|
||||
if (field->is_stable()) {
|
||||
set_wrote_stable(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright Amazon.com Inc. 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 8333791
|
||||
* @requires os.arch=="aarch64" | os.arch=="riscv64" | os.arch=="x86_64" | os.arch=="amd64"
|
||||
* @requires vm.gc.Parallel
|
||||
* @requires vm.compiler2.enabled
|
||||
* @summary Check stable field folding and barriers
|
||||
* @modules java.base/jdk.internal.vm.annotation
|
||||
* @library /test/lib /
|
||||
* @run driver compiler.c2.irTests.stable.StablePrimArrayTest
|
||||
*/
|
||||
|
||||
package compiler.c2.irTests.stable;
|
||||
|
||||
import compiler.lib.ir_framework.*;
|
||||
import jdk.test.lib.Asserts;
|
||||
|
||||
import jdk.internal.vm.annotation.Stable;
|
||||
|
||||
public class StablePrimArrayTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
TestFramework tf = new TestFramework();
|
||||
tf.addTestClassesToBootClassPath();
|
||||
tf.addFlags(
|
||||
"-XX:+UnlockExperimentalVMOptions",
|
||||
"-XX:CompileThreshold=100",
|
||||
"-XX:-TieredCompilation",
|
||||
"-XX:+UseParallelGC"
|
||||
);
|
||||
tf.start();
|
||||
}
|
||||
|
||||
static final int[] EMPTY_INTEGER = new int[] { 0 };
|
||||
static final int[] FULL_INTEGER = new int[] { 42 };
|
||||
|
||||
static class Carrier {
|
||||
@Stable
|
||||
int[] field;
|
||||
|
||||
@ForceInline
|
||||
public Carrier(int initLevel) {
|
||||
switch (initLevel) {
|
||||
case 0:
|
||||
// Do nothing.
|
||||
break;
|
||||
case 1:
|
||||
field = EMPTY_INTEGER;
|
||||
break;
|
||||
case 2:
|
||||
field = FULL_INTEGER;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unknown level");
|
||||
}
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
public void initEmpty() {
|
||||
field = EMPTY_INTEGER;
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
public void initFull() {
|
||||
field = FULL_INTEGER;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static final Carrier BLANK_CARRIER = new Carrier(0);
|
||||
static final Carrier INIT_EMPTY_CARRIER = new Carrier(1);
|
||||
static final Carrier INIT_FULL_CARRIER = new Carrier(2);
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.LOAD, ">0" })
|
||||
@IR(failOn = { IRNode.MEMBAR })
|
||||
static int testNoFold() {
|
||||
// Access should not be folded.
|
||||
// No barriers expected for plain fields.
|
||||
int[] is = BLANK_CARRIER.field;
|
||||
if (is != null) {
|
||||
return is[0];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.LOAD, ">0" })
|
||||
@IR(failOn = { IRNode.MEMBAR })
|
||||
static int testPartialFold() {
|
||||
// Access should not be folded.
|
||||
// No barriers expected for plain fields.
|
||||
int[] is = INIT_EMPTY_CARRIER.field;
|
||||
if (is != null) {
|
||||
return is[0];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@IR(failOn = { IRNode.LOAD, IRNode.MEMBAR })
|
||||
static int testFold() {
|
||||
// Access should be completely folded.
|
||||
int[] is = INIT_FULL_CARRIER.field;
|
||||
if (is != null) {
|
||||
return is[0];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.MEMBAR_STORESTORE, "1" })
|
||||
static Carrier testConstructorBlankInit() {
|
||||
// Only the header barrier.
|
||||
return new Carrier(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.MEMBAR_STORESTORE, "1" })
|
||||
static Carrier testConstructorEmptyInit() {
|
||||
// Only the header barrier.
|
||||
return new Carrier(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.MEMBAR_STORESTORE, "1" })
|
||||
static Carrier testConstructorFullInit() {
|
||||
// Only the header barrier.
|
||||
return new Carrier(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = { IRNode.MEMBAR })
|
||||
static void testMethodEmptyInit() {
|
||||
// Reference inits do not have membars.
|
||||
INIT_EMPTY_CARRIER.initEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = { IRNode.MEMBAR })
|
||||
static void testMethodFullInit() {
|
||||
// Reference inits do not have membars.
|
||||
INIT_FULL_CARRIER.initFull();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright Amazon.com Inc. 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 8333791
|
||||
* @requires os.arch=="aarch64" | os.arch=="riscv64" | os.arch=="x86_64" | os.arch=="amd64"
|
||||
* @requires vm.gc.Parallel
|
||||
* @requires vm.compiler2.enabled
|
||||
* @summary Check stable field folding and barriers
|
||||
* @modules java.base/jdk.internal.vm.annotation
|
||||
* @library /test/lib /
|
||||
* @run driver compiler.c2.irTests.stable.StablePrimFinalTest
|
||||
*/
|
||||
|
||||
package compiler.c2.irTests.stable;
|
||||
|
||||
import compiler.lib.ir_framework.*;
|
||||
import jdk.test.lib.Asserts;
|
||||
|
||||
import jdk.internal.vm.annotation.Stable;
|
||||
|
||||
public class StablePrimFinalTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
TestFramework tf = new TestFramework();
|
||||
tf.addTestClassesToBootClassPath();
|
||||
tf.addFlags(
|
||||
"-XX:+UnlockExperimentalVMOptions",
|
||||
"-XX:CompileThreshold=100",
|
||||
"-XX:-TieredCompilation",
|
||||
"-XX:+UseParallelGC"
|
||||
);
|
||||
tf.start();
|
||||
}
|
||||
|
||||
static class Carrier {
|
||||
@Stable
|
||||
final int field;
|
||||
|
||||
@ForceInline
|
||||
public Carrier(boolean init) {
|
||||
field = init ? 42 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
static final Carrier BLANK_CARRIER = new Carrier(false);
|
||||
static final Carrier INIT_CARRIER = new Carrier(true);
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.LOAD, "1" })
|
||||
@IR(failOn = { IRNode.MEMBAR })
|
||||
static int testNoFold() {
|
||||
// Access should not be folded.
|
||||
// No barriers expected for final fields.
|
||||
return BLANK_CARRIER.field;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = { IRNode.LOAD, IRNode.MEMBAR })
|
||||
static int testFold() {
|
||||
// Access should be completely folded.
|
||||
return INIT_CARRIER.field;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.MEMBAR_STORESTORE, "1" })
|
||||
static Carrier testConstructorBlankInit() {
|
||||
// Single header+final barrier.
|
||||
return new Carrier(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.MEMBAR_STORESTORE, "1" })
|
||||
static Carrier testConstructorFullInit() {
|
||||
// Single header+final barrier.
|
||||
return new Carrier(true);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright Amazon.com Inc. 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 8333791
|
||||
* @requires os.arch=="aarch64" | os.arch=="riscv64" | os.arch=="x86_64" | os.arch=="amd64"
|
||||
* @requires vm.gc.Parallel
|
||||
* @requires vm.compiler2.enabled
|
||||
* @summary Check stable field folding and barriers
|
||||
* @modules java.base/jdk.internal.vm.annotation
|
||||
* @library /test/lib /
|
||||
* @run driver compiler.c2.irTests.stable.StablePrimPlainTest
|
||||
*/
|
||||
|
||||
package compiler.c2.irTests.stable;
|
||||
|
||||
import compiler.lib.ir_framework.*;
|
||||
import jdk.test.lib.Asserts;
|
||||
|
||||
import jdk.internal.vm.annotation.Stable;
|
||||
|
||||
public class StablePrimPlainTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
TestFramework tf = new TestFramework();
|
||||
tf.addTestClassesToBootClassPath();
|
||||
tf.addFlags(
|
||||
"-XX:+UnlockExperimentalVMOptions",
|
||||
"-XX:CompileThreshold=100",
|
||||
"-XX:-TieredCompilation",
|
||||
"-XX:+UseParallelGC"
|
||||
);
|
||||
tf.start();
|
||||
}
|
||||
|
||||
static class Carrier {
|
||||
@Stable
|
||||
int field;
|
||||
|
||||
@ForceInline
|
||||
public Carrier(boolean init) {
|
||||
if (init) {
|
||||
field = 42;
|
||||
}
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
public void init() {
|
||||
field = 42;
|
||||
}
|
||||
}
|
||||
|
||||
static final Carrier BLANK_CARRIER = new Carrier(false);
|
||||
static final Carrier INIT_CARRIER = new Carrier(true);
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.LOAD, "1" })
|
||||
@IR(failOn = { IRNode.MEMBAR })
|
||||
static int testNoFold() {
|
||||
// Access should not be folded.
|
||||
// No barriers expected for plain fields.
|
||||
return BLANK_CARRIER.field;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = { IRNode.LOAD, IRNode.MEMBAR })
|
||||
static int testFold() {
|
||||
// Access should be completely folded.
|
||||
return INIT_CARRIER.field;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.MEMBAR_STORESTORE, "1" })
|
||||
static Carrier testConstructorBlankInit() {
|
||||
// Only the header barrier.
|
||||
return new Carrier(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.MEMBAR_STORESTORE, "1" })
|
||||
static Carrier testConstructorFullInit() {
|
||||
// Only the header barrier.
|
||||
return new Carrier(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = { IRNode.MEMBAR })
|
||||
static void testMethodInit() {
|
||||
// Primitive inits have no membars.
|
||||
INIT_CARRIER.init();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright Amazon.com Inc. 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 8333791
|
||||
* @requires os.arch=="aarch64" | os.arch=="riscv64" | os.arch=="x86_64" | os.arch=="amd64"
|
||||
* @requires vm.gc.Parallel
|
||||
* @requires vm.compiler2.enabled
|
||||
* @summary Check stable field folding and barriers
|
||||
* @modules java.base/jdk.internal.vm.annotation
|
||||
* @library /test/lib /
|
||||
* @run driver compiler.c2.irTests.stable.StablePrimVolatileTest
|
||||
*/
|
||||
|
||||
package compiler.c2.irTests.stable;
|
||||
|
||||
import compiler.lib.ir_framework.*;
|
||||
import jdk.test.lib.Asserts;
|
||||
|
||||
import jdk.internal.vm.annotation.Stable;
|
||||
|
||||
public class StablePrimVolatileTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
TestFramework tf = new TestFramework();
|
||||
tf.addTestClassesToBootClassPath();
|
||||
tf.addFlags(
|
||||
"-XX:+UnlockExperimentalVMOptions",
|
||||
"-XX:CompileThreshold=100",
|
||||
"-XX:-TieredCompilation",
|
||||
"-XX:+UseParallelGC"
|
||||
);
|
||||
tf.start();
|
||||
}
|
||||
|
||||
static class Carrier {
|
||||
@Stable
|
||||
volatile int field;
|
||||
|
||||
@ForceInline
|
||||
public Carrier(boolean init) {
|
||||
if (init) {
|
||||
field = 42;
|
||||
}
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
public void init() {
|
||||
field = 42;
|
||||
}
|
||||
}
|
||||
|
||||
static final Carrier BLANK_CARRIER = new Carrier(false);
|
||||
static final Carrier INIT_CARRIER = new Carrier(true);
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.LOAD, "1" })
|
||||
@IR(counts = { IRNode.MEMBAR, ">0" })
|
||||
static int testNoFold() {
|
||||
// Access should not be folded.
|
||||
// Barriers expected for volatile fields.
|
||||
return BLANK_CARRIER.field;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = { IRNode.LOAD, IRNode.MEMBAR })
|
||||
static int testFold() {
|
||||
// Access should be completely folded.
|
||||
return INIT_CARRIER.field;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.MEMBAR_STORESTORE, "1" })
|
||||
static Carrier testConstructorBlankInit() {
|
||||
// Expect only the header barrier.
|
||||
return new Carrier(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.MEMBAR, ">0" })
|
||||
static Carrier testConstructorFullInit() {
|
||||
// Volatile barriers expected.
|
||||
return new Carrier(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.MEMBAR, ">0" })
|
||||
static void testMethodInit() {
|
||||
// Volatile barriers expected.
|
||||
INIT_CARRIER.init();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright Amazon.com Inc. 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 8333791
|
||||
* @requires os.arch=="aarch64" | os.arch=="riscv64" | os.arch=="x86_64" | os.arch=="amd64"
|
||||
* @requires vm.gc.Parallel
|
||||
* @requires vm.compiler2.enabled
|
||||
* @summary Check stable field folding and barriers
|
||||
* @modules java.base/jdk.internal.vm.annotation
|
||||
* @library /test/lib /
|
||||
* @run driver compiler.c2.irTests.stable.StableRefArrayTest
|
||||
*/
|
||||
|
||||
package compiler.c2.irTests.stable;
|
||||
|
||||
import compiler.lib.ir_framework.*;
|
||||
import jdk.test.lib.Asserts;
|
||||
|
||||
import jdk.internal.vm.annotation.Stable;
|
||||
|
||||
public class StableRefArrayTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
TestFramework tf = new TestFramework();
|
||||
tf.addTestClassesToBootClassPath();
|
||||
tf.addFlags(
|
||||
"-XX:+UnlockExperimentalVMOptions",
|
||||
"-XX:CompileThreshold=100",
|
||||
"-XX:-TieredCompilation",
|
||||
"-XX:+UseParallelGC"
|
||||
);
|
||||
tf.start();
|
||||
}
|
||||
|
||||
static final Integer[] EMPTY_INTEGER = new Integer[] { null };
|
||||
static final Integer[] FULL_INTEGER = new Integer[] { 42 };
|
||||
|
||||
static class Carrier {
|
||||
@Stable
|
||||
Integer[] field;
|
||||
|
||||
@ForceInline
|
||||
public Carrier(int initLevel) {
|
||||
switch (initLevel) {
|
||||
case 0:
|
||||
// Do nothing.
|
||||
break;
|
||||
case 1:
|
||||
field = EMPTY_INTEGER;
|
||||
break;
|
||||
case 2:
|
||||
field = FULL_INTEGER;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unknown level");
|
||||
}
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
public void initEmpty() {
|
||||
field = EMPTY_INTEGER;
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
public void initFull() {
|
||||
field = FULL_INTEGER;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static final Carrier BLANK_CARRIER = new Carrier(0);
|
||||
static final Carrier INIT_EMPTY_CARRIER = new Carrier(1);
|
||||
static final Carrier INIT_FULL_CARRIER = new Carrier(2);
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.LOAD, ">0" })
|
||||
@IR(failOn = { IRNode.MEMBAR })
|
||||
static int testNoFold() {
|
||||
// Access should not be folded.
|
||||
// No barriers expected for plain fields.
|
||||
Integer[] is = BLANK_CARRIER.field;
|
||||
if (is != null) {
|
||||
Integer i = is[0];
|
||||
if (i != null) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.LOAD, ">0" })
|
||||
@IR(failOn = { IRNode.MEMBAR })
|
||||
static int testPartialFold() {
|
||||
// Access should not be folded.
|
||||
// No barriers expected for plain fields.
|
||||
Integer[] is = INIT_EMPTY_CARRIER.field;
|
||||
if (is != null) {
|
||||
Integer i = is[0];
|
||||
if (i != null) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@IR(failOn = { IRNode.LOAD, IRNode.MEMBAR })
|
||||
static int testFold() {
|
||||
// Access should be completely folded.
|
||||
Integer[] is = INIT_FULL_CARRIER.field;
|
||||
if (is != null) {
|
||||
Integer i = is[0];
|
||||
if (i != null) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.MEMBAR_STORESTORE, "1" })
|
||||
static Carrier testConstructorBlankInit() {
|
||||
// Only the header barrier.
|
||||
return new Carrier(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.MEMBAR_STORESTORE, "1" })
|
||||
static Carrier testConstructorEmptyInit() {
|
||||
// Only the header barrier.
|
||||
return new Carrier(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.MEMBAR_STORESTORE, "1" })
|
||||
static Carrier testConstructorFullInit() {
|
||||
// Only the header barrier.
|
||||
return new Carrier(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = { IRNode.MEMBAR })
|
||||
static void testMethodEmptyInit() {
|
||||
// Reference inits do not have membars.
|
||||
INIT_EMPTY_CARRIER.initEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = { IRNode.MEMBAR })
|
||||
static void testMethodFullInit() {
|
||||
// Reference inits do not have membars.
|
||||
INIT_FULL_CARRIER.initFull();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright Amazon.com Inc. 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 8333791
|
||||
* @requires os.arch=="aarch64" | os.arch=="riscv64" | os.arch=="x86_64" | os.arch=="amd64"
|
||||
* @requires vm.gc.Parallel
|
||||
* @requires vm.compiler2.enabled
|
||||
* @summary Check stable field folding and barriers
|
||||
* @modules java.base/jdk.internal.vm.annotation
|
||||
* @library /test/lib /
|
||||
* @run driver compiler.c2.irTests.stable.StableRefFinalTest
|
||||
*/
|
||||
|
||||
package compiler.c2.irTests.stable;
|
||||
|
||||
import compiler.lib.ir_framework.*;
|
||||
import jdk.test.lib.Asserts;
|
||||
|
||||
import jdk.internal.vm.annotation.Stable;
|
||||
|
||||
public class StableRefFinalTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
TestFramework tf = new TestFramework();
|
||||
tf.addTestClassesToBootClassPath();
|
||||
tf.addFlags(
|
||||
"-XX:+UnlockExperimentalVMOptions",
|
||||
"-XX:CompileThreshold=100",
|
||||
"-XX:-TieredCompilation",
|
||||
"-XX:+UseParallelGC"
|
||||
);
|
||||
tf.start();
|
||||
}
|
||||
|
||||
static final Integer INTEGER = 42;
|
||||
|
||||
static class Carrier {
|
||||
@Stable
|
||||
final Integer field;
|
||||
|
||||
@ForceInline
|
||||
public Carrier(boolean init) {
|
||||
field = init ? INTEGER : null;
|
||||
}
|
||||
}
|
||||
|
||||
static final Carrier BLANK_CARRIER = new Carrier(false);
|
||||
static final Carrier INIT_CARRIER = new Carrier(true);
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.LOAD, ">0" })
|
||||
@IR(failOn = { IRNode.MEMBAR })
|
||||
static int testNoFold() {
|
||||
// Access should not be folded.
|
||||
// No barriers expected for plain fields.
|
||||
Integer i = BLANK_CARRIER.field;
|
||||
return i != null ? i : 0;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = { IRNode.LOAD, IRNode.MEMBAR })
|
||||
static int testFold() {
|
||||
// Access should be completely folded.
|
||||
Integer i = INIT_CARRIER.field;
|
||||
return i != null ? i : 0;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.MEMBAR_STORESTORE, "1" })
|
||||
static Carrier testConstructorInit() {
|
||||
// Only the header+final barrier.
|
||||
return new Carrier(true);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright Amazon.com Inc. 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 8333791
|
||||
* @requires os.arch=="aarch64" | os.arch=="riscv64" | os.arch=="x86_64" | os.arch=="amd64"
|
||||
* @requires vm.gc.Parallel
|
||||
* @requires vm.compiler2.enabled
|
||||
* @summary Check stable field folding and barriers
|
||||
* @modules java.base/jdk.internal.vm.annotation
|
||||
* @library /test/lib /
|
||||
* @run driver compiler.c2.irTests.stable.StableRefPlainTest
|
||||
*/
|
||||
|
||||
package compiler.c2.irTests.stable;
|
||||
|
||||
import compiler.lib.ir_framework.*;
|
||||
import jdk.test.lib.Asserts;
|
||||
|
||||
import jdk.internal.vm.annotation.Stable;
|
||||
|
||||
public class StableRefPlainTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
TestFramework tf = new TestFramework();
|
||||
tf.addTestClassesToBootClassPath();
|
||||
tf.addFlags(
|
||||
"-XX:+UnlockExperimentalVMOptions",
|
||||
"-XX:CompileThreshold=100",
|
||||
"-XX:-TieredCompilation",
|
||||
"-XX:+UseParallelGC"
|
||||
);
|
||||
tf.start();
|
||||
}
|
||||
|
||||
static final Integer INTEGER = 42;
|
||||
|
||||
static class Carrier {
|
||||
@Stable
|
||||
Integer field;
|
||||
|
||||
@ForceInline
|
||||
public Carrier(boolean init) {
|
||||
if (init) {
|
||||
field = INTEGER;
|
||||
}
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
public void init() {
|
||||
field = INTEGER;
|
||||
}
|
||||
}
|
||||
|
||||
static final Carrier BLANK_CARRIER = new Carrier(false);
|
||||
static final Carrier INIT_CARRIER = new Carrier(true);
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.LOAD, ">0" })
|
||||
@IR(failOn = { IRNode.MEMBAR })
|
||||
static int testNoFold() {
|
||||
// Access should not be folded.
|
||||
// No barriers expected for plain fields.
|
||||
Integer i = BLANK_CARRIER.field;
|
||||
return i != null ? i : 0;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = { IRNode.LOAD, IRNode.MEMBAR })
|
||||
static int testFold() {
|
||||
// Access should be completely folded.
|
||||
Integer i = INIT_CARRIER.field;
|
||||
return i != null ? i : 0;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.MEMBAR_STORESTORE, "1" })
|
||||
static Carrier testConstructorBlankInit() {
|
||||
// Only the header barrier.
|
||||
return new Carrier(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.MEMBAR_STORESTORE, "1" })
|
||||
static Carrier testConstructorFullInit() {
|
||||
// Only the header barrier.
|
||||
return new Carrier(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = { IRNode.MEMBAR })
|
||||
static void testMethodInit() {
|
||||
// Reference inits do not have membars.
|
||||
INIT_CARRIER.init();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright Amazon.com Inc. 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 8333791
|
||||
* @requires os.arch=="aarch64" | os.arch=="riscv64" | os.arch=="x86_64" | os.arch=="amd64"
|
||||
* @requires vm.gc.Parallel
|
||||
* @requires vm.compiler2.enabled
|
||||
* @summary Check stable field folding and barriers
|
||||
* @modules java.base/jdk.internal.vm.annotation
|
||||
* @library /test/lib /
|
||||
* @run driver compiler.c2.irTests.stable.StableRefVolatileTest
|
||||
*/
|
||||
|
||||
package compiler.c2.irTests.stable;
|
||||
|
||||
import compiler.lib.ir_framework.*;
|
||||
import jdk.test.lib.Asserts;
|
||||
|
||||
import jdk.internal.vm.annotation.Stable;
|
||||
|
||||
public class StableRefVolatileTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
TestFramework tf = new TestFramework();
|
||||
tf.addTestClassesToBootClassPath();
|
||||
tf.addFlags(
|
||||
"-XX:+UnlockExperimentalVMOptions",
|
||||
"-XX:CompileThreshold=100",
|
||||
"-XX:-TieredCompilation",
|
||||
"-XX:+UseParallelGC"
|
||||
);
|
||||
tf.start();
|
||||
}
|
||||
|
||||
static final Integer INTEGER = 42;
|
||||
|
||||
static class Carrier {
|
||||
@Stable
|
||||
volatile Integer field;
|
||||
|
||||
@ForceInline
|
||||
public Carrier(boolean init) {
|
||||
if (init) {
|
||||
field = INTEGER;
|
||||
}
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
public void init() {
|
||||
field = INTEGER;
|
||||
}
|
||||
}
|
||||
|
||||
static final Carrier BLANK_CARRIER = new Carrier(false);
|
||||
static final Carrier INIT_CARRIER = new Carrier(true);
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.LOAD, ">0" })
|
||||
@IR(counts = { IRNode.MEMBAR, ">0" })
|
||||
static int testNoFold() {
|
||||
// Access should not be folded.
|
||||
// Barriers are expected for volatile field.
|
||||
Integer i = BLANK_CARRIER.field;
|
||||
return i != null ? i : 0;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = { IRNode.LOAD, IRNode.MEMBAR })
|
||||
static int testFold() {
|
||||
// Access should be completely folded.
|
||||
Integer i = INIT_CARRIER.field;
|
||||
return i != null ? i : 0;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.MEMBAR_STORESTORE, "1" })
|
||||
static Carrier testConstructorBlankInit() {
|
||||
// Only the header barrier.
|
||||
return new Carrier(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.MEMBAR, ">0" })
|
||||
static Carrier testConstructorFullInit() {
|
||||
// Volatile writes, expect more barriers.
|
||||
return new Carrier(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.MEMBAR, ">0" })
|
||||
static void testMethodInit() {
|
||||
// Barriers are expected for volatile fields.
|
||||
INIT_CARRIER.init();
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user