8230043: Lazily load libverify

8230140: Remove unused mutex and monitor declarations

Reviewed-by: hseigel, erikj, alanb, dholmes
This commit is contained in:
Claes Redestad 2019-10-07 16:55:24 +02:00
parent 204ed44122
commit fba19ffbb2
12 changed files with 74 additions and 152 deletions

View File

@ -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 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBJAVA, \
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, \
))

View File

@ -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 volatile jint _is_new_verify_byte_codes_fn = (jint) true;
static verify_byte_codes_fn_t 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;
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;
// 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 @@ Symbol* Verifier::inference_verify(
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 @@ Symbol* Verifier::inference_verify(
// 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);

View File

@ -1043,19 +1043,6 @@ JVM_IsSameClassPackage(JNIEnv *env, jclass class1, jclass class2);
/* Get classfile constants */
#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.
*/
@ -1086,28 +1073,6 @@ typedef struct {
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 | \

View File

@ -66,7 +66,6 @@ Mutex* TouchedMethodLog_lock = NULL;
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 @@ Mutex* Management_lock = NULL;
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 @@ void mutex_init() {
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);

View File

@ -103,7 +103,6 @@ extern Mutex* Debug3_lock;
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 Mutex* Management_lock; // a lock used to serialize JVM
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

View File

@ -536,14 +536,6 @@ void* os::native_java_library() {
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")) {

View File

@ -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 @@ Java_java_lang_Class_forName0(JNIEnv *env, jclass this, jstring classname,
}
(*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;
}

View File

@ -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 @@ Java_java_lang_ClassLoader_defineClass1(JNIEnv *env,
if (utfName == NULL) {
goto free_body;
}
VerifyFixClassname(utfName);
fixClassname(utfName);
} else {
utfName = NULL;
}
@ -185,7 +182,7 @@ Java_java_lang_ClassLoader_defineClass2(JNIEnv *env,
JNU_ThrowOutOfMemoryError(env, NULL);
return result;
}
VerifyFixClassname(utfName);
fixClassname(utfName);
} else {
utfName = NULL;
}
@ -231,9 +228,9 @@ Java_java_lang_ClassLoader_findBootstrapClass(JNIEnv *env, jobject loader,
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;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* 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
@ -31,6 +31,7 @@
#include "jni.h"
#include "jvm.h"
#include "check_classname.h"
typedef unsigned short unicode;
@ -223,16 +224,13 @@ skip_over_field_signature(char *name, jboolean void_okay,
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)
jboolean verifyClassname(char *name, jboolean allowArrayClass)
{
size_t s = strlen(name);
assert(s <= UINT_MAX);
@ -254,10 +252,9 @@ VerifyClassname(char *name, jboolean allowArrayClass)
}
/*
* Translates '.' to '/'. Returns JNI_TRUE is any / were present.
* Translates '.' to '/'. Returns JNI_TRUE if any / were present.
*/
JNIEXPORT jboolean
VerifyFixClassname(char *name)
jboolean verifyFixClassname(char *name)
{
char *p = name;
jboolean slashesFound = JNI_FALSE;
@ -276,3 +273,20 @@ VerifyFixClassname(char *name)
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);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved.
* 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
@ -23,37 +23,12 @@
* 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;
/*
* Class name checking methods
*/
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);
}
jboolean verifyClassname(char *name, jboolean allowArrayClass);
jboolean verifyFixClassname(char *name);
void fixClassname(char *name);

View File

@ -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
@ -30,9 +30,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 @@ VerifyClassForMajorVersion(JNIEnv *env, jclass cb, char *buffer, jint len,
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)
{

View File

@ -52,9 +52,8 @@ public class ClhsdbPmap {
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) {