# HG changeset patch # User neliasso # Date 1353056348 -3600 # Node ID 6b6ddf8c43298860c133be0d2c9dacc1fb8344af # Parent c5d4acbb943dfc3e1af10676a18d459a66778851# Parent bb33c6fdcf0db558457321a2ccf528639a8388d4 Merge diff -r bb33c6fdcf0d -r 6b6ddf8c4329 src/os/bsd/vm/os_bsd.cpp --- a/src/os/bsd/vm/os_bsd.cpp Thu Nov 15 10:42:06 2012 -0800 +++ b/src/os/bsd/vm/os_bsd.cpp Fri Nov 16 09:59:08 2012 +0100 @@ -1198,19 +1198,20 @@ return os::stat(filename, &statbuf) == 0; } -void os::dll_build_name(char* buffer, size_t buflen, +bool os::dll_build_name(char* buffer, size_t buflen, const char* pname, const char* fname) { + bool retval = false; // Copied from libhpi const size_t pnamelen = pname ? strlen(pname) : 0; - // Quietly truncate on buffer overflow. Should be an error. + // Return error on buffer overflow. if (pnamelen + strlen(fname) + strlen(JNI_LIB_PREFIX) + strlen(JNI_LIB_SUFFIX) + 2 > buflen) { - *buffer = '\0'; - return; + return retval; } if (pnamelen == 0) { snprintf(buffer, buflen, JNI_LIB_PREFIX "%s" JNI_LIB_SUFFIX, fname); + retval = true; } else if (strchr(pname, *os::path_separator()) != NULL) { int n; char** pelements = split_path(pname, &n); @@ -1222,6 +1223,7 @@ snprintf(buffer, buflen, "%s/" JNI_LIB_PREFIX "%s" JNI_LIB_SUFFIX, pelements[i], fname); if (file_exists(buffer)) { + retval = true; break; } } @@ -1236,7 +1238,9 @@ } } else { snprintf(buffer, buflen, "%s/" JNI_LIB_PREFIX "%s" JNI_LIB_SUFFIX, pname, fname); + retval = true; } + return retval; } const char* os::get_current_directory(char *buf, int buflen) { diff -r bb33c6fdcf0d -r 6b6ddf8c4329 src/os/linux/vm/os_linux.cpp --- a/src/os/linux/vm/os_linux.cpp Thu Nov 15 10:42:06 2012 -0800 +++ b/src/os/linux/vm/os_linux.cpp Fri Nov 16 09:59:08 2012 +0100 @@ -1650,19 +1650,20 @@ return os::stat(filename, &statbuf) == 0; } -void os::dll_build_name(char* buffer, size_t buflen, +bool os::dll_build_name(char* buffer, size_t buflen, const char* pname, const char* fname) { + bool retval = false; // Copied from libhpi const size_t pnamelen = pname ? strlen(pname) : 0; - // Quietly truncate on buffer overflow. Should be an error. + // Return error on buffer overflow. if (pnamelen + strlen(fname) + 10 > (size_t) buflen) { - *buffer = '\0'; - return; + return retval; } if (pnamelen == 0) { snprintf(buffer, buflen, "lib%s.so", fname); + retval = true; } else if (strchr(pname, *os::path_separator()) != NULL) { int n; char** pelements = split_path(pname, &n); @@ -1673,6 +1674,7 @@ } snprintf(buffer, buflen, "%s/lib%s.so", pelements[i], fname); if (file_exists(buffer)) { + retval = true; break; } } @@ -1687,7 +1689,9 @@ } } else { snprintf(buffer, buflen, "%s/lib%s.so", pname, fname); - } + retval = true; + } + return retval; } const char* os::get_current_directory(char *buf, int buflen) { diff -r bb33c6fdcf0d -r 6b6ddf8c4329 src/os/solaris/vm/os_solaris.cpp --- a/src/os/solaris/vm/os_solaris.cpp Thu Nov 15 10:42:06 2012 -0800 +++ b/src/os/solaris/vm/os_solaris.cpp Fri Nov 16 09:59:08 2012 +0100 @@ -1894,18 +1894,19 @@ return os::stat(filename, &statbuf) == 0; } -void os::dll_build_name(char* buffer, size_t buflen, +bool os::dll_build_name(char* buffer, size_t buflen, const char* pname, const char* fname) { + bool retval = false; const size_t pnamelen = pname ? strlen(pname) : 0; - // Quietly truncate on buffer overflow. Should be an error. + // Return error on buffer overflow. if (pnamelen + strlen(fname) + 10 > (size_t) buflen) { - *buffer = '\0'; - return; + return retval; } if (pnamelen == 0) { snprintf(buffer, buflen, "lib%s.so", fname); + retval = true; } else if (strchr(pname, *os::path_separator()) != NULL) { int n; char** pelements = split_path(pname, &n); @@ -1916,6 +1917,7 @@ } snprintf(buffer, buflen, "%s/lib%s.so", pelements[i], fname); if (file_exists(buffer)) { + retval = true; break; } } @@ -1930,7 +1932,9 @@ } } else { snprintf(buffer, buflen, "%s/lib%s.so", pname, fname); - } + retval = true; + } + return retval; } const char* os::get_current_directory(char *buf, int buflen) { diff -r bb33c6fdcf0d -r 6b6ddf8c4329 src/os/windows/vm/os_windows.cpp --- a/src/os/windows/vm/os_windows.cpp Thu Nov 15 10:42:06 2012 -0800 +++ b/src/os/windows/vm/os_windows.cpp Fri Nov 16 09:59:08 2012 +0100 @@ -1132,21 +1132,23 @@ return GetFileAttributes(filename) != INVALID_FILE_ATTRIBUTES; } -void os::dll_build_name(char *buffer, size_t buflen, +bool os::dll_build_name(char *buffer, size_t buflen, const char* pname, const char* fname) { + bool retval = false; 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. + // Return error on buffer overflow. if (pnamelen + strlen(fname) + 10 > buflen) { - *buffer = '\0'; - return; + return retval; } if (pnamelen == 0) { jio_snprintf(buffer, buflen, "%s.dll", fname); + retval = true; } else if (c == ':' || c == '\\') { jio_snprintf(buffer, buflen, "%s%s.dll", pname, fname); + retval = true; } else if (strchr(pname, *os::path_separator()) != NULL) { int n; char** pelements = split_path(pname, &n); @@ -1164,6 +1166,7 @@ jio_snprintf(buffer, buflen, "%s\\%s.dll", path, fname); } if (file_exists(buffer)) { + retval = true; break; } } @@ -1178,7 +1181,9 @@ } } else { jio_snprintf(buffer, buflen, "%s\\%s.dll", pname, fname); - } + retval = true; + } + return retval; } // Needs to be in os specific directory because windows requires another diff -r bb33c6fdcf0d -r 6b6ddf8c4329 src/share/vm/classfile/classLoader.cpp --- a/src/share/vm/classfile/classLoader.cpp Thu Nov 15 10:42:06 2012 -0800 +++ b/src/share/vm/classfile/classLoader.cpp Fri Nov 16 09:59:08 2012 +0100 @@ -605,8 +605,10 @@ // Load zip library char path[JVM_MAXPATHLEN]; char ebuf[1024]; - os::dll_build_name(path, sizeof(path), Arguments::get_dll_dir(), "zip"); - void* handle = os::dll_load(path, ebuf, sizeof ebuf); + void* handle = NULL; + if (os::dll_build_name(path, sizeof(path), Arguments::get_dll_dir(), "zip")) { + handle = os::dll_load(path, ebuf, sizeof ebuf); + } if (handle == NULL) { vm_exit_during_initialization("Unable to load ZIP library", path); } diff -r bb33c6fdcf0d -r 6b6ddf8c4329 src/share/vm/memory/binaryTreeDictionary.cpp --- a/src/share/vm/memory/binaryTreeDictionary.cpp Thu Nov 15 10:42:06 2012 -0800 +++ b/src/share/vm/memory/binaryTreeDictionary.cpp Fri Nov 16 09:59:08 2012 +0100 @@ -239,7 +239,7 @@ } else { if (nextTC == NULL) { // Removing chunk at tail of list - link_tail(prevFC); + this->link_tail(prevFC); } // Chunk is interior to the list prevFC->link_after(nextTC); @@ -296,7 +296,7 @@ Chunk_t* fc = tail(); fc->link_after(chunk); - link_tail(chunk); + this->link_tail(chunk); assert(!tail() || size() == tail()->size(), "Wrong sized chunk in list"); FreeList_t::increment_count(); @@ -323,7 +323,7 @@ chunk->link_after(fc); } else { assert(tail() == NULL, "List is inconsistent"); - link_tail(chunk); + this->link_tail(chunk); } head()->link_after(chunk); assert(!head() || size() == head()->size(), "Wrong sized chunk in list"); @@ -940,7 +940,7 @@ void do_tree(TreeList* tl) { if (tl != NULL) { do_tree(tl->left()); - do_list(tl); + this->do_list(tl); do_tree(tl->right()); } } @@ -952,7 +952,7 @@ void do_tree(TreeList* tl) { if (tl != NULL) { do_tree(tl->right()); - do_list(tl); + this->do_list(tl); do_tree(tl->left()); } } @@ -1022,7 +1022,7 @@ bool do_tree(TreeList* tl) { if (tl != NULL) { if (do_tree(tl->right())) return true; - if (do_list(tl)) return true; + if (this->do_list(tl)) return true; if (do_tree(tl->left())) return true; } return false; diff -r bb33c6fdcf0d -r 6b6ddf8c4329 src/share/vm/memory/metaspace.cpp --- a/src/share/vm/memory/metaspace.cpp Thu Nov 15 10:42:06 2012 -0800 +++ b/src/share/vm/memory/metaspace.cpp Fri Nov 16 09:59:08 2012 +0100 @@ -42,6 +42,10 @@ typedef BinaryTreeDictionary BlockTreeDictionary; typedef BinaryTreeDictionary ChunkTreeDictionary; +// Define this macro to enable slow integrity checking of +// the free chunk lists +const bool metaspace_slow_verify = false; + // Parameters for stress mode testing const uint metadata_deallocate_a_lot_block = 10; @@ -161,7 +165,17 @@ size_t sum_free_chunks_count(); void locked_verify_free_chunks_total(); + void slow_locked_verify_free_chunks_total() { + if (metaspace_slow_verify) { + locked_verify_free_chunks_total(); + } + } void locked_verify_free_chunks_count(); + void slow_locked_verify_free_chunks_count() { + if (metaspace_slow_verify) { + locked_verify_free_chunks_count(); + } + } void verify_free_chunks_count(); public: @@ -201,7 +215,17 @@ // Debug support void verify(); + void slow_verify() { + if (metaspace_slow_verify) { + verify(); + } + } void locked_verify(); + void slow_locked_verify() { + if (metaspace_slow_verify) { + locked_verify(); + } + } void verify_free_chunks_total(); void locked_print_free_chunks(outputStream* st); @@ -1507,7 +1531,7 @@ if (!UseConcMarkSweepGC && !SpaceManager::expand_lock()->is_locked()) { MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); - locked_verify_free_chunks_total(); + slow_locked_verify_free_chunks_total(); } #endif return _free_chunks_total; @@ -1524,10 +1548,10 @@ Mutex::_no_safepoint_check_flag); // This lock is only needed in debug because the verification // of the _free_chunks_totals walks the list of free chunks - locked_verify_free_chunks_count(); + slow_locked_verify_free_chunks_count(); } #endif - return _free_chunks_count; + return _free_chunks_count; } void ChunkManager::locked_verify_free_chunks_total() { @@ -1561,14 +1585,9 @@ } void ChunkManager::verify() { -#ifdef ASSERT - if (!UseConcMarkSweepGC) { - MutexLockerEx cl(SpaceManager::expand_lock(), - Mutex::_no_safepoint_check_flag); - locked_verify_free_chunks_total(); - locked_verify_free_chunks_count(); - } -#endif + MutexLockerEx cl(SpaceManager::expand_lock(), + Mutex::_no_safepoint_check_flag); + locked_verify(); } void ChunkManager::locked_verify() { @@ -1642,7 +1661,7 @@ free_list->set_head(chunk); // chunk is being returned to the chunk free list inc_free_chunks_total(chunk->capacity_word_size()); - locked_verify(); + slow_locked_verify(); } void ChunkManager::chunk_freelist_deallocate(Metachunk* chunk) { @@ -1650,8 +1669,8 @@ // manangement code for a Metaspace and does not hold the // lock. assert(chunk != NULL, "Deallocating NULL"); - // MutexLockerEx fcl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); - locked_verify(); + assert_lock_strong(SpaceManager::expand_lock()); + slow_locked_verify(); if (TraceMetadataChunkAllocation) { tty->print_cr("ChunkManager::chunk_freelist_deallocate: chunk " PTR_FORMAT " size " SIZE_FORMAT, @@ -1663,7 +1682,7 @@ Metachunk* ChunkManager::free_chunks_get(size_t word_size) { assert_lock_strong(SpaceManager::expand_lock()); - locked_verify(); + slow_locked_verify(); Metachunk* chunk = NULL; if (!SpaceManager::is_humongous(word_size)) { @@ -1708,13 +1727,13 @@ #endif } } - locked_verify(); + slow_locked_verify(); return chunk; } Metachunk* ChunkManager::chunk_freelist_allocate(size_t word_size) { assert_lock_strong(SpaceManager::expand_lock()); - locked_verify(); + slow_locked_verify(); // Take from the beginning of the list Metachunk* chunk = free_chunks_get(word_size); @@ -1959,7 +1978,7 @@ ChunkManager* chunk_manager = vs_list()->chunk_manager(); - chunk_manager->locked_verify(); + chunk_manager->slow_locked_verify(); if (TraceMetadataChunkAllocation && Verbose) { gclog_or_tty->print_cr("~SpaceManager(): " PTR_FORMAT, this); @@ -2015,7 +2034,7 @@ humongous_chunks = next_humongous_chunks; } set_chunks_in_use(HumongousIndex, NULL); - chunk_manager->locked_verify(); + chunk_manager->slow_locked_verify(); } void SpaceManager::deallocate(MetaWord* p, size_t word_size) { @@ -2330,8 +2349,7 @@ ChunkManager* chunk = (mdtype == Metaspace::ClassType) ? Metaspace::class_space_list()->chunk_manager() : Metaspace::space_list()->chunk_manager(); - - chunk->verify_free_chunks_total(); + chunk->slow_verify(); return chunk->free_chunks_total(); } @@ -2435,6 +2453,11 @@ print_waste(out); } +void MetaspaceAux::verify_free_chunks() { + Metaspace::space_list()->chunk_manager()->verify(); + Metaspace::class_space_list()->chunk_manager()->verify(); +} + // Metaspace methods size_t Metaspace::_first_chunk_word_size = 0; diff -r bb33c6fdcf0d -r 6b6ddf8c4329 src/share/vm/memory/metaspace.hpp --- a/src/share/vm/memory/metaspace.hpp Thu Nov 15 10:42:06 2012 -0800 +++ b/src/share/vm/memory/metaspace.hpp Fri Nov 16 09:59:08 2012 +0100 @@ -189,6 +189,7 @@ static void print_waste(outputStream* out); static void dump(outputStream* out); + static void verify_free_chunks(); }; // Metaspace are deallocated when their class loader are GC'ed. diff -r bb33c6fdcf0d -r 6b6ddf8c4329 src/share/vm/memory/universe.cpp --- a/src/share/vm/memory/universe.cpp Thu Nov 15 10:42:06 2012 -0800 +++ b/src/share/vm/memory/universe.cpp Fri Nov 16 09:59:08 2012 +0100 @@ -1304,6 +1304,8 @@ if (!silent) gclog_or_tty->print("cldg "); ClassLoaderDataGraph::verify(); #endif + if (!silent) gclog_or_tty->print("metaspace chunks "); + MetaspaceAux::verify_free_chunks(); if (!silent) gclog_or_tty->print("hand "); JNIHandles::verify(); if (!silent) gclog_or_tty->print("C-heap "); diff -r bb33c6fdcf0d -r 6b6ddf8c4329 src/share/vm/prims/jvmtiExport.cpp --- a/src/share/vm/prims/jvmtiExport.cpp Thu Nov 15 10:42:06 2012 -0800 +++ b/src/share/vm/prims/jvmtiExport.cpp Fri Nov 16 09:59:08 2012 +0100 @@ -2177,7 +2177,7 @@ jint JvmtiExport::load_agent_library(AttachOperation* op, outputStream* st) { char ebuf[1024]; char buffer[JVM_MAXPATHLEN]; - void* library; + void* library = NULL; jint result = JNI_ERR; // get agent name and options @@ -2196,13 +2196,16 @@ library = os::dll_load(agent, ebuf, sizeof ebuf); } else { // Try to load the agent from the standard dll directory - os::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), agent); - library = os::dll_load(buffer, ebuf, sizeof ebuf); + if (os::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), + agent)) { + library = os::dll_load(buffer, ebuf, sizeof ebuf); + } if (library == NULL) { // not found - try local path char ns[1] = {0}; - os::dll_build_name(buffer, sizeof(buffer), ns, agent); - library = os::dll_load(buffer, ebuf, sizeof ebuf); + if (os::dll_build_name(buffer, sizeof(buffer), ns, agent)) { + library = os::dll_load(buffer, ebuf, sizeof ebuf); + } } } diff -r bb33c6fdcf0d -r 6b6ddf8c4329 src/share/vm/runtime/os.cpp --- a/src/share/vm/runtime/os.cpp Thu Nov 15 10:42:06 2012 -0800 +++ b/src/share/vm/runtime/os.cpp Fri Nov 16 09:59:08 2012 +0100 @@ -397,12 +397,16 @@ // 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. - dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "verify"); - dll_load(buffer, ebuf, sizeof(ebuf)); + if (dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), + "verify")) { + dll_load(buffer, ebuf, sizeof(ebuf)); + } // Load java dll - dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "java"); - _native_java_library = dll_load(buffer, ebuf, sizeof(ebuf)); + if (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); } @@ -410,8 +414,10 @@ #if defined(__OpenBSD__) // Work-around OpenBSD's lack of $ORIGIN support by pre-loading libnet.so // ignore errors - dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "net"); - dll_load(buffer, ebuf, sizeof(ebuf)); + if (dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), + "net")) { + dll_load(buffer, ebuf, sizeof(ebuf)); + } #endif } static jboolean onLoaded = JNI_FALSE; @@ -1156,7 +1162,7 @@ if (inpath == NULL) { return NULL; } - strncpy(inpath, path, strlen(path)); + strcpy(inpath, path); int count = 1; char* p = strchr(inpath, psepchar); // Get a count of elements to allocate memory diff -r bb33c6fdcf0d -r 6b6ddf8c4329 src/share/vm/runtime/os.hpp --- a/src/share/vm/runtime/os.hpp Thu Nov 15 10:42:06 2012 -0800 +++ b/src/share/vm/runtime/os.hpp Fri Nov 16 09:59:08 2012 +0100 @@ -479,7 +479,8 @@ 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, + // Returns true if buffer contains full path to existing file, false otherwise + static bool dll_build_name(char* buffer, size_t size, const char* pathname, const char* fname); // Symbol lookup, find nearest function name; basically it implements diff -r bb33c6fdcf0d -r 6b6ddf8c4329 src/share/vm/runtime/thread.cpp --- a/src/share/vm/runtime/thread.cpp Thu Nov 15 10:42:06 2012 -0800 +++ b/src/share/vm/runtime/thread.cpp Fri Nov 16 09:59:08 2012 +0100 @@ -3753,8 +3753,10 @@ } } else { // Try to load the agent from the standard dll directory - os::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), name); - library = os::dll_load(buffer, ebuf, sizeof ebuf); + if (os::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), + name)) { + library = os::dll_load(buffer, ebuf, sizeof ebuf); + } #ifdef KERNEL // Download instrument dll if (library == NULL && strcmp(name, "instrument") == 0) { @@ -3779,8 +3781,9 @@ #endif // KERNEL if (library == NULL) { // Try the local directory char ns[1] = {0}; - os::dll_build_name(buffer, sizeof(buffer), ns, name); - library = os::dll_load(buffer, ebuf, sizeof ebuf); + if (os::dll_build_name(buffer, sizeof(buffer), ns, name)) { + library = os::dll_load(buffer, ebuf, sizeof ebuf); + } if (library == NULL) { const char *sub_msg = " on the library path, with error: "; size_t len = strlen(msg) + strlen(name) + strlen(sub_msg) + strlen(ebuf) + 1;