8012260: ciReplay: Include PID into the name of replay data file

Thu, 25 Apr 2013 11:02:32 -0700

author
vlivanov
date
Thu, 25 Apr 2013 11:02:32 -0700
changeset 5027
e12c9b3740db
parent 4973
47766e2d2527
child 5028
dc7db03f5aa2

8012260: ciReplay: Include PID into the name of replay data file
Reviewed-by: kvn, twisti

src/os/bsd/vm/os_bsd.cpp file | annotate | diff | comparison | revisions
src/os/linux/vm/os_linux.cpp file | annotate | diff | comparison | revisions
src/os/posix/vm/os_posix.cpp file | annotate | diff | comparison | revisions
src/os/solaris/vm/os_solaris.cpp file | annotate | diff | comparison | revisions
src/os/windows/vm/os_windows.cpp file | annotate | diff | comparison | revisions
src/share/vm/ci/ciEnv.cpp file | annotate | diff | comparison | revisions
src/share/vm/ci/ciEnv.hpp file | annotate | diff | comparison | revisions
src/share/vm/ci/ciReplay.cpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/globals.hpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/os.hpp file | annotate | diff | comparison | revisions
src/share/vm/utilities/ostream.hpp file | annotate | diff | comparison | revisions
src/share/vm/utilities/vmError.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/os/bsd/vm/os_bsd.cpp	Wed Apr 24 18:20:04 2013 -0400
     1.2 +++ b/src/os/bsd/vm/os_bsd.cpp	Thu Apr 25 11:02:32 2013 -0700
     1.3 @@ -1230,10 +1230,6 @@
     1.4    return retval;
     1.5  }
     1.6  
     1.7 -const char* os::get_current_directory(char *buf, int buflen) {
     1.8 -  return getcwd(buf, buflen);
     1.9 -}
    1.10 -
    1.11  // check if addr is inside libjvm.so
    1.12  bool os::address_is_in_vm(address addr) {
    1.13    static address libjvm_base_addr;
     2.1 --- a/src/os/linux/vm/os_linux.cpp	Wed Apr 24 18:20:04 2013 -0400
     2.2 +++ b/src/os/linux/vm/os_linux.cpp	Thu Apr 25 11:02:32 2013 -0700
     2.3 @@ -1662,10 +1662,6 @@
     2.4    return retval;
     2.5  }
     2.6  
     2.7 -const char* os::get_current_directory(char *buf, int buflen) {
     2.8 -  return getcwd(buf, buflen);
     2.9 -}
    2.10 -
    2.11  // check if addr is inside libjvm.so
    2.12  bool os::address_is_in_vm(address addr) {
    2.13    static address libjvm_base_addr;
     3.1 --- a/src/os/posix/vm/os_posix.cpp	Wed Apr 24 18:20:04 2013 -0400
     3.2 +++ b/src/os/posix/vm/os_posix.cpp	Thu Apr 25 11:02:32 2013 -0700
     3.3 @@ -251,3 +251,11 @@
     3.4    return true;
     3.5  #endif
     3.6  }
     3.7 +
     3.8 +const char* os::get_current_directory(char *buf, size_t buflen) {
     3.9 +  return getcwd(buf, buflen);
    3.10 +}
    3.11 +
    3.12 +FILE* os::open(int fd, const char* mode) {
    3.13 +  return ::fdopen(fd, mode);
    3.14 +}
     4.1 --- a/src/os/solaris/vm/os_solaris.cpp	Wed Apr 24 18:20:04 2013 -0400
     4.2 +++ b/src/os/solaris/vm/os_solaris.cpp	Thu Apr 25 11:02:32 2013 -0700
     4.3 @@ -1915,10 +1915,6 @@
     4.4    return retval;
     4.5  }
     4.6  
     4.7 -const char* os::get_current_directory(char *buf, int buflen) {
     4.8 -  return getcwd(buf, buflen);
     4.9 -}
    4.10 -
    4.11  // check if addr is inside libjvm.so
    4.12  bool os::address_is_in_vm(address addr) {
    4.13    static address libjvm_base_addr;
     5.1 --- a/src/os/windows/vm/os_windows.cpp	Wed Apr 24 18:20:04 2013 -0400
     5.2 +++ b/src/os/windows/vm/os_windows.cpp	Thu Apr 25 11:02:32 2013 -0700
     5.3 @@ -1221,8 +1221,10 @@
     5.4  
     5.5  // Needs to be in os specific directory because windows requires another
     5.6  // header file <direct.h>
     5.7 -const char* os::get_current_directory(char *buf, int buflen) {
     5.8 -  return _getcwd(buf, buflen);
     5.9 +const char* os::get_current_directory(char *buf, size_t buflen) {
    5.10 +  int n = static_cast<int>(buflen);
    5.11 +  if (buflen > INT_MAX)  n = INT_MAX;
    5.12 +  return _getcwd(buf, n);
    5.13  }
    5.14  
    5.15  //-----------------------------------------------------------
    5.16 @@ -4098,6 +4100,10 @@
    5.17    return ::open(pathbuf, oflag | O_BINARY | O_NOINHERIT, mode);
    5.18  }
    5.19  
    5.20 +FILE* os::open(int fd, const char* mode) {
    5.21 +  return ::_fdopen(fd, mode);
    5.22 +}
    5.23 +
    5.24  // Is a (classpath) directory empty?
    5.25  bool os::dir_is_empty(const char* path) {
    5.26    WIN32_FIND_DATA fd;
     6.1 --- a/src/share/vm/ci/ciEnv.cpp	Wed Apr 24 18:20:04 2013 -0400
     6.2 +++ b/src/share/vm/ci/ciEnv.cpp	Thu Apr 25 11:02:32 2013 -0700
     6.3 @@ -1149,23 +1149,9 @@
     6.4    record_method_not_compilable("out of memory");
     6.5  }
     6.6  
     6.7 -fileStream* ciEnv::_replay_data_stream = NULL;
     6.8 -
     6.9 -void ciEnv::dump_replay_data() {
    6.10 +void ciEnv::dump_replay_data(outputStream* out) {
    6.11    VM_ENTRY_MARK;
    6.12    MutexLocker ml(Compile_lock);
    6.13 -  if (_replay_data_stream == NULL) {
    6.14 -    _replay_data_stream = new (ResourceObj::C_HEAP, mtCompiler) fileStream(ReplayDataFile);
    6.15 -    if (_replay_data_stream == NULL) {
    6.16 -      fatal(err_msg("Can't open %s for replay data", ReplayDataFile));
    6.17 -    }
    6.18 -  }
    6.19 -  dump_replay_data(_replay_data_stream);
    6.20 -}
    6.21 -
    6.22 -
    6.23 -void ciEnv::dump_replay_data(outputStream* out) {
    6.24 -  ASSERT_IN_VM;
    6.25    ResourceMark rm;
    6.26  #if INCLUDE_JVMTI
    6.27    out->print_cr("JvmtiExport can_access_local_variables %d",     _jvmti_can_access_local_variables);
     7.1 --- a/src/share/vm/ci/ciEnv.hpp	Wed Apr 24 18:20:04 2013 -0400
     7.2 +++ b/src/share/vm/ci/ciEnv.hpp	Thu Apr 25 11:02:32 2013 -0700
     7.3 @@ -46,8 +46,6 @@
     7.4    friend class CompileBroker;
     7.5    friend class Dependencies;  // for get_object, during logging
     7.6  
     7.7 -  static fileStream* _replay_data_stream;
     7.8 -
     7.9  private:
    7.10    Arena*           _arena;       // Alias for _ciEnv_arena except in init_shared_objects()
    7.11    Arena            _ciEnv_arena;
    7.12 @@ -451,10 +449,6 @@
    7.13    // RedefineClasses support
    7.14    void metadata_do(void f(Metadata*)) { _factory->metadata_do(f); }
    7.15  
    7.16 -  // Dump the compilation replay data for this ciEnv to
    7.17 -  // ReplayDataFile, creating the file if needed.
    7.18 -  void  dump_replay_data();
    7.19 -
    7.20    // Dump the compilation replay data for the ciEnv to the stream.
    7.21    void dump_replay_data(outputStream* out);
    7.22  };
     8.1 --- a/src/share/vm/ci/ciReplay.cpp	Wed Apr 24 18:20:04 2013 -0400
     8.2 +++ b/src/share/vm/ci/ciReplay.cpp	Thu Apr 25 11:02:32 2013 -0700
     8.3 @@ -89,7 +89,7 @@
     8.4      loader = Handle(thread, SystemDictionary::java_system_loader());
     8.5      stream = fopen(filename, "rt");
     8.6      if (stream == NULL) {
     8.7 -      fprintf(stderr, "Can't open replay file %s\n", filename);
     8.8 +      fprintf(stderr, "ERROR: Can't open replay file %s\n", filename);
     8.9      }
    8.10      buffer_length = 32;
    8.11      buffer = NEW_RESOURCE_ARRAY(char, buffer_length);
    8.12 @@ -327,7 +327,6 @@
    8.13          if (had_error()) {
    8.14            tty->print_cr("Error while parsing line %d: %s\n", line_no, _error_message);
    8.15            tty->print_cr("%s", buffer);
    8.16 -          assert(false, "error");
    8.17            return;
    8.18          }
    8.19          pos = 0;
    8.20 @@ -551,7 +550,7 @@
    8.21            if (parsed_two_word == i) continue;
    8.22  
    8.23          default:
    8.24 -          ShouldNotReachHere();
    8.25 +          fatal(err_msg_res("Unexpected tag: %d", cp->tag_at(i).value()));
    8.26            break;
    8.27        }
    8.28  
    8.29 @@ -819,6 +818,11 @@
    8.30      ReplaySuppressInitializers = 1;
    8.31    }
    8.32  
    8.33 +  if (FLAG_IS_DEFAULT(ReplayDataFile)) {
    8.34 +    tty->print_cr("ERROR: no compiler replay data file specified (use -XX:ReplayDataFile=replay_pid12345.txt).");
    8.35 +    return 1;
    8.36 +  }
    8.37 +
    8.38    // Load and parse the replay data
    8.39    CompileReplay rp(ReplayDataFile, THREAD);
    8.40    int exit_code = 0;
     9.1 --- a/src/share/vm/runtime/globals.hpp	Wed Apr 24 18:20:04 2013 -0400
     9.2 +++ b/src/share/vm/runtime/globals.hpp	Thu Apr 25 11:02:32 2013 -0700
     9.3 @@ -3223,8 +3223,9 @@
     9.4    develop(bool, ReplayCompiles, false,                                      \
     9.5            "Enable replay of compilations from ReplayDataFile")              \
     9.6                                                                              \
     9.7 -  develop(ccstr, ReplayDataFile, "replay.txt",                              \
     9.8 -          "file containing compilation replay information")                 \
     9.9 +  product(ccstr, ReplayDataFile, NULL,                                      \
    9.10 +          "File containing compilation replay information"                  \
    9.11 +          "[default: ./replay_pid%p.log] (%p replaced with pid)")           \
    9.12                                                                              \
    9.13    develop(intx, ReplaySuppressInitializers, 2,                              \
    9.14            "Controls handling of class initialization during replay"         \
    9.15 @@ -3237,8 +3238,8 @@
    9.16    develop(bool, ReplayIgnoreInitErrors, false,                              \
    9.17            "Ignore exceptions thrown during initialization for replay")      \
    9.18                                                                              \
    9.19 -  develop(bool, DumpReplayDataOnError, true,                                \
    9.20 -          "record replay data for crashing compiler threads")               \
    9.21 +  product(bool, DumpReplayDataOnError, true,                                \
    9.22 +          "Record replay data for crashing compiler threads")               \
    9.23                                                                              \
    9.24    product(bool, CICompilerCountPerCPU, false,                               \
    9.25            "1 compiler thread for log(N CPUs)")                              \
    10.1 --- a/src/share/vm/runtime/os.hpp	Wed Apr 24 18:20:04 2013 -0400
    10.2 +++ b/src/share/vm/runtime/os.hpp	Thu Apr 25 11:02:32 2013 -0700
    10.3 @@ -454,6 +454,7 @@
    10.4    // File i/o operations
    10.5    static const int default_file_open_flags();
    10.6    static int open(const char *path, int oflag, int mode);
    10.7 +  static FILE* open(int fd, const char* mode);
    10.8    static int close(int fd);
    10.9    static jlong lseek(int fd, jlong offset, int whence);
   10.10    static char* native_path(char *path);
   10.11 @@ -477,7 +478,7 @@
   10.12    static const char*    dll_file_extension();
   10.13  
   10.14    static const char*    get_temp_directory();
   10.15 -  static const char*    get_current_directory(char *buf, int buflen);
   10.16 +  static const char*    get_current_directory(char *buf, size_t buflen);
   10.17  
   10.18    // Builds a platform-specific full library path given a ld path and lib name
   10.19    // Returns true if buffer contains full path to existing file, false otherwise
    11.1 --- a/src/share/vm/utilities/ostream.hpp	Wed Apr 24 18:20:04 2013 -0400
    11.2 +++ b/src/share/vm/utilities/ostream.hpp	Thu Apr 25 11:02:32 2013 -0700
    11.3 @@ -196,7 +196,7 @@
    11.4    fileStream() { _file = NULL; _need_close = false; }
    11.5    fileStream(const char* file_name);
    11.6    fileStream(const char* file_name, const char* opentype);
    11.7 -  fileStream(FILE* file) { _file = file; _need_close = false; }
    11.8 +  fileStream(FILE* file, bool need_close = false) { _file = file; _need_close = need_close; }
    11.9    ~fileStream();
   11.10    bool is_open() const { return _file != NULL; }
   11.11    void set_need_close(bool b) { _need_close = b;}
    12.1 --- a/src/share/vm/utilities/vmError.cpp	Wed Apr 24 18:20:04 2013 -0400
    12.2 +++ b/src/share/vm/utilities/vmError.cpp	Thu Apr 25 11:02:32 2013 -0700
    12.3 @@ -796,6 +796,56 @@
    12.4  VMError* volatile VMError::first_error = NULL;
    12.5  volatile jlong VMError::first_error_tid = -1;
    12.6  
    12.7 +/** Expand a pattern into a buffer starting at pos and open a file using constructed path */
    12.8 +static int expand_and_open(const char* pattern, char* buf, size_t buflen, size_t pos) {
    12.9 +  int fd = -1;
   12.10 +  if (Arguments::copy_expand_pid(pattern, strlen(pattern), &buf[pos], buflen - pos)) {
   12.11 +    fd = open(buf, O_RDWR | O_CREAT | O_TRUNC, 0666);
   12.12 +  }
   12.13 +  return fd;
   12.14 +}
   12.15 +
   12.16 +/**
   12.17 + * Construct file name for a log file and return it's file descriptor.
   12.18 + * Name and location depends on pattern, default_pattern params and access
   12.19 + * permissions.
   12.20 + */
   12.21 +static int prepare_log_file(const char* pattern, const char* default_pattern, char* buf, size_t buflen) {
   12.22 +  int fd = -1;
   12.23 +
   12.24 +  // If possible, use specified pattern to construct log file name
   12.25 +  if (pattern != NULL) {
   12.26 +    fd = expand_and_open(pattern, buf, buflen, 0);
   12.27 +  }
   12.28 +
   12.29 +  // Either user didn't specify, or the user's location failed,
   12.30 +  // so use the default name in the current directory
   12.31 +  if (fd == -1) {
   12.32 +    const char* cwd = os::get_current_directory(buf, buflen);
   12.33 +    if (cwd != NULL) {
   12.34 +      size_t pos = strlen(cwd);
   12.35 +      int fsep_len = jio_snprintf(&buf[pos], buflen-pos, "%s", os::file_separator());
   12.36 +      pos += fsep_len;
   12.37 +      if (fsep_len > 0) {
   12.38 +        fd = expand_and_open(default_pattern, buf, buflen, pos);
   12.39 +      }
   12.40 +    }
   12.41 +  }
   12.42 +
   12.43 +   // try temp directory if it exists.
   12.44 +   if (fd == -1) {
   12.45 +     const char* tmpdir = os::get_temp_directory();
   12.46 +     if (tmpdir != NULL && strlen(tmpdir) > 0) {
   12.47 +       int pos = jio_snprintf(buf, buflen, "%s%s", tmpdir, os::file_separator());
   12.48 +       if (pos > 0) {
   12.49 +         fd = expand_and_open(default_pattern, buf, buflen, pos);
   12.50 +       }
   12.51 +     }
   12.52 +   }
   12.53 +
   12.54 +  return fd;
   12.55 +}
   12.56 +
   12.57  void VMError::report_and_die() {
   12.58    // Don't allocate large buffer on stack
   12.59    static char buffer[O_BUFLEN];
   12.60 @@ -905,36 +955,7 @@
   12.61      // see if log file is already open
   12.62      if (!log.is_open()) {
   12.63        // open log file
   12.64 -      int fd = -1;
   12.65 -
   12.66 -      if (ErrorFile != NULL) {
   12.67 -        bool copy_ok =
   12.68 -          Arguments::copy_expand_pid(ErrorFile, strlen(ErrorFile), buffer, sizeof(buffer));
   12.69 -        if (copy_ok) {
   12.70 -          fd = open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666);
   12.71 -        }
   12.72 -      }
   12.73 -
   12.74 -      if (fd == -1) {
   12.75 -        const char *cwd = os::get_current_directory(buffer, sizeof(buffer));
   12.76 -        size_t len = strlen(cwd);
   12.77 -        // either user didn't specify, or the user's location failed,
   12.78 -        // so use the default name in the current directory
   12.79 -        jio_snprintf(&buffer[len], sizeof(buffer)-len, "%shs_err_pid%u.log",
   12.80 -                     os::file_separator(), os::current_process_id());
   12.81 -        fd = open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666);
   12.82 -      }
   12.83 -
   12.84 -      if (fd == -1) {
   12.85 -        const char * tmpdir = os::get_temp_directory();
   12.86 -        // try temp directory if it exists.
   12.87 -        if (tmpdir != NULL && tmpdir[0] != '\0') {
   12.88 -          jio_snprintf(buffer, sizeof(buffer), "%s%shs_err_pid%u.log",
   12.89 -                       tmpdir, os::file_separator(), os::current_process_id());
   12.90 -          fd = open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666);
   12.91 -        }
   12.92 -      }
   12.93 -
   12.94 +      int fd = prepare_log_file(ErrorFile, "hs_err_pid%p.log", buffer, sizeof(buffer));
   12.95        if (fd != -1) {
   12.96          out.print_raw("# An error report file with more information is saved as:\n# ");
   12.97          out.print_raw_cr(buffer);
   12.98 @@ -958,7 +979,7 @@
   12.99      // Run error reporting to determine whether or not to report the crash.
  12.100      if (!transmit_report_done && should_report_bug(first_error->_id)) {
  12.101        transmit_report_done = true;
  12.102 -      FILE* hs_err = ::fdopen(log.fd(), "r");
  12.103 +      FILE* hs_err = os::open(log.fd(), "r");
  12.104        if (NULL != hs_err) {
  12.105          ErrorReporter er;
  12.106          er.call(hs_err, buffer, O_BUFLEN);
  12.107 @@ -1008,7 +1029,19 @@
  12.108      skip_replay = true;
  12.109      ciEnv* env = ciEnv::current();
  12.110      if (env != NULL) {
  12.111 -      env->dump_replay_data();
  12.112 +      int fd = prepare_log_file(ReplayDataFile, "replay_pid%p.log", buffer, sizeof(buffer));
  12.113 +      if (fd != -1) {
  12.114 +        FILE* replay_data_file = os::open(fd, "w");
  12.115 +        if (replay_data_file != NULL) {
  12.116 +          fileStream replay_data_stream(replay_data_file, /*need_close=*/true);
  12.117 +          env->dump_replay_data(&replay_data_stream);
  12.118 +          out.print_raw("#\n# Compiler replay data is saved as:\n# ");
  12.119 +          out.print_raw_cr(buffer);
  12.120 +        } else {
  12.121 +          out.print_raw("#\n# Can't open file to dump replay data. Error: ");
  12.122 +          out.print_raw_cr(strerror(os::get_last_error()));
  12.123 +        }
  12.124 +      }
  12.125      }
  12.126    }
  12.127  

mercurial