--- a/make/gensrc/Gensrc-jdk.internal.vm.compiler.management.gmk Mon Oct 07 20:15:47 2019 +0200
+++ b/make/gensrc/Gensrc-jdk.internal.vm.compiler.management.gmk Tue Oct 08 11:57:11 2019 +0200
@@ -73,7 +73,7 @@
($(CD) $(GENSRC_DIR)/META-INF/providers && \
p=""; \
impl=""; \
- for i in $$($(GREP) '^' * | $(SORT) -t ':' -k 2 | $(SED) 's/:.*//'); do \
+ for i in $$($(NAWK) '$$0=FILENAME" "$$0' * | $(SORT) -k 2 | $(SED) 's/ .*//'); do \
c=$$($(CAT) $$i | $(TR) -d '\n\r'); \
if test x$$p != x$$c; then \
if test x$$p != x; then \
--- a/make/lib/CoreLibraries.gmk Mon Oct 07 20:15:47 2019 +0200
+++ b/make/lib/CoreLibraries.gmk Tue Oct 08 11:57:11 2019 +0200
@@ -23,8 +23,6 @@
# questions.
#
-WIN_VERIFY_LIB := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libverify/verify.lib
-
# Hook to include the corresponding custom file, if present.
$(eval $(call IncludeCustomExtension, lib/CoreLibraries.gmk))
@@ -110,14 +108,14 @@
LDFLAGS_macosx := -L$(SUPPORT_OUTPUTDIR)/native/$(MODULE)/, \
LDFLAGS_windows := -delayload:shell32.dll, \
LIBS := $(BUILD_LIBFDLIBM_TARGET), \
- LIBS_unix := -ljvm -lverify, \
+ LIBS_unix := -ljvm, \
LIBS_linux := $(LIBDL), \
LIBS_solaris := -lsocket -lnsl -lscf $(LIBDL), \
LIBS_aix := $(LIBDL) $(LIBM),\
LIBS_macosx := -framework CoreFoundation \
-framework Foundation \
-framework SystemConfiguration, \
- LIBS_windows := jvm.lib $(WIN_VERIFY_LIB) \
+ LIBS_windows := jvm.lib \
shell32.lib delayimp.lib \
advapi32.lib version.lib, \
))
--- a/src/hotspot/os/aix/os_aix.cpp Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/os/aix/os_aix.cpp Tue Oct 08 11:57:11 2019 +0200
@@ -132,18 +132,6 @@
#define ERROR_MP_VMGETINFO_CLAIMS_NO_SUPPORT_FOR_64K 103
// excerpts from systemcfg.h that might be missing on older os levels
-#ifndef PV_5_Compat
- #define PV_5_Compat 0x0F8000 /* Power PC 5 */
-#endif
-#ifndef PV_6
- #define PV_6 0x100000 /* Power PC 6 */
-#endif
-#ifndef PV_6_1
- #define PV_6_1 0x100001 /* Power PC 6 DD1.x */
-#endif
-#ifndef PV_6_Compat
- #define PV_6_Compat 0x108000 /* Power PC 6 */
-#endif
#ifndef PV_7
#define PV_7 0x200000 /* Power PC 7 */
#endif
@@ -156,6 +144,13 @@
#ifndef PV_8_Compat
#define PV_8_Compat 0x308000 /* Power PC 8 */
#endif
+#ifndef PV_9
+ #define PV_9 0x400000 /* Power PC 9 */
+#endif
+#ifndef PV_9_Compat
+ #define PV_9_Compat 0x408000 /* Power PC 9 */
+#endif
+
static address resolve_function_descriptor_to_code_pointer(address p);
@@ -1386,15 +1381,7 @@
void os::print_os_info(outputStream* st) {
st->print("OS:");
- st->print("uname:");
- struct utsname name;
- uname(&name);
- st->print(name.sysname); st->print(" ");
- st->print(name.nodename); st->print(" ");
- st->print(name.release); st->print(" ");
- st->print(name.version); st->print(" ");
- st->print(name.machine);
- st->cr();
+ os::Posix::print_uname_info(st);
uint32_t ver = os::Aix::os_version();
st->print_cr("AIX kernel version %u.%u.%u.%u",
@@ -1402,16 +1389,12 @@
os::Posix::print_rlimit_info(st);
+ os::Posix::print_load_average(st);
+
// _SC_THREAD_THREADS_MAX is the maximum number of threads within a process.
long tmax = sysconf(_SC_THREAD_THREADS_MAX);
st->print_cr("maximum #threads within a process:%ld", tmax);
- // load average
- st->print("load average:");
- double loadavg[3] = {-1.L, -1.L, -1.L};
- os::loadavg(loadavg, 3);
- st->print_cr("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]);
-
// print wpar info
libperfstat::wparinfo_t wi;
if (libperfstat::get_wparinfo(&wi)) {
@@ -1504,6 +1487,9 @@
void os::get_summary_cpu_info(char* buf, size_t buflen) {
// read _system_configuration.version
switch (_system_configuration.version) {
+ case PV_9:
+ strncpy(buf, "Power PC 9", buflen);
+ break;
case PV_8:
strncpy(buf, "Power PC 8", buflen);
break;
@@ -1537,6 +1523,9 @@
case PV_8_Compat:
strncpy(buf, "PV_8_Compat", buflen);
break;
+ case PV_9_Compat:
+ strncpy(buf, "PV_9_Compat", buflen);
+ break;
default:
strncpy(buf, "unknown", buflen);
}
--- a/src/hotspot/os/posix/os_posix.cpp Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/os/posix/os_posix.cpp Tue Oct 08 11:57:11 2019 +0200
@@ -373,8 +373,12 @@
void os::Posix::print_load_average(outputStream* st) {
st->print("load average:");
double loadavg[3];
- os::loadavg(loadavg, 3);
- st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]);
+ int res = os::loadavg(loadavg, 3);
+ if (res != -1) {
+ st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]);
+ } else {
+ st->print(" Unavailable");
+ }
st->cr();
}
--- a/src/hotspot/share/classfile/classLoader.hpp Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/classfile/classLoader.hpp Tue Oct 08 11:57:11 2019 +0200
@@ -237,6 +237,8 @@
CDS_ONLY(static ClassPathEntry* app_classpath_entries() {return _app_classpath_entries;})
CDS_ONLY(static ClassPathEntry* module_path_entries() {return _module_path_entries;})
+ static bool has_bootclasspath_append() { return _first_append_entry != NULL; }
+
protected:
// Initialization:
// - setup the boot loader's system class path
--- a/src/hotspot/share/classfile/javaClasses.cpp Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/classfile/javaClasses.cpp Tue Oct 08 11:57:11 2019 +0200
@@ -377,7 +377,7 @@
if (_to_java_string_fn == NULL) {
void *lib_handle = os::native_java_library();
- _to_java_string_fn = CAST_TO_FN_PTR(to_java_string_fn_t, os::dll_lookup(lib_handle, "NewStringPlatform"));
+ _to_java_string_fn = CAST_TO_FN_PTR(to_java_string_fn_t, os::dll_lookup(lib_handle, "JNU_NewStringPlatform"));
if (_to_java_string_fn == NULL) {
fatal("NewStringPlatform missing");
}
--- a/src/hotspot/share/classfile/systemDictionary.cpp Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/classfile/systemDictionary.cpp Tue Oct 08 11:57:11 2019 +0200
@@ -1432,6 +1432,11 @@
// a named package within the unnamed module. In all cases,
// limit visibility to search for the class only in the boot
// loader's append path.
+ if (!ClassLoader::has_bootclasspath_append()) {
+ // If there is no bootclasspath append entry, no need to continue
+ // searching.
+ return NULL;
+ }
search_only_bootloader_append = true;
}
}
--- a/src/hotspot/share/classfile/verifier.cpp Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/classfile/verifier.cpp Tue Oct 08 11:57:11 2019 +0200
@@ -63,29 +63,39 @@
#define STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION 52
#define MAX_ARRAY_DIMENSIONS 255
-// Access to external entry for VerifyClassCodes - old byte code verifier
+// Access to external entry for VerifyClassForMajorVersion - old byte code verifier
extern "C" {
- typedef jboolean (*verify_byte_codes_fn_t)(JNIEnv *, jclass, char *, jint);
- typedef jboolean (*verify_byte_codes_fn_new_t)(JNIEnv *, jclass, char *, jint, jint);
+ typedef jboolean (*verify_byte_codes_fn_t)(JNIEnv *, jclass, char *, jint, jint);
}
-static void* volatile _verify_byte_codes_fn = NULL;
+static verify_byte_codes_fn_t volatile _verify_byte_codes_fn = NULL;
+
+static verify_byte_codes_fn_t verify_byte_codes_fn() {
-static volatile jint _is_new_verify_byte_codes_fn = (jint) true;
+ if (_verify_byte_codes_fn != NULL)
+ return _verify_byte_codes_fn;
+
+ MutexLocker locker(Verify_lock);
+
+ if (_verify_byte_codes_fn != NULL)
+ return _verify_byte_codes_fn;
-static void* verify_byte_codes_fn() {
- if (OrderAccess::load_acquire(&_verify_byte_codes_fn) == NULL) {
- void *lib_handle = os::native_java_library();
- void *func = os::dll_lookup(lib_handle, "VerifyClassCodesForMajorVersion");
- OrderAccess::release_store(&_verify_byte_codes_fn, func);
- if (func == NULL) {
- _is_new_verify_byte_codes_fn = false;
- func = os::dll_lookup(lib_handle, "VerifyClassCodes");
- OrderAccess::release_store(&_verify_byte_codes_fn, func);
- }
- }
- return (void*)_verify_byte_codes_fn;
+ // Load verify dll
+ char buffer[JVM_MAXPATHLEN];
+ char ebuf[1024];
+ if (!os::dll_locate_lib(buffer, sizeof(buffer), Arguments::get_dll_dir(), "verify"))
+ return NULL; // Caller will throw VerifyError
+
+ void *lib_handle = os::dll_load(buffer, ebuf, sizeof(ebuf));
+ if (lib_handle == NULL)
+ return NULL; // Caller will throw VerifyError
+
+ void *fn = os::dll_lookup(lib_handle, "VerifyClassForMajorVersion");
+ if (fn == NULL)
+ return NULL; // Caller will throw VerifyError
+
+ return _verify_byte_codes_fn = CAST_TO_FN_PTR(verify_byte_codes_fn_t, fn);
}
@@ -282,7 +292,7 @@
JavaThread* thread = (JavaThread*)THREAD;
JNIEnv *env = thread->jni_environment();
- void* verify_func = verify_byte_codes_fn();
+ verify_byte_codes_fn_t verify_func = verify_byte_codes_fn();
if (verify_func == NULL) {
jio_snprintf(message, message_len, "Could not link verifier");
@@ -301,16 +311,7 @@
// ThreadToNativeFromVM takes care of changing thread_state, so safepoint
// code knows that we have left the VM
- if (_is_new_verify_byte_codes_fn) {
- verify_byte_codes_fn_new_t func =
- CAST_TO_FN_PTR(verify_byte_codes_fn_new_t, verify_func);
- result = (*func)(env, cls, message, (int)message_len,
- klass->major_version());
- } else {
- verify_byte_codes_fn_t func =
- CAST_TO_FN_PTR(verify_byte_codes_fn_t, verify_func);
- result = (*func)(env, cls, message, (int)message_len);
- }
+ result = (*verify_func)(env, cls, message, (int)message_len, klass->major_version());
}
JNIHandles::destroy_local(cls);
--- a/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp Tue Oct 08 11:57:11 2019 +0200
@@ -69,7 +69,8 @@
// enough, but we also do not want to steal too much CPU from the concurrently running
// application. Using 1/4 of available threads for concurrent GC seems a good
// compromise here.
- if (FLAG_IS_DEFAULT(ConcGCThreads)) {
+ bool ergo_conc = FLAG_IS_DEFAULT(ConcGCThreads);
+ if (ergo_conc) {
FLAG_SET_DEFAULT(ConcGCThreads, MAX2(1, os::processor_count() / 4));
}
@@ -82,7 +83,8 @@
// that will overwhelm the OS scheduler. Using 1/2 of available threads seems to be a fair
// compromise here. Due to implementation constraints, it should not be lower than
// the number of concurrent threads.
- if (FLAG_IS_DEFAULT(ParallelGCThreads)) {
+ bool ergo_parallel = FLAG_IS_DEFAULT(ParallelGCThreads);
+ if (ergo_parallel) {
FLAG_SET_DEFAULT(ParallelGCThreads, MAX2(1, os::processor_count() / 2));
}
@@ -90,9 +92,21 @@
vm_exit_during_initialization("Shenandoah expects ParallelGCThreads > 0, check -XX:ParallelGCThreads=#");
}
+ // Make sure ergonomic decisions do not break the thread count invariants.
+ // This may happen when user overrides one of the flags, but not the other.
+ // When that happens, we want to adjust the setting that was set ergonomically.
if (ParallelGCThreads < ConcGCThreads) {
- warning("Shenandoah expects ConcGCThreads <= ParallelGCThreads, adjusting ParallelGCThreads automatically");
- FLAG_SET_DEFAULT(ParallelGCThreads, ConcGCThreads);
+ if (ergo_conc && !ergo_parallel) {
+ FLAG_SET_DEFAULT(ConcGCThreads, ParallelGCThreads);
+ } else if (!ergo_conc && ergo_parallel) {
+ FLAG_SET_DEFAULT(ParallelGCThreads, ConcGCThreads);
+ } else if (ergo_conc && ergo_parallel) {
+ // Should not happen, check the ergonomic computation above. Fail with relevant error.
+ vm_exit_during_initialization("Shenandoah thread count ergonomic error");
+ } else {
+ // User settings error, report and ask user to rectify.
+ vm_exit_during_initialization("Shenandoah expects ConcGCThreads <= ParallelGCThreads, check -XX:ParallelGCThreads, -XX:ConcGCThreads");
+ }
}
if (FLAG_IS_DEFAULT(ParallelRefProcEnabled)) {
--- a/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp Tue Oct 08 11:57:11 2019 +0200
@@ -314,9 +314,6 @@
diagnostic(bool, ShenandoahTerminationTrace, false, \
"Tracing task termination timings") \
\
- develop(bool, ShenandoahVerifyObjectEquals, false, \
- "Verify that == and != are not used on oops. Only in fastdebug") \
- \
diagnostic(bool, ShenandoahAlwaysPreTouch, false, \
"Pre-touch heap memory, overrides global AlwaysPreTouch") \
\
--- a/src/hotspot/share/include/jvm.h Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/include/jvm.h Tue Oct 08 11:57:11 2019 +0200
@@ -1044,19 +1044,6 @@
#include "classfile_constants.h"
/*
- * A function defined by the byte-code verifier and called by the VM.
- * This is not a function implemented in the VM.
- *
- * Returns JNI_FALSE if verification fails. A detailed error message
- * will be places in msg_buf, whose length is specified by buf_len.
- */
-typedef jboolean (*verifier_fn_t)(JNIEnv *env,
- jclass cb,
- char * msg_buf,
- jint buf_len);
-
-
-/*
* Support for a VM-independent class format checker.
*/
typedef struct {
@@ -1086,28 +1073,6 @@
typedef jstring (*to_java_string_fn_t)(JNIEnv *env, char *str);
-typedef char *(*to_c_string_fn_t)(JNIEnv *env, jstring s, jboolean *b);
-
-/* This is the function defined in libjava.so that performs class
- * format checks. This functions fills in size information about
- * the class file and returns:
- *
- * 0: good
- * -1: out of memory
- * -2: bad format
- * -3: unsupported version
- * -4: bad class name
- */
-
-typedef jint (*check_format_fn_t)(char *class_name,
- unsigned char *data,
- unsigned int data_size,
- class_size_info *class_size,
- char *message_buffer,
- jint buffer_length,
- jboolean measure_only,
- jboolean check_relaxed);
-
#define JVM_RECOGNIZED_CLASS_MODIFIERS (JVM_ACC_PUBLIC | \
JVM_ACC_FINAL | \
JVM_ACC_SUPER | \
--- a/src/hotspot/share/prims/jniCheck.cpp Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/prims/jniCheck.cpp Tue Oct 08 11:57:11 2019 +0200
@@ -448,16 +448,16 @@
Method* jniCheck::validate_jmethod_id(JavaThread* thr, jmethodID method_id) {
ASSERT_OOPS_ALLOWED;
// do the fast jmethodID check first
- Method* moop = Method::checked_resolve_jmethod_id(method_id);
- if (moop == NULL) {
+ Method* m = Method::checked_resolve_jmethod_id(method_id);
+ if (m == NULL) {
ReportJNIFatalError(thr, fatal_wrong_class_or_method);
}
- // jmethodIDs are supposed to be weak handles in the class loader data,
+ // jmethodIDs are handles in the class loader data,
// but that can be expensive so check it last
else if (!Method::is_method_id(method_id)) {
ReportJNIFatalError(thr, fatal_non_weak_method);
}
- return moop;
+ return m;
}
@@ -518,18 +518,29 @@
}
}
-void jniCheck::validate_call_object(JavaThread* thr, jobject obj, jmethodID method_id) {
- /* validate the object being passed */
+void jniCheck::validate_call(JavaThread* thr, jclass clazz, jmethodID method_id, jobject obj) {
ASSERT_OOPS_ALLOWED;
- jniCheck::validate_jmethod_id(thr, method_id);
- jniCheck::validate_object(thr, obj);
-}
+ Method* m = jniCheck::validate_jmethod_id(thr, method_id);
+ InstanceKlass* holder = m->method_holder();
+
+ if (clazz != NULL) {
+ Klass* k = jniCheck::validate_class(thr, clazz, false);
+ // Check that method is in the class, must be InstanceKlass
+ if (!InstanceKlass::cast(k)->is_subtype_of(holder)) {
+ ReportJNIFatalError(thr, fatal_wrong_class_or_method);
+ }
+ }
-void jniCheck::validate_call_class(JavaThread* thr, jclass clazz, jmethodID method_id) {
- /* validate the class being passed */
- ASSERT_OOPS_ALLOWED;
- jniCheck::validate_jmethod_id(thr, method_id);
- jniCheck::validate_class(thr, clazz, false);
+ if (obj != NULL) {
+ oop recv = jniCheck::validate_object(thr, obj);
+ assert(recv != NULL, "validate_object checks that");
+ Klass* ik = recv->klass();
+
+ // Check that the object is a subtype of method holder too.
+ if (!InstanceKlass::cast(ik)->is_subtype_of(holder)) {
+ ReportJNIFatalError(thr, fatal_wrong_class_or_method);
+ }
+ }
}
@@ -595,8 +606,7 @@
jboolean isStatic))
functionEnter(thr);
IN_VM(
- jniCheck::validate_class(thr, cls, false);
- jniCheck::validate_jmethod_id(thr, methodID);
+ jniCheck::validate_call(thr, cls, methodID);
)
jobject result = UNCHECKED()->ToReflectedMethod(env, cls, methodID,
isStatic);
@@ -852,8 +862,7 @@
functionEnter(thr);
va_list args;
IN_VM(
- jniCheck::validate_class(thr, clazz, false);
- jniCheck::validate_jmethod_id(thr, methodID);
+ jniCheck::validate_call(thr, clazz, methodID);
)
va_start(args, methodID);
jobject result = UNCHECKED()->NewObjectV(env,clazz,methodID,args);
@@ -869,8 +878,7 @@
va_list args))
functionEnter(thr);
IN_VM(
- jniCheck::validate_class(thr, clazz, false);
- jniCheck::validate_jmethod_id(thr, methodID);
+ jniCheck::validate_call(thr, clazz, methodID);
)
jobject result = UNCHECKED()->NewObjectV(env,clazz,methodID,args);
functionExit(thr);
@@ -884,8 +892,7 @@
const jvalue *args))
functionEnter(thr);
IN_VM(
- jniCheck::validate_class(thr, clazz, false);
- jniCheck::validate_jmethod_id(thr, methodID);
+ jniCheck::validate_call(thr, clazz, methodID);
)
jobject result = UNCHECKED()->NewObjectA(env,clazz,methodID,args);
functionExit(thr);
@@ -941,7 +948,7 @@
functionEnter(thr); \
va_list args; \
IN_VM( \
- jniCheck::validate_call_object(thr, obj, methodID); \
+ jniCheck::validate_call(thr, NULL, methodID, obj); \
) \
va_start(args,methodID); \
ResultType result =UNCHECKED()->Call##Result##MethodV(env, obj, methodID, \
@@ -959,7 +966,7 @@
va_list args)) \
functionEnter(thr); \
IN_VM(\
- jniCheck::validate_call_object(thr, obj, methodID); \
+ jniCheck::validate_call(thr, NULL, methodID, obj); \
) \
ResultType result = UNCHECKED()->Call##Result##MethodV(env, obj, methodID,\
args); \
@@ -975,7 +982,7 @@
const jvalue * args)) \
functionEnter(thr); \
IN_VM( \
- jniCheck::validate_call_object(thr, obj, methodID); \
+ jniCheck::validate_call(thr, NULL, methodID, obj); \
) \
ResultType result = UNCHECKED()->Call##Result##MethodA(env, obj, methodID,\
args); \
@@ -1002,7 +1009,7 @@
functionEnter(thr);
va_list args;
IN_VM(
- jniCheck::validate_call_object(thr, obj, methodID);
+ jniCheck::validate_call(thr, NULL, methodID, obj);
)
va_start(args,methodID);
UNCHECKED()->CallVoidMethodV(env,obj,methodID,args);
@@ -1018,7 +1025,7 @@
va_list args))
functionEnter(thr);
IN_VM(
- jniCheck::validate_call_object(thr, obj, methodID);
+ jniCheck::validate_call(thr, NULL, methodID, obj);
)
UNCHECKED()->CallVoidMethodV(env,obj,methodID,args);
thr->set_pending_jni_exception_check("CallVoidMethodV");
@@ -1032,7 +1039,7 @@
const jvalue * args))
functionEnter(thr);
IN_VM(
- jniCheck::validate_call_object(thr, obj, methodID);
+ jniCheck::validate_call(thr, NULL, methodID, obj);
)
UNCHECKED()->CallVoidMethodA(env,obj,methodID,args);
thr->set_pending_jni_exception_check("CallVoidMethodA");
@@ -1049,8 +1056,7 @@
functionEnter(thr); \
va_list args; \
IN_VM( \
- jniCheck::validate_call_object(thr, obj, methodID); \
- jniCheck::validate_call_class(thr, clazz, methodID); \
+ jniCheck::validate_call(thr, clazz, methodID, obj); \
) \
va_start(args,methodID); \
ResultType result = UNCHECKED()->CallNonvirtual##Result##MethodV(env, \
@@ -1072,8 +1078,7 @@
va_list args)) \
functionEnter(thr); \
IN_VM( \
- jniCheck::validate_call_object(thr, obj, methodID); \
- jniCheck::validate_call_class(thr, clazz, methodID); \
+ jniCheck::validate_call(thr, clazz, methodID, obj); \
) \
ResultType result = UNCHECKED()->CallNonvirtual##Result##MethodV(env, \
obj, \
@@ -1093,8 +1098,7 @@
const jvalue * args)) \
functionEnter(thr); \
IN_VM( \
- jniCheck::validate_call_object(thr, obj, methodID); \
- jniCheck::validate_call_class(thr, clazz, methodID); \
+ jniCheck::validate_call(thr, clazz, methodID, obj); \
) \
ResultType result = UNCHECKED()->CallNonvirtual##Result##MethodA(env, \
obj, \
@@ -1125,8 +1129,7 @@
functionEnter(thr);
va_list args;
IN_VM(
- jniCheck::validate_call_object(thr, obj, methodID);
- jniCheck::validate_call_class(thr, clazz, methodID);
+ jniCheck::validate_call(thr, clazz, methodID, obj);
)
va_start(args,methodID);
UNCHECKED()->CallNonvirtualVoidMethodV(env,obj,clazz,methodID,args);
@@ -1143,8 +1146,7 @@
va_list args))
functionEnter(thr);
IN_VM(
- jniCheck::validate_call_object(thr, obj, methodID);
- jniCheck::validate_call_class(thr, clazz, methodID);
+ jniCheck::validate_call(thr, clazz, methodID, obj);
)
UNCHECKED()->CallNonvirtualVoidMethodV(env,obj,clazz,methodID,args);
thr->set_pending_jni_exception_check("CallNonvirtualVoidMethodV");
@@ -1159,8 +1161,7 @@
const jvalue * args))
functionEnter(thr);
IN_VM(
- jniCheck::validate_call_object(thr, obj, methodID);
- jniCheck::validate_call_class(thr, clazz, methodID);
+ jniCheck::validate_call(thr, clazz, methodID, obj);
)
UNCHECKED()->CallNonvirtualVoidMethodA(env,obj,clazz,methodID,args);
thr->set_pending_jni_exception_check("CallNonvirtualVoidMethodA");
@@ -1253,8 +1254,7 @@
functionEnter(thr); \
va_list args; \
IN_VM( \
- jniCheck::validate_jmethod_id(thr, methodID); \
- jniCheck::validate_class(thr, clazz, false); \
+ jniCheck::validate_call(thr, clazz, methodID); \
) \
va_start(args,methodID); \
ReturnType result = UNCHECKED()->CallStatic##Result##MethodV(env, \
@@ -1274,8 +1274,7 @@
va_list args)) \
functionEnter(thr); \
IN_VM( \
- jniCheck::validate_jmethod_id(thr, methodID); \
- jniCheck::validate_class(thr, clazz, false); \
+ jniCheck::validate_call(thr, clazz, methodID); \
) \
ReturnType result = UNCHECKED()->CallStatic##Result##MethodV(env, \
clazz, \
@@ -1293,8 +1292,7 @@
const jvalue *args)) \
functionEnter(thr); \
IN_VM( \
- jniCheck::validate_jmethod_id(thr, methodID); \
- jniCheck::validate_class(thr, clazz, false); \
+ jniCheck::validate_call(thr, clazz, methodID); \
) \
ReturnType result = UNCHECKED()->CallStatic##Result##MethodA(env, \
clazz, \
@@ -1323,8 +1321,7 @@
functionEnter(thr);
va_list args;
IN_VM(
- jniCheck::validate_jmethod_id(thr, methodID);
- jniCheck::validate_class(thr, cls, false);
+ jniCheck::validate_call(thr, cls, methodID);
)
va_start(args,methodID);
UNCHECKED()->CallStaticVoidMethodV(env,cls,methodID,args);
@@ -1340,8 +1337,7 @@
va_list args))
functionEnter(thr);
IN_VM(
- jniCheck::validate_jmethod_id(thr, methodID);
- jniCheck::validate_class(thr, cls, false);
+ jniCheck::validate_call(thr, cls, methodID);
)
UNCHECKED()->CallStaticVoidMethodV(env,cls,methodID,args);
thr->set_pending_jni_exception_check("CallStaticVoidMethodV");
@@ -1355,8 +1351,7 @@
const jvalue * args))
functionEnter(thr);
IN_VM(
- jniCheck::validate_jmethod_id(thr, methodID);
- jniCheck::validate_class(thr, cls, false);
+ jniCheck::validate_call(thr, cls, methodID);
)
UNCHECKED()->CallStaticVoidMethodA(env,cls,methodID,args);
thr->set_pending_jni_exception_check("CallStaticVoidMethodA");
--- a/src/hotspot/share/prims/jniCheck.hpp Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/prims/jniCheck.hpp Tue Oct 08 11:57:11 2019 +0200
@@ -51,8 +51,7 @@
static Klass* validate_class(JavaThread* thr, jclass clazz, bool allow_primitive = false);
static void validate_class_descriptor(JavaThread* thr, const char* name);
static void validate_throwable_klass(JavaThread* thr, Klass* klass);
- static void validate_call_object(JavaThread* thr, jobject obj, jmethodID method_id);
- static void validate_call_class(JavaThread* thr, jclass clazz, jmethodID method_id);
+ static void validate_call(JavaThread* thr, jclass clazz, jmethodID method_id, jobject obj = NULL);
static Method* validate_jmethod_id(JavaThread* thr, jmethodID method_id);
};
--- a/src/hotspot/share/prims/jvmtiEnv.cpp Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/prims/jvmtiEnv.cpp Tue Oct 08 11:57:11 2019 +0200
@@ -3229,23 +3229,23 @@
jvmtiError
JvmtiEnv::DestroyRawMonitor(JvmtiRawMonitor * rmonitor) {
if (Threads::number_of_threads() == 0) {
- // Remove this monitor from pending raw monitors list
+ // Remove this monitor from pending raw monitors list
// if it has entered in onload or start phase.
JvmtiPendingMonitors::destroy(rmonitor);
} else {
Thread* thread = Thread::current();
- if (rmonitor->is_entered(thread)) {
+ if (rmonitor->owner() == thread) {
// The caller owns this monitor which we are about to destroy.
// We exit the underlying synchronization object so that the
// "delete monitor" call below can work without an assertion
// failure on systems that don't like destroying synchronization
// objects that are locked.
int r;
- intptr_t recursion = rmonitor->recursions();
- for (intptr_t i = 0; i <= recursion; i++) {
+ int recursion = rmonitor->recursions();
+ for (int i = 0; i <= recursion; i++) {
r = rmonitor->raw_exit(thread);
- assert(r == ObjectMonitor::OM_OK, "raw_exit should have worked");
- if (r != ObjectMonitor::OM_OK) { // robustness
+ assert(r == JvmtiRawMonitor::M_OK, "raw_exit should have worked");
+ if (r != JvmtiRawMonitor::M_OK) { // robustness
return JVMTI_ERROR_INTERNAL;
}
}
@@ -3271,7 +3271,7 @@
jvmtiError
JvmtiEnv::RawMonitorEnter(JvmtiRawMonitor * rmonitor) {
if (Threads::number_of_threads() == 0) {
- // No JavaThreads exist so ObjectMonitor enter cannot be
+ // No JavaThreads exist so JvmtiRawMonitor enter cannot be
// used, add this raw monitor to the pending list.
// The pending monitors will be actually entered when
// the VM is setup.
@@ -3279,20 +3279,10 @@
// in thread.cpp.
JvmtiPendingMonitors::enter(rmonitor);
} else {
- int r = 0;
Thread* thread = Thread::current();
-
if (thread->is_Java_thread()) {
JavaThread* current_thread = (JavaThread*)thread;
-#ifdef PROPER_TRANSITIONS
- // Not really unknown but ThreadInVMfromNative does more than we want
- ThreadInVMfromUnknown __tiv;
- {
- ThreadBlockInVM __tbivm(current_thread);
- r = rmonitor->raw_enter(current_thread);
- }
-#else
/* Transition to thread_blocked without entering vm state */
/* This is really evil. Normally you can't undo _thread_blocked */
/* transitions like this because it would cause us to miss a */
@@ -3308,22 +3298,11 @@
current_thread->frame_anchor()->walkable(), "Must be walkable");
current_thread->set_thread_state(_thread_blocked);
- r = rmonitor->raw_enter(current_thread);
+ rmonitor->raw_enter(current_thread);
// restore state, still at a safepoint safe state
current_thread->set_thread_state(state);
-
-#endif /* PROPER_TRANSITIONS */
- assert(r == ObjectMonitor::OM_OK, "raw_enter should have worked");
} else {
- if (thread->is_Named_thread()) {
- r = rmonitor->raw_enter(thread);
- } else {
- ShouldNotReachHere();
- }
- }
-
- if (r != ObjectMonitor::OM_OK) { // robustness
- return JVMTI_ERROR_INTERNAL;
+ rmonitor->raw_enter(thread);
}
}
return JVMTI_ERROR_NONE;
@@ -3342,31 +3321,10 @@
err = JVMTI_ERROR_NOT_MONITOR_OWNER;
}
} else {
- int r = 0;
Thread* thread = Thread::current();
-
- if (thread->is_Java_thread()) {
- JavaThread* current_thread = (JavaThread*)thread;
-#ifdef PROPER_TRANSITIONS
- // Not really unknown but ThreadInVMfromNative does more than we want
- ThreadInVMfromUnknown __tiv;
-#endif /* PROPER_TRANSITIONS */
- r = rmonitor->raw_exit(current_thread);
- } else {
- if (thread->is_Named_thread()) {
- r = rmonitor->raw_exit(thread);
- } else {
- ShouldNotReachHere();
- }
- }
-
- if (r == ObjectMonitor::OM_ILLEGAL_MONITOR_STATE) {
+ int r = rmonitor->raw_exit(thread);
+ if (r == JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE) {
err = JVMTI_ERROR_NOT_MONITOR_OWNER;
- } else {
- assert(r == ObjectMonitor::OM_OK, "raw_exit should have worked");
- if (r != ObjectMonitor::OM_OK) { // robustness
- err = JVMTI_ERROR_INTERNAL;
- }
}
}
return err;
@@ -3381,14 +3339,7 @@
if (thread->is_Java_thread()) {
JavaThread* current_thread = (JavaThread*)thread;
-#ifdef PROPER_TRANSITIONS
- // Not really unknown but ThreadInVMfromNative does more than we want
- ThreadInVMfromUnknown __tiv;
- {
- ThreadBlockInVM __tbivm(current_thread);
- r = rmonitor->raw_wait(millis, true, current_thread);
- }
-#else
+
/* Transition to thread_blocked without entering vm state */
/* This is really evil. Normally you can't undo _thread_blocked */
/* transitions like this because it would cause us to miss a */
@@ -3408,57 +3359,31 @@
// restore state, still at a safepoint safe state
current_thread->set_thread_state(state);
-#endif /* PROPER_TRANSITIONS */
} else {
- if (thread->is_Named_thread()) {
r = rmonitor->raw_wait(millis, false, thread);
- } else {
- ShouldNotReachHere();
- }
+ assert(r != JvmtiRawMonitor::M_INTERRUPTED, "non-JavaThread can't be interrupted");
}
switch (r) {
- case ObjectMonitor::OM_INTERRUPTED:
+ case JvmtiRawMonitor::M_INTERRUPTED:
return JVMTI_ERROR_INTERRUPT;
- case ObjectMonitor::OM_ILLEGAL_MONITOR_STATE:
+ case JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE:
return JVMTI_ERROR_NOT_MONITOR_OWNER;
+ default:
+ return JVMTI_ERROR_NONE;
}
- assert(r == ObjectMonitor::OM_OK, "raw_wait should have worked");
- if (r != ObjectMonitor::OM_OK) { // robustness
- return JVMTI_ERROR_INTERNAL;
- }
-
- return JVMTI_ERROR_NONE;
} /* end RawMonitorWait */
// rmonitor - pre-checked for validity
jvmtiError
JvmtiEnv::RawMonitorNotify(JvmtiRawMonitor * rmonitor) {
- int r = 0;
Thread* thread = Thread::current();
-
- if (thread->is_Java_thread()) {
- JavaThread* current_thread = (JavaThread*)thread;
- // Not really unknown but ThreadInVMfromNative does more than we want
- ThreadInVMfromUnknown __tiv;
- r = rmonitor->raw_notify(current_thread);
- } else {
- if (thread->is_Named_thread()) {
- r = rmonitor->raw_notify(thread);
- } else {
- ShouldNotReachHere();
- }
- }
-
- if (r == ObjectMonitor::OM_ILLEGAL_MONITOR_STATE) {
+ int r = rmonitor->raw_notify(thread);
+
+ if (r == JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE) {
return JVMTI_ERROR_NOT_MONITOR_OWNER;
}
- assert(r == ObjectMonitor::OM_OK, "raw_notify should have worked");
- if (r != ObjectMonitor::OM_OK) { // robustness
- return JVMTI_ERROR_INTERNAL;
- }
-
return JVMTI_ERROR_NONE;
} /* end RawMonitorNotify */
@@ -3466,29 +3391,12 @@
// rmonitor - pre-checked for validity
jvmtiError
JvmtiEnv::RawMonitorNotifyAll(JvmtiRawMonitor * rmonitor) {
- int r = 0;
Thread* thread = Thread::current();
-
- if (thread->is_Java_thread()) {
- JavaThread* current_thread = (JavaThread*)thread;
- ThreadInVMfromUnknown __tiv;
- r = rmonitor->raw_notifyAll(current_thread);
- } else {
- if (thread->is_Named_thread()) {
- r = rmonitor->raw_notifyAll(thread);
- } else {
- ShouldNotReachHere();
- }
- }
-
- if (r == ObjectMonitor::OM_ILLEGAL_MONITOR_STATE) {
+ int r = rmonitor->raw_notifyAll(thread);
+
+ if (r == JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE) {
return JVMTI_ERROR_NOT_MONITOR_OWNER;
}
- assert(r == ObjectMonitor::OM_OK, "raw_notifyAll should have worked");
- if (r != ObjectMonitor::OM_OK) { // robustness
- return JVMTI_ERROR_INTERNAL;
- }
-
return JVMTI_ERROR_NONE;
} /* end RawMonitorNotifyAll */
--- a/src/hotspot/share/prims/jvmtiEnvBase.cpp Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp Tue Oct 08 11:57:11 2019 +0200
@@ -659,10 +659,9 @@
// thread is not doing an Object.wait() call
mon = java_thread->current_pending_monitor();
if (mon != NULL) {
- // The thread is trying to enter() or raw_enter() an ObjectMonitor.
+ // The thread is trying to enter() an ObjectMonitor.
obj = (oop)mon->object();
- // If obj == NULL, then ObjectMonitor is raw which doesn't count
- // as contended for this API
+ assert(obj != NULL, "ObjectMonitor should have a valid object!");
}
// implied else: no contended ObjectMonitor
} else {
--- a/src/hotspot/share/prims/jvmtiRawMonitor.cpp Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/prims/jvmtiRawMonitor.cpp Tue Oct 08 11:57:11 2019 +0200
@@ -30,21 +30,23 @@
#include "runtime/orderAccess.hpp"
#include "runtime/thread.inline.hpp"
-GrowableArray<JvmtiRawMonitor*> *JvmtiPendingMonitors::_monitors = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<JvmtiRawMonitor*>(1,true);
+JvmtiRawMonitor::QNode::QNode(Thread* thread) : _next(NULL), _prev(NULL),
+ _event(thread->_ParkEvent),
+ _notified(0), TState(TS_RUN) {
+}
+
+GrowableArray<JvmtiRawMonitor*> *JvmtiPendingMonitors::_monitors =
+ new (ResourceObj::C_HEAP, mtInternal) GrowableArray<JvmtiRawMonitor*>(1, true);
void JvmtiPendingMonitors::transition_raw_monitors() {
assert((Threads::number_of_threads()==1),
- "Java thread has not created yet or more than one java thread \
+ "Java thread has not been created yet or more than one java thread \
is running. Raw monitor transition will not work");
JavaThread *current_java_thread = JavaThread::current();
assert(current_java_thread->thread_state() == _thread_in_vm, "Must be in vm");
- {
- ThreadBlockInVM __tbivm(current_java_thread);
- for(int i=0; i< count(); i++) {
- JvmtiRawMonitor *rmonitor = monitors()->at(i);
- int r = rmonitor->raw_enter(current_java_thread);
- assert(r == ObjectMonitor::OM_OK, "raw_enter should have worked");
- }
+ for(int i=0; i< count(); i++) {
+ JvmtiRawMonitor *rmonitor = monitors()->at(i);
+ rmonitor->raw_enter(current_java_thread);
}
// pending monitors are converted to real monitor so delete them all.
dispose();
@@ -54,13 +56,16 @@
// class JvmtiRawMonitor
//
-JvmtiRawMonitor::JvmtiRawMonitor(const char *name) {
+JvmtiRawMonitor::JvmtiRawMonitor(const char *name) : _owner(NULL),
+ _recursions(0),
+ _EntryList(NULL),
+ _WaitSet(NULL),
+ _waiters(0),
+ _magic(JVMTI_RM_MAGIC),
+ _name(NULL) {
#ifdef ASSERT
_name = strcpy(NEW_C_HEAP_ARRAY(char, strlen(name) + 1, mtInternal), name);
-#else
- _name = NULL;
#endif
- _magic = JVMTI_RM_MAGIC;
}
JvmtiRawMonitor::~JvmtiRawMonitor() {
@@ -100,41 +105,29 @@
}
// -------------------------------------------------------------------------
-// The raw monitor subsystem is entirely distinct from normal
-// java-synchronization or jni-synchronization. raw monitors are not
+// The JVMTI raw monitor subsystem is entirely distinct from normal
+// java-synchronization or jni-synchronization. JVMTI raw monitors are not
// associated with objects. They can be implemented in any manner
// that makes sense. The original implementors decided to piggy-back
-// the raw-monitor implementation on the existing Java objectMonitor mechanism.
-// This flaw needs to fixed. We should reimplement raw monitors as sui-generis.
-// Specifically, we should not implement raw monitors via java monitors.
-// Time permitting, we should disentangle and deconvolve the two implementations
-// and move the resulting raw monitor implementation over to the JVMTI directories.
-// Ideally, the raw monitor implementation would be built on top of
-// park-unpark and nothing else.
-//
-// raw monitors are used mainly by JVMTI
-// The raw monitor implementation borrows the ObjectMonitor structure,
-// but the operators are degenerate and extremely simple.
-//
-// Mixed use of a single objectMonitor instance -- as both a raw monitor
-// and a normal java monitor -- is not permissible.
+// the raw-monitor implementation on the existing Java ObjectMonitor mechanism.
+// Now we just use a simplified form of that ObjectMonitor code.
//
// Note that we use the single RawMonitor_lock to protect queue operations for
// _all_ raw monitors. This is a scalability impediment, but since raw monitor usage
-// is deprecated and rare, this is not of concern. The RawMonitor_lock can not
+// is fairly rare, this is not of concern. The RawMonitor_lock can not
// be held indefinitely. The critical sections must be short and bounded.
//
// -------------------------------------------------------------------------
-int JvmtiRawMonitor::SimpleEnter (Thread * Self) {
+void JvmtiRawMonitor::SimpleEnter (Thread * Self) {
for (;;) {
if (Atomic::replace_if_null(Self, &_owner)) {
- return OS_OK ;
+ return ;
}
- ObjectWaiter Node (Self) ;
+ QNode Node (Self) ;
Self->_ParkEvent->reset() ; // strictly optional
- Node.TState = ObjectWaiter::TS_ENTER ;
+ Node.TState = QNode::TS_ENTER ;
RawMonitor_lock->lock_without_safepoint_check() ;
Node._next = _EntryList ;
@@ -143,21 +136,21 @@
if (_owner == NULL && Atomic::replace_if_null(Self, &_owner)) {
_EntryList = Node._next ;
RawMonitor_lock->unlock() ;
- return OS_OK ;
+ return ;
}
RawMonitor_lock->unlock() ;
- while (Node.TState == ObjectWaiter::TS_ENTER) {
+ while (Node.TState == QNode::TS_ENTER) {
Self->_ParkEvent->park() ;
}
}
}
-int JvmtiRawMonitor::SimpleExit (Thread * Self) {
+void JvmtiRawMonitor::SimpleExit (Thread * Self) {
guarantee (_owner == Self, "invariant") ;
- OrderAccess::release_store(&_owner, (void*)NULL) ;
+ OrderAccess::release_store(&_owner, (Thread*)NULL) ;
OrderAccess::fence() ;
- if (_EntryList == NULL) return OS_OK ;
- ObjectWaiter * w ;
+ if (_EntryList == NULL) return ;
+ QNode * w ;
RawMonitor_lock->lock_without_safepoint_check() ;
w = _EntryList ;
@@ -166,27 +159,27 @@
}
RawMonitor_lock->unlock() ;
if (w != NULL) {
- guarantee (w ->TState == ObjectWaiter::TS_ENTER, "invariant") ;
+ guarantee (w ->TState == QNode::TS_ENTER, "invariant") ;
// Once we set TState to TS_RUN the waiting thread can complete
// SimpleEnter and 'w' is pointing into random stack space. So we have
// to ensure we extract the ParkEvent (which is in type-stable memory)
// before we set the state, and then don't access 'w'.
ParkEvent * ev = w->_event ;
OrderAccess::loadstore();
- w->TState = ObjectWaiter::TS_RUN ;
+ w->TState = QNode::TS_RUN ;
OrderAccess::fence() ;
ev->unpark() ;
}
- return OS_OK ;
+ return ;
}
int JvmtiRawMonitor::SimpleWait (Thread * Self, jlong millis) {
guarantee (_owner == Self , "invariant") ;
guarantee (_recursions == 0, "invariant") ;
- ObjectWaiter Node (Self) ;
+ QNode Node (Self) ;
Node._notified = 0 ;
- Node.TState = ObjectWaiter::TS_WAIT ;
+ Node.TState = QNode::TS_WAIT ;
RawMonitor_lock->lock_without_safepoint_check() ;
Node._next = _WaitSet ;
@@ -208,12 +201,12 @@
// as TState is volatile and the lock-unlock operators are
// serializing (barrier-equivalent).
- if (Node.TState == ObjectWaiter::TS_WAIT) {
+ if (Node.TState == QNode::TS_WAIT) {
RawMonitor_lock->lock_without_safepoint_check() ;
- if (Node.TState == ObjectWaiter::TS_WAIT) {
+ if (Node.TState == QNode::TS_WAIT) {
// Simple O(n) unlink, but performance isn't critical here.
- ObjectWaiter * p ;
- ObjectWaiter * q = NULL ;
+ QNode * p ;
+ QNode * q = NULL ;
for (p = _WaitSet ; p != &Node; p = p->_next) {
q = p ;
}
@@ -225,12 +218,12 @@
guarantee (p == q->_next, "invariant") ;
q->_next = p->_next ;
}
- Node.TState = ObjectWaiter::TS_RUN ;
+ Node.TState = QNode::TS_RUN ;
}
RawMonitor_lock->unlock() ;
}
- guarantee (Node.TState == ObjectWaiter::TS_RUN, "invariant") ;
+ guarantee (Node.TState == QNode::TS_RUN, "invariant") ;
SimpleEnter (Self) ;
guarantee (_owner == Self, "invariant") ;
@@ -238,9 +231,9 @@
return ret ;
}
-int JvmtiRawMonitor::SimpleNotify (Thread * Self, bool All) {
+void JvmtiRawMonitor::SimpleNotify (Thread * Self, bool All) {
guarantee (_owner == Self, "invariant") ;
- if (_WaitSet == NULL) return OS_OK ;
+ if (_WaitSet == NULL) return ;
// We have two options:
// A. Transfer the threads from the WaitSet to the EntryList
@@ -252,29 +245,29 @@
ParkEvent * ev = NULL ; // consider using a small auto array ...
RawMonitor_lock->lock_without_safepoint_check() ;
for (;;) {
- ObjectWaiter * w = _WaitSet ;
+ QNode * w = _WaitSet ;
if (w == NULL) break ;
_WaitSet = w->_next ;
if (ev != NULL) { ev->unpark(); ev = NULL; }
ev = w->_event ;
OrderAccess::loadstore() ;
- w->TState = ObjectWaiter::TS_RUN ;
+ w->TState = QNode::TS_RUN ;
OrderAccess::storeload();
if (!All) break ;
}
RawMonitor_lock->unlock() ;
if (ev != NULL) ev->unpark();
- return OS_OK ;
+ return ;
}
// Any JavaThread will enter here with state _thread_blocked
-int JvmtiRawMonitor::raw_enter(TRAPS) {
+void JvmtiRawMonitor::raw_enter(Thread * Self) {
void * Contended ;
-
+ JavaThread * jt = NULL;
// don't enter raw monitor if thread is being externally suspended, it will
// surprise the suspender if a "suspended" thread can still enter monitor
- JavaThread * jt = (JavaThread *)THREAD;
- if (THREAD->is_Java_thread()) {
+ if (Self->is_Java_thread()) {
+ jt = (JavaThread*) Self;
jt->SR_lock()->lock_without_safepoint_check();
while (jt->is_external_suspend()) {
jt->SR_lock()->unlock();
@@ -282,150 +275,136 @@
jt->SR_lock()->lock_without_safepoint_check();
}
// guarded by SR_lock to avoid racing with new external suspend requests.
- Contended = Atomic::cmpxchg(THREAD, &_owner, (void*)NULL);
+ Contended = Atomic::cmpxchg(jt, &_owner, (Thread*)NULL);
jt->SR_lock()->unlock();
} else {
- Contended = Atomic::cmpxchg(THREAD, &_owner, (void*)NULL);
+ Contended = Atomic::cmpxchg(Self, &_owner, (Thread*)NULL);
}
- if (Contended == THREAD) {
+ if (Contended == Self) {
_recursions ++ ;
- return OM_OK ;
+ return ;
}
if (Contended == NULL) {
- guarantee (_owner == THREAD, "invariant") ;
+ guarantee (_owner == Self, "invariant") ;
guarantee (_recursions == 0, "invariant") ;
- return OM_OK ;
+ return ;
}
- THREAD->set_current_pending_monitor(this);
+ Self->set_current_pending_raw_monitor(this);
- if (!THREAD->is_Java_thread()) {
- // No other non-Java threads besides VM thread would acquire
- // a raw monitor.
- assert(THREAD->is_VM_thread(), "must be VM thread");
- SimpleEnter (THREAD) ;
- } else {
- guarantee (jt->thread_state() == _thread_blocked, "invariant") ;
- for (;;) {
- jt->set_suspend_equivalent();
- // cleared by handle_special_suspend_equivalent_condition() or
- // java_suspend_self()
- SimpleEnter (THREAD) ;
-
- // were we externally suspended while we were waiting?
- if (!jt->handle_special_suspend_equivalent_condition()) break ;
+ if (!Self->is_Java_thread()) {
+ SimpleEnter (Self) ;
+ } else {
+ guarantee (jt->thread_state() == _thread_blocked, "invariant") ;
+ for (;;) {
+ jt->set_suspend_equivalent();
+ // cleared by handle_special_suspend_equivalent_condition() or
+ // java_suspend_self()
+ SimpleEnter (jt) ;
- // This thread was externally suspended
- //
- // This logic isn't needed for JVMTI raw monitors,
- // but doesn't hurt just in case the suspend rules change. This
- // logic is needed for the JvmtiRawMonitor.wait() reentry phase.
- // We have reentered the contended monitor, but while we were
- // waiting another thread suspended us. We don't want to reenter
- // the monitor while suspended because that would surprise the
- // thread that suspended us.
- //
- // Drop the lock -
- SimpleExit (THREAD) ;
+ // were we externally suspended while we were waiting?
+ if (!jt->handle_special_suspend_equivalent_condition()) break ;
- jt->java_suspend_self();
- }
+ // This thread was externally suspended
+ // We have reentered the contended monitor, but while we were
+ // waiting another thread suspended us. We don't want to reenter
+ // the monitor while suspended because that would surprise the
+ // thread that suspended us.
+ //
+ // Drop the lock
+ SimpleExit (jt) ;
- assert(_owner == THREAD, "Fatal error with monitor owner!");
- assert(_recursions == 0, "Fatal error with monitor recursions!");
+ jt->java_suspend_self();
+ }
}
- THREAD->set_current_pending_monitor(NULL);
+ Self->set_current_pending_raw_monitor(NULL);
+
+ guarantee (_owner == Self, "invariant") ;
guarantee (_recursions == 0, "invariant") ;
- return OM_OK;
}
-// Used mainly for JVMTI raw monitor implementation
-// Also used for JvmtiRawMonitor::wait().
-int JvmtiRawMonitor::raw_exit(TRAPS) {
- if (THREAD != _owner) {
- return OM_ILLEGAL_MONITOR_STATE;
+int JvmtiRawMonitor::raw_exit(Thread * Self) {
+ if (Self != _owner) {
+ return M_ILLEGAL_MONITOR_STATE;
}
if (_recursions > 0) {
--_recursions ;
- return OM_OK ;
+ } else {
+ SimpleExit (Self) ;
}
- void * List = _EntryList ;
- SimpleExit (THREAD) ;
-
- return OM_OK;
+ return M_OK;
}
-// Used for JVMTI raw monitor implementation.
// All JavaThreads will enter here with state _thread_blocked
-int JvmtiRawMonitor::raw_wait(jlong millis, bool interruptible, TRAPS) {
- if (THREAD != _owner) {
- return OM_ILLEGAL_MONITOR_STATE;
+int JvmtiRawMonitor::raw_wait(jlong millis, bool interruptible, Thread * Self) {
+ if (Self != _owner) {
+ return M_ILLEGAL_MONITOR_STATE;
}
// To avoid spurious wakeups we reset the parkevent -- This is strictly optional.
// The caller must be able to tolerate spurious returns from raw_wait().
- THREAD->_ParkEvent->reset() ;
+ Self->_ParkEvent->reset() ;
OrderAccess::fence() ;
+ JavaThread * jt = NULL;
// check interrupt event
if (interruptible) {
- assert(THREAD->is_Java_thread(), "Only JavaThreads can be interruptible");
- JavaThread* jt = (JavaThread*) THREAD;
+ assert(Self->is_Java_thread(), "Only JavaThreads can be interruptible");
+ jt = (JavaThread*) Self;
if (jt->is_interrupted(true)) {
- return OM_INTERRUPTED;
+ return M_INTERRUPTED;
}
+ } else {
+ assert(!Self->is_Java_thread(), "JavaThreads must be interuptible");
}
intptr_t save = _recursions ;
_recursions = 0 ;
_waiters ++ ;
- if (THREAD->is_Java_thread()) {
- guarantee (((JavaThread *) THREAD)->thread_state() == _thread_blocked, "invariant") ;
- ((JavaThread *)THREAD)->set_suspend_equivalent();
+ if (Self->is_Java_thread()) {
+ guarantee (jt->thread_state() == _thread_blocked, "invariant") ;
+ jt->set_suspend_equivalent();
}
- int rv = SimpleWait (THREAD, millis) ;
+ int rv = SimpleWait (Self, millis) ;
_recursions = save ;
_waiters -- ;
- guarantee (THREAD == _owner, "invariant") ;
- if (THREAD->is_Java_thread()) {
- JavaThread * jSelf = (JavaThread *) THREAD ;
+ guarantee (Self == _owner, "invariant") ;
+ if (Self->is_Java_thread()) {
for (;;) {
- if (!jSelf->handle_special_suspend_equivalent_condition()) break ;
- SimpleExit (THREAD) ;
- jSelf->java_suspend_self();
- SimpleEnter (THREAD) ;
- jSelf->set_suspend_equivalent() ;
+ if (!jt->handle_special_suspend_equivalent_condition()) break ;
+ SimpleExit (jt) ;
+ jt->java_suspend_self();
+ SimpleEnter (jt) ;
+ jt->set_suspend_equivalent() ;
}
+ guarantee (jt == _owner, "invariant") ;
}
- guarantee (THREAD == _owner, "invariant") ;
- if (interruptible) {
- JavaThread* jt = (JavaThread*) THREAD;
- if (jt->is_interrupted(true)) {
- return OM_INTERRUPTED;
- }
+ if (interruptible && jt->is_interrupted(true)) {
+ return M_INTERRUPTED;
}
- return OM_OK ;
+
+ return M_OK ;
}
-int JvmtiRawMonitor::raw_notify(TRAPS) {
- if (THREAD != _owner) {
- return OM_ILLEGAL_MONITOR_STATE;
+int JvmtiRawMonitor::raw_notify(Thread * Self) {
+ if (Self != _owner) {
+ return M_ILLEGAL_MONITOR_STATE;
}
- SimpleNotify (THREAD, false) ;
- return OM_OK;
+ SimpleNotify (Self, false) ;
+ return M_OK;
}
-int JvmtiRawMonitor::raw_notifyAll(TRAPS) {
- if (THREAD != _owner) {
- return OM_ILLEGAL_MONITOR_STATE;
+int JvmtiRawMonitor::raw_notifyAll(Thread * Self) {
+ if (Self != _owner) {
+ return M_ILLEGAL_MONITOR_STATE;
}
- SimpleNotify (THREAD, true) ;
- return OM_OK;
+ SimpleNotify (Self, true) ;
+ return M_OK;
}
--- a/src/hotspot/share/prims/jvmtiRawMonitor.hpp Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/prims/jvmtiRawMonitor.hpp Tue Oct 08 11:57:11 2019 +0200
@@ -25,7 +25,8 @@
#ifndef SHARE_PRIMS_JVMTIRAWMONITOR_HPP
#define SHARE_PRIMS_JVMTIRAWMONITOR_HPP
-#include "runtime/objectMonitor.hpp"
+#include "memory/allocation.hpp"
+#include "runtime/park.hpp"
#include "utilities/growableArray.hpp"
//
@@ -33,31 +34,69 @@
//
// Used by JVMTI methods: All RawMonitor methods (CreateRawMonitor, EnterRawMonitor, etc.)
//
-// Wrapper for ObjectMonitor class that saves the Monitor's name
+// A simplified version of the ObjectMonitor code.
//
-class JvmtiRawMonitor : public ObjectMonitor {
-private:
+class JvmtiRawMonitor : public CHeapObj<mtSynchronizer> {
+
+ // Helper class to allow Threads to be linked into queues.
+ // This is a stripped down version of ObjectWaiter.
+ class QNode : public StackObj {
+ friend class JvmtiRawMonitor;
+ enum TStates { TS_READY, TS_RUN, TS_WAIT, TS_ENTER };
+ QNode* volatile _next;
+ QNode* volatile _prev;
+ ParkEvent * _event;
+ volatile int _notified;
+ volatile TStates TState;
+
+ QNode(Thread* thread);
+ };
+
+ Thread* volatile _owner; // pointer to owning thread
+ volatile int _recursions; // recursion count, 0 for first entry
+ QNode* volatile _EntryList; // Threads blocked on entry or reentry.
+ // The list is actually composed of nodes,
+ // acting as proxies for Threads.
+ QNode* volatile _WaitSet; // Threads wait()ing on the monitor
+ volatile jint _waiters; // number of waiting threads
int _magic;
char * _name;
// JVMTI_RM_MAGIC is set in contructor and unset in destructor.
enum { JVMTI_RM_MAGIC = (int)(('T' << 24) | ('I' << 16) | ('R' << 8) | 'M') };
- int SimpleEnter (Thread * Self) ;
- int SimpleExit (Thread * Self) ;
+ void SimpleEnter (Thread * Self) ;
+ void SimpleExit (Thread * Self) ;
int SimpleWait (Thread * Self, jlong millis) ;
- int SimpleNotify (Thread * Self, bool All) ;
+ void SimpleNotify(Thread * Self, bool All) ;
public:
+
+ // return codes
+ enum {
+ M_OK, // no error
+ M_ILLEGAL_MONITOR_STATE, // IllegalMonitorStateException
+ M_INTERRUPTED // Thread.interrupt()
+ };
+
+ // Non-aborting operator new
+ void* operator new(size_t size) throw() {
+ return CHeapObj::operator new(size, std::nothrow);
+ }
+
JvmtiRawMonitor(const char *name);
~JvmtiRawMonitor();
- int raw_enter(TRAPS);
- int raw_exit(TRAPS);
- int raw_wait(jlong millis, bool interruptable, TRAPS);
- int raw_notify(TRAPS);
- int raw_notifyAll(TRAPS);
- int magic() { return _magic; }
- const char *get_name() { return _name; }
+
+ Thread * owner() const { return _owner; }
+ void set_owner(Thread * owner) { _owner = owner; }
+ int recursions() const { return _recursions; }
+ void raw_enter(Thread * Self);
+ int raw_exit(Thread * Self);
+ int raw_wait(jlong millis, bool interruptable, Thread * Self);
+ int raw_notify(Thread * Self);
+ int raw_notifyAll(Thread * Self);
+ int magic() const { return _magic; }
+ const char *get_name() const { return _name; }
bool is_valid();
};
--- a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp Tue Oct 08 11:57:11 2019 +0200
@@ -3528,15 +3528,6 @@
"should be replaced");
}
}
- // Update deleted jmethodID
- for (int j = 0; j < _deleted_methods_length; ++j) {
- Method* old_method = _deleted_methods[j];
- jmethodID jmid = old_method->find_jmethod_id_or_null();
- if (jmid != NULL) {
- // Change the jmethodID to point to NSME.
- Method::change_method_associated_with_jmethod_id(jmid, Universe::throw_no_such_method_error());
- }
- }
}
int VM_RedefineClasses::check_methods_and_mark_as_obsolete() {
--- a/src/hotspot/share/runtime/mutexLocker.cpp Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/runtime/mutexLocker.cpp Tue Oct 08 11:57:11 2019 +0200
@@ -66,7 +66,6 @@
Mutex* RetData_lock = NULL;
Monitor* VMOperationQueue_lock = NULL;
Monitor* VMOperationRequest_lock = NULL;
-Monitor* SerializePage_lock = NULL;
Monitor* Threads_lock = NULL;
Mutex* NonJavaThreadsList_lock = NULL;
Mutex* NonJavaThreadsListSync_lock = NULL;
@@ -118,6 +117,7 @@
Monitor* Service_lock = NULL;
Monitor* PeriodicTask_lock = NULL;
Monitor* RedefineClasses_lock = NULL;
+Mutex* Verify_lock = NULL;
#if INCLUDE_JFR
Mutex* JfrStacktrace_lock = NULL;
@@ -298,6 +298,7 @@
def(CompileThread_lock , PaddedMonitor, nonleaf+5, false, _safepoint_check_always);
def(PeriodicTask_lock , PaddedMonitor, nonleaf+5, true, _safepoint_check_always);
def(RedefineClasses_lock , PaddedMonitor, nonleaf+5, true, _safepoint_check_always);
+ def(Verify_lock , PaddedMutex, nonleaf+5, true, _safepoint_check_always);
if (WhiteBoxAPI) {
def(Compilation_lock , PaddedMonitor, leaf, false, _safepoint_check_never);
--- a/src/hotspot/share/runtime/mutexLocker.hpp Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/runtime/mutexLocker.hpp Tue Oct 08 11:57:11 2019 +0200
@@ -103,7 +103,6 @@
extern Mutex* RawMonitor_lock;
extern Mutex* PerfDataMemAlloc_lock; // a lock on the allocator for PerfData memory for performance data
extern Mutex* PerfDataManager_lock; // a long on access to PerfDataManager resources
-extern Mutex* ParkerFreeList_lock;
extern Mutex* OopMapCacheAlloc_lock; // protects allocation of oop_map caches
extern Mutex* FreeList_lock; // protects the free region list during safepoints
@@ -114,6 +113,7 @@
extern Monitor* Service_lock; // a lock used for service thread operation
extern Monitor* PeriodicTask_lock; // protects the periodic task structure
extern Monitor* RedefineClasses_lock; // locks classes from parallel redefinition
+extern Mutex* Verify_lock; // synchronize initialization of verify library
extern Monitor* ThreadsSMRDelete_lock; // Used by ThreadsSMRSupport to take pressure off the Threads_lock
extern Mutex* ThreadIdTableCreate_lock; // Used by ThreadIdTable to lazily create the thread id table
extern Mutex* SharedDecoder_lock; // serializes access to the decoder during normal (not error reporting) use
--- a/src/hotspot/share/runtime/objectMonitor.hpp Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/runtime/objectMonitor.hpp Tue Oct 08 11:57:11 2019 +0200
@@ -43,7 +43,6 @@
class ObjectWaiter : public StackObj {
public:
enum TStates { TS_UNDEF, TS_READY, TS_RUN, TS_WAIT, TS_ENTER, TS_CXQ };
- enum Sorted { PREPEND, APPEND, SORTED };
ObjectWaiter* volatile _next;
ObjectWaiter* volatile _prev;
Thread* _thread;
@@ -51,7 +50,6 @@
ParkEvent * _event;
volatile int _notified;
volatile TStates TState;
- Sorted _Sorted; // List placement disposition
bool _active; // Contention monitoring is enabled
public:
ObjectWaiter(Thread* thread);
@@ -68,10 +66,6 @@
// WARNING: This is a very sensitive and fragile class. DO NOT make any
// changes unless you are fully aware of the underlying semantics.
//
-// Class JvmtiRawMonitor currently inherits from ObjectMonitor so
-// changes in this class must be careful to not break JvmtiRawMonitor.
-// These two subsystems should be separated.
-//
// ObjectMonitor Layout Overview/Highlights/Restrictions:
//
// - The _header field must be at offset 0 because the displaced header
@@ -127,16 +121,6 @@
// in a 64-bit JVM.
class ObjectMonitor {
- public:
- enum {
- OM_OK, // no error
- OM_SYSTEM_ERROR, // operating system error
- OM_ILLEGAL_MONITOR_STATE, // IllegalMonitorStateException
- OM_INTERRUPTED, // Thread.interrupt()
- OM_TIMED_OUT // Object.wait() timed out
- };
-
- private:
friend class ObjectSynchronizer;
friend class ObjectWaiter;
friend class VMStructs;
@@ -158,16 +142,13 @@
DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE,
sizeof(volatile markWord) + sizeof(void* volatile) +
sizeof(ObjectMonitor *));
- protected: // protected for JvmtiRawMonitor
void* volatile _owner; // pointer to owning thread OR BasicLock
- private:
volatile jlong _previous_owner_tid; // thread id of the previous owner of the monitor
- protected: // protected for JvmtiRawMonitor
volatile intptr_t _recursions; // recursion count, 0 for first entry
ObjectWaiter* volatile _EntryList; // Threads blocked on entry or reentry.
// The list is actually composed of WaitNodes,
// acting as proxies for Threads.
- private:
+
ObjectWaiter* volatile _cxq; // LL of recently-arrived threads blocked on entry.
Thread* volatile _succ; // Heir presumptive thread - used for futile wakeup throttling
Thread* volatile _Responsible;
--- a/src/hotspot/share/runtime/os.cpp Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/runtime/os.cpp Tue Oct 08 11:57:11 2019 +0200
@@ -536,14 +536,6 @@
char buffer[JVM_MAXPATHLEN];
char ebuf[1024];
- // Try to load verify dll first. In 1.3 java dll depends on it and is not
- // always able to find it when the loading executable is outside the JDK.
- // In order to keep working with 1.2 we ignore any loading errors.
- if (dll_locate_lib(buffer, sizeof(buffer), Arguments::get_dll_dir(),
- "verify")) {
- dll_load(buffer, ebuf, sizeof(ebuf));
- }
-
// Load java dll
if (dll_locate_lib(buffer, sizeof(buffer), Arguments::get_dll_dir(),
"java")) {
--- a/src/hotspot/share/runtime/thread.cpp Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/runtime/thread.cpp Tue Oct 08 11:57:11 2019 +0200
@@ -258,6 +258,7 @@
_current_pending_monitor = NULL;
_current_pending_monitor_is_from_java = true;
_current_waiting_monitor = NULL;
+ _current_pending_raw_monitor = NULL;
_num_nested_signal = 0;
om_free_list = NULL;
om_free_count = 0;
@@ -3847,7 +3848,7 @@
// Create the VMThread
{ TraceTime timer("Start VMThread", TRACETIME_LOG(Info, startuptime));
- VMThread::create();
+ VMThread::create();
Thread* vmthread = VMThread::vm_thread();
if (!os::create_thread(vmthread, os::vm_thread)) {
--- a/src/hotspot/share/runtime/thread.hpp Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/runtime/thread.hpp Tue Oct 08 11:57:11 2019 +0200
@@ -62,6 +62,7 @@
class ThreadsList;
class ThreadsSMRSupport;
+class JvmtiRawMonitor;
class JvmtiThreadState;
class ThreadStatistics;
class ConcurrentLocksDump;
@@ -404,6 +405,9 @@
ObjectMonitor* _current_pending_monitor; // ObjectMonitor this thread
// is waiting to lock
bool _current_pending_monitor_is_from_java; // locking is from Java code
+ JvmtiRawMonitor* _current_pending_raw_monitor; // JvmtiRawMonitor this thread
+ // is waiting to lock
+
// ObjectMonitor on which this thread called Object.wait()
ObjectMonitor* _current_waiting_monitor;
@@ -640,6 +644,14 @@
_current_waiting_monitor = monitor;
}
+ // For tracking the Jvmti raw monitor the thread is pending on.
+ JvmtiRawMonitor* current_pending_raw_monitor() {
+ return _current_pending_raw_monitor;
+ }
+ void set_current_pending_raw_monitor(JvmtiRawMonitor* monitor) {
+ _current_pending_raw_monitor = monitor;
+ }
+
// GC support
// Apply "f->do_oop" to all root oops in "this".
// Used by JavaThread::oops_do.
@@ -786,7 +798,7 @@
public:
volatile intptr_t _Stalled;
volatile int _TypeTag;
- ParkEvent * _ParkEvent; // for synchronized()
+ ParkEvent * _ParkEvent; // for Object monitors and JVMTI raw monitors
ParkEvent * _MuxEvent; // for low-level muxAcquire-muxRelease
int NativeSyncRecursion; // diagnostic
--- a/src/hotspot/share/services/threadService.cpp Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/services/threadService.cpp Tue Oct 08 11:57:11 2019 +0200
@@ -32,6 +32,7 @@
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
+#include "prims/jvmtiRawMonitor.hpp"
#include "runtime/atomic.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/init.hpp"
@@ -217,10 +218,10 @@
} else {
ObjectMonitor *enter_obj = thread->current_pending_monitor();
if (enter_obj != NULL) {
- // thread is trying to enter() or raw_enter() an ObjectMonitor.
+ // thread is trying to enter() an ObjectMonitor.
obj = (oop) enter_obj->object();
+ assert(obj != NULL, "ObjectMonitor should have an associated object!");
}
- // If obj == NULL, then ObjectMonitor is raw which doesn't count.
}
Handle h(Thread::current(), obj);
@@ -354,13 +355,15 @@
}
}
-// Find deadlocks involving object monitors and concurrent locks if concurrent_locks is true
+// Find deadlocks involving raw monitors, object monitors and concurrent locks
+// if concurrent_locks is true.
DeadlockCycle* ThreadService::find_deadlocks_at_safepoint(ThreadsList * t_list, bool concurrent_locks) {
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
// This code was modified from the original Threads::find_deadlocks code.
int globalDfn = 0, thisDfn;
ObjectMonitor* waitingToLockMonitor = NULL;
+ JvmtiRawMonitor* waitingToLockRawMonitor = NULL;
oop waitingToLockBlocker = NULL;
bool blocked_on_monitor = false;
JavaThread *currentThread, *previousThread;
@@ -391,13 +394,30 @@
// When there is a deadlock, all the monitors involved in the dependency
// cycle must be contended and heavyweight. So we only care about the
// heavyweight monitor a thread is waiting to lock.
- waitingToLockMonitor = (ObjectMonitor*)jt->current_pending_monitor();
+ waitingToLockMonitor = jt->current_pending_monitor();
+ // JVM TI raw monitors can also be involved in deadlocks, and we can be
+ // waiting to lock both a raw monitor and ObjectMonitor at the same time.
+ // It isn't clear how to make deadlock detection work correctly if that
+ // happens.
+ waitingToLockRawMonitor = jt->current_pending_raw_monitor();
+
if (concurrent_locks) {
waitingToLockBlocker = jt->current_park_blocker();
}
- while (waitingToLockMonitor != NULL || waitingToLockBlocker != NULL) {
+
+ while (waitingToLockMonitor != NULL ||
+ waitingToLockRawMonitor != NULL ||
+ waitingToLockBlocker != NULL) {
cycle->add_thread(currentThread);
- if (waitingToLockMonitor != NULL) {
+ // Give preference to the raw monitor
+ if (waitingToLockRawMonitor != NULL) {
+ Thread* owner = waitingToLockRawMonitor->owner();
+ if (owner != NULL && // the raw monitor could be released at any time
+ owner->is_Java_thread()) {
+ // only JavaThreads can be reported here
+ currentThread = (JavaThread*) owner;
+ }
+ } else if (waitingToLockMonitor != NULL) {
address currentOwner = (address)waitingToLockMonitor->owner();
if (currentOwner != NULL) {
currentThread = Threads::owning_thread_from_monitor_owner(t_list,
@@ -948,28 +968,44 @@
JavaThread* currentThread;
ObjectMonitor* waitingToLockMonitor;
+ JvmtiRawMonitor* waitingToLockRawMonitor;
oop waitingToLockBlocker;
int len = _threads->length();
for (int i = 0; i < len; i++) {
currentThread = _threads->at(i);
- waitingToLockMonitor = (ObjectMonitor*)currentThread->current_pending_monitor();
+ waitingToLockMonitor = currentThread->current_pending_monitor();
+ waitingToLockRawMonitor = currentThread->current_pending_raw_monitor();
waitingToLockBlocker = currentThread->current_park_blocker();
st->cr();
st->print_cr("\"%s\":", currentThread->get_thread_name());
const char* owner_desc = ",\n which is held by";
+
+ // Note: As the JVM TI "monitor contended enter" event callback is executed after ObjectMonitor
+ // sets the current pending monitor, it is possible to then see a pending raw monitor as well.
+ if (waitingToLockRawMonitor != NULL) {
+ st->print(" waiting to lock JVM TI raw monitor " INTPTR_FORMAT, p2i(waitingToLockRawMonitor));
+ Thread* owner = waitingToLockRawMonitor->owner();
+ // Could be NULL as the raw monitor could be released at any time if held by non-JavaThread
+ if (owner != NULL) {
+ if (owner->is_Java_thread()) {
+ currentThread = (JavaThread*) owner;
+ st->print_cr("%s \"%s\"", owner_desc, currentThread->get_thread_name());
+ } else {
+ st->print_cr(",\n which has now been released");
+ }
+ } else {
+ st->print_cr("%s non-Java thread=" PTR_FORMAT, owner_desc, p2i(owner));
+ }
+ }
+
if (waitingToLockMonitor != NULL) {
st->print(" waiting to lock monitor " INTPTR_FORMAT, p2i(waitingToLockMonitor));
oop obj = (oop)waitingToLockMonitor->object();
- if (obj != NULL) {
- st->print(" (object " INTPTR_FORMAT ", a %s)", p2i(obj),
- obj->klass()->external_name());
+ st->print(" (object " INTPTR_FORMAT ", a %s)", p2i(obj),
+ obj->klass()->external_name());
- if (!currentThread->current_pending_monitor_is_from_java()) {
- owner_desc = "\n in JNI, which is held by";
- }
- } else {
- // No Java object associated - a JVMTI raw monitor
- owner_desc = " (JVMTI raw monitor),\n which is held by";
+ if (!currentThread->current_pending_monitor_is_from_java()) {
+ owner_desc = "\n in JNI, which is held by";
}
currentThread = Threads::owning_thread_from_monitor_owner(t_list,
(address)waitingToLockMonitor->owner());
@@ -978,7 +1014,7 @@
// that owns waitingToLockMonitor should be findable, but
// if it is not findable, then the previous currentThread is
// blocked permanently.
- st->print("%s UNKNOWN_owner_addr=" PTR_FORMAT, owner_desc,
+ st->print_cr("%s UNKNOWN_owner_addr=" PTR_FORMAT, owner_desc,
p2i(waitingToLockMonitor->owner()));
continue;
}
@@ -992,11 +1028,10 @@
currentThread = java_lang_Thread::thread(ownerObj);
assert(currentThread != NULL, "AbstractOwnableSynchronizer owning thread is unexpectedly NULL");
}
- st->print("%s \"%s\"", owner_desc, currentThread->get_thread_name());
+ st->print_cr("%s \"%s\"", owner_desc, currentThread->get_thread_name());
}
st->cr();
- st->cr();
// Print stack traces
bool oldJavaMonitorsInStackTrace = JavaMonitorsInStackTrace;
--- a/src/java.base/share/classes/java/util/Collection.java Mon Oct 07 20:15:47 2019 +0200
+++ b/src/java.base/share/classes/java/util/Collection.java Tue Oct 08 11:57:11 2019 +0200
@@ -188,6 +188,38 @@
* or if the only reference to the backing collection is through an
* unmodifiable view, the view can be considered effectively immutable.
*
+ * <h2><a id="serializable">Serializability of Collections</a></h2>
+ *
+ * <p>Serializability of collections is optional. As such, none of the collections
+ * interfaces are declared to implement the {@link java.io.Serializable} interface.
+ * However, serializability is regarded as being generally useful, so most collection
+ * implementations are serializable.
+ *
+ * <p>The collection implementations that are public classes (such as {@code ArrayList}
+ * or {@code HashMap}) are declared to implement the {@code Serializable} interface if they
+ * are in fact serializable. Some collections implementations are not public classes,
+ * such as the <a href="#unmodifiable">unmodifiable collections.</a> In such cases, the
+ * serializability of such collections is described in the specification of the method
+ * that creates them, or in some other suitable place. In cases where the serializability
+ * of a collection is not specified, there is no guarantee about the serializability of such
+ * collections. In particular, many <a href="#view">view collections</a> are not serializable.
+ *
+ * <p>A collection implementation that implements the {@code Serializable} interface cannot
+ * be guaranteed to be serializable. The reason is that in general, collections
+ * contain elements of other types, and it is not possible to determine statically
+ * whether instances of some element type are actually serializable. For example, consider
+ * a serializable {@code Collection<E>}, where {@code E} does not implement the
+ * {@code Serializable} interface. The collection may be serializable, if it contains only
+ * elements of some serializable subtype of {@code E}, or if it is empty. Collections are
+ * thus said to be <i>conditionally serializable,</i> as the serializability of the collection
+ * as a whole depends on whether the collection itself is serializable and on whether all
+ * contained elements are also serializable.
+ *
+ * <p>An additional case occurs with instances of {@link SortedSet} and {@link SortedMap}.
+ * These collections can be created with a {@link Comparator} that imposes an ordering on
+ * the set elements or map keys. Such a collection is serializable only if the provided
+ * {@code Comparator} is also serializable.
+ *
* <p>This interface is a member of the
* <a href="{@docRoot}/java.base/java/util/package-summary.html#CollectionsFramework">
* Java Collections Framework</a>.
--- a/src/java.base/share/native/libjava/Class.c Mon Oct 07 20:15:47 2019 +0200
+++ b/src/java.base/share/native/libjava/Class.c Tue Oct 08 11:57:11 2019 +0200
@@ -35,12 +35,9 @@
#include "jni.h"
#include "jni_util.h"
#include "jvm.h"
+#include "check_classname.h"
#include "java_lang_Class.h"
-/* defined in libverify.so/verify.dll (src file common/check_format.c) */
-extern jboolean VerifyClassname(char *utf_name, jboolean arrayAllowed);
-extern jboolean VerifyFixClassname(char *utf_name);
-
#define OBJ "Ljava/lang/Object;"
#define CLS "Ljava/lang/Class;"
#define CPL "Ljdk/internal/reflect/ConstantPool;"
@@ -123,14 +120,14 @@
}
(*env)->GetStringUTFRegion(env, classname, 0, unicode_len, clname);
- if (VerifyFixClassname(clname) == JNI_TRUE) {
+ if (verifyFixClassname(clname) == JNI_TRUE) {
/* slashes present in clname, use name b4 translation for exception */
(*env)->GetStringUTFRegion(env, classname, 0, unicode_len, clname);
JNU_ThrowClassNotFoundException(env, clname);
goto done;
}
- if (!VerifyClassname(clname, JNI_TRUE)) { /* expects slashed name */
+ if (!verifyClassname(clname, JNI_TRUE)) { /* expects slashed name */
JNU_ThrowClassNotFoundException(env, clname);
goto done;
}
--- a/src/java.base/share/native/libjava/ClassLoader.c Mon Oct 07 20:15:47 2019 +0200
+++ b/src/java.base/share/native/libjava/ClassLoader.c Tue Oct 08 11:57:11 2019 +0200
@@ -30,14 +30,11 @@
#include "jni_util.h"
#include "jlong.h"
#include "jvm.h"
+#include "check_classname.h"
#include "java_lang_ClassLoader.h"
#include "java_lang_ClassLoader_NativeLibrary.h"
#include <string.h>
-/* defined in libverify.so/verify.dll (src file common/check_format.c) */
-extern jboolean VerifyClassname(char *utf_name, jboolean arrayAllowed);
-extern jboolean VerifyFixClassname(char *utf_name);
-
static JNINativeMethod methods[] = {
{"retrieveDirectives", "()Ljava/lang/AssertionStatusDirectives;", (void *)&JVM_AssertionStatusDirectives}
};
@@ -120,7 +117,7 @@
if (utfName == NULL) {
goto free_body;
}
- VerifyFixClassname(utfName);
+ fixClassname(utfName);
} else {
utfName = NULL;
}
@@ -185,7 +182,7 @@
JNU_ThrowOutOfMemoryError(env, NULL);
return result;
}
- VerifyFixClassname(utfName);
+ fixClassname(utfName);
} else {
utfName = NULL;
}
@@ -231,9 +228,9 @@
JNU_ThrowOutOfMemoryError(env, NULL);
return NULL;
}
- VerifyFixClassname(clname);
+ fixClassname(clname);
- if (!VerifyClassname(clname, JNI_TRUE)) { /* expects slashed name */
+ if (!verifyClassname(clname, JNI_TRUE)) { /* expects slashed name */
goto done;
}
--- a/src/java.base/share/native/libjava/VM.c Mon Oct 07 20:15:47 2019 +0200
+++ b/src/java.base/share/native/libjava/VM.c Tue Oct 08 11:57:11 2019 +0200
@@ -42,11 +42,6 @@
JNIEXPORT void JNICALL
Java_jdk_internal_misc_VM_initialize(JNIEnv *env, jclass cls) {
- if (!JDK_InitJvmHandle()) {
- JNU_ThrowInternalError(env, "Handle for JVM not found for symbol lookup");
- return;
- }
-
// Registers implementations of native methods described in methods[]
// above.
// In particular, registers JVM_GetNanoTimeAdjustment as the implementation
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/native/libjava/check_classname.c Tue Oct 08 11:57:11 2019 +0200
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 1997, 2019, 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. Oracle designates this
+ * 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
+ * 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.
+ */
+
+#include <assert.h>
+#include <limits.h>
+#include <setjmp.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "jni.h"
+#include "jvm.h"
+#include "check_classname.h"
+
+typedef unsigned short unicode;
+
+static char *
+skip_over_fieldname(char *name, jboolean slash_okay,
+ unsigned int len);
+static char *
+skip_over_field_signature(char *name, jboolean void_okay,
+ unsigned int len);
+
+/*
+ * Return non-zero if the character is a valid in JVM class name, zero
+ * otherwise. The only characters currently disallowed from JVM class
+ * names are given in the table below:
+ *
+ * Character Hex Decimal
+ * '.' 0x2e 46
+ * '/' 0x2f 47
+ * ';' 0x3b 59
+ * '[' 0x5b 91
+ *
+ * (Method names have further restrictions dealing with the '<' and
+ * '>' characters.)
+ */
+static int isJvmIdentifier(unicode ch) {
+ if( ch > 91 || ch < 46 )
+ return 1; /* Lowercase ASCII letters are > 91 */
+ else { /* 46 <= ch <= 91 */
+ if (ch <= 90 && ch >= 60) {
+ return 1; /* Uppercase ASCII recognized here */
+ } else { /* ch == 91 || 46 <= ch <= 59 */
+ if (ch == 91 || ch == 59 || ch <= 47)
+ return 0;
+ else
+ return 1;
+ }
+ }
+}
+
+static unicode
+next_utf2unicode(char **utfstring_ptr, int * valid)
+{
+ unsigned char *ptr = (unsigned char *)(*utfstring_ptr);
+ unsigned char ch, ch2, ch3;
+ int length = 1; /* default length */
+ unicode result = 0x80; /* default bad result; */
+ *valid = 1;
+ switch ((ch = ptr[0]) >> 4) {
+ default:
+ result = ch;
+ break;
+
+ case 0x8: case 0x9: case 0xA: case 0xB: case 0xF:
+ /* Shouldn't happen. */
+ *valid = 0;
+ break;
+
+ case 0xC: case 0xD:
+ /* 110xxxxx 10xxxxxx */
+ if (((ch2 = ptr[1]) & 0xC0) == 0x80) {
+ unsigned char high_five = ch & 0x1F;
+ unsigned char low_six = ch2 & 0x3F;
+ result = (high_five << 6) + low_six;
+ length = 2;
+ }
+ break;
+
+ case 0xE:
+ /* 1110xxxx 10xxxxxx 10xxxxxx */
+ if (((ch2 = ptr[1]) & 0xC0) == 0x80) {
+ if (((ch3 = ptr[2]) & 0xC0) == 0x80) {
+ unsigned char high_four = ch & 0x0f;
+ unsigned char mid_six = ch2 & 0x3f;
+ unsigned char low_six = ch3 & 0x3f;
+ result = (((high_four << 6) + mid_six) << 6) + low_six;
+ length = 3;
+ } else {
+ length = 2;
+ }
+ }
+ break;
+ } /* end of switch */
+
+ *utfstring_ptr = (char *)(ptr + length);
+ return result;
+}
+
+/* Take pointer to a string. Skip over the longest part of the string that
+ * could be taken as a fieldname. Allow '/' if slash_okay is JNI_TRUE.
+ *
+ * Return a pointer to just past the fieldname. Return NULL if no fieldname
+ * at all was found, or in the case of slash_okay being true, we saw
+ * consecutive slashes (meaning we were looking for a qualified path but
+ * found something that was badly-formed).
+ */
+static char *
+skip_over_fieldname(char *name, jboolean slash_okay,
+ unsigned int length)
+{
+ char *p;
+ unicode ch;
+ unicode last_ch = 0;
+ int valid = 1;
+ /* last_ch == 0 implies we are looking at the first char. */
+ for (p = name; p != name + length; last_ch = ch) {
+ char *old_p = p;
+ ch = *p;
+ if (ch < 128) {
+ p++;
+ if (isJvmIdentifier(ch)) {
+ continue;
+ }
+ } else {
+ char *tmp_p = p;
+ ch = next_utf2unicode(&tmp_p, &valid);
+ if (valid == 0)
+ return 0;
+ p = tmp_p;
+ if (isJvmIdentifier(ch)) {
+ continue;
+ }
+ }
+
+ if (slash_okay && ch == '/' && last_ch) {
+ if (last_ch == '/') {
+ return 0; /* Don't permit consecutive slashes */
+ }
+ } else if (ch == '_' || ch == '$') {
+ } else {
+ return last_ch ? old_p : 0;
+ }
+ }
+ return last_ch ? p : 0;
+}
+
+/* Take pointer to a string. Skip over the longest part of the string that
+ * could be taken as a field signature. Allow "void" if void_okay.
+ *
+ * Return a pointer to just past the signature. Return NULL if no legal
+ * signature is found.
+ */
+
+static char *
+skip_over_field_signature(char *name, jboolean void_okay,
+ unsigned int length)
+{
+ unsigned int array_dim = 0;
+ for (;length > 0;) {
+ switch (name[0]) {
+ case JVM_SIGNATURE_VOID:
+ if (!void_okay) return 0;
+ /* FALL THROUGH */
+ case JVM_SIGNATURE_BOOLEAN:
+ case JVM_SIGNATURE_BYTE:
+ case JVM_SIGNATURE_CHAR:
+ case JVM_SIGNATURE_SHORT:
+ case JVM_SIGNATURE_INT:
+ case JVM_SIGNATURE_FLOAT:
+ case JVM_SIGNATURE_LONG:
+ case JVM_SIGNATURE_DOUBLE:
+ return name + 1;
+
+ case JVM_SIGNATURE_CLASS: {
+ /* Skip over the classname, if one is there. */
+ char *p =
+ skip_over_fieldname(name + 1, JNI_TRUE, --length);
+ /* The next character better be a semicolon. */
+ if (p && p - name - 1 > 0 && p[0] == ';')
+ return p + 1;
+ return 0;
+ }
+
+ case JVM_SIGNATURE_ARRAY:
+ array_dim++;
+ /* JVMS 2nd ed. 4.10 */
+ /* The number of dimensions in an array is limited to 255 ... */
+ if (array_dim > 255) {
+ return 0;
+ }
+ /* The rest of what's there better be a legal signature. */
+ name++;
+ length--;
+ void_okay = JNI_FALSE;
+ break;
+
+ default:
+ return 0;
+ }
+ }
+ return 0;
+}
+
+/* Determine if the specified name is legal
+ * UTF name for a classname.
+ *
+ * Note that this routine expects the internal form of qualified classes:
+ * the dots should have been replaced by slashes.
+ */
+jboolean verifyClassname(char *name, jboolean allowArrayClass)
+{
+ size_t s = strlen(name);
+ assert(s <= UINT_MAX);
+ unsigned int length = (unsigned int)s;
+ char *p;
+
+ if (length > 0 && name[0] == JVM_SIGNATURE_ARRAY) {
+ if (!allowArrayClass) {
+ return JNI_FALSE;
+ } else {
+ /* Everything that's left better be a field signature */
+ p = skip_over_field_signature(name, JNI_FALSE, length);
+ }
+ } else {
+ /* skip over the fieldname. Slashes are okay */
+ p = skip_over_fieldname(name, JNI_TRUE, length);
+ }
+ return (p != 0 && p - name == (ptrdiff_t)length);
+}
+
+/*
+ * Translates '.' to '/'. Returns JNI_TRUE if any / were present.
+ */
+jboolean verifyFixClassname(char *name)
+{
+ char *p = name;
+ jboolean slashesFound = JNI_FALSE;
+ int valid = 1;
+
+ while (valid != 0 && *p != '\0') {
+ if (*p == '/') {
+ slashesFound = JNI_TRUE;
+ p++;
+ } else if (*p == '.') {
+ *p++ = '/';
+ } else {
+ next_utf2unicode(&p, &valid);
+ }
+ }
+
+ return slashesFound && valid != 0;
+}
+
+/*
+ * Translates '.' to '/'.
+ */
+void fixClassname(char *name)
+{
+ char *p = name;
+ int valid = 1;
+
+ while (valid != 0 && *p != '\0') {
+ if (*p == '.') {
+ *p++ = '/';
+ } else {
+ next_utf2unicode(&p, &valid);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/native/libjava/check_classname.h Tue Oct 08 11:57:11 2019 +0200
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2019, 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. Oracle designates this
+ * 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
+ * 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.
+ */
+
+#include "jni.h"
+
+/*
+ * Class name checking methods
+ */
+
+jboolean verifyClassname(char *name, jboolean allowArrayClass);
+jboolean verifyFixClassname(char *name);
+void fixClassname(char *name);
--- a/src/java.base/share/native/libjava/jdk_util.h Mon Oct 07 20:15:47 2019 +0200
+++ b/src/java.base/share/native/libjava/jdk_util.h Tue Oct 08 11:57:11 2019 +0200
@@ -45,20 +45,6 @@
JNIEXPORT void
JDK_GetVersionInfo0(jdk_version_info* info, size_t info_size);
-
-/*-------------------------------------------------------
- * Internal interface for JDK to use
- *-------------------------------------------------------
- */
-
-/* Init JVM handle for symbol lookup;
- * Return 0 if JVM handle not found.
- */
-int JDK_InitJvmHandle();
-
-/* Find the named JVM entry; returns NULL if not found. */
-void* JDK_FindJvmEntry(const char* name);
-
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
--- a/src/java.base/share/native/libjava/jni_util.c Mon Oct 07 20:15:47 2019 +0200
+++ b/src/java.base/share/native/libjava/jni_util.c Tue Oct 08 11:57:11 2019 +0200
@@ -77,77 +77,23 @@
}
JNIEXPORT void JNICALL
-JNU_ThrowIllegalAccessError(JNIEnv *env, const char *msg)
-{
- JNU_ThrowByName(env, "java/lang/IllegalAccessError", msg);
-}
-
-JNIEXPORT void JNICALL
-JNU_ThrowIllegalAccessException(JNIEnv *env, const char *msg)
-{
- JNU_ThrowByName(env, "java/lang/IllegalAccessException", msg);
-}
-
-JNIEXPORT void JNICALL
JNU_ThrowInternalError(JNIEnv *env, const char *msg)
{
JNU_ThrowByName(env, "java/lang/InternalError", msg);
}
JNIEXPORT void JNICALL
-JNU_ThrowNoSuchFieldException(JNIEnv *env, const char *msg)
-{
- JNU_ThrowByName(env, "java/lang/NoSuchFieldException", msg);
-}
-
-JNIEXPORT void JNICALL
-JNU_ThrowNoSuchMethodException(JNIEnv *env, const char *msg)
-{
- JNU_ThrowByName(env, "java/lang/NoSuchMethodException", msg);
-}
-
-JNIEXPORT void JNICALL
JNU_ThrowClassNotFoundException(JNIEnv *env, const char *msg)
{
JNU_ThrowByName(env, "java/lang/ClassNotFoundException", msg);
}
JNIEXPORT void JNICALL
-JNU_ThrowNumberFormatException(JNIEnv *env, const char *msg)
-{
- JNU_ThrowByName(env, "java/lang/NumberFormatException", msg);
-}
-
-JNIEXPORT void JNICALL
JNU_ThrowIOException(JNIEnv *env, const char *msg)
{
JNU_ThrowByName(env, "java/io/IOException", msg);
}
-JNIEXPORT void JNICALL
-JNU_ThrowNoSuchFieldError(JNIEnv *env, const char *msg)
-{
- JNU_ThrowByName(env, "java/lang/NoSuchFieldError", msg);
-}
-
-JNIEXPORT void JNICALL
-JNU_ThrowNoSuchMethodError(JNIEnv *env, const char *msg)
-{
- JNU_ThrowByName(env, "java/lang/NoSuchMethodError", msg);
-}
-
-JNIEXPORT void JNICALL
-JNU_ThrowStringIndexOutOfBoundsException(JNIEnv *env, const char *msg)
-{
- JNU_ThrowByName(env, "java/lang/StringIndexOutOfBoundsException", msg);
-}
-
-JNIEXPORT void JNICALL
-JNU_ThrowInstantiationException(JNIEnv *env, const char *msg)
-{
- JNU_ThrowByName(env, "java/lang/InstantiationException", msg);
-}
-
/*
* Throw an exception by name, using the string returned by
* getLastErrorString for the detail string. If the last-error
@@ -845,12 +791,6 @@
CHECK_NULL(String_value_ID);
}
-JNIEXPORT jstring
-NewStringPlatform(JNIEnv *env, const char *str)
-{
- return JNU_NewStringPlatform(env, str);
-}
-
JNIEXPORT jstring JNICALL
JNU_NewStringPlatform(JNIEnv *env, const char *str)
{
@@ -1024,54 +964,6 @@
return cls;
}
-JNIEXPORT jclass JNICALL
-JNU_ClassClass(JNIEnv *env)
-{
- static jclass cls = 0;
- if (cls == 0) {
- jclass c;
- if ((*env)->EnsureLocalCapacity(env, 1) < 0)
- return 0;
- c = (*env)->FindClass(env, "java/lang/Class");
- CHECK_NULL_RETURN(c, NULL);
- cls = (*env)->NewGlobalRef(env, c);
- (*env)->DeleteLocalRef(env, c);
- }
- return cls;
-}
-
-JNIEXPORT jclass JNICALL
-JNU_ClassObject(JNIEnv *env)
-{
- static jclass cls = 0;
- if (cls == 0) {
- jclass c;
- if ((*env)->EnsureLocalCapacity(env, 1) < 0)
- return 0;
- c = (*env)->FindClass(env, "java/lang/Object");
- CHECK_NULL_RETURN(c, NULL);
- cls = (*env)->NewGlobalRef(env, c);
- (*env)->DeleteLocalRef(env, c);
- }
- return cls;
-}
-
-JNIEXPORT jclass JNICALL
-JNU_ClassThrowable(JNIEnv *env)
-{
- static jclass cls = 0;
- if (cls == 0) {
- jclass c;
- if ((*env)->EnsureLocalCapacity(env, 1) < 0)
- return 0;
- c = (*env)->FindClass(env, "java/lang/Throwable");
- CHECK_NULL_RETURN(c, NULL);
- cls = (*env)->NewGlobalRef(env, c);
- (*env)->DeleteLocalRef(env, c);
- }
- return cls;
-}
-
JNIEXPORT jint JNICALL
JNU_CopyObjectArray(JNIEnv *env, jobjectArray dst, jobjectArray src,
jint count)
@@ -1110,125 +1002,10 @@
return JNI_ERR;
}
-JNIEXPORT jboolean JNICALL
-JNU_Equals(JNIEnv *env, jobject object1, jobject object2)
-{
- static jmethodID mid = NULL;
- if (mid == NULL) {
- jclass objClazz = JNU_ClassObject(env);
- CHECK_NULL_RETURN(objClazz, JNI_FALSE);
- mid = (*env)->GetMethodID(env, objClazz, "equals",
- "(Ljava/lang/Object;)Z");
- CHECK_NULL_RETURN(mid, JNI_FALSE);
- }
- return (*env)->CallBooleanMethod(env, object1, mid, object2);
-}
-
-
-/************************************************************************
- * Thread calls
- */
-
-static jmethodID Object_waitMID;
-static jmethodID Object_notifyMID;
-static jmethodID Object_notifyAllMID;
-
-JNIEXPORT void JNICALL
-JNU_MonitorWait(JNIEnv *env, jobject object, jlong timeout)
-{
- if (object == NULL) {
- JNU_ThrowNullPointerException(env, "JNU_MonitorWait argument");
- return;
- }
- if (Object_waitMID == NULL) {
- jclass cls = JNU_ClassObject(env);
- if (cls == NULL) {
- return;
- }
- Object_waitMID = (*env)->GetMethodID(env, cls, "wait", "(J)V");
- if (Object_waitMID == NULL) {
- return;
- }
- }
- (*env)->CallVoidMethod(env, object, Object_waitMID, timeout);
-}
-
-JNIEXPORT void JNICALL
-JNU_Notify(JNIEnv *env, jobject object)
-{
- if (object == NULL) {
- JNU_ThrowNullPointerException(env, "JNU_Notify argument");
- return;
- }
- if (Object_notifyMID == NULL) {
- jclass cls = JNU_ClassObject(env);
- if (cls == NULL) {
- return;
- }
- Object_notifyMID = (*env)->GetMethodID(env, cls, "notify", "()V");
- if (Object_notifyMID == NULL) {
- return;
- }
- }
- (*env)->CallVoidMethod(env, object, Object_notifyMID);
-}
-
-JNIEXPORT void JNICALL
-JNU_NotifyAll(JNIEnv *env, jobject object)
-{
- if (object == NULL) {
- JNU_ThrowNullPointerException(env, "JNU_NotifyAll argument");
- return;
- }
- if (Object_notifyAllMID == NULL) {
- jclass cls = JNU_ClassObject(env);
- if (cls == NULL) {
- return;
- }
- Object_notifyAllMID = (*env)->GetMethodID(env, cls,"notifyAll", "()V");
- if (Object_notifyAllMID == NULL) {
- return;
- }
- }
- (*env)->CallVoidMethod(env, object, Object_notifyAllMID);
-}
-
-
/************************************************************************
* Debugging utilities
*/
-JNIEXPORT void JNICALL
-JNU_PrintString(JNIEnv *env, char *hdr, jstring string)
-{
- if (string == NULL) {
- fprintf(stderr, "%s: is NULL\n", hdr);
- } else {
- const char *stringPtr = JNU_GetStringPlatformChars(env, string, 0);
- if (stringPtr == 0)
- return;
- fprintf(stderr, "%s: %s\n", hdr, stringPtr);
- JNU_ReleaseStringPlatformChars(env, string, stringPtr);
- }
-}
-
-JNIEXPORT void JNICALL
-JNU_PrintClass(JNIEnv *env, char* hdr, jobject object)
-{
- if (object == NULL) {
- fprintf(stderr, "%s: object is NULL\n", hdr);
- return;
- } else {
- jclass cls = (*env)->GetObjectClass(env, object);
- jstring clsName = JNU_ToString(env, cls);
- if (clsName == NULL) {
- JNU_PrintString(env, hdr, clsName);
- }
- (*env)->DeleteLocalRef(env, cls);
- (*env)->DeleteLocalRef(env, clsName);
- }
-}
-
JNIEXPORT jstring JNICALL
JNU_ToString(JNIEnv *env, jobject object)
{
@@ -1437,70 +1214,3 @@
}
return result;
}
-
-JNIEXPORT void JNICALL
-JNU_SetStaticFieldByName(JNIEnv *env,
- jboolean *hasException,
- const char *classname,
- const char *name,
- const char *signature,
- ...)
-{
- jclass cls;
- jfieldID fid;
- va_list args;
-
- if ((*env)->EnsureLocalCapacity(env, 3) < 0)
- goto done2;
-
- cls = (*env)->FindClass(env, classname);
- if (cls == 0)
- goto done2;
-
- fid = (*env)->GetStaticFieldID(env, cls, name, signature);
- if (fid == 0)
- goto done1;
-
- va_start(args, signature);
- switch (*signature) {
- case '[':
- case 'L':
- (*env)->SetStaticObjectField(env, cls, fid, va_arg(args, jobject));
- break;
- case 'Z':
- (*env)->SetStaticBooleanField(env, cls, fid, (jboolean)va_arg(args, int));
- break;
- case 'B':
- (*env)->SetStaticByteField(env, cls, fid, (jbyte)va_arg(args, int));
- break;
- case 'C':
- (*env)->SetStaticCharField(env, cls, fid, (jchar)va_arg(args, int));
- break;
- case 'S':
- (*env)->SetStaticShortField(env, cls, fid, (jshort)va_arg(args, int));
- break;
- case 'I':
- (*env)->SetStaticIntField(env, cls, fid, va_arg(args, jint));
- break;
- case 'J':
- (*env)->SetStaticLongField(env, cls, fid, va_arg(args, jlong));
- break;
- case 'F':
- (*env)->SetStaticFloatField(env, cls, fid, (jfloat)va_arg(args, jdouble));
- break;
- case 'D':
- (*env)->SetStaticDoubleField(env, cls, fid, va_arg(args, jdouble));
- break;
-
- default:
- (*env)->FatalError(env, "JNU_SetStaticFieldByName: illegal signature");
- }
- va_end(args);
-
- done1:
- (*env)->DeleteLocalRef(env, cls);
- done2:
- if (hasException) {
- *hasException = (*env)->ExceptionCheck(env);
- }
-}
--- a/src/java.base/share/native/libjava/jni_util.h Mon Oct 07 20:15:47 2019 +0200
+++ b/src/java.base/share/native/libjava/jni_util.h Tue Oct 08 11:57:11 2019 +0200
@@ -62,41 +62,14 @@
JNU_ThrowIllegalArgumentException(JNIEnv *env, const char *msg);
JNIEXPORT void JNICALL
-JNU_ThrowIllegalAccessError(JNIEnv *env, const char *msg);
-
-JNIEXPORT void JNICALL
-JNU_ThrowIllegalAccessException(JNIEnv *env, const char *msg);
-
-JNIEXPORT void JNICALL
JNU_ThrowInternalError(JNIEnv *env, const char *msg);
JNIEXPORT void JNICALL
JNU_ThrowIOException(JNIEnv *env, const char *msg);
JNIEXPORT void JNICALL
-JNU_ThrowNoSuchFieldException(JNIEnv *env, const char *msg);
-
-JNIEXPORT void JNICALL
-JNU_ThrowNoSuchMethodException(JNIEnv *env, const char *msg);
-
-JNIEXPORT void JNICALL
JNU_ThrowClassNotFoundException(JNIEnv *env, const char *msg);
-JNIEXPORT void JNICALL
-JNU_ThrowNumberFormatException(JNIEnv *env, const char *msg);
-
-JNIEXPORT void JNICALL
-JNU_ThrowNoSuchFieldError(JNIEnv *env, const char *msg);
-
-JNIEXPORT void JNICALL
-JNU_ThrowNoSuchMethodError(JNIEnv *env, const char *msg);
-
-JNIEXPORT void JNICALL
-JNU_ThrowStringIndexOutOfBoundsException(JNIEnv *env, const char *msg);
-
-JNIEXPORT void JNICALL
-JNU_ThrowInstantiationException(JNIEnv *env, const char *msg);
-
/* Throw an exception by name, using the string returned by
* getLastErrorString for the detail string. If the last-error
* string is NULL, use the given default detail string.
@@ -120,9 +93,6 @@
JNU_ThrowIOExceptionWithLastError(JNIEnv *env, const char *defaultDetail);
/* Convert between Java strings and i18n C strings */
-JNIEXPORT jstring
-NewStringPlatform(JNIEnv *env, const char *str);
-
JNIEXPORT const char *
GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy);
@@ -139,15 +109,6 @@
JNIEXPORT jclass JNICALL
JNU_ClassString(JNIEnv *env);
-JNIEXPORT jclass JNICALL
-JNU_ClassClass(JNIEnv *env);
-
-JNIEXPORT jclass JNICALL
-JNU_ClassObject(JNIEnv *env);
-
-JNIEXPORT jclass JNICALL
-JNU_ClassThrowable(JNIEnv *env);
-
/* Copy count number of arguments from src to dst. Array bounds
* and ArrayStoreException are checked.
*/
@@ -246,36 +207,6 @@
const char *classname,
const char *name,
const char *sig);
-JNIEXPORT void JNICALL
-JNU_SetStaticFieldByName(JNIEnv *env,
- jboolean *hasException,
- const char *classname,
- const char *name,
- const char *sig,
- ...);
-
-
-/*
- * Calls the .equals method.
- */
-JNIEXPORT jboolean JNICALL
-JNU_Equals(JNIEnv *env, jobject object1, jobject object2);
-
-
-/************************************************************************
- * Thread calls
- *
- * Convenience thread-related calls on the java.lang.Object class.
- */
-
-JNIEXPORT void JNICALL
-JNU_MonitorWait(JNIEnv *env, jobject object, jlong timeout);
-
-JNIEXPORT void JNICALL
-JNU_Notify(JNIEnv *env, jobject object);
-
-JNIEXPORT void JNICALL
-JNU_NotifyAll(JNIEnv *env, jobject object);
/************************************************************************
@@ -349,19 +280,15 @@
} \
} while (0)
#endif /* __cplusplus */
+
/************************************************************************
* Debugging utilities
*/
-JNIEXPORT void JNICALL
-JNU_PrintString(JNIEnv *env, char *hdr, jstring string);
-
-JNIEXPORT void JNICALL
-JNU_PrintClass(JNIEnv *env, char *hdr, jobject object);
-
JNIEXPORT jstring JNICALL
JNU_ToString(JNIEnv *env, jobject object);
+
/*
* Package shorthand for use by native libraries
*/
@@ -402,8 +329,6 @@
FAST_UTF_8
};
-int getFastEncoding();
-
JNIEXPORT void InitializeEncoding(JNIEnv *env, const char *name);
void* getProcessHandle();
--- a/src/java.base/share/native/libjava/verify_stub.c Mon Oct 07 20:15:47 2019 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 1999, 2003, 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. Oracle designates this
- * 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
- * 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.
- */
-
-
-/*
- * The real verifier now lives in libverifier.so/verifier.dll.
- *
- * This dummy exists so that HotSpot will run with the new
- * libjava.so/java.dll which is where is it accustomed to finding the
- * verifier.
- */
-
-#include "jni.h"
-
-struct struct_class_size_info;
-typedef struct struct_class_size_info class_size_info;
-
-
-JNIIMPORT jboolean
-VerifyClass(JNIEnv *env, jclass cb, char *buffer, jint len);
-
-JNIIMPORT jboolean
-VerifyClassForMajorVersion(JNIEnv *env, jclass cb, char *buffer, jint len,
- jint major_version);
-
-JNIEXPORT jboolean
-VerifyClassCodes(JNIEnv *env, jclass cb, char *buffer, jint len)
-{
- return VerifyClass(env, cb, buffer, len);
-}
-
-JNIEXPORT jboolean
-VerifyClassCodesForMajorVersion(JNIEnv *env, jclass cb, char *buffer,
- jint len, jint major_version)
-{
- return VerifyClassForMajorVersion(env, cb, buffer, len, major_version);
-}
--- a/src/java.base/share/native/libverify/check_code.c Mon Oct 07 20:15:47 2019 +0200
+++ b/src/java.base/share/native/libverify/check_code.c Tue Oct 08 11:57:11 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2019, 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
@@ -31,9 +31,6 @@
Exported function:
jboolean
- VerifyClass(JNIEnv *env, jclass cb, char *message_buffer,
- jint buffer_length)
- jboolean
VerifyClassForMajorVersion(JNIEnv *env, jclass cb, char *message_buffer,
jint buffer_length, jint major_version)
@@ -910,20 +907,6 @@
return result;
}
-#define OLD_FORMAT_MAX_MAJOR_VERSION 48
-
-JNIEXPORT jboolean
-VerifyClass(JNIEnv *env, jclass cb, char *buffer, jint len)
-{
- static int warned = 0;
- if (!warned) {
- jio_fprintf(stdout, "Warning! An old version of jvm is used. This is not supported.\n");
- warned = 1;
- }
- return VerifyClassForMajorVersion(env, cb, buffer, len,
- OLD_FORMAT_MAX_MAJOR_VERSION);
-}
-
static void
verify_field(context_type *context, jclass cb, int field_index)
{
--- a/src/java.base/share/native/libverify/check_format.c Mon Oct 07 20:15:47 2019 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,278 +0,0 @@
-/*
- * Copyright (c) 1997, 2008, 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. Oracle designates this
- * 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
- * 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.
- */
-
-#include <assert.h>
-#include <limits.h>
-#include <setjmp.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "jni.h"
-#include "jvm.h"
-
-typedef unsigned short unicode;
-
-static char *
-skip_over_fieldname(char *name, jboolean slash_okay,
- unsigned int len);
-static char *
-skip_over_field_signature(char *name, jboolean void_okay,
- unsigned int len);
-
-/*
- * Return non-zero if the character is a valid in JVM class name, zero
- * otherwise. The only characters currently disallowed from JVM class
- * names are given in the table below:
- *
- * Character Hex Decimal
- * '.' 0x2e 46
- * '/' 0x2f 47
- * ';' 0x3b 59
- * '[' 0x5b 91
- *
- * (Method names have further restrictions dealing with the '<' and
- * '>' characters.)
- */
-static int isJvmIdentifier(unicode ch) {
- if( ch > 91 || ch < 46 )
- return 1; /* Lowercase ASCII letters are > 91 */
- else { /* 46 <= ch <= 91 */
- if (ch <= 90 && ch >= 60) {
- return 1; /* Uppercase ASCII recognized here */
- } else { /* ch == 91 || 46 <= ch <= 59 */
- if (ch == 91 || ch == 59 || ch <= 47)
- return 0;
- else
- return 1;
- }
- }
-}
-
-static unicode
-next_utf2unicode(char **utfstring_ptr, int * valid)
-{
- unsigned char *ptr = (unsigned char *)(*utfstring_ptr);
- unsigned char ch, ch2, ch3;
- int length = 1; /* default length */
- unicode result = 0x80; /* default bad result; */
- *valid = 1;
- switch ((ch = ptr[0]) >> 4) {
- default:
- result = ch;
- break;
-
- case 0x8: case 0x9: case 0xA: case 0xB: case 0xF:
- /* Shouldn't happen. */
- *valid = 0;
- break;
-
- case 0xC: case 0xD:
- /* 110xxxxx 10xxxxxx */
- if (((ch2 = ptr[1]) & 0xC0) == 0x80) {
- unsigned char high_five = ch & 0x1F;
- unsigned char low_six = ch2 & 0x3F;
- result = (high_five << 6) + low_six;
- length = 2;
- }
- break;
-
- case 0xE:
- /* 1110xxxx 10xxxxxx 10xxxxxx */
- if (((ch2 = ptr[1]) & 0xC0) == 0x80) {
- if (((ch3 = ptr[2]) & 0xC0) == 0x80) {
- unsigned char high_four = ch & 0x0f;
- unsigned char mid_six = ch2 & 0x3f;
- unsigned char low_six = ch3 & 0x3f;
- result = (((high_four << 6) + mid_six) << 6) + low_six;
- length = 3;
- } else {
- length = 2;
- }
- }
- break;
- } /* end of switch */
-
- *utfstring_ptr = (char *)(ptr + length);
- return result;
-}
-
-/* Take pointer to a string. Skip over the longest part of the string that
- * could be taken as a fieldname. Allow '/' if slash_okay is JNI_TRUE.
- *
- * Return a pointer to just past the fieldname. Return NULL if no fieldname
- * at all was found, or in the case of slash_okay being true, we saw
- * consecutive slashes (meaning we were looking for a qualified path but
- * found something that was badly-formed).
- */
-static char *
-skip_over_fieldname(char *name, jboolean slash_okay,
- unsigned int length)
-{
- char *p;
- unicode ch;
- unicode last_ch = 0;
- int valid = 1;
- /* last_ch == 0 implies we are looking at the first char. */
- for (p = name; p != name + length; last_ch = ch) {
- char *old_p = p;
- ch = *p;
- if (ch < 128) {
- p++;
- if (isJvmIdentifier(ch)) {
- continue;
- }
- } else {
- char *tmp_p = p;
- ch = next_utf2unicode(&tmp_p, &valid);
- if (valid == 0)
- return 0;
- p = tmp_p;
- if (isJvmIdentifier(ch)) {
- continue;
- }
- }
-
- if (slash_okay && ch == '/' && last_ch) {
- if (last_ch == '/') {
- return 0; /* Don't permit consecutive slashes */
- }
- } else if (ch == '_' || ch == '$') {
- } else {
- return last_ch ? old_p : 0;
- }
- }
- return last_ch ? p : 0;
-}
-
-/* Take pointer to a string. Skip over the longest part of the string that
- * could be taken as a field signature. Allow "void" if void_okay.
- *
- * Return a pointer to just past the signature. Return NULL if no legal
- * signature is found.
- */
-
-static char *
-skip_over_field_signature(char *name, jboolean void_okay,
- unsigned int length)
-{
- unsigned int array_dim = 0;
- for (;length > 0;) {
- switch (name[0]) {
- case JVM_SIGNATURE_VOID:
- if (!void_okay) return 0;
- /* FALL THROUGH */
- case JVM_SIGNATURE_BOOLEAN:
- case JVM_SIGNATURE_BYTE:
- case JVM_SIGNATURE_CHAR:
- case JVM_SIGNATURE_SHORT:
- case JVM_SIGNATURE_INT:
- case JVM_SIGNATURE_FLOAT:
- case JVM_SIGNATURE_LONG:
- case JVM_SIGNATURE_DOUBLE:
- return name + 1;
-
- case JVM_SIGNATURE_CLASS: {
- /* Skip over the classname, if one is there. */
- char *p =
- skip_over_fieldname(name + 1, JNI_TRUE, --length);
- /* The next character better be a semicolon. */
- if (p && p - name - 1 > 0 && p[0] == ';')
- return p + 1;
- return 0;
- }
-
- case JVM_SIGNATURE_ARRAY:
- array_dim++;
- /* JVMS 2nd ed. 4.10 */
- /* The number of dimensions in an array is limited to 255 ... */
- if (array_dim > 255) {
- return 0;
- }
- /* The rest of what's there better be a legal signature. */
- name++;
- length--;
- void_okay = JNI_FALSE;
- break;
-
- default:
- return 0;
- }
- }
- return 0;
-}
-
-
-/* Used in java/lang/Class.c */
-/* Determine if the specified name is legal
- * UTF name for a classname.
- *
- * Note that this routine expects the internal form of qualified classes:
- * the dots should have been replaced by slashes.
- */
-JNIEXPORT jboolean
-VerifyClassname(char *name, jboolean allowArrayClass)
-{
- size_t s = strlen(name);
- assert(s <= UINT_MAX);
- unsigned int length = (unsigned int)s;
- char *p;
-
- if (length > 0 && name[0] == JVM_SIGNATURE_ARRAY) {
- if (!allowArrayClass) {
- return JNI_FALSE;
- } else {
- /* Everything that's left better be a field signature */
- p = skip_over_field_signature(name, JNI_FALSE, length);
- }
- } else {
- /* skip over the fieldname. Slashes are okay */
- p = skip_over_fieldname(name, JNI_TRUE, length);
- }
- return (p != 0 && p - name == (ptrdiff_t)length);
-}
-
-/*
- * Translates '.' to '/'. Returns JNI_TRUE is any / were present.
- */
-JNIEXPORT jboolean
-VerifyFixClassname(char *name)
-{
- char *p = name;
- jboolean slashesFound = JNI_FALSE;
- int valid = 1;
-
- while (valid != 0 && *p != '\0') {
- if (*p == '/') {
- slashesFound = JNI_TRUE;
- p++;
- } else if (*p == '.') {
- *p++ = '/';
- } else {
- next_utf2unicode(&p, &valid);
- }
- }
-
- return slashesFound && valid != 0;
-}
--- a/src/java.base/unix/native/libjava/jdk_util_md.c Mon Oct 07 20:15:47 2019 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2004, 2005, 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. Oracle designates this
- * 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
- * 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.
- */
-
-#include <dlfcn.h>
-#include "jdk_util.h"
-
-int JDK_InitJvmHandle() {
- /* nop */
- return 1;
-}
-
-void* JDK_FindJvmEntry(const char* name) {
- return dlsym(RTLD_DEFAULT, name);
-}
--- a/src/java.base/windows/native/libjava/jdk_util_md.c Mon Oct 07 20:15:47 2019 +0200
+++ b/src/java.base/windows/native/libjava/jdk_util_md.c Tue Oct 08 11:57:11 2019 +0200
@@ -28,17 +28,6 @@
#define JVM_DLL "jvm.dll"
-static HMODULE jvm_handle = NULL;
-
-int JDK_InitJvmHandle() {
- jvm_handle = GetModuleHandle(JVM_DLL);
- return (jvm_handle != NULL);
-}
-
-void* JDK_FindJvmEntry(const char* name) {
- return (void*) GetProcAddress(jvm_handle, name);
-}
-
JNIEXPORT HMODULE JDK_LoadSystemLibrary(const char* name) {
HMODULE handle = NULL;
char path[MAX_PATH];
--- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11AEADCipher.java Mon Oct 07 20:15:47 2019 +0200
+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11AEADCipher.java Tue Oct 08 11:57:11 2019 +0200
@@ -378,9 +378,6 @@
long p11KeyID = p11Key.getKeyID();
try {
- if (session == null) {
- session = token.getOpSession();
- }
CK_MECHANISM mechWithParams;
switch (blockMode) {
case MODE_GCM:
@@ -390,6 +387,9 @@
default:
throw new ProviderException("Unsupported mode: " + blockMode);
}
+ if (session == null) {
+ session = token.getOpSession();
+ }
if (encrypt) {
token.p11.C_EncryptInit(session.id(), mechWithParams,
p11KeyID);
@@ -398,7 +398,6 @@
p11KeyID);
}
} catch (PKCS11Exception e) {
- //e.printStackTrace();
p11Key.releaseKeyID();
session = token.releaseSession(session);
throw e;
@@ -718,7 +717,9 @@
errorCode == CKR_ENCRYPTED_DATA_LEN_RANGE) {
throw (IllegalBlockSizeException)
(new IllegalBlockSizeException(e.toString()).initCause(e));
- } else if (errorCode == CKR_ENCRYPTED_DATA_INVALID) {
+ } else if (errorCode == CKR_ENCRYPTED_DATA_INVALID ||
+ // Solaris-specific
+ errorCode == CKR_GENERAL_ERROR) {
throw (BadPaddingException)
(new BadPaddingException(e.toString()).initCause(e));
}
--- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Digest.java Mon Oct 07 20:15:47 2019 +0200
+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Digest.java Tue Oct 08 11:57:11 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -103,9 +103,11 @@
digestLength = 20;
break;
case (int)CKM_SHA224:
+ case (int)CKM_SHA512_224:
digestLength = 28;
break;
case (int)CKM_SHA256:
+ case (int)CKM_SHA512_256:
digestLength = 32;
break;
case (int)CKM_SHA384:
--- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Mac.java Mon Oct 07 20:15:47 2019 +0200
+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Mac.java Tue Oct 08 11:57:11 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -91,9 +91,11 @@
macLength = 20;
break;
case (int)CKM_SHA224_HMAC:
+ case (int)CKM_SHA512_224_HMAC:
macLength = 28;
break;
case (int)CKM_SHA256_HMAC:
+ case (int)CKM_SHA512_256_HMAC:
macLength = 32;
break;
case (int)CKM_SHA384_HMAC:
--- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c Mon Oct 07 20:15:47 2019 +0200
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c Tue Oct 08 11:57:11 2019 +0200
@@ -721,7 +721,7 @@
}
// populate using java values
- ckParamPtr->prfMechanism = jLongToCKULong(jPrfMechanism);
+ ckParamPtr->prfHashMechanism = jLongToCKULong(jPrfMechanism);
ckParamPtr->ulMacLength = jLongToCKULong(jUlMacLength);
ckParamPtr->ulServerOrClient = jLongToCKULong(jUlServerOrClient);
@@ -1014,17 +1014,18 @@
}
/*
- * converts the Java CK_GCM_PARAMS object to a CK_GCM_PARAMS pointer
+ * converts the Java CK_GCM_PARAMS object to a CK_GCM_PARAMS_NO_IVBITS pointer
+ * Note: Need to try NSS definition first to avoid SIGSEGV.
*
* @param env - used to call JNI funktions to get the Java classes and objects
* @param jParam - the Java CK_GCM_PARAMS object to convert
* @param pLength - length of the allocated memory of the returned pointer
- * @return pointer to the new CK_GCM_PARAMS structure
+ * @return pointer to the new CK_GCM_PARAMS_NO_IVBITS structure
*/
-CK_GCM_PARAMS_PTR
+CK_GCM_PARAMS_NO_IVBITS_PTR
jGCMParamsToCKGCMParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength)
{
- CK_GCM_PARAMS_PTR ckParamPtr;
+ CK_GCM_PARAMS_NO_IVBITS_PTR ckParamPtr;
jclass jGcmParamsClass;
jfieldID fieldID;
jobject jIv, jAad;
@@ -1052,8 +1053,8 @@
if (fieldID == NULL) { return NULL; }
jTagLen = (*env)->GetLongField(env, jParam, fieldID);
- // allocate memory for CK_GCM_PARAMS pointer
- ckParamPtr = calloc(1, sizeof(CK_GCM_PARAMS));
+ // allocate memory for CK_GCM_PARAMS_NO_IVBITS pointer
+ ckParamPtr = calloc(1, sizeof(CK_GCM_PARAMS_NO_IVBITS));
if (ckParamPtr == NULL) {
throwOutOfMemoryError(env, 0);
return NULL;
@@ -1073,16 +1074,15 @@
ckParamPtr->ulTagBits = jLongToCKULong(jTagLen);
if (pLength != NULL) {
- *pLength = sizeof(CK_GCM_PARAMS);
+ *pLength = sizeof(CK_GCM_PARAMS_NO_IVBITS);
}
- TRACE1("Created inner GCM_PARAMS PTR %lX\n", ptr_to_jlong(ckParamPtr));
+ TRACE1("Created inner GCM_PARAMS PTR w/o ulIvBits %p\n", ckParamPtr);
return ckParamPtr;
cleanup:
free(ckParamPtr->pIv);
free(ckParamPtr->pAAD);
free(ckParamPtr);
return NULL;
-
}
/*
@@ -1179,7 +1179,7 @@
throwOutOfMemoryError(env, 0);
return NULL;
}
- TRACE1("DEBUG jMechanismToCKMechanismPtr: allocated mech %p \n", ckpMech);
+ TRACE1("DEBUG jMechanismToCKMechanismPtr: allocated mech %p\n", ckpMech);
ckpMech->mechanism = jLongToCKULong(jMechType);
--- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_crypt.c Mon Oct 07 20:15:47 2019 +0200
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_crypt.c Tue Oct 08 11:57:11 2019 +0200
@@ -72,6 +72,7 @@
{
CK_SESSION_HANDLE ckSessionHandle;
CK_MECHANISM_PTR ckpMechanism = NULL;
+ CK_MECHANISM_PTR ckpTemp;
CK_OBJECT_HANDLE ckKeyHandle;
CK_RV rv;
@@ -81,15 +82,32 @@
ckSessionHandle = jLongToCKULong(jSessionHandle);
ckKeyHandle = jLongToCKULong(jKeyHandle);
ckpMechanism = jMechanismToCKMechanismPtr(env, jMechanism);
+ TRACE1("DEBUG C_EncryptInit: created pMech = %p\n",
+ ckpMechanism);
+
if ((*env)->ExceptionCheck(env)) { return; }
rv = (*ckpFunctions->C_EncryptInit)(ckSessionHandle, ckpMechanism,
ckKeyHandle);
- // if OAEP, then cannot free here
+ if (ckpMechanism->mechanism == CKM_AES_GCM) {
+ if (rv == CKR_ARGUMENTS_BAD || rv == CKR_MECHANISM_PARAM_INVALID) {
+ // retry with CKM_GCM_PARAMS structure in pkcs11t.h
+ TRACE0("DEBUG C_EncryptInit: retry with CK_GCM_PARAMS\n");
+ ckpTemp = updateGCMParams(env, ckpMechanism);
+ if (ckpTemp != NULL) { // only re-call if conversion succeeds
+ ckpMechanism = ckpTemp;
+ rv = (*ckpFunctions->C_EncryptInit)(ckSessionHandle, ckpMechanism,
+ ckKeyHandle);
+ }
+ }
+ }
+
+ TRACE1("DEBUG C_EncryptInit: freed pMech = %p\n", ckpMechanism);
freeCKMechanismPtr(ckpMechanism);
+ if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
- if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+ TRACE0("FINISHED\n");
}
#endif
@@ -292,6 +310,7 @@
{
CK_SESSION_HANDLE ckSessionHandle;
CK_MECHANISM_PTR ckpMechanism = NULL;
+ CK_MECHANISM_PTR ckpTemp;
CK_OBJECT_HANDLE ckKeyHandle;
CK_RV rv;
@@ -301,15 +320,32 @@
ckSessionHandle = jLongToCKULong(jSessionHandle);
ckKeyHandle = jLongToCKULong(jKeyHandle);
ckpMechanism = jMechanismToCKMechanismPtr(env, jMechanism);
+ TRACE1("DEBUG C_DecryptInit: created pMech = %p\n",
+ ckpMechanism);
+
if ((*env)->ExceptionCheck(env)) { return; }
rv = (*ckpFunctions->C_DecryptInit)(ckSessionHandle, ckpMechanism,
ckKeyHandle);
- // if OAEP, then cannot free here
+ if (ckpMechanism->mechanism == CKM_AES_GCM) {
+ if (rv == CKR_ARGUMENTS_BAD || rv == CKR_MECHANISM_PARAM_INVALID) {
+ // retry with CKM_GCM_PARAMS structure in pkcs11t.h
+ TRACE0("DEBUG C_DecryptInit: retry with CK_GCM_PARAMS\n");
+ ckpTemp = updateGCMParams(env, ckpMechanism);
+ if (ckpTemp != NULL) { // only re-call if conversion succeeds
+ ckpMechanism = ckpTemp;
+ rv = (*ckpFunctions->C_DecryptInit)(ckSessionHandle, ckpMechanism,
+ ckKeyHandle);
+ }
+ }
+ }
+
+ TRACE1("DEBUG C_DecryptInit: freed pMech = %p\n", ckpMechanism);
freeCKMechanismPtr(ckpMechanism);
+ if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
- if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+ TRACE0("FINISHED\n");
}
#endif
--- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c Mon Oct 07 20:15:47 2019 +0200
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c Tue Oct 08 11:57:11 2019 +0200
@@ -302,29 +302,30 @@
CK_TLS12_KEY_MAT_PARAMS* tlsKmTmp;
if (mechPtr != NULL) {
- TRACE2("DEBUG: free mech %lX (mech id = 0x%lX)\n",
- ptr_to_jlong(mechPtr), mechPtr->mechanism);
+ TRACE2("DEBUG freeCKMechanismPtr: free pMech %p (mech 0x%lX)\n",
+ mechPtr, mechPtr->mechanism);
if (mechPtr->pParameter != NULL) {
+ tmp = mechPtr->pParameter;
switch (mechPtr->mechanism) {
case CKM_AES_GCM:
- tmp = mechPtr->pParameter;
- TRACE1("\t=> free GCM_PARAMS %lX\n",
- ptr_to_jlong(tmp));
- free(((CK_GCM_PARAMS*)tmp)->pIv);
- free(((CK_GCM_PARAMS*)tmp)->pAAD);
+ if (mechPtr->ulParameterLen == sizeof(CK_GCM_PARAMS_NO_IVBITS)) {
+ TRACE0("[ GCM_PARAMS w/o ulIvBits ]\n");
+ free(((CK_GCM_PARAMS_NO_IVBITS*)tmp)->pIv);
+ free(((CK_GCM_PARAMS_NO_IVBITS*)tmp)->pAAD);
+ } else if (mechPtr->ulParameterLen == sizeof(CK_GCM_PARAMS)) {
+ TRACE0("[ GCM_PARAMS ]\n");
+ free(((CK_GCM_PARAMS*)tmp)->pIv);
+ free(((CK_GCM_PARAMS*)tmp)->pAAD);
+ }
break;
case CKM_AES_CCM:
- tmp = mechPtr->pParameter;
- TRACE1("\t=> free CK_CCM_PARAMS %lX\n",
- ptr_to_jlong(tmp));
+ TRACE0("[ CK_CCM_PARAMS ]\n");
free(((CK_CCM_PARAMS*)tmp)->pNonce);
free(((CK_CCM_PARAMS*)tmp)->pAAD);
break;
case CKM_TLS_PRF:
case CKM_NSS_TLS_PRF_GENERAL:
- tmp = mechPtr->pParameter;
- TRACE1("\t=> free CK_TLS_PRF_PARAMS %lX\n",
- ptr_to_jlong(tmp));
+ TRACE0("[ CK_TLS_PRF_PARAMS ]\n");
free(((CK_TLS_PRF_PARAMS*)tmp)->pSeed);
free(((CK_TLS_PRF_PARAMS*)tmp)->pLabel);
free(((CK_TLS_PRF_PARAMS*)tmp)->pulOutputLen);
@@ -334,18 +335,16 @@
case CKM_TLS_MASTER_KEY_DERIVE:
case CKM_SSL3_MASTER_KEY_DERIVE_DH:
case CKM_TLS_MASTER_KEY_DERIVE_DH:
- sslMkdTmp = mechPtr->pParameter;
- TRACE1("\t=> free CK_SSL3_MASTER_KEY_DERIVE_PARAMS %lX\n",
- ptr_to_jlong(sslMkdTmp));
+ sslMkdTmp = tmp;
+ TRACE0("[ CK_SSL3_MASTER_KEY_DERIVE_PARAMS ]\n");
free(sslMkdTmp->RandomInfo.pClientRandom);
free(sslMkdTmp->RandomInfo.pServerRandom);
free(sslMkdTmp->pVersion);
break;
case CKM_SSL3_KEY_AND_MAC_DERIVE:
case CKM_TLS_KEY_AND_MAC_DERIVE:
- sslKmTmp = mechPtr->pParameter;
- TRACE1("\t=> free CK_SSL3_KEY_MAT_PARAMS %lX\n",
- ptr_to_jlong(sslKmTmp));
+ sslKmTmp = tmp;
+ TRACE0("[ CK_SSL3_KEY_MAT_PARAMS ]\n");
free(sslKmTmp->RandomInfo.pClientRandom);
free(sslKmTmp->RandomInfo.pServerRandom);
if (sslKmTmp->pReturnedKeyMaterial != NULL) {
@@ -356,17 +355,15 @@
break;
case CKM_TLS12_MASTER_KEY_DERIVE:
case CKM_TLS12_MASTER_KEY_DERIVE_DH:
- tlsMkdTmp = mechPtr->pParameter;
- TRACE1("\t=> CK_TLS12_MASTER_KEY_DERIVE_PARAMS %lX\n",
- ptr_to_jlong(tlsMkdTmp));
+ tlsMkdTmp = tmp;
+ TRACE0("[ CK_TLS12_MASTER_KEY_DERIVE_PARAMS ]\n");
free(tlsMkdTmp->RandomInfo.pClientRandom);
free(tlsMkdTmp->RandomInfo.pServerRandom);
free(tlsMkdTmp->pVersion);
break;
case CKM_TLS12_KEY_AND_MAC_DERIVE:
- tlsKmTmp = mechPtr->pParameter;
- TRACE1("\t=> free CK_TLS12_KEY_MAT_PARAMS %lX\n",
- ptr_to_jlong(tlsKmTmp));
+ tlsKmTmp = tmp;
+ TRACE0("[ CK_TLS12_KEY_MAT_PARAMS ]\n");
free(tlsKmTmp->RandomInfo.pClientRandom);
free(tlsKmTmp->RandomInfo.pServerRandom);
if (tlsKmTmp->pReturnedKeyMaterial != NULL) {
@@ -377,9 +374,7 @@
break;
case CKM_ECDH1_DERIVE:
case CKM_ECDH1_COFACTOR_DERIVE:
- tmp = mechPtr->pParameter;
- TRACE1("\t=> free CK_ECDH1_DERIVE_PARAMS %lX\n",
- ptr_to_jlong(tmp));
+ TRACE0("[ CK_ECDH1_DERIVE_PARAMS ]\n");
free(((CK_ECDH1_DERIVE_PARAMS *)tmp)->pSharedData);
free(((CK_ECDH1_DERIVE_PARAMS *)tmp)->pPublicData);
break;
@@ -387,7 +382,6 @@
case CKM_AES_CTR:
case CKM_RSA_PKCS_PSS:
case CKM_CAMELLIA_CTR:
- TRACE0("\t=> NO OP\n");
// params do not contain pointers
break;
default:
@@ -399,17 +393,59 @@
// CKM_EXTRACT_KEY_FROM_KEY, CKM_OTP, CKM_KIP,
// CKM_DSA_PARAMETER_GEN?, CKM_GOSTR3410_*
// CK_any_CBC_ENCRYPT_DATA?
- TRACE0("\t=> ERROR UNSUPPORTED CK PARAMS\n");
+ TRACE0("ERROR: UNSUPPORTED CK_MECHANISM\n");
break;
}
- free(mechPtr->pParameter);
+ TRACE1("\t=> freed param %p\n", tmp);
+ free(tmp);
} else {
- TRACE0("DEBUG => Parameter NULL\n");
+ TRACE0("\t=> param NULL\n");
}
free(mechPtr);
+ TRACE0("FINISHED\n");
}
}
+/* This function replaces the CK_GCM_PARAMS_NO_IVBITS structure associated
+ * with the specified CK_MECHANISM structure with CK_GCM_PARAMS
+ * structure.
+ *
+ * @param mechPtr pointer to the CK_MECHANISM structure containing
+ * the to-be-converted CK_GCM_PARAMS_NO_IVBITS structure.
+ * @return pointer to the CK_MECHANISM structure containing the
+ * converted CK_GCM_PARAMS structure or NULL if no conversion took place.
+ */
+CK_MECHANISM_PTR updateGCMParams(JNIEnv *env, CK_MECHANISM_PTR mechPtr) {
+ CK_GCM_PARAMS* pGcmParams2 = NULL;
+ CK_GCM_PARAMS_NO_IVBITS* pParams = NULL;
+ if ((mechPtr->mechanism == CKM_AES_GCM) &&
+ (mechPtr->pParameter != NULL_PTR) &&
+ (mechPtr->ulParameterLen == sizeof(CK_GCM_PARAMS_NO_IVBITS))) {
+ pGcmParams2 = calloc(1, sizeof(CK_GCM_PARAMS));
+ if (pGcmParams2 == NULL) {
+ throwOutOfMemoryError(env, 0);
+ return NULL;
+ }
+ pParams = (CK_GCM_PARAMS_NO_IVBITS*) mechPtr->pParameter;
+ pGcmParams2->pIv = pParams->pIv;
+ pGcmParams2->ulIvLen = pParams->ulIvLen;
+ pGcmParams2->ulIvBits = (pGcmParams2->ulIvLen << 3);
+ pGcmParams2->pAAD = pParams->pAAD;
+ pGcmParams2->ulAADLen = pParams->ulAADLen;
+ pGcmParams2->ulTagBits = pParams->ulTagBits;
+ TRACE1("DEBUG updateGCMParams: pMech %p\n", mechPtr);
+ TRACE2("\t=> GCM param w/o ulIvBits %p => GCM param %p\n", pParams,
+ pGcmParams2);
+ free(pParams);
+ mechPtr->pParameter = pGcmParams2;
+ mechPtr->ulParameterLen = sizeof(CK_GCM_PARAMS);
+ return mechPtr;
+ } else {
+ TRACE0("DEBUG updateGCMParams: no conversion done\n");
+ }
+ return NULL;
+}
+
/*
* the following functions convert Java arrays to PKCS#11 array pointers and
* their array length and vice versa
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11gcm2.h Tue Oct 08 11:57:11 2019 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2019, 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.
+ */
+
+/* There is a known incompatibility for CK_GCM_PARAMS structure.
+ * PKCS#11 v2.40 standard mechanisms specification specifies
+ * CK_GCM_PARAMS as
+ * typedef struct CK_GCM_PARAMS {
+ * CK_BYTE_PTR pIv;
+ * CK_ULONG ulIvLen;
+ * CK_BYTE_PTR pAAD;
+ * CK_ULONG ulAADLen;
+ * CK_ULONG ulTagBits;
+ * } CK_GCM_PARAMS;
+ * However, the official header file of PKCS#11 v2.40 defines the
+ * CK_GCM_PARAMS with an extra "ulIvBits" field (type CK_ULONG).
+ * NSS uses the spec version while Solaris and SoftHSM2 use the header
+ * version. In order to work with both sides, SunPKCS11 provider defines
+ * the spec version of CK_GCM_PARAMS as CK_GCM_PARAMS_NO_IVBITS (as in this
+ * file) and uses it first before failing over to the header version.
+ */
+#ifndef _PKCS11GCM2_H_
+#define _PKCS11GCM2_H_ 1
+
+/* include the platform dependent part of the header */
+typedef struct CK_GCM_PARAMS_NO_IVBITS {
+ CK_BYTE_PTR pIv;
+ CK_ULONG ulIvLen;
+ CK_BYTE_PTR pAAD;
+ CK_ULONG ulAADLen;
+ CK_ULONG ulTagBits;
+} CK_GCM_PARAMS_NO_IVBITS;
+
+typedef CK_GCM_PARAMS_NO_IVBITS CK_PTR CK_GCM_PARAMS_NO_IVBITS_PTR;
+
+#endif /* _PKCS11GCM2_H_ */
--- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11t.h Mon Oct 07 20:15:47 2019 +0200
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11t.h Tue Oct 08 11:57:11 2019 +0200
@@ -1833,6 +1833,7 @@
typedef struct CK_GCM_PARAMS {
CK_BYTE_PTR pIv;
CK_ULONG ulIvLen;
+ CK_ULONG ulIvBits;
CK_BYTE_PTR pAAD;
CK_ULONG ulAADLen;
CK_ULONG ulTagBits;
@@ -1962,7 +1963,7 @@
typedef CK_TLS_KDF_PARAMS CK_PTR CK_TLS_KDF_PARAMS_PTR;
typedef struct CK_TLS_MAC_PARAMS {
- CK_MECHANISM_TYPE prfMechanism;
+ CK_MECHANISM_TYPE prfHashMechanism;
CK_ULONG ulMacLength;
CK_ULONG ulServerOrClient;
} CK_TLS_MAC_PARAMS;
@@ -2000,3 +2001,4 @@
#endif /* _PKCS11T_H_ */
+
--- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h Mon Oct 07 20:15:47 2019 +0200
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h Tue Oct 08 11:57:11 2019 +0200
@@ -159,7 +159,6 @@
/* include the platform dependent part of the header */
#include "p11_md.h"
-#include "pkcs11.h"
#include <jni.h>
#include <jni_util.h>
#include <stdarg.h>
@@ -296,6 +295,10 @@
#define CLASS_TLS_PRF_PARAMS "sun/security/pkcs11/wrapper/CK_TLS_PRF_PARAMS"
#define CLASS_TLS_MAC_PARAMS "sun/security/pkcs11/wrapper/CK_TLS_MAC_PARAMS"
+/* function to update the CK_NSS_GCM_PARAMS in mechanism pointer with
+ * CK_GCM_PARAMS
+ */
+CK_MECHANISM_PTR updateGCMParams(JNIEnv *env, CK_MECHANISM_PTR mechPtr);
/* function to convert a PKCS#11 return value other than CK_OK into a Java Exception
* or to throw a PKCS11RuntimeException
--- a/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.h Mon Oct 07 20:15:47 2019 +0200
+++ b/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.h Tue Oct 08 11:57:11 2019 +0200
@@ -1,3 +1,7 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ */
+
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
@@ -69,6 +73,7 @@
#endif
#include "pkcs11.h"
+#include "pkcs11gcm2.h"
#include "jni.h"
--- a/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.h Mon Oct 07 20:15:47 2019 +0200
+++ b/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.h Tue Oct 08 11:57:11 2019 +0200
@@ -1,3 +1,7 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ */
+
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
@@ -77,6 +81,7 @@
#endif /* CreateMutex */
#include "pkcs11.h"
+#include "pkcs11gcm2.h"
/* statement according to PKCS11 docu */
#pragma pack(pop, cryptoki)
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecording.java Mon Oct 07 20:15:47 2019 +0200
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecording.java Tue Oct 08 11:57:11 2019 +0200
@@ -370,10 +370,16 @@
public void setDestination(WriteableUserPath userSuppliedPath) throws IOException {
synchronized (recorder) {
+ checkSetDestination(userSuppliedPath);
+ this.destination = userSuppliedPath;
+ }
+ }
+
+ public void checkSetDestination(WriteableUserPath userSuppliedPath) throws IOException {
+ synchronized (recorder) {
if (Utils.isState(getState(), RecordingState.STOPPED, RecordingState.CLOSED)) {
throw new IllegalStateException("Destination can't be set on a recording that has been stopped/closed");
}
- this.destination = userSuppliedPath;
}
}
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/management/ManagementSupport.java Mon Oct 07 20:15:47 2019 +0200
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/management/ManagementSupport.java Tue Oct 08 11:57:11 2019 +0200
@@ -25,6 +25,8 @@
package jdk.jfr.internal.management;
+import java.io.IOException;
+import java.nio.file.Paths;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Collections;
@@ -98,4 +100,12 @@
WriteableUserPath wup = pr.getDestination();
return wup == null ? null : wup.getOriginalText();
}
+
+ public static void checkSetDestination(Recording recording, String destination) throws IOException{
+ PlatformRecording pr = PrivateAccess.getInstance().getPlatformRecording(recording);
+ if(destination != null){
+ WriteableUserPath wup = new WriteableUserPath(Paths.get(destination));
+ pr.checkSetDestination(wup);
+ }
+ }
}
--- a/src/jdk.management.jfr/share/classes/jdk/management/jfr/FlightRecorderMXBeanImpl.java Mon Oct 07 20:15:47 2019 +0200
+++ b/src/jdk.management.jfr/share/classes/jdk/management/jfr/FlightRecorderMXBeanImpl.java Tue Oct 08 11:57:11 2019 +0200
@@ -28,6 +28,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
+import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.AccessControlContext;
import java.security.AccessController;
@@ -105,7 +106,8 @@
private static final String OPTION_DISK = "disk";
private static final String OPTION_DUMP_ON_EXIT = "dumpOnExit";
private static final String OPTION_DURATION = "duration";
- private static final List<String> OPTIONS = Arrays.asList(new String[] { OPTION_DUMP_ON_EXIT, OPTION_DURATION, OPTION_NAME, OPTION_MAX_AGE, OPTION_MAX_SIZE, OPTION_DISK, });
+ private static final String OPTION_DESTINATION = "destination";
+ private static final List<String> OPTIONS = Arrays.asList(new String[] { OPTION_DUMP_ON_EXIT, OPTION_DURATION, OPTION_NAME, OPTION_MAX_AGE, OPTION_MAX_SIZE, OPTION_DISK, OPTION_DESTINATION, });
private final StreamManager streamHandler = new StreamManager();
private final Map<Long, Object> changes = new ConcurrentHashMap<>();
private final AtomicLong sequenceNumber = new AtomicLong();
@@ -283,6 +285,7 @@
validateOption(ops, OPTION_MAX_AGE, MBeanUtils::duration);
validateOption(ops, OPTION_MAX_SIZE, MBeanUtils::size);
validateOption(ops, OPTION_DURATION, MBeanUtils::duration);
+ validateOption(ops, OPTION_DESTINATION, x -> MBeanUtils.destination(r, x));
// All OK, now set them.atomically
setOption(ops, OPTION_DUMP_ON_EXIT, "false", MBeanUtils::booleanValue, x -> r.setDumpOnExit(x));
@@ -291,6 +294,7 @@
setOption(ops, OPTION_MAX_AGE, null, MBeanUtils::duration, x -> r.setMaxAge(x));
setOption(ops, OPTION_MAX_SIZE, "0", MBeanUtils::size, x -> r.setMaxSize(x));
setOption(ops, OPTION_DURATION, null, MBeanUtils::duration, x -> r.setDuration(x));
+ setOption(ops, OPTION_DESTINATION, null, x -> MBeanUtils.destination(r, x), x -> setOptionDestination(r, x));
}
@Override
@@ -305,6 +309,7 @@
Long maxSize = r.getMaxSize();
options.put(OPTION_MAX_SIZE, String.valueOf(maxSize == null ? "0" : maxSize.toString()));
options.put(OPTION_DURATION, ManagementSupport.formatTimespan(r.getDuration(), " "));
+ options.put(OPTION_DESTINATION, ManagementSupport.getDestinationOriginalText(r));
return options;
}
@@ -349,6 +354,20 @@
}
}
+ private static void setOptionDestination(Recording recording, String destination){
+ try {
+ Path pathDestination = null;
+ if(destination != null){
+ pathDestination = Paths.get(destination);
+ }
+ recording.setDestination(pathDestination);
+ } catch (IOException e) {
+ IllegalArgumentException iae = new IllegalArgumentException("Not a valid destination " + destination);
+ iae.addSuppressed(e);
+ throw iae;
+ }
+ }
+
private static <T, U> void validateOption(Map<String, String> options, String name, Function<String, U> validator) {
try {
String v = options.get(name);
--- a/src/jdk.management.jfr/share/classes/jdk/management/jfr/MBeanUtils.java Mon Oct 07 20:15:47 2019 +0200
+++ b/src/jdk.management.jfr/share/classes/jdk/management/jfr/MBeanUtils.java Tue Oct 08 11:57:11 2019 +0200
@@ -24,6 +24,7 @@
*/
package jdk.management.jfr;
+import java.io.IOException;
import java.lang.management.ManagementPermission;
import java.security.Permission;
import java.time.DateTimeException;
@@ -37,6 +38,7 @@
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
+import jdk.jfr.Recording;
import jdk.jfr.internal.management.ManagementSupport;
final class MBeanUtils {
@@ -126,5 +128,16 @@
}
return size;
}
+
+ public static String destination(Recording recording, String destination) throws IllegalArgumentException{
+ try {
+ ManagementSupport.checkSetDestination(recording, destination);
+ return destination;
+ }catch(IOException e){
+ IllegalArgumentException iae = new IllegalArgumentException("Not a valid destination " + destination);
+ iae.addSuppressed(e);
+ throw iae;
+ }
+ }
}
--- a/test/hotspot/jtreg/gc/shenandoah/TestGCThreadGroups.java Mon Oct 07 20:15:47 2019 +0200
+++ b/test/hotspot/jtreg/gc/shenandoah/TestGCThreadGroups.java Tue Oct 08 11:57:11 2019 +0200
@@ -32,12 +32,6 @@
* -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4
* -Dtarget=1000
* TestGCThreadGroups
- *
- * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
- * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
- * -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2
- * -Dtarget=1000
- * TestGCThreadGroups
*/
/**
@@ -71,46 +65,22 @@
* TestGCThreadGroups
*
* @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
- * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
- * -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2
- * -Dtarget=1000
- * TestGCThreadGroups
- *
- * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
* -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=static
* -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4
* -Dtarget=1000
* TestGCThreadGroups
*
* @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
- * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=static
- * -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2
- * -Dtarget=1000
- * TestGCThreadGroups
- *
- * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
* -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact
* -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4
* -Dtarget=100
* TestGCThreadGroups
*
* @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
- * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact
- * -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2
- * -Dtarget=100
- * TestGCThreadGroups
- *
- * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
* -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
* -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4
* -Dtarget=100
* TestGCThreadGroups
- *
- * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
- * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
- * -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2
- * -Dtarget=100
- * TestGCThreadGroups
*/
/**
@@ -130,18 +100,6 @@
* -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4
* -Dtarget=1000
* TestGCThreadGroups
- *
- * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
- * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
- * -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2
- * -Dtarget=1000
- * TestGCThreadGroups
- *
- * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
- * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
- * -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2
- * -Dtarget=1000
- * TestGCThreadGroups
*/
public class TestGCThreadGroups {
--- a/test/hotspot/jtreg/gc/shenandoah/options/TestThreadCounts.java Mon Oct 07 20:15:47 2019 +0200
+++ b/test/hotspot/jtreg/gc/shenandoah/options/TestThreadCounts.java Tue Oct 08 11:57:11 2019 +0200
@@ -61,7 +61,7 @@
output.shouldHaveExitValue(1);
} else if (conc > par) {
output.shouldContain("Shenandoah expects ConcGCThreads <= ParallelGCThreads");
- output.shouldHaveExitValue(0);
+ output.shouldHaveExitValue(1);
} else {
output.shouldNotContain("Shenandoah expects ConcGCThreads <= ParallelGCThreads");
output.shouldHaveExitValue(0);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/shenandoah/options/TestThreadCountsOverride.java Tue Oct 08 11:57:11 2019 +0200
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2016, 2018, Red Hat, Inc. All rights reserved.
+ *
+ * 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 TestThreadCountsOverride
+ * @summary Test that Shenandoah GC thread counts are overridable
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ * java.management
+ * @run driver TestThreadCountsOverride
+ */
+
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class TestThreadCountsOverride {
+ public static void main(String[] args) throws Exception {
+ {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+UseShenandoahGC",
+ "-XX:ParallelGCThreads=1",
+ "-XX:+PrintFlagsFinal",
+ "-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+ output.shouldMatch("ParallelGCThreads(.*)= 1 ");
+ output.shouldHaveExitValue(0);
+ }
+
+ {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+UseShenandoahGC",
+ "-XX:ConcGCThreads=1",
+ "-XX:+PrintFlagsFinal",
+ "-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+ output.shouldMatch("ConcGCThreads(.*)= 1 ");
+ output.shouldHaveExitValue(0);
+ }
+ }
+
+}
--- a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/RedefineDeleteJmethod.java Mon Oct 07 20:15:47 2019 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2019, 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 8181171
- * @summary Test deleting static method pointing to by a jmethod
- * @library /test/lib
- * @modules java.base/jdk.internal.misc
- * @modules java.compiler
- * java.instrument
- * jdk.jartool/sun.tools.jar
- * @run main RedefineClassHelper
- * @run main/native/othervm -javaagent:redefineagent.jar -XX:+AllowRedefinitionToAddDeleteMethods -Xlog:redefine+class*=trace RedefineDeleteJmethod
- */
-
-class B {
- private static int deleteMe() { System.out.println("deleteMe called"); return 5; }
- public static int callDeleteMe() { return deleteMe(); }
-}
-
-public class RedefineDeleteJmethod {
-
- public static String newB =
- "class B {" +
- "public static int callDeleteMe() { return 6; }" +
- "}";
-
- public static String newerB =
- "class B {" +
- "private static int deleteMe() { System.out.println(\"deleteMe (2) called\"); return 7; }" +
- "public static int callDeleteMe() { return deleteMe(); }" +
- "}";
-
-
- static {
- System.loadLibrary("RedefineDeleteJmethod");
- }
-
- static native int jniCallDeleteMe();
-
- static void test(int expected, boolean nsme_expected) throws Exception {
- // Call through static method
- int res = B.callDeleteMe();
- System.out.println("Result = " + res);
- if (res != expected) {
- throw new Error("returned " + res + " expected " + expected);
- }
-
- // Call through jmethodID, saved from first call.
- try {
- res = jniCallDeleteMe();
- if (nsme_expected) {
- throw new RuntimeException("Failed, NoSuchMethodError expected");
- }
- if (res != expected) {
- throw new Error("returned " + res + " expected " + expected);
- }
- } catch (NoSuchMethodError ex) {
- if (!nsme_expected) {
- throw new RuntimeException("Failed, NoSuchMethodError not expected");
- }
- System.out.println("Passed, NoSuchMethodError expected");
- }
- }
-
- public static void main(String[] args) throws Exception {
- test(5, false);
- RedefineClassHelper.redefineClass(B.class, newB);
- test(6, true);
- RedefineClassHelper.redefineClass(B.class, newerB);
- test(7, true);
- }
-}
--- a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/libRedefineDeleteJmethod.c Mon Oct 07 20:15:47 2019 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2019, 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.
- */
-
-#include <jni.h>
-
-jmethodID mid;
-jclass cls;
-static int count = 0;
-
-JNIEXPORT jint JNICALL
-Java_RedefineDeleteJmethod_jniCallDeleteMe(JNIEnv* env, jobject obj) {
-
- if (count == 0) {
- count++;
- cls = (*env)->FindClass(env, "B");
- if (NULL == cls) {
- (*env)->FatalError(env, "could not find class");
- }
-
- mid = (*env)->GetStaticMethodID(env, cls, "deleteMe", "()I");
- if (NULL == mid) {
- (*env)->FatalError(env, "could not find method");
- }
- }
-
- return (*env)->CallStaticIntMethod(env, cls, mid);
-}
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbPmap.java Mon Oct 07 20:15:47 2019 +0200
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbPmap.java Tue Oct 08 11:57:11 2019 +0200
@@ -52,9 +52,8 @@
List<String> cmds = List.of("pmap");
Map<String, List<String>> expStrMap = new HashMap<>();
- expStrMap.put("pmap", List.of(
- "jvm", "java", "net", "nio",
- "jimage", "zip", "verify"));
+ expStrMap.put("pmap",
+ List.of("jvm", "java", "net", "nio", "jimage", "zip"));
test.run(theApp.getPid(), cmds, expStrMap, null);
} catch (SkippedException se) {
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RawMonitorWait/rawmnwait005/rawmnwait005.cpp Mon Oct 07 20:15:47 2019 +0200
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RawMonitorWait/rawmnwait005/rawmnwait005.cpp Tue Oct 08 11:57:11 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -37,7 +37,7 @@
static jvmtiEnv *jvmti = NULL;
static jvmtiCapabilities caps;
static jint result = PASSED;
-static jboolean printdump = JNI_FALSE;
+static jboolean printdump = JNI_TRUE;
static jrawMonitorID monitor;
static jrawMonitorID wait_lock;
static jlong wait_time;
@@ -100,6 +100,8 @@
jvmtiError err;
const char* const thread_name = "test thread";
+ // Once we hold this monitor we know we can't get interrupted
+ // until we have called wait().
err = jvmti->RawMonitorEnter(monitor);
if (err != JVMTI_ERROR_NONE) {
printf("(RawMonitorEnter#test) unexpected error: %s (%d)\n",
@@ -110,6 +112,7 @@
printf(">>> [%s] acquired lock for 'monitor' ...\n", thread_name);
}
+ // We can't get this monitor until the main thread has called wait() on it.
err = jvmti->RawMonitorEnter(wait_lock);
if (err != JVMTI_ERROR_NONE) {
printf("(RawMonitorEnter#wait) unexpected error: %s (%d)\n",
@@ -156,6 +159,36 @@
result = STATUS_FAILED;
}
+ // We can't reacquire this monitor until the main thread is waiting for us to
+ // complete.
+ err = jvmti->RawMonitorEnter(wait_lock);
+ if (err != JVMTI_ERROR_NONE) {
+ printf("(RawMonitorEnter#wait) unexpected error: %s (%d)\n",
+ TranslateError(err), err);
+ result = STATUS_FAILED;
+ return;
+ }
+
+ if (printdump == JNI_TRUE) {
+ printf(">>> [%s] acquired lock for 'wait_lock' ...\n", thread_name);
+ printf(">>> [%s] notifying main thread we are done ...\n", thread_name);
+ }
+
+ err = jvmti->RawMonitorNotify(wait_lock);
+ if (err != JVMTI_ERROR_NONE) {
+ printf("(RawMonitorWait#wait) unexpected error: %s (%d)\n",
+ TranslateError(err), err);
+ result = STATUS_FAILED;
+ return;
+ }
+ err = jvmti->RawMonitorExit(wait_lock);
+ if (err != JVMTI_ERROR_NONE) {
+ printf("(RawMonitorExit#wait) unexpected error: %s (%d)\n",
+ TranslateError(err), err);
+ result = STATUS_FAILED;
+ return;
+ }
+
if (printdump == JNI_TRUE) {
printf(">>> [%s] all done\n", thread_name);
}
@@ -223,6 +256,11 @@
if (printdump == JNI_TRUE) {
printf(">>> [%s] starting test thread ...\n", thread_name);
}
+
+ // This starts a daemon thread, so we need to synchronize with it
+ // before we terminate - else the test will end before it checks
+ // it was interrupted!
+
err = jvmti->RunAgentThread(thr, test_thread, NULL,
JVMTI_THREAD_NORM_PRIORITY);
if (err != JVMTI_ERROR_NONE) {
@@ -244,12 +282,7 @@
printf(">>> [%s] got notification from test thread ...\n", thread_name);
}
- err = jvmti->RawMonitorExit(wait_lock);
- if (err != JVMTI_ERROR_NONE) {
- printf("(RawMonitorExit#wait) unexpected error: %s (%d)\n",
- TranslateError(err), err);
- return STATUS_FAILED;
- }
+ // Keep the wait_lock so we can wait again at the end.
err = jvmti->RawMonitorEnter(monitor);
if (err != JVMTI_ERROR_NONE) {
@@ -280,6 +313,26 @@
}
if (printdump == JNI_TRUE) {
+ printf(">>> [%s] waiting for test thread to complete its wait and notify us ...\n", thread_name);
+ }
+ err = jvmti->RawMonitorWait(wait_lock, (jlong)0);
+ if (err != JVMTI_ERROR_NONE) {
+ printf("(RawMonitorWait#wait) unexpected error: %s (%d)\n",
+ TranslateError(err), err);
+ return STATUS_FAILED;
+ }
+ if (printdump == JNI_TRUE) {
+ printf(">>> [%s] got final notification from test thread ...\n", thread_name);
+ }
+
+ err = jvmti->RawMonitorExit(wait_lock);
+ if (err != JVMTI_ERROR_NONE) {
+ printf("(RawMonitorExit#wait) unexpected error: %s (%d)\n",
+ TranslateError(err), err);
+ return STATUS_FAILED;
+ }
+
+ if (printdump == JNI_TRUE) {
printf(">>> [%s] all done\n", thread_name);
}
--- a/test/jdk/jdk/jfr/jmx/TestRecordingOptions.java Mon Oct 07 20:15:47 2019 +0200
+++ b/test/jdk/jdk/jfr/jmx/TestRecordingOptions.java Tue Oct 08 11:57:11 2019 +0200
@@ -25,6 +25,7 @@
package jdk.jfr.jmx;
+import java.io.File;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
@@ -49,7 +50,7 @@
options.put("dumpOnExit", "false");
options.put("disk", "false");
options.put("duration", "1 h"); // don't want recording to stop
-
+ options.put("destination", "." + File.separator + "dump.jfr");
FlightRecorderMXBean bean = JmxHelper.getFlighteRecorderMXBean();
long recId = bean.newRecording();
Map<String, String> defaults = bean.getRecordingOptions(recId);
@@ -72,6 +73,7 @@
Asserts.assertEquals(outOptions.get("dumpOnExit"), "false", "Wrong dumpOnExit");
Asserts.assertEquals(outOptions.get("disk"), "false", "Wrong disk");
Asserts.assertEquals(outOptions.get("duration"), "1 h", "Wrong duration");
+ Asserts.assertEquals(outOptions.get("destination"), "." + File.separator + "dump.jfr", "Wrong destination");
// try empty map
bean.setRecordingOptions(recId, new HashMap<>());
@@ -116,6 +118,7 @@
nullMap.put("dumpOnExit", null);
nullMap.put("disk", null);
nullMap.put("duration", null);
+ nullMap.put("destination", null);
bean.setRecordingOptions(recId, nullMap);
Asserts.assertEquals(bean.getRecordingOptions(recId), defaults);
--- a/test/jdk/sun/security/pkcs11/Cipher/TestGCMKeyAndIvCheck.java Mon Oct 07 20:15:47 2019 +0200
+++ b/test/jdk/sun/security/pkcs11/Cipher/TestGCMKeyAndIvCheck.java Tue Oct 08 11:57:11 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, 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
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8080462
+ * @bug 8080462 8229243
* @library /test/lib ..
* @modules jdk.crypto.cryptoki
* @run main TestGCMKeyAndIvCheck
@@ -81,6 +81,7 @@
", no support for " + mode);
return;
}
+ System.out.println("Testing against " + p.getName());
SecretKey key = new SecretKeySpec(new byte[16], "AES");
// First try parameter-less init.
c.init(Cipher.ENCRYPT_MODE, key);
@@ -111,12 +112,11 @@
throw new Exception("Parameters contains incorrect IV value");
}
- // Should be ok to use the same key+iv for decryption
c.init(Cipher.DECRYPT_MODE, key, params);
c.updateAAD(AAD);
byte[] recovered = c.doFinal(ctPlusTag);
if (!Arrays.equals(recovered, PT)) {
- throw new Exception("decryption result mismatch");
+ throw new Exception("Decryption result mismatch");
}
// Now try to encrypt again using the same key+iv; should fail also
@@ -125,6 +125,7 @@
throw new Exception("Should throw exception when same key+iv is used");
} catch (InvalidAlgorithmParameterException iape) {
// expected
+ System.out.println("Expected IAPE thrown");
}
// Now try to encrypt again using parameter-less init; should work
@@ -138,7 +139,8 @@
}
// Now try to encrypt again using a different parameter; should work
- AlgorithmParameterSpec spec2 = new GCMParameterSpec(128, new byte[30]);
+ AlgorithmParameterSpec spec2 = new GCMParameterSpec(128,
+ "Solaris PKCS11 lib does not allow all-zero IV".getBytes());
c.init(Cipher.ENCRYPT_MODE, key, spec2);
c.updateAAD(AAD);
c.doFinal(PT);
@@ -154,7 +156,7 @@
c.updateAAD(AAD);
recovered = c.doFinal(ctPlusTag);
if (!Arrays.equals(recovered, PT)) {
- throw new Exception("decryption result mismatch");
+ throw new Exception("Decryption result mismatch");
}
// Now try decryption again and re-init using the same parameters