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:
Keith McGuigan 2008-07-28 14:07:44 -04:00
parent 20dba03e99
commit 74faacc945
18 changed files with 432 additions and 158 deletions

View File

@ -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

View File

@ -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) {

View File

@ -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) {

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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(),

View File

@ -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;

View File

@ -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)

View File

@ -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);
}
}
}

View File

@ -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;
}
};

View File

@ -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");
}
}
}
}

View File

@ -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);

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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) \
\
\
\

View File

@ -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)) {