This commit is contained in:
Jesper Wilhelmsson 2020-07-07 23:42:50 +02:00
commit c782d0e486
15 changed files with 428 additions and 339 deletions

View file

@ -54,6 +54,7 @@
#include "runtime/arguments.hpp" #include "runtime/arguments.hpp"
#include "runtime/flags/jvmFlag.hpp" #include "runtime/flags/jvmFlag.hpp"
#include "runtime/globals.hpp" #include "runtime/globals.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/os.hpp" #include "runtime/os.hpp"
#include "runtime/os_perf.hpp" #include "runtime/os_perf.hpp"
#include "runtime/thread.inline.hpp" #include "runtime/thread.inline.hpp"
@ -174,7 +175,13 @@ TRACE_REQUEST_FUNC(CPULoad) {
double u = 0; // user time double u = 0; // user time
double s = 0; // kernel time double s = 0; // kernel time
double t = 0; // total time double t = 0; // total time
int ret_val = JfrOSInterface::cpu_loads_process(&u, &s, &t); int ret_val = OS_ERR;
{
// Can take some time on certain platforms, especially under heavy load.
// Transition to native to avoid unnecessary stalls for pending safepoint synchronizations.
ThreadToNativeFromVM transition((JavaThread*)Thread::current());
ret_val = JfrOSInterface::cpu_loads_process(&u, &s, &t);
}
if (ret_val == OS_ERR) { if (ret_val == OS_ERR) {
log_debug(jfr, system)( "Unable to generate requestable event CPULoad"); log_debug(jfr, system)( "Unable to generate requestable event CPULoad");
return; return;
@ -248,7 +255,13 @@ TRACE_REQUEST_FUNC(SystemProcess) {
TRACE_REQUEST_FUNC(ThreadContextSwitchRate) { TRACE_REQUEST_FUNC(ThreadContextSwitchRate) {
double rate = 0.0; double rate = 0.0;
int ret_val = JfrOSInterface::context_switch_rate(&rate); int ret_val = OS_ERR;
{
// Can take some time on certain platforms, especially under heavy load.
// Transition to native to avoid unnecessary stalls for pending safepoint synchronizations.
ThreadToNativeFromVM transition((JavaThread*)Thread::current());
ret_val = JfrOSInterface::context_switch_rate(&rate);
}
if (ret_val == OS_ERR) { if (ret_val == OS_ERR) {
log_debug(jfr, system)( "Unable to generate requestable event ThreadContextSwitchRate"); log_debug(jfr, system)( "Unable to generate requestable event ThreadContextSwitchRate");
return; return;

View file

@ -868,7 +868,7 @@ public abstract class Provider extends Properties {
// For backward compatibility, the registration ordering of // For backward compatibility, the registration ordering of
// SecureRandom (RNG) algorithms needs to be preserved for // SecureRandom (RNG) algorithms needs to be preserved for
// "new SecureRandom()" calls when this provider is used // "new SecureRandom()" calls when this provider is used
private transient Set<Service> prngServices; private transient Set<String> prngAlgos;
// Map<ServiceKey,Service> // Map<ServiceKey,Service>
// used for services added via legacy methods, init on demand // used for services added via legacy methods, init on demand
@ -1089,7 +1089,7 @@ public abstract class Provider extends Properties {
legacyChanged = false; legacyChanged = false;
servicesChanged = false; servicesChanged = false;
serviceSet = null; serviceSet = null;
prngServices = null; prngAlgos = null;
super.clear(); super.clear();
putId(); putId();
} }
@ -1221,7 +1221,7 @@ public abstract class Provider extends Properties {
s.className = className; s.className = className;
if (type.equals("SecureRandom")) { if (type.equals("SecureRandom")) {
updateSecureRandomEntries(true, s); updateSecureRandomEntries(true, s.algorithm);
} }
} else { // attribute } else { // attribute
// e.g. put("MessageDigest.SHA-1 ImplementedIn", "Software"); // e.g. put("MessageDigest.SHA-1 ImplementedIn", "Software");
@ -1383,25 +1383,25 @@ public abstract class Provider extends Properties {
synchronized (this) { synchronized (this) {
putPropertyStrings(s); putPropertyStrings(s);
if (type.equals("SecureRandom")) { if (type.equals("SecureRandom")) {
updateSecureRandomEntries(true, s); updateSecureRandomEntries(true, s.algorithm);
} }
} }
} }
private void updateSecureRandomEntries(boolean doAdd, Service s) { // keep tracks of the registered secure random algos and store them in order
private void updateSecureRandomEntries(boolean doAdd, String s) {
Objects.requireNonNull(s); Objects.requireNonNull(s);
if (doAdd) { if (doAdd) {
if (prngServices == null) { if (prngAlgos == null) {
prngServices = new LinkedHashSet<Service>(); prngAlgos = new LinkedHashSet<String>();
} }
prngServices.add(s); prngAlgos.add(s);
} else { } else {
prngServices.remove(s); prngAlgos.remove(s);
} }
if (debug != null) { if (debug != null) {
debug.println((doAdd? "Add":"Remove") + " SecureRandom algo " + debug.println((doAdd? "Add":"Remove") + " SecureRandom algo " + s);
s.getAlgorithm());
} }
} }
@ -1411,12 +1411,15 @@ public abstract class Provider extends Properties {
checkInitialized(); checkInitialized();
if (legacyChanged) { if (legacyChanged) {
prngServices = null; prngAlgos = null;
ensureLegacyParsed(); ensureLegacyParsed();
} }
if (prngServices != null && !prngServices.isEmpty()) { if (prngAlgos != null && !prngAlgos.isEmpty()) {
return prngServices.iterator().next(); // IMPORTANT: use the Service obj returned by getService(...) call
// as providers may override putService(...)/getService(...) and
// return their own Service objects
return getService("SecureRandom", prngAlgos.iterator().next());
} }
return null; return null;
@ -1516,7 +1519,7 @@ public abstract class Provider extends Properties {
synchronized (this) { synchronized (this) {
removePropertyStrings(s); removePropertyStrings(s);
if (type.equals("SecureRandom")) { if (type.equals("SecureRandom")) {
updateSecureRandomEntries(false, s); updateSecureRandomEntries(false, s.algorithm);
} }
} }
} }

View file

@ -143,7 +143,7 @@ vmTestbase/nsk/jvmti/scenarios/jni_interception/JI05/ji05t001/TestDescription.ja
vmTestbase/nsk/jvmti/scenarios/jni_interception/JI06/ji06t001/TestDescription.java 8219652 aix-ppc64 vmTestbase/nsk/jvmti/scenarios/jni_interception/JI06/ji06t001/TestDescription.java 8219652 aix-ppc64
vmTestbase/nsk/jvmti/SetJNIFunctionTable/setjniftab001/TestDescription.java 8219652 aix-ppc64 vmTestbase/nsk/jvmti/SetJNIFunctionTable/setjniftab001/TestDescription.java 8219652 aix-ppc64
vmTestbase/gc/lock/jni/jnilock002/TestDescription.java 8208243,8192647 generic-all vmTestbase/gc/lock/jni/jnilock002/TestDescription.java 8192647 generic-all
vmTestbase/jit/escape/LockCoarsening/LockCoarsening001.java 8148743 generic-all vmTestbase/jit/escape/LockCoarsening/LockCoarsening001.java 8148743 generic-all
vmTestbase/jit/escape/LockCoarsening/LockCoarsening002.java 8208259 generic-all vmTestbase/jit/escape/LockCoarsening/LockCoarsening002.java 8208259 generic-all

View file

@ -4,9 +4,7 @@
* *
* This code is free software; you can redistribute it and/or modify it * 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 * under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Alibaba designates this * published by the Free Software Foundation.
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
* *
* This code is distributed in the hope that it will be useful, but WITHOUT * This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
@ -18,6 +16,9 @@
* 2 along with this work; if not, write to the Free Software Foundation, * 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * 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 /* @test

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -56,13 +56,15 @@ JNIEXPORT jboolean JNICALL Java_nsk_share_gc_lock_jni_BooleanArrayCriticalLocker
start_time = time(NULL); start_time = time(NULL);
enterTime /= 1000; enterTime /= 1000;
current_time = 0; current_time = 0;
while (current_time - start_time < enterTime) { while (difftime(current_time, start_time) < enterTime) {
hash = JNI_TRUE;
pa = (jboolean*) ec_jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL); pa = (jboolean*) ec_jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL);
if (pa != NULL) { if (pa != NULL) {
for (i = 0; i < size; ++i) for (i = 0; i < size; ++i) {
hash ^= pa[i]; hash ^= pa[i];
}
} else { } else {
hash = JNI_FALSE; jni_env->FatalError("GetPrimitiveArrayCritical returned NULL");
} }
mssleep((long) sleepTime); mssleep((long) sleepTime);
ec_jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL); ec_jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL);

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -55,13 +55,15 @@ JNIEXPORT jbyte JNICALL Java_nsk_share_gc_lock_jni_ByteArrayCriticalLocker_criti
start_time = time(NULL); start_time = time(NULL);
enterTime /= 1000; enterTime /= 1000;
current_time = 0; current_time = 0;
while (current_time - start_time < enterTime) { while (difftime(current_time, start_time) < enterTime) {
hash = 0;
pa = (jbyte*) ec_jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL); pa = (jbyte*) ec_jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL);
if (pa != NULL) { if (pa != NULL) {
for (i = 0; i < size; ++i) for (i = 0; i < size; ++i) {
hash ^= pa[i]; hash ^= pa[i];
}
} else { } else {
hash = 0; jni_env->FatalError("GetPrimitiveArrayCritical returned NULL");
} }
mssleep((long) sleepTime); mssleep((long) sleepTime);
ec_jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL); ec_jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL);

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -56,13 +56,15 @@ JNIEXPORT jchar JNICALL Java_nsk_share_gc_lock_jni_CharArrayCriticalLocker_criti
start_time = time(NULL); start_time = time(NULL);
current_time = 0; current_time = 0;
enterTime /= 1000; enterTime /= 1000;
while (current_time - start_time < enterTime) { while (difftime(current_time, start_time) < enterTime) {
hash = 0;
pa = (jchar*) ec_jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL); pa = (jchar*) ec_jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL);
if (pa != NULL) { if (pa != NULL) {
for (i = 0; i < size; ++i) for (i = 0; i < size; ++i) {
hash ^= pa[i]; hash ^= pa[i];
}
} else { } else {
hash = 0; jni_env->FatalError("GetPrimitiveArrayCritical returned NULL");
} }
mssleep((long) sleepTime); mssleep((long) sleepTime);
ec_jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL); ec_jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL);

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -56,13 +56,15 @@ JNIEXPORT jdouble JNICALL Java_nsk_share_gc_lock_jni_DoubleArrayCriticalLocker_c
start_time = time(NULL); start_time = time(NULL);
enterTime /= 1000; enterTime /= 1000;
current_time = 0; current_time = 0;
while (current_time - start_time < enterTime) { while (difftime(current_time, start_time) < enterTime) {
hash = 0;
pa = (jdouble*) ec_jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL); pa = (jdouble*) ec_jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL);
if (pa != NULL) { if (pa != NULL) {
for (i = 0; i < size; ++i) for (i = 0; i < size; ++i) {
hash += pa[i]; hash += pa[i];
}
} else { } else {
hash = 0; jni_env->FatalError("GetPrimitiveArrayCritical returned NULL");
} }
mssleep((long) sleepTime); mssleep((long) sleepTime);
ec_jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL); ec_jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL);

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -56,13 +56,15 @@ JNIEXPORT jfloat JNICALL Java_nsk_share_gc_lock_jni_FloatArrayCriticalLocker_cri
start_time = time(NULL); start_time = time(NULL);
enterTime /= 1000; enterTime /= 1000;
current_time = 0; current_time = 0;
while (current_time - start_time < enterTime) { while (difftime(current_time, start_time) < enterTime) {
hash = 0;
pa = (jfloat*) ec_jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL); pa = (jfloat*) ec_jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL);
if (pa != NULL) { if (pa != NULL) {
for (i = 0; i < size; ++i) for (i = 0; i < size; ++i) {
hash += pa[i]; hash += pa[i];
}
} else { } else {
hash = 0; jni_env->FatalError("GetPrimitiveArrayCritical returned NULL");
} }
mssleep((long) sleepTime); mssleep((long) sleepTime);
ec_jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL); ec_jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL);

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -56,13 +56,15 @@ JNIEXPORT jint JNICALL Java_nsk_share_gc_lock_jni_IntArrayCriticalLocker_critica
start_time = time(NULL); start_time = time(NULL);
enterTime /= 1000; enterTime /= 1000;
current_time = 0; current_time = 0;
while (current_time - start_time < enterTime) { while (difftime(current_time, start_time) < enterTime) {
hash = 0;
pa = (jint*) ec_jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL); pa = (jint*) ec_jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL);
if (pa != NULL) { if (pa != NULL) {
for (i = 0; i < size; ++i) for (i = 0; i < size; ++i) {
hash ^= pa[i]; hash ^= pa[i];
}
} else { } else {
hash = 0; jni_env->FatalError("GetPrimitiveArrayCritical returned NULL");
} }
mssleep((long) sleepTime); mssleep((long) sleepTime);
ec_jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL); ec_jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL);

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -56,13 +56,15 @@ JNIEXPORT jlong JNICALL Java_nsk_share_gc_lock_jni_LongArrayCriticalLocker_criti
start_time = time(NULL); start_time = time(NULL);
enterTime /= 1000; enterTime /= 1000;
current_time = 0; current_time = 0;
while (current_time - start_time < enterTime) { while (difftime(current_time, start_time) < enterTime) {
hash = 0;
pa = (jlong*) ec_jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL); pa = (jlong*) ec_jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL);
if (pa != NULL) { if (pa != NULL) {
for (i = 0; i < size; ++i) for (i = 0; i < size; ++i) {
hash ^= pa[i]; hash ^= pa[i];
}
} else { } else {
hash = 0; jni_env->FatalError("GetPrimitiveArrayCritical returned NULL");
} }
mssleep((long) sleepTime); mssleep((long) sleepTime);
ec_jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL); ec_jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL);

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -57,12 +57,14 @@ JNIEXPORT jshort JNICALL Java_nsk_share_gc_lock_jni_ShortArrayCriticalLocker_cri
enterTime /= 1000; enterTime /= 1000;
current_time = 0; current_time = 0;
while (current_time - start_time < enterTime) { while (current_time - start_time < enterTime) {
hash = 0;
pa = (jshort*) ec_jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL); pa = (jshort*) ec_jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL);
if (pa != NULL) { if (pa != NULL) {
for (i = 0; i < size; ++i) for (i = 0; i < size; ++i) {
hash ^= pa[i]; hash ^= pa[i];
}
} else { } else {
hash = 0; jni_env->FatalError("GetPrimitiveArrayCritical returned NULL");
} }
mssleep((long) sleepTime); mssleep((long) sleepTime);
ec_jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL); ec_jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL);

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -57,12 +57,14 @@ JNIEXPORT jchar JNICALL Java_nsk_share_gc_lock_jni_StringCriticalLocker_critical
enterTime /= 1000; enterTime /= 1000;
current_time = 0; current_time = 0;
while (current_time - start_time < enterTime) { while (current_time - start_time < enterTime) {
hash = 0;
pa = ec_jni->GetStringCritical(str, NULL, TRACE_JNI_CALL); pa = ec_jni->GetStringCritical(str, NULL, TRACE_JNI_CALL);
if (pa != NULL) { if (pa != NULL) {
for (i = 0; i < size; ++i) for (i = 0; i < size; ++i) {
hash ^= pa[i]; hash ^= pa[i];
}
} else { } else {
hash = JNI_FALSE; jni_env->FatalError("GetStringCritical returned NULL");
} }
mssleep((long) sleepTime); mssleep((long) sleepTime);
ec_jni->ReleaseStringCritical(str, pa, TRACE_JNI_CALL); ec_jni->ReleaseStringCritical(str, pa, TRACE_JNI_CALL);

View file

@ -26,13 +26,12 @@ import java.security.Provider;
import java.security.Security; import java.security.Security;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.security.Provider.Service; import java.security.Provider.Service;
import java.util.Objects;
import java.util.Arrays; import java.util.Arrays;
import sun.security.provider.SunEntries; import sun.security.provider.SunEntries;
/** /**
* @test * @test
* @bug 8228613 8246613 * @bug 8228613 8246613 8248505
* @summary Ensure that the default SecureRandom algo used is based * @summary Ensure that the default SecureRandom algo used is based
* on the registration ordering, and falls to next provider * on the registration ordering, and falls to next provider
* if none are found * if none are found
@ -40,6 +39,9 @@ import sun.security.provider.SunEntries;
*/ */
public class DefaultAlgo { public class DefaultAlgo {
private static final String SR_IMPLCLASS =
"sun.security.provider.SecureRandom";
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
String[] algos = { "A", "B", "C" }; String[] algos = { "A", "B", "C" };
test3rdParty(algos); test3rdParty(algos);
@ -51,7 +53,8 @@ public class DefaultAlgo {
private static void test3rdParty(String[] algos) { private static void test3rdParty(String[] algos) {
Provider[] provs = { Provider[] provs = {
new SampleLegacyProvider(algos), new SampleLegacyProvider(algos),
new SampleServiceProvider(algos) new SampleServiceProvider(algos),
new CustomProvider(algos)
}; };
for (Provider p : provs) { for (Provider p : provs) {
checkDefault(p, algos); checkDefault(p, algos);
@ -72,9 +75,10 @@ public class DefaultAlgo {
} }
private static void checkDefault(Provider p, String ... algos) { private static void checkDefault(Provider p, String ... algos) {
out.println(p.getName() + " with " + Arrays.toString(algos));
int pos = Security.insertProviderAt(p, 1);
String pName = p.getName(); String pName = p.getName();
out.println(pName + " with " + Arrays.toString(algos));
int pos = Security.insertProviderAt(p, 1);
boolean isLegacy = pName.equals("SampleLegacy"); boolean isLegacy = pName.equals("SampleLegacy");
try { try {
if (isLegacy) { if (isLegacy) {
@ -91,7 +95,13 @@ public class DefaultAlgo {
out.println("=> Test Passed"); out.println("=> Test Passed");
} finally { } finally {
if (pos != -1) { if (pos != -1) {
Security.removeProvider(p.getName()); Security.removeProvider(pName);
}
if (isLegacy) {
// add back the removed algos
for (String s : algos) {
p.put("SecureRandom." + s, SR_IMPLCLASS);
}
} }
} }
} }
@ -100,7 +110,7 @@ public class DefaultAlgo {
SampleLegacyProvider(String[] listOfSupportedRNGs) { SampleLegacyProvider(String[] listOfSupportedRNGs) {
super("SampleLegacy", "1.0", "test provider using legacy put"); super("SampleLegacy", "1.0", "test provider using legacy put");
for (String s : listOfSupportedRNGs) { for (String s : listOfSupportedRNGs) {
put("SecureRandom." + s, "sun.security.provider.SecureRandom"); put("SecureRandom." + s, SR_IMPLCLASS);
} }
} }
} }
@ -110,8 +120,37 @@ public class DefaultAlgo {
super("SampleService", "1.0", "test provider using putService"); super("SampleService", "1.0", "test provider using putService");
for (String s : listOfSupportedRNGs) { for (String s : listOfSupportedRNGs) {
putService(new Provider.Service(this, "SecureRandom", s, putService(new Provider.Service(this, "SecureRandom", s,
"sun.security.provider.SecureRandom", null, null)); SR_IMPLCLASS, null, null));
} }
} }
} }
// custom provider which overrides putService(...)/getService() and uses
// its own Service impl
private static class CustomProvider extends Provider {
private static class CustomService extends Provider.Service {
CustomService(Provider p, String type, String algo, String cName) {
super(p, type, algo, cName, null, null);
}
}
CustomProvider(String[] listOfSupportedRNGs) {
super("Custom", "1.0", "test provider overrides putService with " +
" custom service with legacy registration");
for (String s : listOfSupportedRNGs) {
putService(new CustomService(this, "SecureRandom", s ,
SR_IMPLCLASS));
}
}
@Override
protected void putService(Provider.Service s) {
// convert to legacy puts
put(s.getType() + "." + s.getAlgorithm(), s.getClassName());
put(s.getType() + ":" + s.getAlgorithm(), s);
}
@Override
public Provider.Service getService(String type, String algo) {
return (Provider.Service) get(type + ":" + algo);
}
}
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -48,16 +48,19 @@ import jdk.test.lib.jfr.Events;
*/ */
/** /**
* Starts and stops a number of threads in order. * Starts a number of threads in order and verifies
* Verifies that events are in the same order. * that Thread Start events are in that same order.
* The order of Thread End events is non-deterministic.
*/ */
public class TestThreadStartEndEvents { public class TestThreadStartEndEvents {
private final static String EVENT_NAME_THREAD_START = EventNames.ThreadStart; private final static String EVENT_NAME_THREAD_START = EventNames.ThreadStart;
private final static String EVENT_NAME_THREAD_END = EventNames.ThreadEnd; private final static String EVENT_NAME_THREAD_END = EventNames.ThreadEnd;
private static final String THREAD_NAME_PREFIX = "TestThread-"; private static final String THREAD_NAME_PREFIX = "TestThread-";
private static int currentThreadIndex = 0;
private static int numberOfThreadStartEvents = 0;
private static int numberOfThreadEndEvents = 0;
public static void main(String[] args) throws Throwable { public static void main(String[] args) throws Throwable {
// Test Java Thread Start event
Recording recording = new Recording(); Recording recording = new Recording();
recording.enable(EVENT_NAME_THREAD_START).withThreshold(Duration.ofMillis(0)); recording.enable(EVENT_NAME_THREAD_START).withThreshold(Duration.ofMillis(0));
recording.enable(EVENT_NAME_THREAD_END).withThreshold(Duration.ofMillis(0)); recording.enable(EVENT_NAME_THREAD_END).withThreshold(Duration.ofMillis(0));
@ -65,8 +68,6 @@ public class TestThreadStartEndEvents {
LatchedThread[] threads = startThreads(); LatchedThread[] threads = startThreads();
stopThreads(threads); stopThreads(threads);
recording.stop(); recording.stop();
int currThreadIndex = 0;
List<RecordedEvent> events = Events.fromRecording(recording); List<RecordedEvent> events = Events.fromRecording(recording);
events.sort((e1, e2) -> e1.getStartTime().compareTo(e2.getStartTime())); events.sort((e1, e2) -> e1.getStartTime().compareTo(e2.getStartTime()));
Events.hasEvents(events); Events.hasEvents(events);
@ -75,22 +76,37 @@ public class TestThreadStartEndEvents {
continue; continue;
} }
System.out.println("Event:" + event); System.out.println("Event:" + event);
// Threads should be started and stopped in the correct order. String eventType = event.getEventType().getName();
Events.assertEventThread(event, threads[currThreadIndex % threads.length]); switch (eventType) {
String eventName = currThreadIndex < threads.length ? EVENT_NAME_THREAD_START : EVENT_NAME_THREAD_END; case EVENT_NAME_THREAD_START:
if (!eventName.equals(event.getEventType().getName())) { validateThreadStartEvent(event, threads);
throw new Exception("Expected event of type " + eventName + " but got " + event.getEventType().getName()); break;
case EVENT_NAME_THREAD_END:
validateThreadEndEvent(event);
break;
default:
throw new RuntimeException("Test encountered an invalid event: " + eventType);
}
}
assertEQ(numberOfThreadStartEvents, threads.length);
assertEQ(numberOfThreadEndEvents, threads.length);
} }
if (eventName == EVENT_NAME_THREAD_START) { // The order of Thread Start events should corresponding to their start order.
private static void validateThreadStartEvent(RecordedEvent event, LatchedThread[] threads) {
Events.assertEventThread(event, threads[currentThreadIndex++]);
Events.assertEventThread(event, "parentThread", Thread.currentThread()); Events.assertEventThread(event, "parentThread", Thread.currentThread());
RecordedStackTrace stackTrace = event.getValue("stackTrace"); RecordedStackTrace stackTrace = event.getValue("stackTrace");
assertNotNull(stackTrace); assertNotNull(stackTrace);
RecordedMethod topMethod = stackTrace.getFrames().get(0).getMethod(); RecordedMethod topMethod = stackTrace.getFrames().get(0).getMethod();
assertEQ(topMethod.getName(), "startThread"); assertEQ(topMethod.getName(), "startThread");
numberOfThreadStartEvents++;
} }
currThreadIndex++;
} // The order of Thread End events is non-deterministic. This is because the event
// is committed as part of dismantling the JavaThread in the VM, post thread.isAlive().
private static void validateThreadEndEvent(RecordedEvent event) {
numberOfThreadEndEvents++;
} }
private static LatchedThread[] startThreads() { private static LatchedThread[] startThreads() {
@ -147,5 +163,4 @@ public class TestThreadStartEndEvents {
stop.countDown(); stop.countDown();
} }
} }
} }