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
// Small ClearArray non-AVX512.
instruct rep_stos(eCXRegI cnt, eDIRegP base, regD tmp, eAXRegI zero, Universe dummy, eFlagsReg cr) %{
predicate(!((ClearArrayNode*)n)->is_large() &&
(UseAVX <= 2));
predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX <= 2));
match(Set dummy (ClearArray cnt base));
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.
instruct rep_stos_evex(eCXRegI cnt, eDIRegP base, regD tmp, kReg ktmp, eAXRegI zero, Universe dummy, eFlagsReg cr) %{
predicate(!((ClearArrayNode*)n)->is_large() &&
UseAVX > 2 &&
!n->in(2)->bottom_type()->is_int()->is_con());
predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX > 2));
match(Set dummy (ClearArray cnt base));
ins_cost(125);
effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr);
format %{ $$template
@ -11603,7 +11601,7 @@ instruct rep_stos_evex(eCXRegI cnt, eDIRegP base, regD tmp, kReg ktmp, eAXRegI z
// Large ClearArray non-AVX512.
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));
effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr);
format %{ $$template
@ -11653,7 +11651,7 @@ instruct rep_stos_large(eCXRegI cnt, eDIRegP base, regD tmp, eAXRegI zero, Unive
// Large ClearArray AVX512.
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));
effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr);
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)
%{
predicate(!((ClearArrayNode*)n)->is_large() &&
(UseAVX > 2 && VM_Version::supports_avx512vlbw() &&
n->in(2)->bottom_type()->is_int()->is_con()));
((UseAVX > 2) && VM_Version::supports_avx512vlbw()));
match(Set dummy (ClearArray cnt base));
ins_cost(100);
effect(TEMP tmp, TEMP zero, TEMP ktmp, KILL cr);
format %{ "clear_mem_imm $base , $cnt \n\t" %}
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,
Universe dummy, rFlagsReg cr)
%{
predicate(!((ClearArrayNode*)n)->is_large() &&
(UseAVX <= 2));
predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX <= 2));
match(Set dummy (ClearArray cnt base));
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,
Universe dummy, rFlagsReg cr)
%{
predicate(!((ClearArrayNode*)n)->is_large() &&
UseAVX > 2 &&
!n->in(2)->bottom_type()->is_long()->is_con());
predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX > 2));
match(Set dummy (ClearArray cnt base));
ins_cost(125);
effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr);
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,
Universe dummy, rFlagsReg cr)
%{
predicate(UseAVX <=2 && ((ClearArrayNode*)n)->is_large());
predicate((UseAVX <=2) && ((ClearArrayNode*)n)->is_large());
match(Set dummy (ClearArray cnt base));
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,
Universe dummy, rFlagsReg cr)
%{
predicate(UseAVX > 2 && ((ClearArrayNode*)n)->is_large());
predicate((UseAVX > 2) && ((ClearArrayNode*)n)->is_large());
match(Set dummy (ClearArray cnt base));
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)
%{
predicate(!((ClearArrayNode*)n)->is_large() &&
(UseAVX > 2 && VM_Version::supports_avx512vlbw() &&
n->in(2)->bottom_type()->is_long()->is_con()));
((UseAVX > 2) && VM_Version::supports_avx512vlbw()));
match(Set dummy (ClearArray cnt base));
ins_cost(100);
effect(TEMP tmp, TEMP zero, TEMP ktmp, KILL cr);
format %{ "clear_mem_imm $base , $cnt \n\t" %}
ins_encode %{

View File

@ -625,6 +625,8 @@ class PhaseCFG : public Phase {
bool trace_opto_pipelining() const { return false; }
#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
// memory writer.
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;
}
// 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---------------------------
// A load may need to witness memory that nearby stores can overwrite.
// 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
// with a precedence edge.
// (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);
must_raise_LCA = true;
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.
assert(store != load->find_exact_control(load->in(0)), "dependence cycle found");
if (verify) {
#ifdef ASSERT
// 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,
assert(store->find_edge(load) != -1 || unrelated_load_in_store_null_block(store, load),
"missing precedence edge");
} else {
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);
}
// 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]:
// 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]:
// MAX(old_limit, MIN(limit, max_jint))
Node* cmp = new CmpLNode(limit, _igvn.longcon(is_positive_stride ? min_jint : max_jint));
register_new_node(cmp, pre_ctrl);
Node* bol = new BoolNode(cmp, is_positive_stride ? BoolTest::lt : BoolTest::gt);
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);
// INT(MAXL(old_limit, MINL(limit, max_jint)))
// - integer overflow of limit: MINL chooses max_jint.
// - integer underflow of limit: MAXL chooses old_limit (>= MIN_INT > limit)
// INT() is finally converting the limit back to an integer value.
limit = is_positive_stride ? (Node*)(new MinINode(old_limit, limit))
: (Node*)(new MaxINode(old_limit, limit));
// We use CMove nodes to implement long versions of min/max (MINL/MAXL).
// 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);
return limit;
}

View File

@ -965,8 +965,9 @@ void PhaseMacroExpand::process_users_of_allocation(CallNode *alloc) {
if (ctrl_proj != NULL) {
_igvn.replace_node(ctrl_proj, init->in(TypeFunc::Control));
#ifdef ASSERT
// If the InitializeNode has no memory out, it will die, and tmp will become NULL
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
}
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) {
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()) {
MemBarNode* leading = leading_membar();
@ -3315,8 +3316,12 @@ void MemBarNode::remove(PhaseIterGVN *igvn) {
leading->remove(igvn);
}
}
igvn->replace_node(proj_out(TypeFunc::Memory), in(TypeFunc::Memory));
igvn->replace_node(proj_out(TypeFunc::Control), in(TypeFunc::Control));
if (proj_out_or_null(TypeFunc::Memory) != NULL) {
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------------------------------------------

View File

@ -54,6 +54,7 @@ import java.security.AccessController;
import java.security.CodeSource;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@ -61,6 +62,7 @@ import java.util.Properties;
import java.util.PropertyPermission;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.function.Supplier;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;
@ -326,6 +328,13 @@ public final class System {
private static native void setOut0(PrintStream out);
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
private static volatile @Stable PrintStream initialErrStream;
@ -378,19 +387,21 @@ public final class System {
public static void setSecurityManager(@SuppressWarnings("removal") SecurityManager sm) {
if (allowSecurityManager()) {
var callerClass = Reflection.getCallerClass();
URL url = codeSource(callerClass);
final String source;
if (url == null) {
source = callerClass.getName();
} else {
source = callerClass.getName() + " (" + url + ")";
if (CallersHolder.callers.putIfAbsent(callerClass, true) == null) {
URL url = codeSource(callerClass);
final String source;
if (url == null) {
source = callerClass.getName();
} 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);
} else {
// 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");
}
// Whitelist of annotation classes that are allowed, even though
// List of annotation classes that are allowed, even though
// they don't have @MetadataDefinition.
private static boolean isKnownJFRAnnotation(Class<? extends Annotation> annotationType) {
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
* @bug 8261730
* @bug 8261730 8265132
* @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.
* @run main/othervm -XX:-BackgroundCompilation
@ -40,8 +40,9 @@ public class TestNullCheckAntiDependence {
private static MyInteger foo = 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++) {
// This load is placed in the null block.
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) {
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
* @bug 8266459 8268349
* @bug 8266459 8268349 8269543
* @summary check various warnings
* @library /test/lib
*/
@ -62,7 +62,9 @@ public class SecurityManagerWarnings {
JarUtils.createJarFile(Path.of("a.jar"),
Path.of(testClasses),
Path.of("SecurityManagerWarnings.class"));
Path.of("SecurityManagerWarnings.class"),
Path.of("A.class"),
Path.of("B.class"));
allowTest(null, "a.jar");
} else {
@ -72,7 +74,12 @@ public class SecurityManagerWarnings {
// to the original System.err and will not be swallowed.
System.setErr(new PrintStream(new ByteArrayOutputStream()));
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) {
// Exception messages must show in original stderr
e.printStackTrace(oldErr);
@ -113,9 +120,12 @@ public class SecurityManagerWarnings {
String uri = new File(cp).toURI().toString();
return oa
.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: Please consider reporting this to the maintainers of SecurityManagerWarnings")
.stderrShouldContain("WARNING: System::setSecurityManager will be removed in a future release");
.stderrShouldContain("WARNING: System::setSecurityManager has been called by A (" + uri + ")")
.stderrShouldContain("WARNING: System::setSecurityManager has been called by B (" + uri + ")")
.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 {
@ -133,6 +143,19 @@ public class SecurityManagerWarnings {
"-Djava.security.policy=policy",
"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());
}
}