Wed, 18 Sep 2013 12:52:15 -0400
Merge
test/runtime/6878713/Test6878713.sh | file | annotate | diff | comparison | revisions | |
test/runtime/6878713/testcase.jar | file | annotate | diff | comparison | revisions | |
test/runtime/7020373/Test7020373.sh | file | annotate | diff | comparison | revisions | |
test/runtime/7020373/testcase.jar | file | annotate | diff | comparison | revisions |
1.1 --- a/make/bsd/makefiles/gcc.make Fri Sep 13 00:43:01 2013 -0700 1.2 +++ b/make/bsd/makefiles/gcc.make Wed Sep 18 12:52:15 2013 -0400 1.3 @@ -80,7 +80,7 @@ 1.4 HOSTCC = $(CC) 1.5 endif 1.6 1.7 - AS = $(CC) -c -x assembler-with-cpp 1.8 + AS = $(CC) -c 1.9 endif 1.10 1.11 1.12 @@ -347,6 +347,13 @@ 1.13 LDFLAGS += -mmacosx-version-min=$(MACOSX_VERSION_MIN) 1.14 endif 1.15 1.16 + 1.17 +#------------------------------------------------------------------------ 1.18 +# Assembler flags 1.19 + 1.20 +# Enforce prerpocessing of .s files 1.21 +ASFLAGS += -x assembler-with-cpp 1.22 + 1.23 #------------------------------------------------------------------------ 1.24 # Linker flags 1.25
2.1 --- a/src/os/linux/vm/os_linux.cpp Fri Sep 13 00:43:01 2013 -0700 2.2 +++ b/src/os/linux/vm/os_linux.cpp Wed Sep 18 12:52:15 2013 -0400 2.3 @@ -131,6 +131,7 @@ 2.4 bool os::Linux::_supports_fast_thread_cpu_time = false; 2.5 const char * os::Linux::_glibc_version = NULL; 2.6 const char * os::Linux::_libpthread_version = NULL; 2.7 +pthread_condattr_t os::Linux::_condattr[1]; 2.8 2.9 static jlong initial_time_count=0; 2.10 2.11 @@ -1399,12 +1400,15 @@ 2.12 clock_gettime_func(CLOCK_MONOTONIC, &tp) == 0) { 2.13 // yes, monotonic clock is supported 2.14 _clock_gettime = clock_gettime_func; 2.15 + return; 2.16 } else { 2.17 // close librt if there is no monotonic clock 2.18 dlclose(handle); 2.19 } 2.20 } 2.21 } 2.22 + warning("No monotonic clock was available - timed services may " \ 2.23 + "be adversely affected if the time-of-day clock changes"); 2.24 } 2.25 2.26 #ifndef SYS_clock_getres 2.27 @@ -2165,23 +2169,49 @@ 2.28 } 2.29 2.30 // Try to identify popular distros. 2.31 -// Most Linux distributions have /etc/XXX-release file, which contains 2.32 -// the OS version string. Some have more than one /etc/XXX-release file 2.33 -// (e.g. Mandrake has both /etc/mandrake-release and /etc/redhat-release.), 2.34 -// so the order is important. 2.35 +// Most Linux distributions have a /etc/XXX-release file, which contains 2.36 +// the OS version string. Newer Linux distributions have a /etc/lsb-release 2.37 +// file that also contains the OS version string. Some have more than one 2.38 +// /etc/XXX-release file (e.g. Mandrake has both /etc/mandrake-release and 2.39 +// /etc/redhat-release.), so the order is important. 2.40 +// Any Linux that is based on Redhat (i.e. Oracle, Mandrake, Sun JDS...) have 2.41 +// their own specific XXX-release file as well as a redhat-release file. 2.42 +// Because of this the XXX-release file needs to be searched for before the 2.43 +// redhat-release file. 2.44 +// Since Red Hat has a lsb-release file that is not very descriptive the 2.45 +// search for redhat-release needs to be before lsb-release. 2.46 +// Since the lsb-release file is the new standard it needs to be searched 2.47 +// before the older style release files. 2.48 +// Searching system-release (Red Hat) and os-release (other Linuxes) are a 2.49 +// next to last resort. The os-release file is a new standard that contains 2.50 +// distribution information and the system-release file seems to be an old 2.51 +// standard that has been replaced by the lsb-release and os-release files. 2.52 +// Searching for the debian_version file is the last resort. It contains 2.53 +// an informative string like "6.0.6" or "wheezy/sid". Because of this 2.54 +// "Debian " is printed before the contents of the debian_version file. 2.55 void os::Linux::print_distro_info(outputStream* st) { 2.56 - if (!_print_ascii_file("/etc/mandrake-release", st) && 2.57 - !_print_ascii_file("/etc/sun-release", st) && 2.58 - !_print_ascii_file("/etc/redhat-release", st) && 2.59 - !_print_ascii_file("/etc/SuSE-release", st) && 2.60 - !_print_ascii_file("/etc/turbolinux-release", st) && 2.61 - !_print_ascii_file("/etc/gentoo-release", st) && 2.62 - !_print_ascii_file("/etc/debian_version", st) && 2.63 - !_print_ascii_file("/etc/ltib-release", st) && 2.64 - !_print_ascii_file("/etc/angstrom-version", st)) { 2.65 - st->print("Linux"); 2.66 - } 2.67 - st->cr(); 2.68 + if (!_print_ascii_file("/etc/oracle-release", st) && 2.69 + !_print_ascii_file("/etc/mandriva-release", st) && 2.70 + !_print_ascii_file("/etc/mandrake-release", st) && 2.71 + !_print_ascii_file("/etc/sun-release", st) && 2.72 + !_print_ascii_file("/etc/redhat-release", st) && 2.73 + !_print_ascii_file("/etc/lsb-release", st) && 2.74 + !_print_ascii_file("/etc/SuSE-release", st) && 2.75 + !_print_ascii_file("/etc/turbolinux-release", st) && 2.76 + !_print_ascii_file("/etc/gentoo-release", st) && 2.77 + !_print_ascii_file("/etc/ltib-release", st) && 2.78 + !_print_ascii_file("/etc/angstrom-version", st) && 2.79 + !_print_ascii_file("/etc/system-release", st) && 2.80 + !_print_ascii_file("/etc/os-release", st)) { 2.81 + 2.82 + if (file_exists("/etc/debian_version")) { 2.83 + st->print("Debian "); 2.84 + _print_ascii_file("/etc/debian_version", st); 2.85 + } else { 2.86 + st->print("Linux"); 2.87 + } 2.88 + } 2.89 + st->cr(); 2.90 } 2.91 2.92 void os::Linux::print_libversion_info(outputStream* st) { 2.93 @@ -4709,6 +4739,26 @@ 2.94 2.95 Linux::clock_init(); 2.96 initial_time_count = os::elapsed_counter(); 2.97 + 2.98 + // pthread_condattr initialization for monotonic clock 2.99 + int status; 2.100 + pthread_condattr_t* _condattr = os::Linux::condAttr(); 2.101 + if ((status = pthread_condattr_init(_condattr)) != 0) { 2.102 + fatal(err_msg("pthread_condattr_init: %s", strerror(status))); 2.103 + } 2.104 + // Only set the clock if CLOCK_MONOTONIC is available 2.105 + if (Linux::supports_monotonic_clock()) { 2.106 + if ((status = pthread_condattr_setclock(_condattr, CLOCK_MONOTONIC)) != 0) { 2.107 + if (status == EINVAL) { 2.108 + warning("Unable to use monotonic clock with relative timed-waits" \ 2.109 + " - changes to the time-of-day clock may have adverse affects"); 2.110 + } else { 2.111 + fatal(err_msg("pthread_condattr_setclock: %s", strerror(status))); 2.112 + } 2.113 + } 2.114 + } 2.115 + // else it defaults to CLOCK_REALTIME 2.116 + 2.117 pthread_mutex_init(&dl_mutex, NULL); 2.118 2.119 // If the pagesize of the VM is greater than 8K determine the appropriate 2.120 @@ -5519,21 +5569,36 @@ 2.121 2.122 static struct timespec* compute_abstime(timespec* abstime, jlong millis) { 2.123 if (millis < 0) millis = 0; 2.124 - struct timeval now; 2.125 - int status = gettimeofday(&now, NULL); 2.126 - assert(status == 0, "gettimeofday"); 2.127 + 2.128 jlong seconds = millis / 1000; 2.129 millis %= 1000; 2.130 if (seconds > 50000000) { // see man cond_timedwait(3T) 2.131 seconds = 50000000; 2.132 } 2.133 - abstime->tv_sec = now.tv_sec + seconds; 2.134 - long usec = now.tv_usec + millis * 1000; 2.135 - if (usec >= 1000000) { 2.136 - abstime->tv_sec += 1; 2.137 - usec -= 1000000; 2.138 - } 2.139 - abstime->tv_nsec = usec * 1000; 2.140 + 2.141 + if (os::Linux::supports_monotonic_clock()) { 2.142 + struct timespec now; 2.143 + int status = os::Linux::clock_gettime(CLOCK_MONOTONIC, &now); 2.144 + assert_status(status == 0, status, "clock_gettime"); 2.145 + abstime->tv_sec = now.tv_sec + seconds; 2.146 + long nanos = now.tv_nsec + millis * NANOSECS_PER_MILLISEC; 2.147 + if (nanos >= NANOSECS_PER_SEC) { 2.148 + abstime->tv_sec += 1; 2.149 + nanos -= NANOSECS_PER_SEC; 2.150 + } 2.151 + abstime->tv_nsec = nanos; 2.152 + } else { 2.153 + struct timeval now; 2.154 + int status = gettimeofday(&now, NULL); 2.155 + assert(status == 0, "gettimeofday"); 2.156 + abstime->tv_sec = now.tv_sec + seconds; 2.157 + long usec = now.tv_usec + millis * 1000; 2.158 + if (usec >= 1000000) { 2.159 + abstime->tv_sec += 1; 2.160 + usec -= 1000000; 2.161 + } 2.162 + abstime->tv_nsec = usec * 1000; 2.163 + } 2.164 return abstime; 2.165 } 2.166 2.167 @@ -5625,7 +5690,7 @@ 2.168 status = os::Linux::safe_cond_timedwait(_cond, _mutex, &abst); 2.169 if (status != 0 && WorkAroundNPTLTimedWaitHang) { 2.170 pthread_cond_destroy (_cond); 2.171 - pthread_cond_init (_cond, NULL) ; 2.172 + pthread_cond_init (_cond, os::Linux::condAttr()) ; 2.173 } 2.174 assert_status(status == 0 || status == EINTR || 2.175 status == ETIME || status == ETIMEDOUT, 2.176 @@ -5726,32 +5791,50 @@ 2.177 2.178 static void unpackTime(timespec* absTime, bool isAbsolute, jlong time) { 2.179 assert (time > 0, "convertTime"); 2.180 - 2.181 - struct timeval now; 2.182 - int status = gettimeofday(&now, NULL); 2.183 - assert(status == 0, "gettimeofday"); 2.184 - 2.185 - time_t max_secs = now.tv_sec + MAX_SECS; 2.186 - 2.187 - if (isAbsolute) { 2.188 - jlong secs = time / 1000; 2.189 - if (secs > max_secs) { 2.190 - absTime->tv_sec = max_secs; 2.191 + time_t max_secs = 0; 2.192 + 2.193 + if (!os::Linux::supports_monotonic_clock() || isAbsolute) { 2.194 + struct timeval now; 2.195 + int status = gettimeofday(&now, NULL); 2.196 + assert(status == 0, "gettimeofday"); 2.197 + 2.198 + max_secs = now.tv_sec + MAX_SECS; 2.199 + 2.200 + if (isAbsolute) { 2.201 + jlong secs = time / 1000; 2.202 + if (secs > max_secs) { 2.203 + absTime->tv_sec = max_secs; 2.204 + } else { 2.205 + absTime->tv_sec = secs; 2.206 + } 2.207 + absTime->tv_nsec = (time % 1000) * NANOSECS_PER_MILLISEC; 2.208 + } else { 2.209 + jlong secs = time / NANOSECS_PER_SEC; 2.210 + if (secs >= MAX_SECS) { 2.211 + absTime->tv_sec = max_secs; 2.212 + absTime->tv_nsec = 0; 2.213 + } else { 2.214 + absTime->tv_sec = now.tv_sec + secs; 2.215 + absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_usec*1000; 2.216 + if (absTime->tv_nsec >= NANOSECS_PER_SEC) { 2.217 + absTime->tv_nsec -= NANOSECS_PER_SEC; 2.218 + ++absTime->tv_sec; // note: this must be <= max_secs 2.219 + } 2.220 + } 2.221 } 2.222 - else { 2.223 - absTime->tv_sec = secs; 2.224 - } 2.225 - absTime->tv_nsec = (time % 1000) * NANOSECS_PER_MILLISEC; 2.226 - } 2.227 - else { 2.228 + } else { 2.229 + // must be relative using monotonic clock 2.230 + struct timespec now; 2.231 + int status = os::Linux::clock_gettime(CLOCK_MONOTONIC, &now); 2.232 + assert_status(status == 0, status, "clock_gettime"); 2.233 + max_secs = now.tv_sec + MAX_SECS; 2.234 jlong secs = time / NANOSECS_PER_SEC; 2.235 if (secs >= MAX_SECS) { 2.236 absTime->tv_sec = max_secs; 2.237 absTime->tv_nsec = 0; 2.238 - } 2.239 - else { 2.240 + } else { 2.241 absTime->tv_sec = now.tv_sec + secs; 2.242 - absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_usec*1000; 2.243 + absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_nsec; 2.244 if (absTime->tv_nsec >= NANOSECS_PER_SEC) { 2.245 absTime->tv_nsec -= NANOSECS_PER_SEC; 2.246 ++absTime->tv_sec; // note: this must be <= max_secs 2.247 @@ -5831,15 +5914,19 @@ 2.248 jt->set_suspend_equivalent(); 2.249 // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self() 2.250 2.251 + assert(_cur_index == -1, "invariant"); 2.252 if (time == 0) { 2.253 - status = pthread_cond_wait (_cond, _mutex) ; 2.254 + _cur_index = REL_INDEX; // arbitrary choice when not timed 2.255 + status = pthread_cond_wait (&_cond[_cur_index], _mutex) ; 2.256 } else { 2.257 - status = os::Linux::safe_cond_timedwait (_cond, _mutex, &absTime) ; 2.258 + _cur_index = isAbsolute ? ABS_INDEX : REL_INDEX; 2.259 + status = os::Linux::safe_cond_timedwait (&_cond[_cur_index], _mutex, &absTime) ; 2.260 if (status != 0 && WorkAroundNPTLTimedWaitHang) { 2.261 - pthread_cond_destroy (_cond) ; 2.262 - pthread_cond_init (_cond, NULL); 2.263 + pthread_cond_destroy (&_cond[_cur_index]) ; 2.264 + pthread_cond_init (&_cond[_cur_index], isAbsolute ? NULL : os::Linux::condAttr()); 2.265 } 2.266 } 2.267 + _cur_index = -1; 2.268 assert_status(status == 0 || status == EINTR || 2.269 status == ETIME || status == ETIMEDOUT, 2.270 status, "cond_timedwait"); 2.271 @@ -5868,17 +5955,24 @@ 2.272 s = _counter; 2.273 _counter = 1; 2.274 if (s < 1) { 2.275 - if (WorkAroundNPTLTimedWaitHang) { 2.276 - status = pthread_cond_signal (_cond) ; 2.277 - assert (status == 0, "invariant") ; 2.278 + // thread might be parked 2.279 + if (_cur_index != -1) { 2.280 + // thread is definitely parked 2.281 + if (WorkAroundNPTLTimedWaitHang) { 2.282 + status = pthread_cond_signal (&_cond[_cur_index]); 2.283 + assert (status == 0, "invariant"); 2.284 status = pthread_mutex_unlock(_mutex); 2.285 - assert (status == 0, "invariant") ; 2.286 - } else { 2.287 + assert (status == 0, "invariant"); 2.288 + } else { 2.289 status = pthread_mutex_unlock(_mutex); 2.290 - assert (status == 0, "invariant") ; 2.291 - status = pthread_cond_signal (_cond) ; 2.292 - assert (status == 0, "invariant") ; 2.293 - } 2.294 + assert (status == 0, "invariant"); 2.295 + status = pthread_cond_signal (&_cond[_cur_index]); 2.296 + assert (status == 0, "invariant"); 2.297 + } 2.298 + } else { 2.299 + pthread_mutex_unlock(_mutex); 2.300 + assert (status == 0, "invariant") ; 2.301 + } 2.302 } else { 2.303 pthread_mutex_unlock(_mutex); 2.304 assert (status == 0, "invariant") ;
3.1 --- a/src/os/linux/vm/os_linux.hpp Fri Sep 13 00:43:01 2013 -0700 3.2 +++ b/src/os/linux/vm/os_linux.hpp Wed Sep 18 12:52:15 2013 -0400 3.3 @@ -221,6 +221,13 @@ 3.4 3.5 static jlong fast_thread_cpu_time(clockid_t clockid); 3.6 3.7 + // pthread_cond clock suppport 3.8 + private: 3.9 + static pthread_condattr_t _condattr[1]; 3.10 + 3.11 + public: 3.12 + static pthread_condattr_t* condAttr() { return _condattr; } 3.13 + 3.14 // Stack repair handling 3.15 3.16 // none present 3.17 @@ -295,7 +302,7 @@ 3.18 public: 3.19 PlatformEvent() { 3.20 int status; 3.21 - status = pthread_cond_init (_cond, NULL); 3.22 + status = pthread_cond_init (_cond, os::Linux::condAttr()); 3.23 assert_status(status == 0, status, "cond_init"); 3.24 status = pthread_mutex_init (_mutex, NULL); 3.25 assert_status(status == 0, status, "mutex_init"); 3.26 @@ -310,14 +317,19 @@ 3.27 void park () ; 3.28 void unpark () ; 3.29 int TryPark () ; 3.30 - int park (jlong millis) ; 3.31 + int park (jlong millis) ; // relative timed-wait only 3.32 void SetAssociation (Thread * a) { _Assoc = a ; } 3.33 } ; 3.34 3.35 class PlatformParker : public CHeapObj<mtInternal> { 3.36 protected: 3.37 + enum { 3.38 + REL_INDEX = 0, 3.39 + ABS_INDEX = 1 3.40 + }; 3.41 + int _cur_index; // which cond is in use: -1, 0, 1 3.42 pthread_mutex_t _mutex [1] ; 3.43 - pthread_cond_t _cond [1] ; 3.44 + pthread_cond_t _cond [2] ; // one for relative times and one for abs. 3.45 3.46 public: // TODO-FIXME: make dtor private 3.47 ~PlatformParker() { guarantee (0, "invariant") ; } 3.48 @@ -325,10 +337,13 @@ 3.49 public: 3.50 PlatformParker() { 3.51 int status; 3.52 - status = pthread_cond_init (_cond, NULL); 3.53 - assert_status(status == 0, status, "cond_init"); 3.54 + status = pthread_cond_init (&_cond[REL_INDEX], os::Linux::condAttr()); 3.55 + assert_status(status == 0, status, "cond_init rel"); 3.56 + status = pthread_cond_init (&_cond[ABS_INDEX], NULL); 3.57 + assert_status(status == 0, status, "cond_init abs"); 3.58 status = pthread_mutex_init (_mutex, NULL); 3.59 assert_status(status == 0, status, "mutex_init"); 3.60 + _cur_index = -1; // mark as unused 3.61 } 3.62 }; 3.63
4.1 --- a/src/os/windows/vm/decoder_windows.cpp Fri Sep 13 00:43:01 2013 -0700 4.2 +++ b/src/os/windows/vm/decoder_windows.cpp Wed Sep 18 12:52:15 2013 -0400 4.3 @@ -32,7 +32,11 @@ 4.4 _can_decode_in_vm = false; 4.5 _pfnSymGetSymFromAddr64 = NULL; 4.6 _pfnUndecorateSymbolName = NULL; 4.7 - 4.8 +#ifdef AMD64 4.9 + _pfnStackWalk64 = NULL; 4.10 + _pfnSymFunctionTableAccess64 = NULL; 4.11 + _pfnSymGetModuleBase64 = NULL; 4.12 +#endif 4.13 _decoder_status = no_error; 4.14 initialize(); 4.15 } 4.16 @@ -53,14 +57,24 @@ 4.17 _pfnUndecorateSymbolName = (pfn_UndecorateSymbolName)::GetProcAddress(handle, "UnDecorateSymbolName"); 4.18 4.19 if (_pfnSymSetOptions == NULL || _pfnSymInitialize == NULL || _pfnSymGetSymFromAddr64 == NULL) { 4.20 - _pfnSymGetSymFromAddr64 = NULL; 4.21 - _pfnUndecorateSymbolName = NULL; 4.22 - ::FreeLibrary(handle); 4.23 - _dbghelp_handle = NULL; 4.24 + uninitialize(); 4.25 _decoder_status = helper_func_error; 4.26 return; 4.27 } 4.28 4.29 +#ifdef AMD64 4.30 + _pfnStackWalk64 = (pfn_StackWalk64)::GetProcAddress(handle, "StackWalk64"); 4.31 + _pfnSymFunctionTableAccess64 = (pfn_SymFunctionTableAccess64)::GetProcAddress(handle, "SymFunctionTableAccess64"); 4.32 + _pfnSymGetModuleBase64 = (pfn_SymGetModuleBase64)::GetProcAddress(handle, "SymGetModuleBase64"); 4.33 + if (_pfnStackWalk64 == NULL || _pfnSymFunctionTableAccess64 == NULL || _pfnSymGetModuleBase64 == NULL) { 4.34 + // We can't call StackWalk64 to walk the stack, but we are still 4.35 + // able to decode the symbols. Let's limp on. 4.36 + _pfnStackWalk64 = NULL; 4.37 + _pfnSymFunctionTableAccess64 = NULL; 4.38 + _pfnSymGetModuleBase64 = NULL; 4.39 + } 4.40 +#endif 4.41 + 4.42 HANDLE hProcess = ::GetCurrentProcess(); 4.43 _pfnSymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_EXACT_SYMBOLS); 4.44 if (!_pfnSymInitialize(hProcess, NULL, TRUE)) { 4.45 @@ -156,6 +170,11 @@ 4.46 void WindowsDecoder::uninitialize() { 4.47 _pfnSymGetSymFromAddr64 = NULL; 4.48 _pfnUndecorateSymbolName = NULL; 4.49 +#ifdef AMD64 4.50 + _pfnStackWalk64 = NULL; 4.51 + _pfnSymFunctionTableAccess64 = NULL; 4.52 + _pfnSymGetModuleBase64 = NULL; 4.53 +#endif 4.54 if (_dbghelp_handle != NULL) { 4.55 ::FreeLibrary(_dbghelp_handle); 4.56 } 4.57 @@ -195,3 +214,65 @@ 4.58 _pfnUndecorateSymbolName(symbol, buf, buflen, UNDNAME_COMPLETE); 4.59 } 4.60 4.61 +#ifdef AMD64 4.62 +BOOL WindowsDbgHelp::StackWalk64(DWORD MachineType, 4.63 + HANDLE hProcess, 4.64 + HANDLE hThread, 4.65 + LPSTACKFRAME64 StackFrame, 4.66 + PVOID ContextRecord, 4.67 + PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, 4.68 + PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, 4.69 + PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, 4.70 + PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress) { 4.71 + DecoderLocker locker; 4.72 + WindowsDecoder* wd = (WindowsDecoder*)locker.decoder(); 4.73 + 4.74 + if (!wd->has_error() && wd->_pfnStackWalk64) { 4.75 + return wd->_pfnStackWalk64(MachineType, 4.76 + hProcess, 4.77 + hThread, 4.78 + StackFrame, 4.79 + ContextRecord, 4.80 + ReadMemoryRoutine, 4.81 + FunctionTableAccessRoutine, 4.82 + GetModuleBaseRoutine, 4.83 + TranslateAddress); 4.84 + } else { 4.85 + return false; 4.86 + } 4.87 +} 4.88 + 4.89 +PVOID WindowsDbgHelp::SymFunctionTableAccess64(HANDLE hProcess, DWORD64 AddrBase) { 4.90 + DecoderLocker locker; 4.91 + WindowsDecoder* wd = (WindowsDecoder*)locker.decoder(); 4.92 + 4.93 + if (!wd->has_error() && wd->_pfnSymFunctionTableAccess64) { 4.94 + return wd->_pfnSymFunctionTableAccess64(hProcess, AddrBase); 4.95 + } else { 4.96 + return NULL; 4.97 + } 4.98 +} 4.99 + 4.100 +pfn_SymFunctionTableAccess64 WindowsDbgHelp::pfnSymFunctionTableAccess64() { 4.101 + DecoderLocker locker; 4.102 + WindowsDecoder* wd = (WindowsDecoder*)locker.decoder(); 4.103 + 4.104 + if (!wd->has_error()) { 4.105 + return wd->_pfnSymFunctionTableAccess64; 4.106 + } else { 4.107 + return NULL; 4.108 + } 4.109 +} 4.110 + 4.111 +pfn_SymGetModuleBase64 WindowsDbgHelp::pfnSymGetModuleBase64() { 4.112 + DecoderLocker locker; 4.113 + WindowsDecoder* wd = (WindowsDecoder*)locker.decoder(); 4.114 + 4.115 + if (!wd->has_error()) { 4.116 + return wd->_pfnSymGetModuleBase64; 4.117 + } else { 4.118 + return NULL; 4.119 + } 4.120 +} 4.121 + 4.122 +#endif // AMD64
5.1 --- a/src/os/windows/vm/decoder_windows.hpp Fri Sep 13 00:43:01 2013 -0700 5.2 +++ b/src/os/windows/vm/decoder_windows.hpp Wed Sep 18 12:52:15 2013 -0400 5.3 @@ -38,6 +38,20 @@ 5.4 typedef BOOL (WINAPI *pfn_SymSetSearchPath)(HANDLE, PCTSTR); 5.5 typedef BOOL (WINAPI *pfn_SymGetSearchPath)(HANDLE, PTSTR, int); 5.6 5.7 +#ifdef AMD64 5.8 +typedef BOOL (WINAPI *pfn_StackWalk64)(DWORD MachineType, 5.9 + HANDLE hProcess, 5.10 + HANDLE hThread, 5.11 + LPSTACKFRAME64 StackFrame, 5.12 + PVOID ContextRecord, 5.13 + PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, 5.14 + PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, 5.15 + PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, 5.16 + PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress); 5.17 +typedef PVOID (WINAPI *pfn_SymFunctionTableAccess64)(HANDLE hProcess, DWORD64 AddrBase); 5.18 +typedef DWORD64 (WINAPI *pfn_SymGetModuleBase64)(HANDLE hProcess, DWORD64 dwAddr); 5.19 +#endif 5.20 + 5.21 class WindowsDecoder : public AbstractDecoder { 5.22 5.23 public: 5.24 @@ -61,7 +75,34 @@ 5.25 bool _can_decode_in_vm; 5.26 pfn_SymGetSymFromAddr64 _pfnSymGetSymFromAddr64; 5.27 pfn_UndecorateSymbolName _pfnUndecorateSymbolName; 5.28 +#ifdef AMD64 5.29 + pfn_StackWalk64 _pfnStackWalk64; 5.30 + pfn_SymFunctionTableAccess64 _pfnSymFunctionTableAccess64; 5.31 + pfn_SymGetModuleBase64 _pfnSymGetModuleBase64; 5.32 + 5.33 + friend class WindowsDbgHelp; 5.34 +#endif 5.35 }; 5.36 5.37 +#ifdef AMD64 5.38 +// TODO: refactor and move the handling of dbghelp.dll outside of Decoder 5.39 +class WindowsDbgHelp : public Decoder { 5.40 +public: 5.41 + static BOOL StackWalk64(DWORD MachineType, 5.42 + HANDLE hProcess, 5.43 + HANDLE hThread, 5.44 + LPSTACKFRAME64 StackFrame, 5.45 + PVOID ContextRecord, 5.46 + PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, 5.47 + PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, 5.48 + PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, 5.49 + PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress); 5.50 + static PVOID SymFunctionTableAccess64(HANDLE hProcess, DWORD64 AddrBase); 5.51 + 5.52 + static pfn_SymFunctionTableAccess64 pfnSymFunctionTableAccess64(); 5.53 + static pfn_SymGetModuleBase64 pfnSymGetModuleBase64(); 5.54 +}; 5.55 +#endif 5.56 + 5.57 #endif // OS_WINDOWS_VM_DECODER_WINDOWS_HPP 5.58
6.1 --- a/src/os_cpu/windows_x86/vm/os_windows_x86.cpp Fri Sep 13 00:43:01 2013 -0700 6.2 +++ b/src/os_cpu/windows_x86/vm/os_windows_x86.cpp Wed Sep 18 12:52:15 2013 -0400 6.3 @@ -29,6 +29,7 @@ 6.4 #include "classfile/vmSymbols.hpp" 6.5 #include "code/icBuffer.hpp" 6.6 #include "code/vtableStubs.hpp" 6.7 +#include "decoder_windows.hpp" 6.8 #include "interpreter/interpreter.hpp" 6.9 #include "jvm_windows.h" 6.10 #include "memory/allocation.inline.hpp" 6.11 @@ -327,6 +328,94 @@ 6.12 6.13 cmpxchg_long_func_t* os::atomic_cmpxchg_long_func = os::atomic_cmpxchg_long_bootstrap; 6.14 6.15 +#ifdef AMD64 6.16 +/* 6.17 + * Windows/x64 does not use stack frames the way expected by Java: 6.18 + * [1] in most cases, there is no frame pointer. All locals are addressed via RSP 6.19 + * [2] in rare cases, when alloca() is used, a frame pointer is used, but this may 6.20 + * not be RBP. 6.21 + * See http://msdn.microsoft.com/en-us/library/ew5tede7.aspx 6.22 + * 6.23 + * So it's not possible to print the native stack using the 6.24 + * while (...) {... fr = os::get_sender_for_C_frame(&fr); } 6.25 + * loop in vmError.cpp. We need to roll our own loop. 6.26 + */ 6.27 +bool os::platform_print_native_stack(outputStream* st, void* context, 6.28 + char *buf, int buf_size) 6.29 +{ 6.30 + CONTEXT ctx; 6.31 + if (context != NULL) { 6.32 + memcpy(&ctx, context, sizeof(ctx)); 6.33 + } else { 6.34 + RtlCaptureContext(&ctx); 6.35 + } 6.36 + 6.37 + st->print_cr("Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)"); 6.38 + 6.39 + STACKFRAME stk; 6.40 + memset(&stk, 0, sizeof(stk)); 6.41 + stk.AddrStack.Offset = ctx.Rsp; 6.42 + stk.AddrStack.Mode = AddrModeFlat; 6.43 + stk.AddrFrame.Offset = ctx.Rbp; 6.44 + stk.AddrFrame.Mode = AddrModeFlat; 6.45 + stk.AddrPC.Offset = ctx.Rip; 6.46 + stk.AddrPC.Mode = AddrModeFlat; 6.47 + 6.48 + int count = 0; 6.49 + address lastpc = 0; 6.50 + while (count++ < StackPrintLimit) { 6.51 + intptr_t* sp = (intptr_t*)stk.AddrStack.Offset; 6.52 + intptr_t* fp = (intptr_t*)stk.AddrFrame.Offset; // NOT necessarily the same as ctx.Rbp! 6.53 + address pc = (address)stk.AddrPC.Offset; 6.54 + 6.55 + if (pc != NULL && sp != NULL && fp != NULL) { 6.56 + if (count == 2 && lastpc == pc) { 6.57 + // Skip it -- StackWalk64() may return the same PC 6.58 + // (but different SP) on the first try. 6.59 + } else { 6.60 + // Don't try to create a frame(sp, fp, pc) -- on WinX64, stk.AddrFrame 6.61 + // may not contain what Java expects, and may cause the frame() constructor 6.62 + // to crash. Let's just print out the symbolic address. 6.63 + frame::print_C_frame(st, buf, buf_size, pc); 6.64 + st->cr(); 6.65 + } 6.66 + lastpc = pc; 6.67 + } else { 6.68 + break; 6.69 + } 6.70 + 6.71 + PVOID p = WindowsDbgHelp::SymFunctionTableAccess64(GetCurrentProcess(), stk.AddrPC.Offset); 6.72 + if (!p) { 6.73 + // StackWalk64() can't handle this PC. Calling StackWalk64 again may cause crash. 6.74 + break; 6.75 + } 6.76 + 6.77 + BOOL result = WindowsDbgHelp::StackWalk64( 6.78 + IMAGE_FILE_MACHINE_AMD64, // __in DWORD MachineType, 6.79 + GetCurrentProcess(), // __in HANDLE hProcess, 6.80 + GetCurrentThread(), // __in HANDLE hThread, 6.81 + &stk, // __inout LP STACKFRAME64 StackFrame, 6.82 + &ctx, // __inout PVOID ContextRecord, 6.83 + NULL, // __in_opt PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, 6.84 + WindowsDbgHelp::pfnSymFunctionTableAccess64(), 6.85 + // __in_opt PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, 6.86 + WindowsDbgHelp::pfnSymGetModuleBase64(), 6.87 + // __in_opt PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, 6.88 + NULL); // __in_opt PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress 6.89 + 6.90 + if (!result) { 6.91 + break; 6.92 + } 6.93 + } 6.94 + if (count > StackPrintLimit) { 6.95 + st->print_cr("...<more frames>..."); 6.96 + } 6.97 + st->cr(); 6.98 + 6.99 + return true; 6.100 +} 6.101 +#endif // AMD64 6.102 + 6.103 ExtendedPC os::fetch_frame_from_context(void* ucVoid, 6.104 intptr_t** ret_sp, intptr_t** ret_fp) { 6.105 6.106 @@ -401,6 +490,9 @@ 6.107 StubRoutines::x86::get_previous_fp_entry()); 6.108 if (func == NULL) return frame(); 6.109 intptr_t* fp = (*func)(); 6.110 + if (fp == NULL) { 6.111 + return frame(); 6.112 + } 6.113 #else 6.114 intptr_t* fp = _get_previous_fp(); 6.115 #endif // AMD64
7.1 --- a/src/os_cpu/windows_x86/vm/os_windows_x86.hpp Fri Sep 13 00:43:01 2013 -0700 7.2 +++ b/src/os_cpu/windows_x86/vm/os_windows_x86.hpp Wed Sep 18 12:52:15 2013 -0400 7.3 @@ -62,4 +62,10 @@ 7.4 7.5 static bool register_code_area(char *low, char *high); 7.6 7.7 +#ifdef AMD64 7.8 +#define PLATFORM_PRINT_NATIVE_STACK 1 7.9 +static bool platform_print_native_stack(outputStream* st, void* context, 7.10 + char *buf, int buf_size); 7.11 +#endif 7.12 + 7.13 #endif // OS_CPU_WINDOWS_X86_VM_OS_WINDOWS_X86_HPP
8.1 --- a/src/share/vm/classfile/classFileParser.cpp Fri Sep 13 00:43:01 2013 -0700 8.2 +++ b/src/share/vm/classfile/classFileParser.cpp Wed Sep 18 12:52:15 2013 -0400 8.3 @@ -888,6 +888,7 @@ 8.4 int runtime_visible_type_annotations_length = 0; 8.5 u1* runtime_invisible_type_annotations = NULL; 8.6 int runtime_invisible_type_annotations_length = 0; 8.7 + bool runtime_invisible_type_annotations_exists = false; 8.8 while (attributes_count--) { 8.9 cfs->guarantee_more(6, CHECK); // attribute_name_index, attribute_length 8.10 u2 attribute_name_index = cfs->get_u2_fast(); 8.11 @@ -946,15 +947,27 @@ 8.12 assert(runtime_invisible_annotations != NULL, "null invisible annotations"); 8.13 cfs->skip_u1(runtime_invisible_annotations_length, CHECK); 8.14 } else if (attribute_name == vmSymbols::tag_runtime_visible_type_annotations()) { 8.15 + if (runtime_visible_type_annotations != NULL) { 8.16 + classfile_parse_error( 8.17 + "Multiple RuntimeVisibleTypeAnnotations attributes for field in class file %s", CHECK); 8.18 + } 8.19 runtime_visible_type_annotations_length = attribute_length; 8.20 runtime_visible_type_annotations = cfs->get_u1_buffer(); 8.21 assert(runtime_visible_type_annotations != NULL, "null visible type annotations"); 8.22 cfs->skip_u1(runtime_visible_type_annotations_length, CHECK); 8.23 - } else if (PreserveAllAnnotations && attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) { 8.24 - runtime_invisible_type_annotations_length = attribute_length; 8.25 - runtime_invisible_type_annotations = cfs->get_u1_buffer(); 8.26 - assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); 8.27 - cfs->skip_u1(runtime_invisible_type_annotations_length, CHECK); 8.28 + } else if (attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) { 8.29 + if (runtime_invisible_type_annotations_exists) { 8.30 + classfile_parse_error( 8.31 + "Multiple RuntimeInvisibleTypeAnnotations attributes for field in class file %s", CHECK); 8.32 + } else { 8.33 + runtime_invisible_type_annotations_exists = true; 8.34 + } 8.35 + if (PreserveAllAnnotations) { 8.36 + runtime_invisible_type_annotations_length = attribute_length; 8.37 + runtime_invisible_type_annotations = cfs->get_u1_buffer(); 8.38 + assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); 8.39 + } 8.40 + cfs->skip_u1(attribute_length, CHECK); 8.41 } else { 8.42 cfs->skip_u1(attribute_length, CHECK); // Skip unknown attributes 8.43 } 8.44 @@ -2066,6 +2079,7 @@ 8.45 int runtime_visible_type_annotations_length = 0; 8.46 u1* runtime_invisible_type_annotations = NULL; 8.47 int runtime_invisible_type_annotations_length = 0; 8.48 + bool runtime_invisible_type_annotations_exists = false; 8.49 u1* annotation_default = NULL; 8.50 int annotation_default_length = 0; 8.51 8.52 @@ -2322,16 +2336,30 @@ 8.53 assert(annotation_default != NULL, "null annotation default"); 8.54 cfs->skip_u1(annotation_default_length, CHECK_(nullHandle)); 8.55 } else if (method_attribute_name == vmSymbols::tag_runtime_visible_type_annotations()) { 8.56 + if (runtime_visible_type_annotations != NULL) { 8.57 + classfile_parse_error( 8.58 + "Multiple RuntimeVisibleTypeAnnotations attributes for method in class file %s", 8.59 + CHECK_(nullHandle)); 8.60 + } 8.61 runtime_visible_type_annotations_length = method_attribute_length; 8.62 runtime_visible_type_annotations = cfs->get_u1_buffer(); 8.63 assert(runtime_visible_type_annotations != NULL, "null visible type annotations"); 8.64 // No need for the VM to parse Type annotations 8.65 cfs->skip_u1(runtime_visible_type_annotations_length, CHECK_(nullHandle)); 8.66 - } else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) { 8.67 - runtime_invisible_type_annotations_length = method_attribute_length; 8.68 - runtime_invisible_type_annotations = cfs->get_u1_buffer(); 8.69 - assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); 8.70 - cfs->skip_u1(runtime_invisible_type_annotations_length, CHECK_(nullHandle)); 8.71 + } else if (method_attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) { 8.72 + if (runtime_invisible_type_annotations_exists) { 8.73 + classfile_parse_error( 8.74 + "Multiple RuntimeInvisibleTypeAnnotations attributes for method in class file %s", 8.75 + CHECK_(nullHandle)); 8.76 + } else { 8.77 + runtime_invisible_type_annotations_exists = true; 8.78 + } 8.79 + if (PreserveAllAnnotations) { 8.80 + runtime_invisible_type_annotations_length = method_attribute_length; 8.81 + runtime_invisible_type_annotations = cfs->get_u1_buffer(); 8.82 + assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); 8.83 + } 8.84 + cfs->skip_u1(method_attribute_length, CHECK_(nullHandle)); 8.85 } else { 8.86 // Skip unknown attributes 8.87 cfs->skip_u1(method_attribute_length, CHECK_(nullHandle)); 8.88 @@ -2824,6 +2852,7 @@ 8.89 int runtime_visible_type_annotations_length = 0; 8.90 u1* runtime_invisible_type_annotations = NULL; 8.91 int runtime_invisible_type_annotations_length = 0; 8.92 + bool runtime_invisible_type_annotations_exists = false; 8.93 u1* inner_classes_attribute_start = NULL; 8.94 u4 inner_classes_attribute_length = 0; 8.95 u2 enclosing_method_class_index = 0; 8.96 @@ -2927,16 +2956,28 @@ 8.97 parsed_bootstrap_methods_attribute = true; 8.98 parse_classfile_bootstrap_methods_attribute(attribute_length, CHECK); 8.99 } else if (tag == vmSymbols::tag_runtime_visible_type_annotations()) { 8.100 + if (runtime_visible_type_annotations != NULL) { 8.101 + classfile_parse_error( 8.102 + "Multiple RuntimeVisibleTypeAnnotations attributes in class file %s", CHECK); 8.103 + } 8.104 runtime_visible_type_annotations_length = attribute_length; 8.105 runtime_visible_type_annotations = cfs->get_u1_buffer(); 8.106 assert(runtime_visible_type_annotations != NULL, "null visible type annotations"); 8.107 // No need for the VM to parse Type annotations 8.108 cfs->skip_u1(runtime_visible_type_annotations_length, CHECK); 8.109 - } else if (PreserveAllAnnotations && tag == vmSymbols::tag_runtime_invisible_type_annotations()) { 8.110 - runtime_invisible_type_annotations_length = attribute_length; 8.111 - runtime_invisible_type_annotations = cfs->get_u1_buffer(); 8.112 - assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); 8.113 - cfs->skip_u1(runtime_invisible_type_annotations_length, CHECK); 8.114 + } else if (tag == vmSymbols::tag_runtime_invisible_type_annotations()) { 8.115 + if (runtime_invisible_type_annotations_exists) { 8.116 + classfile_parse_error( 8.117 + "Multiple RuntimeInvisibleTypeAnnotations attributes in class file %s", CHECK); 8.118 + } else { 8.119 + runtime_invisible_type_annotations_exists = true; 8.120 + } 8.121 + if (PreserveAllAnnotations) { 8.122 + runtime_invisible_type_annotations_length = attribute_length; 8.123 + runtime_invisible_type_annotations = cfs->get_u1_buffer(); 8.124 + assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); 8.125 + } 8.126 + cfs->skip_u1(attribute_length, CHECK); 8.127 } else { 8.128 // Unknown attribute 8.129 cfs->skip_u1(attribute_length, CHECK);
9.1 --- a/src/share/vm/classfile/defaultMethods.cpp Fri Sep 13 00:43:01 2013 -0700 9.2 +++ b/src/share/vm/classfile/defaultMethods.cpp Wed Sep 18 12:52:15 2013 -0400 9.3 @@ -450,6 +450,10 @@ 9.4 streamIndentor si(str, indent * 2); 9.5 str->indent().print("Selected method: "); 9.6 print_method(str, _selected_target); 9.7 + Klass* method_holder = _selected_target->method_holder(); 9.8 + if (!method_holder->is_interface()) { 9.9 + tty->print(" : in superclass"); 9.10 + } 9.11 str->print_cr(""); 9.12 } 9.13 9.14 @@ -1141,19 +1145,23 @@ 9.15 #endif // ndef PRODUCT 9.16 if (method->has_target()) { 9.17 Method* selected = method->get_selected_target(); 9.18 - max_stack = assemble_redirect( 9.19 + if (selected->method_holder()->is_interface()) { 9.20 + max_stack = assemble_redirect( 9.21 &bpool, &buffer, slot->signature(), selected, CHECK); 9.22 + } 9.23 } else if (method->throws_exception()) { 9.24 max_stack = assemble_abstract_method_error( 9.25 &bpool, &buffer, method->get_exception_message(), CHECK); 9.26 } 9.27 - AccessFlags flags = accessFlags_from( 9.28 + if (max_stack != 0) { 9.29 + AccessFlags flags = accessFlags_from( 9.30 JVM_ACC_PUBLIC | JVM_ACC_SYNTHETIC | JVM_ACC_BRIDGE); 9.31 - Method* m = new_method(&bpool, &buffer, slot->name(), slot->signature(), 9.32 + Method* m = new_method(&bpool, &buffer, slot->name(), slot->signature(), 9.33 flags, max_stack, slot->size_of_parameters(), 9.34 ConstMethod::OVERPASS, CHECK); 9.35 - if (m != NULL) { 9.36 - overpasses.push(m); 9.37 + if (m != NULL) { 9.38 + overpasses.push(m); 9.39 + } 9.40 } 9.41 } 9.42 }
10.1 --- a/src/share/vm/prims/jni.cpp Fri Sep 13 00:43:01 2013 -0700 10.2 +++ b/src/share/vm/prims/jni.cpp Wed Sep 18 12:52:15 2013 -0400 10.3 @@ -5037,6 +5037,7 @@ 10.4 #include "gc_implementation/g1/heapRegionRemSet.hpp" 10.5 #endif 10.6 #include "utilities/quickSort.hpp" 10.7 +#include "utilities/ostream.hpp" 10.8 #if INCLUDE_VM_STRUCTS 10.9 #include "runtime/vmStructs.hpp" 10.10 #endif 10.11 @@ -5060,6 +5061,7 @@ 10.12 run_unit_test(CollectedHeap::test_is_in()); 10.13 run_unit_test(QuickSort::test_quick_sort()); 10.14 run_unit_test(AltHashing::test_alt_hash()); 10.15 + run_unit_test(test_loggc_filename()); 10.16 #if INCLUDE_VM_STRUCTS 10.17 run_unit_test(VMStructs::test()); 10.18 #endif
11.1 --- a/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Sep 13 00:43:01 2013 -0700 11.2 +++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp Wed Sep 18 12:52:15 2013 -0400 11.3 @@ -1072,8 +1072,17 @@ 11.4 } 11.5 11.6 res = merge_cp_and_rewrite(the_class, scratch_class, THREAD); 11.7 - if (res != JVMTI_ERROR_NONE) { 11.8 - return res; 11.9 + if (HAS_PENDING_EXCEPTION) { 11.10 + Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); 11.11 + // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark 11.12 + RC_TRACE_WITH_THREAD(0x00000002, THREAD, 11.13 + ("merge_cp_and_rewrite exception: '%s'", ex_name->as_C_string())); 11.14 + CLEAR_PENDING_EXCEPTION; 11.15 + if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) { 11.16 + return JVMTI_ERROR_OUT_OF_MEMORY; 11.17 + } else { 11.18 + return JVMTI_ERROR_INTERNAL; 11.19 + } 11.20 } 11.21 11.22 if (VerifyMergedCPBytecodes) { 11.23 @@ -1105,6 +1114,9 @@ 11.24 } 11.25 if (HAS_PENDING_EXCEPTION) { 11.26 Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); 11.27 + // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark 11.28 + RC_TRACE_WITH_THREAD(0x00000002, THREAD, 11.29 + ("Rewriter::rewrite or link_methods exception: '%s'", ex_name->as_C_string())); 11.30 CLEAR_PENDING_EXCEPTION; 11.31 if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) { 11.32 return JVMTI_ERROR_OUT_OF_MEMORY; 11.33 @@ -1395,8 +1407,8 @@ 11.34 ClassLoaderData* loader_data = the_class->class_loader_data(); 11.35 ConstantPool* merge_cp_oop = 11.36 ConstantPool::allocate(loader_data, 11.37 - merge_cp_length, 11.38 - THREAD); 11.39 + merge_cp_length, 11.40 + CHECK_(JVMTI_ERROR_OUT_OF_MEMORY)); 11.41 MergeCPCleaner cp_cleaner(loader_data, merge_cp_oop); 11.42 11.43 HandleMark hm(THREAD); // make sure handles are cleared before 11.44 @@ -1472,7 +1484,8 @@ 11.45 11.46 // Replace the new constant pool with a shrunken copy of the 11.47 // merged constant pool 11.48 - set_new_constant_pool(loader_data, scratch_class, merge_cp, merge_cp_length, THREAD); 11.49 + set_new_constant_pool(loader_data, scratch_class, merge_cp, merge_cp_length, 11.50 + CHECK_(JVMTI_ERROR_OUT_OF_MEMORY)); 11.51 // The new constant pool replaces scratch_cp so have cleaner clean it up. 11.52 // It can't be cleaned up while there are handles to it. 11.53 cp_cleaner.add_scratch_cp(scratch_cp()); 11.54 @@ -1502,7 +1515,8 @@ 11.55 // merged constant pool so now the rewritten bytecodes have 11.56 // valid references; the previous new constant pool will get 11.57 // GCed. 11.58 - set_new_constant_pool(loader_data, scratch_class, merge_cp, merge_cp_length, THREAD); 11.59 + set_new_constant_pool(loader_data, scratch_class, merge_cp, merge_cp_length, 11.60 + CHECK_(JVMTI_ERROR_OUT_OF_MEMORY)); 11.61 // The new constant pool replaces scratch_cp so have cleaner clean it up. 11.62 // It can't be cleaned up while there are handles to it. 11.63 cp_cleaner.add_scratch_cp(scratch_cp()); 11.64 @@ -1590,11 +1604,23 @@ 11.65 for (int i = methods->length() - 1; i >= 0; i--) { 11.66 methodHandle method(THREAD, methods->at(i)); 11.67 methodHandle new_method; 11.68 - rewrite_cp_refs_in_method(method, &new_method, CHECK_false); 11.69 + rewrite_cp_refs_in_method(method, &new_method, THREAD); 11.70 if (!new_method.is_null()) { 11.71 // the method has been replaced so save the new method version 11.72 + // even in the case of an exception. original method is on the 11.73 + // deallocation list. 11.74 methods->at_put(i, new_method()); 11.75 } 11.76 + if (HAS_PENDING_EXCEPTION) { 11.77 + Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); 11.78 + // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark 11.79 + RC_TRACE_WITH_THREAD(0x00000002, THREAD, 11.80 + ("rewrite_cp_refs_in_method exception: '%s'", ex_name->as_C_string())); 11.81 + // Need to clear pending exception here as the super caller sets 11.82 + // the JVMTI_ERROR_INTERNAL if the returned value is false. 11.83 + CLEAR_PENDING_EXCEPTION; 11.84 + return false; 11.85 + } 11.86 } 11.87 11.88 return true; 11.89 @@ -1674,10 +1700,7 @@ 11.90 Pause_No_Safepoint_Verifier pnsv(&nsv); 11.91 11.92 // ldc is 2 bytes and ldc_w is 3 bytes 11.93 - m = rc.insert_space_at(bci, 3, inst_buffer, THREAD); 11.94 - if (m.is_null() || HAS_PENDING_EXCEPTION) { 11.95 - guarantee(false, "insert_space_at() failed"); 11.96 - } 11.97 + m = rc.insert_space_at(bci, 3, inst_buffer, CHECK); 11.98 } 11.99 11.100 // return the new method so that the caller can update 11.101 @@ -2487,8 +2510,8 @@ 11.102 // scratch_cp is a merged constant pool and has enough space for a 11.103 // worst case merge situation. We want to associate the minimum 11.104 // sized constant pool with the klass to save space. 11.105 - constantPoolHandle smaller_cp(THREAD, 11.106 - ConstantPool::allocate(loader_data, scratch_cp_length, THREAD)); 11.107 + ConstantPool* cp = ConstantPool::allocate(loader_data, scratch_cp_length, CHECK); 11.108 + constantPoolHandle smaller_cp(THREAD, cp); 11.109 11.110 // preserve version() value in the smaller copy 11.111 int version = scratch_cp->version(); 11.112 @@ -2500,6 +2523,11 @@ 11.113 smaller_cp->set_pool_holder(scratch_class()); 11.114 11.115 scratch_cp->copy_cp_to(1, scratch_cp_length - 1, smaller_cp, 1, THREAD); 11.116 + if (HAS_PENDING_EXCEPTION) { 11.117 + // Exception is handled in the caller 11.118 + loader_data->add_to_deallocate_list(smaller_cp()); 11.119 + return; 11.120 + } 11.121 scratch_cp = smaller_cp; 11.122 11.123 // attach new constant pool to klass
12.1 --- a/src/share/vm/runtime/arguments.cpp Fri Sep 13 00:43:01 2013 -0700 12.2 +++ b/src/share/vm/runtime/arguments.cpp Wed Sep 18 12:52:15 2013 -0400 12.3 @@ -1839,7 +1839,7 @@ 12.4 (NumberOfGCLogFiles == 0) || 12.5 (GCLogFileSize == 0)) { 12.6 jio_fprintf(defaultStream::output_stream(), 12.7 - "To enable GC log rotation, use -Xloggc:<filename> -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=<num_of_files> -XX:GCLogFileSize=<num_of_size>\n" 12.8 + "To enable GC log rotation, use -Xloggc:<filename> -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=<num_of_files> -XX:GCLogFileSize=<num_of_size>[k|K|m|M|g|G]\n" 12.9 "where num_of_file > 0 and num_of_size > 0\n" 12.10 "GC log rotation is turned off\n"); 12.11 UseGCLogFileRotation = false; 12.12 @@ -1853,6 +1853,51 @@ 12.13 } 12.14 } 12.15 12.16 +// This function is called for -Xloggc:<filename>, it can be used 12.17 +// to check if a given file name(or string) conforms to the following 12.18 +// specification: 12.19 +// A valid string only contains "[A-Z][a-z][0-9].-_%[p|t]" 12.20 +// %p and %t only allowed once. We only limit usage of filename not path 12.21 +bool is_filename_valid(const char *file_name) { 12.22 + const char* p = file_name; 12.23 + char file_sep = os::file_separator()[0]; 12.24 + const char* cp; 12.25 + // skip prefix path 12.26 + for (cp = file_name; *cp != '\0'; cp++) { 12.27 + if (*cp == '/' || *cp == file_sep) { 12.28 + p = cp + 1; 12.29 + } 12.30 + } 12.31 + 12.32 + int count_p = 0; 12.33 + int count_t = 0; 12.34 + while (*p != '\0') { 12.35 + if ((*p >= '0' && *p <= '9') || 12.36 + (*p >= 'A' && *p <= 'Z') || 12.37 + (*p >= 'a' && *p <= 'z') || 12.38 + *p == '-' || 12.39 + *p == '_' || 12.40 + *p == '.') { 12.41 + p++; 12.42 + continue; 12.43 + } 12.44 + if (*p == '%') { 12.45 + if(*(p + 1) == 'p') { 12.46 + p += 2; 12.47 + count_p ++; 12.48 + continue; 12.49 + } 12.50 + if (*(p + 1) == 't') { 12.51 + p += 2; 12.52 + count_t ++; 12.53 + continue; 12.54 + } 12.55 + } 12.56 + return false; 12.57 + } 12.58 + return count_p < 2 && count_t < 2; 12.59 +} 12.60 + 12.61 // Check consistency of GC selection 12.62 bool Arguments::check_gc_consistency() { 12.63 check_gclog_consistency(); 12.64 @@ -2806,6 +2851,13 @@ 12.65 // ostream_init_log(), when called will use this filename 12.66 // to initialize a fileStream. 12.67 _gc_log_filename = strdup(tail); 12.68 + if (!is_filename_valid(_gc_log_filename)) { 12.69 + jio_fprintf(defaultStream::output_stream(), 12.70 + "Invalid file name for use with -Xloggc: Filename can only contain the " 12.71 + "characters [A-Z][a-z][0-9]-_.%%[p|t] but it has been %s\n" 12.72 + "Note %%p or %%t can only be used once\n", _gc_log_filename); 12.73 + return JNI_EINVAL; 12.74 + } 12.75 FLAG_SET_CMDLINE(bool, PrintGC, true); 12.76 FLAG_SET_CMDLINE(bool, PrintGCTimeStamps, true); 12.77
13.1 --- a/src/share/vm/runtime/frame.cpp Fri Sep 13 00:43:01 2013 -0700 13.2 +++ b/src/share/vm/runtime/frame.cpp Wed Sep 18 12:52:15 2013 -0400 13.3 @@ -652,7 +652,7 @@ 13.4 // Return whether the frame is in the VM or os indicating a Hotspot problem. 13.5 // Otherwise, it's likely a bug in the native library that the Java code calls, 13.6 // hopefully indicating where to submit bugs. 13.7 -static void print_C_frame(outputStream* st, char* buf, int buflen, address pc) { 13.8 +void frame::print_C_frame(outputStream* st, char* buf, int buflen, address pc) { 13.9 // C/C++ frame 13.10 bool in_vm = os::address_is_in_vm(pc); 13.11 st->print(in_vm ? "V" : "C");
14.1 --- a/src/share/vm/runtime/frame.hpp Fri Sep 13 00:43:01 2013 -0700 14.2 +++ b/src/share/vm/runtime/frame.hpp Wed Sep 18 12:52:15 2013 -0400 14.3 @@ -406,6 +406,7 @@ 14.4 void print_on(outputStream* st) const; 14.5 void interpreter_frame_print_on(outputStream* st) const; 14.6 void print_on_error(outputStream* st, char* buf, int buflen, bool verbose = false) const; 14.7 + static void print_C_frame(outputStream* st, char* buf, int buflen, address pc); 14.8 14.9 // Add annotated descriptions of memory locations belonging to this frame to values 14.10 void describe(FrameValues& values, int frame_no);
15.1 --- a/src/share/vm/runtime/os.hpp Fri Sep 13 00:43:01 2013 -0700 15.2 +++ b/src/share/vm/runtime/os.hpp Wed Sep 18 12:52:15 2013 -0400 15.3 @@ -795,6 +795,14 @@ 15.4 #endif 15.5 15.6 public: 15.7 +#ifndef PLATFORM_PRINT_NATIVE_STACK 15.8 + // No platform-specific code for printing the native stack. 15.9 + static bool platform_print_native_stack(outputStream* st, void* context, 15.10 + char *buf, int buf_size) { 15.11 + return false; 15.12 + } 15.13 +#endif 15.14 + 15.15 // debugging support (mostly used by debug.cpp but also fatal error handler) 15.16 static bool find(address pc, outputStream* st = tty); // OS specific function to make sense out of an address 15.17
16.1 --- a/src/share/vm/runtime/thread.cpp Fri Sep 13 00:43:01 2013 -0700 16.2 +++ b/src/share/vm/runtime/thread.cpp Wed Sep 18 12:52:15 2013 -0400 16.3 @@ -333,6 +333,8 @@ 16.4 // Reclaim the objectmonitors from the omFreeList of the moribund thread. 16.5 ObjectSynchronizer::omFlush (this) ; 16.6 16.7 + EVENT_THREAD_DESTRUCT(this); 16.8 + 16.9 // stack_base can be NULL if the thread is never started or exited before 16.10 // record_stack_base_and_size called. Although, we would like to ensure 16.11 // that all started threads do call record_stack_base_and_size(), there is
17.1 --- a/src/share/vm/services/gcNotifier.cpp Fri Sep 13 00:43:01 2013 -0700 17.2 +++ b/src/share/vm/services/gcNotifier.cpp Wed Sep 18 12:52:15 2013 -0400 17.3 @@ -209,7 +209,7 @@ 17.4 GCNotificationRequest *request = getRequest(); 17.5 if (request != NULL) { 17.6 NotificationMark nm(request); 17.7 - Handle objGcInfo = createGcInfo(request->gcManager, request->gcStatInfo, THREAD); 17.8 + Handle objGcInfo = createGcInfo(request->gcManager, request->gcStatInfo, CHECK); 17.9 17.10 Handle objName = java_lang_String::create_from_str(request->gcManager->name(), CHECK); 17.11 Handle objAction = java_lang_String::create_from_str(request->gcAction, CHECK);
18.1 --- a/src/share/vm/services/memPtr.cpp Fri Sep 13 00:43:01 2013 -0700 18.2 +++ b/src/share/vm/services/memPtr.cpp Wed Sep 18 12:52:15 2013 -0400 18.3 @@ -1,5 +1,5 @@ 18.4 /* 18.5 - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. 18.6 + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 18.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 18.8 * 18.9 * This code is free software; you can redistribute it and/or modify it 18.10 @@ -34,9 +34,9 @@ 18.11 jint seq = Atomic::add(1, &_seq_number); 18.12 if (seq < 0) { 18.13 MemTracker::shutdown(MemTracker::NMT_sequence_overflow); 18.14 + } else { 18.15 + NOT_PRODUCT(_max_seq_number = (seq > _max_seq_number) ? seq : _max_seq_number;) 18.16 } 18.17 - assert(seq > 0, "counter overflow"); 18.18 - NOT_PRODUCT(_max_seq_number = (seq > _max_seq_number) ? seq : _max_seq_number;) 18.19 return seq; 18.20 } 18.21
19.1 --- a/src/share/vm/trace/traceMacros.hpp Fri Sep 13 00:43:01 2013 -0700 19.2 +++ b/src/share/vm/trace/traceMacros.hpp Wed Sep 18 12:52:15 2013 -0400 19.3 @@ -26,6 +26,7 @@ 19.4 #define SHARE_VM_TRACE_TRACE_MACRO_HPP 19.5 19.6 #define EVENT_THREAD_EXIT(thread) 19.7 +#define EVENT_THREAD_DESTRUCT(thread) 19.8 19.9 #define TRACE_INIT_ID(k) 19.10 #define TRACE_DATA TraceThreadData
20.1 --- a/src/share/vm/utilities/decoder.cpp Fri Sep 13 00:43:01 2013 -0700 20.2 +++ b/src/share/vm/utilities/decoder.cpp Wed Sep 18 12:52:15 2013 -0400 20.3 @@ -24,7 +24,6 @@ 20.4 20.5 #include "precompiled.hpp" 20.6 #include "prims/jvm.h" 20.7 -#include "runtime/mutexLocker.hpp" 20.8 #include "runtime/os.hpp" 20.9 #include "utilities/decoder.hpp" 20.10 #include "utilities/vmError.hpp" 20.11 @@ -80,6 +79,23 @@ 20.12 return decoder; 20.13 } 20.14 20.15 +inline bool DecoderLocker::is_first_error_thread() { 20.16 + return (os::current_thread_id() == VMError::get_first_error_tid()); 20.17 +} 20.18 + 20.19 +DecoderLocker::DecoderLocker() : 20.20 + MutexLockerEx(DecoderLocker::is_first_error_thread() ? 20.21 + NULL : Decoder::shared_decoder_lock(), true) { 20.22 + _decoder = is_first_error_thread() ? 20.23 + Decoder::get_error_handler_instance() : Decoder::get_shared_instance(); 20.24 + assert(_decoder != NULL, "null decoder"); 20.25 +} 20.26 + 20.27 +Mutex* Decoder::shared_decoder_lock() { 20.28 + assert(_shared_decoder_lock != NULL, "Just check"); 20.29 + return _shared_decoder_lock; 20.30 +} 20.31 + 20.32 bool Decoder::decode(address addr, char* buf, int buflen, int* offset, const char* modulepath) { 20.33 assert(_shared_decoder_lock != NULL, "Just check"); 20.34 bool error_handling_thread = os::current_thread_id() == VMError::first_error_tid;
21.1 --- a/src/share/vm/utilities/decoder.hpp Fri Sep 13 00:43:01 2013 -0700 21.2 +++ b/src/share/vm/utilities/decoder.hpp Wed Sep 18 12:52:15 2013 -0400 21.3 @@ -28,6 +28,7 @@ 21.4 21.5 #include "memory/allocation.hpp" 21.6 #include "runtime/mutex.hpp" 21.7 +#include "runtime/mutexLocker.hpp" 21.8 21.9 class AbstractDecoder : public CHeapObj<mtInternal> { 21.10 public: 21.11 @@ -124,6 +125,19 @@ 21.12 21.13 protected: 21.14 static Mutex* _shared_decoder_lock; 21.15 + static Mutex* shared_decoder_lock(); 21.16 + 21.17 + friend class DecoderLocker; 21.18 +}; 21.19 + 21.20 +class DecoderLocker : public MutexLockerEx { 21.21 + AbstractDecoder* _decoder; 21.22 + inline bool is_first_error_thread(); 21.23 +public: 21.24 + DecoderLocker(); 21.25 + AbstractDecoder* decoder() { 21.26 + return _decoder; 21.27 + } 21.28 }; 21.29 21.30 #endif // SHARE_VM_UTILITIES_DECODER_HPP
22.1 --- a/src/share/vm/utilities/ostream.cpp Fri Sep 13 00:43:01 2013 -0700 22.2 +++ b/src/share/vm/utilities/ostream.cpp Wed Sep 18 12:52:15 2013 -0400 22.3 @@ -342,7 +342,7 @@ 22.4 } 22.5 22.6 char* stringStream::as_string() { 22.7 - char* copy = NEW_RESOURCE_ARRAY(char, buffer_pos+1); 22.8 + char* copy = NEW_RESOURCE_ARRAY(char, buffer_pos + 1); 22.9 strncpy(copy, buffer, buffer_pos); 22.10 copy[buffer_pos] = 0; // terminating null 22.11 return copy; 22.12 @@ -355,14 +355,190 @@ 22.13 outputStream* gclog_or_tty; 22.14 extern Mutex* tty_lock; 22.15 22.16 +#define EXTRACHARLEN 32 22.17 +#define CURRENTAPPX ".current" 22.18 +#define FILENAMEBUFLEN 1024 22.19 +// convert YYYY-MM-DD HH:MM:SS to YYYY-MM-DD_HH-MM-SS 22.20 +char* get_datetime_string(char *buf, size_t len) { 22.21 + os::local_time_string(buf, len); 22.22 + int i = (int)strlen(buf); 22.23 + while (i-- >= 0) { 22.24 + if (buf[i] == ' ') buf[i] = '_'; 22.25 + else if (buf[i] == ':') buf[i] = '-'; 22.26 + } 22.27 + return buf; 22.28 +} 22.29 + 22.30 +static const char* make_log_name_internal(const char* log_name, const char* force_directory, 22.31 + int pid, const char* tms) { 22.32 + const char* basename = log_name; 22.33 + char file_sep = os::file_separator()[0]; 22.34 + const char* cp; 22.35 + char pid_text[32]; 22.36 + 22.37 + for (cp = log_name; *cp != '\0'; cp++) { 22.38 + if (*cp == '/' || *cp == file_sep) { 22.39 + basename = cp + 1; 22.40 + } 22.41 + } 22.42 + const char* nametail = log_name; 22.43 + // Compute buffer length 22.44 + size_t buffer_length; 22.45 + if (force_directory != NULL) { 22.46 + buffer_length = strlen(force_directory) + strlen(os::file_separator()) + 22.47 + strlen(basename) + 1; 22.48 + } else { 22.49 + buffer_length = strlen(log_name) + 1; 22.50 + } 22.51 + 22.52 + // const char* star = strchr(basename, '*'); 22.53 + const char* pts = strstr(basename, "%p"); 22.54 + int pid_pos = (pts == NULL) ? -1 : (pts - nametail); 22.55 + 22.56 + if (pid_pos >= 0) { 22.57 + jio_snprintf(pid_text, sizeof(pid_text), "pid%u", pid); 22.58 + buffer_length += strlen(pid_text); 22.59 + } 22.60 + 22.61 + pts = strstr(basename, "%t"); 22.62 + int tms_pos = (pts == NULL) ? -1 : (pts - nametail); 22.63 + if (tms_pos >= 0) { 22.64 + buffer_length += strlen(tms); 22.65 + } 22.66 + 22.67 + // Create big enough buffer. 22.68 + char *buf = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal); 22.69 + 22.70 + strcpy(buf, ""); 22.71 + if (force_directory != NULL) { 22.72 + strcat(buf, force_directory); 22.73 + strcat(buf, os::file_separator()); 22.74 + nametail = basename; // completely skip directory prefix 22.75 + } 22.76 + 22.77 + // who is first, %p or %t? 22.78 + int first = -1, second = -1; 22.79 + const char *p1st = NULL; 22.80 + const char *p2nd = NULL; 22.81 + 22.82 + if (pid_pos >= 0 && tms_pos >= 0) { 22.83 + // contains both %p and %t 22.84 + if (pid_pos < tms_pos) { 22.85 + // case foo%pbar%tmonkey.log 22.86 + first = pid_pos; 22.87 + p1st = pid_text; 22.88 + second = tms_pos; 22.89 + p2nd = tms; 22.90 + } else { 22.91 + // case foo%tbar%pmonkey.log 22.92 + first = tms_pos; 22.93 + p1st = tms; 22.94 + second = pid_pos; 22.95 + p2nd = pid_text; 22.96 + } 22.97 + } else if (pid_pos >= 0) { 22.98 + // contains %p only 22.99 + first = pid_pos; 22.100 + p1st = pid_text; 22.101 + } else if (tms_pos >= 0) { 22.102 + // contains %t only 22.103 + first = tms_pos; 22.104 + p1st = tms; 22.105 + } 22.106 + 22.107 + int buf_pos = (int)strlen(buf); 22.108 + const char* tail = nametail; 22.109 + 22.110 + if (first >= 0) { 22.111 + tail = nametail + first + 2; 22.112 + strncpy(&buf[buf_pos], nametail, first); 22.113 + strcpy(&buf[buf_pos + first], p1st); 22.114 + buf_pos = (int)strlen(buf); 22.115 + if (second >= 0) { 22.116 + strncpy(&buf[buf_pos], tail, second - first - 2); 22.117 + strcpy(&buf[buf_pos + second - first - 2], p2nd); 22.118 + tail = nametail + second + 2; 22.119 + } 22.120 + } 22.121 + strcat(buf, tail); // append rest of name, or all of name 22.122 + return buf; 22.123 +} 22.124 + 22.125 +// log_name comes from -XX:LogFile=log_name or -Xloggc:log_name 22.126 +// in log_name, %p => pipd1234 and 22.127 +// %t => YYYY-MM-DD_HH-MM-SS 22.128 +static const char* make_log_name(const char* log_name, const char* force_directory) { 22.129 + char timestr[32]; 22.130 + get_datetime_string(timestr, sizeof(timestr)); 22.131 + return make_log_name_internal(log_name, force_directory, os::current_process_id(), 22.132 + timestr); 22.133 +} 22.134 + 22.135 +#ifndef PRODUCT 22.136 +void test_loggc_filename() { 22.137 + int pid; 22.138 + char tms[32]; 22.139 + char i_result[FILENAMEBUFLEN]; 22.140 + const char* o_result; 22.141 + get_datetime_string(tms, sizeof(tms)); 22.142 + pid = os::current_process_id(); 22.143 + 22.144 + // test.log 22.145 + jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "test.log", tms); 22.146 + o_result = make_log_name_internal("test.log", NULL, pid, tms); 22.147 + assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test.log\", NULL)"); 22.148 + FREE_C_HEAP_ARRAY(char, o_result, mtInternal); 22.149 + 22.150 + // test-%t-%p.log 22.151 + jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "test-%s-pid%u.log", tms, pid); 22.152 + o_result = make_log_name_internal("test-%t-%p.log", NULL, pid, tms); 22.153 + assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test-%%t-%%p.log\", NULL)"); 22.154 + FREE_C_HEAP_ARRAY(char, o_result, mtInternal); 22.155 + 22.156 + // test-%t%p.log 22.157 + jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "test-%spid%u.log", tms, pid); 22.158 + o_result = make_log_name_internal("test-%t%p.log", NULL, pid, tms); 22.159 + assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test-%%t%%p.log\", NULL)"); 22.160 + FREE_C_HEAP_ARRAY(char, o_result, mtInternal); 22.161 + 22.162 + // %p%t.log 22.163 + jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "pid%u%s.log", pid, tms); 22.164 + o_result = make_log_name_internal("%p%t.log", NULL, pid, tms); 22.165 + assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%p%%t.log\", NULL)"); 22.166 + FREE_C_HEAP_ARRAY(char, o_result, mtInternal); 22.167 + 22.168 + // %p-test.log 22.169 + jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "pid%u-test.log", pid); 22.170 + o_result = make_log_name_internal("%p-test.log", NULL, pid, tms); 22.171 + assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%p-test.log\", NULL)"); 22.172 + FREE_C_HEAP_ARRAY(char, o_result, mtInternal); 22.173 + 22.174 + // %t.log 22.175 + jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "%s.log", tms); 22.176 + o_result = make_log_name_internal("%t.log", NULL, pid, tms); 22.177 + assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%t.log\", NULL)"); 22.178 + FREE_C_HEAP_ARRAY(char, o_result, mtInternal); 22.179 +} 22.180 +#endif // PRODUCT 22.181 + 22.182 fileStream::fileStream(const char* file_name) { 22.183 _file = fopen(file_name, "w"); 22.184 - _need_close = true; 22.185 + if (_file != NULL) { 22.186 + _need_close = true; 22.187 + } else { 22.188 + warning("Cannot open file %s due to %s\n", file_name, strerror(errno)); 22.189 + _need_close = false; 22.190 + } 22.191 } 22.192 22.193 fileStream::fileStream(const char* file_name, const char* opentype) { 22.194 _file = fopen(file_name, opentype); 22.195 - _need_close = true; 22.196 + if (_file != NULL) { 22.197 + _need_close = true; 22.198 + } else { 22.199 + warning("Cannot open file %s due to %s\n", file_name, strerror(errno)); 22.200 + _need_close = false; 22.201 + } 22.202 } 22.203 22.204 void fileStream::write(const char* s, size_t len) { 22.205 @@ -423,34 +599,51 @@ 22.206 update_position(s, len); 22.207 } 22.208 22.209 -rotatingFileStream::~rotatingFileStream() { 22.210 +// dump vm version, os version, platform info, build id, 22.211 +// memory usage and command line flags into header 22.212 +void gcLogFileStream::dump_loggc_header() { 22.213 + if (is_open()) { 22.214 + print_cr(Abstract_VM_Version::internal_vm_info_string()); 22.215 + os::print_memory_info(this); 22.216 + print("CommandLine flags: "); 22.217 + CommandLineFlags::printSetFlags(this); 22.218 + } 22.219 +} 22.220 + 22.221 +gcLogFileStream::~gcLogFileStream() { 22.222 if (_file != NULL) { 22.223 if (_need_close) fclose(_file); 22.224 - _file = NULL; 22.225 + _file = NULL; 22.226 + } 22.227 + if (_file_name != NULL) { 22.228 FREE_C_HEAP_ARRAY(char, _file_name, mtInternal); 22.229 _file_name = NULL; 22.230 } 22.231 } 22.232 22.233 -rotatingFileStream::rotatingFileStream(const char* file_name) { 22.234 +gcLogFileStream::gcLogFileStream(const char* file_name) { 22.235 _cur_file_num = 0; 22.236 _bytes_written = 0L; 22.237 - _file_name = NEW_C_HEAP_ARRAY(char, strlen(file_name)+10, mtInternal); 22.238 - jio_snprintf(_file_name, strlen(file_name)+10, "%s.%d", file_name, _cur_file_num); 22.239 - _file = fopen(_file_name, "w"); 22.240 - _need_close = true; 22.241 + _file_name = make_log_name(file_name, NULL); 22.242 + 22.243 + // gc log file rotation 22.244 + if (UseGCLogFileRotation && NumberOfGCLogFiles > 1) { 22.245 + char tempbuf[FILENAMEBUFLEN]; 22.246 + jio_snprintf(tempbuf, sizeof(tempbuf), "%s.%d" CURRENTAPPX, _file_name, _cur_file_num); 22.247 + _file = fopen(tempbuf, "w"); 22.248 + } else { 22.249 + _file = fopen(_file_name, "w"); 22.250 + } 22.251 + if (_file != NULL) { 22.252 + _need_close = true; 22.253 + dump_loggc_header(); 22.254 + } else { 22.255 + warning("Cannot open file %s due to %s\n", _file_name, strerror(errno)); 22.256 + _need_close = false; 22.257 + } 22.258 } 22.259 22.260 -rotatingFileStream::rotatingFileStream(const char* file_name, const char* opentype) { 22.261 - _cur_file_num = 0; 22.262 - _bytes_written = 0L; 22.263 - _file_name = NEW_C_HEAP_ARRAY(char, strlen(file_name)+10, mtInternal); 22.264 - jio_snprintf(_file_name, strlen(file_name)+10, "%s.%d", file_name, _cur_file_num); 22.265 - _file = fopen(_file_name, opentype); 22.266 - _need_close = true; 22.267 -} 22.268 - 22.269 -void rotatingFileStream::write(const char* s, size_t len) { 22.270 +void gcLogFileStream::write(const char* s, size_t len) { 22.271 if (_file != NULL) { 22.272 size_t count = fwrite(s, 1, len, _file); 22.273 _bytes_written += count; 22.274 @@ -466,7 +659,12 @@ 22.275 // write to gc log file at safepoint. If in future, changes made for mutator threads or 22.276 // concurrent GC threads to run parallel with VMThread at safepoint, write and rotate_log 22.277 // must be synchronized. 22.278 -void rotatingFileStream::rotate_log() { 22.279 +void gcLogFileStream::rotate_log() { 22.280 + char time_msg[FILENAMEBUFLEN]; 22.281 + char time_str[EXTRACHARLEN]; 22.282 + char current_file_name[FILENAMEBUFLEN]; 22.283 + char renamed_file_name[FILENAMEBUFLEN]; 22.284 + 22.285 if (_bytes_written < (jlong)GCLogFileSize) { 22.286 return; 22.287 } 22.288 @@ -481,27 +679,89 @@ 22.289 // rotate in same file 22.290 rewind(); 22.291 _bytes_written = 0L; 22.292 + jio_snprintf(time_msg, sizeof(time_msg), "File %s rotated at %s\n", 22.293 + _file_name, os::local_time_string((char *)time_str, sizeof(time_str))); 22.294 + write(time_msg, strlen(time_msg)); 22.295 + dump_loggc_header(); 22.296 return; 22.297 } 22.298 22.299 - // rotate file in names file.0, file.1, file.2, ..., file.<MaxGCLogFileNumbers-1> 22.300 - // close current file, rotate to next file 22.301 +#if defined(_WINDOWS) 22.302 +#ifndef F_OK 22.303 +#define F_OK 0 22.304 +#endif 22.305 +#endif // _WINDOWS 22.306 + 22.307 + // rotate file in names extended_filename.0, extended_filename.1, ..., 22.308 + // extended_filename.<NumberOfGCLogFiles - 1>. Current rotation file name will 22.309 + // have a form of extended_filename.<i>.current where i is the current rotation 22.310 + // file number. After it reaches max file size, the file will be saved and renamed 22.311 + // with .current removed from its tail. 22.312 + size_t filename_len = strlen(_file_name); 22.313 if (_file != NULL) { 22.314 - _cur_file_num ++; 22.315 - if (_cur_file_num >= NumberOfGCLogFiles) _cur_file_num = 0; 22.316 - jio_snprintf(_file_name, strlen(Arguments::gc_log_filename()) + 10, "%s.%d", 22.317 - Arguments::gc_log_filename(), _cur_file_num); 22.318 + jio_snprintf(renamed_file_name, filename_len + EXTRACHARLEN, "%s.%d", 22.319 + _file_name, _cur_file_num); 22.320 + jio_snprintf(current_file_name, filename_len + EXTRACHARLEN, "%s.%d" CURRENTAPPX, 22.321 + _file_name, _cur_file_num); 22.322 + jio_snprintf(time_msg, sizeof(time_msg), "%s GC log file has reached the" 22.323 + " maximum size. Saved as %s\n", 22.324 + os::local_time_string((char *)time_str, sizeof(time_str)), 22.325 + renamed_file_name); 22.326 + write(time_msg, strlen(time_msg)); 22.327 + 22.328 fclose(_file); 22.329 _file = NULL; 22.330 + 22.331 + bool can_rename = true; 22.332 + if (access(current_file_name, F_OK) != 0) { 22.333 + // current file does not exist? 22.334 + warning("No source file exists, cannot rename\n"); 22.335 + can_rename = false; 22.336 + } 22.337 + if (can_rename) { 22.338 + if (access(renamed_file_name, F_OK) == 0) { 22.339 + if (remove(renamed_file_name) != 0) { 22.340 + warning("Could not delete existing file %s\n", renamed_file_name); 22.341 + can_rename = false; 22.342 + } 22.343 + } else { 22.344 + // file does not exist, ok to rename 22.345 + } 22.346 + } 22.347 + if (can_rename && rename(current_file_name, renamed_file_name) != 0) { 22.348 + warning("Could not rename %s to %s\n", _file_name, renamed_file_name); 22.349 + } 22.350 } 22.351 - _file = fopen(_file_name, "w"); 22.352 + 22.353 + _cur_file_num++; 22.354 + if (_cur_file_num > NumberOfGCLogFiles - 1) _cur_file_num = 0; 22.355 + jio_snprintf(current_file_name, filename_len + EXTRACHARLEN, "%s.%d" CURRENTAPPX, 22.356 + _file_name, _cur_file_num); 22.357 + _file = fopen(current_file_name, "w"); 22.358 + 22.359 if (_file != NULL) { 22.360 _bytes_written = 0L; 22.361 _need_close = true; 22.362 + // reuse current_file_name for time_msg 22.363 + jio_snprintf(current_file_name, filename_len + EXTRACHARLEN, 22.364 + "%s.%d", _file_name, _cur_file_num); 22.365 + jio_snprintf(time_msg, sizeof(time_msg), "%s GC log file created %s\n", 22.366 + os::local_time_string((char *)time_str, sizeof(time_str)), 22.367 + current_file_name); 22.368 + write(time_msg, strlen(time_msg)); 22.369 + dump_loggc_header(); 22.370 + // remove the existing file 22.371 + if (access(current_file_name, F_OK) == 0) { 22.372 + if (remove(current_file_name) != 0) { 22.373 + warning("Could not delete existing file %s\n", current_file_name); 22.374 + } 22.375 + } 22.376 } else { 22.377 - tty->print_cr("failed to open rotation log file %s due to %s\n", 22.378 + warning("failed to open rotation log file %s due to %s\n" 22.379 + "Turned off GC log file rotation\n", 22.380 _file_name, strerror(errno)); 22.381 _need_close = false; 22.382 + FLAG_SET_DEFAULT(UseGCLogFileRotation, false); 22.383 } 22.384 } 22.385 22.386 @@ -530,66 +790,6 @@ 22.387 return _log_file != NULL; 22.388 } 22.389 22.390 -static const char* make_log_name(const char* log_name, const char* force_directory) { 22.391 - const char* basename = log_name; 22.392 - char file_sep = os::file_separator()[0]; 22.393 - const char* cp; 22.394 - for (cp = log_name; *cp != '\0'; cp++) { 22.395 - if (*cp == '/' || *cp == file_sep) { 22.396 - basename = cp+1; 22.397 - } 22.398 - } 22.399 - const char* nametail = log_name; 22.400 - 22.401 - // Compute buffer length 22.402 - size_t buffer_length; 22.403 - if (force_directory != NULL) { 22.404 - buffer_length = strlen(force_directory) + strlen(os::file_separator()) + 22.405 - strlen(basename) + 1; 22.406 - } else { 22.407 - buffer_length = strlen(log_name) + 1; 22.408 - } 22.409 - 22.410 - const char* star = strchr(basename, '*'); 22.411 - int star_pos = (star == NULL) ? -1 : (star - nametail); 22.412 - int skip = 1; 22.413 - if (star == NULL) { 22.414 - // Try %p 22.415 - star = strstr(basename, "%p"); 22.416 - if (star != NULL) { 22.417 - skip = 2; 22.418 - } 22.419 - } 22.420 - star_pos = (star == NULL) ? -1 : (star - nametail); 22.421 - 22.422 - char pid[32]; 22.423 - if (star_pos >= 0) { 22.424 - jio_snprintf(pid, sizeof(pid), "%u", os::current_process_id()); 22.425 - buffer_length += strlen(pid); 22.426 - } 22.427 - 22.428 - // Create big enough buffer. 22.429 - char *buf = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal); 22.430 - 22.431 - strcpy(buf, ""); 22.432 - if (force_directory != NULL) { 22.433 - strcat(buf, force_directory); 22.434 - strcat(buf, os::file_separator()); 22.435 - nametail = basename; // completely skip directory prefix 22.436 - } 22.437 - 22.438 - if (star_pos >= 0) { 22.439 - // convert foo*bar.log or foo%pbar.log to foo123bar.log 22.440 - int buf_pos = (int) strlen(buf); 22.441 - strncpy(&buf[buf_pos], nametail, star_pos); 22.442 - strcpy(&buf[buf_pos + star_pos], pid); 22.443 - nametail += star_pos + skip; // skip prefix and pid format 22.444 - } 22.445 - 22.446 - strcat(buf, nametail); // append rest of name, or all of name 22.447 - return buf; 22.448 -} 22.449 - 22.450 void defaultStream::init_log() { 22.451 // %%% Need a MutexLocker? 22.452 const char* log_name = LogFile != NULL ? LogFile : "hotspot.log"; 22.453 @@ -877,11 +1077,8 @@ 22.454 22.455 gclog_or_tty = tty; // default to tty 22.456 if (Arguments::gc_log_filename() != NULL) { 22.457 - fileStream * gclog = UseGCLogFileRotation ? 22.458 - new(ResourceObj::C_HEAP, mtInternal) 22.459 - rotatingFileStream(Arguments::gc_log_filename()) : 22.460 - new(ResourceObj::C_HEAP, mtInternal) 22.461 - fileStream(Arguments::gc_log_filename()); 22.462 + fileStream * gclog = new(ResourceObj::C_HEAP, mtInternal) 22.463 + gcLogFileStream(Arguments::gc_log_filename()); 22.464 if (gclog->is_open()) { 22.465 // now we update the time stamp of the GC log to be synced up 22.466 // with tty.
23.1 --- a/src/share/vm/utilities/ostream.hpp Fri Sep 13 00:43:01 2013 -0700 23.2 +++ b/src/share/vm/utilities/ostream.hpp Wed Sep 18 12:52:15 2013 -0400 23.3 @@ -231,20 +231,24 @@ 23.4 void flush() {}; 23.5 }; 23.6 23.7 -class rotatingFileStream : public fileStream { 23.8 +class gcLogFileStream : public fileStream { 23.9 protected: 23.10 - char* _file_name; 23.11 + const char* _file_name; 23.12 jlong _bytes_written; 23.13 - uintx _cur_file_num; // current logfile rotation number, from 0 to MaxGCLogFileNumbers-1 23.14 + uintx _cur_file_num; // current logfile rotation number, from 0 to NumberOfGCLogFiles-1 23.15 public: 23.16 - rotatingFileStream(const char* file_name); 23.17 - rotatingFileStream(const char* file_name, const char* opentype); 23.18 - rotatingFileStream(FILE* file) : fileStream(file) {} 23.19 - ~rotatingFileStream(); 23.20 + gcLogFileStream(const char* file_name); 23.21 + ~gcLogFileStream(); 23.22 virtual void write(const char* c, size_t len); 23.23 virtual void rotate_log(); 23.24 + void dump_loggc_header(); 23.25 }; 23.26 23.27 +#ifndef PRODUCT 23.28 +// unit test for checking -Xloggc:<filename> parsing result 23.29 +void test_loggc_filename(); 23.30 +#endif 23.31 + 23.32 void ostream_init(); 23.33 void ostream_init_log(); 23.34 void ostream_exit();
24.1 --- a/src/share/vm/utilities/vmError.cpp Fri Sep 13 00:43:01 2013 -0700 24.2 +++ b/src/share/vm/utilities/vmError.cpp Wed Sep 18 12:52:15 2013 -0400 24.3 @@ -574,6 +574,10 @@ 24.4 STEP(120, "(printing native stack)" ) 24.5 24.6 if (_verbose) { 24.7 + if (os::platform_print_native_stack(st, _context, buf, sizeof(buf))) { 24.8 + // We have printed the native stack in platform-specific code 24.9 + // Windows/x64 needs special handling. 24.10 + } else { 24.11 frame fr = _context ? os::fetch_frame_from_context(_context) 24.12 : os::current_frame(); 24.13 24.14 @@ -604,6 +608,7 @@ 24.15 st->cr(); 24.16 } 24.17 } 24.18 + } 24.19 24.20 STEP(130, "(printing Java stack)" ) 24.21
25.1 --- a/src/share/vm/utilities/vmError.hpp Fri Sep 13 00:43:01 2013 -0700 25.2 +++ b/src/share/vm/utilities/vmError.hpp Wed Sep 18 12:52:15 2013 -0400 25.3 @@ -136,6 +136,10 @@ 25.4 25.5 // check to see if fatal error reporting is in progress 25.6 static bool fatal_error_in_progress() { return first_error != NULL; } 25.7 + 25.8 + static jlong get_first_error_tid() { 25.9 + return first_error_tid; 25.10 + } 25.11 }; 25.12 25.13 #endif // SHARE_VM_UTILITIES_VMERROR_HPP
26.1 --- a/test/runtime/6878713/Test6878713.sh Fri Sep 13 00:43:01 2013 -0700 26.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 26.3 @@ -1,137 +0,0 @@ 26.4 -#!/bin/sh 26.5 - 26.6 -# 26.7 -# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. 26.8 -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 26.9 -# 26.10 -# This code is free software; you can redistribute it and/or modify it 26.11 -# under the terms of the GNU General Public License version 2 only, as 26.12 -# published by the Free Software Foundation. 26.13 -# 26.14 -# This code is distributed in the hope that it will be useful, but WITHOUT 26.15 -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 26.16 -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 26.17 -# version 2 for more details (a copy is included in the LICENSE file that 26.18 -# accompanied this code). 26.19 -# 26.20 -# You should have received a copy of the GNU General Public License version 26.21 -# 2 along with this work; if not, write to the Free Software Foundation, 26.22 -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 26.23 -# 26.24 -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 26.25 -# or visit www.oracle.com if you need additional information or have any 26.26 -# questions. 26.27 -# 26.28 - 26.29 - 26.30 - 26.31 -## 26.32 -## @test 26.33 -## @bug 6878713 26.34 -## @bug 7030610 26.35 -## @bug 7037122 26.36 -## @bug 7123945 26.37 -## @summary Verifier heap corruption, relating to backward jsrs 26.38 -## @run shell Test6878713.sh 26.39 -## 26.40 -## some tests require path to find test source dir 26.41 -if [ "${TESTSRC}" = "" ] 26.42 -then 26.43 - TESTSRC=${PWD} 26.44 - echo "TESTSRC not set. Using "${TESTSRC}" as default" 26.45 -fi 26.46 -echo "TESTSRC=${TESTSRC}" 26.47 -## Adding common setup Variables for running shell tests. 26.48 -. ${TESTSRC}/../../test_env.sh 26.49 - 26.50 -TARGET_CLASS=OOMCrashClass1960_2 26.51 - 26.52 -echo "INFO: extracting the target class." 26.53 -${COMPILEJAVA}${FS}bin${FS}jar xvf \ 26.54 - ${TESTSRC}${FS}testcase.jar ${TARGET_CLASS}.class 26.55 - 26.56 -# remove any hs_err_pid that might exist here 26.57 -rm -f hs_err_pid*.log 26.58 - 26.59 -echo "INFO: checking for 32-bit versus 64-bit VM." 26.60 -${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -version 2>&1 \ 26.61 - | grep "64-Bit [^ ][^ ]* VM" > /dev/null 2>&1 26.62 -status="$?" 26.63 -if [ "$status" = 0 ]; then 26.64 - echo "INFO: testing a 64-bit VM." 26.65 - is_64_bit=true 26.66 -else 26.67 - echo "INFO: testing a 32-bit VM." 26.68 -fi 26.69 - 26.70 -if [ "$is_64_bit" = true ]; then 26.71 - # limit is 768MB in 8-byte words (1024 * 1024 * 768 / 8) == 100663296 26.72 - MALLOC_MAX=100663296 26.73 -else 26.74 - # limit is 768MB in 4-byte words (1024 * 1024 * 768 / 4) == 201326592 26.75 - MALLOC_MAX=201326592 26.76 -fi 26.77 -echo "INFO: MALLOC_MAX=$MALLOC_MAX" 26.78 - 26.79 -echo "INFO: executing the target class." 26.80 -# -XX:+PrintCommandLineFlags for debugging purposes 26.81 -# -XX:+IgnoreUnrecognizedVMOptions so test will run on a VM without 26.82 -# the new -XX:MallocMaxTestWords option 26.83 -# -XX:+UnlockDiagnosticVMOptions so we can use -XX:MallocMaxTestWords 26.84 -# -XX:MallocMaxTestWords limits malloc to $MALLOC_MAX 26.85 -${TESTJAVA}${FS}bin${FS}java \ 26.86 - -XX:+PrintCommandLineFlags \ 26.87 - -XX:+IgnoreUnrecognizedVMOptions \ 26.88 - -XX:+UnlockDiagnosticVMOptions \ 26.89 - -XX:MallocMaxTestWords=$MALLOC_MAX \ 26.90 - ${TESTVMOPTS} ${TARGET_CLASS} > test.out 2>&1 26.91 - 26.92 -echo "INFO: begin contents of test.out:" 26.93 -cat test.out 26.94 -echo "INFO: end contents of test.out." 26.95 - 26.96 -echo "INFO: checking for memory allocation error message." 26.97 -# We are looking for this specific memory allocation failure mesg so 26.98 -# we know we exercised the right allocation path with the test class: 26.99 -MESG1="Native memory allocation (malloc) failed to allocate 25696531[0-9][0-9] bytes" 26.100 -grep "$MESG1" test.out 26.101 -status="$?" 26.102 -if [ "$status" = 0 ]; then 26.103 - echo "INFO: found expected memory allocation error message." 26.104 -else 26.105 - echo "INFO: did not find expected memory allocation error message." 26.106 - 26.107 - # If we didn't find MESG1 above, then there are several scenarios: 26.108 - # 1) -XX:MallocMaxTestWords is not supported by the current VM and we 26.109 - # didn't fail TARGET_CLASS's memory allocation attempt; instead 26.110 - # we failed to find TARGET_CLASS's main() method. The TARGET_CLASS 26.111 - # is designed to provoke a memory allocation failure during class 26.112 - # loading; we actually don't care about running the class which is 26.113 - # why it doesn't have a main() method. 26.114 - # 2) we failed a memory allocation, but not the one we were looking 26.115 - # so it might be that TARGET_CLASS no longer tickles the same 26.116 - # memory allocation code path 26.117 - # 3) TARGET_CLASS reproduces the failure mode (SIGSEGV) fixed by 26.118 - # 6878713 because the test is running on a pre-fix VM. 26.119 - echo "INFO: checking for no main() method message." 26.120 - MESG2="Error: Main method not found in class" 26.121 - grep "$MESG2" test.out 26.122 - status="$?" 26.123 - if [ "$status" = 0 ]; then 26.124 - echo "INFO: found no main() method message." 26.125 - else 26.126 - echo "FAIL: did not find no main() method message." 26.127 - # status is non-zero for exit below 26.128 - 26.129 - if [ -s hs_err_pid*.log ]; then 26.130 - echo "INFO: begin contents of hs_err_pid file:" 26.131 - cat hs_err_pid*.log 26.132 - echo "INFO: end contents of hs_err_pid file." 26.133 - fi 26.134 - fi 26.135 -fi 26.136 - 26.137 -if [ "$status" = 0 ]; then 26.138 - echo "PASS: test found one of the expected messages." 26.139 -fi 26.140 -exit "$status"
27.1 Binary file test/runtime/6878713/testcase.jar has changed
28.1 --- a/test/runtime/7020373/Test7020373.sh Fri Sep 13 00:43:01 2013 -0700 28.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 28.3 @@ -1,43 +0,0 @@ 28.4 -#!/bin/sh 28.5 - 28.6 -## 28.7 -## @test 28.8 -## @bug 7020373 7055247 7053586 7185550 28.9 -## @key cte_test 28.10 -## @summary JSR rewriting can overflow memory address size variables 28.11 -## @ignore Ignore it as 7053586 test uses lots of memory. See bug report for detail. 28.12 -## @run shell Test7020373.sh 28.13 -## 28.14 - 28.15 -if [ "${TESTSRC}" = "" ] 28.16 -then 28.17 - TESTSRC=${PWD} 28.18 - echo "TESTSRC not set. Using "${TESTSRC}" as default" 28.19 -fi 28.20 -echo "TESTSRC=${TESTSRC}" 28.21 -## Adding common setup Variables for running shell tests. 28.22 -. ${TESTSRC}/../../test_env.sh 28.23 - 28.24 -${COMPILEJAVA}${FS}bin${FS}jar xvf ${TESTSRC}${FS}testcase.jar 28.25 - 28.26 -${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} OOMCrashClass4000_1 > test.out 2>&1 28.27 - 28.28 -cat test.out 28.29 - 28.30 -egrep "SIGSEGV|An unexpected error has been detected" test.out 28.31 - 28.32 -if [ $? = 0 ] 28.33 -then 28.34 - echo "Test Failed" 28.35 - exit 1 28.36 -else 28.37 - egrep "java.lang.LinkageError|java.lang.NoSuchMethodError|Main method not found in class OOMCrashClass4000_1|insufficient memory" test.out 28.38 - if [ $? = 0 ] 28.39 - then 28.40 - echo "Test Passed" 28.41 - exit 0 28.42 - else 28.43 - echo "Test Failed" 28.44 - exit 1 28.45 - fi 28.46 -fi
29.1 Binary file test/runtime/7020373/testcase.jar has changed
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 30.2 +++ b/test/runtime/ClassFile/JsrRewriting.java Wed Sep 18 12:52:15 2013 -0400 30.3 @@ -0,0 +1,102 @@ 30.4 +/* 30.5 + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. 30.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 30.7 + * 30.8 + * This code is free software; you can redistribute it and/or modify it 30.9 + * under the terms of the GNU General Public License version 2 only, as 30.10 + * published by the Free Software Foundation. 30.11 + * 30.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 30.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 30.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 30.15 + * version 2 for more details (a copy is included in the LICENSE file that 30.16 + * accompanied this code). 30.17 + * 30.18 + * You should have received a copy of the GNU General Public License version 30.19 + * 2 along with this work; if not, write to the Free Software Foundation, 30.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 30.21 + * 30.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 30.23 + * or visit www.oracle.com if you need additional information or have any 30.24 + * questions. 30.25 + */ 30.26 + 30.27 + 30.28 + 30.29 +/* 30.30 + * @test JsrRewriting 30.31 + * @summary JSR (jump local subroutine) 30.32 + * rewriting can overflow memory address size variables 30.33 + * @bug 7020373 30.34 + * @bug 7055247 30.35 + * @bug 7053586 30.36 + * @bug 7185550 30.37 + * @bug 7149464 30.38 + * @key cte_test 30.39 + * @library /testlibrary 30.40 + * @run main JsrRewriting 30.41 + */ 30.42 + 30.43 +import com.oracle.java.testlibrary.*; 30.44 +import java.io.File; 30.45 + 30.46 +public class JsrRewriting { 30.47 + 30.48 + public static void main(String[] args) throws Exception { 30.49 + 30.50 + // ======= Configure the test 30.51 + String jarFile = System.getProperty("test.src") + 30.52 + File.separator + "JsrRewritingTestCase.jar"; 30.53 + String className = "OOMCrashClass4000_1"; 30.54 + 30.55 + // limit is 768MB in native words 30.56 + int mallocMaxTestWords = (1024 * 1024 * 768 / 4); 30.57 + if (Platform.is64bit()) 30.58 + mallocMaxTestWords = (mallocMaxTestWords / 2); 30.59 + 30.60 + // ======= extract the test class 30.61 + ProcessBuilder pb = new ProcessBuilder(new String[] { 30.62 + JDKToolFinder.getJDKTool("jar"), 30.63 + "xvf", jarFile } ); 30.64 + OutputAnalyzer output = new OutputAnalyzer(pb.start()); 30.65 + output.shouldHaveExitValue(0); 30.66 + 30.67 + // ======= execute the test 30.68 + pb = ProcessTools.createJavaProcessBuilder( 30.69 + "-cp", ".", 30.70 + "-XX:+UnlockDiagnosticVMOptions", 30.71 + "-XX:MallocMaxTestWords=" + mallocMaxTestWords, 30.72 + className); 30.73 + 30.74 + output = new OutputAnalyzer(pb.start()); 30.75 + String[] expectedMsgs = { 30.76 + "java.lang.LinkageError", 30.77 + "java.lang.NoSuchMethodError", 30.78 + "Main method not found in class " + className, 30.79 + "insufficient memory" 30.80 + }; 30.81 + 30.82 + MultipleOrMatch(output, expectedMsgs); 30.83 + } 30.84 + 30.85 + private static void 30.86 + MultipleOrMatch(OutputAnalyzer analyzer, String[] whatToMatch) { 30.87 + String output = analyzer.getOutput(); 30.88 + 30.89 + for (String expected : whatToMatch) 30.90 + if (output.contains(expected)) 30.91 + return; 30.92 + 30.93 + String err = 30.94 + " stdout: [" + analyzer.getOutput() + "];\n" + 30.95 + " exitValue = " + analyzer.getExitValue() + "\n"; 30.96 + System.err.println(err); 30.97 + 30.98 + StringBuilder msg = new StringBuilder("Output did not contain " + 30.99 + "any of the following expected messages: \n"); 30.100 + for (String expected : whatToMatch) 30.101 + msg.append(expected).append(System.lineSeparator()); 30.102 + throw new RuntimeException(msg.toString()); 30.103 + } 30.104 +} 30.105 +
31.1 Binary file test/runtime/ClassFile/JsrRewritingTestCase.jar has changed
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 32.2 +++ b/test/runtime/ClassFile/OomWhileParsingRepeatedJsr.java Wed Sep 18 12:52:15 2013 -0400 32.3 @@ -0,0 +1,74 @@ 32.4 +/* 32.5 + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. 32.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 32.7 + * 32.8 + * This code is free software; you can redistribute it and/or modify it 32.9 + * under the terms of the GNU General Public License version 2 only, as 32.10 + * published by the Free Software Foundation. 32.11 + * 32.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 32.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 32.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 32.15 + * version 2 for more details (a copy is included in the LICENSE file that 32.16 + * accompanied this code). 32.17 + * 32.18 + * You should have received a copy of the GNU General Public License version 32.19 + * 2 along with this work; if not, write to the Free Software Foundation, 32.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 32.21 + * 32.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 32.23 + * or visit www.oracle.com if you need additional information or have any 32.24 + * questions. 32.25 + */ 32.26 + 32.27 + 32.28 + 32.29 +/* 32.30 + * @test OomWhileParsingRepeatedJsr 32.31 + * @summary Testing class file parser; specifically parsing 32.32 + * a file with repeated JSR (jump local subroutine) 32.33 + * bytecode command. 32.34 + * @bug 6878713 32.35 + * @bug 7030610 32.36 + * @bug 7037122 32.37 + * @bug 7123945 32.38 + * @bug 8016029 32.39 + * @library /testlibrary 32.40 + * @run main OomWhileParsingRepeatedJsr 32.41 + */ 32.42 + 32.43 +import com.oracle.java.testlibrary.*; 32.44 + 32.45 + 32.46 +public class OomWhileParsingRepeatedJsr { 32.47 + 32.48 + public static void main(String[] args) throws Exception { 32.49 + 32.50 + // ======= Configure the test 32.51 + String jarFile = System.getProperty("test.src") + "/testcase.jar"; 32.52 + String className = "OOMCrashClass1960_2"; 32.53 + 32.54 + // limit is 768MB in native words 32.55 + int mallocMaxTestWords = (1024 * 1024 * 768 / 4); 32.56 + if (Platform.is64bit()) 32.57 + mallocMaxTestWords = (mallocMaxTestWords / 2); 32.58 + 32.59 + // ======= extract the test class 32.60 + ProcessBuilder pb = new ProcessBuilder(new String[] { 32.61 + JDKToolFinder.getJDKTool("jar"), 32.62 + "xvf", jarFile } ); 32.63 + OutputAnalyzer output = new OutputAnalyzer(pb.start()); 32.64 + output.shouldHaveExitValue(0); 32.65 + 32.66 + // ======= execute the test 32.67 + pb = ProcessTools.createJavaProcessBuilder( 32.68 + "-cp", ".", 32.69 + "-XX:+UnlockDiagnosticVMOptions", 32.70 + "-XX:MallocMaxTestWords=" + mallocMaxTestWords, 32.71 + className ); 32.72 + 32.73 + output = new OutputAnalyzer(pb.start()); 32.74 + output.shouldContain("Cannot reserve enough memory"); 32.75 + } 32.76 +} 32.77 +
33.1 Binary file test/runtime/ClassFile/testcase.jar has changed
34.1 --- a/test/runtime/InitialThreadOverflow/testme.sh Fri Sep 13 00:43:01 2013 -0700 34.2 +++ b/test/runtime/InitialThreadOverflow/testme.sh Wed Sep 18 12:52:15 2013 -0400 34.3 @@ -43,9 +43,9 @@ 34.4 exit 0 34.5 fi 34.6 34.7 -gcc_cmd=`which gcc` 34.8 -if [ "x$gcc_cmd" == "x" ]; then 34.9 - echo "WARNING: gcc not found. Cannot execute test." 2>&1 34.10 +gcc_cmd=`which g++` 34.11 +if [ "x$gcc_cmd" = "x" ]; then 34.12 + echo "WARNING: g++ not found. Cannot execute test." 2>&1 34.13 exit 0; 34.14 fi 34.15