This commit is contained in:
Jesper Wilhelmsson 2021-07-02 20:50:11 +00:00
commit 17f53f2f9c
12 changed files with 308 additions and 76 deletions

View File

@ -11480,8 +11480,7 @@ instruct MoveL2D_reg_reg_sse(regD dst, eRegL src, regD tmp) %{
// fast clearing of an array // fast clearing of an array
// Small ClearArray non-AVX512. // Small ClearArray non-AVX512.
instruct rep_stos(eCXRegI cnt, eDIRegP base, regD tmp, eAXRegI zero, Universe dummy, eFlagsReg cr) %{ instruct rep_stos(eCXRegI cnt, eDIRegP base, regD tmp, eAXRegI zero, Universe dummy, eFlagsReg cr) %{
predicate(!((ClearArrayNode*)n)->is_large() && predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX <= 2));
(UseAVX <= 2));
match(Set dummy (ClearArray cnt base)); match(Set dummy (ClearArray cnt base));
effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr);
@ -11541,10 +11540,9 @@ instruct rep_stos(eCXRegI cnt, eDIRegP base, regD tmp, eAXRegI zero, Universe du
// Small ClearArray AVX512 non-constant length. // Small ClearArray AVX512 non-constant length.
instruct rep_stos_evex(eCXRegI cnt, eDIRegP base, regD tmp, kReg ktmp, eAXRegI zero, Universe dummy, eFlagsReg cr) %{ instruct rep_stos_evex(eCXRegI cnt, eDIRegP base, regD tmp, kReg ktmp, eAXRegI zero, Universe dummy, eFlagsReg cr) %{
predicate(!((ClearArrayNode*)n)->is_large() && predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX > 2));
UseAVX > 2 &&
!n->in(2)->bottom_type()->is_int()->is_con());
match(Set dummy (ClearArray cnt base)); match(Set dummy (ClearArray cnt base));
ins_cost(125);
effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr);
format %{ $$template format %{ $$template
@ -11603,7 +11601,7 @@ instruct rep_stos_evex(eCXRegI cnt, eDIRegP base, regD tmp, kReg ktmp, eAXRegI z
// Large ClearArray non-AVX512. // Large ClearArray non-AVX512.
instruct rep_stos_large(eCXRegI cnt, eDIRegP base, regD tmp, eAXRegI zero, Universe dummy, eFlagsReg cr) %{ instruct rep_stos_large(eCXRegI cnt, eDIRegP base, regD tmp, eAXRegI zero, Universe dummy, eFlagsReg cr) %{
predicate(UseAVX <= 2 && ((ClearArrayNode*)n)->is_large()); predicate((UseAVX <= 2) && ((ClearArrayNode*)n)->is_large());
match(Set dummy (ClearArray cnt base)); match(Set dummy (ClearArray cnt base));
effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr);
format %{ $$template format %{ $$template
@ -11653,7 +11651,7 @@ instruct rep_stos_large(eCXRegI cnt, eDIRegP base, regD tmp, eAXRegI zero, Unive
// Large ClearArray AVX512. // Large ClearArray AVX512.
instruct rep_stos_large_evex(eCXRegI cnt, eDIRegP base, regD tmp, kReg ktmp, eAXRegI zero, Universe dummy, eFlagsReg cr) %{ instruct rep_stos_large_evex(eCXRegI cnt, eDIRegP base, regD tmp, kReg ktmp, eAXRegI zero, Universe dummy, eFlagsReg cr) %{
predicate(UseAVX > 2 && ((ClearArrayNode*)n)->is_large()); predicate((UseAVX > 2) && ((ClearArrayNode*)n)->is_large());
match(Set dummy (ClearArray cnt base)); match(Set dummy (ClearArray cnt base));
effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr);
format %{ $$template format %{ $$template
@ -11705,9 +11703,9 @@ instruct rep_stos_large_evex(eCXRegI cnt, eDIRegP base, regD tmp, kReg ktmp, eAX
instruct rep_stos_im(immI cnt, kReg ktmp, eRegP base, regD tmp, rRegI zero, Universe dummy, eFlagsReg cr) instruct rep_stos_im(immI cnt, kReg ktmp, eRegP base, regD tmp, rRegI zero, Universe dummy, eFlagsReg cr)
%{ %{
predicate(!((ClearArrayNode*)n)->is_large() && predicate(!((ClearArrayNode*)n)->is_large() &&
(UseAVX > 2 && VM_Version::supports_avx512vlbw() && ((UseAVX > 2) && VM_Version::supports_avx512vlbw()));
n->in(2)->bottom_type()->is_int()->is_con()));
match(Set dummy (ClearArray cnt base)); match(Set dummy (ClearArray cnt base));
ins_cost(100);
effect(TEMP tmp, TEMP zero, TEMP ktmp, KILL cr); effect(TEMP tmp, TEMP zero, TEMP ktmp, KILL cr);
format %{ "clear_mem_imm $base , $cnt \n\t" %} format %{ "clear_mem_imm $base , $cnt \n\t" %}
ins_encode %{ ins_encode %{

View File

@ -11043,8 +11043,7 @@ instruct MoveL2D_reg_reg(regD dst, rRegL src) %{
instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero,
Universe dummy, rFlagsReg cr) Universe dummy, rFlagsReg cr)
%{ %{
predicate(!((ClearArrayNode*)n)->is_large() && predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX <= 2));
(UseAVX <= 2));
match(Set dummy (ClearArray cnt base)); match(Set dummy (ClearArray cnt base));
effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr);
@ -11104,10 +11103,9 @@ instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero,
instruct rep_stos_evex(rcx_RegL cnt, rdi_RegP base, regD tmp, kReg ktmp, rax_RegI zero, instruct rep_stos_evex(rcx_RegL cnt, rdi_RegP base, regD tmp, kReg ktmp, rax_RegI zero,
Universe dummy, rFlagsReg cr) Universe dummy, rFlagsReg cr)
%{ %{
predicate(!((ClearArrayNode*)n)->is_large() && predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX > 2));
UseAVX > 2 &&
!n->in(2)->bottom_type()->is_long()->is_con());
match(Set dummy (ClearArray cnt base)); match(Set dummy (ClearArray cnt base));
ins_cost(125);
effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr);
format %{ $$template format %{ $$template
@ -11166,7 +11164,7 @@ instruct rep_stos_evex(rcx_RegL cnt, rdi_RegP base, regD tmp, kReg ktmp, rax_Reg
instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero,
Universe dummy, rFlagsReg cr) Universe dummy, rFlagsReg cr)
%{ %{
predicate(UseAVX <=2 && ((ClearArrayNode*)n)->is_large()); predicate((UseAVX <=2) && ((ClearArrayNode*)n)->is_large());
match(Set dummy (ClearArray cnt base)); match(Set dummy (ClearArray cnt base));
effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr);
@ -11217,7 +11215,7 @@ instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero,
instruct rep_stos_large_evex(rcx_RegL cnt, rdi_RegP base, regD tmp, kReg ktmp, rax_RegI zero, instruct rep_stos_large_evex(rcx_RegL cnt, rdi_RegP base, regD tmp, kReg ktmp, rax_RegI zero,
Universe dummy, rFlagsReg cr) Universe dummy, rFlagsReg cr)
%{ %{
predicate(UseAVX > 2 && ((ClearArrayNode*)n)->is_large()); predicate((UseAVX > 2) && ((ClearArrayNode*)n)->is_large());
match(Set dummy (ClearArray cnt base)); match(Set dummy (ClearArray cnt base));
effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr);
@ -11268,9 +11266,9 @@ instruct rep_stos_large_evex(rcx_RegL cnt, rdi_RegP base, regD tmp, kReg ktmp, r
instruct rep_stos_im(immL cnt, rRegP base, regD tmp, rRegI zero, kReg ktmp, Universe dummy, rFlagsReg cr) instruct rep_stos_im(immL cnt, rRegP base, regD tmp, rRegI zero, kReg ktmp, Universe dummy, rFlagsReg cr)
%{ %{
predicate(!((ClearArrayNode*)n)->is_large() && predicate(!((ClearArrayNode*)n)->is_large() &&
(UseAVX > 2 && VM_Version::supports_avx512vlbw() && ((UseAVX > 2) && VM_Version::supports_avx512vlbw()));
n->in(2)->bottom_type()->is_long()->is_con()));
match(Set dummy (ClearArray cnt base)); match(Set dummy (ClearArray cnt base));
ins_cost(100);
effect(TEMP tmp, TEMP zero, TEMP ktmp, KILL cr); effect(TEMP tmp, TEMP zero, TEMP ktmp, KILL cr);
format %{ "clear_mem_imm $base , $cnt \n\t" %} format %{ "clear_mem_imm $base , $cnt \n\t" %}
ins_encode %{ ins_encode %{

View File

@ -625,6 +625,8 @@ class PhaseCFG : public Phase {
bool trace_opto_pipelining() const { return false; } bool trace_opto_pipelining() const { return false; }
#endif #endif
bool unrelated_load_in_store_null_block(Node* store, Node* load);
// Check that block b is in the home loop (or an ancestor) of n, if n is a // Check that block b is in the home loop (or an ancestor) of n, if n is a
// memory writer. // memory writer.
void verify_memory_writer_placement(const Block* b, const Node* n) const NOT_DEBUG_RETURN; void verify_memory_writer_placement(const Block* b, const Node* n) const NOT_DEBUG_RETURN;

View File

@ -540,6 +540,28 @@ static Block* memory_early_block(Node* load, Block* early, const PhaseCFG* cfg)
return early; return early;
} }
// This function is used by insert_anti_dependences to find unrelated loads for stores in implicit null checks.
bool PhaseCFG::unrelated_load_in_store_null_block(Node* store, Node* load) {
// We expect an anti-dependence edge from 'load' to 'store', except when
// implicit_null_check() has hoisted 'store' above its early block to
// perform an implicit null check, and 'load' is placed in the null
// block. In this case it is safe to ignore the anti-dependence, as the
// null block is only reached if 'store' tries to write to null object and
// 'load' read from non-null object (there is preceding check for that)
// These objects can't be the same.
Block* store_block = get_block_for_node(store);
Block* load_block = get_block_for_node(load);
Node* end = store_block->end();
if (end->is_MachNullCheck() && (end->in(1) == store) && store_block->dominates(load_block)) {
Node* if_true = end->find_out_with(Op_IfTrue);
assert(if_true != NULL, "null check without null projection");
Node* null_block_region = if_true->find_out_with(Op_Region);
assert(null_block_region != NULL, "null check without null region");
return get_block_for_node(null_block_region) == load_block;
}
return false;
}
//--------------------------insert_anti_dependences--------------------------- //--------------------------insert_anti_dependences---------------------------
// A load may need to witness memory that nearby stores can overwrite. // A load may need to witness memory that nearby stores can overwrite.
// For each nearby store, either insert an "anti-dependence" edge // For each nearby store, either insert an "anti-dependence" edge
@ -759,7 +781,7 @@ Block* PhaseCFG::insert_anti_dependences(Block* LCA, Node* load, bool verify) {
// will find him on the non_early_stores list and stick him // will find him on the non_early_stores list and stick him
// with a precedence edge. // with a precedence edge.
// (But, don't bother if LCA is already raised all the way.) // (But, don't bother if LCA is already raised all the way.)
if (LCA != early) { if (LCA != early && !unrelated_load_in_store_null_block(store, load)) {
store_block->set_raise_LCA_mark(load_index); store_block->set_raise_LCA_mark(load_index);
must_raise_LCA = true; must_raise_LCA = true;
non_early_stores.push(store); non_early_stores.push(store);
@ -770,23 +792,7 @@ Block* PhaseCFG::insert_anti_dependences(Block* LCA, Node* load, bool verify) {
// Add an anti-dep edge, and squeeze 'load' into the highest block. // Add an anti-dep edge, and squeeze 'load' into the highest block.
assert(store != load->find_exact_control(load->in(0)), "dependence cycle found"); assert(store != load->find_exact_control(load->in(0)), "dependence cycle found");
if (verify) { if (verify) {
#ifdef ASSERT assert(store->find_edge(load) != -1 || unrelated_load_in_store_null_block(store, load),
// We expect an anti-dependence edge from 'load' to 'store', except when
// implicit_null_check() has hoisted 'store' above its early block to
// perform an implicit null check, and 'load' is placed in the null
// block. In this case it is safe to ignore the anti-dependence, as the
// null block is only reached if 'store' tries to write to null.
Block* store_null_block = NULL;
Node* store_null_check = store->find_out_with(Op_MachNullCheck);
if (store_null_check != NULL) {
Node* if_true = store_null_check->find_out_with(Op_IfTrue);
assert(if_true != NULL, "null check without null projection");
Node* null_block_region = if_true->find_out_with(Op_Region);
assert(null_block_region != NULL, "null check without null region");
store_null_block = get_block_for_node(null_block_region);
}
#endif
assert(LCA == store_null_block || store->find_edge(load) != -1,
"missing precedence edge"); "missing precedence edge");
} else { } else {
store->add_prec(load); store->add_prec(load);

View File

@ -2331,22 +2331,40 @@ Node* PhaseIdealLoop::adjust_limit(bool is_positive_stride, Node* scale, Node* o
register_new_node(limit, pre_ctrl); register_new_node(limit, pre_ctrl);
} }
// Clamp the limit to handle integer under-/overflows. // Clamp the limit to handle integer under-/overflows by using long values.
// We only convert the limit back to int when we handled under-/overflows.
// Note that all values are longs in the following computations.
// When reducing the limit, clamp to [min_jint, old_limit]: // When reducing the limit, clamp to [min_jint, old_limit]:
// MIN(old_limit, MAX(limit, min_jint)) // INT(MINL(old_limit, MAXL(limit, min_jint)))
// - integer underflow of limit: MAXL chooses min_jint.
// - integer overflow of limit: MINL chooses old_limit (<= MAX_INT < limit)
// When increasing the limit, clamp to [old_limit, max_jint]: // When increasing the limit, clamp to [old_limit, max_jint]:
// MAX(old_limit, MIN(limit, max_jint)) // INT(MAXL(old_limit, MINL(limit, max_jint)))
Node* cmp = new CmpLNode(limit, _igvn.longcon(is_positive_stride ? min_jint : max_jint)); // - integer overflow of limit: MINL chooses max_jint.
register_new_node(cmp, pre_ctrl); // - integer underflow of limit: MAXL chooses old_limit (>= MIN_INT > limit)
Node* bol = new BoolNode(cmp, is_positive_stride ? BoolTest::lt : BoolTest::gt); // INT() is finally converting the limit back to an integer value.
register_new_node(bol, pre_ctrl);
limit = new ConvL2INode(limit);
register_new_node(limit, pre_ctrl);
limit = new CMoveINode(bol, limit, _igvn.intcon(is_positive_stride ? min_jint : max_jint), TypeInt::INT);
register_new_node(limit, pre_ctrl);
limit = is_positive_stride ? (Node*)(new MinINode(old_limit, limit)) // We use CMove nodes to implement long versions of min/max (MINL/MAXL).
: (Node*)(new MaxINode(old_limit, limit)); // We use helper methods for inner MINL/MAXL which return CMoveL nodes to keep a long value for the outer MINL/MAXL comparison:
Node* inner_result_long;
if (is_positive_stride) {
inner_result_long = MaxNode::signed_max(limit, _igvn.longcon(min_jint), TypeLong::LONG, _igvn);
} else {
inner_result_long = MaxNode::signed_min(limit, _igvn.longcon(max_jint), TypeLong::LONG, _igvn);
}
set_subtree_ctrl(inner_result_long, false);
// Outer MINL/MAXL:
// The comparison is done with long values but the result is the converted back to int by using CmovI.
Node* old_limit_long = new ConvI2LNode(old_limit);
register_new_node(old_limit_long, pre_ctrl);
Node* cmp = new CmpLNode(old_limit_long, limit);
register_new_node(cmp, pre_ctrl);
Node* bol = new BoolNode(cmp, is_positive_stride ? BoolTest::gt : BoolTest::lt);
register_new_node(bol, pre_ctrl);
Node* inner_result_int = new ConvL2INode(inner_result_long); // Could under-/overflow but that's fine as comparison was done with CmpL
register_new_node(inner_result_int, pre_ctrl);
limit = new CMoveINode(bol, old_limit, inner_result_int, TypeInt::INT);
register_new_node(limit, pre_ctrl); register_new_node(limit, pre_ctrl);
return limit; return limit;
} }

View File

@ -965,8 +965,9 @@ void PhaseMacroExpand::process_users_of_allocation(CallNode *alloc) {
if (ctrl_proj != NULL) { if (ctrl_proj != NULL) {
_igvn.replace_node(ctrl_proj, init->in(TypeFunc::Control)); _igvn.replace_node(ctrl_proj, init->in(TypeFunc::Control));
#ifdef ASSERT #ifdef ASSERT
// If the InitializeNode has no memory out, it will die, and tmp will become NULL
Node* tmp = init->in(TypeFunc::Control); Node* tmp = init->in(TypeFunc::Control);
assert(tmp == _callprojs.fallthrough_catchproj, "allocation control projection"); assert(tmp == NULL || tmp == _callprojs.fallthrough_catchproj, "allocation control projection");
#endif #endif
} }
Node *mem_proj = init->proj_out_or_null(TypeFunc::Memory); Node *mem_proj = init->proj_out_or_null(TypeFunc::Memory);

View File

@ -3306,7 +3306,8 @@ MemBarNode* MemBarNode::make(Compile* C, int opcode, int atp, Node* pn) {
void MemBarNode::remove(PhaseIterGVN *igvn) { void MemBarNode::remove(PhaseIterGVN *igvn) {
if (outcnt() != 2) { if (outcnt() != 2) {
return; assert(Opcode() == Op_Initialize, "Only seen when there are no use of init memory");
assert(outcnt() == 1, "Only control then");
} }
if (trailing_store() || trailing_load_store()) { if (trailing_store() || trailing_load_store()) {
MemBarNode* leading = leading_membar(); MemBarNode* leading = leading_membar();
@ -3315,8 +3316,12 @@ void MemBarNode::remove(PhaseIterGVN *igvn) {
leading->remove(igvn); leading->remove(igvn);
} }
} }
igvn->replace_node(proj_out(TypeFunc::Memory), in(TypeFunc::Memory)); if (proj_out_or_null(TypeFunc::Memory) != NULL) {
igvn->replace_node(proj_out(TypeFunc::Control), in(TypeFunc::Control)); igvn->replace_node(proj_out(TypeFunc::Memory), in(TypeFunc::Memory));
}
if (proj_out_or_null(TypeFunc::Control) != NULL) {
igvn->replace_node(proj_out(TypeFunc::Control), in(TypeFunc::Control));
}
} }
//------------------------------Ideal------------------------------------------ //------------------------------Ideal------------------------------------------

View File

@ -54,6 +54,7 @@ import java.security.AccessController;
import java.security.CodeSource; import java.security.CodeSource;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import java.security.ProtectionDomain; import java.security.ProtectionDomain;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
@ -61,6 +62,7 @@ import java.util.Properties;
import java.util.PropertyPermission; import java.util.PropertyPermission;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import java.util.Set; import java.util.Set;
import java.util.WeakHashMap;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -326,6 +328,13 @@ public final class System {
private static native void setOut0(PrintStream out); private static native void setOut0(PrintStream out);
private static native void setErr0(PrintStream err); private static native void setErr0(PrintStream err);
private static class CallersHolder {
// Remember callers of setSecurityManager() here so that warning
// is only printed once for each different caller
final static Map<Class<?>, Boolean> callers
= Collections.synchronizedMap(new WeakHashMap<>());
}
// Remember initial System.err. setSecurityManager() warning goes here // Remember initial System.err. setSecurityManager() warning goes here
private static volatile @Stable PrintStream initialErrStream; private static volatile @Stable PrintStream initialErrStream;
@ -378,19 +387,21 @@ public final class System {
public static void setSecurityManager(@SuppressWarnings("removal") SecurityManager sm) { public static void setSecurityManager(@SuppressWarnings("removal") SecurityManager sm) {
if (allowSecurityManager()) { if (allowSecurityManager()) {
var callerClass = Reflection.getCallerClass(); var callerClass = Reflection.getCallerClass();
URL url = codeSource(callerClass); if (CallersHolder.callers.putIfAbsent(callerClass, true) == null) {
final String source; URL url = codeSource(callerClass);
if (url == null) { final String source;
source = callerClass.getName(); if (url == null) {
} else { source = callerClass.getName();
source = callerClass.getName() + " (" + url + ")"; } else {
source = callerClass.getName() + " (" + url + ")";
}
initialErrStream.printf("""
WARNING: A terminally deprecated method in java.lang.System has been called
WARNING: System::setSecurityManager has been called by %s
WARNING: Please consider reporting this to the maintainers of %s
WARNING: System::setSecurityManager will be removed in a future release
""", source, callerClass.getName());
} }
initialErrStream.printf("""
WARNING: A terminally deprecated method in java.lang.System has been called
WARNING: System::setSecurityManager has been called by %s
WARNING: Please consider reporting this to the maintainers of %s
WARNING: System::setSecurityManager will be removed in a future release
""", source, callerClass.getName());
implSetSecurityManager(sm); implSetSecurityManager(sm);
} else { } else {
// security manager not allowed // security manager not allowed

View File

@ -375,7 +375,7 @@ public final class AnnotationElement {
throw new IllegalArgumentException("Only primitives types or java.lang.String are allowed"); throw new IllegalArgumentException("Only primitives types or java.lang.String are allowed");
} }
// Whitelist of annotation classes that are allowed, even though // List of annotation classes that are allowed, even though
// they don't have @MetadataDefinition. // they don't have @MetadataDefinition.
private static boolean isKnownJFRAnnotation(Class<? extends Annotation> annotationType) { private static boolean isKnownJFRAnnotation(Class<? extends Annotation> annotationType) {
if (annotationType == Registered.class) { if (annotationType == Registered.class) {

View File

@ -0,0 +1,158 @@
/*
* Copyright (c) 2021, 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 8262017
* @summary Dominator failure because ConvL2I node becomes TOP due to missing overflow/underflow handling in range check elimination
* in PhaseIdealLoop::add_constraint().
* @run main/othervm -Xcomp -XX:-TieredCompilation -XX:CompileCommand=compileonly,compiler.rangechecks.TestRangeCheckLimits::*
* compiler.rangechecks.TestRangeCheckLimits
*/
package compiler.rangechecks;
public class TestRangeCheckLimits {
static int a = 400;
static volatile int b;
static long lFld;
static int iFld;
public static void main(String[] k) {
// Test all cases in PhaseIdealLoop::add_constraint().
testPositiveCaseMainLoop();
testNegativeCaseMainLoop();
testPositiveCasePreLoop();
testNegativeCasePreLoop();
}
public static void testPositiveCaseMainLoop() {
int e, f, g = 0, h[] = new int[a];
double i[] = new double[a];
long j = 9;
Helper.init(h, 3);
for (e = 5; e < 154; e++) {
for (f = 1; f < 169; f += 2) {
b = e;
}
i[1] = b;
for (g = 8; g < 168; g += 2) {
j = g - 5;
if (j > Integer.MAX_VALUE - 1) {
switch (3) {
case 3:
}
}
}
}
if (g != 168) {
throw new RuntimeException("fail");
}
lFld = j;
}
public static void testPositiveCasePreLoop() {
int e, f, g = 0, h[] = new int[a];
double i[] = new double[a];
long j = 9;
Helper.init(h, 3);
for (e = 5; e < 154; e++) {
for (f = 1; f < 169; f += 2) {
b = e;
}
i[1] = b;
for (g = 8; g < 168; g += 2) {
j = g + 5;
if (j > 180) {
switch (3) {
case 3:
}
}
}
}
if (g != 168) {
throw new RuntimeException("fail");
}
lFld = j;
}
public static void testNegativeCaseMainLoop() {
int e, f, g = 0, h[] = new int[a];
double i[] = new double[a];
long j = 9;
Helper.init(h, 3);
for (e = 5; e < 154; e++) {
for (f = 1; f < 169; f += 2) {
b = e;
}
i[1] = b;
for (g = 8; g < 168; g += 2) {
j = g;
if (j < 5) {
switch (3) {
case 3:
}
}
}
}
if (g != 168) {
throw new RuntimeException("fail");
}
lFld = j;
}
public static void testNegativeCasePreLoop() {
int e, f, g = 0, h[] = new int[a];
double i[] = new double[a];
long j = 9;
Helper.init(h, 3);
for (e = 5; e < 154; e++) {
for (f = 1; f < 169; f += 2) {
b = e;
}
i[1] = b;
for (g = 168; g > 8; g -= 2) {
j = g - 5;
if (j > Integer.MAX_VALUE - 1) {
switch (3) {
case 3:
}
}
}
}
if (g != 8) {
throw new RuntimeException("fail");
}
lFld = j;
}
}
class Helper {
public static void init(int[] a, int seed) {
for (int j = 0; j < a.length; j++) {
a[j] = (j % 2 == 0) ? seed + j : seed - j;
}
}
}

View File

@ -25,7 +25,7 @@ package compiler.uncommontrap;
/** /**
* @test * @test
* @bug 8261730 * @bug 8261730 8265132
* @summary Test that no anti-dependence violation is reported between a store * @summary Test that no anti-dependence violation is reported between a store
* used as an implicit null check and a load placed in the null block. * used as an implicit null check and a load placed in the null block.
* @run main/othervm -XX:-BackgroundCompilation * @run main/othervm -XX:-BackgroundCompilation
@ -40,8 +40,9 @@ public class TestNullCheckAntiDependence {
private static MyInteger foo = new MyInteger(); private static MyInteger foo = new MyInteger();
private static MyInteger bar = new MyInteger(); private static MyInteger bar = new MyInteger();
private static MyInteger[] global = {new MyInteger()};
static void setFooToZero() { static void test1() {
for (int i = 0; i < 1; i++) { for (int i = 0; i < 1; i++) {
// This load is placed in the null block. // This load is placed in the null block.
foo.val = -bar.val; foo.val = -bar.val;
@ -52,10 +53,21 @@ public class TestNullCheckAntiDependence {
} }
} }
static void test2(MyInteger a, MyInteger b) {
global[0].val = a.val + b.val * 31;
global[0].val = 0;
return;
}
public static void main(String[] args) { public static void main(String[] args) {
for (int i = 0; i < 10_000; i++) { for (int i = 0; i < 10_000; i++) {
setFooToZero(); test1();
} }
for (int i = 0; i < 10_000; i++) {
test2(new MyInteger(), new MyInteger());
}
} }
} }

View File

@ -23,7 +23,7 @@
/* /*
* @test * @test
* @bug 8266459 8268349 * @bug 8266459 8268349 8269543
* @summary check various warnings * @summary check various warnings
* @library /test/lib * @library /test/lib
*/ */
@ -62,7 +62,9 @@ public class SecurityManagerWarnings {
JarUtils.createJarFile(Path.of("a.jar"), JarUtils.createJarFile(Path.of("a.jar"),
Path.of(testClasses), Path.of(testClasses),
Path.of("SecurityManagerWarnings.class")); Path.of("SecurityManagerWarnings.class"),
Path.of("A.class"),
Path.of("B.class"));
allowTest(null, "a.jar"); allowTest(null, "a.jar");
} else { } else {
@ -72,7 +74,12 @@ public class SecurityManagerWarnings {
// to the original System.err and will not be swallowed. // to the original System.err and will not be swallowed.
System.setErr(new PrintStream(new ByteArrayOutputStream())); System.setErr(new PrintStream(new ByteArrayOutputStream()));
try { try {
System.setSecurityManager(new SecurityManager()); // Run A.run() twice will show only one warning
// (setSecurityManager(null) to ensure the next set is permitted)
// Run B.run() and a new warning will appear
A.run(); // System.setSecurityManager(null);
A.run(); // System.setSecurityManager(null);
B.run(); // System.setSecurityManager(new SecurityManager());
} catch (Exception e) { } catch (Exception e) {
// Exception messages must show in original stderr // Exception messages must show in original stderr
e.printStackTrace(oldErr); e.printStackTrace(oldErr);
@ -113,9 +120,12 @@ public class SecurityManagerWarnings {
String uri = new File(cp).toURI().toString(); String uri = new File(cp).toURI().toString();
return oa return oa
.stderrShouldContain("WARNING: A terminally deprecated method in java.lang.System has been called") .stderrShouldContain("WARNING: A terminally deprecated method in java.lang.System has been called")
.stderrShouldContain("WARNING: System::setSecurityManager has been called by SecurityManagerWarnings (" + uri + ")") .stderrShouldContain("WARNING: System::setSecurityManager has been called by A (" + uri + ")")
.stderrShouldContain("WARNING: Please consider reporting this to the maintainers of SecurityManagerWarnings") .stderrShouldContain("WARNING: System::setSecurityManager has been called by B (" + uri + ")")
.stderrShouldContain("WARNING: System::setSecurityManager will be removed in a future release"); .stderrShouldContain("WARNING: Please consider reporting this to the maintainers of A")
.stderrShouldContain("WARNING: Please consider reporting this to the maintainers of B")
.stderrShouldContain("WARNING: System::setSecurityManager will be removed in a future release")
.stderrShouldNotMatch("(?s)by A.*by A"); // "by A" appears only once
} }
static OutputAnalyzer run(String prop, String cp) throws Exception { static OutputAnalyzer run(String prop, String cp) throws Exception {
@ -133,6 +143,19 @@ public class SecurityManagerWarnings {
"-Djava.security.policy=policy", "-Djava.security.policy=policy",
"SecurityManagerWarnings", "run"); "SecurityManagerWarnings", "run");
} }
return ProcessTools.executeProcess(pb); return ProcessTools.executeProcess(pb)
.stderrShouldNotContain("AccessControlException");
}
}
class A {
static void run() {
System.setSecurityManager(null);
}
}
class B {
static void run() {
System.setSecurityManager(new SecurityManager());
} }
} }