This commit is contained in:
Erik Trimble 2008-10-15 18:51:04 -07:00
commit 4b983d3b39
25 changed files with 318 additions and 70 deletions

View file

@ -1110,7 +1110,7 @@ static jstring getPlatformEncoding(JNIEnv *env) {
if (propname) {
jclass cls;
jmethodID mid;
NULL_CHECK0 (cls = (*env)->FindClass(env, "java/lang/System"));
NULL_CHECK0 (cls = FindBootStrapClass(env, "java/lang/System"));
NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
env, cls,
"getProperty",
@ -1125,7 +1125,7 @@ static jstring getPlatformEncoding(JNIEnv *env) {
static jboolean isEncodingSupported(JNIEnv *env, jstring enc) {
jclass cls;
jmethodID mid;
NULL_CHECK0 (cls = (*env)->FindClass(env, "java/nio/charset/Charset"));
NULL_CHECK0 (cls = FindBootStrapClass(env, "java/nio/charset/Charset"));
NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
env, cls,
"isSupported",
@ -1161,7 +1161,7 @@ NewPlatformString(JNIEnv *env, char *s)
#else
if (isEncodingSupported(env, enc) == JNI_TRUE) {
#endif
NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String"));
NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String"));
NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
"([BLjava/lang/String;)V"));
str = (*env)->NewObject(env, cls, mid, ary, enc);
@ -1172,7 +1172,7 @@ NewPlatformString(JNIEnv *env, char *s)
the encoding name, in which the StringCoding class will
pickup the iso-8859-1 as the fallback converter for us.
*/
NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String"));
NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String"));
NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
"([B)V"));
str = (*env)->NewObject(env, cls, mid, ary);
@ -1195,7 +1195,7 @@ NewPlatformStringArray(JNIEnv *env, char **strv, int strc)
jarray ary;
int i;
NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String"));
NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String"));
NULL_CHECK0(ary = (*env)->NewObjectArray(env, strc, cls, 0));
for (i = 0; i < strc; i++) {
jstring str = NewPlatformString(env, *strv++);
@ -1224,6 +1224,7 @@ LoadClass(JNIEnv *env, char *name)
c = *t++;
*s++ = (c == '.') ? '/' : c;
} while (c != '\0');
// use the application class loader for main-class
cls = (*env)->FindClass(env, buf);
free(buf);
@ -1250,7 +1251,7 @@ GetMainClassName(JNIEnv *env, char *jarname)
jobject jar, man, attr;
jstring str, result = 0;
NULL_CHECK0(cls = (*env)->FindClass(env, "java/util/jar/JarFile"));
NULL_CHECK0(cls = FindBootStrapClass(env, "java/util/jar/JarFile"));
NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
"(Ljava/lang/String;)V"));
NULL_CHECK0(str = NewPlatformString(env, jarname));
@ -1471,7 +1472,7 @@ PrintJavaVersion(JNIEnv *env)
jclass ver;
jmethodID print;
NULL_CHECK(ver = (*env)->FindClass(env, "sun/misc/Version"));
NULL_CHECK(ver = FindBootStrapClass(env, "sun/misc/Version"));
NULL_CHECK(print = (*env)->GetStaticMethodID(env, ver, "print", "()V"));
(*env)->CallStaticVoidMethod(env, ver, print);

View file

@ -100,5 +100,15 @@ void* MemAlloc(size_t size);
* Make launcher spit debug output.
*/
extern jboolean _launcher_debug;
/*
* This allows for finding classes from the VM's bootstrap class loader
* directly, FindClass uses the application class loader internally, this will
* cause unnecessary searching of the classpath for the required classes.
*/
typedef jclass (JNICALL FindClassFromBootLoader_t(JNIEnv *env,
const char *name,
jboolean throwError));
jclass FindBootStrapClass(JNIEnv *env, const char *classname);
#endif /* _JAVA_H_ */

View file

@ -1826,3 +1826,23 @@ UnsetEnv(char *name)
{
return(borrowed_unsetenv(name));
}
/*
* The implementation for finding classes from the bootstrap
* class loader, refer to java.h
*/
static FindClassFromBootLoader_t *findBootClass = NULL;
jclass
FindBootStrapClass(JNIEnv *env, const char* classname)
{
if (findBootClass == NULL) {
findBootClass = (FindClassFromBootLoader_t *)dlsym(RTLD_DEFAULT,
"JVM_FindClassFromBootLoader");
if (findBootClass == NULL) {
fprintf(stderr, "Error: could load method JVM_FindClassFromBootLoader");
return NULL;
}
}
return findBootClass(env, classname, JNI_FALSE);
}

View file

@ -38,5 +38,6 @@
// platforms, but they may have different default values on other platforms.
//
define_pd_global(bool, UseLargePages, false);
define_pd_global(bool, UseLargePagesIndividualAllocation, false);
define_pd_global(bool, UseOSErrorReporting, false);
define_pd_global(bool, UseThreadPriorities, true) ;

View file

@ -1110,7 +1110,7 @@ static jstring getPlatformEncoding(JNIEnv *env) {
if (propname) {
jclass cls;
jmethodID mid;
NULL_CHECK0 (cls = (*env)->FindClass(env, "java/lang/System"));
NULL_CHECK0 (cls = FindBootStrapClass(env, "java/lang/System"));
NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
env, cls,
"getProperty",
@ -1125,7 +1125,7 @@ static jstring getPlatformEncoding(JNIEnv *env) {
static jboolean isEncodingSupported(JNIEnv *env, jstring enc) {
jclass cls;
jmethodID mid;
NULL_CHECK0 (cls = (*env)->FindClass(env, "java/nio/charset/Charset"));
NULL_CHECK0 (cls = FindBootStrapClass(env, "java/nio/charset/Charset"));
NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
env, cls,
"isSupported",
@ -1161,7 +1161,7 @@ NewPlatformString(JNIEnv *env, char *s)
#else
if (isEncodingSupported(env, enc) == JNI_TRUE) {
#endif
NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String"));
NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String"));
NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
"([BLjava/lang/String;)V"));
str = (*env)->NewObject(env, cls, mid, ary, enc);
@ -1172,7 +1172,7 @@ NewPlatformString(JNIEnv *env, char *s)
the encoding name, in which the StringCoding class will
pickup the iso-8859-1 as the fallback converter for us.
*/
NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String"));
NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String"));
NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
"([B)V"));
str = (*env)->NewObject(env, cls, mid, ary);
@ -1195,7 +1195,7 @@ NewPlatformStringArray(JNIEnv *env, char **strv, int strc)
jarray ary;
int i;
NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String"));
NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String"));
NULL_CHECK0(ary = (*env)->NewObjectArray(env, strc, cls, 0));
for (i = 0; i < strc; i++) {
jstring str = NewPlatformString(env, *strv++);
@ -1224,6 +1224,7 @@ LoadClass(JNIEnv *env, char *name)
c = *t++;
*s++ = (c == '.') ? '/' : c;
} while (c != '\0');
// use the application class loader for the main-class
cls = (*env)->FindClass(env, buf);
free(buf);
@ -1250,7 +1251,7 @@ GetMainClassName(JNIEnv *env, char *jarname)
jobject jar, man, attr;
jstring str, result = 0;
NULL_CHECK0(cls = (*env)->FindClass(env, "java/util/jar/JarFile"));
NULL_CHECK0(cls = FindBootStrapClass(env, "java/util/jar/JarFile"));
NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
"(Ljava/lang/String;)V"));
NULL_CHECK0(str = NewPlatformString(env, jarname));
@ -1471,7 +1472,7 @@ PrintJavaVersion(JNIEnv *env)
jclass ver;
jmethodID print;
NULL_CHECK(ver = (*env)->FindClass(env, "sun/misc/Version"));
NULL_CHECK(ver = FindBootStrapClass(env, "sun/misc/Version"));
NULL_CHECK(print = (*env)->GetStaticMethodID(env, ver, "print", "()V"));
(*env)->CallStaticVoidMethod(env, ver, print);

View file

@ -101,4 +101,15 @@ void* MemAlloc(size_t size);
*/
extern jboolean _launcher_debug;
/*
* This allows for finding classes from the VM's bootstrap class loader
* directly, FindClass uses the application class loader internally, this will
* cause unnecessary searching of the classpath for the required classes.
*/
typedef jclass (JNICALL FindClassFromBootLoader_t(JNIEnv *env,
const char *name,
jboolean throwError));
jclass FindBootStrapClass(JNIEnv *env, const char *classname);
#endif /* _JAVA_H_ */

View file

@ -1826,3 +1826,24 @@ UnsetEnv(char *name)
{
return(borrowed_unsetenv(name));
}
/*
* The implementation for finding classes from the bootstrap
* class loader, refer to java.h
*/
static FindClassFromBootLoader_t *findBootClass = NULL;
jclass
FindBootStrapClass(JNIEnv *env, const char* classname)
{
if (findBootClass == NULL) {
findBootClass = (FindClassFromBootLoader_t *)dlsym(RTLD_DEFAULT,
"JVM_FindClassFromBootLoader");
if (findBootClass == NULL) {
fprintf(stderr, "Error: could not load method JVM_FindClassFromBootLoader");
return NULL;
}
}
return findBootClass(env, classname, JNI_FALSE);
}

View file

@ -44,5 +44,6 @@
// platforms, but they may have different default values on other platforms.
//
define_pd_global(bool, UseLargePages, true);
define_pd_global(bool, UseLargePagesIndividualAllocation, false);
define_pd_global(bool, UseOSErrorReporting, false);
define_pd_global(bool, UseThreadPriorities, false);

View file

@ -462,16 +462,14 @@ int os::active_processor_count() {
int online_cpus = sysconf(_SC_NPROCESSORS_ONLN);
pid_t pid = getpid();
psetid_t pset = PS_NONE;
// Are we running in a processor set?
// Are we running in a processor set or is there any processor set around?
if (pset_bind(PS_QUERY, P_PID, pid, &pset) == 0) {
if (pset != PS_NONE) {
uint_t pset_cpus;
// Query number of cpus in processor set
if (pset_info(pset, NULL, &pset_cpus, NULL) == 0) {
assert(pset_cpus > 0 && pset_cpus <= online_cpus, "sanity check");
_processors_online = pset_cpus;
return pset_cpus;
}
uint_t pset_cpus;
// Query the number of cpus available to us.
if (pset_info(pset, NULL, &pset_cpus, NULL) == 0) {
assert(pset_cpus > 0 && pset_cpus <= online_cpus, "sanity check");
_processors_online = pset_cpus;
return pset_cpus;
}
}
// Otherwise return number of online cpus

View file

@ -37,5 +37,6 @@
// platforms, but they may have different default values on other platforms.
//
define_pd_global(bool, UseLargePages, false);
define_pd_global(bool, UseLargePagesIndividualAllocation, true);
define_pd_global(bool, UseOSErrorReporting, false); // for now.
define_pd_global(bool, UseThreadPriorities, true) ;

View file

@ -2593,9 +2593,104 @@ bool os::can_execute_large_page_memory() {
}
char* os::reserve_memory_special(size_t bytes) {
DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES;
char * res = (char *)VirtualAlloc(NULL, bytes, flag, PAGE_EXECUTE_READWRITE);
return res;
if (UseLargePagesIndividualAllocation) {
if (TracePageSizes && Verbose) {
tty->print_cr("Reserving large pages individually.");
}
char * p_buf;
// first reserve enough address space in advance since we want to be
// able to break a single contiguous virtual address range into multiple
// large page commits but WS2003 does not allow reserving large page space
// so we just use 4K pages for reserve, this gives us a legal contiguous
// address space. then we will deallocate that reservation, and re alloc
// using large pages
const size_t size_of_reserve = bytes + _large_page_size;
if (bytes > size_of_reserve) {
// Overflowed.
warning("Individually allocated large pages failed, "
"use -XX:-UseLargePagesIndividualAllocation to turn off");
return NULL;
}
p_buf = (char *) VirtualAlloc(NULL,
size_of_reserve, // size of Reserve
MEM_RESERVE,
PAGE_EXECUTE_READWRITE);
// If reservation failed, return NULL
if (p_buf == NULL) return NULL;
release_memory(p_buf, bytes + _large_page_size);
// round up to page boundary. If the size_of_reserve did not
// overflow and the reservation did not fail, this align up
// should not overflow.
p_buf = (char *) align_size_up((size_t)p_buf, _large_page_size);
// now go through and allocate one page at a time until all bytes are
// allocated
size_t bytes_remaining = align_size_up(bytes, _large_page_size);
// An overflow of align_size_up() would have been caught above
// in the calculation of size_of_reserve.
char * next_alloc_addr = p_buf;
#ifdef ASSERT
// Variable for the failure injection
long ran_num = os::random();
size_t fail_after = ran_num % bytes;
#endif
while (bytes_remaining) {
size_t bytes_to_rq = MIN2(bytes_remaining, _large_page_size);
// Note allocate and commit
char * p_new;
#ifdef ASSERT
bool inject_error = LargePagesIndividualAllocationInjectError &&
(bytes_remaining <= fail_after);
#else
const bool inject_error = false;
#endif
if (inject_error) {
p_new = NULL;
} else {
p_new = (char *) VirtualAlloc(next_alloc_addr,
bytes_to_rq,
MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES,
PAGE_EXECUTE_READWRITE);
}
if (p_new == NULL) {
// Free any allocated pages
if (next_alloc_addr > p_buf) {
// Some memory was committed so release it.
size_t bytes_to_release = bytes - bytes_remaining;
release_memory(p_buf, bytes_to_release);
}
#ifdef ASSERT
if (UseLargePagesIndividualAllocation &&
LargePagesIndividualAllocationInjectError) {
if (TracePageSizes && Verbose) {
tty->print_cr("Reserving large pages individually failed.");
}
}
#endif
return NULL;
}
bytes_remaining -= bytes_to_rq;
next_alloc_addr += bytes_to_rq;
}
return p_buf;
} else {
// normal policy just allocate it all at once
DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES;
char * res = (char *)VirtualAlloc(NULL,
bytes,
flag,
PAGE_EXECUTE_READWRITE);
return res;
}
}
bool os::release_memory_special(char* base, size_t bytes) {
@ -2983,6 +3078,7 @@ size_t os::win32::_default_stack_size = 0;
volatile intx os::win32::_os_thread_count = 0;
bool os::win32::_is_nt = false;
bool os::win32::_is_windows_2003 = false;
void os::win32::initialize_system_info() {
@ -3005,7 +3101,15 @@ void os::win32::initialize_system_info() {
GetVersionEx(&oi);
switch(oi.dwPlatformId) {
case VER_PLATFORM_WIN32_WINDOWS: _is_nt = false; break;
case VER_PLATFORM_WIN32_NT: _is_nt = true; break;
case VER_PLATFORM_WIN32_NT:
_is_nt = true;
{
int os_vers = oi.dwMajorVersion * 1000 + oi.dwMinorVersion;
if (os_vers == 5002) {
_is_windows_2003 = true;
}
}
break;
default: fatal("Unknown platform");
}
@ -3103,9 +3207,13 @@ void os::init(void) {
NoYieldsInMicrolock = true;
}
#endif
// This may be overridden later when argument processing is done.
FLAG_SET_ERGO(bool, UseLargePagesIndividualAllocation,
os::win32::is_windows_2003());
// Initialize main_process and main_thread
main_process = GetCurrentProcess(); // Remember main_process is a pseudo handle
if (!DuplicateHandle(main_process, GetCurrentThread(), main_process,
if (!DuplicateHandle(main_process, GetCurrentThread(), main_process,
&main_thread, THREAD_ALL_ACCESS, false, 0)) {
fatal("DuplicateHandle failed\n");
}

View file

@ -34,6 +34,7 @@ class win32 {
static julong _physical_memory;
static size_t _default_stack_size;
static bool _is_nt;
static bool _is_windows_2003;
public:
// Windows-specific interface:
@ -60,6 +61,9 @@ class win32 {
// Tells whether the platform is NT or Windown95
static bool is_nt() { return _is_nt; }
// Tells whether the platform is Windows 2003
static bool is_windows_2003() { return _is_windows_2003; }
// Returns the byte size of a virtual memory page
static int vm_page_size() { return _vm_page_size; }