aboutsummaryrefslogtreecommitdiff
path: root/src/share/vm/utilities
diff options
context:
space:
mode:
Diffstat (limited to 'src/share/vm/utilities')
-rw-r--r--src/share/vm/utilities/bitMap.inline.hpp20
-rw-r--r--src/share/vm/utilities/decoder.cpp18
-rw-r--r--src/share/vm/utilities/decoder.hpp14
-rw-r--r--src/share/vm/utilities/ostream.cpp383
-rw-r--r--src/share/vm/utilities/ostream.hpp18
-rw-r--r--src/share/vm/utilities/vmError.cpp5
-rw-r--r--src/share/vm/utilities/vmError.hpp4
-rw-r--r--src/share/vm/utilities/yieldingWorkgroup.hpp5
8 files changed, 352 insertions, 115 deletions
diff --git a/src/share/vm/utilities/bitMap.inline.hpp b/src/share/vm/utilities/bitMap.inline.hpp
index 7bb244795..2171e849f 100644
--- a/src/share/vm/utilities/bitMap.inline.hpp
+++ b/src/share/vm/utilities/bitMap.inline.hpp
@@ -52,16 +52,16 @@ inline void BitMap::clear_bit(idx_t bit) {
inline bool BitMap::par_set_bit(idx_t bit) {
verify_index(bit);
- volatile idx_t* const addr = word_addr(bit);
- const idx_t mask = bit_mask(bit);
- idx_t old_val = *addr;
+ volatile bm_word_t* const addr = word_addr(bit);
+ const bm_word_t mask = bit_mask(bit);
+ bm_word_t old_val = *addr;
do {
- const idx_t new_val = old_val | mask;
+ const bm_word_t new_val = old_val | mask;
if (new_val == old_val) {
return false; // Someone else beat us to it.
}
- const idx_t cur_val = (idx_t) Atomic::cmpxchg_ptr((void*) new_val,
+ const bm_word_t cur_val = (bm_word_t) Atomic::cmpxchg_ptr((void*) new_val,
(volatile void*) addr,
(void*) old_val);
if (cur_val == old_val) {
@@ -73,16 +73,16 @@ inline bool BitMap::par_set_bit(idx_t bit) {
inline bool BitMap::par_clear_bit(idx_t bit) {
verify_index(bit);
- volatile idx_t* const addr = word_addr(bit);
- const idx_t mask = ~bit_mask(bit);
- idx_t old_val = *addr;
+ volatile bm_word_t* const addr = word_addr(bit);
+ const bm_word_t mask = ~bit_mask(bit);
+ bm_word_t old_val = *addr;
do {
- const idx_t new_val = old_val & mask;
+ const bm_word_t new_val = old_val & mask;
if (new_val == old_val) {
return false; // Someone else beat us to it.
}
- const idx_t cur_val = (idx_t) Atomic::cmpxchg_ptr((void*) new_val,
+ const bm_word_t cur_val = (bm_word_t) Atomic::cmpxchg_ptr((void*) new_val,
(volatile void*) addr,
(void*) old_val);
if (cur_val == old_val) {
diff --git a/src/share/vm/utilities/decoder.cpp b/src/share/vm/utilities/decoder.cpp
index 5489fe6fe..3fc934b4f 100644
--- a/src/share/vm/utilities/decoder.cpp
+++ b/src/share/vm/utilities/decoder.cpp
@@ -24,7 +24,6 @@
#include "precompiled.hpp"
#include "prims/jvm.h"
-#include "runtime/mutexLocker.hpp"
#include "runtime/os.hpp"
#include "utilities/decoder.hpp"
#include "utilities/vmError.hpp"
@@ -80,6 +79,23 @@ AbstractDecoder* Decoder::create_decoder() {
return decoder;
}
+inline bool DecoderLocker::is_first_error_thread() {
+ return (os::current_thread_id() == VMError::get_first_error_tid());
+}
+
+DecoderLocker::DecoderLocker() :
+ MutexLockerEx(DecoderLocker::is_first_error_thread() ?
+ NULL : Decoder::shared_decoder_lock(), true) {
+ _decoder = is_first_error_thread() ?
+ Decoder::get_error_handler_instance() : Decoder::get_shared_instance();
+ assert(_decoder != NULL, "null decoder");
+}
+
+Mutex* Decoder::shared_decoder_lock() {
+ assert(_shared_decoder_lock != NULL, "Just check");
+ return _shared_decoder_lock;
+}
+
bool Decoder::decode(address addr, char* buf, int buflen, int* offset, const char* modulepath) {
assert(_shared_decoder_lock != NULL, "Just check");
bool error_handling_thread = os::current_thread_id() == VMError::first_error_tid;
diff --git a/src/share/vm/utilities/decoder.hpp b/src/share/vm/utilities/decoder.hpp
index 0d2af8098..0cc880f19 100644
--- a/src/share/vm/utilities/decoder.hpp
+++ b/src/share/vm/utilities/decoder.hpp
@@ -28,6 +28,7 @@
#include "memory/allocation.hpp"
#include "runtime/mutex.hpp"
+#include "runtime/mutexLocker.hpp"
class AbstractDecoder : public CHeapObj<mtInternal> {
public:
@@ -124,6 +125,19 @@ private:
protected:
static Mutex* _shared_decoder_lock;
+ static Mutex* shared_decoder_lock();
+
+ friend class DecoderLocker;
+};
+
+class DecoderLocker : public MutexLockerEx {
+ AbstractDecoder* _decoder;
+ inline bool is_first_error_thread();
+public:
+ DecoderLocker();
+ AbstractDecoder* decoder() {
+ return _decoder;
+ }
};
#endif // SHARE_VM_UTILITIES_DECODER_HPP
diff --git a/src/share/vm/utilities/ostream.cpp b/src/share/vm/utilities/ostream.cpp
index 905320786..e4215504a 100644
--- a/src/share/vm/utilities/ostream.cpp
+++ b/src/share/vm/utilities/ostream.cpp
@@ -342,7 +342,7 @@ void stringStream::write(const char* s, size_t len) {
}
char* stringStream::as_string() {
- char* copy = NEW_RESOURCE_ARRAY(char, buffer_pos+1);
+ char* copy = NEW_RESOURCE_ARRAY(char, buffer_pos + 1);
strncpy(copy, buffer, buffer_pos);
copy[buffer_pos] = 0; // terminating null
return copy;
@@ -355,14 +355,190 @@ outputStream* tty;
outputStream* gclog_or_tty;
extern Mutex* tty_lock;
+#define EXTRACHARLEN 32
+#define CURRENTAPPX ".current"
+#define FILENAMEBUFLEN 1024
+// convert YYYY-MM-DD HH:MM:SS to YYYY-MM-DD_HH-MM-SS
+char* get_datetime_string(char *buf, size_t len) {
+ os::local_time_string(buf, len);
+ int i = (int)strlen(buf);
+ while (i-- >= 0) {
+ if (buf[i] == ' ') buf[i] = '_';
+ else if (buf[i] == ':') buf[i] = '-';
+ }
+ return buf;
+}
+
+static const char* make_log_name_internal(const char* log_name, const char* force_directory,
+ int pid, const char* tms) {
+ const char* basename = log_name;
+ char file_sep = os::file_separator()[0];
+ const char* cp;
+ char pid_text[32];
+
+ for (cp = log_name; *cp != '\0'; cp++) {
+ if (*cp == '/' || *cp == file_sep) {
+ basename = cp + 1;
+ }
+ }
+ const char* nametail = log_name;
+ // Compute buffer length
+ size_t buffer_length;
+ if (force_directory != NULL) {
+ buffer_length = strlen(force_directory) + strlen(os::file_separator()) +
+ strlen(basename) + 1;
+ } else {
+ buffer_length = strlen(log_name) + 1;
+ }
+
+ // const char* star = strchr(basename, '*');
+ const char* pts = strstr(basename, "%p");
+ int pid_pos = (pts == NULL) ? -1 : (pts - nametail);
+
+ if (pid_pos >= 0) {
+ jio_snprintf(pid_text, sizeof(pid_text), "pid%u", pid);
+ buffer_length += strlen(pid_text);
+ }
+
+ pts = strstr(basename, "%t");
+ int tms_pos = (pts == NULL) ? -1 : (pts - nametail);
+ if (tms_pos >= 0) {
+ buffer_length += strlen(tms);
+ }
+
+ // Create big enough buffer.
+ char *buf = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal);
+
+ strcpy(buf, "");
+ if (force_directory != NULL) {
+ strcat(buf, force_directory);
+ strcat(buf, os::file_separator());
+ nametail = basename; // completely skip directory prefix
+ }
+
+ // who is first, %p or %t?
+ int first = -1, second = -1;
+ const char *p1st = NULL;
+ const char *p2nd = NULL;
+
+ if (pid_pos >= 0 && tms_pos >= 0) {
+ // contains both %p and %t
+ if (pid_pos < tms_pos) {
+ // case foo%pbar%tmonkey.log
+ first = pid_pos;
+ p1st = pid_text;
+ second = tms_pos;
+ p2nd = tms;
+ } else {
+ // case foo%tbar%pmonkey.log
+ first = tms_pos;
+ p1st = tms;
+ second = pid_pos;
+ p2nd = pid_text;
+ }
+ } else if (pid_pos >= 0) {
+ // contains %p only
+ first = pid_pos;
+ p1st = pid_text;
+ } else if (tms_pos >= 0) {
+ // contains %t only
+ first = tms_pos;
+ p1st = tms;
+ }
+
+ int buf_pos = (int)strlen(buf);
+ const char* tail = nametail;
+
+ if (first >= 0) {
+ tail = nametail + first + 2;
+ strncpy(&buf[buf_pos], nametail, first);
+ strcpy(&buf[buf_pos + first], p1st);
+ buf_pos = (int)strlen(buf);
+ if (second >= 0) {
+ strncpy(&buf[buf_pos], tail, second - first - 2);
+ strcpy(&buf[buf_pos + second - first - 2], p2nd);
+ tail = nametail + second + 2;
+ }
+ }
+ strcat(buf, tail); // append rest of name, or all of name
+ return buf;
+}
+
+// log_name comes from -XX:LogFile=log_name or -Xloggc:log_name
+// in log_name, %p => pipd1234 and
+// %t => YYYY-MM-DD_HH-MM-SS
+static const char* make_log_name(const char* log_name, const char* force_directory) {
+ char timestr[32];
+ get_datetime_string(timestr, sizeof(timestr));
+ return make_log_name_internal(log_name, force_directory, os::current_process_id(),
+ timestr);
+}
+
+#ifndef PRODUCT
+void test_loggc_filename() {
+ int pid;
+ char tms[32];
+ char i_result[FILENAMEBUFLEN];
+ const char* o_result;
+ get_datetime_string(tms, sizeof(tms));
+ pid = os::current_process_id();
+
+ // test.log
+ jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "test.log", tms);
+ o_result = make_log_name_internal("test.log", NULL, pid, tms);
+ assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test.log\", NULL)");
+ FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
+
+ // test-%t-%p.log
+ jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "test-%s-pid%u.log", tms, pid);
+ o_result = make_log_name_internal("test-%t-%p.log", NULL, pid, tms);
+ assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test-%%t-%%p.log\", NULL)");
+ FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
+
+ // test-%t%p.log
+ jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "test-%spid%u.log", tms, pid);
+ o_result = make_log_name_internal("test-%t%p.log", NULL, pid, tms);
+ assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test-%%t%%p.log\", NULL)");
+ FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
+
+ // %p%t.log
+ jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "pid%u%s.log", pid, tms);
+ o_result = make_log_name_internal("%p%t.log", NULL, pid, tms);
+ assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%p%%t.log\", NULL)");
+ FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
+
+ // %p-test.log
+ jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "pid%u-test.log", pid);
+ o_result = make_log_name_internal("%p-test.log", NULL, pid, tms);
+ assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%p-test.log\", NULL)");
+ FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
+
+ // %t.log
+ jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "%s.log", tms);
+ o_result = make_log_name_internal("%t.log", NULL, pid, tms);
+ assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%t.log\", NULL)");
+ FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
+}
+#endif // PRODUCT
+
fileStream::fileStream(const char* file_name) {
_file = fopen(file_name, "w");
- _need_close = true;
+ if (_file != NULL) {
+ _need_close = true;
+ } else {
+ warning("Cannot open file %s due to %s\n", file_name, strerror(errno));
+ _need_close = false;
+ }
}
fileStream::fileStream(const char* file_name, const char* opentype) {
_file = fopen(file_name, opentype);
- _need_close = true;
+ if (_file != NULL) {
+ _need_close = true;
+ } else {
+ warning("Cannot open file %s due to %s\n", file_name, strerror(errno));
+ _need_close = false;
+ }
}
void fileStream::write(const char* s, size_t len) {
@@ -423,34 +599,51 @@ void fdStream::write(const char* s, size_t len) {
update_position(s, len);
}
-rotatingFileStream::~rotatingFileStream() {
+// dump vm version, os version, platform info, build id,
+// memory usage and command line flags into header
+void gcLogFileStream::dump_loggc_header() {
+ if (is_open()) {
+ print_cr(Abstract_VM_Version::internal_vm_info_string());
+ os::print_memory_info(this);
+ print("CommandLine flags: ");
+ CommandLineFlags::printSetFlags(this);
+ }
+}
+
+gcLogFileStream::~gcLogFileStream() {
if (_file != NULL) {
if (_need_close) fclose(_file);
- _file = NULL;
+ _file = NULL;
+ }
+ if (_file_name != NULL) {
FREE_C_HEAP_ARRAY(char, _file_name, mtInternal);
_file_name = NULL;
}
}
-rotatingFileStream::rotatingFileStream(const char* file_name) {
+gcLogFileStream::gcLogFileStream(const char* file_name) {
_cur_file_num = 0;
_bytes_written = 0L;
- _file_name = NEW_C_HEAP_ARRAY(char, strlen(file_name)+10, mtInternal);
- jio_snprintf(_file_name, strlen(file_name)+10, "%s.%d", file_name, _cur_file_num);
- _file = fopen(_file_name, "w");
- _need_close = true;
-}
+ _file_name = make_log_name(file_name, NULL);
-rotatingFileStream::rotatingFileStream(const char* file_name, const char* opentype) {
- _cur_file_num = 0;
- _bytes_written = 0L;
- _file_name = NEW_C_HEAP_ARRAY(char, strlen(file_name)+10, mtInternal);
- jio_snprintf(_file_name, strlen(file_name)+10, "%s.%d", file_name, _cur_file_num);
- _file = fopen(_file_name, opentype);
- _need_close = true;
+ // gc log file rotation
+ if (UseGCLogFileRotation && NumberOfGCLogFiles > 1) {
+ char tempbuf[FILENAMEBUFLEN];
+ jio_snprintf(tempbuf, sizeof(tempbuf), "%s.%d" CURRENTAPPX, _file_name, _cur_file_num);
+ _file = fopen(tempbuf, "w");
+ } else {
+ _file = fopen(_file_name, "w");
+ }
+ if (_file != NULL) {
+ _need_close = true;
+ dump_loggc_header();
+ } else {
+ warning("Cannot open file %s due to %s\n", _file_name, strerror(errno));
+ _need_close = false;
+ }
}
-void rotatingFileStream::write(const char* s, size_t len) {
+void gcLogFileStream::write(const char* s, size_t len) {
if (_file != NULL) {
size_t count = fwrite(s, 1, len, _file);
_bytes_written += count;
@@ -466,7 +659,12 @@ void rotatingFileStream::write(const char* s, size_t len) {
// write to gc log file at safepoint. If in future, changes made for mutator threads or
// concurrent GC threads to run parallel with VMThread at safepoint, write and rotate_log
// must be synchronized.
-void rotatingFileStream::rotate_log() {
+void gcLogFileStream::rotate_log() {
+ char time_msg[FILENAMEBUFLEN];
+ char time_str[EXTRACHARLEN];
+ char current_file_name[FILENAMEBUFLEN];
+ char renamed_file_name[FILENAMEBUFLEN];
+
if (_bytes_written < (jlong)GCLogFileSize) {
return;
}
@@ -481,27 +679,89 @@ void rotatingFileStream::rotate_log() {
// rotate in same file
rewind();
_bytes_written = 0L;
+ jio_snprintf(time_msg, sizeof(time_msg), "File %s rotated at %s\n",
+ _file_name, os::local_time_string((char *)time_str, sizeof(time_str)));
+ write(time_msg, strlen(time_msg));
+ dump_loggc_header();
return;
}
- // rotate file in names file.0, file.1, file.2, ..., file.<MaxGCLogFileNumbers-1>
- // close current file, rotate to next file
+#if defined(_WINDOWS)
+#ifndef F_OK
+#define F_OK 0
+#endif
+#endif // _WINDOWS
+
+ // rotate file in names extended_filename.0, extended_filename.1, ...,
+ // extended_filename.<NumberOfGCLogFiles - 1>. Current rotation file name will
+ // have a form of extended_filename.<i>.current where i is the current rotation
+ // file number. After it reaches max file size, the file will be saved and renamed
+ // with .current removed from its tail.
+ size_t filename_len = strlen(_file_name);
if (_file != NULL) {
- _cur_file_num ++;
- if (_cur_file_num >= NumberOfGCLogFiles) _cur_file_num = 0;
- jio_snprintf(_file_name, strlen(Arguments::gc_log_filename()) + 10, "%s.%d",
- Arguments::gc_log_filename(), _cur_file_num);
+ jio_snprintf(renamed_file_name, filename_len + EXTRACHARLEN, "%s.%d",
+ _file_name, _cur_file_num);
+ jio_snprintf(current_file_name, filename_len + EXTRACHARLEN, "%s.%d" CURRENTAPPX,
+ _file_name, _cur_file_num);
+ jio_snprintf(time_msg, sizeof(time_msg), "%s GC log file has reached the"
+ " maximum size. Saved as %s\n",
+ os::local_time_string((char *)time_str, sizeof(time_str)),
+ renamed_file_name);
+ write(time_msg, strlen(time_msg));
+
fclose(_file);
_file = NULL;
+
+ bool can_rename = true;
+ if (access(current_file_name, F_OK) != 0) {
+ // current file does not exist?
+ warning("No source file exists, cannot rename\n");
+ can_rename = false;
+ }
+ if (can_rename) {
+ if (access(renamed_file_name, F_OK) == 0) {
+ if (remove(renamed_file_name) != 0) {
+ warning("Could not delete existing file %s\n", renamed_file_name);
+ can_rename = false;
+ }
+ } else {
+ // file does not exist, ok to rename
+ }
+ }
+ if (can_rename && rename(current_file_name, renamed_file_name) != 0) {
+ warning("Could not rename %s to %s\n", _file_name, renamed_file_name);
+ }
}
- _file = fopen(_file_name, "w");
+
+ _cur_file_num++;
+ if (_cur_file_num > NumberOfGCLogFiles - 1) _cur_file_num = 0;
+ jio_snprintf(current_file_name, filename_len + EXTRACHARLEN, "%s.%d" CURRENTAPPX,
+ _file_name, _cur_file_num);
+ _file = fopen(current_file_name, "w");
+
if (_file != NULL) {
_bytes_written = 0L;
_need_close = true;
+ // reuse current_file_name for time_msg
+ jio_snprintf(current_file_name, filename_len + EXTRACHARLEN,
+ "%s.%d", _file_name, _cur_file_num);
+ jio_snprintf(time_msg, sizeof(time_msg), "%s GC log file created %s\n",
+ os::local_time_string((char *)time_str, sizeof(time_str)),
+ current_file_name);
+ write(time_msg, strlen(time_msg));
+ dump_loggc_header();
+ // remove the existing file
+ if (access(current_file_name, F_OK) == 0) {
+ if (remove(current_file_name) != 0) {
+ warning("Could not delete existing file %s\n", current_file_name);
+ }
+ }
} else {
- tty->print_cr("failed to open rotation log file %s due to %s\n",
+ warning("failed to open rotation log file %s due to %s\n"
+ "Turned off GC log file rotation\n",
_file_name, strerror(errno));
_need_close = false;
+ FLAG_SET_DEFAULT(UseGCLogFileRotation, false);
}
}
@@ -530,66 +790,6 @@ bool defaultStream::has_log_file() {
return _log_file != NULL;
}
-static const char* make_log_name(const char* log_name, const char* force_directory) {
- const char* basename = log_name;
- char file_sep = os::file_separator()[0];
- const char* cp;
- for (cp = log_name; *cp != '\0'; cp++) {
- if (*cp == '/' || *cp == file_sep) {
- basename = cp+1;
- }
- }
- const char* nametail = log_name;
-
- // Compute buffer length
- size_t buffer_length;
- if (force_directory != NULL) {
- buffer_length = strlen(force_directory) + strlen(os::file_separator()) +
- strlen(basename) + 1;
- } else {
- buffer_length = strlen(log_name) + 1;
- }
-
- const char* star = strchr(basename, '*');
- int star_pos = (star == NULL) ? -1 : (star - nametail);
- int skip = 1;
- if (star == NULL) {
- // Try %p
- star = strstr(basename, "%p");
- if (star != NULL) {
- skip = 2;
- }
- }
- star_pos = (star == NULL) ? -1 : (star - nametail);
-
- char pid[32];
- if (star_pos >= 0) {
- jio_snprintf(pid, sizeof(pid), "%u", os::current_process_id());
- buffer_length += strlen(pid);
- }
-
- // Create big enough buffer.
- char *buf = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal);
-
- strcpy(buf, "");
- if (force_directory != NULL) {
- strcat(buf, force_directory);
- strcat(buf, os::file_separator());
- nametail = basename; // completely skip directory prefix
- }
-
- if (star_pos >= 0) {
- // convert foo*bar.log or foo%pbar.log to foo123bar.log
- int buf_pos = (int) strlen(buf);
- strncpy(&buf[buf_pos], nametail, star_pos);
- strcpy(&buf[buf_pos + star_pos], pid);
- nametail += star_pos + skip; // skip prefix and pid format
- }
-
- strcat(buf, nametail); // append rest of name, or all of name
- return buf;
-}
-
void defaultStream::init_log() {
// %%% Need a MutexLocker?
const char* log_name = LogFile != NULL ? LogFile : "hotspot_pid%p.log";
@@ -878,11 +1078,8 @@ void ostream_init_log() {
gclog_or_tty = tty; // default to tty
if (Arguments::gc_log_filename() != NULL) {
- fileStream * gclog = UseGCLogFileRotation ?
- new(ResourceObj::C_HEAP, mtInternal)
- rotatingFileStream(Arguments::gc_log_filename()) :
- new(ResourceObj::C_HEAP, mtInternal)
- fileStream(Arguments::gc_log_filename());
+ fileStream * gclog = new(ResourceObj::C_HEAP, mtInternal)
+ gcLogFileStream(Arguments::gc_log_filename());
if (gclog->is_open()) {
// now we update the time stamp of the GC log to be synced up
// with tty.
diff --git a/src/share/vm/utilities/ostream.hpp b/src/share/vm/utilities/ostream.hpp
index 4d1384766..9b1b1217b 100644
--- a/src/share/vm/utilities/ostream.hpp
+++ b/src/share/vm/utilities/ostream.hpp
@@ -231,20 +231,24 @@ class fdStream : public outputStream {
void flush() {};
};
-class rotatingFileStream : public fileStream {
+class gcLogFileStream : public fileStream {
protected:
- char* _file_name;
+ const char* _file_name;
jlong _bytes_written;
- uintx _cur_file_num; // current logfile rotation number, from 0 to MaxGCLogFileNumbers-1
+ uintx _cur_file_num; // current logfile rotation number, from 0 to NumberOfGCLogFiles-1
public:
- rotatingFileStream(const char* file_name);
- rotatingFileStream(const char* file_name, const char* opentype);
- rotatingFileStream(FILE* file) : fileStream(file) {}
- ~rotatingFileStream();
+ gcLogFileStream(const char* file_name);
+ ~gcLogFileStream();
virtual void write(const char* c, size_t len);
virtual void rotate_log();
+ void dump_loggc_header();
};
+#ifndef PRODUCT
+// unit test for checking -Xloggc:<filename> parsing result
+void test_loggc_filename();
+#endif
+
void ostream_init();
void ostream_init_log();
void ostream_exit();
diff --git a/src/share/vm/utilities/vmError.cpp b/src/share/vm/utilities/vmError.cpp
index b07404dc9..79769aeb3 100644
--- a/src/share/vm/utilities/vmError.cpp
+++ b/src/share/vm/utilities/vmError.cpp
@@ -574,6 +574,10 @@ void VMError::report(outputStream* st) {
STEP(120, "(printing native stack)" )
if (_verbose) {
+ if (os::platform_print_native_stack(st, _context, buf, sizeof(buf))) {
+ // We have printed the native stack in platform-specific code
+ // Windows/x64 needs special handling.
+ } else {
frame fr = _context ? os::fetch_frame_from_context(_context)
: os::current_frame();
@@ -604,6 +608,7 @@ void VMError::report(outputStream* st) {
st->cr();
}
}
+ }
STEP(130, "(printing Java stack)" )
diff --git a/src/share/vm/utilities/vmError.hpp b/src/share/vm/utilities/vmError.hpp
index 1b1608bdc..299cfaa6f 100644
--- a/src/share/vm/utilities/vmError.hpp
+++ b/src/share/vm/utilities/vmError.hpp
@@ -136,6 +136,10 @@ public:
// check to see if fatal error reporting is in progress
static bool fatal_error_in_progress() { return first_error != NULL; }
+
+ static jlong get_first_error_tid() {
+ return first_error_tid;
+ }
};
#endif // SHARE_VM_UTILITIES_VMERROR_HPP
diff --git a/src/share/vm/utilities/yieldingWorkgroup.hpp b/src/share/vm/utilities/yieldingWorkgroup.hpp
index 5a626ce7f..98d8f438e 100644
--- a/src/share/vm/utilities/yieldingWorkgroup.hpp
+++ b/src/share/vm/utilities/yieldingWorkgroup.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,10 +26,7 @@
#define SHARE_VM_UTILITIES_YIELDINGWORKGROUP_HPP
#include "utilities/macros.hpp"
-#if INCLUDE_ALL_GCS
#include "utilities/workgroup.hpp"
-#endif // INCLUDE_ALL_GCS
-
// Forward declarations
class YieldingFlexibleWorkGang;