Merge

Wed, 18 Sep 2013 12:52:15 -0400

author
zgu
date
Wed, 18 Sep 2013 12:52:15 -0400
changeset 5687
41e6ae9f6dd7
parent 5665
e42e456fbe6e
parent 5686
6f45933aef35
child 5693
cc5b40a76049
child 5720
06ae47d9d088

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  

mercurial