--- a/src/hotspot/share/classfile/verifier.cpp Thu Oct 17 20:27:44 2019 +0100
+++ b/src/hotspot/share/classfile/verifier.cpp Thu Oct 17 20:53:35 2019 +0100
@@ -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);
}
@@ -165,22 +175,28 @@
PerfClassTraceTime::CLASS_VERIFY);
// If the class should be verified, first see if we can use the split
- // verifier. If not, or if verification fails and FailOverToOldVerifier
- // is set, then call the inference verifier.
+ // verifier. If not, or if verification fails and can failover, then
+ // call the inference verifier.
Symbol* exception_name = NULL;
const size_t message_buffer_len = klass->name()->utf8_length() + 1024;
char* message_buffer = NULL;
char* exception_message = NULL;
- bool can_failover = FailOverToOldVerifier &&
- klass->major_version() < NOFAILOVER_MAJOR_VERSION;
-
log_info(class, init)("Start class verification for: %s", klass->external_name());
if (klass->major_version() >= STACKMAP_ATTRIBUTE_MAJOR_VERSION) {
ClassVerifier split_verifier(klass, THREAD);
split_verifier.verify_class(THREAD);
exception_name = split_verifier.result();
- if (can_failover && !HAS_PENDING_EXCEPTION &&
+
+ // If DumpSharedSpaces is set then don't fall back to the old verifier on
+ // verification failure. If a class fails verification with the split verifier,
+ // it might fail the CDS runtime verifier constraint check. In that case, we
+ // don't want to share the class. We only archive classes that pass the split
+ // verifier.
+ bool can_failover = !DumpSharedSpaces &&
+ klass->major_version() < NOFAILOVER_MAJOR_VERSION;
+
+ if (can_failover && !HAS_PENDING_EXCEPTION && // Split verifier doesn't set PENDING_EXCEPTION for failure
(exception_name == vmSymbols::java_lang_VerifyError() ||
exception_name == vmSymbols::java_lang_ClassFormatError())) {
log_info(verification)("Fail over class verification to old verifier for: %s", klass->external_name());
@@ -276,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");
@@ -295,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);