6721093: -XX:AppendRatio=N not supported
Add mechanism to ignore unsupported flags for a set period of time Reviewed-by: acorn, never, coleenp
This commit is contained in:
parent
20dba03e99
commit
74faacc945
@ -94,6 +94,9 @@ static pid_t _initial_pid = 0;
|
||||
static int SR_signum = SIGUSR2;
|
||||
sigset_t SR_sigset;
|
||||
|
||||
/* Used to protect dlsym() calls */
|
||||
static pthread_mutex_t dl_mutex;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// utility functions
|
||||
|
||||
@ -1493,6 +1496,24 @@ const char* os::dll_file_extension() { return ".so"; }
|
||||
|
||||
const char* os::get_temp_directory() { return "/tmp/"; }
|
||||
|
||||
void os::dll_build_name(
|
||||
char* buffer, size_t buflen, const char* pname, const char* fname) {
|
||||
// copied from libhpi
|
||||
const size_t pnamelen = pname ? strlen(pname) : 0;
|
||||
|
||||
/* Quietly truncate on buffer overflow. Should be an error. */
|
||||
if (pnamelen + strlen(fname) + 10 > (size_t) buflen) {
|
||||
*buffer = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
if (pnamelen == 0) {
|
||||
sprintf(buffer, "lib%s.so", fname);
|
||||
} else {
|
||||
sprintf(buffer, "%s/lib%s.so", pname, fname);
|
||||
}
|
||||
}
|
||||
|
||||
const char* os::get_current_directory(char *buf, int buflen) {
|
||||
return getcwd(buf, buflen);
|
||||
}
|
||||
@ -1742,7 +1763,17 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* glibc-2.0 libdl is not MT safe. If you are building with any glibc,
|
||||
* chances are you might want to run the generated bits against glibc-2.0
|
||||
* libdl.so, so always use locking for any version of glibc.
|
||||
*/
|
||||
void* os::dll_lookup(void* handle, const char* name) {
|
||||
pthread_mutex_lock(&dl_mutex);
|
||||
void* res = dlsym(handle, name);
|
||||
pthread_mutex_unlock(&dl_mutex);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
bool _print_ascii_file(const char* filename, outputStream* st) {
|
||||
@ -3581,6 +3612,7 @@ void os::init(void) {
|
||||
|
||||
Linux::clock_init();
|
||||
initial_time_count = os::elapsed_counter();
|
||||
pthread_mutex_init(&dl_mutex, NULL);
|
||||
}
|
||||
|
||||
// To install functions for atexit system call
|
||||
|
@ -1783,6 +1783,24 @@ const char* os::dll_file_extension() { return ".so"; }
|
||||
|
||||
const char* os::get_temp_directory() { return "/tmp/"; }
|
||||
|
||||
void os::dll_build_name(
|
||||
char* buffer, size_t buflen, const char* pname, const char* fname) {
|
||||
// copied from libhpi
|
||||
const size_t pnamelen = pname ? strlen(pname) : 0;
|
||||
|
||||
/* Quietly truncate on buffer overflow. Should be an error. */
|
||||
if (pnamelen + strlen(fname) + 10 > (size_t) buflen) {
|
||||
*buffer = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
if (pnamelen == 0) {
|
||||
sprintf(buffer, "lib%s.so", fname);
|
||||
} else {
|
||||
sprintf(buffer, "%s/lib%s.so", pname, fname);
|
||||
}
|
||||
}
|
||||
|
||||
const char* os::get_current_directory(char *buf, int buflen) {
|
||||
return getcwd(buf, buflen);
|
||||
}
|
||||
@ -2034,6 +2052,9 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* os::dll_lookup(void* handle, const char* name) {
|
||||
return dlsym(handle, name);
|
||||
}
|
||||
|
||||
|
||||
bool _print_ascii_file(const char* filename, outputStream* st) {
|
||||
|
@ -985,6 +985,28 @@ const char * os::get_temp_directory()
|
||||
}
|
||||
}
|
||||
|
||||
void os::dll_build_name(char *holder, size_t holderlen,
|
||||
const char* pname, const char* fname)
|
||||
{
|
||||
// copied from libhpi
|
||||
const size_t pnamelen = pname ? strlen(pname) : 0;
|
||||
const char c = (pnamelen > 0) ? pname[pnamelen-1] : 0;
|
||||
|
||||
/* Quietly truncates on buffer overflow. Should be an error. */
|
||||
if (pnamelen + strlen(fname) + 10 > holderlen) {
|
||||
*holder = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
if (pnamelen == 0) {
|
||||
sprintf(holder, "%s.dll", fname);
|
||||
} else if (c == ':' || c == '\\') {
|
||||
sprintf(holder, "%s%s.dll", pname, fname);
|
||||
} else {
|
||||
sprintf(holder, "%s\\%s.dll", pname, fname);
|
||||
}
|
||||
}
|
||||
|
||||
// Needs to be in os specific directory because windows requires another
|
||||
// header file <direct.h>
|
||||
const char* os::get_current_directory(char *buf, int buflen) {
|
||||
@ -1248,6 +1270,10 @@ bool os::dll_address_to_function_name(address addr, char *buf,
|
||||
return false;
|
||||
}
|
||||
|
||||
void* os::dll_lookup(void* handle, const char* name) {
|
||||
return GetProcAddress((HMODULE)handle, name);
|
||||
}
|
||||
|
||||
// save the start and end address of jvm.dll into param[0] and param[1]
|
||||
static int _locate_jvm_dll(int pid, char* mod_fname, address base_addr,
|
||||
unsigned size, void * param) {
|
||||
|
@ -649,8 +649,8 @@ jlong java_lang_Thread::thread_id(oop java_thread) {
|
||||
}
|
||||
|
||||
oop java_lang_Thread::park_blocker(oop java_thread) {
|
||||
assert(JDK_Version::supports_thread_park_blocker() && _park_blocker_offset != 0,
|
||||
"Must support parkBlocker field");
|
||||
assert(JDK_Version::current().supports_thread_park_blocker() &&
|
||||
_park_blocker_offset != 0, "Must support parkBlocker field");
|
||||
|
||||
if (_park_blocker_offset > 0) {
|
||||
return java_thread->obj_field(_park_blocker_offset);
|
||||
|
@ -178,6 +178,7 @@ arguments.cpp os_<os_family>.inline.hpp
|
||||
arguments.cpp universe.inline.hpp
|
||||
arguments.cpp vm_version_<arch_model>.hpp
|
||||
|
||||
arguments.hpp java.hpp
|
||||
arguments.hpp perfData.hpp
|
||||
arguments.hpp top.hpp
|
||||
|
||||
|
@ -367,26 +367,31 @@ void Universe::genesis(TRAPS) {
|
||||
// Only 1.3 or later has the java.lang.Shutdown class.
|
||||
// Only 1.4 or later has the java.lang.CharSequence interface.
|
||||
// Only 1.5 or later has the java.lang.management.MemoryUsage class.
|
||||
if (JDK_Version::is_pre_jdk16_version()) {
|
||||
klassOop k = SystemDictionary::resolve_or_null(vmSymbolHandles::java_lang_management_MemoryUsage(), THREAD);
|
||||
if (JDK_Version::is_partially_initialized()) {
|
||||
uint8_t jdk_version;
|
||||
klassOop k = SystemDictionary::resolve_or_null(
|
||||
vmSymbolHandles::java_lang_management_MemoryUsage(), THREAD);
|
||||
CLEAR_PENDING_EXCEPTION; // ignore exceptions
|
||||
if (k == NULL) {
|
||||
k = SystemDictionary::resolve_or_null(vmSymbolHandles::java_lang_CharSequence(), THREAD);
|
||||
k = SystemDictionary::resolve_or_null(
|
||||
vmSymbolHandles::java_lang_CharSequence(), THREAD);
|
||||
CLEAR_PENDING_EXCEPTION; // ignore exceptions
|
||||
if (k == NULL) {
|
||||
k = SystemDictionary::resolve_or_null(vmSymbolHandles::java_lang_Shutdown(), THREAD);
|
||||
k = SystemDictionary::resolve_or_null(
|
||||
vmSymbolHandles::java_lang_Shutdown(), THREAD);
|
||||
CLEAR_PENDING_EXCEPTION; // ignore exceptions
|
||||
if (k == NULL) {
|
||||
JDK_Version::set_jdk12x_version();
|
||||
jdk_version = 2;
|
||||
} else {
|
||||
JDK_Version::set_jdk13x_version();
|
||||
jdk_version = 3;
|
||||
}
|
||||
} else {
|
||||
JDK_Version::set_jdk14x_version();
|
||||
jdk_version = 4;
|
||||
}
|
||||
} else {
|
||||
JDK_Version::set_jdk15x_version();
|
||||
jdk_version = 5;
|
||||
}
|
||||
JDK_Version::fully_initialize(jdk_version);
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
|
@ -153,37 +153,56 @@ void Arguments::init_system_properties() {
|
||||
os::init_system_properties_values();
|
||||
}
|
||||
|
||||
// String containing commands that will be ignored and cause a
|
||||
// warning to be issued. These commands should be accepted
|
||||
// for 1.6 but not 1.7. The string should be cleared at the
|
||||
// beginning of 1.7.
|
||||
static const char* obsolete_jvm_flags_1_5_0[] = {
|
||||
"UseTrainGC",
|
||||
"UseSpecialLargeObjectHandling",
|
||||
"UseOversizedCarHandling",
|
||||
"TraceCarAllocation",
|
||||
"PrintTrainGCProcessingStats",
|
||||
"LogOfCarSpaceSize",
|
||||
"OversizedCarThreshold",
|
||||
"MinTickInterval",
|
||||
"DefaultTickInterval",
|
||||
"MaxTickInterval",
|
||||
"DelayTickAdjustment",
|
||||
"ProcessingToTenuringRatio",
|
||||
"MinTrainLength",
|
||||
0};
|
||||
/**
|
||||
* Provide a slightly more user-friendly way of eliminating -XX flags.
|
||||
* When a flag is eliminated, it can be added to this list in order to
|
||||
* continue accepting this flag on the command-line, while issuing a warning
|
||||
* and ignoring the value. Once the JDK version reaches the 'accept_until'
|
||||
* limit, we flatly refuse to admit the existence of the flag. This allows
|
||||
* a flag to die correctly over JDK releases using HSX.
|
||||
*/
|
||||
typedef struct {
|
||||
const char* name;
|
||||
JDK_Version obsoleted_in; // when the flag went away
|
||||
JDK_Version accept_until; // which version to start denying the existence
|
||||
} ObsoleteFlag;
|
||||
|
||||
bool Arguments::made_obsolete_in_1_5_0(const char *s) {
|
||||
static ObsoleteFlag obsolete_jvm_flags[] = {
|
||||
{ "UseTrainGC", JDK_Version::jdk(5), JDK_Version::jdk(7) },
|
||||
{ "UseSpecialLargeObjectHandling", JDK_Version::jdk(5), JDK_Version::jdk(7) },
|
||||
{ "UseOversizedCarHandling", JDK_Version::jdk(5), JDK_Version::jdk(7) },
|
||||
{ "TraceCarAllocation", JDK_Version::jdk(5), JDK_Version::jdk(7) },
|
||||
{ "PrintTrainGCProcessingStats", JDK_Version::jdk(5), JDK_Version::jdk(7) },
|
||||
{ "LogOfCarSpaceSize", JDK_Version::jdk(5), JDK_Version::jdk(7) },
|
||||
{ "OversizedCarThreshold", JDK_Version::jdk(5), JDK_Version::jdk(7) },
|
||||
{ "MinTickInterval", JDK_Version::jdk(5), JDK_Version::jdk(7) },
|
||||
{ "DefaultTickInterval", JDK_Version::jdk(5), JDK_Version::jdk(7) },
|
||||
{ "MaxTickInterval", JDK_Version::jdk(5), JDK_Version::jdk(7) },
|
||||
{ "DelayTickAdjustment", JDK_Version::jdk(5), JDK_Version::jdk(7) },
|
||||
{ "ProcessingToTenuringRatio", JDK_Version::jdk(5), JDK_Version::jdk(7) },
|
||||
{ "MinTrainLength", JDK_Version::jdk(5), JDK_Version::jdk(7) },
|
||||
{ "AppendRatio", JDK_Version::jdk_update(6,10), JDK_Version::jdk(7) },
|
||||
{ NULL, JDK_Version(0), JDK_Version(0) }
|
||||
};
|
||||
|
||||
// Returns true if the flag is obsolete and fits into the range specified
|
||||
// for being ignored. In the case that the flag is ignored, the 'version'
|
||||
// value is filled in with the version number when the flag became
|
||||
// obsolete so that that value can be displayed to the user.
|
||||
bool Arguments::is_newly_obsolete(const char *s, JDK_Version* version) {
|
||||
int i = 0;
|
||||
while (obsolete_jvm_flags_1_5_0[i] != NULL) {
|
||||
assert(version != NULL, "Must provide a version buffer");
|
||||
while (obsolete_jvm_flags[i].name != NULL) {
|
||||
const ObsoleteFlag& flag_status = obsolete_jvm_flags[i];
|
||||
// <flag>=xxx form
|
||||
// [-|+]<flag> form
|
||||
if ((strncmp(obsolete_jvm_flags_1_5_0[i], s,
|
||||
strlen(obsolete_jvm_flags_1_5_0[i])) == 0) ||
|
||||
if ((strncmp(flag_status.name, s, strlen(flag_status.name)) == 0) ||
|
||||
((s[0] == '+' || s[0] == '-') &&
|
||||
(strncmp(obsolete_jvm_flags_1_5_0[i], &s[1],
|
||||
strlen(obsolete_jvm_flags_1_5_0[i])) == 0))) {
|
||||
return true;
|
||||
(strncmp(flag_status.name, &s[1], strlen(flag_status.name)) == 0))) {
|
||||
if (JDK_Version::current().compare(flag_status.accept_until) == -1) {
|
||||
*version = flag_status.obsoleted_in;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
@ -705,14 +724,20 @@ void Arguments::print_jvm_args_on(outputStream* st) {
|
||||
}
|
||||
}
|
||||
|
||||
bool Arguments::process_argument(const char* arg, jboolean ignore_unrecognized, FlagValueOrigin origin) {
|
||||
bool Arguments::process_argument(const char* arg,
|
||||
jboolean ignore_unrecognized, FlagValueOrigin origin) {
|
||||
|
||||
JDK_Version since = JDK_Version();
|
||||
|
||||
if (parse_argument(arg, origin)) {
|
||||
// do nothing
|
||||
} else if (made_obsolete_in_1_5_0(arg)) {
|
||||
} else if (is_newly_obsolete(arg, &since)) {
|
||||
enum { bufsize = 256 };
|
||||
char buffer[bufsize];
|
||||
since.to_string(buffer, bufsize);
|
||||
jio_fprintf(defaultStream::error_stream(),
|
||||
"Warning: The flag %s has been EOL'd as of 1.5.0 and will"
|
||||
" be ignored\n", arg);
|
||||
"Warning: The flag %s has been EOL'd as of %s and will"
|
||||
" be ignored\n", arg, buffer);
|
||||
} else {
|
||||
if (!ignore_unrecognized) {
|
||||
jio_fprintf(defaultStream::error_stream(),
|
||||
|
@ -357,9 +357,11 @@ class Arguments : AllStatic {
|
||||
short* methodsNum, short* methodsMax, char*** methods, bool** allClasses
|
||||
);
|
||||
|
||||
// Returns true if the string s is in the list of
|
||||
// flags made obsolete in 1.5.0.
|
||||
static bool made_obsolete_in_1_5_0(const char* s);
|
||||
// Returns true if the string s is in the list of flags that have recently
|
||||
// been made obsolete. If we detect one of these flags on the command
|
||||
// line, instead of failing we print a warning message and ignore the
|
||||
// flag. This gives the user a release or so to stop using the flag.
|
||||
static bool is_newly_obsolete(const char* s, JDK_Version* buffer);
|
||||
|
||||
static short CompileOnlyClassesNum;
|
||||
static short CompileOnlyClassesMax;
|
||||
|
@ -39,7 +39,6 @@ void bytecodes_init();
|
||||
void classLoader_init();
|
||||
void codeCache_init();
|
||||
void VM_Version_init();
|
||||
void JDK_Version_init();
|
||||
void stubRoutines_init1();
|
||||
jint universe_init(); // dependent on codeCache_init and stubRoutines_init
|
||||
void interpreter_init(); // before any methods loaded
|
||||
@ -88,7 +87,6 @@ jint init_globals() {
|
||||
classLoader_init();
|
||||
codeCache_init();
|
||||
VM_Version_init();
|
||||
JDK_Version_init();
|
||||
stubRoutines_init1();
|
||||
jint status = universe_init(); // dependent on codeCache_init and stubRoutines_init
|
||||
if (status != JNI_OK)
|
||||
|
@ -563,32 +563,104 @@ void vm_shutdown_during_initialization(const char* error, const char* message) {
|
||||
vm_shutdown();
|
||||
}
|
||||
|
||||
jdk_version_info JDK_Version::_version_info = {0};
|
||||
bool JDK_Version::_pre_jdk16_version = false;
|
||||
int JDK_Version::_jdk_version = 0;
|
||||
JDK_Version JDK_Version::_current;
|
||||
|
||||
void JDK_Version::initialize() {
|
||||
jdk_version_info info;
|
||||
assert(!_current.is_valid(), "Don't initialize twice");
|
||||
|
||||
void *lib_handle = os::native_java_library();
|
||||
jdk_version_info_fn_t func =
|
||||
CAST_TO_FN_PTR(jdk_version_info_fn_t, hpi::dll_lookup(lib_handle, "JDK_GetVersionInfo0"));
|
||||
jdk_version_info_fn_t func = CAST_TO_FN_PTR(jdk_version_info_fn_t,
|
||||
os::dll_lookup(lib_handle, "JDK_GetVersionInfo0"));
|
||||
|
||||
if (func == NULL) {
|
||||
// JDK older than 1.6
|
||||
_pre_jdk16_version = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (func != NULL) {
|
||||
(*func)(&_version_info, sizeof(_version_info));
|
||||
}
|
||||
if (jdk_major_version() == 1) {
|
||||
_jdk_version = jdk_minor_version();
|
||||
_current._partially_initialized = true;
|
||||
} else {
|
||||
// If the release version string is changed to n.x.x (e.g. 7.0.0) in a future release
|
||||
_jdk_version = jdk_major_version();
|
||||
(*func)(&info, sizeof(info));
|
||||
|
||||
int major = JDK_VERSION_MAJOR(info.jdk_version);
|
||||
int minor = JDK_VERSION_MINOR(info.jdk_version);
|
||||
int micro = JDK_VERSION_MICRO(info.jdk_version);
|
||||
int build = JDK_VERSION_BUILD(info.jdk_version);
|
||||
if (major == 1 && minor > 4) {
|
||||
// We represent "1.5.0" as "5.0", but 1.4.2 as itself.
|
||||
major = minor;
|
||||
minor = micro;
|
||||
micro = 0;
|
||||
}
|
||||
_current = JDK_Version(major, minor, micro, info.update_version,
|
||||
info.special_update_version, build,
|
||||
info.thread_park_blocker == 1);
|
||||
}
|
||||
}
|
||||
|
||||
void JDK_Version::fully_initialize(
|
||||
uint8_t major, uint8_t minor, uint8_t micro, uint8_t update) {
|
||||
// This is only called when current is less than 1.6 and we've gotten
|
||||
// far enough in the initialization to determine the exact version.
|
||||
assert(major < 6, "not needed for JDK version >= 6");
|
||||
assert(is_partially_initialized(), "must not initialize");
|
||||
if (major < 5) {
|
||||
// JDK verison sequence: 1.2.x, 1.3.x, 1.4.x, 5.0.x, 6.0.x, etc.
|
||||
micro = minor;
|
||||
minor = major;
|
||||
major = 1;
|
||||
}
|
||||
_current = JDK_Version(major, minor, micro, update);
|
||||
}
|
||||
|
||||
void JDK_Version_init() {
|
||||
JDK_Version::initialize();
|
||||
}
|
||||
|
||||
static int64_t encode_jdk_version(const JDK_Version& v) {
|
||||
return
|
||||
((int64_t)v.major_version() << (BitsPerByte * 5)) |
|
||||
((int64_t)v.minor_version() << (BitsPerByte * 4)) |
|
||||
((int64_t)v.micro_version() << (BitsPerByte * 3)) |
|
||||
((int64_t)v.update_version() << (BitsPerByte * 2)) |
|
||||
((int64_t)v.special_update_version() << (BitsPerByte * 1)) |
|
||||
((int64_t)v.build_number() << (BitsPerByte * 0));
|
||||
}
|
||||
|
||||
int JDK_Version::compare(const JDK_Version& other) const {
|
||||
assert(is_valid() && other.is_valid(), "Invalid version (uninitialized?)");
|
||||
if (!is_partially_initialized() && other.is_partially_initialized()) {
|
||||
return -(other.compare(*this)); // flip the comparators
|
||||
}
|
||||
assert(!other.is_partially_initialized(), "Not initialized yet");
|
||||
if (is_partially_initialized()) {
|
||||
assert(other.major_version() >= 6,
|
||||
"Invalid JDK version comparison during initialization");
|
||||
return -1;
|
||||
} else {
|
||||
uint64_t e = encode_jdk_version(*this);
|
||||
uint64_t o = encode_jdk_version(other);
|
||||
return (e > o) ? 1 : ((e == o) ? 0 : -1);
|
||||
}
|
||||
}
|
||||
|
||||
void JDK_Version::to_string(char* buffer, size_t buflen) const {
|
||||
size_t index = 0;
|
||||
if (!is_valid()) {
|
||||
jio_snprintf(buffer, buflen, "%s", "(uninitialized)");
|
||||
} else if (is_partially_initialized()) {
|
||||
jio_snprintf(buffer, buflen, "%s", "(uninitialized) pre-1.6.0");
|
||||
} else {
|
||||
index += jio_snprintf(
|
||||
&buffer[index], buflen - index, "%d.%d", _major, _minor);
|
||||
if (_micro > 0) {
|
||||
index += jio_snprintf(&buffer[index], buflen - index, ".%d", _micro);
|
||||
}
|
||||
if (_update > 0) {
|
||||
index += jio_snprintf(&buffer[index], buflen - index, "_%02d", _update);
|
||||
}
|
||||
if (_special > 0) {
|
||||
index += jio_snprintf(&buffer[index], buflen - index, "%c", _special);
|
||||
}
|
||||
if (_build > 0) {
|
||||
index += jio_snprintf(&buffer[index], buflen - index, "-b%02d", _build);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,100 +48,163 @@ extern void vm_exit_during_initialization(symbolHandle exception_name, const cha
|
||||
extern void vm_exit_during_initialization(const char* error, const char* message = NULL);
|
||||
extern void vm_shutdown_during_initialization(const char* error, const char* message = NULL);
|
||||
|
||||
class JDK_Version : AllStatic {
|
||||
/**
|
||||
* Discovering the JDK_Version during initialization is tricky when the
|
||||
* running JDK is less than JDK6. For JDK6 and greater, a "GetVersion"
|
||||
* function exists in libjava.so and we simply call it during the
|
||||
* 'initialize()' call to find the version. For JDKs with version < 6, no
|
||||
* such call exists and we have to probe the JDK in order to determine
|
||||
* the exact version. This probing cannot happen during late in
|
||||
* the VM initialization process so there's a period of time during
|
||||
* initialization when we don't know anything about the JDK version other than
|
||||
* that it less than version 6. This is the "partially initialized" time,
|
||||
* when we can answer only certain version queries (such as, is the JDK
|
||||
* version greater than 5? Answer: no). Once the JDK probing occurs, we
|
||||
* know the version and are considered fully initialized.
|
||||
*/
|
||||
class JDK_Version VALUE_OBJ_CLASS_SPEC {
|
||||
friend class VMStructs;
|
||||
friend class Universe;
|
||||
friend void JDK_Version_init();
|
||||
private:
|
||||
static jdk_version_info _version_info;
|
||||
static bool _pre_jdk16_version;
|
||||
static int _jdk_version; // JDK version number representing the release
|
||||
// i.e. n in 1.n.x (= jdk_minor_version())
|
||||
|
||||
static JDK_Version _current;
|
||||
|
||||
// In this class, we promote the minor version of release to be the
|
||||
// major version for releases >= 5 in anticipation of the JDK doing the
|
||||
// same thing. For example, we represent "1.5.0" as major version 5 (we
|
||||
// drop the leading 1 and use 5 as the 'major').
|
||||
|
||||
uint8_t _major;
|
||||
uint8_t _minor;
|
||||
uint8_t _micro;
|
||||
uint8_t _update;
|
||||
uint8_t _special;
|
||||
uint8_t _build;
|
||||
|
||||
// If partially initialized, the above fields are invalid and we know
|
||||
// that we're less than major version 6.
|
||||
bool _partially_initialized;
|
||||
|
||||
bool _thread_park_blocker;
|
||||
|
||||
bool is_valid() const {
|
||||
return (_major != 0 || _partially_initialized);
|
||||
}
|
||||
|
||||
// initializes or partially initializes the _current static field
|
||||
static void initialize();
|
||||
|
||||
// Completes initialization for a pre-JDK6 version.
|
||||
static void fully_initialize(uint8_t major, uint8_t minor = 0,
|
||||
uint8_t micro = 0, uint8_t update = 0);
|
||||
|
||||
public:
|
||||
static void initialize();
|
||||
static int jdk_major_version() { return JDK_VERSION_MAJOR(_version_info.jdk_version); }
|
||||
static int jdk_minor_version() { return JDK_VERSION_MINOR(_version_info.jdk_version); }
|
||||
static int jdk_micro_version() { return JDK_VERSION_MICRO(_version_info.jdk_version); }
|
||||
static int jdk_build_number() { return JDK_VERSION_BUILD(_version_info.jdk_version); }
|
||||
|
||||
static bool is_pre_jdk16_version() { return _pre_jdk16_version; }
|
||||
static bool is_jdk12x_version() { assert(is_jdk_version_initialized(), "must have been initialized"); return _jdk_version == 2; }
|
||||
static bool is_jdk13x_version() { assert(is_jdk_version_initialized(), "must have been initialized"); return _jdk_version == 3; }
|
||||
static bool is_jdk14x_version() { assert(is_jdk_version_initialized(), "must have been initialized"); return _jdk_version == 4; }
|
||||
static bool is_jdk15x_version() { assert(is_jdk_version_initialized(), "must have been initialized"); return _jdk_version == 5; }
|
||||
// Returns true if the the current version has only been partially initialized
|
||||
static bool is_partially_initialized() {
|
||||
return _current._partially_initialized;
|
||||
}
|
||||
|
||||
JDK_Version() : _major(0), _minor(0), _micro(0), _update(0),
|
||||
_special(0), _build(0), _partially_initialized(false),
|
||||
_thread_park_blocker(false) {}
|
||||
|
||||
JDK_Version(uint8_t major, uint8_t minor = 0, uint8_t micro = 0,
|
||||
uint8_t update = 0, uint8_t special = 0, uint8_t build = 0,
|
||||
bool thread_park_blocker = false) :
|
||||
_major(major), _minor(minor), _micro(micro), _update(update),
|
||||
_special(special), _build(build), _partially_initialized(false),
|
||||
_thread_park_blocker(thread_park_blocker) {}
|
||||
|
||||
// Returns the current running JDK version
|
||||
static JDK_Version current() { return _current; }
|
||||
|
||||
// Factory methods for convenience
|
||||
static JDK_Version jdk(uint8_t m) {
|
||||
return JDK_Version(m);
|
||||
}
|
||||
|
||||
static JDK_Version jdk_update(uint8_t major, uint8_t update_number) {
|
||||
return JDK_Version(major, 0, 0, update_number);
|
||||
}
|
||||
|
||||
uint8_t major_version() const { return _major; }
|
||||
uint8_t minor_version() const { return _minor; }
|
||||
uint8_t micro_version() const { return _micro; }
|
||||
uint8_t update_version() const { return _update; }
|
||||
uint8_t special_update_version() const { return _special; }
|
||||
uint8_t build_number() const { return _build; }
|
||||
|
||||
bool supports_thread_park_blocker() const {
|
||||
return _thread_park_blocker;
|
||||
}
|
||||
|
||||
// Performs a full ordering comparison using all fields (update, build, etc.)
|
||||
int compare(const JDK_Version& other) const;
|
||||
|
||||
/**
|
||||
* Performs comparison using only the major version, returning negative
|
||||
* if the major version of 'this' is less than the parameter, 0 if it is
|
||||
* equal, and a positive value if it is greater.
|
||||
*/
|
||||
int compare_major(int version) const {
|
||||
if (_partially_initialized) {
|
||||
if (version >= 6) {
|
||||
return -1;
|
||||
} else {
|
||||
assert(false, "Can't make this comparison during init time");
|
||||
return -1; // conservative
|
||||
}
|
||||
} else {
|
||||
return major_version() - version;
|
||||
}
|
||||
}
|
||||
|
||||
void to_string(char* buffer, size_t buflen) const;
|
||||
|
||||
// Convenience methods for queries on the current major/minor version
|
||||
static bool is_jdk12x_version() {
|
||||
return current().compare_major(2) == 0;
|
||||
}
|
||||
|
||||
static bool is_jdk13x_version() {
|
||||
return current().compare_major(3) == 0;
|
||||
}
|
||||
|
||||
static bool is_jdk14x_version() {
|
||||
return current().compare_major(4) == 0;
|
||||
}
|
||||
|
||||
static bool is_jdk15x_version() {
|
||||
return current().compare_major(5) == 0;
|
||||
}
|
||||
|
||||
static bool is_jdk16x_version() {
|
||||
if (is_jdk_version_initialized()) {
|
||||
return _jdk_version == 6;
|
||||
} else {
|
||||
assert(is_pre_jdk16_version(), "must have been initialized");
|
||||
return false;
|
||||
}
|
||||
return current().compare_major(6) == 0;
|
||||
}
|
||||
|
||||
static bool is_jdk17x_version() {
|
||||
if (is_jdk_version_initialized()) {
|
||||
return _jdk_version == 7;
|
||||
} else {
|
||||
assert(is_pre_jdk16_version(), "must have been initialized");
|
||||
return false;
|
||||
}
|
||||
return current().compare_major(7) == 0;
|
||||
}
|
||||
|
||||
static bool supports_thread_park_blocker() { return _version_info.thread_park_blocker; }
|
||||
static bool is_gte_jdk13x_version() {
|
||||
return current().compare_major(3) >= 0;
|
||||
}
|
||||
|
||||
static bool is_gte_jdk14x_version() {
|
||||
// Keep the semantics of this that the version number is >= 1.4
|
||||
assert(is_jdk_version_initialized(), "Not initialized");
|
||||
return _jdk_version >= 4;
|
||||
return current().compare_major(4) >= 0;
|
||||
}
|
||||
|
||||
static bool is_gte_jdk15x_version() {
|
||||
// Keep the semantics of this that the version number is >= 1.5
|
||||
assert(is_jdk_version_initialized(), "Not initialized");
|
||||
return _jdk_version >= 5;
|
||||
return current().compare_major(5) >= 0;
|
||||
}
|
||||
|
||||
static bool is_gte_jdk16x_version() {
|
||||
// Keep the semantics of this that the version number is >= 1.6
|
||||
if (is_jdk_version_initialized()) {
|
||||
return _jdk_version >= 6;
|
||||
} else {
|
||||
assert(is_pre_jdk16_version(), "Not initialized");
|
||||
return false;
|
||||
}
|
||||
return current().compare_major(6) >= 0;
|
||||
}
|
||||
|
||||
static bool is_gte_jdk17x_version() {
|
||||
// Keep the semantics of this that the version number is >= 1.7
|
||||
if (is_jdk_version_initialized()) {
|
||||
return _jdk_version >= 7;
|
||||
} else {
|
||||
assert(is_pre_jdk16_version(), "Not initialized");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool is_jdk_version_initialized() {
|
||||
return _jdk_version > 0;
|
||||
}
|
||||
|
||||
// These methods are defined to deal with pre JDK 1.6 versions
|
||||
static void set_jdk12x_version() {
|
||||
assert(_pre_jdk16_version && !is_jdk_version_initialized(), "must not initialize");
|
||||
_jdk_version = 2;
|
||||
_version_info.jdk_version = (1 << 24) | (2 << 16);
|
||||
}
|
||||
static void set_jdk13x_version() {
|
||||
assert(_pre_jdk16_version && !is_jdk_version_initialized(), "must not initialize");
|
||||
_jdk_version = 3;
|
||||
_version_info.jdk_version = (1 << 24) | (3 << 16);
|
||||
}
|
||||
static void set_jdk14x_version() {
|
||||
assert(_pre_jdk16_version && !is_jdk_version_initialized(), "must not initialize");
|
||||
_jdk_version = 4;
|
||||
_version_info.jdk_version = (1 << 24) | (4 << 16);
|
||||
}
|
||||
static void set_jdk15x_version() {
|
||||
assert(_pre_jdk16_version && !is_jdk_version_initialized(), "must not initialize");
|
||||
_jdk_version = 5;
|
||||
_version_info.jdk_version = (1 << 24) | (5 << 16);
|
||||
return current().compare_major(7) >= 0;
|
||||
}
|
||||
};
|
||||
|
@ -336,29 +336,38 @@ 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.
|
||||
// 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.
|
||||
hpi::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "verify");
|
||||
hpi::dll_load(buffer, ebuf, sizeof(ebuf));
|
||||
dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "verify");
|
||||
dll_load(buffer, ebuf, sizeof(ebuf));
|
||||
|
||||
// Load java dll
|
||||
hpi::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "java");
|
||||
_native_java_library = hpi::dll_load(buffer, ebuf, sizeof(ebuf));
|
||||
dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "java");
|
||||
_native_java_library = dll_load(buffer, ebuf, sizeof(ebuf));
|
||||
if (_native_java_library == NULL) {
|
||||
vm_exit_during_initialization("Unable to load native library", ebuf);
|
||||
}
|
||||
// The JNI_OnLoad handling is normally done by method load in java.lang.ClassLoader$NativeLibrary,
|
||||
// but the VM loads the base library explicitly so we have to check for JNI_OnLoad as well
|
||||
const char *onLoadSymbols[] = JNI_ONLOAD_SYMBOLS;
|
||||
JNI_OnLoad_t JNI_OnLoad = CAST_TO_FN_PTR(JNI_OnLoad_t, hpi::dll_lookup(_native_java_library, onLoadSymbols[0]));
|
||||
if (JNI_OnLoad != NULL) {
|
||||
JavaThread* thread = JavaThread::current();
|
||||
ThreadToNativeFromVM ttn(thread);
|
||||
HandleMark hm(thread);
|
||||
jint ver = (*JNI_OnLoad)(&main_vm, NULL);
|
||||
if (!Threads::is_supported_jni_version_including_1_1(ver)) {
|
||||
vm_exit_during_initialization("Unsupported JNI version");
|
||||
}
|
||||
static jboolean onLoaded = JNI_FALSE;
|
||||
if (onLoaded) {
|
||||
// We may have to wait to fire OnLoad until TLS is initialized.
|
||||
if (ThreadLocalStorage::is_initialized()) {
|
||||
// The JNI_OnLoad handling is normally done by method load in
|
||||
// java.lang.ClassLoader$NativeLibrary, but the VM loads the base library
|
||||
// explicitly so we have to check for JNI_OnLoad as well
|
||||
const char *onLoadSymbols[] = JNI_ONLOAD_SYMBOLS;
|
||||
JNI_OnLoad_t JNI_OnLoad = CAST_TO_FN_PTR(
|
||||
JNI_OnLoad_t, dll_lookup(_native_java_library, onLoadSymbols[0]));
|
||||
if (JNI_OnLoad != NULL) {
|
||||
JavaThread* thread = JavaThread::current();
|
||||
ThreadToNativeFromVM ttn(thread);
|
||||
HandleMark hm(thread);
|
||||
jint ver = (*JNI_OnLoad)(&main_vm, NULL);
|
||||
onLoaded = JNI_TRUE;
|
||||
if (!Threads::is_supported_jni_version_including_1_1(ver)) {
|
||||
vm_exit_during_initialization("Unsupported JNI version");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -390,6 +390,10 @@ class os: AllStatic {
|
||||
static const char* get_temp_directory();
|
||||
static const char* get_current_directory(char *buf, int buflen);
|
||||
|
||||
// Builds a platform-specific full library path given a ld path and lib name
|
||||
static void dll_build_name(char* buffer, size_t size,
|
||||
const char* pathname, const char* fname);
|
||||
|
||||
// Symbol lookup, find nearest function name; basically it implements
|
||||
// dladdr() for all platforms. Name of the nearest function is copied
|
||||
// to buf. Distance from its base address is returned as offset.
|
||||
@ -413,6 +417,9 @@ class os: AllStatic {
|
||||
// same architecture as Hotspot is running on
|
||||
static void* dll_load(const char *name, char *ebuf, int ebuflen);
|
||||
|
||||
// lookup symbol in a shared library
|
||||
static void* dll_lookup(void* handle, const char* name);
|
||||
|
||||
// Print out system information; they are called by fatal error handler.
|
||||
// Output format may be different on different platforms.
|
||||
static void print_os_info(outputStream* st);
|
||||
|
@ -2578,7 +2578,8 @@ void JavaThread::prepare(jobject jni_thread, ThreadPriority prio) {
|
||||
oop JavaThread::current_park_blocker() {
|
||||
// Support for JSR-166 locks
|
||||
oop thread_oop = threadObj();
|
||||
if (thread_oop != NULL && JDK_Version::supports_thread_park_blocker()) {
|
||||
if (thread_oop != NULL &&
|
||||
JDK_Version::current().supports_thread_park_blocker()) {
|
||||
return java_lang_Thread::park_blocker(thread_oop);
|
||||
}
|
||||
return NULL;
|
||||
@ -2761,6 +2762,8 @@ void Threads::threads_do(ThreadClosure* tc) {
|
||||
|
||||
jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
|
||||
|
||||
extern void JDK_Version_init();
|
||||
|
||||
// Check version
|
||||
if (!is_supported_jni_version(args->version)) return JNI_EVERSION;
|
||||
|
||||
@ -2776,6 +2779,9 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
|
||||
// Initialize system properties.
|
||||
Arguments::init_system_properties();
|
||||
|
||||
// So that JDK version can be used as a discrimintor when parsing arguments
|
||||
JDK_Version_init();
|
||||
|
||||
// Parse arguments
|
||||
jint parse_result = Arguments::parse(args);
|
||||
if (parse_result != JNI_OK) return parse_result;
|
||||
|
@ -42,8 +42,13 @@ void ThreadLocalStorage::set_thread(Thread* thread) {
|
||||
}
|
||||
|
||||
void ThreadLocalStorage::init() {
|
||||
assert(ThreadLocalStorage::thread_index() == -1, "More than one attempt to initialize threadLocalStorage");
|
||||
assert(!is_initialized(),
|
||||
"More than one attempt to initialize threadLocalStorage");
|
||||
pd_init();
|
||||
set_thread_index(os::allocate_thread_local_storage());
|
||||
generate_code_for_get_thread();
|
||||
}
|
||||
|
||||
bool ThreadLocalStorage::is_initialized() {
|
||||
return (thread_index() != -1);
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ class ThreadLocalStorage : AllStatic {
|
||||
// Initialization
|
||||
// Called explicitly from VMThread::activate_system instead of init_globals.
|
||||
static void init();
|
||||
static bool is_initialized();
|
||||
|
||||
private:
|
||||
static int _thread_index;
|
||||
|
@ -761,8 +761,9 @@ static inline uint64_t cast_uint64_t(size_t x)
|
||||
static_field(Abstract_VM_Version, _vm_minor_version, int) \
|
||||
static_field(Abstract_VM_Version, _vm_build_number, int) \
|
||||
\
|
||||
static_field(JDK_Version, _pre_jdk16_version, bool) \
|
||||
static_field(JDK_Version, _jdk_version, int) \
|
||||
static_field(JDK_Version, _current, JDK_Version) \
|
||||
nonstatic_field(JDK_Version, _partially_initialized, bool) \
|
||||
nonstatic_field(JDK_Version, _major, unsigned char) \
|
||||
\
|
||||
\
|
||||
\
|
||||
|
@ -744,7 +744,7 @@ ThreadSnapshot::ThreadSnapshot(JavaThread* thread) {
|
||||
}
|
||||
|
||||
// Support for JSR-166 locks
|
||||
if (JDK_Version::supports_thread_park_blocker() &&
|
||||
if (JDK_Version::current().supports_thread_park_blocker() &&
|
||||
(_thread_status == java_lang_Thread::PARKED ||
|
||||
_thread_status == java_lang_Thread::PARKED_TIMED)) {
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user