!383 I69W1Y: Add feature and bug fix for 8u352
From: @eapen Reviewed-by: @kuenking111 Signed-off-by: @kuenking111
This commit is contained in:
commit
8a232aaf43
96
8065402-G1-does-not-expand-marking-stack-when-mark-s.patch
Normal file
96
8065402-G1-does-not-expand-marking-stack-when-mark-s.patch
Normal file
@ -0,0 +1,96 @@
|
||||
From 21a76a7829958e0064051956d1d1f6ddb8b48650 Mon Sep 17 00:00:00 2001
|
||||
From: eapen <zhangyipeng7@huawei.com>
|
||||
Date: Mon, 24 Oct 2022 14:54:04 +0800
|
||||
Subject: [PATCH 28/33] I68TO2: 8065402: G1 does not expand marking stack when mark
|
||||
stack overflow happens during concurrent marking
|
||||
---
|
||||
.../vm/gc_implementation/g1/concurrentMark.cpp | 22 ++++++----------------
|
||||
.../vm/gc_implementation/g1/concurrentMark.hpp | 4 ----
|
||||
2 files changed, 6 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
|
||||
index 831ec94..df901a5 100644
|
||||
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
|
||||
@@ -247,7 +247,6 @@ bool CMMarkStack::allocate(size_t capacity) {
|
||||
setEmpty();
|
||||
_capacity = (jint) capacity;
|
||||
_saved_index = -1;
|
||||
- _should_expand = false;
|
||||
NOT_PRODUCT(_max_depth = 0);
|
||||
return true;
|
||||
}
|
||||
@@ -256,8 +255,6 @@ void CMMarkStack::expand() {
|
||||
// Called, during remark, if we've overflown the marking stack during marking.
|
||||
assert(isEmpty(), "stack should been emptied while handling overflow");
|
||||
assert(_capacity <= (jint) MarkStackSizeMax, "stack bigger than permitted");
|
||||
- // Clear expansion flag
|
||||
- _should_expand = false;
|
||||
if (_capacity == (jint) MarkStackSizeMax) {
|
||||
if (PrintGCDetails && Verbose) {
|
||||
gclog_or_tty->print_cr(" (benign) Can't expand marking stack capacity, at max size limit");
|
||||
@@ -290,13 +287,6 @@ void CMMarkStack::expand() {
|
||||
}
|
||||
}
|
||||
|
||||
-void CMMarkStack::set_should_expand() {
|
||||
- // If we're resetting the marking state because of an
|
||||
- // marking stack overflow, record that we should, if
|
||||
- // possible, expand the stack.
|
||||
- _should_expand = _cm->has_overflown();
|
||||
-}
|
||||
-
|
||||
CMMarkStack::~CMMarkStack() {
|
||||
if (_base != NULL) {
|
||||
_base = NULL;
|
||||
@@ -795,8 +785,13 @@ void ConcurrentMark::reset() {
|
||||
|
||||
|
||||
void ConcurrentMark::reset_marking_state(bool clear_overflow) {
|
||||
- _markStack.set_should_expand();
|
||||
_markStack.setEmpty(); // Also clears the _markStack overflow flag
|
||||
+
|
||||
+ // Expand the marking stack, if we have to and if we can.
|
||||
+ if (has_overflown()) {
|
||||
+ _markStack.expand();
|
||||
+ }
|
||||
+
|
||||
if (clear_overflow) {
|
||||
clear_has_overflown();
|
||||
} else {
|
||||
@@ -1367,11 +1362,6 @@ void ConcurrentMark::checkpointRootsFinal(bool clear_all_soft_refs) {
|
||||
set_non_marking_state();
|
||||
}
|
||||
|
||||
- // Expand the marking stack, if we have to and if we can.
|
||||
- if (_markStack.should_expand()) {
|
||||
- _markStack.expand();
|
||||
- }
|
||||
-
|
||||
// Statistics
|
||||
double now = os::elapsedTime();
|
||||
_remark_mark_times.add((mark_work_end - start) * 1000.0);
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp
|
||||
index f78b1cb..bbd5d59 100644
|
||||
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp
|
||||
@@ -178,7 +178,6 @@ class CMMarkStack VALUE_OBJ_CLASS_SPEC {
|
||||
NOT_PRODUCT(jint _max_depth;) // max depth plumbed during run
|
||||
|
||||
bool _overflow;
|
||||
- bool _should_expand;
|
||||
DEBUG_ONLY(bool _drain_in_progress;)
|
||||
DEBUG_ONLY(bool _drain_in_progress_yields;)
|
||||
|
||||
@@ -255,9 +254,6 @@ class CMMarkStack VALUE_OBJ_CLASS_SPEC {
|
||||
bool overflow() { return _overflow; }
|
||||
void clear_overflow() { _overflow = false; }
|
||||
|
||||
- bool should_expand() const { return _should_expand; }
|
||||
- void set_should_expand();
|
||||
-
|
||||
// Expand the stack, typically in response to an overflow condition
|
||||
void expand();
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
498
8140594-Various-minor-code-improvements-compiler.patch
Normal file
498
8140594-Various-minor-code-improvements-compiler.patch
Normal file
@ -0,0 +1,498 @@
|
||||
From 39f5104db20a569e361c0300756e35ab7e6ac296 Mon Sep 17 00:00:00 2001
|
||||
From: eapen <zhangyipeng7@huawei.com>
|
||||
Date: Fri, 16 Dec 2022 16:06:02 +0000
|
||||
Subject: [PATCH 30/33] I68TO2: 8140594: Various minor code improvements (compiler)
|
||||
---
|
||||
hotspot/src/os/linux/vm/os_linux.cpp | 5 +-
|
||||
hotspot/src/os/linux/vm/vmError_linux.cpp | 16 ++---
|
||||
hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp | 2 +-
|
||||
hotspot/src/share/vm/adlc/formssel.cpp | 13 ++--
|
||||
hotspot/src/share/vm/c1/c1_LinearScan.cpp | 7 +-
|
||||
hotspot/src/share/vm/classfile/classFileParser.cpp | 11 +--
|
||||
.../src/share/vm/classfile/systemDictionary.cpp | 6 +-
|
||||
hotspot/src/share/vm/compiler/compileBroker.cpp | 84 +++++++---------------
|
||||
hotspot/src/share/vm/compiler/compileBroker.hpp | 11 +--
|
||||
hotspot/src/share/vm/compiler/compileLog.cpp | 3 +-
|
||||
hotspot/src/share/vm/compiler/disassembler.cpp | 6 +-
|
||||
hotspot/src/share/vm/oops/generateOopMap.cpp | 8 ++-
|
||||
hotspot/src/share/vm/opto/block.cpp | 2 +-
|
||||
hotspot/src/share/vm/opto/graphKit.cpp | 2 +-
|
||||
hotspot/src/share/vm/opto/matcher.cpp | 9 ++-
|
||||
hotspot/src/share/vm/runtime/relocator.cpp | 4 +-
|
||||
16 files changed, 84 insertions(+), 105 deletions(-)
|
||||
|
||||
diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp
|
||||
index ab28ee3..b82352c 100644
|
||||
--- a/hotspot/src/os/linux/vm/os_linux.cpp
|
||||
+++ b/hotspot/src/os/linux/vm/os_linux.cpp
|
||||
@@ -2159,9 +2159,10 @@ static bool _print_ascii_file(const char* filename, outputStream* st) {
|
||||
return false;
|
||||
}
|
||||
|
||||
- char buf[32];
|
||||
+ char buf[33];
|
||||
int bytes;
|
||||
- while ((bytes = ::read(fd, buf, sizeof(buf))) > 0) {
|
||||
+ buf[32] = '\0';
|
||||
+ while ((bytes = ::read(fd, buf, sizeof(buf) - 1)) > 0) {
|
||||
st->print_raw(buf, bytes);
|
||||
}
|
||||
|
||||
diff --git a/hotspot/src/os/linux/vm/vmError_linux.cpp b/hotspot/src/os/linux/vm/vmError_linux.cpp
|
||||
index fca239c..52ca40b 100644
|
||||
--- a/hotspot/src/os/linux/vm/vmError_linux.cpp
|
||||
+++ b/hotspot/src/os/linux/vm/vmError_linux.cpp
|
||||
@@ -42,19 +42,19 @@ void VMError::show_message_box(char *buf, int buflen) {
|
||||
char *p = &buf[len];
|
||||
|
||||
jio_snprintf(p, buflen - len,
|
||||
- "\n\n"
|
||||
- "Do you want to debug the problem?\n\n"
|
||||
- "To debug, run 'gdb /proc/%d/exe %d'; then switch to thread " UINTX_FORMAT " (" INTPTR_FORMAT ")\n"
|
||||
- "Enter 'yes' to launch gdb automatically (PATH must include gdb)\n"
|
||||
- "Otherwise, press RETURN to abort...",
|
||||
- os::current_process_id(), os::current_process_id(),
|
||||
- os::current_thread_id(), os::current_thread_id());
|
||||
+ "\n\n"
|
||||
+ "Do you want to debug the problem?\n\n"
|
||||
+ "To debug, run 'gdb /proc/%d/exe %d'; then switch to thread " UINTX_FORMAT " (" INTPTR_FORMAT ")\n"
|
||||
+ "Enter 'yes' to launch gdb automatically (PATH must include gdb)\n"
|
||||
+ "Otherwise, press RETURN to abort...",
|
||||
+ os::current_process_id(), os::current_process_id(),
|
||||
+ os::current_thread_id(), os::current_thread_id());
|
||||
|
||||
yes = os::message_box("Unexpected Error", buf);
|
||||
|
||||
if (yes) {
|
||||
// yes, user asked VM to launch debugger
|
||||
- jio_snprintf(buf, buflen, "gdb /proc/%d/exe %d",
|
||||
+ jio_snprintf(buf, sizeof(char)*buflen, "gdb /proc/%d/exe %d",
|
||||
os::current_process_id(), os::current_process_id());
|
||||
|
||||
os::fork_and_exec(buf);
|
||||
diff --git a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp
|
||||
index 4775dc8..fba3d28 100644
|
||||
--- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp
|
||||
+++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp
|
||||
@@ -813,7 +813,7 @@ void os::print_context(outputStream *st, void *context) {
|
||||
|
||||
intptr_t *sp = (intptr_t *)os::Linux::ucontext_get_sp(uc);
|
||||
st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", sp);
|
||||
- print_hex_dump(st, (address)sp, (address)(sp + 8*sizeof(intptr_t)), sizeof(intptr_t));
|
||||
+ print_hex_dump(st, (address)sp, (address)(sp + 8), sizeof(intptr_t));
|
||||
st->cr();
|
||||
|
||||
// Note: it may be unsafe to inspect memory near pc. For example, pc may
|
||||
diff --git a/hotspot/src/share/vm/adlc/formssel.cpp b/hotspot/src/share/vm/adlc/formssel.cpp
|
||||
index 23fa1bb..6d57ff2 100644
|
||||
--- a/hotspot/src/share/vm/adlc/formssel.cpp
|
||||
+++ b/hotspot/src/share/vm/adlc/formssel.cpp
|
||||
@@ -1496,7 +1496,8 @@ void MachNodeForm::output(FILE *fp) {
|
||||
// twice, we need to check that the operands are pointer-eequivalent in
|
||||
// the DFA during the labeling process.
|
||||
Predicate *InstructForm::build_predicate() {
|
||||
- char buf[1024], *s=buf;
|
||||
+ const int buflen = 1024;
|
||||
+ char buf[buflen], *s=buf;
|
||||
Dict names(cmpstr,hashstr,Form::arena); // Map Names to counts
|
||||
|
||||
MatchNode *mnode =
|
||||
@@ -1505,12 +1506,12 @@ Predicate *InstructForm::build_predicate() {
|
||||
|
||||
uint first = 1;
|
||||
// Start with the predicate supplied in the .ad file.
|
||||
- if( _predicate ) {
|
||||
- if( first ) first=0;
|
||||
- strcpy(s,"("); s += strlen(s);
|
||||
- strcpy(s,_predicate->_pred);
|
||||
+ if(_predicate) {
|
||||
+ if(first) first = 0;
|
||||
+ strcpy(s, "("); s += strlen(s);
|
||||
+ strncpy(s, _predicate->_pred, buflen - strlen(s) - 1);
|
||||
s += strlen(s);
|
||||
- strcpy(s,")"); s += strlen(s);
|
||||
+ strcpy(s, ")"); s += strlen(s);
|
||||
}
|
||||
for( DictI i(&names); i.test(); ++i ) {
|
||||
uintptr_t cnt = (uintptr_t)i._value;
|
||||
diff --git a/hotspot/src/share/vm/c1/c1_LinearScan.cpp b/hotspot/src/share/vm/c1/c1_LinearScan.cpp
|
||||
index ec4a67e..d754aa9 100644
|
||||
--- a/hotspot/src/share/vm/c1/c1_LinearScan.cpp
|
||||
+++ b/hotspot/src/share/vm/c1/c1_LinearScan.cpp
|
||||
@@ -5484,7 +5484,7 @@ int LinearScanWalker::find_locked_double_reg(int reg_needed_until, int interval_
|
||||
}
|
||||
}
|
||||
|
||||
- if (_block_pos[max_reg] <= interval_to || _block_pos[max_reg + 1] <= interval_to) {
|
||||
+ if (max_reg != any_reg && (_block_pos[max_reg] <= interval_to || _block_pos[max_reg + 1] <= interval_to)) {
|
||||
*need_split = true;
|
||||
}
|
||||
|
||||
@@ -6443,8 +6443,9 @@ void LinearScanStatistic::print(const char* title) {
|
||||
if (_counters_sum[i] > 0 || _counters_max[i] >= 0) {
|
||||
tty->print("%25s: %8d", counter_name(i), _counters_sum[i]);
|
||||
|
||||
- if (base_counter(i) != invalid_counter) {
|
||||
- tty->print(" (%5.1f%%) ", _counters_sum[i] * 100.0 / _counters_sum[base_counter(i)]);
|
||||
+ LinearScanStatistic::Counter cntr = base_counter(i);
|
||||
+ if (cntr != invalid_counter) {
|
||||
+ tty->print(" (%5.1f%%) ", _counters_sum[i] * 100.0 / _counters_sum[cntr]);
|
||||
} else {
|
||||
tty->print(" ");
|
||||
}
|
||||
diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp
|
||||
index 51ab4f5..d8e99e6 100644
|
||||
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp
|
||||
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp
|
||||
@@ -1085,9 +1085,11 @@ class FieldAllocationCount: public ResourceObj {
|
||||
|
||||
FieldAllocationType update(bool is_static, BasicType type) {
|
||||
FieldAllocationType atype = basic_type_to_atype(is_static, type);
|
||||
- // Make sure there is no overflow with injected fields.
|
||||
- assert(count[atype] < 0xFFFF, "More than 65535 fields");
|
||||
- count[atype]++;
|
||||
+ if (atype != BAD_ALLOCATION_TYPE) {
|
||||
+ // Make sure there is no overflow with injected fields.
|
||||
+ assert(count[atype] < 0xFFFF, "More than 65535 fields");
|
||||
+ count[atype]++;
|
||||
+ }
|
||||
return atype;
|
||||
}
|
||||
};
|
||||
@@ -3087,8 +3089,9 @@ void ClassFileParser::parse_classfile_attributes(ClassFileParser::ClassAnnotatio
|
||||
}
|
||||
} else if (tag == vmSymbols::tag_bootstrap_methods() &&
|
||||
_major_version >= Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
|
||||
- if (parsed_bootstrap_methods_attribute)
|
||||
+ if (parsed_bootstrap_methods_attribute) {
|
||||
classfile_parse_error("Multiple BootstrapMethods attributes in class file %s", CHECK);
|
||||
+ }
|
||||
parsed_bootstrap_methods_attribute = true;
|
||||
parse_classfile_bootstrap_methods_attribute(attribute_length, CHECK);
|
||||
} else if (tag == vmSymbols::tag_runtime_visible_type_annotations()) {
|
||||
diff --git a/hotspot/src/share/vm/classfile/systemDictionary.cpp b/hotspot/src/share/vm/classfile/systemDictionary.cpp
|
||||
index d02ed31..9089a76 100644
|
||||
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp
|
||||
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp
|
||||
@@ -1195,10 +1195,10 @@ Klass* SystemDictionary::resolve_from_stream(Symbol* class_name,
|
||||
while ((index = strchr(name, '/')) != NULL) {
|
||||
*index = '.'; // replace '/' with '.' in package name
|
||||
}
|
||||
- const char* fmt = "Prohibited package name: %s";
|
||||
- size_t len = strlen(fmt) + strlen(name);
|
||||
+ const char* msg_text = "Prohibited package name: ";
|
||||
+ size_t len = strlen(msg_text) + strlen(name) + 1;
|
||||
char* message = NEW_RESOURCE_ARRAY(char, len);
|
||||
- jio_snprintf(message, len, fmt, name);
|
||||
+ jio_snprintf(message, len, "%s%s", msg_text, name);
|
||||
Exceptions::_throw_msg(THREAD_AND_LOCATION,
|
||||
vmSymbols::java_lang_SecurityException(), message);
|
||||
}
|
||||
diff --git a/hotspot/src/share/vm/compiler/compileBroker.cpp b/hotspot/src/share/vm/compiler/compileBroker.cpp
|
||||
index 0e9af0d..7963625 100644
|
||||
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp
|
||||
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp
|
||||
@@ -136,11 +136,6 @@ AbstractCompiler* CompileBroker::_compilers[2];
|
||||
volatile jint CompileBroker::_compilation_id = 0;
|
||||
volatile jint CompileBroker::_osr_compilation_id = 0;
|
||||
|
||||
-// Debugging information
|
||||
-int CompileBroker::_last_compile_type = no_compile;
|
||||
-int CompileBroker::_last_compile_level = CompLevel_none;
|
||||
-char CompileBroker::_last_method_compiled[CompileBroker::name_buffer_length];
|
||||
-
|
||||
// Performance counters
|
||||
PerfCounter* CompileBroker::_perf_total_compilation = NULL;
|
||||
PerfCounter* CompileBroker::_perf_osr_compilation = NULL;
|
||||
@@ -882,8 +877,6 @@ CompilerCounters::CompilerCounters(const char* thread_name, int instance, TRAPS)
|
||||
//
|
||||
// Initialize the Compilation object
|
||||
void CompileBroker::compilation_init() {
|
||||
- _last_method_compiled[0] = '\0';
|
||||
-
|
||||
// No need to initialize compilation system if we do not use it.
|
||||
if (!UseCompiler) {
|
||||
return;
|
||||
@@ -1964,8 +1957,10 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) {
|
||||
}
|
||||
assert(!method->is_native(), "no longer compile natives");
|
||||
|
||||
- // Save information about this method in case of failure.
|
||||
- set_last_compile(thread, method, is_osr, task_level);
|
||||
+ // Update compile information when using perfdata.
|
||||
+ if (UsePerfData) {
|
||||
+ update_compile_perf_data(thread, method, is_osr);
|
||||
+ }
|
||||
|
||||
DTRACE_METHOD_COMPILE_BEGIN_PROBE(method, compiler_name(task_level));
|
||||
}
|
||||
@@ -2180,52 +2175,44 @@ void CompileBroker::handle_full_code_cache() {
|
||||
// CompileBroker::set_last_compile
|
||||
//
|
||||
// Record this compilation for debugging purposes.
|
||||
-void CompileBroker::set_last_compile(CompilerThread* thread, methodHandle method, bool is_osr, int comp_level) {
|
||||
+void CompileBroker::update_compile_perf_data(CompilerThread* thread, const methodHandle& method, bool is_osr) {
|
||||
ResourceMark rm;
|
||||
char* method_name = method->name()->as_C_string();
|
||||
- strncpy(_last_method_compiled, method_name, CompileBroker::name_buffer_length);
|
||||
- _last_method_compiled[CompileBroker::name_buffer_length - 1] = '\0'; // ensure null terminated
|
||||
char current_method[CompilerCounters::cmname_buffer_length];
|
||||
size_t maxLen = CompilerCounters::cmname_buffer_length;
|
||||
|
||||
- if (UsePerfData) {
|
||||
- const char* class_name = method->method_holder()->name()->as_C_string();
|
||||
+ const char* class_name = method->method_holder()->name()->as_C_string();
|
||||
|
||||
- size_t s1len = strlen(class_name);
|
||||
- size_t s2len = strlen(method_name);
|
||||
+ size_t s1len = strlen(class_name);
|
||||
+ size_t s2len = strlen(method_name);
|
||||
|
||||
- // check if we need to truncate the string
|
||||
- if (s1len + s2len + 2 > maxLen) {
|
||||
+ // check if we need to truncate the string
|
||||
+ if (s1len + s2len + 2 > maxLen) {
|
||||
|
||||
- // the strategy is to lop off the leading characters of the
|
||||
- // class name and the trailing characters of the method name.
|
||||
+ // the strategy is to lop off the leading characters of the
|
||||
+ // class name and the trailing characters of the method name.
|
||||
|
||||
- if (s2len + 2 > maxLen) {
|
||||
- // lop of the entire class name string, let snprintf handle
|
||||
- // truncation of the method name.
|
||||
- class_name += s1len; // null string
|
||||
- }
|
||||
- else {
|
||||
- // lop off the extra characters from the front of the class name
|
||||
- class_name += ((s1len + s2len + 2) - maxLen);
|
||||
- }
|
||||
+ if (s2len + 2 > maxLen) {
|
||||
+ // lop of the entire class name string, let snprintf handle
|
||||
+ // truncation of the method name.
|
||||
+ class_name += s1len; // null string
|
||||
+ }
|
||||
+ else {
|
||||
+ // lop off the extra characters from the front of the class name
|
||||
+ class_name += ((s1len + s2len + 2) - maxLen);
|
||||
}
|
||||
-
|
||||
- jio_snprintf(current_method, maxLen, "%s %s", class_name, method_name);
|
||||
}
|
||||
|
||||
+ jio_snprintf(current_method, maxLen, "%s %s", class_name, method_name);
|
||||
+
|
||||
+ int last_compile_type = normal_compile;
|
||||
if (CICountOSR && is_osr) {
|
||||
- _last_compile_type = osr_compile;
|
||||
- } else {
|
||||
- _last_compile_type = normal_compile;
|
||||
+ last_compile_type = normal_compile;
|
||||
}
|
||||
- _last_compile_level = comp_level;
|
||||
|
||||
- if (UsePerfData) {
|
||||
- CompilerCounters* counters = thread->counters();
|
||||
- counters->set_current_method(current_method);
|
||||
- counters->set_compile_type((jlong)_last_compile_type);
|
||||
- }
|
||||
+ CompilerCounters* counters = thread->counters();
|
||||
+ counters->set_current_method(current_method);
|
||||
+ counters->set_compile_type((jlong) last_compile_type);
|
||||
}
|
||||
|
||||
|
||||
@@ -2417,23 +2404,6 @@ void CompileBroker::print_times() {
|
||||
tty->print_cr(" nmethod total size : %6d bytes", CompileBroker::_sum_nmethod_size);
|
||||
}
|
||||
|
||||
-// Debugging output for failure
|
||||
-void CompileBroker::print_last_compile() {
|
||||
- if ( _last_compile_level != CompLevel_none &&
|
||||
- compiler(_last_compile_level) != NULL &&
|
||||
- _last_method_compiled != NULL &&
|
||||
- _last_compile_type != no_compile) {
|
||||
- if (_last_compile_type == osr_compile) {
|
||||
- tty->print_cr("Last parse: [osr]%d+++(%d) %s",
|
||||
- _osr_compilation_id, _last_compile_level, _last_method_compiled);
|
||||
- } else {
|
||||
- tty->print_cr("Last parse: %d+++(%d) %s",
|
||||
- _compilation_id, _last_compile_level, _last_method_compiled);
|
||||
- }
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-
|
||||
void CompileBroker::print_compiler_threads_on(outputStream* st) {
|
||||
#ifndef PRODUCT
|
||||
st->print_cr("Compiler thread printing unimplemented.");
|
||||
diff --git a/hotspot/src/share/vm/compiler/compileBroker.hpp b/hotspot/src/share/vm/compiler/compileBroker.hpp
|
||||
index 16e0ba3..96d5e81 100644
|
||||
--- a/hotspot/src/share/vm/compiler/compileBroker.hpp
|
||||
+++ b/hotspot/src/share/vm/compiler/compileBroker.hpp
|
||||
@@ -265,7 +265,7 @@ class CompileBroker: AllStatic {
|
||||
name_buffer_length = 100
|
||||
};
|
||||
|
||||
- // Compile type Information for print_last_compile() and CompilerCounters
|
||||
+ // Compile type Information for CompilerCounters
|
||||
enum { no_compile, normal_compile, osr_compile, native_compile };
|
||||
static int assign_compile_id (methodHandle method, int osr_bci);
|
||||
|
||||
@@ -284,10 +284,6 @@ class CompileBroker: AllStatic {
|
||||
static volatile jint _compilation_id;
|
||||
static volatile jint _osr_compilation_id;
|
||||
|
||||
- static int _last_compile_type;
|
||||
- static int _last_compile_level;
|
||||
- static char _last_method_compiled[name_buffer_length];
|
||||
-
|
||||
static CompileQueue* _c2_compile_queue;
|
||||
static CompileQueue* _c1_compile_queue;
|
||||
|
||||
@@ -356,7 +352,7 @@ class CompileBroker: AllStatic {
|
||||
static void wait_for_completion(CompileTask* task);
|
||||
|
||||
static void invoke_compiler_on_method(CompileTask* task);
|
||||
- static void set_last_compile(CompilerThread *thread, methodHandle method, bool is_osr, int comp_level);
|
||||
+ static void update_compile_perf_data(CompilerThread *thread, const methodHandle& method, bool is_osr);
|
||||
static void push_jni_handle_block();
|
||||
static void pop_jni_handle_block();
|
||||
static bool check_break_at(methodHandle method, int compile_id, bool is_osr);
|
||||
@@ -454,9 +450,6 @@ class CompileBroker: AllStatic {
|
||||
// Print a detailed accounting of compilation time
|
||||
static void print_times();
|
||||
|
||||
- // Debugging output for failure
|
||||
- static void print_last_compile();
|
||||
-
|
||||
static void print_compiler_threads_on(outputStream* st);
|
||||
|
||||
// compiler name for debugging
|
||||
diff --git a/hotspot/src/share/vm/compiler/compileLog.cpp b/hotspot/src/share/vm/compiler/compileLog.cpp
|
||||
index 0637fd0..7dd9b46 100644
|
||||
--- a/hotspot/src/share/vm/compiler/compileLog.cpp
|
||||
+++ b/hotspot/src/share/vm/compiler/compileLog.cpp
|
||||
@@ -221,7 +221,8 @@ void CompileLog::finish_log_on_error(outputStream* file, char* buf, int buflen)
|
||||
// Copy any remaining data inside a quote:
|
||||
bool saw_slop = false;
|
||||
int end_cdata = 0; // state machine [0..2] watching for too many "]]"
|
||||
- while ((nr = read(partial_fd, buf, buflen)) > 0) {
|
||||
+ while ((nr = read(partial_fd, buf, buflen-1)) > 0) {
|
||||
+ buf[buflen-1] = '\0';
|
||||
if (!saw_slop) {
|
||||
file->print_raw_cr("<fragment>");
|
||||
file->print_raw_cr("<![CDATA[");
|
||||
diff --git a/hotspot/src/share/vm/compiler/disassembler.cpp b/hotspot/src/share/vm/compiler/disassembler.cpp
|
||||
index dfdd5f7..063f86a 100644
|
||||
--- a/hotspot/src/share/vm/compiler/disassembler.cpp
|
||||
+++ b/hotspot/src/share/vm/compiler/disassembler.cpp
|
||||
@@ -92,7 +92,7 @@ bool Disassembler::load_library() {
|
||||
const char* p = strrchr(buf, *os::file_separator());
|
||||
if (p != NULL) lib_offset = p - base + 1;
|
||||
p = strstr(p ? p : base, "jvm");
|
||||
- if (p != NULL) jvm_offset = p - base;
|
||||
+ if (p != NULL) jvm_offset = p - base;
|
||||
}
|
||||
// Find the disassembler shared library.
|
||||
// Search for several paths derived from libjvm, in this order:
|
||||
@@ -105,13 +105,13 @@ bool Disassembler::load_library() {
|
||||
strcpy(&buf[jvm_offset], hsdis_library_name);
|
||||
strcat(&buf[jvm_offset], os::dll_file_extension());
|
||||
_library = os::dll_load(buf, ebuf, sizeof ebuf);
|
||||
- if (_library == NULL) {
|
||||
+ if (_library == NULL && lib_offset >= 0) {
|
||||
// 2. <home>/jre/lib/<arch>/<vm>/hsdis-<arch>.so
|
||||
strcpy(&buf[lib_offset], hsdis_library_name);
|
||||
strcat(&buf[lib_offset], os::dll_file_extension());
|
||||
_library = os::dll_load(buf, ebuf, sizeof ebuf);
|
||||
}
|
||||
- if (_library == NULL) {
|
||||
+ if (_library == NULL && lib_offset > 0) {
|
||||
// 3. <home>/jre/lib/<arch>/hsdis-<arch>.so
|
||||
buf[lib_offset - 1] = '\0';
|
||||
const char* p = strrchr(buf, *os::file_separator());
|
||||
diff --git a/hotspot/src/share/vm/oops/generateOopMap.cpp b/hotspot/src/share/vm/oops/generateOopMap.cpp
|
||||
index bb951f8..8452f96 100644
|
||||
--- a/hotspot/src/share/vm/oops/generateOopMap.cpp
|
||||
+++ b/hotspot/src/share/vm/oops/generateOopMap.cpp
|
||||
@@ -1684,7 +1684,13 @@ void GenerateOopMap::ppdupswap(int poplen, const char *out) {
|
||||
assert(poplen < 5, "this must be less than length of actual vector");
|
||||
|
||||
// pop all arguments
|
||||
- for(int i = 0; i < poplen; i++) actual[i] = pop();
|
||||
+ for (int i = 0; i < poplen; i++) {
|
||||
+ actual[i] = pop();
|
||||
+ }
|
||||
+ // Field _state is uninitialized when calling push.
|
||||
+ for (int i = poplen; i < 5; i++) {
|
||||
+ actual[i] = CellTypeState::uninit;
|
||||
+ }
|
||||
|
||||
// put them back
|
||||
char push_ch = *out++;
|
||||
diff --git a/hotspot/src/share/vm/opto/block.cpp b/hotspot/src/share/vm/opto/block.cpp
|
||||
index 245ce42..1789d49 100644
|
||||
--- a/hotspot/src/share/vm/opto/block.cpp
|
||||
+++ b/hotspot/src/share/vm/opto/block.cpp
|
||||
@@ -1430,7 +1430,7 @@ void PhaseBlockLayout::find_edges() {
|
||||
if (n->num_preds() != 1) break;
|
||||
|
||||
i++;
|
||||
- assert(n = _cfg.get_block(i), "expecting next block");
|
||||
+ assert(n == _cfg.get_block(i), "expecting next block");
|
||||
tr->append(n);
|
||||
uf->map(n->_pre_order, tr->id());
|
||||
traces[n->_pre_order] = NULL;
|
||||
diff --git a/hotspot/src/share/vm/opto/graphKit.cpp b/hotspot/src/share/vm/opto/graphKit.cpp
|
||||
index f7c1009..dfadd3e 100644
|
||||
--- a/hotspot/src/share/vm/opto/graphKit.cpp
|
||||
+++ b/hotspot/src/share/vm/opto/graphKit.cpp
|
||||
@@ -1074,7 +1074,7 @@ bool GraphKit::compute_stack_effects(int& inputs, int& depth) {
|
||||
case Bytecodes::_freturn:
|
||||
case Bytecodes::_dreturn:
|
||||
case Bytecodes::_areturn:
|
||||
- assert(rsize = -depth, "");
|
||||
+ assert(rsize == -depth, "");
|
||||
inputs = rsize;
|
||||
break;
|
||||
|
||||
diff --git a/hotspot/src/share/vm/opto/matcher.cpp b/hotspot/src/share/vm/opto/matcher.cpp
|
||||
index b26015c..11e11e0 100644
|
||||
--- a/hotspot/src/share/vm/opto/matcher.cpp
|
||||
+++ b/hotspot/src/share/vm/opto/matcher.cpp
|
||||
@@ -659,11 +659,14 @@ void Matcher::Fixup_Save_On_Entry( ) {
|
||||
uint reth_edge_cnt = TypeFunc::Parms+1;
|
||||
RegMask *reth_rms = init_input_masks( reth_edge_cnt + soe_cnt, _return_addr_mask, c_frame_ptr_mask );
|
||||
// Rethrow takes exception oop only, but in the argument 0 slot.
|
||||
- reth_rms[TypeFunc::Parms] = mreg2regmask[find_receiver(false)];
|
||||
+ OptoReg::Name reg = find_receiver(false);
|
||||
+ if (reg >= 0) {
|
||||
+ reth_rms[TypeFunc::Parms] = mreg2regmask[reg];
|
||||
#ifdef _LP64
|
||||
- // Need two slots for ptrs in 64-bit land
|
||||
- reth_rms[TypeFunc::Parms].Insert(OptoReg::add(OptoReg::Name(find_receiver(false)),1));
|
||||
+ // Need two slots for ptrs in 64-bit land
|
||||
+ reth_rms[TypeFunc::Parms].Insert(OptoReg::add(OptoReg::Name(reg), 1));
|
||||
#endif
|
||||
+ }
|
||||
|
||||
// Input RegMask array shared by all TailCalls
|
||||
uint tail_call_edge_cnt = TypeFunc::Parms+2;
|
||||
diff --git a/hotspot/src/share/vm/runtime/relocator.cpp b/hotspot/src/share/vm/runtime/relocator.cpp
|
||||
index 450bcf2..2bbb8db 100644
|
||||
--- a/hotspot/src/share/vm/runtime/relocator.cpp
|
||||
+++ b/hotspot/src/share/vm/runtime/relocator.cpp
|
||||
@@ -612,8 +612,8 @@ bool Relocator::relocate_code(int bci, int ilen, int delta) {
|
||||
// In case we have shrunken a tableswitch/lookupswitch statement, we store the last
|
||||
// bytes that get overwritten. We have to copy the bytes after the change_jumps method
|
||||
// has been called, since it is likly to update last offset in a tableswitch/lookupswitch
|
||||
- if (delta < 0) {
|
||||
- assert(delta>=-3, "we cannot overwrite more than 3 bytes");
|
||||
+ assert(delta >= -3, "We cannot overwrite more than 3 bytes.");
|
||||
+ if (delta < 0 && delta >= -3) {
|
||||
memcpy(_overwrite, addr_at(bci + ilen + delta), -delta);
|
||||
}
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
561
8189688-NMT-Report-per-class-load-metadata-informati.patch
Normal file
561
8189688-NMT-Report-per-class-load-metadata-informati.patch
Normal file
@ -0,0 +1,561 @@
|
||||
From 528a3b6459e34532120f468ba9afb8833d516f5a Mon Sep 17 00:00:00 2001
|
||||
From: eapen <zhangyipeng7@huawei.com>
|
||||
Date: Thu, 15 Dec 2022 11:38:55 +0800
|
||||
Subject: [PATCH 19/33] I68TO2: 8189688: NMT: Report per-class load metadata
|
||||
information
|
||||
---
|
||||
hotspot/src/share/vm/memory/metaspace.cpp | 322 ++++++++++++++++++++++++-
|
||||
hotspot/src/share/vm/memory/metaspace.hpp | 4 +
|
||||
hotspot/src/share/vm/runtime/vm_operations.cpp | 4 +
|
||||
hotspot/src/share/vm/runtime/vm_operations.hpp | 12 +
|
||||
hotspot/src/share/vm/services/nmtDCmd.cpp | 16 +-
|
||||
hotspot/src/share/vm/services/nmtDCmd.hpp | 1 +
|
||||
6 files changed, 354 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp
|
||||
index 6c4654b..cf4a112 100644
|
||||
--- a/hotspot/src/share/vm/memory/metaspace.cpp
|
||||
+++ b/hotspot/src/share/vm/memory/metaspace.cpp
|
||||
@@ -75,6 +75,22 @@ enum ChunkIndex {
|
||||
NumberOfInUseLists = 4
|
||||
};
|
||||
|
||||
+// Helper, returns a descriptive name for the given index.
|
||||
+static const char* chunk_size_name(ChunkIndex index) {
|
||||
+ switch (index) {
|
||||
+ case SpecializedIndex:
|
||||
+ return "specialized";
|
||||
+ case SmallIndex:
|
||||
+ return "small";
|
||||
+ case MediumIndex:
|
||||
+ return "medium";
|
||||
+ case HumongousIndex:
|
||||
+ return "humongous";
|
||||
+ default:
|
||||
+ return "Invalid index";
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
enum ChunkSizes { // in words.
|
||||
ClassSpecializedChunk = 128,
|
||||
SpecializedChunk = 128,
|
||||
@@ -89,6 +105,18 @@ static ChunkIndex next_chunk_index(ChunkIndex i) {
|
||||
return (ChunkIndex) (i+1);
|
||||
}
|
||||
|
||||
+static const char* scale_unit(size_t scale) {
|
||||
+ switch(scale) {
|
||||
+ case 1: return "BYTES";
|
||||
+ case K: return "KB";
|
||||
+ case M: return "MB";
|
||||
+ case G: return "GB";
|
||||
+ default:
|
||||
+ ShouldNotReachHere();
|
||||
+ return NULL;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
volatile intptr_t MetaspaceGC::_capacity_until_GC = 0;
|
||||
uint MetaspaceGC::_shrink_factor = 0;
|
||||
bool MetaspaceGC::_should_concurrent_collect = false;
|
||||
@@ -141,6 +169,18 @@ class ChunkManager : public CHeapObj<mtInternal> {
|
||||
}
|
||||
void verify_free_chunks_count();
|
||||
|
||||
+ struct ChunkManagerStatistics {
|
||||
+ size_t num_by_type[NumberOfFreeLists];
|
||||
+ size_t single_size_by_type[NumberOfFreeLists];
|
||||
+ size_t total_size_by_type[NumberOfFreeLists];
|
||||
+ size_t num_humongous_chunks;
|
||||
+ size_t total_size_humongous_chunks;
|
||||
+ };
|
||||
+
|
||||
+ void locked_get_statistics(ChunkManagerStatistics* stat) const;
|
||||
+ void get_statistics(ChunkManagerStatistics* stat) const;
|
||||
+ static void print_statistics(const ChunkManagerStatistics* stat, outputStream* out, size_t scale);
|
||||
+
|
||||
public:
|
||||
|
||||
ChunkManager(size_t specialized_size, size_t small_size, size_t medium_size)
|
||||
@@ -157,6 +197,9 @@ class ChunkManager : public CHeapObj<mtInternal> {
|
||||
// for special, small, medium, and humongous chunks.
|
||||
ChunkIndex list_index(size_t size);
|
||||
|
||||
+ // Map a given index to the chunk size.
|
||||
+ size_t size_by_index(ChunkIndex index) const;
|
||||
+
|
||||
// Remove the chunk from its freelist. It is
|
||||
// expected to be on one of the _free_chunks[] lists.
|
||||
void remove_chunk(Metachunk* chunk);
|
||||
@@ -249,6 +292,10 @@ class ChunkManager : public CHeapObj<mtInternal> {
|
||||
void locked_print_sum_free_chunks(outputStream* st);
|
||||
|
||||
void print_on(outputStream* st) const;
|
||||
+
|
||||
+ // Prints composition for both non-class and (if available)
|
||||
+ // class chunk manager.
|
||||
+ static void print_all_chunkmanagers(outputStream* out, size_t scale = 1);
|
||||
};
|
||||
|
||||
// Used to manage the free list of Metablocks (a block corresponds
|
||||
@@ -1707,7 +1754,6 @@ bool Metadebug::test_metadata_failure() {
|
||||
#endif
|
||||
|
||||
// ChunkManager methods
|
||||
-
|
||||
size_t ChunkManager::free_chunks_total_words() {
|
||||
return _free_chunks_total;
|
||||
}
|
||||
@@ -1729,6 +1775,12 @@ size_t ChunkManager::free_chunks_count() {
|
||||
return _free_chunks_count;
|
||||
}
|
||||
|
||||
+size_t ChunkManager::size_by_index(ChunkIndex index) const {
|
||||
+ index_bounds_check(index);
|
||||
+ assert(index != HumongousIndex, "Do not call for humongous chunks.");
|
||||
+ return _free_chunks[index].size();
|
||||
+}
|
||||
+
|
||||
void ChunkManager::locked_verify_free_chunks_total() {
|
||||
assert_lock_strong(SpaceManager::expand_lock());
|
||||
assert(sum_free_chunks() == _free_chunks_total,
|
||||
@@ -1918,7 +1970,83 @@ Metachunk* ChunkManager::chunk_freelist_allocate(size_t word_size) {
|
||||
|
||||
void ChunkManager::print_on(outputStream* out) const {
|
||||
if (PrintFLSStatistics != 0) {
|
||||
- const_cast<ChunkManager *>(this)->humongous_dictionary()->report_statistics();
|
||||
+ _humongous_dictionary.report_statistics();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void ChunkManager::locked_get_statistics(ChunkManagerStatistics* stat) const {
|
||||
+ assert_lock_strong(SpaceManager::expand_lock());
|
||||
+ for (ChunkIndex i = ZeroIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) {
|
||||
+ stat->num_by_type[i] = num_free_chunks(i);
|
||||
+ stat->single_size_by_type[i] = size_by_index(i);
|
||||
+ stat->total_size_by_type[i] = size_free_chunks_in_bytes(i);
|
||||
+ }
|
||||
+ stat->num_humongous_chunks = num_free_chunks(HumongousIndex);
|
||||
+ stat->total_size_humongous_chunks = size_free_chunks_in_bytes(HumongousIndex);
|
||||
+}
|
||||
+
|
||||
+void ChunkManager::get_statistics(ChunkManagerStatistics* stat) const {
|
||||
+ MutexLockerEx cl(SpaceManager::expand_lock(),
|
||||
+ Mutex::_no_safepoint_check_flag);
|
||||
+ locked_get_statistics(stat);
|
||||
+}
|
||||
+
|
||||
+void ChunkManager::print_statistics(const ChunkManagerStatistics* stat, outputStream* out, size_t scale) {
|
||||
+ size_t total = 0;
|
||||
+ assert(scale == 1 || scale == K || scale == M || scale == G, "Invalid scale");
|
||||
+
|
||||
+ const char* unit = scale_unit(scale);
|
||||
+ for (ChunkIndex i = ZeroIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) {
|
||||
+ out->print(" " SIZE_FORMAT " %s (" SIZE_FORMAT " bytes) chunks, total ",
|
||||
+ stat->num_by_type[i], chunk_size_name(i),
|
||||
+ stat->single_size_by_type[i]);
|
||||
+ if (scale == 1) {
|
||||
+ out->print_cr(SIZE_FORMAT " bytes", stat->total_size_by_type[i]);
|
||||
+ } else {
|
||||
+ out->print_cr("%.2f%s", (float)stat->total_size_by_type[i] / scale, unit);
|
||||
+ }
|
||||
+
|
||||
+ total += stat->total_size_by_type[i];
|
||||
+ }
|
||||
+
|
||||
+ total += stat->total_size_humongous_chunks;
|
||||
+
|
||||
+ if (scale == 1) {
|
||||
+ out->print_cr(" " SIZE_FORMAT " humongous chunks, total " SIZE_FORMAT " bytes",
|
||||
+ stat->num_humongous_chunks, stat->total_size_humongous_chunks);
|
||||
+
|
||||
+ out->print_cr(" total size: " SIZE_FORMAT " bytes.", total);
|
||||
+ } else {
|
||||
+ out->print_cr(" " SIZE_FORMAT " humongous chunks, total %.2f%s",
|
||||
+ stat->num_humongous_chunks,
|
||||
+ (float)stat->total_size_humongous_chunks / scale, unit);
|
||||
+
|
||||
+ out->print_cr(" total size: %.2f%s.", (float)total / scale, unit);
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
+
|
||||
+void ChunkManager::print_all_chunkmanagers(outputStream* out, size_t scale) {
|
||||
+ assert(scale == 1 || scale == K || scale == M || scale == G, "Invalid scale");
|
||||
+
|
||||
+ // Note: keep lock protection only to retrieving statistics; keep printing
|
||||
+ // out of lock protection
|
||||
+ ChunkManagerStatistics stat;
|
||||
+ out->print_cr("Chunkmanager (non-class):");
|
||||
+ const ChunkManager* const non_class_cm = Metaspace::chunk_manager_metadata();
|
||||
+ if (non_class_cm != NULL) {
|
||||
+ non_class_cm->get_statistics(&stat);
|
||||
+ ChunkManager::print_statistics(&stat, out, scale);
|
||||
+ } else {
|
||||
+ out->print_cr("unavailable.");
|
||||
+ }
|
||||
+ out->print_cr("Chunkmanager (class):");
|
||||
+ const ChunkManager* const class_cm = Metaspace::chunk_manager_class();
|
||||
+ if (class_cm != NULL) {
|
||||
+ class_cm->get_statistics(&stat);
|
||||
+ ChunkManager::print_statistics(&stat, out, scale);
|
||||
+ } else {
|
||||
+ out->print_cr("unavailable.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2930,6 +3058,195 @@ void MetaspaceAux::print_waste(outputStream* out) {
|
||||
}
|
||||
}
|
||||
|
||||
+class MetadataStats VALUE_OBJ_CLASS_SPEC {
|
||||
+private:
|
||||
+ size_t _capacity;
|
||||
+ size_t _used;
|
||||
+ size_t _free;
|
||||
+ size_t _waste;
|
||||
+
|
||||
+public:
|
||||
+ MetadataStats() : _capacity(0), _used(0), _free(0), _waste(0) { }
|
||||
+ MetadataStats(size_t capacity, size_t used, size_t free, size_t waste)
|
||||
+ : _capacity(capacity), _used(used), _free(free), _waste(waste) { }
|
||||
+
|
||||
+ void add(const MetadataStats& stats) {
|
||||
+ _capacity += stats.capacity();
|
||||
+ _used += stats.used();
|
||||
+ _free += stats.free();
|
||||
+ _waste += stats.waste();
|
||||
+ }
|
||||
+
|
||||
+ size_t capacity() const { return _capacity; }
|
||||
+ size_t used() const { return _used; }
|
||||
+ size_t free() const { return _free; }
|
||||
+ size_t waste() const { return _waste; }
|
||||
+
|
||||
+ void print_on(outputStream* out, size_t scale) const;
|
||||
+};
|
||||
+
|
||||
+
|
||||
+void MetadataStats::print_on(outputStream* out, size_t scale) const {
|
||||
+ const char* unit = scale_unit(scale);
|
||||
+ out->print_cr("capacity=%10.2f%s used=%10.2f%s free=%10.2f%s waste=%10.2f%s",
|
||||
+ (float)capacity() / scale, unit,
|
||||
+ (float)used() / scale, unit,
|
||||
+ (float)free() / scale, unit,
|
||||
+ (float)waste() / scale, unit);
|
||||
+}
|
||||
+
|
||||
+class PrintCLDMetaspaceInfoClosure : public CLDClosure {
|
||||
+private:
|
||||
+ outputStream* _out;
|
||||
+ size_t _scale;
|
||||
+
|
||||
+ size_t _total_count;
|
||||
+ MetadataStats _total_metadata;
|
||||
+ MetadataStats _total_class;
|
||||
+
|
||||
+ size_t _total_anon_count;
|
||||
+ MetadataStats _total_anon_metadata;
|
||||
+ MetadataStats _total_anon_class;
|
||||
+
|
||||
+public:
|
||||
+ PrintCLDMetaspaceInfoClosure(outputStream* out, size_t scale = K)
|
||||
+ : _out(out), _scale(scale), _total_count(0), _total_anon_count(0) { }
|
||||
+
|
||||
+ ~PrintCLDMetaspaceInfoClosure() {
|
||||
+ print_summary();
|
||||
+ }
|
||||
+
|
||||
+ void do_cld(ClassLoaderData* cld) {
|
||||
+ assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
|
||||
+
|
||||
+ if (cld->is_unloading()) return;
|
||||
+ Metaspace* msp = cld->metaspace_or_null();
|
||||
+ if (msp == NULL) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ bool anonymous = false;
|
||||
+ if (cld->is_anonymous()) {
|
||||
+ _out->print_cr("ClassLoader: for anonymous class");
|
||||
+ anonymous = true;
|
||||
+ } else {
|
||||
+ ResourceMark rm;
|
||||
+ _out->print_cr("ClassLoader: %s", cld->loader_name());
|
||||
+ }
|
||||
+
|
||||
+ print_metaspace(msp, anonymous);
|
||||
+ _out->cr();
|
||||
+ }
|
||||
+
|
||||
+private:
|
||||
+ void print_metaspace(Metaspace* msp, bool anonymous);
|
||||
+ void print_summary() const;
|
||||
+};
|
||||
+
|
||||
+void PrintCLDMetaspaceInfoClosure::print_metaspace(Metaspace* msp, bool anonymous){
|
||||
+ assert(msp != NULL, "Sanity");
|
||||
+ SpaceManager* vsm = msp->vsm();
|
||||
+ const char* unit = scale_unit(_scale);
|
||||
+
|
||||
+ size_t capacity = vsm->sum_capacity_in_chunks_in_use() * BytesPerWord;
|
||||
+ size_t used = vsm->sum_used_in_chunks_in_use() * BytesPerWord;
|
||||
+ size_t free = vsm->sum_free_in_chunks_in_use() * BytesPerWord;
|
||||
+ size_t waste = vsm->sum_waste_in_chunks_in_use() * BytesPerWord;
|
||||
+
|
||||
+ _total_count ++;
|
||||
+ MetadataStats metadata_stats(capacity, used, free, waste);
|
||||
+ _total_metadata.add(metadata_stats);
|
||||
+
|
||||
+ if (anonymous) {
|
||||
+ _total_anon_count ++;
|
||||
+ _total_anon_metadata.add(metadata_stats);
|
||||
+ }
|
||||
+
|
||||
+ _out->print(" Metadata ");
|
||||
+ metadata_stats.print_on(_out, _scale);
|
||||
+
|
||||
+ if (Metaspace::using_class_space()) {
|
||||
+ vsm = msp->class_vsm();
|
||||
+
|
||||
+ capacity = vsm->sum_capacity_in_chunks_in_use() * BytesPerWord;
|
||||
+ used = vsm->sum_used_in_chunks_in_use() * BytesPerWord;
|
||||
+ free = vsm->sum_free_in_chunks_in_use() * BytesPerWord;
|
||||
+ waste = vsm->sum_waste_in_chunks_in_use() * BytesPerWord;
|
||||
+
|
||||
+ MetadataStats class_stats(capacity, used, free, waste);
|
||||
+ _total_class.add(class_stats);
|
||||
+
|
||||
+ if (anonymous) {
|
||||
+ _total_anon_class.add(class_stats);
|
||||
+ }
|
||||
+
|
||||
+ _out->print(" Class data ");
|
||||
+ class_stats.print_on(_out, _scale);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void PrintCLDMetaspaceInfoClosure::print_summary() const {
|
||||
+ const char* unit = scale_unit(_scale);
|
||||
+ _out->cr();
|
||||
+ _out->print_cr("Summary:");
|
||||
+
|
||||
+ MetadataStats total;
|
||||
+ total.add(_total_metadata);
|
||||
+ total.add(_total_class);
|
||||
+
|
||||
+ _out->print(" Total class loaders=" SIZE_FORMAT_W(6) " ", _total_count);
|
||||
+ total.print_on(_out, _scale);
|
||||
+
|
||||
+ _out->print(" Metadata ");
|
||||
+ _total_metadata.print_on(_out, _scale);
|
||||
+
|
||||
+ if (Metaspace::using_class_space()) {
|
||||
+ _out->print(" Class data ");
|
||||
+ _total_class.print_on(_out, _scale);
|
||||
+ }
|
||||
+ _out->cr();
|
||||
+
|
||||
+ MetadataStats total_anon;
|
||||
+ total_anon.add(_total_anon_metadata);
|
||||
+ total_anon.add(_total_anon_class);
|
||||
+
|
||||
+ _out->print("For anonymous classes=" SIZE_FORMAT_W(6) " ", _total_anon_count);
|
||||
+ total_anon.print_on(_out, _scale);
|
||||
+
|
||||
+ _out->print(" Metadata ");
|
||||
+ _total_anon_metadata.print_on(_out, _scale);
|
||||
+
|
||||
+ if (Metaspace::using_class_space()) {
|
||||
+ _out->print(" Class data ");
|
||||
+ _total_anon_class.print_on(_out, _scale);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void MetaspaceAux::print_metadata_for_nmt(outputStream* out, size_t scale) {
|
||||
+ const char* unit = scale_unit(scale);
|
||||
+ out->print_cr("Metaspaces:");
|
||||
+ out->print_cr(" Metadata space: reserved=" SIZE_FORMAT_W(10) "%s committed=" SIZE_FORMAT_W(10) "%s",
|
||||
+ reserved_bytes(Metaspace::NonClassType) / scale, unit,
|
||||
+ committed_bytes(Metaspace::NonClassType) / scale, unit);
|
||||
+ if (Metaspace::using_class_space()) {
|
||||
+ out->print_cr(" Class space: reserved=" SIZE_FORMAT_W(10) "%s committed=" SIZE_FORMAT_W(10) "%s",
|
||||
+ reserved_bytes(Metaspace::ClassType) / scale, unit,
|
||||
+ committed_bytes(Metaspace::ClassType) / scale, unit);
|
||||
+ }
|
||||
+
|
||||
+ out->cr();
|
||||
+ ChunkManager::print_all_chunkmanagers(out, scale);
|
||||
+
|
||||
+ out->cr();
|
||||
+ out->print_cr("Per-classloader metadata:");
|
||||
+ out->cr();
|
||||
+
|
||||
+ PrintCLDMetaspaceInfoClosure cl(out, scale);
|
||||
+ ClassLoaderDataGraph::cld_do(&cl);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+
|
||||
// Dump global metaspace things from the end of ClassLoaderDataGraph
|
||||
void MetaspaceAux::dump(outputStream* out) {
|
||||
out->print_cr("All Metaspace:");
|
||||
@@ -3743,6 +4060,7 @@ void Metaspace::report_metadata_oome(ClassLoaderData* loader_data, size_t word_s
|
||||
loader_data->dump(gclog_or_tty);
|
||||
}
|
||||
MetaspaceAux::dump(gclog_or_tty);
|
||||
+ ChunkManager::print_all_chunkmanagers(gclog_or_tty);
|
||||
}
|
||||
|
||||
bool out_of_compressed_class_space = false;
|
||||
diff --git a/hotspot/src/share/vm/memory/metaspace.hpp b/hotspot/src/share/vm/memory/metaspace.hpp
|
||||
index 122dd4b..ff1b232 100644
|
||||
--- a/hotspot/src/share/vm/memory/metaspace.hpp
|
||||
+++ b/hotspot/src/share/vm/memory/metaspace.hpp
|
||||
@@ -65,6 +65,7 @@ class MetaspaceTracer;
|
||||
class MetaWord;
|
||||
class Mutex;
|
||||
class outputStream;
|
||||
+class PrintCLDMetaspaceInfoClosure;
|
||||
class SpaceManager;
|
||||
class VirtualSpaceList;
|
||||
|
||||
@@ -88,6 +89,7 @@ class Metaspace : public CHeapObj<mtClass> {
|
||||
friend class VM_CollectForMetadataAllocation;
|
||||
friend class MetaspaceGC;
|
||||
friend class MetaspaceAux;
|
||||
+ friend class PrintCLDMetaspaceInfoClosure;
|
||||
|
||||
public:
|
||||
enum MetadataType {
|
||||
@@ -372,6 +374,8 @@ class MetaspaceAux : AllStatic {
|
||||
return min_chunk_size_words() * BytesPerWord;
|
||||
}
|
||||
|
||||
+ static void print_metadata_for_nmt(outputStream* out, size_t scale = K);
|
||||
+
|
||||
static bool has_chunk_free_list(Metaspace::MetadataType mdtype);
|
||||
static MetaspaceChunkFreeListSummary chunk_free_list_summary(Metaspace::MetadataType mdtype);
|
||||
|
||||
diff --git a/hotspot/src/share/vm/runtime/vm_operations.cpp b/hotspot/src/share/vm/runtime/vm_operations.cpp
|
||||
index d401ea6..b42d18f 100644
|
||||
--- a/hotspot/src/share/vm/runtime/vm_operations.cpp
|
||||
+++ b/hotspot/src/share/vm/runtime/vm_operations.cpp
|
||||
@@ -209,6 +209,10 @@ void VM_PrintJNI::doit() {
|
||||
JNIHandles::print_on(_out);
|
||||
}
|
||||
|
||||
+void VM_PrintMetadata::doit() {
|
||||
+ MetaspaceAux::print_metadata_for_nmt(_out, _scale);
|
||||
+}
|
||||
+
|
||||
VM_FindDeadlocks::~VM_FindDeadlocks() {
|
||||
if (_deadlocks != NULL) {
|
||||
DeadlockCycle* cycle = _deadlocks;
|
||||
diff --git a/hotspot/src/share/vm/runtime/vm_operations.hpp b/hotspot/src/share/vm/runtime/vm_operations.hpp
|
||||
index 3744040..19c33f8 100644
|
||||
--- a/hotspot/src/share/vm/runtime/vm_operations.hpp
|
||||
+++ b/hotspot/src/share/vm/runtime/vm_operations.hpp
|
||||
@@ -101,6 +101,7 @@
|
||||
template(ClassLoaderHierarchyOperation) \
|
||||
template(JFROldObject) \
|
||||
template(PrintClasses) \
|
||||
+ template(PrintMetadata) \
|
||||
|
||||
class VM_Operation: public CHeapObj<mtInternal> {
|
||||
public:
|
||||
@@ -329,6 +330,17 @@ class VM_PrintJNI: public VM_Operation {
|
||||
void doit();
|
||||
};
|
||||
|
||||
+class VM_PrintMetadata : public VM_Operation {
|
||||
+ private:
|
||||
+ outputStream* _out;
|
||||
+ size_t _scale;
|
||||
+ public:
|
||||
+ VM_PrintMetadata(outputStream* out, size_t scale) : _out(out), _scale(scale) {};
|
||||
+
|
||||
+ VMOp_Type type() const { return VMOp_PrintMetadata; }
|
||||
+ void doit();
|
||||
+};
|
||||
+
|
||||
class DeadlockCycle;
|
||||
class VM_FindDeadlocks: public VM_Operation {
|
||||
private:
|
||||
diff --git a/hotspot/src/share/vm/services/nmtDCmd.cpp b/hotspot/src/share/vm/services/nmtDCmd.cpp
|
||||
index fcad784..659ca33 100644
|
||||
--- a/hotspot/src/share/vm/services/nmtDCmd.cpp
|
||||
+++ b/hotspot/src/share/vm/services/nmtDCmd.cpp
|
||||
@@ -24,6 +24,8 @@
|
||||
#include "precompiled.hpp"
|
||||
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
+#include "runtime/vmThread.hpp"
|
||||
+#include "runtime/vm_operations.hpp"
|
||||
#include "services/nmtDCmd.hpp"
|
||||
#include "services/memReporter.hpp"
|
||||
#include "services/memTracker.hpp"
|
||||
@@ -38,6 +40,8 @@ NMTDCmd::NMTDCmd(outputStream* output,
|
||||
_detail("detail", "request runtime to report memory allocation >= "
|
||||
"1K by each callsite.",
|
||||
"BOOLEAN", false, "false"),
|
||||
+ _metadata("metadata", "request runtime to report metadata information",
|
||||
+ "BOOLEAN", false, "false"),
|
||||
_baseline("baseline", "request runtime to baseline current memory usage, " \
|
||||
"so it can be compared against in later time.",
|
||||
"BOOLEAN", false, "false"),
|
||||
@@ -57,6 +61,7 @@ NMTDCmd::NMTDCmd(outputStream* output,
|
||||
"STRING", false, "KB") {
|
||||
_dcmdparser.add_dcmd_option(&_summary);
|
||||
_dcmdparser.add_dcmd_option(&_detail);
|
||||
+ _dcmdparser.add_dcmd_option(&_metadata);
|
||||
_dcmdparser.add_dcmd_option(&_baseline);
|
||||
_dcmdparser.add_dcmd_option(&_summary_diff);
|
||||
_dcmdparser.add_dcmd_option(&_detail_diff);
|
||||
@@ -92,6 +97,7 @@ void NMTDCmd::execute(DCmdSource source, TRAPS) {
|
||||
int nopt = 0;
|
||||
if (_summary.is_set() && _summary.value()) { ++nopt; }
|
||||
if (_detail.is_set() && _detail.value()) { ++nopt; }
|
||||
+ if (_metadata.is_set() && _metadata.value()) { ++nopt; }
|
||||
if (_baseline.is_set() && _baseline.value()) { ++nopt; }
|
||||
if (_summary_diff.is_set() && _summary_diff.value()) { ++nopt; }
|
||||
if (_detail_diff.is_set() && _detail_diff.value()) { ++nopt; }
|
||||
@@ -100,7 +106,7 @@ void NMTDCmd::execute(DCmdSource source, TRAPS) {
|
||||
|
||||
if (nopt > 1) {
|
||||
output()->print_cr("At most one of the following option can be specified: " \
|
||||
- "summary, detail, baseline, summary.diff, detail.diff, shutdown");
|
||||
+ "summary, detail, metadata, baseline, summary.diff, detail.diff, shutdown");
|
||||
return;
|
||||
} else if (nopt == 0) {
|
||||
if (_summary.is_set()) {
|
||||
@@ -118,9 +124,13 @@ void NMTDCmd::execute(DCmdSource source, TRAPS) {
|
||||
report(true, scale_unit);
|
||||
} else if (_detail.value()) {
|
||||
if (!check_detail_tracking_level(output())) {
|
||||
- return;
|
||||
- }
|
||||
+ return;
|
||||
+ }
|
||||
report(false, scale_unit);
|
||||
+ } else if (_metadata.value()) {
|
||||
+ size_t scale = get_scale(_scale.value());
|
||||
+ VM_PrintMetadata op(output(), scale);
|
||||
+ VMThread::execute(&op);
|
||||
} else if (_baseline.value()) {
|
||||
MemBaseline& baseline = MemTracker::get_baseline();
|
||||
if (!baseline.baseline(MemTracker::tracking_level() != NMT_detail)) {
|
||||
diff --git a/hotspot/src/share/vm/services/nmtDCmd.hpp b/hotspot/src/share/vm/services/nmtDCmd.hpp
|
||||
index df1ab36..bbd1391 100644
|
||||
--- a/hotspot/src/share/vm/services/nmtDCmd.hpp
|
||||
+++ b/hotspot/src/share/vm/services/nmtDCmd.hpp
|
||||
@@ -39,6 +39,7 @@ class NMTDCmd: public DCmdWithParser {
|
||||
protected:
|
||||
DCmdArgument<bool> _summary;
|
||||
DCmdArgument<bool> _detail;
|
||||
+ DCmdArgument<bool> _metadata;
|
||||
DCmdArgument<bool> _baseline;
|
||||
DCmdArgument<bool> _summary_diff;
|
||||
DCmdArgument<bool> _detail_diff;
|
||||
--
|
||||
1.8.3.1
|
||||
165
8198553-jcmd-separate-Metaspace-statistics-from-NMT.patch
Normal file
165
8198553-jcmd-separate-Metaspace-statistics-from-NMT.patch
Normal file
@ -0,0 +1,165 @@
|
||||
From d19efeaa550f4a2069273d9ab23c27a53bf4ec91 Mon Sep 17 00:00:00 2001
|
||||
From: eapen <zhangyipeng7@huawei.com>
|
||||
Date: Thu, 15 Dec 2022 19:00:53 +0800
|
||||
Subject: [PATCH 22/33] I68TO2: 8198553: jcmd: separate Metaspace statistics from NMT
|
||||
---
|
||||
.../src/share/vm/services/diagnosticCommand.cpp | 1 +
|
||||
.../src/share/vm/services/diagnosticCommand.hpp | 23 +++++++++++++-
|
||||
hotspot/src/share/vm/services/metaspaceDCmd.cpp | 36 ++++++++++++++++++++++
|
||||
hotspot/src/share/vm/services/nmtDCmd.cpp | 10 +-----
|
||||
hotspot/src/share/vm/services/nmtDCmd.hpp | 1 -
|
||||
5 files changed, 60 insertions(+), 11 deletions(-)
|
||||
create mode 100644 hotspot/src/share/vm/services/metaspaceDCmd.cpp
|
||||
|
||||
diff --git a/hotspot/src/share/vm/services/diagnosticCommand.cpp b/hotspot/src/share/vm/services/diagnosticCommand.cpp
|
||||
index d3b91d9..c9bc7d2 100644
|
||||
--- a/hotspot/src/share/vm/services/diagnosticCommand.cpp
|
||||
+++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp
|
||||
@@ -67,6 +67,7 @@ void DCmdRegistrant::register_dcmds(){
|
||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassHistogramDCmd>(full_export, true, false));
|
||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassesDCmd>(full_export, true, false));
|
||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassStatsDCmd>(full_export, true, false));
|
||||
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<MetaspaceDCmd>(full_export, true, false));
|
||||
#endif // INCLUDE_SERVICES
|
||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(full_export, true, false));
|
||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RotateGCLogDCmd>(full_export, true, false));
|
||||
diff --git a/hotspot/src/share/vm/services/diagnosticCommand.hpp b/hotspot/src/share/vm/services/diagnosticCommand.hpp
|
||||
index f86ab5f..275e053 100644
|
||||
--- a/hotspot/src/share/vm/services/diagnosticCommand.hpp
|
||||
+++ b/hotspot/src/share/vm/services/diagnosticCommand.hpp
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
+ * Copyright (c) 2011, 2018, 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
|
||||
@@ -487,4 +487,25 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
+class MetaspaceDCmd : public DCmd {
|
||||
+public:
|
||||
+ MetaspaceDCmd(outputStream* output, bool heap);
|
||||
+ static const char* name() {
|
||||
+ return "VM.metaspace";
|
||||
+ }
|
||||
+ static const char* description() {
|
||||
+ return "Prints the statistics for the metaspace";
|
||||
+ }
|
||||
+ static const char* impact() {
|
||||
+ return "Medium: Depends on number of classes loaded.";
|
||||
+ }
|
||||
+ static const JavaPermission permission() {
|
||||
+ JavaPermission p = {"java.lang.management.ManagementPermission",
|
||||
+ "monitor", NULL};
|
||||
+ return p;
|
||||
+ }
|
||||
+ static int num_arguments() { return 0; }
|
||||
+ virtual void execute(DCmdSource source, TRAPS);
|
||||
+};
|
||||
+
|
||||
#endif // SHARE_VM_SERVICES_DIAGNOSTICCOMMAND_HPP
|
||||
diff --git a/hotspot/src/share/vm/services/metaspaceDCmd.cpp b/hotspot/src/share/vm/services/metaspaceDCmd.cpp
|
||||
new file mode 100644
|
||||
index 0000000..9d4262e
|
||||
--- /dev/null
|
||||
+++ b/hotspot/src/share/vm/services/metaspaceDCmd.cpp
|
||||
@@ -0,0 +1,36 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2022, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
+ * Copyright (c) 2018, 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
|
||||
+ * under the terms of the GNU General Public License version 2 only, as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
+ * version 2 for more details (a copy is included in the LICENSE file that
|
||||
+ * accompanied this code).
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License version
|
||||
+ * 2 along with this work; if not, write to the Free Software Foundation,
|
||||
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
+ *
|
||||
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
+ * or visit www.oracle.com if you need additional information or have any
|
||||
+ * questions.
|
||||
+ *
|
||||
+ */
|
||||
+#include "precompiled.hpp"
|
||||
+#include "memory/metaspace.hpp"
|
||||
+#include "services/diagnosticCommand.hpp"
|
||||
+
|
||||
+MetaspaceDCmd::MetaspaceDCmd(outputStream* output, bool heap): DCmd(output, heap) {
|
||||
+}
|
||||
+
|
||||
+void MetaspaceDCmd::execute(DCmdSource source, TRAPS) {
|
||||
+ const size_t scale = 1 * K;
|
||||
+ VM_PrintMetadata op(output(), scale);
|
||||
+ VMThread::execute(&op);
|
||||
+}
|
||||
diff --git a/hotspot/src/share/vm/services/nmtDCmd.cpp b/hotspot/src/share/vm/services/nmtDCmd.cpp
|
||||
index 659ca33..2635bbb 100644
|
||||
--- a/hotspot/src/share/vm/services/nmtDCmd.cpp
|
||||
+++ b/hotspot/src/share/vm/services/nmtDCmd.cpp
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
+ * Copyright (c) 2012, 2018, 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
|
||||
@@ -40,8 +40,6 @@ NMTDCmd::NMTDCmd(outputStream* output,
|
||||
_detail("detail", "request runtime to report memory allocation >= "
|
||||
"1K by each callsite.",
|
||||
"BOOLEAN", false, "false"),
|
||||
- _metadata("metadata", "request runtime to report metadata information",
|
||||
- "BOOLEAN", false, "false"),
|
||||
_baseline("baseline", "request runtime to baseline current memory usage, " \
|
||||
"so it can be compared against in later time.",
|
||||
"BOOLEAN", false, "false"),
|
||||
@@ -61,7 +59,6 @@ NMTDCmd::NMTDCmd(outputStream* output,
|
||||
"STRING", false, "KB") {
|
||||
_dcmdparser.add_dcmd_option(&_summary);
|
||||
_dcmdparser.add_dcmd_option(&_detail);
|
||||
- _dcmdparser.add_dcmd_option(&_metadata);
|
||||
_dcmdparser.add_dcmd_option(&_baseline);
|
||||
_dcmdparser.add_dcmd_option(&_summary_diff);
|
||||
_dcmdparser.add_dcmd_option(&_detail_diff);
|
||||
@@ -97,7 +94,6 @@ void NMTDCmd::execute(DCmdSource source, TRAPS) {
|
||||
int nopt = 0;
|
||||
if (_summary.is_set() && _summary.value()) { ++nopt; }
|
||||
if (_detail.is_set() && _detail.value()) { ++nopt; }
|
||||
- if (_metadata.is_set() && _metadata.value()) { ++nopt; }
|
||||
if (_baseline.is_set() && _baseline.value()) { ++nopt; }
|
||||
if (_summary_diff.is_set() && _summary_diff.value()) { ++nopt; }
|
||||
if (_detail_diff.is_set() && _detail_diff.value()) { ++nopt; }
|
||||
@@ -127,10 +123,6 @@ void NMTDCmd::execute(DCmdSource source, TRAPS) {
|
||||
return;
|
||||
}
|
||||
report(false, scale_unit);
|
||||
- } else if (_metadata.value()) {
|
||||
- size_t scale = get_scale(_scale.value());
|
||||
- VM_PrintMetadata op(output(), scale);
|
||||
- VMThread::execute(&op);
|
||||
} else if (_baseline.value()) {
|
||||
MemBaseline& baseline = MemTracker::get_baseline();
|
||||
if (!baseline.baseline(MemTracker::tracking_level() != NMT_detail)) {
|
||||
diff --git a/hotspot/src/share/vm/services/nmtDCmd.hpp b/hotspot/src/share/vm/services/nmtDCmd.hpp
|
||||
index bbd1391..df1ab36 100644
|
||||
--- a/hotspot/src/share/vm/services/nmtDCmd.hpp
|
||||
+++ b/hotspot/src/share/vm/services/nmtDCmd.hpp
|
||||
@@ -39,7 +39,6 @@ class NMTDCmd: public DCmdWithParser {
|
||||
protected:
|
||||
DCmdArgument<bool> _summary;
|
||||
DCmdArgument<bool> _detail;
|
||||
- DCmdArgument<bool> _metadata;
|
||||
DCmdArgument<bool> _baseline;
|
||||
DCmdArgument<bool> _summary_diff;
|
||||
DCmdArgument<bool> _detail_diff;
|
||||
--
|
||||
1.8.3.1
|
||||
409
8200720-Print-additional-information-in-thread-dump-.patch
Normal file
409
8200720-Print-additional-information-in-thread-dump-.patch
Normal file
@ -0,0 +1,409 @@
|
||||
From f68539b01f6345809266cf57fe4bdc0f45c8ab37 Mon Sep 17 00:00:00 2001
|
||||
From: eapen <zhangyipeng7@huawei.com>
|
||||
Date: Fri, 16 Dec 2022 10:02:37 +0800
|
||||
Subject: [PATCH 25/33] I68TO2: 8200720: Print additional information in thread dump
|
||||
(times, allocated bytes etc.)
|
||||
---
|
||||
hotspot/src/share/vm/classfile/classFileParser.cpp | 4 ++
|
||||
hotspot/src/share/vm/runtime/globals.hpp | 3 ++
|
||||
hotspot/src/share/vm/runtime/thread.cpp | 29 ++++++++++---
|
||||
hotspot/src/share/vm/runtime/thread.hpp | 15 +++++--
|
||||
.../src/share/vm/runtime/threadStatisticalInfo.hpp | 49 ++++++++++++++++++++++
|
||||
hotspot/src/share/vm/runtime/vm_operations.cpp | 2 +-
|
||||
hotspot/src/share/vm/runtime/vm_operations.hpp | 13 ++++--
|
||||
hotspot/src/share/vm/services/attachListener.cpp | 14 +++++--
|
||||
.../src/share/vm/services/diagnosticCommand.cpp | 6 ++-
|
||||
.../src/share/vm/services/diagnosticCommand.hpp | 1 +
|
||||
jdk/src/share/classes/sun/tools/jstack/JStack.java | 19 ++++++---
|
||||
11 files changed, 131 insertions(+), 24 deletions(-)
|
||||
create mode 100644 hotspot/src/share/vm/runtime/threadStatisticalInfo.hpp
|
||||
|
||||
diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp
|
||||
index 3ec6aec..51ab4f5 100644
|
||||
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp
|
||||
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp
|
||||
@@ -3843,6 +3843,10 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
||||
ClassFileStream* cfs = stream();
|
||||
// Timing
|
||||
assert(THREAD->is_Java_thread(), "must be a JavaThread");
|
||||
+
|
||||
+ // increment counter
|
||||
+ THREAD->statistical_info().incr_define_class_count();
|
||||
+
|
||||
JavaThread* jt = (JavaThread*) THREAD;
|
||||
|
||||
PerfClassTraceTime ctimer(ClassLoader::perf_class_parse_time(),
|
||||
diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
|
||||
index 14c3c89..2631971 100644
|
||||
--- a/hotspot/src/share/vm/runtime/globals.hpp
|
||||
+++ b/hotspot/src/share/vm/runtime/globals.hpp
|
||||
@@ -1001,6 +1001,9 @@ class CommandLineFlags {
|
||||
product(bool, PrintCompilation, false, \
|
||||
"Print compilations") \
|
||||
\
|
||||
+ product(bool, PrintExtendedThreadInfo, false, \
|
||||
+ "Print more information in thread dump") \
|
||||
+ \
|
||||
diagnostic(bool, TraceNMethodInstalls, false, \
|
||||
"Trace nmethod installation") \
|
||||
\
|
||||
diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp
|
||||
index 61627e4..bd35e95 100644
|
||||
--- a/hotspot/src/share/vm/runtime/thread.cpp
|
||||
+++ b/hotspot/src/share/vm/runtime/thread.cpp
|
||||
@@ -71,6 +71,7 @@
|
||||
#include "runtime/thread.inline.hpp"
|
||||
#include "runtime/threadCritical.hpp"
|
||||
#include "runtime/threadLocalStorage.hpp"
|
||||
+#include "runtime/threadStatisticalInfo.hpp"
|
||||
#include "runtime/vframe.hpp"
|
||||
#include "runtime/vframeArray.hpp"
|
||||
#include "runtime/vframe_hp.hpp"
|
||||
@@ -859,13 +860,29 @@ void Thread::metadata_do(void f(Metadata*)) {
|
||||
}
|
||||
}
|
||||
|
||||
-void Thread::print_on(outputStream* st) const {
|
||||
+void Thread::print_on(outputStream* st, bool print_extended_info) const {
|
||||
// get_priority assumes osthread initialized
|
||||
if (osthread() != NULL) {
|
||||
int os_prio;
|
||||
if (os::get_native_priority(this, &os_prio) == OS_OK) {
|
||||
st->print("os_prio=%d ", os_prio);
|
||||
}
|
||||
+
|
||||
+ st->print("cpu=%.2fms ",
|
||||
+ os::thread_cpu_time(const_cast<Thread*>(this), true) / 1000000.0
|
||||
+ );
|
||||
+ st->print("elapsed=%.2fs ",
|
||||
+ _statistical_info.getElapsedTime() / 1000.0
|
||||
+ );
|
||||
+ if (is_Java_thread() && (PrintExtendedThreadInfo || print_extended_info)) {
|
||||
+ size_t allocated_bytes = (size_t) const_cast<Thread*>(this)->cooked_allocated_bytes();
|
||||
+ st->print("allocated=" SIZE_FORMAT "%s ",
|
||||
+ byte_size_in_proper_unit(allocated_bytes),
|
||||
+ proper_unit_for_byte_size(allocated_bytes)
|
||||
+ );
|
||||
+ st->print("defined_classes=" INT64_FORMAT " ", _statistical_info.getDefineClassCount());
|
||||
+ }
|
||||
+
|
||||
st->print("tid=" INTPTR_FORMAT " ", this);
|
||||
ext().print_on(st);
|
||||
osthread()->print_on(st);
|
||||
@@ -2856,7 +2873,7 @@ void JavaThread::print_thread_state() const {
|
||||
#endif // PRODUCT
|
||||
|
||||
// Called by Threads::print() for VM_PrintThreads operation
|
||||
-void JavaThread::print_on(outputStream *st) const {
|
||||
+void JavaThread::print_on(outputStream *st, bool print_extended_info) const {
|
||||
st->print("\"%s\" ", get_thread_name());
|
||||
oop thread_oop = threadObj();
|
||||
if (thread_oop != NULL) {
|
||||
@@ -2864,7 +2881,7 @@ void JavaThread::print_on(outputStream *st) const {
|
||||
if (java_lang_Thread::is_daemon(thread_oop)) st->print("daemon ");
|
||||
st->print("prio=%d ", java_lang_Thread::priority(thread_oop));
|
||||
}
|
||||
- Thread::print_on(st);
|
||||
+ Thread::print_on(st, print_extended_info);
|
||||
// print guess for valid stack memory region (assume 4K pages); helps lock debugging
|
||||
st->print_cr("[" INTPTR_FORMAT "]", (intptr_t)last_Java_sp() & ~right_n_bits(12));
|
||||
if (thread_oop != NULL && JDK_Version::is_gte_jdk15x_version()) {
|
||||
@@ -4344,7 +4361,9 @@ JavaThread *Threads::owning_thread_from_monitor_owner(address owner, bool doLock
|
||||
}
|
||||
|
||||
// Threads::print_on() is called at safepoint by VM_PrintThreads operation.
|
||||
-void Threads::print_on(outputStream* st, bool print_stacks, bool internal_format, bool print_concurrent_locks) {
|
||||
+void Threads::print_on(outputStream* st, bool print_stacks,
|
||||
+ bool internal_format, bool print_concurrent_locks,
|
||||
+ bool print_extended_info) {
|
||||
char buf[32];
|
||||
st->print_cr("%s", os::local_time_string(buf, sizeof(buf)));
|
||||
|
||||
@@ -4365,7 +4384,7 @@ void Threads::print_on(outputStream* st, bool print_stacks, bool internal_format
|
||||
|
||||
ALL_JAVA_THREADS(p) {
|
||||
ResourceMark rm;
|
||||
- p->print_on(st);
|
||||
+ p->print_on(st, print_extended_info);
|
||||
if (print_stacks) {
|
||||
if (internal_format) {
|
||||
p->trace_stack();
|
||||
diff --git a/hotspot/src/share/vm/runtime/thread.hpp b/hotspot/src/share/vm/runtime/thread.hpp
|
||||
index fcd4814..be53498 100644
|
||||
--- a/hotspot/src/share/vm/runtime/thread.hpp
|
||||
+++ b/hotspot/src/share/vm/runtime/thread.hpp
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "runtime/stubRoutines.hpp"
|
||||
#include "runtime/threadLocalStorage.hpp"
|
||||
#include "runtime/thread_ext.hpp"
|
||||
+#include "runtime/threadStatisticalInfo.hpp"
|
||||
#include "runtime/unhandledOops.hpp"
|
||||
#include "utilities/exceptions.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
@@ -263,6 +264,8 @@ class Thread: public ThreadShadow {
|
||||
// Thread-local buffer used by MetadataOnStackMark.
|
||||
MetadataOnStackBuffer* _metadata_on_stack_buffer;
|
||||
|
||||
+ ThreadStatisticalInfo _statistical_info; // Statistics about the thread
|
||||
+
|
||||
JFR_ONLY(DEFINE_THREAD_LOCAL_FIELD_JFR;) // Thread-local data for jfr
|
||||
|
||||
ThreadExt _ext;
|
||||
@@ -446,6 +449,8 @@ class Thread: public ThreadShadow {
|
||||
void incr_allocated_bytes(jlong size) { _allocated_bytes += size; }
|
||||
inline jlong cooked_allocated_bytes();
|
||||
|
||||
+ ThreadStatisticalInfo& statistical_info() { return _statistical_info; }
|
||||
+
|
||||
JFR_ONLY(DEFINE_THREAD_LOCAL_ACCESSOR_JFR;)
|
||||
JFR_ONLY(DEFINE_TRACE_SUSPEND_FLAG_METHODS)
|
||||
|
||||
@@ -570,7 +575,8 @@ protected:
|
||||
void set_lgrp_id(int value) { _lgrp_id = value; }
|
||||
|
||||
// Printing
|
||||
- void print_on(outputStream* st) const;
|
||||
+ void print_on(outputStream* st, bool print_extended_info) const;
|
||||
+ void print_on(outputStream* st) const { print_on(st, false); }
|
||||
void print() const { print_on(tty); }
|
||||
virtual void print_on_error(outputStream* st, char* buf, int buflen) const;
|
||||
|
||||
@@ -1463,7 +1469,8 @@ class JavaThread: public Thread {
|
||||
|
||||
// Misc. operations
|
||||
char* name() const { return (char*)get_thread_name(); }
|
||||
- void print_on(outputStream* st) const;
|
||||
+ void print_on(outputStream* st, bool print_extended_info) const;
|
||||
+ void print_on(outputStream* st) const { print_on(st, false); }
|
||||
void print() const { print_on(tty); }
|
||||
void print_value();
|
||||
void print_thread_state_on(outputStream* ) const PRODUCT_RETURN;
|
||||
@@ -1975,10 +1982,10 @@ class Threads: AllStatic {
|
||||
|
||||
// Verification
|
||||
static void verify();
|
||||
- static void print_on(outputStream* st, bool print_stacks, bool internal_format, bool print_concurrent_locks);
|
||||
+ static void print_on(outputStream* st, bool print_stacks, bool internal_format, bool print_concurrent_locks, bool print_extended_info);
|
||||
static void print(bool print_stacks, bool internal_format) {
|
||||
// this function is only used by debug.cpp
|
||||
- print_on(tty, print_stacks, internal_format, false /* no concurrent lock printed */);
|
||||
+ print_on(tty, print_stacks, internal_format, false /* no concurrent lock printed */, false /* simple format */);
|
||||
}
|
||||
static void print_on_error(outputStream* st, Thread* current, char* buf, int buflen);
|
||||
|
||||
diff --git a/hotspot/src/share/vm/runtime/threadStatisticalInfo.hpp b/hotspot/src/share/vm/runtime/threadStatisticalInfo.hpp
|
||||
new file mode 100644
|
||||
index 0000000..9dbe62d
|
||||
--- /dev/null
|
||||
+++ b/hotspot/src/share/vm/runtime/threadStatisticalInfo.hpp
|
||||
@@ -0,0 +1,49 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
+ * Copyright (c) 2018 SAP SE. All rights reserved.
|
||||
+ * Copyright (c) 2022, Huawei Technologies Co., Ltd. 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
|
||||
+ * under the terms of the GNU General Public License version 2 only, as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
+ * version 2 for more details (a copy is included in the LICENSE file that
|
||||
+ * accompanied this code).
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License version
|
||||
+ * 2 along with this work; if not, write to the Free Software Foundation,
|
||||
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
+ *
|
||||
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
+ * or visit www.oracle.com if you need additional information or have any
|
||||
+ * questions.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#ifndef SHARE_VM_RUNTIME_THREADSTATISTICS_HPP
|
||||
+#define SHARE_VM_RUNTIME_THREADSTATISTICS_HPP
|
||||
+
|
||||
+#include "prims/jni.h"
|
||||
+#include "runtime/os.hpp"
|
||||
+#include "utilities/globalDefinitions.hpp"
|
||||
+
|
||||
+
|
||||
+class ThreadStatisticalInfo {
|
||||
+ // The time stamp the thread was started.
|
||||
+ const uint64_t _start_time_stamp;
|
||||
+ uint64_t _define_class_count;
|
||||
+
|
||||
+public:
|
||||
+ ThreadStatisticalInfo() : _start_time_stamp(os::javaTimeMillis()), _define_class_count(0) {}
|
||||
+ uint64_t getStartTime() const { return _start_time_stamp; }
|
||||
+ uint64_t getDefineClassCount() const { return _define_class_count; }
|
||||
+ void setDefineClassCount(uint64_t defineClassCount) { _define_class_count = defineClassCount; }
|
||||
+ void incr_define_class_count() { _define_class_count += 1; }
|
||||
+ uint64_t getElapsedTime() const { return os::javaTimeMillis() - getStartTime(); }
|
||||
+};
|
||||
+
|
||||
+#endif // SHARE_VM_RUNTIME_THREADSTATISTICS_HPP
|
||||
diff --git a/hotspot/src/share/vm/runtime/vm_operations.cpp b/hotspot/src/share/vm/runtime/vm_operations.cpp
|
||||
index b42d18f..03c4249 100644
|
||||
--- a/hotspot/src/share/vm/runtime/vm_operations.cpp
|
||||
+++ b/hotspot/src/share/vm/runtime/vm_operations.cpp
|
||||
@@ -195,7 +195,7 @@ bool VM_PrintThreads::doit_prologue() {
|
||||
}
|
||||
|
||||
void VM_PrintThreads::doit() {
|
||||
- Threads::print_on(_out, true, false, _print_concurrent_locks);
|
||||
+ Threads::print_on(_out, true, false, _print_concurrent_locks, _print_extended_info);
|
||||
}
|
||||
|
||||
void VM_PrintThreads::doit_epilogue() {
|
||||
diff --git a/hotspot/src/share/vm/runtime/vm_operations.hpp b/hotspot/src/share/vm/runtime/vm_operations.hpp
|
||||
index 19c33f8..baf6042 100644
|
||||
--- a/hotspot/src/share/vm/runtime/vm_operations.hpp
|
||||
+++ b/hotspot/src/share/vm/runtime/vm_operations.hpp
|
||||
@@ -311,10 +311,17 @@ class VM_PrintThreads: public VM_Operation {
|
||||
private:
|
||||
outputStream* _out;
|
||||
bool _print_concurrent_locks;
|
||||
+ bool _print_extended_info;
|
||||
public:
|
||||
- VM_PrintThreads() { _out = tty; _print_concurrent_locks = PrintConcurrentLocks; }
|
||||
- VM_PrintThreads(outputStream* out, bool print_concurrent_locks) { _out = out; _print_concurrent_locks = print_concurrent_locks; }
|
||||
- VMOp_Type type() const { return VMOp_PrintThreads; }
|
||||
+ VM_PrintThreads()
|
||||
+ : _out(tty), _print_concurrent_locks(PrintConcurrentLocks), _print_extended_info(false)
|
||||
+ {}
|
||||
+ VM_PrintThreads(outputStream* out, bool print_concurrent_locks, bool print_extended_info)
|
||||
+ : _out(out), _print_concurrent_locks(print_concurrent_locks), _print_extended_info(print_extended_info)
|
||||
+ {}
|
||||
+ VMOp_Type type() const {
|
||||
+ return VMOp_PrintThreads;
|
||||
+ }
|
||||
void doit();
|
||||
bool doit_prologue();
|
||||
void doit_epilogue();
|
||||
diff --git a/hotspot/src/share/vm/services/attachListener.cpp b/hotspot/src/share/vm/services/attachListener.cpp
|
||||
index d4dea71..7c57637 100644
|
||||
--- a/hotspot/src/share/vm/services/attachListener.cpp
|
||||
+++ b/hotspot/src/share/vm/services/attachListener.cpp
|
||||
@@ -132,12 +132,20 @@ static jint data_dump(AttachOperation* op, outputStream* out) {
|
||||
//
|
||||
static jint thread_dump(AttachOperation* op, outputStream* out) {
|
||||
bool print_concurrent_locks = false;
|
||||
- if (op->arg(0) != NULL && strcmp(op->arg(0), "-l") == 0) {
|
||||
- print_concurrent_locks = true;
|
||||
+ bool print_extended_info = false;
|
||||
+ if (op->arg(0) != NULL) {
|
||||
+ for (int i = 0; op->arg(0)[i] != 0; ++i) {
|
||||
+ if (op->arg(0)[i] == 'l') {
|
||||
+ print_concurrent_locks = true;
|
||||
+ }
|
||||
+ if (op->arg(0)[i] == 'e') {
|
||||
+ print_extended_info = true;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
// thread stacks
|
||||
- VM_PrintThreads op1(out, print_concurrent_locks);
|
||||
+ VM_PrintThreads op1(out, print_concurrent_locks, print_extended_info);
|
||||
VMThread::execute(&op1);
|
||||
|
||||
// JNI global handles
|
||||
diff --git a/hotspot/src/share/vm/services/diagnosticCommand.cpp b/hotspot/src/share/vm/services/diagnosticCommand.cpp
|
||||
index c9bc7d2..fb8e293 100644
|
||||
--- a/hotspot/src/share/vm/services/diagnosticCommand.cpp
|
||||
+++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp
|
||||
@@ -535,13 +535,15 @@ int ClassStatsDCmd::num_arguments() {
|
||||
|
||||
ThreadDumpDCmd::ThreadDumpDCmd(outputStream* output, bool heap) :
|
||||
DCmdWithParser(output, heap),
|
||||
- _locks("-l", "print java.util.concurrent locks", "BOOLEAN", false, "false") {
|
||||
+ _locks("-l", "print java.util.concurrent locks", "BOOLEAN", false, "false"),
|
||||
+ _extended("-e", "print extended thread information", "BOOLEAN", false, "false") {
|
||||
_dcmdparser.add_dcmd_option(&_locks);
|
||||
+ _dcmdparser.add_dcmd_option(&_extended);
|
||||
}
|
||||
|
||||
void ThreadDumpDCmd::execute(DCmdSource source, TRAPS) {
|
||||
// thread stacks
|
||||
- VM_PrintThreads op1(output(), _locks.value());
|
||||
+ VM_PrintThreads op1(output(), _locks.value(), _extended.value());
|
||||
VMThread::execute(&op1);
|
||||
|
||||
// JNI global handles
|
||||
diff --git a/hotspot/src/share/vm/services/diagnosticCommand.hpp b/hotspot/src/share/vm/services/diagnosticCommand.hpp
|
||||
index 275e053..87bff52 100644
|
||||
--- a/hotspot/src/share/vm/services/diagnosticCommand.hpp
|
||||
+++ b/hotspot/src/share/vm/services/diagnosticCommand.hpp
|
||||
@@ -362,6 +362,7 @@ public:
|
||||
class ThreadDumpDCmd : public DCmdWithParser {
|
||||
protected:
|
||||
DCmdArgument<bool> _locks;
|
||||
+ DCmdArgument<bool> _extended;
|
||||
public:
|
||||
ThreadDumpDCmd(outputStream* output, bool heap);
|
||||
static const char* name() { return "Thread.print"; }
|
||||
diff --git a/jdk/src/share/classes/sun/tools/jstack/JStack.java b/jdk/src/share/classes/sun/tools/jstack/JStack.java
|
||||
index 6c96af2..3eea094 100644
|
||||
--- a/jdk/src/share/classes/sun/tools/jstack/JStack.java
|
||||
+++ b/jdk/src/share/classes/sun/tools/jstack/JStack.java
|
||||
@@ -48,6 +48,7 @@ public class JStack {
|
||||
boolean useSA = false;
|
||||
boolean mixed = false;
|
||||
boolean locks = false;
|
||||
+ boolean extended = false;
|
||||
|
||||
// Parse the options (arguments starting with "-" )
|
||||
int optionCount = 0;
|
||||
@@ -69,7 +70,11 @@ public class JStack {
|
||||
if (arg.equals("-l")) {
|
||||
locks = true;
|
||||
} else {
|
||||
- usage(1);
|
||||
+ if (arg.equals("-e")) {
|
||||
+ extended = true;
|
||||
+ } else {
|
||||
+ usage(1);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -107,11 +112,12 @@ public class JStack {
|
||||
} else {
|
||||
// pass -l to thread dump operation to get extra lock info
|
||||
String pid = args[optionCount];
|
||||
- String params[];
|
||||
+ String params[]= new String[] { "" };
|
||||
+ if (extended) {
|
||||
+ params[0] += "-e ";
|
||||
+ }
|
||||
if (locks) {
|
||||
- params = new String[] { "-l" };
|
||||
- } else {
|
||||
- params = new String[0];
|
||||
+ params[0] += "-l";
|
||||
}
|
||||
runThreadDump(pid, params);
|
||||
}
|
||||
@@ -205,7 +211,7 @@ public class JStack {
|
||||
// print usage message
|
||||
private static void usage(int exit) {
|
||||
System.err.println("Usage:");
|
||||
- System.err.println(" jstack [-l] <pid>");
|
||||
+ System.err.println(" jstack [-l][-e] <pid>");
|
||||
System.err.println(" (to connect to running process)");
|
||||
|
||||
if (loadSAClass() != null) {
|
||||
@@ -227,6 +233,7 @@ public class JStack {
|
||||
}
|
||||
|
||||
System.err.println(" -l long listing. Prints additional information about locks");
|
||||
+ System.err.println(" -e extended listing. Prints additional information about threads");
|
||||
System.err.println(" -h or -help to print this help message");
|
||||
System.exit(exit);
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
811
8203682-Add-jcmd-VM.classloaders-command-to-print-ou.patch
Normal file
811
8203682-Add-jcmd-VM.classloaders-command-to-print-ou.patch
Normal file
@ -0,0 +1,811 @@
|
||||
From 953fdbbfbc6512c3f04f3663fa5ad216d7547984 Mon Sep 17 00:00:00 2001
|
||||
From: eapen <zhangyipeng7@huawei.com>
|
||||
Date: Thu, 15 Dec 2022 09:48:37 +0800
|
||||
Subject: [PATCH 17/33] I68TO2: 8203682: Add jcmd "VM.classloaders" command to print
|
||||
out class loader hierarchy, details
|
||||
---
|
||||
.../vm/classfile/classLoaderHierarchyDCmd.cpp | 468 +++++++++++++++++++++
|
||||
.../vm/classfile/classLoaderHierarchyDCmd.hpp | 59 +++
|
||||
hotspot/src/share/vm/runtime/vm_operations.hpp | 1 +
|
||||
.../src/share/vm/services/diagnosticCommand.cpp | 2 +
|
||||
.../dcmd/ClassLoaderHierarchyTest.java | 213 ++++++++++
|
||||
5 files changed, 743 insertions(+)
|
||||
create mode 100644 hotspot/src/share/vm/classfile/classLoaderHierarchyDCmd.cpp
|
||||
create mode 100644 hotspot/src/share/vm/classfile/classLoaderHierarchyDCmd.hpp
|
||||
create mode 100644 hotspot/test/serviceability/dcmd/ClassLoaderHierarchyTest.java
|
||||
|
||||
diff --git a/hotspot/src/share/vm/classfile/classLoaderHierarchyDCmd.cpp b/hotspot/src/share/vm/classfile/classLoaderHierarchyDCmd.cpp
|
||||
new file mode 100644
|
||||
index 0000000..4c25091
|
||||
--- /dev/null
|
||||
+++ b/hotspot/src/share/vm/classfile/classLoaderHierarchyDCmd.cpp
|
||||
@@ -0,0 +1,468 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
+ * Copyright (c) 2018 SAP SE. 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
|
||||
+ * under the terms of the GNU General Public License version 2 only, as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
+ * version 2 for more details (a copy is included in the LICENSE file that
|
||||
+ * accompanied this code).
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License version
|
||||
+ * 2 along with this work; if not, write to the Free Software Foundation,
|
||||
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
+ *
|
||||
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
+ * or visit www.oracle.com if you need additional information or have any
|
||||
+ * questions.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include "precompiled.hpp"
|
||||
+
|
||||
+#include "classfile/classLoaderData.inline.hpp"
|
||||
+#include "classfile/classLoaderHierarchyDCmd.hpp"
|
||||
+#include "memory/allocation.hpp"
|
||||
+#include "memory/resourceArea.hpp"
|
||||
+#include "runtime/safepoint.hpp"
|
||||
+#include "utilities/globalDefinitions.hpp"
|
||||
+#include "utilities/ostream.hpp"
|
||||
+
|
||||
+
|
||||
+ClassLoaderHierarchyDCmd::ClassLoaderHierarchyDCmd(outputStream* output, bool heap)
|
||||
+ : DCmdWithParser(output, heap)
|
||||
+ , _show_classes("show-classes", "Print loaded classes.", "BOOLEAN", false, "false")
|
||||
+ , _verbose("verbose", "Print detailed information.", "BOOLEAN", false, "false") {
|
||||
+ _dcmdparser.add_dcmd_option(&_show_classes);
|
||||
+ _dcmdparser.add_dcmd_option(&_verbose);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+int ClassLoaderHierarchyDCmd::num_arguments() {
|
||||
+ ResourceMark rm;
|
||||
+ ClassLoaderHierarchyDCmd* dcmd = new ClassLoaderHierarchyDCmd(NULL, false);
|
||||
+ if (dcmd != NULL) {
|
||||
+ DCmdMark mark(dcmd);
|
||||
+ return dcmd->_dcmdparser.num_arguments();
|
||||
+ } else {
|
||||
+ return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+// Helper class for drawing the branches to the left of a node.
|
||||
+class BranchTracker : public StackObj {
|
||||
+ // "<x>"
|
||||
+ // " |---<y>"
|
||||
+ // " | |
|
||||
+ // " | <z>"
|
||||
+ // " | |---<z1>
|
||||
+ // " | |---<z2>
|
||||
+ // ^^^^^^^ ^^^
|
||||
+ // A B
|
||||
+
|
||||
+ // Some terms for the graphics:
|
||||
+ // - branch: vertical connection between a node's ancestor to a later sibling.
|
||||
+ // - branchwork: (A) the string to print as a prefix at the start of each line, contains all branches.
|
||||
+ // - twig (B): Length of the dashed line connecting a node to its branch.
|
||||
+ // - branch spacing: how many spaces between branches are printed.
|
||||
+
|
||||
+public:
|
||||
+
|
||||
+ enum { max_depth = 64, twig_len = 2, branch_spacing = 5 };
|
||||
+
|
||||
+private:
|
||||
+
|
||||
+ char _branches[max_depth];
|
||||
+ int _pos;
|
||||
+
|
||||
+public:
|
||||
+ BranchTracker()
|
||||
+ : _pos(0) {}
|
||||
+
|
||||
+ void push(bool has_branch) {
|
||||
+ if (_pos < max_depth) {
|
||||
+ _branches[_pos] = has_branch ? '|' : ' ';
|
||||
+ }
|
||||
+ _pos ++; // beyond max depth, omit branch drawing but do count on.
|
||||
+ }
|
||||
+
|
||||
+ void pop() {
|
||||
+ assert(_pos > 0, "must be");
|
||||
+ _pos --;
|
||||
+ }
|
||||
+
|
||||
+ void print(outputStream* st) {
|
||||
+ for (int i = 0; i < _pos; i ++) {
|
||||
+ st->print("%c%.*s", _branches[i], branch_spacing, " ");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ class Mark {
|
||||
+ BranchTracker& _tr;
|
||||
+ public:
|
||||
+ Mark(BranchTracker& tr, bool has_branch_here)
|
||||
+ : _tr(tr) { _tr.push(has_branch_here); }
|
||||
+ ~Mark() { _tr.pop(); }
|
||||
+ };
|
||||
+
|
||||
+}; // end: BranchTracker
|
||||
+
|
||||
+struct LoadedClassInfo : public ResourceObj {
|
||||
+public:
|
||||
+ LoadedClassInfo* _next;
|
||||
+ Klass* const _klass;
|
||||
+ const ClassLoaderData* const _cld;
|
||||
+
|
||||
+ LoadedClassInfo(Klass* klass, const ClassLoaderData* cld)
|
||||
+ : _next(NULL), _klass(klass), _cld(cld) {}
|
||||
+
|
||||
+};
|
||||
+
|
||||
+class LoaderTreeNode : public ResourceObj {
|
||||
+
|
||||
+ // We walk the CLDG and, for each CLD which is non-anonymous, add
|
||||
+ // a tree node. To add a node we need its parent node; if it itself
|
||||
+ // does not exist yet, we add a preliminary node for it. This preliminary
|
||||
+ // node just contains its loader oop; later, when encountering its CLD in
|
||||
+ // our CLDG walk, we complete the missing information in this node.
|
||||
+
|
||||
+ const oop _loader_oop;
|
||||
+ const ClassLoaderData* _cld; // May be NULL if loader never loaded anything
|
||||
+
|
||||
+ LoaderTreeNode* _child;
|
||||
+ LoaderTreeNode* _next;
|
||||
+
|
||||
+ LoadedClassInfo* _classes;
|
||||
+ int _num_classes;
|
||||
+
|
||||
+ LoadedClassInfo* _anon_classes;
|
||||
+ int _num_anon_classes;
|
||||
+
|
||||
+ // Returns Klass of loader; NULL for bootstrap loader
|
||||
+ const Klass* loader_klass() const {
|
||||
+ return (_loader_oop != NULL) ? _loader_oop->klass() : NULL;
|
||||
+ }
|
||||
+
|
||||
+ // Returns ResourceArea-allocated class name of loader class; "" if there is no klass (bootstrap loader)
|
||||
+ const char* loader_class_name() const {
|
||||
+ const Klass* klass = loader_klass();
|
||||
+ return klass != NULL ? klass->external_name() : "";
|
||||
+ }
|
||||
+
|
||||
+ bool is_bootstrap() const {
|
||||
+ if (_loader_oop == NULL) {
|
||||
+ assert(_cld != NULL && _cld->is_the_null_class_loader_data(), "bootstrap loader must have CLD");
|
||||
+ return true;
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ void print_with_child_nodes(outputStream* st, BranchTracker& branchtracker,
|
||||
+ bool print_classes, bool verbose) const {
|
||||
+
|
||||
+ assert(SafepointSynchronize::is_at_safepoint(), "invariant");
|
||||
+
|
||||
+ ResourceMark rm;
|
||||
+
|
||||
+ // Retrieve information.
|
||||
+ const Klass* const the_loader_klass = loader_klass();
|
||||
+ const char* const the_loader_class_name = loader_class_name();
|
||||
+ // ClassLoader.java does not contain 'name' field. Replace it with loader_class_name().
|
||||
+ const char* const the_loader_name = the_loader_class_name;
|
||||
+
|
||||
+ branchtracker.print(st);
|
||||
+
|
||||
+ // e.g. "+--- jdk.internal.reflect.DelegatingClassLoader"
|
||||
+ st->print("+%.*s", BranchTracker::twig_len, "----------");
|
||||
+ if (is_bootstrap()) {
|
||||
+ st->print(" <bootstrap>");
|
||||
+ } else {
|
||||
+ if (the_loader_name[0] != '\0') {
|
||||
+ st->print(" \"%s\",", the_loader_name);
|
||||
+ }
|
||||
+ st->print(" %s", the_loader_class_name);
|
||||
+ st->print(" {" PTR_FORMAT "}", p2i(_loader_oop));
|
||||
+ }
|
||||
+ st->cr();
|
||||
+
|
||||
+ // Output following this node (node details and child nodes) - up to the next sibling node
|
||||
+ // needs to be prefixed with "|" if there is a follow up sibling.
|
||||
+ const bool have_sibling = _next != NULL;
|
||||
+ BranchTracker::Mark trm(branchtracker, have_sibling);
|
||||
+
|
||||
+ {
|
||||
+ // optional node details following this node needs to be prefixed with "|"
|
||||
+ // if there are follow up child nodes.
|
||||
+ const bool have_child = _child != NULL;
|
||||
+ BranchTracker::Mark trm(branchtracker, have_child);
|
||||
+
|
||||
+ // Empty line
|
||||
+ branchtracker.print(st);
|
||||
+ st->cr();
|
||||
+
|
||||
+ const int indentation = 18;
|
||||
+
|
||||
+ if (verbose) {
|
||||
+ branchtracker.print(st);
|
||||
+ st->print_cr("%*s " PTR_FORMAT, indentation, "Loader Data:", p2i(_cld));
|
||||
+ branchtracker.print(st);
|
||||
+ st->print_cr("%*s " PTR_FORMAT, indentation, "Loader Klass:", p2i(the_loader_klass));
|
||||
+
|
||||
+ // Empty line
|
||||
+ branchtracker.print(st);
|
||||
+ st->cr();
|
||||
+ }
|
||||
+
|
||||
+ if (print_classes) {
|
||||
+
|
||||
+ if (_classes != NULL) {
|
||||
+ assert(_cld != NULL, "we have classes, we should have a CLD");
|
||||
+ for (LoadedClassInfo* lci = _classes; lci; lci = lci->_next) {
|
||||
+ branchtracker.print(st);
|
||||
+ if (lci == _classes) { // first iteration
|
||||
+ st->print("%*s ", indentation, "Classes:");
|
||||
+ } else {
|
||||
+ st->print("%*s ", indentation, "");
|
||||
+ }
|
||||
+ st->print("%s", lci->_klass->external_name());
|
||||
+ st->cr();
|
||||
+ // Non-anonymous classes should live in the primary CLD of its loader
|
||||
+ assert(lci->_cld == _cld, "must be");
|
||||
+ }
|
||||
+ branchtracker.print(st);
|
||||
+ st->print("%*s ", indentation, "");
|
||||
+ st->print_cr("(%u class%s)", _num_classes, (_num_classes == 1) ? "" : "es");
|
||||
+
|
||||
+ // Empty line
|
||||
+ branchtracker.print(st);
|
||||
+ st->cr();
|
||||
+ }
|
||||
+
|
||||
+ if (_anon_classes != NULL) {
|
||||
+ assert(_cld != NULL, "we have classes, we should have a CLD");
|
||||
+ for (LoadedClassInfo* lci = _anon_classes; lci; lci = lci->_next) {
|
||||
+ branchtracker.print(st);
|
||||
+ if (lci == _anon_classes) { // first iteration
|
||||
+ st->print("%*s ", indentation, "Anonymous Classes:");
|
||||
+ } else {
|
||||
+ st->print("%*s ", indentation, "");
|
||||
+ }
|
||||
+ st->print("%s", lci->_klass->external_name());
|
||||
+ // For anonymous classes, also print CLD if verbose. Should be a different one than the primary CLD.
|
||||
+ assert(lci->_cld != _cld, "must be");
|
||||
+ if (verbose) {
|
||||
+ st->print(" (CLD: " PTR_FORMAT ")", p2i(lci->_cld));
|
||||
+ }
|
||||
+ st->cr();
|
||||
+ }
|
||||
+ branchtracker.print(st);
|
||||
+ st->print("%*s ", indentation, "");
|
||||
+ st->print_cr("(%u anonymous class%s)", _num_anon_classes, (_num_anon_classes == 1) ? "" : "es");
|
||||
+
|
||||
+ // Empty line
|
||||
+ branchtracker.print(st);
|
||||
+ st->cr();
|
||||
+ }
|
||||
+
|
||||
+ } // end: print_classes
|
||||
+
|
||||
+ } // Pop branchtracker mark
|
||||
+
|
||||
+ // Print children, recursively
|
||||
+ LoaderTreeNode* c = _child;
|
||||
+ while (c != NULL) {
|
||||
+ c->print_with_child_nodes(st, branchtracker, print_classes, verbose);
|
||||
+ c = c->_next;
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+public:
|
||||
+
|
||||
+ LoaderTreeNode(const oop loader_oop)
|
||||
+ : _loader_oop(loader_oop), _cld(NULL)
|
||||
+ , _child(NULL), _next(NULL)
|
||||
+ , _classes(NULL), _anon_classes(NULL)
|
||||
+ , _num_classes(0), _num_anon_classes(0) {}
|
||||
+
|
||||
+ void set_cld(const ClassLoaderData* cld) {
|
||||
+ assert(_cld == NULL, "there should be only one primary CLD per loader");
|
||||
+ _cld = cld;
|
||||
+ }
|
||||
+
|
||||
+ void add_child(LoaderTreeNode* info) {
|
||||
+ info->_next = _child;
|
||||
+ _child = info;
|
||||
+ }
|
||||
+
|
||||
+ void add_sibling(LoaderTreeNode* info) {
|
||||
+ assert(info->_next == NULL, "must be");
|
||||
+ info->_next = _next;
|
||||
+ _next = info;
|
||||
+ }
|
||||
+
|
||||
+ void add_classes(LoadedClassInfo* first_class, int num_classes, bool anonymous) {
|
||||
+ LoadedClassInfo** p_list_to_add_to = anonymous ? &_anon_classes : &_classes;
|
||||
+ // Search tail.
|
||||
+ while ((*p_list_to_add_to) != NULL) {
|
||||
+ p_list_to_add_to = &(*p_list_to_add_to)->_next;
|
||||
+ }
|
||||
+ *p_list_to_add_to = first_class;
|
||||
+ if (anonymous) {
|
||||
+ _num_anon_classes += num_classes;
|
||||
+ } else {
|
||||
+ _num_classes += num_classes;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ LoaderTreeNode* find(const oop loader_oop) {
|
||||
+ LoaderTreeNode* result = NULL;
|
||||
+ if (_loader_oop == loader_oop) {
|
||||
+ result = this;
|
||||
+ } else {
|
||||
+ LoaderTreeNode* c = _child;
|
||||
+ while (c != NULL && result == NULL) {
|
||||
+ result = c->find(loader_oop);
|
||||
+ c = c->_next;
|
||||
+ }
|
||||
+ }
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
+ void print_with_child_nodes(outputStream* st, bool print_classes, bool print_add_info) const {
|
||||
+ BranchTracker bwt;
|
||||
+ print_with_child_nodes(st, bwt, print_classes, print_add_info);
|
||||
+ }
|
||||
+
|
||||
+};
|
||||
+
|
||||
+class LoadedClassCollectClosure : public KlassClosure {
|
||||
+public:
|
||||
+ LoadedClassInfo* _list;
|
||||
+ const ClassLoaderData* _cld;
|
||||
+ int _num_classes;
|
||||
+ LoadedClassCollectClosure(const ClassLoaderData* cld)
|
||||
+ : _list(NULL), _cld(cld), _num_classes(0) {}
|
||||
+ void do_klass(Klass* k) {
|
||||
+ LoadedClassInfo* lki = new LoadedClassInfo(k, _cld);
|
||||
+ lki->_next = _list;
|
||||
+ _list = lki;
|
||||
+ _num_classes ++;
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+class LoaderInfoScanClosure : public CLDClosure {
|
||||
+
|
||||
+ const bool _print_classes;
|
||||
+ const bool _verbose;
|
||||
+ LoaderTreeNode* _root;
|
||||
+
|
||||
+ static void fill_in_classes(LoaderTreeNode* info, const ClassLoaderData* cld) {
|
||||
+ assert(info != NULL && cld != NULL, "must be");
|
||||
+ LoadedClassCollectClosure lccc(cld);
|
||||
+ const_cast<ClassLoaderData*>(cld)->classes_do(&lccc);
|
||||
+ if (lccc._num_classes > 0) {
|
||||
+ info->add_classes(lccc._list, lccc._num_classes, cld->is_anonymous());
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ LoaderTreeNode* find_node_or_add_empty_node(oop loader_oop) {
|
||||
+
|
||||
+ assert(_root != NULL, "root node must exist");
|
||||
+
|
||||
+ if (loader_oop == NULL) {
|
||||
+ return _root;
|
||||
+ }
|
||||
+
|
||||
+ // Check if a node for this oop already exists.
|
||||
+ LoaderTreeNode* info = _root->find(loader_oop);
|
||||
+
|
||||
+ if (info == NULL) {
|
||||
+ // It does not. Create a node.
|
||||
+ info = new LoaderTreeNode(loader_oop);
|
||||
+
|
||||
+ // Add it to tree.
|
||||
+ LoaderTreeNode* parent_info = NULL;
|
||||
+
|
||||
+ // Recursively add parent nodes if needed.
|
||||
+ const oop parent_oop = java_lang_ClassLoader::parent(loader_oop);
|
||||
+ if (parent_oop == NULL) {
|
||||
+ parent_info = _root;
|
||||
+ } else {
|
||||
+ parent_info = find_node_or_add_empty_node(parent_oop);
|
||||
+ }
|
||||
+ assert(parent_info != NULL, "must be");
|
||||
+
|
||||
+ parent_info->add_child(info);
|
||||
+ }
|
||||
+ return info;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+public:
|
||||
+ LoaderInfoScanClosure(bool print_classes, bool verbose)
|
||||
+ : _print_classes(print_classes), _verbose(verbose), _root(NULL) {
|
||||
+ _root = new LoaderTreeNode(NULL);
|
||||
+ }
|
||||
+
|
||||
+ void print_results(outputStream* st) const {
|
||||
+ _root->print_with_child_nodes(st, _print_classes, _verbose);
|
||||
+ }
|
||||
+
|
||||
+ void do_cld (ClassLoaderData* cld) {
|
||||
+
|
||||
+ // We do not display unloading loaders, for now.
|
||||
+ if (cld->is_unloading()) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ const oop loader_oop = cld->class_loader();
|
||||
+
|
||||
+ LoaderTreeNode* info = find_node_or_add_empty_node(loader_oop);
|
||||
+ assert(info != NULL, "must be");
|
||||
+
|
||||
+ // Update CLD in node, but only if this is the primary CLD for this loader.
|
||||
+ if (cld->is_anonymous() == false) {
|
||||
+ info->set_cld(cld);
|
||||
+ }
|
||||
+
|
||||
+ // Add classes.
|
||||
+ fill_in_classes(info, cld);
|
||||
+ }
|
||||
+
|
||||
+};
|
||||
+
|
||||
+
|
||||
+class ClassLoaderHierarchyVMOperation : public VM_Operation {
|
||||
+ outputStream* const _out;
|
||||
+ const bool _show_classes;
|
||||
+ const bool _verbose;
|
||||
+public:
|
||||
+ ClassLoaderHierarchyVMOperation(outputStream* out, bool show_classes, bool verbose) :
|
||||
+ _out(out), _show_classes(show_classes), _verbose(verbose)
|
||||
+ {}
|
||||
+
|
||||
+ VMOp_Type type() const {
|
||||
+ return VMOp_ClassLoaderHierarchyOperation;
|
||||
+ }
|
||||
+
|
||||
+ void doit() {
|
||||
+ assert(SafepointSynchronize::is_at_safepoint(), "must be a safepoint");
|
||||
+ ResourceMark rm;
|
||||
+ LoaderInfoScanClosure cl (_show_classes, _verbose);
|
||||
+ ClassLoaderDataGraph::cld_do(&cl);
|
||||
+ cl.print_results(_out);
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+// This command needs to be executed at a safepoint.
|
||||
+void ClassLoaderHierarchyDCmd::execute(DCmdSource source, TRAPS) {
|
||||
+ ClassLoaderHierarchyVMOperation op(output(), _show_classes.value(), _verbose.value());
|
||||
+ VMThread::execute(&op);
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/hotspot/src/share/vm/classfile/classLoaderHierarchyDCmd.hpp b/hotspot/src/share/vm/classfile/classLoaderHierarchyDCmd.hpp
|
||||
new file mode 100644
|
||||
index 0000000..49027e6
|
||||
--- /dev/null
|
||||
+++ b/hotspot/src/share/vm/classfile/classLoaderHierarchyDCmd.hpp
|
||||
@@ -0,0 +1,59 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
+ * Copyright (c) 2018 SAP SE. 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
|
||||
+ * under the terms of the GNU General Public License version 2 only, as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
+ * version 2 for more details (a copy is included in the LICENSE file that
|
||||
+ * accompanied this code).
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License version
|
||||
+ * 2 along with this work; if not, write to the Free Software Foundation,
|
||||
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
+ *
|
||||
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
+ * or visit www.oracle.com if you need additional information or have any
|
||||
+ * questions.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#ifndef HOTSPOT_SHARE_CLASSFILE_CLASSLOADERHIERARCHYDCMD_HPP_
|
||||
+#define HOTSPOT_SHARE_CLASSFILE_CLASSLOADERHIERARCHYDCMD_HPP_
|
||||
+
|
||||
+#include "services/diagnosticCommand.hpp"
|
||||
+
|
||||
+class ClassLoaderHierarchyDCmd: public DCmdWithParser {
|
||||
+ DCmdArgument<bool> _show_classes;
|
||||
+ DCmdArgument<bool> _verbose;
|
||||
+public:
|
||||
+
|
||||
+ ClassLoaderHierarchyDCmd(outputStream* output, bool heap);
|
||||
+
|
||||
+ static const char* name() {
|
||||
+ return "VM.classloaders";
|
||||
+ }
|
||||
+
|
||||
+ static const char* description() {
|
||||
+ return "Prints classloader hierarchy.";
|
||||
+ }
|
||||
+ static const char* impact() {
|
||||
+ return "Medium: Depends on number of class loaders and classes loaded.";
|
||||
+ }
|
||||
+ static const JavaPermission permission() {
|
||||
+ JavaPermission p = {"java.lang.management.ManagementPermission",
|
||||
+ "monitor", NULL};
|
||||
+ return p;
|
||||
+ }
|
||||
+ static int num_arguments();
|
||||
+ virtual void execute(DCmdSource source, TRAPS);
|
||||
+
|
||||
+};
|
||||
+
|
||||
+#endif /* HOTSPOT_SHARE_CLASSFILE_CLASSLOADERHIERARCHYDCMD_HPP_ */
|
||||
\ No newline at end of file
|
||||
diff --git a/hotspot/src/share/vm/runtime/vm_operations.hpp b/hotspot/src/share/vm/runtime/vm_operations.hpp
|
||||
index a8ba78b..3744040 100644
|
||||
--- a/hotspot/src/share/vm/runtime/vm_operations.hpp
|
||||
+++ b/hotspot/src/share/vm/runtime/vm_operations.hpp
|
||||
@@ -98,6 +98,7 @@
|
||||
template(RotateGCLog) \
|
||||
template(WhiteBoxOperation) \
|
||||
template(ClassLoaderStatsOperation) \
|
||||
+ template(ClassLoaderHierarchyOperation) \
|
||||
template(JFROldObject) \
|
||||
template(PrintClasses) \
|
||||
|
||||
diff --git a/hotspot/src/share/vm/services/diagnosticCommand.cpp b/hotspot/src/share/vm/services/diagnosticCommand.cpp
|
||||
index e4e6185..d3b91d9 100644
|
||||
--- a/hotspot/src/share/vm/services/diagnosticCommand.cpp
|
||||
+++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "cds/dynamicArchive.hpp"
|
||||
+#include "classfile/classLoaderHierarchyDCmd.hpp"
|
||||
#include "classfile/classLoaderStats.hpp"
|
||||
#include "gc_implementation/shared/vmGCOperations.hpp"
|
||||
#include "runtime/javaCalls.hpp"
|
||||
@@ -70,6 +71,7 @@ void DCmdRegistrant::register_dcmds(){
|
||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(full_export, true, false));
|
||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RotateGCLogDCmd>(full_export, true, false));
|
||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassLoaderStatsDCmd>(full_export, true, false));
|
||||
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassLoaderHierarchyDCmd>(full_export, true, false));
|
||||
#ifdef LINUX
|
||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<TrimCLibcHeapDCmd>(full_export, true, false));
|
||||
#endif // LINUX
|
||||
diff --git a/hotspot/test/serviceability/dcmd/ClassLoaderHierarchyTest.java b/hotspot/test/serviceability/dcmd/ClassLoaderHierarchyTest.java
|
||||
new file mode 100644
|
||||
index 0000000..378997d
|
||||
--- /dev/null
|
||||
+++ b/hotspot/test/serviceability/dcmd/ClassLoaderHierarchyTest.java
|
||||
@@ -0,0 +1,213 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
+ * Copyright (c) 2018, SAP SE. 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
|
||||
+ * under the terms of the GNU General Public License version 2 only, as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
+ * version 2 for more details (a copy is included in the LICENSE file that
|
||||
+ * accompanied this code).
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License version
|
||||
+ * 2 along with this work; if not, write to the Free Software Foundation,
|
||||
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
+ *
|
||||
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
+ * or visit www.oracle.com if you need additional information or have any
|
||||
+ * questions.
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * @test
|
||||
+ * @summary Test of diagnostic command VM.classloaders
|
||||
+ * @library /testlibrary
|
||||
+ * @modules java.base/jdk.internal.misc
|
||||
+ * java.compiler
|
||||
+ * java.management
|
||||
+ * jdk.internal.jvmstat/sun.jvmstat.monitor
|
||||
+ * @run testng ClassLoaderHierarchyTest
|
||||
+ */
|
||||
+
|
||||
+import org.testng.Assert;
|
||||
+import org.testng.annotations.Test;
|
||||
+
|
||||
+import com.oracle.java.testlibrary.OutputAnalyzer;
|
||||
+import com.oracle.java.testlibrary.CommandExecutor;
|
||||
+import com.oracle.java.testlibrary.JMXExecutor;
|
||||
+
|
||||
+import java.io.File;
|
||||
+import java.io.FileInputStream;
|
||||
+import java.io.IOException;
|
||||
+import java.nio.ByteBuffer;
|
||||
+import java.nio.channels.FileChannel;
|
||||
+
|
||||
+public class ClassLoaderHierarchyTest {
|
||||
+
|
||||
+ class EmptyDelegatingLoader extends ClassLoader {
|
||||
+ EmptyDelegatingLoader(ClassLoader parent) {
|
||||
+ super(parent);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ static void loadTestClassInLoaderAndCheck(String classname, ClassLoader loader) throws ClassNotFoundException {
|
||||
+ Class<?> c = Class.forName(classname, true, loader);
|
||||
+ if (c.getClassLoader() != loader) {
|
||||
+ Assert.fail(classname + " defined by wrong classloader: " + c.getClassLoader());
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+//+-- <bootstrap>
|
||||
+// |
|
||||
+// +-- "sun.misc.Launcher$ExtClassLoader", sun.misc.Launcher$ExtClassLoader
|
||||
+// | |
|
||||
+// | +-- "sun.misc.Launcher$AppClassLoader", sun.misc.Launcher$AppClassLoader
|
||||
+// |
|
||||
+// +-- "sun.reflect.DelegatingClassLoader", sun.reflect.DelegatingClassLoader
|
||||
+// |
|
||||
+// +-- "ClassLoaderHierarchyTest$TestClassLoader", ClassLoaderHierarchyTest$TestClassLoader
|
||||
+// | |
|
||||
+// | +-- "ClassLoaderHierarchyTest$TestClassLoader", ClassLoaderHierarchyTest$TestClassLoader
|
||||
+// |
|
||||
+// +-- "ClassLoaderHierarchyTest$EmptyDelegatingLoader", ClassLoaderHierarchyTest$EmptyDelegatingLoader
|
||||
+// | |
|
||||
+// | +-- "ClassLoaderHierarchyTest$EmptyDelegatingLoader", ClassLoaderHierarchyTest$EmptyDelegatingLoader
|
||||
+// | |
|
||||
+// | +-- "ClassLoaderHierarchyTest$TestClassLoader", ClassLoaderHierarchyTest$TestClassLoader
|
||||
+// |
|
||||
+// +-- "ClassLoaderHierarchyTest$EmptyDelegatingLoader", ClassLoaderHierarchyTest$EmptyDelegatingLoader
|
||||
+// |
|
||||
+// +-- "ClassLoaderHierarchyTest$EmptyDelegatingLoader", ClassLoaderHierarchyTest$EmptyDelegatingLoader
|
||||
+// |
|
||||
+// +-- "ClassLoaderHierarchyTest$TestClassLoader", ClassLoaderHierarchyTest$TestClassLoader
|
||||
+// |
|
||||
+// +-- "ClassLoaderHierarchyTest$TestClassLoader", ClassLoaderHierarchyTest$TestClassLoader
|
||||
+// |
|
||||
+// +-- "ClassLoaderHierarchyTest$TestClassLoader", ClassLoaderHierarchyTest$TestClassLoader
|
||||
+
|
||||
+
|
||||
+ public void run(CommandExecutor executor) throws ClassNotFoundException {
|
||||
+
|
||||
+ // A) one unnamed, two named loaders
|
||||
+ ClassLoader unnamed_cl = new TestClassLoader(null);
|
||||
+ ClassLoader named_child_cl = new TestClassLoader(unnamed_cl);
|
||||
+ loadTestClassInLoaderAndCheck("TestClass2", unnamed_cl);
|
||||
+ loadTestClassInLoaderAndCheck("TestClass2", named_child_cl);
|
||||
+
|
||||
+ // B) A named CL with empty loaders as parents (JDK-8293156)
|
||||
+ EmptyDelegatingLoader emptyLoader1 = new EmptyDelegatingLoader( null);
|
||||
+ EmptyDelegatingLoader emptyLoader2 = new EmptyDelegatingLoader(emptyLoader1);
|
||||
+ ClassLoader named_child_2_cl = new TestClassLoader(emptyLoader2);
|
||||
+ loadTestClassInLoaderAndCheck("TestClass2", named_child_2_cl);
|
||||
+
|
||||
+ // C) Test output for several *unnamed* class loaders, same class, same parents,
|
||||
+ // and all these should be folded by default.
|
||||
+ EmptyDelegatingLoader emptyLoader3 = new EmptyDelegatingLoader(null);
|
||||
+ EmptyDelegatingLoader emptyLoader4 = new EmptyDelegatingLoader(emptyLoader3);
|
||||
+ ClassLoader named_child_3_cl = new TestClassLoader(emptyLoader4); // Same names
|
||||
+ ClassLoader named_child_4_cl = new TestClassLoader(emptyLoader4);
|
||||
+ ClassLoader named_child_5_cl = new TestClassLoader(emptyLoader4);
|
||||
+ loadTestClassInLoaderAndCheck("TestClass2", named_child_3_cl);
|
||||
+ loadTestClassInLoaderAndCheck("TestClass2", named_child_4_cl);
|
||||
+ loadTestClassInLoaderAndCheck("TestClass2", named_child_5_cl);
|
||||
+
|
||||
+ // First test: simple output, no classes displayed
|
||||
+ OutputAnalyzer output = executor.execute("VM.classloaders");
|
||||
+ // (A)
|
||||
+ output.shouldContain("+-- <bootstrap>");
|
||||
+ output.shouldContain(" +-- \"sun.misc.Launcher$ExtClassLoader\", sun.misc.Launcher$ExtClassLoader");
|
||||
+ output.shouldContain(" | +-- \"sun.misc.Launcher$AppClassLoader\", sun.misc.Launcher$AppClassLoader");
|
||||
+ output.shouldContain(" +-- \"sun.reflect.DelegatingClassLoader\", sun.reflect.DelegatingClassLoader");
|
||||
+ output.shouldContain(" +-- \"ClassLoaderHierarchyTest$TestClassLoader\", ClassLoaderHierarchyTest$TestClassLoader");
|
||||
+ output.shouldContain(" | +-- \"ClassLoaderHierarchyTest$TestClassLoader\", ClassLoaderHierarchyTest$TestClassLoader");
|
||||
+ // (B)
|
||||
+ output.shouldContain(" +-- \"ClassLoaderHierarchyTest$EmptyDelegatingLoader\", ClassLoaderHierarchyTest$EmptyDelegatingLoader");
|
||||
+ output.shouldContain(" | +-- \"ClassLoaderHierarchyTest$EmptyDelegatingLoader\", ClassLoaderHierarchyTest$EmptyDelegatingLoader");
|
||||
+ output.shouldContain(" | +-- \"ClassLoaderHierarchyTest$TestClassLoader\", ClassLoaderHierarchyTest$TestClassLoader");
|
||||
+ // (C)
|
||||
+ output.shouldContain(" +-- \"ClassLoaderHierarchyTest$EmptyDelegatingLoader\", ClassLoaderHierarchyTest$EmptyDelegatingLoader");
|
||||
+ output.shouldContain(" +-- \"ClassLoaderHierarchyTest$EmptyDelegatingLoader\", ClassLoaderHierarchyTest$EmptyDelegatingLoader");
|
||||
+ output.shouldContain(" +-- \"ClassLoaderHierarchyTest$TestClassLoader\", ClassLoaderHierarchyTest$TestClassLoader");
|
||||
+
|
||||
+ // Second test: print with classes.
|
||||
+ output = executor.execute("VM.classloaders show-classes");
|
||||
+ output.shouldContain("<bootstrap>");
|
||||
+ output.shouldContain("java.lang.Object");
|
||||
+ output.shouldContain("java.lang.Enum");
|
||||
+ output.shouldContain("java.lang.NullPointerException");
|
||||
+ output.shouldContain("TestClass2");
|
||||
+ }
|
||||
+
|
||||
+ static class TestClassLoader extends ClassLoader {
|
||||
+
|
||||
+ public TestClassLoader() {
|
||||
+ super();
|
||||
+ }
|
||||
+
|
||||
+ public TestClassLoader(ClassLoader parent) {
|
||||
+ super(parent);
|
||||
+ }
|
||||
+
|
||||
+ public static final String CLASS_NAME = "TestClass2";
|
||||
+
|
||||
+ static ByteBuffer readClassFile(String name)
|
||||
+ {
|
||||
+ File f = new File(System.getProperty("test.classes", "."),
|
||||
+ name);
|
||||
+ try (FileInputStream fin = new FileInputStream(f);
|
||||
+ FileChannel fc = fin.getChannel())
|
||||
+ {
|
||||
+ return fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
|
||||
+ } catch (IOException e) {
|
||||
+ Assert.fail("Can't open file: " + name, e);
|
||||
+ }
|
||||
+
|
||||
+ /* Will not reach here as Assert.fail() throws exception */
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ protected Class<?> loadClass(String name, boolean resolve)
|
||||
+ throws ClassNotFoundException
|
||||
+ {
|
||||
+ Class<?> c;
|
||||
+ if (!CLASS_NAME.equals(name)) {
|
||||
+ c = super.loadClass(name, resolve);
|
||||
+ } else {
|
||||
+ // should not delegate to the system class loader
|
||||
+ c = findClass(name);
|
||||
+ if (resolve) {
|
||||
+ resolveClass(c);
|
||||
+ }
|
||||
+ }
|
||||
+ return c;
|
||||
+ }
|
||||
+
|
||||
+ protected Class<?> findClass(String name)
|
||||
+ throws ClassNotFoundException
|
||||
+ {
|
||||
+ if (!CLASS_NAME.equals(name)) {
|
||||
+ throw new ClassNotFoundException("Unexpected class: " + name);
|
||||
+ }
|
||||
+ return defineClass(name, readClassFile(name + ".class"), null);
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void jmx() throws ClassNotFoundException {
|
||||
+ run(new JMXExecutor());
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
+
|
||||
+class TestClass2 {
|
||||
+ static {
|
||||
+ Runnable r = () -> System.out.println("Hello");
|
||||
+ r.run();
|
||||
+ }
|
||||
+}
|
||||
\ No newline at end of file
|
||||
--
|
||||
1.8.3.1
|
||||
69
8204595-add-more-thread-related-system-settings-info.patch
Normal file
69
8204595-add-more-thread-related-system-settings-info.patch
Normal file
@ -0,0 +1,69 @@
|
||||
From 16caa051cb7299312cdaf9d79eaef01d294474f6 Mon Sep 17 00:00:00 2001
|
||||
From: eapen <zhangyipeng7@huawei.com>
|
||||
Date: Thu, 15 Dec 2022 17:06:41 +0800
|
||||
Subject: [PATCH 21/33] I68TO2: 8204595: add more thread-related system settings info
|
||||
to hs_error file on Linux
|
||||
---
|
||||
hotspot/src/os/linux/vm/os_linux.cpp | 22 +++++++++++++++++++++-
|
||||
hotspot/src/os/linux/vm/os_linux.hpp | 1 +
|
||||
2 files changed, 22 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp
|
||||
index abf2031..1ec68ab 100644
|
||||
--- a/hotspot/src/os/linux/vm/os_linux.cpp
|
||||
+++ b/hotspot/src/os/linux/vm/os_linux.cpp
|
||||
@@ -2249,6 +2249,8 @@ void os::print_os_info(outputStream* st) {
|
||||
|
||||
os::Linux::print_process_memory_info(st);
|
||||
|
||||
+ os::Linux::print_proc_sys_info(st);
|
||||
+
|
||||
os::Linux::print_container_info(st);
|
||||
}
|
||||
|
||||
@@ -2390,6 +2392,24 @@ void os::Linux::print_process_memory_info(outputStream* st) {
|
||||
|
||||
}
|
||||
|
||||
+void os::Linux::print_proc_sys_info(outputStream* st) {
|
||||
+ st->cr();
|
||||
+ st->print_cr("/proc/sys/kernel/threads-max (system-wide limit on the number of threads):");
|
||||
+ _print_ascii_file("/proc/sys/kernel/threads-max", st);
|
||||
+ st->cr();
|
||||
+ st->cr();
|
||||
+
|
||||
+ st->print_cr("/proc/sys/vm/max_map_count (maximum number of memory map areas a process may have):");
|
||||
+ _print_ascii_file("/proc/sys/vm/max_map_count", st);
|
||||
+ st->cr();
|
||||
+ st->cr();
|
||||
+
|
||||
+ st->print_cr("/proc/sys/kernel/pid_max (system-wide limit on number of process identifiers):");
|
||||
+ _print_ascii_file("/proc/sys/kernel/pid_max", st);
|
||||
+ st->cr();
|
||||
+ st->cr();
|
||||
+}
|
||||
+
|
||||
void os::Linux::print_container_info(outputStream* st) {
|
||||
if (!OSContainer::is_containerized()) {
|
||||
return;
|
||||
@@ -6928,4 +6948,4 @@ bool os::trim_native_heap(os::size_change_t* rss_change) {
|
||||
#else
|
||||
return false; // musl
|
||||
#endif
|
||||
-}
|
||||
\ No newline at end of file
|
||||
+}
|
||||
diff --git a/hotspot/src/os/linux/vm/os_linux.hpp b/hotspot/src/os/linux/vm/os_linux.hpp
|
||||
index 6c27bcb..4ee2c9b 100644
|
||||
--- a/hotspot/src/os/linux/vm/os_linux.hpp
|
||||
+++ b/hotspot/src/os/linux/vm/os_linux.hpp
|
||||
@@ -125,6 +125,7 @@ class Linux {
|
||||
static void print_container_info(outputStream* st);
|
||||
static void print_distro_info(outputStream* st);
|
||||
static void print_libversion_info(outputStream* st);
|
||||
+ static void print_proc_sys_info(outputStream* st);
|
||||
|
||||
public:
|
||||
static bool _stack_is_executable;
|
||||
--
|
||||
1.8.3.1
|
||||
407
8219584-Try-to-dump-error-file-by-thread-which-cause.patch
Normal file
407
8219584-Try-to-dump-error-file-by-thread-which-cause.patch
Normal file
@ -0,0 +1,407 @@
|
||||
From b61cd484f501a1fe7d49c336878a4b8398e727d9 Mon Sep 17 00:00:00 2001
|
||||
From: eapen <zhangyipeng7@huawei.com>
|
||||
Date: Thu, 15 Dec 2022 14:28:05 +0800
|
||||
Subject: [PATCH 20/33] I68TO2: 8219584: Try to dump error file by thread which causes
|
||||
safepoint timeout
|
||||
---
|
||||
hotspot/src/os/posix/vm/os_posix.cpp | 31 ++++++-
|
||||
hotspot/src/os/windows/vm/os_windows.cpp | 9 ++
|
||||
hotspot/src/share/vm/runtime/globals.hpp | 2 +-
|
||||
hotspot/src/share/vm/runtime/os.hpp | 4 +
|
||||
hotspot/src/share/vm/runtime/safepoint.cpp | 21 +++--
|
||||
hotspot/src/share/vm/runtime/vmThread.cpp | 36 +++++---
|
||||
hotspot/src/share/vm/runtime/vmThread.hpp | 10 ++-
|
||||
hotspot/src/share/vm/utilities/vmError.cpp | 3 +
|
||||
.../Safepoint/TestAbortVMOnSafepointTimeout.java | 97 ++++++++++++++++++++++
|
||||
9 files changed, 195 insertions(+), 18 deletions(-)
|
||||
create mode 100644 hotspot/test/runtime/Safepoint/TestAbortVMOnSafepointTimeout.java
|
||||
|
||||
diff --git a/hotspot/src/os/posix/vm/os_posix.cpp b/hotspot/src/os/posix/vm/os_posix.cpp
|
||||
index e7f1fdd..d2663bd 100644
|
||||
--- a/hotspot/src/os/posix/vm/os_posix.cpp
|
||||
+++ b/hotspot/src/os/posix/vm/os_posix.cpp
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "prims/jvm.h"
|
||||
#include "runtime/frame.inline.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
+#include "utilities/events.hpp"
|
||||
#include "utilities/vmError.hpp"
|
||||
|
||||
#include <signal.h>
|
||||
@@ -814,6 +815,15 @@ static bool get_signal_code_description(const siginfo_t* si, enum_sigcode_desc_t
|
||||
return true;
|
||||
}
|
||||
|
||||
+bool os::signal_sent_by_kill(const void* siginfo) {
|
||||
+ const siginfo_t* const si = (const siginfo_t*)siginfo;
|
||||
+ return si->si_code == SI_USER || si->si_code == SI_QUEUE
|
||||
+#ifdef SI_TKILL
|
||||
+ || si->si_code == SI_TKILL
|
||||
+#endif
|
||||
+ ;
|
||||
+}
|
||||
+
|
||||
// A POSIX conform, platform-independend siginfo print routine.
|
||||
// Short print out on one line.
|
||||
void os::Posix::print_siginfo_brief(outputStream* os, const siginfo_t* si) {
|
||||
@@ -844,7 +854,7 @@ void os::Posix::print_siginfo_brief(outputStream* os, const siginfo_t* si) {
|
||||
const int me = (int) ::getpid();
|
||||
const int pid = (int) si->si_pid;
|
||||
|
||||
- if (si->si_code == SI_USER || si->si_code == SI_QUEUE) {
|
||||
+ if (signal_sent_by_kill(si)) {
|
||||
if (IS_VALID_PID(pid) && pid != me) {
|
||||
os->print(", sent from pid: %d (uid: %d)", pid, (int) si->si_uid);
|
||||
}
|
||||
@@ -860,6 +870,25 @@ void os::Posix::print_siginfo_brief(outputStream* os, const siginfo_t* si) {
|
||||
}
|
||||
}
|
||||
|
||||
+bool os::signal_thread(Thread* thread, int sig, const char* reason) {
|
||||
+ OSThread* osthread = thread->osthread();
|
||||
+ if (osthread) {
|
||||
+#if defined (SOLARIS)
|
||||
+ // Note: we cannot use pthread_kill on Solaris - not because
|
||||
+ // its missing, but because we do not have the pthread_t id.
|
||||
+ int status = thr_kill(osthread->thread_id(), sig);
|
||||
+#else
|
||||
+ int status = pthread_kill(osthread->pthread_id(), sig);
|
||||
+#endif
|
||||
+ if (status == 0) {
|
||||
+ Events::log(Thread::current(), "sent signal %d to Thread " INTPTR_FORMAT " because %s.",
|
||||
+ sig, p2i(thread), reason);
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
bool os::Posix::is_root(uid_t uid){
|
||||
return ROOT_UID == uid;
|
||||
}
|
||||
diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp
|
||||
index cc31126..cf1036c 100644
|
||||
--- a/hotspot/src/os/windows/vm/os_windows.cpp
|
||||
+++ b/hotspot/src/os/windows/vm/os_windows.cpp
|
||||
@@ -1877,6 +1877,11 @@ void os::print_memory_info(outputStream* st) {
|
||||
st->cr();
|
||||
}
|
||||
|
||||
+bool os::signal_sent_by_kill(const void* siginfo) {
|
||||
+ // TODO: Is this possible?
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
void os::print_siginfo(outputStream *st, void *siginfo) {
|
||||
EXCEPTION_RECORD* er = (EXCEPTION_RECORD*)siginfo;
|
||||
st->print("siginfo:");
|
||||
@@ -1911,6 +1916,10 @@ void os::print_siginfo(outputStream *st, void *siginfo) {
|
||||
st->cr();
|
||||
}
|
||||
|
||||
+bool os::signal_thread(Thread* thread, int sig, const char* reason) {
|
||||
+ // TODO: Can we kill thread?
|
||||
+ return false;
|
||||
+}
|
||||
|
||||
int os::vsnprintf(char* buf, size_t len, const char* fmt, va_list args) {
|
||||
#if _MSC_VER >= 1900
|
||||
diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
|
||||
index 10e4e7f..64d40e0 100644
|
||||
--- a/hotspot/src/share/vm/runtime/globals.hpp
|
||||
+++ b/hotspot/src/share/vm/runtime/globals.hpp
|
||||
@@ -650,7 +650,7 @@ class CommandLineFlags {
|
||||
"Print out every time compilation is longer than " \
|
||||
"a given threshold") \
|
||||
\
|
||||
- develop(bool, SafepointALot, false, \
|
||||
+ diagnostic(bool, SafepointALot, false, \
|
||||
"Generate a lot of safepoints. This works with " \
|
||||
"GuaranteedSafepointInterval") \
|
||||
\
|
||||
diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp
|
||||
index 5f41e96..092459c 100644
|
||||
--- a/hotspot/src/share/vm/runtime/os.hpp
|
||||
+++ b/hotspot/src/share/vm/runtime/os.hpp
|
||||
@@ -492,6 +492,9 @@ class os: AllStatic {
|
||||
static void pd_start_thread(Thread* thread);
|
||||
static void start_thread(Thread* thread);
|
||||
|
||||
+ // Returns true if successful.
|
||||
+ static bool signal_thread(Thread* thread, int sig, const char* reason);
|
||||
+
|
||||
static void initialize_thread(Thread* thr);
|
||||
static void free_thread(OSThread* osthread);
|
||||
|
||||
@@ -653,6 +656,7 @@ class os: AllStatic {
|
||||
static void print_environment_variables(outputStream* st, const char** env_list, char* buffer, int len);
|
||||
static void print_context(outputStream* st, void* context);
|
||||
static void print_register_info(outputStream* st, void* context);
|
||||
+ static bool signal_sent_by_kill(const void* siginfo);
|
||||
static void print_siginfo(outputStream* st, void* siginfo);
|
||||
static void print_signal_handlers(outputStream* st, char* buf, size_t buflen);
|
||||
static void print_date_and_time(outputStream* st, char* buf, size_t buflen);
|
||||
diff --git a/hotspot/src/share/vm/runtime/safepoint.cpp b/hotspot/src/share/vm/runtime/safepoint.cpp
|
||||
index 440617c..8408bed 100644
|
||||
--- a/hotspot/src/share/vm/runtime/safepoint.cpp
|
||||
+++ b/hotspot/src/share/vm/runtime/safepoint.cpp
|
||||
@@ -476,8 +476,7 @@ void SafepointSynchronize::begin() {
|
||||
GC_locker::set_jni_lock_count(_current_jni_active_count);
|
||||
|
||||
if (TraceSafepoint) {
|
||||
- VM_Operation *op = VMThread::vm_operation();
|
||||
- tty->print_cr("Entering safepoint region: %s", (op != NULL) ? op->name() : "no vm operation");
|
||||
+ tty->print_cr("Entering safepoint region: %s", VMThread::vm_safepoint_description());
|
||||
}
|
||||
|
||||
RuntimeService::record_safepoint_synchronized();
|
||||
@@ -929,11 +928,23 @@ void SafepointSynchronize::print_safepoint_timeout(SafepointTimeoutReason reason
|
||||
// To debug the long safepoint, specify both AbortVMOnSafepointTimeout &
|
||||
// ShowMessageBoxOnError.
|
||||
if (AbortVMOnSafepointTimeout) {
|
||||
+ // Send the blocking thread a signal to terminate and write an error file.
|
||||
+ for (JavaThread *cur_thread = Threads::first(); cur_thread;
|
||||
+ cur_thread = cur_thread->next()) {
|
||||
+ ThreadSafepointState *cur_state = cur_thread->safepoint_state();
|
||||
+ if (cur_thread->thread_state() != _thread_blocked &&
|
||||
+ ((reason == _spinning_timeout && cur_state->is_running()) ||
|
||||
+ (reason == _blocking_timeout && !cur_state->has_called_back()))) {
|
||||
+ if (!os::signal_thread(cur_thread, SIGILL, "blocking a safepoint")) {
|
||||
+ break; // Could not send signal. Report fatal error.
|
||||
+ }
|
||||
+ // Give cur_thread a chance to report the error and terminate the VM.
|
||||
+ os::sleep(Thread::current(), 3000, false);
|
||||
+ }
|
||||
+ }
|
||||
char msg[1024];
|
||||
- VM_Operation *op = VMThread::vm_operation();
|
||||
sprintf(msg, "Safepoint sync time longer than " INTX_FORMAT "ms detected when executing %s.",
|
||||
- SafepointTimeoutDelay,
|
||||
- op != NULL ? op->name() : "no vm operation");
|
||||
+ SafepointTimeoutDelay, VMThread::vm_safepoint_description());
|
||||
fatal(msg);
|
||||
}
|
||||
}
|
||||
diff --git a/hotspot/src/share/vm/runtime/vmThread.cpp b/hotspot/src/share/vm/runtime/vmThread.cpp
|
||||
index b27c287..4f1695e 100644
|
||||
--- a/hotspot/src/share/vm/runtime/vmThread.cpp
|
||||
+++ b/hotspot/src/share/vm/runtime/vmThread.cpp
|
||||
@@ -217,6 +217,7 @@ VMThread* VMThread::_vm_thread = NULL;
|
||||
VM_Operation* VMThread::_cur_vm_operation = NULL;
|
||||
VMOperationQueue* VMThread::_vm_queue = NULL;
|
||||
PerfCounter* VMThread::_perf_accumulated_vm_operation_time = NULL;
|
||||
+const char* VMThread::_no_op_reason = NULL;
|
||||
|
||||
|
||||
void VMThread::create() {
|
||||
@@ -290,6 +291,7 @@ void VMThread::run() {
|
||||
}
|
||||
|
||||
// 4526887 let VM thread exit at Safepoint
|
||||
+ _no_op_reason = "Halt";
|
||||
SafepointSynchronize::begin();
|
||||
|
||||
if (VerifyBeforeExit) {
|
||||
@@ -422,6 +424,25 @@ void VMThread::evaluate_operation(VM_Operation* op) {
|
||||
}
|
||||
}
|
||||
|
||||
+bool VMThread::no_op_safepoint_needed(bool check_time) {
|
||||
+ if (SafepointALot) {
|
||||
+ _no_op_reason = "SafepointALot";
|
||||
+ return true;
|
||||
+ }
|
||||
+ if (!SafepointSynchronize::is_cleanup_needed()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (check_time) {
|
||||
+ long interval = SafepointSynchronize::last_non_safepoint_interval();
|
||||
+ bool max_time_exceeded = GuaranteedSafepointInterval != 0 &&
|
||||
+ (interval > GuaranteedSafepointInterval);
|
||||
+ if (!max_time_exceeded) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ _no_op_reason = "Cleanup";
|
||||
+ return true;
|
||||
+}
|
||||
|
||||
void VMThread::loop() {
|
||||
assert(_cur_vm_operation == NULL, "no current one should be executing");
|
||||
@@ -460,8 +481,7 @@ void VMThread::loop() {
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
- if (timedout && (SafepointALot ||
|
||||
- SafepointSynchronize::is_cleanup_needed())) {
|
||||
+ if (timedout && VMThread::no_op_safepoint_needed(false)) {
|
||||
MutexUnlockerEx mul(VMOperationQueue_lock,
|
||||
Mutex::_no_safepoint_check_flag);
|
||||
// Force a safepoint since we have not had one for at least
|
||||
@@ -585,14 +605,10 @@ void VMThread::loop() {
|
||||
//
|
||||
// We want to make sure that we get to a safepoint regularly.
|
||||
//
|
||||
- if (SafepointALot || SafepointSynchronize::is_cleanup_needed()) {
|
||||
- long interval = SafepointSynchronize::last_non_safepoint_interval();
|
||||
- bool max_time_exceeded = GuaranteedSafepointInterval != 0 && (interval > GuaranteedSafepointInterval);
|
||||
- if (SafepointALot || max_time_exceeded) {
|
||||
- HandleMark hm(VMThread::vm_thread());
|
||||
- SafepointSynchronize::begin();
|
||||
- SafepointSynchronize::end();
|
||||
- }
|
||||
+ if (VMThread::no_op_safepoint_needed(true)) {
|
||||
+ HandleMark hm(VMThread::vm_thread());
|
||||
+ SafepointSynchronize::begin();
|
||||
+ SafepointSynchronize::end();
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/hotspot/src/share/vm/runtime/vmThread.hpp b/hotspot/src/share/vm/runtime/vmThread.hpp
|
||||
index a6d1ad3..d8af0d9 100644
|
||||
--- a/hotspot/src/share/vm/runtime/vmThread.hpp
|
||||
+++ b/hotspot/src/share/vm/runtime/vmThread.hpp
|
||||
@@ -100,7 +100,12 @@ class VMThread: public NamedThread {
|
||||
static Monitor * _terminate_lock;
|
||||
static PerfCounter* _perf_accumulated_vm_operation_time;
|
||||
|
||||
+ static const char* _no_op_reason;
|
||||
+
|
||||
+ static bool no_op_safepoint_needed(bool check_time);
|
||||
+
|
||||
void evaluate_operation(VM_Operation* op);
|
||||
+
|
||||
public:
|
||||
// Constructor
|
||||
VMThread();
|
||||
@@ -123,7 +128,10 @@ class VMThread: public NamedThread {
|
||||
static void execute(VM_Operation* op);
|
||||
|
||||
// Returns the current vm operation if any.
|
||||
- static VM_Operation* vm_operation() { return _cur_vm_operation; }
|
||||
+ static VM_Operation* vm_operation() { return _cur_vm_operation; }
|
||||
+
|
||||
+ // Returns the current vm operation name or set reason
|
||||
+ static const char* vm_safepoint_description() { return _cur_vm_operation != NULL ? _cur_vm_operation->name() : _no_op_reason; };
|
||||
|
||||
// Returns the single instance of VMThread.
|
||||
static VMThread* vm_thread() { return _vm_thread; }
|
||||
diff --git a/hotspot/src/share/vm/utilities/vmError.cpp b/hotspot/src/share/vm/utilities/vmError.cpp
|
||||
index 9b40a34..261591d 100644
|
||||
--- a/hotspot/src/share/vm/utilities/vmError.cpp
|
||||
+++ b/hotspot/src/share/vm/utilities/vmError.cpp
|
||||
@@ -460,6 +460,9 @@ void VMError::report(outputStream* st) {
|
||||
st->print("%s", buf);
|
||||
st->print(" (0x%x)", _id); // signal number
|
||||
st->print(" at pc=" PTR_FORMAT, _pc);
|
||||
+ if (_siginfo != NULL && os::signal_sent_by_kill(_siginfo)) {
|
||||
+ st->print(" (sent by kill)");
|
||||
+ }
|
||||
} else {
|
||||
if (should_report_bug(_id)) {
|
||||
st->print("Internal Error");
|
||||
diff --git a/hotspot/test/runtime/Safepoint/TestAbortVMOnSafepointTimeout.java b/hotspot/test/runtime/Safepoint/TestAbortVMOnSafepointTimeout.java
|
||||
new file mode 100644
|
||||
index 0000000..a097bdc
|
||||
--- /dev/null
|
||||
+++ b/hotspot/test/runtime/Safepoint/TestAbortVMOnSafepointTimeout.java
|
||||
@@ -0,0 +1,97 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2019, SAP SE. All rights reserved.
|
||||
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. 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
|
||||
+ * under the terms of the GNU General Public License version 2 only, as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
+ * version 2 for more details (a copy is included in the LICENSE file that
|
||||
+ * accompanied this code).
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License version
|
||||
+ * 2 along with this work; if not, write to the Free Software Foundation,
|
||||
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
+ *
|
||||
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
+ * or visit www.oracle.com if you need additional information or have any
|
||||
+ * questions.
|
||||
+ */
|
||||
+
|
||||
+import com.oracle.java.testlibrary.*;
|
||||
+
|
||||
+/*
|
||||
+ * @test TestAbortVMOnSafepointTimeout
|
||||
+ * @summary Check if VM can kill thread which doesn't reach safepoint.
|
||||
+ * @bug 8219584 8227528
|
||||
+ * @library /testlibrary
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+public class TestAbortVMOnSafepointTimeout {
|
||||
+
|
||||
+ public static void main(String[] args) throws Exception {
|
||||
+ if (args.length > 0) {
|
||||
+ int result = test_loop(3);
|
||||
+ System.out.println("This message would occur after some time with result " + result);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ testWith(500, 500);
|
||||
+ }
|
||||
+
|
||||
+ static int test_loop(int x) {
|
||||
+ int sum = 0;
|
||||
+ if (x != 0) {
|
||||
+ // Long running loop without safepoint.
|
||||
+ for (int y = 1; y < Integer.MAX_VALUE; ++y) {
|
||||
+ if (y % x == 0) ++sum;
|
||||
+ }
|
||||
+ }
|
||||
+ return sum;
|
||||
+ }
|
||||
+
|
||||
+ public static void testWith(int sfpt_interval, int timeout_delay) throws Exception {
|
||||
+ // -XX:-UseCountedLoopSafepoints - is used to prevent the loop
|
||||
+ // in test_loop() to poll for safepoints.
|
||||
+ // -XX:LoopStripMiningIter=0 and -XX:LoopUnrollLimit=0 - are
|
||||
+ // used to prevent optimizations over the loop in test_loop()
|
||||
+ // since we actually want it to provoke a safepoint timeout.
|
||||
+ // -XX:-UseBiasedLocking - is used to prevent biased locking
|
||||
+ // handshakes from changing the timing of this test.
|
||||
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
|
||||
+ "-XX:+UnlockDiagnosticVMOptions",
|
||||
+ "-XX:-UseBiasedLocking",
|
||||
+ "-XX:+SafepointTimeout",
|
||||
+ "-XX:+SafepointALot",
|
||||
+ "-XX:+AbortVMOnSafepointTimeout",
|
||||
+ "-XX:SafepointTimeoutDelay=" + timeout_delay,
|
||||
+ "-XX:GuaranteedSafepointInterval=" + sfpt_interval,
|
||||
+ "-XX:-TieredCompilation",
|
||||
+ "-XX:-UseCountedLoopSafepoints",
|
||||
+ "-XX:LoopUnrollLimit=0",
|
||||
+ "-XX:CompileCommand=compileonly,TestAbortVMOnSafepointTimeout::test_loop",
|
||||
+ "-Xcomp",
|
||||
+ "-XX:-CreateMinidumpOnCrash",
|
||||
+ "-Xms64m",
|
||||
+ "TestAbortVMOnSafepointTimeout",
|
||||
+ "runTestLoop"
|
||||
+ );
|
||||
+
|
||||
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
|
||||
+ if (Platform.isWindows()) {
|
||||
+ output.shouldMatch("Safepoint sync time longer than");
|
||||
+ } else {
|
||||
+ output.shouldMatch("SIGILL");
|
||||
+ if (Platform.isLinux()) {
|
||||
+ output.shouldMatch("(sent by kill)");
|
||||
+ }
|
||||
+ output.shouldMatch("TestAbortVMOnSafepointTimeout.test_loop");
|
||||
+ }
|
||||
+ output.shouldNotHaveExitValue(0);
|
||||
+ }
|
||||
+}
|
||||
--
|
||||
1.8.3.1
|
||||
697
8229517-Support-for-optional-asynchronous-buffered-l.patch
Normal file
697
8229517-Support-for-optional-asynchronous-buffered-l.patch
Normal file
@ -0,0 +1,697 @@
|
||||
From 577f318d824d91e5deb8b6b82dd211583cb93cac Mon Sep 17 00:00:00 2001
|
||||
From: eapen <zhangyipeng7@huawei.com>
|
||||
Date: Thu, 15 Dec 2022 10:37:31 +0800
|
||||
Subject: [PATCH 18/33] I68TO2: 8229517: Support for optional asynchronous/buffered
|
||||
logging
|
||||
---
|
||||
hotspot/src/os/windows/vm/os_windows.cpp | 1 +
|
||||
hotspot/src/share/vm/runtime/arguments.cpp | 10 ++
|
||||
hotspot/src/share/vm/runtime/globals.hpp | 9 ++
|
||||
hotspot/src/share/vm/runtime/init.cpp | 2 +
|
||||
hotspot/src/share/vm/runtime/logAsyncWriter.cpp | 164 ++++++++++++++++++++++++
|
||||
hotspot/src/share/vm/runtime/logAsyncWriter.hpp | 159 +++++++++++++++++++++++
|
||||
hotspot/src/share/vm/runtime/os.hpp | 1 +
|
||||
hotspot/src/share/vm/runtime/thread.cpp | 26 +++-
|
||||
hotspot/src/share/vm/runtime/vmStructs.cpp | 2 +
|
||||
hotspot/src/share/vm/utilities/linkedlist.hpp | 47 +++++--
|
||||
hotspot/src/share/vm/utilities/ostream.cpp | 26 ++++
|
||||
hotspot/src/share/vm/utilities/ostream.hpp | 3 +
|
||||
12 files changed, 440 insertions(+), 10 deletions(-)
|
||||
create mode 100644 hotspot/src/share/vm/runtime/logAsyncWriter.cpp
|
||||
create mode 100644 hotspot/src/share/vm/runtime/logAsyncWriter.hpp
|
||||
|
||||
diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp
|
||||
index 25122de..cc31126 100644
|
||||
--- a/hotspot/src/os/windows/vm/os_windows.cpp
|
||||
+++ b/hotspot/src/os/windows/vm/os_windows.cpp
|
||||
@@ -562,6 +562,7 @@ bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {
|
||||
case os::pgc_thread:
|
||||
case os::cgc_thread:
|
||||
case os::watcher_thread:
|
||||
+ case os::asynclog_thread:
|
||||
if (VMThreadStackSize > 0) stack_size = (size_t)(VMThreadStackSize * K);
|
||||
break;
|
||||
}
|
||||
diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp
|
||||
index 91e2ce0..fba3d4b 100644
|
||||
--- a/hotspot/src/share/vm/runtime/arguments.cpp
|
||||
+++ b/hotspot/src/share/vm/runtime/arguments.cpp
|
||||
@@ -2269,6 +2269,16 @@ bool Arguments::verify_percentage(uintx value, const char* name) {
|
||||
// no gc log rotation when log file not supplied or
|
||||
// NumberOfGCLogFiles is 0
|
||||
void check_gclog_consistency() {
|
||||
+ if (UseAsyncGCLog) {
|
||||
+ if (Arguments::gc_log_filename() == NULL) {
|
||||
+ jio_fprintf(defaultStream::output_stream(),
|
||||
+ "To enable Async GC log, use -Xloggc:<filename> -XX:UseAsyncGCLog\n"
|
||||
+ "Async GC log is turned off\n");
|
||||
+ UseAsyncGCLog = false;
|
||||
+
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (UseGCLogFileRotation) {
|
||||
if ((Arguments::gc_log_filename() == NULL) || (NumberOfGCLogFiles == 0)) {
|
||||
jio_fprintf(defaultStream::output_stream(),
|
||||
diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
|
||||
index 41b1392..10e4e7f 100644
|
||||
--- a/hotspot/src/share/vm/runtime/globals.hpp
|
||||
+++ b/hotspot/src/share/vm/runtime/globals.hpp
|
||||
@@ -4104,6 +4104,15 @@ class CommandLineFlags {
|
||||
\
|
||||
JFR_ONLY(product(bool, LogJFR, false, \
|
||||
"Enable JFR logging (consider +Verbose)")) \
|
||||
+ \
|
||||
+ product(bool, UseAsyncGCLog, false, \
|
||||
+ "Enable asynchronous GC logging") \
|
||||
+ \
|
||||
+ product(uintx, AsyncLogBufferSize, 2*M, \
|
||||
+ "Memory budget (in bytes) for the buffer of Asynchronous") \
|
||||
+ \
|
||||
+ diagnostic(bool, PrintAsyncGCLog, false, \
|
||||
+ "Print some information of Async GC Log") \
|
||||
|
||||
/*
|
||||
* Macros for factoring of globals
|
||||
diff --git a/hotspot/src/share/vm/runtime/init.cpp b/hotspot/src/share/vm/runtime/init.cpp
|
||||
index d2e0f22..b185409 100644
|
||||
--- a/hotspot/src/share/vm/runtime/init.cpp
|
||||
+++ b/hotspot/src/share/vm/runtime/init.cpp
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "runtime/handles.inline.hpp"
|
||||
#include "runtime/icache.hpp"
|
||||
#include "runtime/init.hpp"
|
||||
+#include "runtime/logAsyncWriter.hpp"
|
||||
#include "runtime/safepoint.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "services/memTracker.hpp"
|
||||
@@ -106,6 +107,7 @@ jint init_globals() {
|
||||
if (status != JNI_OK)
|
||||
return status;
|
||||
|
||||
+ AsyncLogWriter::initialize();
|
||||
interpreter_init(); // before any methods loaded
|
||||
invocationCounter_init(); // before any methods loaded
|
||||
marksweep_init();
|
||||
diff --git a/hotspot/src/share/vm/runtime/logAsyncWriter.cpp b/hotspot/src/share/vm/runtime/logAsyncWriter.cpp
|
||||
new file mode 100644
|
||||
index 0000000..750a23f
|
||||
--- /dev/null
|
||||
+++ b/hotspot/src/share/vm/runtime/logAsyncWriter.cpp
|
||||
@@ -0,0 +1,164 @@
|
||||
+/*
|
||||
+ * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
|
||||
+ * Copyright (c) 2022, Huawei Technologies Co., Ltd. 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
|
||||
+ * under the terms of the GNU General Public License version 2 only, as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
+ * version 2 for more details (a copy is included in the LICENSE file that
|
||||
+ * accompanied this code).
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License version
|
||||
+ * 2 along with this work; if not, write to the Free Software Foundation,
|
||||
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
+ *
|
||||
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
+ * or visit www.oracle.com if you need additional information or have any
|
||||
+ * questions.
|
||||
+ *
|
||||
+ */
|
||||
+#include "precompiled.hpp"
|
||||
+#include "runtime/atomic.hpp"
|
||||
+#include "runtime/logAsyncWriter.hpp"
|
||||
+#include "utilities/ostream.hpp"
|
||||
+
|
||||
+class AsyncLogWriter::AsyncLogLocker : public StackObj {
|
||||
+ public:
|
||||
+ AsyncLogLocker() {
|
||||
+ assert(_instance != NULL, "AsyncLogWriter::_lock is unavailable");
|
||||
+ _instance->_lock.wait();
|
||||
+ }
|
||||
+
|
||||
+ ~AsyncLogLocker() {
|
||||
+ _instance->_lock.signal();
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+void AsyncLogWriter::enqueue_locked(const AsyncLogMessage& msg) {
|
||||
+ if (_buffer.size() >= _buffer_max_size) {
|
||||
+ // drop the enqueueing message.
|
||||
+ os::free(msg.message());
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ assert(_buffer.size() < _buffer_max_size, "_buffer is over-sized.");
|
||||
+ _buffer.push_back(msg);
|
||||
+ _sem.signal();
|
||||
+}
|
||||
+
|
||||
+void AsyncLogWriter::enqueue(const char* msg) {
|
||||
+ AsyncLogMessage m(os::strdup(msg));
|
||||
+
|
||||
+ { // critical area
|
||||
+ AsyncLogLocker locker;
|
||||
+ enqueue_locked(m);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+AsyncLogWriter::AsyncLogWriter()
|
||||
+ : NamedThread(),
|
||||
+ _lock(1), _sem(0), _io_sem(1),
|
||||
+ _initialized(false),
|
||||
+ _buffer_max_size(AsyncLogBufferSize / sizeof(AsyncLogMessage)) {
|
||||
+ if (os::create_thread(this, os::asynclog_thread)) {
|
||||
+ _initialized = true;
|
||||
+ set_name("AsyncLog Thread");
|
||||
+ } else {
|
||||
+ if (PrintAsyncGCLog) {
|
||||
+ tty->print_cr("AsyncLogging failed to create thread. Falling back to synchronous logging.");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (PrintAsyncGCLog) {
|
||||
+ tty->print_cr("The maximum entries of AsyncLogBuffer: " SIZE_FORMAT ", estimated memory use: " SIZE_FORMAT " bytes",
|
||||
+ _buffer_max_size, AsyncLogBufferSize);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void AsyncLogWriter::write() {
|
||||
+ // Use kind of copy-and-swap idiom here.
|
||||
+ // Empty 'logs' swaps the content with _buffer.
|
||||
+ // Along with logs destruction, all processed messages are deleted.
|
||||
+ //
|
||||
+ // The operation 'pop_all()' is done in O(1). All I/O jobs are then performed without
|
||||
+ // lock protection. This guarantees I/O jobs don't block logsites.
|
||||
+ AsyncLogBuffer logs;
|
||||
+ bool own_io = false;
|
||||
+
|
||||
+ { // critical region
|
||||
+ AsyncLogLocker locker;
|
||||
+
|
||||
+ _buffer.pop_all(&logs);
|
||||
+ own_io = _io_sem.trywait();
|
||||
+ }
|
||||
+
|
||||
+ LinkedListIterator<AsyncLogMessage> it(logs.head());
|
||||
+ if (!own_io) {
|
||||
+ _io_sem.wait();
|
||||
+ }
|
||||
+
|
||||
+ bool flush = false;
|
||||
+ while (!it.is_empty()) {
|
||||
+ AsyncLogMessage* e = it.next();
|
||||
+ char* msg = e->message();
|
||||
+
|
||||
+ if (msg != NULL) {
|
||||
+ flush = true;
|
||||
+ ((gcLogFileStream*)gclog_or_tty)->write_blocking(msg, strlen(msg));
|
||||
+ os::free(msg);
|
||||
+ }
|
||||
+ }
|
||||
+ if (flush) {
|
||||
+ ((gcLogFileStream*)gclog_or_tty)->fileStream::flush();
|
||||
+ }
|
||||
+ _io_sem.signal();
|
||||
+}
|
||||
+
|
||||
+void AsyncLogWriter::run() {
|
||||
+ while (true) {
|
||||
+ // The value of a semphore cannot be negative. Therefore, the current thread falls asleep
|
||||
+ // when its value is zero. It will be waken up when new messages are enqueued.
|
||||
+ _sem.wait();
|
||||
+ write();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+AsyncLogWriter* AsyncLogWriter::_instance = NULL;
|
||||
+
|
||||
+void AsyncLogWriter::initialize() {
|
||||
+ if (!UseAsyncGCLog) return;
|
||||
+
|
||||
+ assert(_instance == NULL, "initialize() should only be invoked once.");
|
||||
+
|
||||
+ AsyncLogWriter* self = new AsyncLogWriter();
|
||||
+ if (self->_initialized) {
|
||||
+ OrderAccess::release_store_ptr(&AsyncLogWriter::_instance, self);
|
||||
+ os::start_thread(self);
|
||||
+ if (PrintAsyncGCLog) {
|
||||
+ tty->print_cr("Async logging thread started.");
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+AsyncLogWriter* AsyncLogWriter::instance() {
|
||||
+ return _instance;
|
||||
+}
|
||||
+
|
||||
+// write() acquires and releases _io_sem even _buffer is empty.
|
||||
+// This guarantees all logging I/O of dequeued messages are done when it returns.
|
||||
+void AsyncLogWriter::flush() {
|
||||
+ if (_instance != NULL) {
|
||||
+ _instance->write();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void AsyncLogWriter::print_on(outputStream* st) const{
|
||||
+ st->print("\"%s\" ", name());
|
||||
+ Thread::print_on(st);
|
||||
+ st->cr();
|
||||
+}
|
||||
diff --git a/hotspot/src/share/vm/runtime/logAsyncWriter.hpp b/hotspot/src/share/vm/runtime/logAsyncWriter.hpp
|
||||
new file mode 100644
|
||||
index 0000000..5242426
|
||||
--- /dev/null
|
||||
+++ b/hotspot/src/share/vm/runtime/logAsyncWriter.hpp
|
||||
@@ -0,0 +1,159 @@
|
||||
+/*
|
||||
+ * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
|
||||
+ * Copyright (c) 2022, Huawei Technologies Co., Ltd. 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
|
||||
+ * under the terms of the GNU General Public License version 2 only, as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
+ * version 2 for more details (a copy is included in the LICENSE file that
|
||||
+ * accompanied this code).
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License version
|
||||
+ * 2 along with this work; if not, write to the Free Software Foundation,
|
||||
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
+ *
|
||||
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
+ * or visit www.oracle.com if you need additional information or have any
|
||||
+ * questions.
|
||||
+ *
|
||||
+ */
|
||||
+#ifndef SHARE_VM_RUNTIME_LOGASYNCWRITER_HPP
|
||||
+#define SHARE_VM_RUNTIME_LOGASYNCWRITER_HPP
|
||||
+#include "memory/resourceArea.hpp"
|
||||
+#include "runtime/semaphore.hpp"
|
||||
+#include "utilities/linkedlist.hpp"
|
||||
+
|
||||
+template <typename E, MEMFLAGS F>
|
||||
+class LinkedListDeque : private LinkedListImpl<E, ResourceObj::C_HEAP, F> {
|
||||
+ private:
|
||||
+ LinkedListNode<E>* _tail;
|
||||
+ size_t _size;
|
||||
+
|
||||
+ public:
|
||||
+ LinkedListDeque() : _tail(NULL), _size(0) {}
|
||||
+ void push_back(const E& e) {
|
||||
+ if (!_tail) {
|
||||
+ _tail = this->add(e);
|
||||
+ } else {
|
||||
+ _tail = this->insert_after(e, _tail);
|
||||
+ }
|
||||
+
|
||||
+ ++_size;
|
||||
+ }
|
||||
+
|
||||
+ // pop all elements to logs.
|
||||
+ void pop_all(LinkedList<E>* logs) {
|
||||
+ logs->move(static_cast<LinkedList<E>* >(this));
|
||||
+ _tail = NULL;
|
||||
+ _size = 0;
|
||||
+ }
|
||||
+
|
||||
+ void pop_all(LinkedListDeque<E, F>* logs) {
|
||||
+ logs->_size = _size;
|
||||
+ logs->_tail = _tail;
|
||||
+ pop_all(static_cast<LinkedList<E>* >(logs));
|
||||
+ }
|
||||
+
|
||||
+ void pop_front() {
|
||||
+ LinkedListNode<E>* h = this->unlink_head();
|
||||
+ if (h == _tail) {
|
||||
+ _tail = NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (h != NULL) {
|
||||
+ --_size;
|
||||
+ this->delete_node(h);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ size_t size() const { return _size; }
|
||||
+
|
||||
+ const E* front() const {
|
||||
+ return this->_head == NULL ? NULL : this->_head->peek();
|
||||
+ }
|
||||
+
|
||||
+ const E* back() const {
|
||||
+ return _tail == NULL ? NULL : _tail->peek();
|
||||
+ }
|
||||
+
|
||||
+ LinkedListNode<E>* head() const {
|
||||
+ return this->_head;
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+class AsyncLogMessage {
|
||||
+ char* _message;
|
||||
+
|
||||
+public:
|
||||
+ AsyncLogMessage(char* msg)
|
||||
+ : _message(msg) {}
|
||||
+
|
||||
+ // placeholder for LinkedListImpl.
|
||||
+ bool equals(const AsyncLogMessage& o) const { return false; }
|
||||
+
|
||||
+ char* message() const { return _message; }
|
||||
+};
|
||||
+
|
||||
+typedef LinkedListDeque<AsyncLogMessage, mtInternal> AsyncLogBuffer;
|
||||
+
|
||||
+//
|
||||
+// ASYNC LOGGING SUPPORT
|
||||
+//
|
||||
+// Summary:
|
||||
+// Async Logging is working on the basis of singleton AsyncLogWriter, which manages an intermediate buffer and a flushing thread.
|
||||
+//
|
||||
+// Interface:
|
||||
+//
|
||||
+// initialize() is called once when JVM is initialized. It creates and initializes the singleton instance of AsyncLogWriter.
|
||||
+// Once async logging is established, there's no way to turn it off.
|
||||
+//
|
||||
+// instance() is MT-safe and returns the pointer of the singleton instance if and only if async logging is enabled and has well
|
||||
+// initialized. Clients can use its return value to determine async logging is established or not.
|
||||
+//
|
||||
+// The basic operation of AsyncLogWriter is enqueue(). 2 overloading versions of it are provided to match LogOutput::write().
|
||||
+// They are both MT-safe and non-blocking. Derived classes of LogOutput can invoke the corresponding enqueue() in write() and
|
||||
+// return 0. AsyncLogWriter is responsible of copying neccessary data.
|
||||
+//
|
||||
+// The static member function flush() is designated to flush out all pending messages when JVM is terminating.
|
||||
+// In normal JVM termination, flush() is invoked in LogConfiguration::finalize(). flush() is MT-safe and can be invoked arbitrary
|
||||
+// times. It is no-op if async logging is not established.
|
||||
+//
|
||||
+class AsyncLogWriter : public NamedThread {
|
||||
+ class AsyncLogLocker;
|
||||
+
|
||||
+ static AsyncLogWriter* _instance;
|
||||
+ // _lock(1) denotes a critional region.
|
||||
+ Semaphore _lock;
|
||||
+ // _sem is a semaphore whose value denotes how many messages have been enqueued.
|
||||
+ // It decreases in AsyncLogWriter::run()
|
||||
+ Semaphore _sem;
|
||||
+ // A lock of IO
|
||||
+ Semaphore _io_sem;
|
||||
+
|
||||
+ volatile bool _initialized;
|
||||
+ AsyncLogBuffer _buffer;
|
||||
+
|
||||
+ const size_t _buffer_max_size;
|
||||
+
|
||||
+ AsyncLogWriter();
|
||||
+ void enqueue_locked(const AsyncLogMessage& msg);
|
||||
+ void write();
|
||||
+ void run();
|
||||
+
|
||||
+ public:
|
||||
+ void enqueue(const char* msg);
|
||||
+
|
||||
+ static AsyncLogWriter* instance();
|
||||
+ static void initialize();
|
||||
+ static void flush();
|
||||
+ // Printing
|
||||
+ void print_on(outputStream* st) const;
|
||||
+
|
||||
+};
|
||||
+
|
||||
+#endif // SHARE_LOGGING_LOGASYNCWRITER_HPP
|
||||
diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp
|
||||
index acc57f4..5f41e96 100644
|
||||
--- a/hotspot/src/share/vm/runtime/os.hpp
|
||||
+++ b/hotspot/src/share/vm/runtime/os.hpp
|
||||
@@ -463,6 +463,7 @@ class os: AllStatic {
|
||||
java_thread,
|
||||
compiler_thread,
|
||||
watcher_thread,
|
||||
+ asynclog_thread, // dedicated to flushing logs
|
||||
os_thread
|
||||
};
|
||||
|
||||
diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp
|
||||
index cacab59..61627e4 100644
|
||||
--- a/hotspot/src/share/vm/runtime/thread.cpp
|
||||
+++ b/hotspot/src/share/vm/runtime/thread.cpp
|
||||
@@ -57,6 +57,7 @@
|
||||
#include "runtime/java.hpp"
|
||||
#include "runtime/javaCalls.hpp"
|
||||
#include "runtime/jniPeriodicChecker.hpp"
|
||||
+#include "runtime/logAsyncWriter.hpp"
|
||||
#include "runtime/memprofiler.hpp"
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
#include "runtime/objectMonitor.hpp"
|
||||
@@ -881,7 +882,9 @@ void Thread::print_on_error(outputStream* st, char* buf, int buflen) const {
|
||||
else if (is_GC_task_thread()) st->print("GCTaskThread");
|
||||
else if (is_Watcher_thread()) st->print("WatcherThread");
|
||||
else if (is_ConcurrentGC_thread()) st->print("ConcurrentGCThread");
|
||||
- else st->print("Thread");
|
||||
+ else if (this == AsyncLogWriter::instance()) {
|
||||
+ st->print("%s", this->name());
|
||||
+ } else st->print("Thread");
|
||||
|
||||
st->print(" [stack: " PTR_FORMAT "," PTR_FORMAT "]",
|
||||
_stack_base - _stack_size, _stack_base);
|
||||
@@ -4387,6 +4390,12 @@ void Threads::print_on(outputStream* st, bool print_stacks, bool internal_format
|
||||
st->cr();
|
||||
}
|
||||
CompileBroker::print_compiler_threads_on(st);
|
||||
+ if (UseAsyncGCLog) {
|
||||
+ AsyncLogWriter* aio_writer = AsyncLogWriter::instance();
|
||||
+ if (aio_writer != NULL) {
|
||||
+ aio_writer->print_on(st);
|
||||
+ }
|
||||
+ }
|
||||
st->flush();
|
||||
}
|
||||
|
||||
@@ -4432,6 +4441,21 @@ void Threads::print_on_error(outputStream* st, Thread* current, char* buf, int b
|
||||
wt->print_on_error(st, buf, buflen);
|
||||
st->cr();
|
||||
}
|
||||
+
|
||||
+ if (UseAsyncGCLog) {
|
||||
+ AsyncLogWriter* aio_writer = AsyncLogWriter::instance();
|
||||
+ if (aio_writer != NULL) {
|
||||
+ bool is_current = (current == aio_writer);
|
||||
+ found_current = found_current || is_current;
|
||||
+ st->print("%s", is_current ? "=>" : " ");
|
||||
+
|
||||
+ st->print(PTR_FORMAT, aio_writer);
|
||||
+ st->print(" ");
|
||||
+ aio_writer->print_on_error(st, buf, buflen);
|
||||
+ st->cr();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (!found_current) {
|
||||
st->cr();
|
||||
st->print("=>" PTR_FORMAT " (exited) ", current);
|
||||
diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp
|
||||
index ab20f5c..5d1cf2b 100644
|
||||
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp
|
||||
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp
|
||||
@@ -97,6 +97,7 @@
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/stubRoutines.hpp"
|
||||
#include "runtime/thread.inline.hpp"
|
||||
+#include "runtime/logAsyncWriter.hpp"
|
||||
#include "runtime/virtualspace.hpp"
|
||||
#include "runtime/vmStructs.hpp"
|
||||
#include "utilities/array.hpp"
|
||||
@@ -1599,6 +1600,7 @@ typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
|
||||
declare_type(Thread, ThreadShadow) \
|
||||
declare_type(NamedThread, Thread) \
|
||||
declare_type(WatcherThread, Thread) \
|
||||
+ declare_type(AsyncLogWriter, Thread) \
|
||||
declare_type(JavaThread, Thread) \
|
||||
declare_type(JvmtiAgentThread, JavaThread) \
|
||||
declare_type(ServiceThread, JavaThread) \
|
||||
diff --git a/hotspot/src/share/vm/utilities/linkedlist.hpp b/hotspot/src/share/vm/utilities/linkedlist.hpp
|
||||
index a76c15c..f4f2a9b 100644
|
||||
--- a/hotspot/src/share/vm/utilities/linkedlist.hpp
|
||||
+++ b/hotspot/src/share/vm/utilities/linkedlist.hpp
|
||||
@@ -40,6 +40,25 @@ template <class E> class LinkedListNode : public ResourceObj {
|
||||
E _data; // embedded content
|
||||
LinkedListNode<E>* _next; // next entry
|
||||
|
||||
+ // Select member function 'bool U::equals(const U&) const' if 'U' is of class
|
||||
+ // type. This works because of the "Substitution Failure Is Not An Error"
|
||||
+ // (SFINAE) rule. Notice that this version of 'equal' will also be chosen for
|
||||
+ // class types which don't define a corresponding 'equals()' method (and will
|
||||
+ // result in a compilation error for them). It is not easily possible to
|
||||
+ // specialize this 'equal()' function exclusively for class types which define
|
||||
+ // the correct 'equals()' function because that function can be in a base
|
||||
+ // class, a dependent base class or have a compatible but slightly different
|
||||
+ // signature.
|
||||
+ template <class U>
|
||||
+ static bool equal(const U& a, const U& b, bool (U::*t)(const U&) const) {
|
||||
+ return a.equals(b);
|
||||
+ }
|
||||
+
|
||||
+ template <class U>
|
||||
+ static bool equal(const U& a, const U& b, ...) {
|
||||
+ return a == b;
|
||||
+ }
|
||||
+
|
||||
protected:
|
||||
LinkedListNode() : _next(NULL) { }
|
||||
|
||||
@@ -51,6 +70,10 @@ template <class E> class LinkedListNode : public ResourceObj {
|
||||
|
||||
E* data() { return &_data; }
|
||||
const E* peek() const { return &_data; }
|
||||
+
|
||||
+ bool equals(const E& t) const {
|
||||
+ return equal<E>(_data, t, NULL);
|
||||
+ }
|
||||
};
|
||||
|
||||
// A linked list interface. It does not specify
|
||||
@@ -62,6 +85,7 @@ template <class E> class LinkedList : public ResourceObj {
|
||||
|
||||
public:
|
||||
LinkedList() : _head(NULL) { }
|
||||
+ virtual ~LinkedList() {}
|
||||
|
||||
inline void set_head(LinkedListNode<E>* h) { _head = h; }
|
||||
inline LinkedListNode<E>* head() const { return _head; }
|
||||
@@ -182,7 +206,7 @@ template <class E, ResourceObj::allocation_type T = ResourceObj::C_HEAP,
|
||||
|
||||
virtual LinkedListNode<E>* find_node(const E& e) {
|
||||
LinkedListNode<E>* p = this->head();
|
||||
- while (p != NULL && !p->peek()->equals(e)) {
|
||||
+ while (p != NULL && !p->equals(e)) {
|
||||
p = p->next();
|
||||
}
|
||||
return p;
|
||||
@@ -229,7 +253,7 @@ template <class E, ResourceObj::allocation_type T = ResourceObj::C_HEAP,
|
||||
LinkedListNode<E>* prev = NULL;
|
||||
|
||||
while (tmp != NULL) {
|
||||
- if (tmp->peek()->equals(e)) {
|
||||
+ if (tmp->equals(e)) {
|
||||
return remove_after(prev);
|
||||
}
|
||||
prev = tmp;
|
||||
@@ -396,16 +420,21 @@ template <class E, int (*FUNC)(const E&, const E&),
|
||||
// Iterates all entries in the list
|
||||
template <class E> class LinkedListIterator : public StackObj {
|
||||
private:
|
||||
- LinkedListNode<E>* _p;
|
||||
- bool _is_empty;
|
||||
+ mutable LinkedListNode<E>* _p;
|
||||
+
|
||||
public:
|
||||
- LinkedListIterator(LinkedListNode<E>* head) : _p(head) {
|
||||
- _is_empty = (head == NULL);
|
||||
- }
|
||||
+ LinkedListIterator(LinkedListNode<E>* head) : _p(head) { }
|
||||
+
|
||||
+ bool is_empty() const { return _p == NULL; }
|
||||
|
||||
- bool is_empty() const { return _is_empty; }
|
||||
+ E* next() {
|
||||
+ if (_p == NULL) return NULL;
|
||||
+ E* e = _p->data();
|
||||
+ _p = _p->next();
|
||||
+ return e;
|
||||
+ }
|
||||
|
||||
- const E* next() {
|
||||
+ const E* next() const {
|
||||
if (_p == NULL) return NULL;
|
||||
const E* e = _p->peek();
|
||||
_p = _p->next();
|
||||
diff --git a/hotspot/src/share/vm/utilities/ostream.cpp b/hotspot/src/share/vm/utilities/ostream.cpp
|
||||
index 14d82ad..5d40559 100644
|
||||
--- a/hotspot/src/share/vm/utilities/ostream.cpp
|
||||
+++ b/hotspot/src/share/vm/utilities/ostream.cpp
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/vmThread.hpp"
|
||||
+#include "runtime/logAsyncWriter.hpp"
|
||||
#include "utilities/defaultStream.hpp"
|
||||
#include "utilities/ostream.hpp"
|
||||
#include "utilities/top.hpp"
|
||||
@@ -876,6 +877,17 @@ gcLogFileStream::gcLogFileStream(const char* file_name) : _file_lock(NULL) {
|
||||
}
|
||||
|
||||
void gcLogFileStream::write(const char* s, size_t len) {
|
||||
+ if (UseAsyncGCLog) {
|
||||
+ AsyncLogWriter* aio_writer = AsyncLogWriter::instance();
|
||||
+ if (aio_writer != NULL) {
|
||||
+ aio_writer->enqueue(s);
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ write_blocking(s, len);
|
||||
+}
|
||||
+
|
||||
+void gcLogFileStream::write_blocking(const char* s, size_t len) {
|
||||
if (_file != NULL) {
|
||||
// we can't use Thread::current() here because thread may be NULL
|
||||
// in early stage(ostream_init_log)
|
||||
@@ -1047,6 +1059,17 @@ void gcLogFileStream::rotate_log_impl(bool force, outputStream* out) {
|
||||
}
|
||||
}
|
||||
|
||||
+void gcLogFileStream::flush() {
|
||||
+ if (UseAsyncGCLog) {
|
||||
+ AsyncLogWriter* aio_writer = AsyncLogWriter::instance();
|
||||
+ if (aio_writer != NULL) {
|
||||
+ // do nothing
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ fileStream::flush();
|
||||
+}
|
||||
+
|
||||
defaultStream* defaultStream::instance = NULL;
|
||||
int defaultStream::_output_fd = 1;
|
||||
int defaultStream::_error_fd = 2;
|
||||
@@ -1456,6 +1479,9 @@ void ostream_exit() {
|
||||
|
||||
// ostream_abort() is called by os::abort() when VM is about to die.
|
||||
void ostream_abort() {
|
||||
+ if (UseAsyncGCLog) {
|
||||
+ AsyncLogWriter::flush();
|
||||
+ }
|
||||
// Here we can't delete gclog_or_tty and tty, just flush their output
|
||||
if (gclog_or_tty) gclog_or_tty->flush();
|
||||
if (tty) tty->flush();
|
||||
diff --git a/hotspot/src/share/vm/utilities/ostream.hpp b/hotspot/src/share/vm/utilities/ostream.hpp
|
||||
index d0f9aac..85ff599 100644
|
||||
--- a/hotspot/src/share/vm/utilities/ostream.hpp
|
||||
+++ b/hotspot/src/share/vm/utilities/ostream.hpp
|
||||
@@ -254,6 +254,7 @@ class gcLogFileStream : public fileStream {
|
||||
gcLogFileStream(const char* file_name);
|
||||
~gcLogFileStream();
|
||||
virtual void write(const char* c, size_t len);
|
||||
+ void write_blocking(const char* c, size_t len);
|
||||
virtual void rotate_log(bool force, outputStream* out = NULL);
|
||||
void dump_loggc_header();
|
||||
|
||||
@@ -263,6 +264,8 @@ class gcLogFileStream : public fileStream {
|
||||
((GCLogFileSize != 0) && ((uintx)_bytes_written >= GCLogFileSize));
|
||||
}
|
||||
|
||||
+ virtual void flush();
|
||||
+
|
||||
};
|
||||
|
||||
#ifndef PRODUCT
|
||||
--
|
||||
1.8.3.1
|
||||
594
8232069-enable-shutdown-UseCompressedClassPointers-U.patch
Normal file
594
8232069-enable-shutdown-UseCompressedClassPointers-U.patch
Normal file
@ -0,0 +1,594 @@
|
||||
From bf7e5b40eab65acf8988a30c1530654db1f8cf07 Mon Sep 17 00:00:00 2001
|
||||
From: eapen <zhangyipeng7@huawei.com>
|
||||
Date: Fri, 30 Sep 2022 17:18:50 +0800
|
||||
Subject: [PATCH 27/33] I68TO2: 8232069: enable shutdown UseCompressedClassPointers &&
|
||||
UseCompressedOops when CDS
|
||||
---
|
||||
common/bin/compare.sh | 2 +-
|
||||
hotspot/src/share/vm/memory/filemap.cpp | 12 ++
|
||||
hotspot/src/share/vm/memory/filemap.hpp | 4 +
|
||||
hotspot/src/share/vm/memory/metaspace.cpp | 42 +++--
|
||||
hotspot/src/share/vm/runtime/arguments.cpp | 47 ++---
|
||||
hotspot/src/share/vm/runtime/arguments.hpp | 2 +-
|
||||
.../CDSCompressedKPtrsError.java | 93 ----------
|
||||
.../appcds/CommandLineFlagComboNegative.java | 5 +-
|
||||
.../appcds/TestCombinedCompressedFlags.java | 192 +++++++++++++++++++++
|
||||
jdk/make/BuildJdk.gmk | 2 +
|
||||
10 files changed, 253 insertions(+), 148 deletions(-)
|
||||
delete mode 100644 hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrsError.java
|
||||
create mode 100644 hotspot/test/runtime/appcds/TestCombinedCompressedFlags.java
|
||||
|
||||
diff --git a/common/bin/compare.sh b/common/bin/compare.sh
|
||||
index a36464a..e6a3f67 100644
|
||||
--- a/common/bin/compare.sh
|
||||
+++ b/common/bin/compare.sh
|
||||
@@ -290,7 +290,7 @@ compare_general_files() {
|
||||
! -name "ct.sym" ! -name "*.diz" ! -name "*.dll" \
|
||||
! -name "*.pdb" ! -name "*.exp" ! -name "*.ilk" \
|
||||
! -name "*.lib" ! -name "*.war" ! -name "JavaControlPanel" \
|
||||
- ! -name "classes.jsa" \
|
||||
+ ! -name "classes.jsa" | -name "classes_nocoops.jsa" \
|
||||
| $GREP -v "./bin/" | $SORT | $FILTER)
|
||||
|
||||
echo General files...
|
||||
diff --git a/hotspot/src/share/vm/memory/filemap.cpp b/hotspot/src/share/vm/memory/filemap.cpp
|
||||
index 0682cd6..0d21707 100644
|
||||
--- a/hotspot/src/share/vm/memory/filemap.cpp
|
||||
+++ b/hotspot/src/share/vm/memory/filemap.cpp
|
||||
@@ -241,6 +241,8 @@ void FileMapInfo::FileMapHeader::populate(FileMapInfo* mapinfo, size_t alignment
|
||||
_alignment = alignment;
|
||||
_obj_alignment = ObjectAlignmentInBytes;
|
||||
|
||||
+ _compressed_oops = UseCompressedOops;
|
||||
+ _compressed_class_ptrs = UseCompressedClassPointers;
|
||||
if (!DynamicDumpSharedSpaces) {
|
||||
_classpath_entry_table_size = mapinfo->_classpath_entry_table_size;
|
||||
_classpath_entry_table = mapinfo->_classpath_entry_table;
|
||||
@@ -987,6 +989,16 @@ bool FileMapInfo::FileMapHeader::validate() {
|
||||
_obj_alignment, ObjectAlignmentInBytes);
|
||||
return false;
|
||||
}
|
||||
+ if (PrintSharedSpaces) {
|
||||
+ tty->print_cr("Archive was created with UseCompressedOops = %d, UseCompressedClassPointers = %d",
|
||||
+ compressed_oops(), compressed_class_pointers());
|
||||
+ }
|
||||
+
|
||||
+ if (compressed_oops() != UseCompressedOops || compressed_class_pointers() != UseCompressedClassPointers) {
|
||||
+ FileMapInfo::fail_continue("Unable to use shared archive.\nThe saved state of UseCompressedOops and UseCompressedClassPointers is "
|
||||
+ "different from runtime, CDS will be disabled.");
|
||||
+ return false;
|
||||
+ }
|
||||
|
||||
return true;
|
||||
}
|
||||
diff --git a/hotspot/src/share/vm/memory/filemap.hpp b/hotspot/src/share/vm/memory/filemap.hpp
|
||||
index 27fff35..debfb50 100644
|
||||
--- a/hotspot/src/share/vm/memory/filemap.hpp
|
||||
+++ b/hotspot/src/share/vm/memory/filemap.hpp
|
||||
@@ -105,6 +105,8 @@ public:
|
||||
size_t _alignment; // how shared archive should be aligned
|
||||
int _obj_alignment; // value of ObjectAlignmentInBytes
|
||||
bool _is_default_jsa; // indicates whether is the default jsa file
|
||||
+ bool _compressed_oops; // save the flag UseCompressedOops
|
||||
+ bool _compressed_class_ptrs; // save the flag UseCompressedClassPointers
|
||||
|
||||
struct space_info {
|
||||
int _crc; // crc checksum of the current space
|
||||
@@ -156,6 +158,8 @@ public:
|
||||
int compute_crc();
|
||||
unsigned int magic() const { return _magic; }
|
||||
const char* jvm_ident() const { return _jvm_ident; }
|
||||
+ bool compressed_oops() const { return _compressed_oops; }
|
||||
+ bool compressed_class_pointers() const { return _compressed_class_ptrs; }
|
||||
};
|
||||
|
||||
// Fixme
|
||||
diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp
|
||||
index cf4a112..07bc47a 100644
|
||||
--- a/hotspot/src/share/vm/memory/metaspace.cpp
|
||||
+++ b/hotspot/src/share/vm/memory/metaspace.cpp
|
||||
@@ -3634,25 +3634,33 @@ void Metaspace::global_initialize() {
|
||||
}
|
||||
|
||||
#ifdef _LP64
|
||||
- if (cds_total + compressed_class_space_size() > UnscaledClassSpaceMax) {
|
||||
- vm_exit_during_initialization("Unable to dump shared archive.",
|
||||
- err_msg("Size of archive (" SIZE_FORMAT ") + compressed class space ("
|
||||
- SIZE_FORMAT ") == total (" SIZE_FORMAT ") is larger than compressed "
|
||||
- "klass limit: " SIZE_FORMAT, cds_total, compressed_class_space_size(),
|
||||
- cds_total + compressed_class_space_size(), UnscaledClassSpaceMax));
|
||||
- }
|
||||
+ if (UseCompressedClassPointers) {
|
||||
+ if (cds_total + compressed_class_space_size() > UnscaledClassSpaceMax) {
|
||||
+ vm_exit_during_initialization("Unable to dump shared archive.",
|
||||
+ err_msg("Size of archive (" SIZE_FORMAT ") + compressed class space ("
|
||||
+ SIZE_FORMAT ") == total (" SIZE_FORMAT ") is larger than compressed "
|
||||
+ "klass limit: " SIZE_FORMAT, cds_total, compressed_class_space_size(),
|
||||
+ cds_total + compressed_class_space_size(), UnscaledClassSpaceMax));
|
||||
+ }
|
||||
|
||||
- // Set the compressed klass pointer base so that decoding of these pointers works
|
||||
- // properly when creating the shared archive.
|
||||
- assert(UseCompressedOops && UseCompressedClassPointers,
|
||||
- "UseCompressedOops and UseCompressedClassPointers must be set");
|
||||
- Universe::set_narrow_klass_base((address)_space_list->current_virtual_space()->bottom());
|
||||
- if (TraceMetavirtualspaceAllocation && Verbose) {
|
||||
- gclog_or_tty->print_cr("Setting_narrow_klass_base to Address: " PTR_FORMAT,
|
||||
- _space_list->current_virtual_space()->bottom());
|
||||
- }
|
||||
+ // Set the compressed klass pointer base so that decoding of these pointers works
|
||||
+ // properly when creating the shared archive.
|
||||
+ assert(UseCompressedOops && UseCompressedClassPointers,
|
||||
+ "UseCompressedOops and UseCompressedClassPointers must be set");
|
||||
+ Universe::set_narrow_klass_base((address)_space_list->current_virtual_space()->bottom());
|
||||
+ if (TraceMetavirtualspaceAllocation && Verbose) {
|
||||
+ gclog_or_tty->print_cr("Setting_narrow_klass_base to Address: " PTR_FORMAT,
|
||||
+ _space_list->current_virtual_space()->bottom());
|
||||
+ }
|
||||
|
||||
- Universe::set_narrow_klass_shift(0);
|
||||
+ Universe::set_narrow_klass_shift(0);
|
||||
+ } else {
|
||||
+ if (cds_total > UnscaledClassSpaceMax) {
|
||||
+ vm_exit_during_initialization("Unable to dump shared archive.",
|
||||
+ err_msg("Size of archive (" SIZE_FORMAT ") is larger than compressed "
|
||||
+ "klass limit: " SIZE_FORMAT, cds_total, UnscaledClassSpaceMax));
|
||||
+ }
|
||||
+ }
|
||||
#endif // _LP64
|
||||
#endif // INCLUDE_CDS
|
||||
} else {
|
||||
diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp
|
||||
index fba3d4b..b0b5414 100644
|
||||
--- a/hotspot/src/share/vm/runtime/arguments.cpp
|
||||
+++ b/hotspot/src/share/vm/runtime/arguments.cpp
|
||||
@@ -242,7 +242,9 @@ bool Arguments::init_shared_archive_paths() {
|
||||
}
|
||||
}
|
||||
|
||||
- if (SharedArchiveFile != NULL) {
|
||||
+ if (SharedArchiveFile == NULL) {
|
||||
+ SharedArchivePath = get_default_shared_archive_path();
|
||||
+ } else {
|
||||
int archives = num_archives(SharedArchiveFile);
|
||||
if (is_dumping_archive()) {
|
||||
if (archives > 1) {
|
||||
@@ -4008,7 +4010,7 @@ jint Arguments::parse_options_environment_variable(const char* name, SysClassPat
|
||||
return JNI_OK;
|
||||
}
|
||||
|
||||
-void Arguments::set_shared_spaces_flags() {
|
||||
+jint Arguments::set_shared_spaces_flags() {
|
||||
if (DumpSharedSpaces) {
|
||||
if (FailOverToOldVerifier) {
|
||||
// Don't fall back to the old verifier on verification failure. If a
|
||||
@@ -4022,22 +4024,16 @@ void Arguments::set_shared_spaces_flags() {
|
||||
warning("cannot dump shared archive while using shared archive");
|
||||
}
|
||||
UseSharedSpaces = false;
|
||||
-#ifdef _LP64
|
||||
- if (!UseCompressedOops || !UseCompressedClassPointers) {
|
||||
- vm_exit_during_initialization(
|
||||
- "Cannot dump shared archive when UseCompressedOops or UseCompressedClassPointers is off.", NULL);
|
||||
- }
|
||||
- } else {
|
||||
- if (!UseCompressedOops || !UseCompressedClassPointers) {
|
||||
- no_shared_spaces("UseCompressedOops and UseCompressedClassPointers must be on for UseSharedSpaces.");
|
||||
- }
|
||||
-#endif
|
||||
}
|
||||
|
||||
#if INCLUDE_CDS
|
||||
// Initialize shared archive paths which could include both base and dynamic archive paths
|
||||
- init_shared_archive_paths();
|
||||
+ // This must be after set_ergonomics_flags() called so flag UseCompressedOops is set properly.
|
||||
+ if(!init_shared_archive_paths()) {
|
||||
+ return JNI_ENOMEM;
|
||||
+ }
|
||||
#endif // INCLUDE_CDS
|
||||
+ return JNI_OK;
|
||||
}
|
||||
|
||||
#if !INCLUDE_ALL_GCS
|
||||
@@ -4065,25 +4061,14 @@ char* Arguments::get_default_shared_archive_path() {
|
||||
const size_t len = jvm_path_len + file_sep_len + 20;
|
||||
default_archive_path = NEW_C_HEAP_ARRAY(char, len, mtInternal);
|
||||
if (default_archive_path != NULL) {
|
||||
- jio_snprintf(default_archive_path, len, "%s%sclasses.jsa",
|
||||
+ jio_snprintf(default_archive_path, len,
|
||||
+ UseCompressedClassPointers ? "%s%sclasses.jsa" : "%s%sclasses_nocoops.jsa",
|
||||
jvm_path, os::file_separator());
|
||||
}
|
||||
Arguments::set_is_default_jsa(true);
|
||||
return default_archive_path;
|
||||
}
|
||||
|
||||
-// Sharing support
|
||||
-// Construct the path to the archive
|
||||
-static char* get_shared_archive_path() {
|
||||
- char *shared_archive_path;
|
||||
- if (SharedArchiveFile == NULL) {
|
||||
- shared_archive_path = Arguments::get_default_shared_archive_path();
|
||||
- } else {
|
||||
- shared_archive_path = os::strdup(SharedArchiveFile, mtInternal);
|
||||
- }
|
||||
- return shared_archive_path;
|
||||
-}
|
||||
-
|
||||
|
||||
#ifndef PRODUCT
|
||||
// Determine whether LogVMOutput should be implicitly turned on.
|
||||
@@ -4221,13 +4206,6 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
|
||||
return result;
|
||||
}
|
||||
|
||||
- // Call get_shared_archive_path() here, after possible SharedArchiveFile option got parsed.
|
||||
- SharedArchivePath = get_shared_archive_path();
|
||||
- if (SharedArchivePath == NULL) {
|
||||
- return JNI_ENOMEM;
|
||||
- }
|
||||
-
|
||||
-
|
||||
// Set up VerifySharedSpaces
|
||||
if (FLAG_IS_DEFAULT(VerifySharedSpaces) && SharedArchiveFile != NULL) {
|
||||
VerifySharedSpaces = true;
|
||||
@@ -4321,7 +4299,8 @@ jint Arguments::apply_ergo() {
|
||||
// Set flags based on ergonomics.
|
||||
set_ergonomics_flags();
|
||||
|
||||
- set_shared_spaces_flags();
|
||||
+ jint result = set_shared_spaces_flags();
|
||||
+ if (result != JNI_OK) return result;
|
||||
|
||||
#if defined(SPARC)
|
||||
// BIS instructions require 'membar' instruction regardless of the number
|
||||
diff --git a/hotspot/src/share/vm/runtime/arguments.hpp b/hotspot/src/share/vm/runtime/arguments.hpp
|
||||
index 65907eb..88741e8 100644
|
||||
--- a/hotspot/src/share/vm/runtime/arguments.hpp
|
||||
+++ b/hotspot/src/share/vm/runtime/arguments.hpp
|
||||
@@ -343,7 +343,7 @@ class Arguments : AllStatic {
|
||||
static void set_use_compressed_klass_ptrs();
|
||||
static void select_gc();
|
||||
static void set_ergonomics_flags();
|
||||
- static void set_shared_spaces_flags();
|
||||
+ static jint set_shared_spaces_flags();
|
||||
// limits the given memory size by the maximum amount of memory this process is
|
||||
// currently allowed to allocate or reserve.
|
||||
static julong limit_by_allocatable_memory(julong size);
|
||||
diff --git a/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrsError.java b/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrsError.java
|
||||
deleted file mode 100644
|
||||
index 05b4ac9..0000000
|
||||
--- a/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrsError.java
|
||||
+++ /dev/null
|
||||
@@ -1,93 +0,0 @@
|
||||
-/*
|
||||
- * Copyright (c) 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
|
||||
- * under the terms of the GNU General Public License version 2 only, as
|
||||
- * published by the Free Software Foundation.
|
||||
- *
|
||||
- * This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
- * version 2 for more details (a copy is included in the LICENSE file that
|
||||
- * accompanied this code).
|
||||
- *
|
||||
- * You should have received a copy of the GNU General Public License version
|
||||
- * 2 along with this work; if not, write to the Free Software Foundation,
|
||||
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
- *
|
||||
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
- * or visit www.oracle.com if you need additional information or have any
|
||||
- * questions.
|
||||
- */
|
||||
-
|
||||
-/*
|
||||
- * @test
|
||||
- * @bug 8003424
|
||||
- * @summary Test that cannot use CDS if UseCompressedClassPointers is turned off.
|
||||
- * @library /testlibrary
|
||||
- * @run main CDSCompressedKPtrsError
|
||||
- */
|
||||
-
|
||||
-import com.oracle.java.testlibrary.*;
|
||||
-
|
||||
-public class CDSCompressedKPtrsError {
|
||||
- public static void main(String[] args) throws Exception {
|
||||
- ProcessBuilder pb;
|
||||
- if (Platform.is64bit()) {
|
||||
- pb = ProcessTools.createJavaProcessBuilder(
|
||||
- "-XX:+UseCompressedOops", "-XX:+UseCompressedClassPointers", "-XX:+UnlockDiagnosticVMOptions",
|
||||
- "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
|
||||
- OutputAnalyzer output = new OutputAnalyzer(pb.start());
|
||||
- try {
|
||||
- output.shouldContain("Loading classes to share");
|
||||
- output.shouldHaveExitValue(0);
|
||||
-
|
||||
- pb = ProcessTools.createJavaProcessBuilder(
|
||||
- "-XX:-UseCompressedClassPointers", "-XX:-UseCompressedOops",
|
||||
- "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version");
|
||||
- output = new OutputAnalyzer(pb.start());
|
||||
- output.shouldContain("Unable to use shared archive");
|
||||
- output.shouldHaveExitValue(0);
|
||||
-
|
||||
- pb = ProcessTools.createJavaProcessBuilder(
|
||||
- "-XX:-UseCompressedClassPointers", "-XX:+UseCompressedOops",
|
||||
- "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version");
|
||||
- output = new OutputAnalyzer(pb.start());
|
||||
- output.shouldContain("Unable to use shared archive");
|
||||
- output.shouldHaveExitValue(0);
|
||||
-
|
||||
- pb = ProcessTools.createJavaProcessBuilder(
|
||||
- "-XX:+UseCompressedClassPointers", "-XX:-UseCompressedOops",
|
||||
- "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version");
|
||||
- output = new OutputAnalyzer(pb.start());
|
||||
- output.shouldContain("Unable to use shared archive");
|
||||
- output.shouldHaveExitValue(0);
|
||||
-
|
||||
- } catch (RuntimeException e) {
|
||||
- output.shouldContain("Unable to use shared archive");
|
||||
- output.shouldHaveExitValue(1);
|
||||
- }
|
||||
-
|
||||
- // Test bad options with -Xshare:dump.
|
||||
- pb = ProcessTools.createJavaProcessBuilder(
|
||||
- "-XX:-UseCompressedOops", "-XX:+UseCompressedClassPointers", "-XX:+UnlockDiagnosticVMOptions",
|
||||
- "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
|
||||
- output = new OutputAnalyzer(pb.start());
|
||||
- output.shouldContain("Cannot dump shared archive");
|
||||
-
|
||||
- pb = ProcessTools.createJavaProcessBuilder(
|
||||
- "-XX:+UseCompressedOops", "-XX:-UseCompressedClassPointers", "-XX:+UnlockDiagnosticVMOptions",
|
||||
- "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
|
||||
- output = new OutputAnalyzer(pb.start());
|
||||
- output.shouldContain("Cannot dump shared archive");
|
||||
-
|
||||
- pb = ProcessTools.createJavaProcessBuilder(
|
||||
- "-XX:-UseCompressedOops", "-XX:-UseCompressedClassPointers", "-XX:+UnlockDiagnosticVMOptions",
|
||||
- "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
|
||||
- output = new OutputAnalyzer(pb.start());
|
||||
- output.shouldContain("Cannot dump shared archive");
|
||||
-
|
||||
- }
|
||||
- }
|
||||
-}
|
||||
diff --git a/hotspot/test/runtime/appcds/CommandLineFlagComboNegative.java b/hotspot/test/runtime/appcds/CommandLineFlagComboNegative.java
|
||||
index 4fb965a..286893e 100644
|
||||
--- a/hotspot/test/runtime/appcds/CommandLineFlagComboNegative.java
|
||||
+++ b/hotspot/test/runtime/appcds/CommandLineFlagComboNegative.java
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
+ * Copyright (c) 2022, Huawei Technologies Co., Ltd. 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
|
||||
@@ -64,9 +65,9 @@ public class CommandLineFlagComboNegative {
|
||||
testTable.add( new TestVector("-XX:ObjectAlignmentInBytes=64", "-XX:ObjectAlignmentInBytes=32",
|
||||
"An error has occurred while processing the shared archive file", 1) );
|
||||
testTable.add( new TestVector("-XX:+UseCompressedOops", "-XX:-UseCompressedOops",
|
||||
- "Class data sharing is inconsistent with other specified options", 1) );
|
||||
+ "The saved state of UseCompressedOops and UseCompressedClassPointers is different from runtime, CDS will be disabled", 1) );
|
||||
testTable.add( new TestVector("-XX:+UseCompressedClassPointers", "-XX:-UseCompressedClassPointers",
|
||||
- "Class data sharing is inconsistent with other specified options", 1) );
|
||||
+ "The saved state of UseCompressedOops and UseCompressedClassPointers is different from runtime, CDS will be disabled", 1) );
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/hotspot/test/runtime/appcds/TestCombinedCompressedFlags.java b/hotspot/test/runtime/appcds/TestCombinedCompressedFlags.java
|
||||
new file mode 100644
|
||||
index 0000000..6f0a3be
|
||||
--- /dev/null
|
||||
+++ b/hotspot/test/runtime/appcds/TestCombinedCompressedFlags.java
|
||||
@@ -0,0 +1,192 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
+ * Copyright (c) 2022, Huawei Technologies Co., Ltd. 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
|
||||
+ * under the terms of the GNU General Public License version 2 only, as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
+ * version 2 for more details (a copy is included in the LICENSE file that
|
||||
+ * accompanied this code).
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License version
|
||||
+ * 2 along with this work; if not, write to the Free Software Foundation,
|
||||
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
+ *
|
||||
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
+ * or visit www.oracle.com if you need additional information or have any
|
||||
+ * questions.
|
||||
+ */
|
||||
+
|
||||
+/**
|
||||
+ * @test
|
||||
+ * @bug 8232069
|
||||
+ * @summary Testing different combination of CompressedOops and CompressedClassPointers
|
||||
+ * @requires (vm.gc=="null")
|
||||
+ * @library /testlibrary
|
||||
+ * @compile test-classes/Hello.java
|
||||
+ * @run main/othervm TestCombinedCompressedFlags
|
||||
+ */
|
||||
+
|
||||
+import com.oracle.java.testlibrary.Platform;
|
||||
+import com.oracle.java.testlibrary.OutputAnalyzer;
|
||||
+import java.util.List;
|
||||
+import java.util.ArrayList;
|
||||
+
|
||||
+public class TestCombinedCompressedFlags {
|
||||
+ public static String HELLO_STRING = "Hello World";
|
||||
+ public static String EXEC_ABNORMAL_MSG = "Unable to use shared archive.";
|
||||
+ public static final int PASS = 0;
|
||||
+ public static final int FAIL = 1;
|
||||
+
|
||||
+ static class ConfArg {
|
||||
+ public boolean useCompressedOops; // UseCompressedOops
|
||||
+ public boolean useCompressedClassPointers; // UseCompressedClassPointers
|
||||
+ public String msg;
|
||||
+ public int code;
|
||||
+ public ConfArg(boolean useCompressedOops, boolean useCompressedClassPointers, String msg, int code) {
|
||||
+ this.useCompressedOops = useCompressedOops;
|
||||
+ this.useCompressedClassPointers = useCompressedClassPointers;
|
||||
+ this.msg = msg;
|
||||
+ this.code = code;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ static class RunArg {
|
||||
+ public ConfArg dumpArg;
|
||||
+ public List<ConfArg> execArgs;
|
||||
+ public RunArg(ConfArg arg) {
|
||||
+ dumpArg = arg;
|
||||
+ initExecArgs();
|
||||
+ }
|
||||
+ private void initExecArgs() {
|
||||
+ /* The combinations have four cases. Note COOP off, CCPTR must be off
|
||||
+ * UseCompressedOops UseCompressedClassPointers Result
|
||||
+ * 1.
|
||||
+ * dump: on on
|
||||
+ * test: on on Pass
|
||||
+ * on off Fail
|
||||
+ * off on Fail
|
||||
+ * off off Fail
|
||||
+ * 2.
|
||||
+ * dump: on off
|
||||
+ * test: on off Pass
|
||||
+ * on on Fail
|
||||
+ * off on Pass
|
||||
+ * off off Fail
|
||||
+ * 3.
|
||||
+ * dump: off on
|
||||
+ * test: off on Pass
|
||||
+ * off off Pass
|
||||
+ * on on Fail
|
||||
+ * on off Fail
|
||||
+ * 4.
|
||||
+ * dump: off off
|
||||
+ * test: off off Pass
|
||||
+ * off on Pass
|
||||
+ * on on Fail
|
||||
+ * on off Fail
|
||||
+ **/
|
||||
+ execArgs = new ArrayList<ConfArg>();
|
||||
+ if (dumpArg.useCompressedOops && dumpArg.useCompressedClassPointers) {
|
||||
+ execArgs
|
||||
+ .add(new ConfArg(true, true, HELLO_STRING, PASS));
|
||||
+ execArgs
|
||||
+ .add(new ConfArg(true, false, EXEC_ABNORMAL_MSG, FAIL));
|
||||
+ execArgs
|
||||
+ .add(new ConfArg(false, true, EXEC_ABNORMAL_MSG, FAIL));
|
||||
+ execArgs
|
||||
+ .add(new ConfArg(false, false, EXEC_ABNORMAL_MSG, FAIL));
|
||||
+
|
||||
+ } else if(dumpArg.useCompressedOops && !dumpArg.useCompressedClassPointers) {
|
||||
+ execArgs
|
||||
+ .add(new ConfArg(true, false, HELLO_STRING, PASS));
|
||||
+ execArgs
|
||||
+ .add(new ConfArg(true, true, EXEC_ABNORMAL_MSG, FAIL));
|
||||
+ execArgs
|
||||
+ .add(new ConfArg(false, true, EXEC_ABNORMAL_MSG, FAIL));
|
||||
+ execArgs
|
||||
+ .add(new ConfArg(false, false, EXEC_ABNORMAL_MSG, FAIL));
|
||||
+
|
||||
+ } else if (!dumpArg.useCompressedOops && dumpArg.useCompressedClassPointers) {
|
||||
+ execArgs
|
||||
+ .add(new ConfArg(false, false, HELLO_STRING, PASS));
|
||||
+ execArgs
|
||||
+ .add(new ConfArg(false, true, HELLO_STRING, PASS));
|
||||
+ execArgs
|
||||
+ .add(new ConfArg(true, true, EXEC_ABNORMAL_MSG, FAIL));
|
||||
+ execArgs
|
||||
+ .add(new ConfArg(true, false, EXEC_ABNORMAL_MSG, FAIL));
|
||||
+ } else if (!dumpArg.useCompressedOops && !dumpArg.useCompressedClassPointers) {
|
||||
+ execArgs
|
||||
+ .add(new ConfArg(false, false, HELLO_STRING, PASS));
|
||||
+ execArgs
|
||||
+ .add(new ConfArg(false, true, HELLO_STRING, PASS));
|
||||
+ execArgs
|
||||
+ .add(new ConfArg(true, true, EXEC_ABNORMAL_MSG, FAIL));
|
||||
+ execArgs
|
||||
+ .add(new ConfArg(true, false, EXEC_ABNORMAL_MSG, FAIL));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public static String getCompressedOopsArg(boolean on) {
|
||||
+ if (on) return "-XX:+UseCompressedOops";
|
||||
+ else return "-XX:-UseCompressedOops";
|
||||
+ }
|
||||
+
|
||||
+ public static String getCompressedClassPointersArg(boolean on) {
|
||||
+ if (on) return "-XX:+UseCompressedClassPointers";
|
||||
+ else return "-XX:-UseCompressedClassPointers";
|
||||
+ }
|
||||
+
|
||||
+ public static List<RunArg> runList;
|
||||
+
|
||||
+ public static void configureRunArgs() {
|
||||
+ runList = new ArrayList<RunArg>();
|
||||
+ runList
|
||||
+ .add(new RunArg(new ConfArg(true, true, null, PASS)));
|
||||
+ runList
|
||||
+ .add(new RunArg(new ConfArg(true, false, null, PASS)));
|
||||
+ runList
|
||||
+ .add(new RunArg(new ConfArg(false, true, null, PASS)));
|
||||
+ runList
|
||||
+ .add(new RunArg(new ConfArg(false, false, null, PASS)));
|
||||
+ }
|
||||
+
|
||||
+ public static void main(String[] args) throws Exception {
|
||||
+ if (!Platform.is64bit()) {
|
||||
+ System.out.println("Test case not applicable on 32-bit platforms");
|
||||
+ return;
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ String helloJar = JarBuilder.build("hello", "Hello");
|
||||
+ configureRunArgs();
|
||||
+ OutputAnalyzer out;
|
||||
+ for (RunArg t: runList) {
|
||||
+ out = TestCommon
|
||||
+ .dump(helloJar,
|
||||
+ new String[] {"Hello"},
|
||||
+ getCompressedOopsArg(t.dumpArg.useCompressedOops),
|
||||
+ getCompressedClassPointersArg(t.dumpArg.useCompressedClassPointers));
|
||||
+ out.shouldContain("total : ");
|
||||
+ out.shouldHaveExitValue(0);
|
||||
+
|
||||
+ for (ConfArg c : t.execArgs) {
|
||||
+ out = TestCommon.exec(helloJar,
|
||||
+ "-cp",
|
||||
+ helloJar,
|
||||
+ getCompressedOopsArg(c.useCompressedOops),
|
||||
+ getCompressedClassPointersArg(c.useCompressedClassPointers),
|
||||
+ "Hello");
|
||||
+ out.shouldContain(c.msg);
|
||||
+ out.shouldHaveExitValue(c.code);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/jdk/make/BuildJdk.gmk b/jdk/make/BuildJdk.gmk
|
||||
index bb8ea8a..6707456 100644
|
||||
--- a/jdk/make/BuildJdk.gmk
|
||||
+++ b/jdk/make/BuildJdk.gmk
|
||||
@@ -106,8 +106,10 @@ images:
|
||||
ifeq ($(BUILD_CDS_ARCHIVE), true)
|
||||
echo Creating CDS archive for jdk image
|
||||
$(JDK_IMAGE_DIR)/bin/java -Xshare:dump -Xmx128M -Xms128M -XX:ParallelGCThreads=1 -Xint $(LOG_INFO)
|
||||
+ $(JDK_IMAGE_DIR)/bin/java -Xshare:dump -Xmx128M -Xms128M -XX:ParallelGCThreads=1 -Xint -XX:-UseCompressedOops $(LOG_INFO)
|
||||
echo Creating CDS archive for jre image
|
||||
$(JRE_IMAGE_DIR)/bin/java -Xshare:dump -Xmx128M -Xms128M -XX:ParallelGCThreads=1 -Xint $(LOG_INFO)
|
||||
+ $(JDK_IMAGE_DIR)/bin/java -Xshare:dump -Xmx128M -Xms128M -XX:ParallelGCThreads=1 -Xint -XX:-UseCompressedOops $(LOG_INFO)
|
||||
endif
|
||||
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
2830
8242181-Show-source-information-when-printing-native.patch
Normal file
2830
8242181-Show-source-information-when-printing-native.patch
Normal file
File diff suppressed because it is too large
Load Diff
123
8257695-linux-Add-process-memory-information-to-hs-e.patch
Normal file
123
8257695-linux-Add-process-memory-information-to-hs-e.patch
Normal file
@ -0,0 +1,123 @@
|
||||
From d68c637a36b65d0bce893991e9c910efbc06239a Mon Sep 17 00:00:00 2001
|
||||
From: eapen <zhangyipeng7@huawei.com>
|
||||
Date: Mon, 12 Dec 2022 16:10:41 +0800
|
||||
Subject: [PATCH 10/33] I68TO2: 8257695: [linux] Add process-memory information to
|
||||
hs-err and VM.info
|
||||
---
|
||||
hotspot/src/os/linux/vm/os_linux.cpp | 67 ++++++++++++++++++++++++++++++++++--
|
||||
hotspot/src/os/linux/vm/os_linux.hpp | 3 +-
|
||||
2 files changed, 67 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp
|
||||
index 6dbedf5..4c265d5 100644
|
||||
--- a/hotspot/src/os/linux/vm/os_linux.cpp
|
||||
+++ b/hotspot/src/os/linux/vm/os_linux.cpp
|
||||
@@ -103,6 +103,9 @@
|
||||
# include <stdint.h>
|
||||
# include <inttypes.h>
|
||||
# include <sys/ioctl.h>
|
||||
+#ifdef __GLIBC__
|
||||
+# include <malloc.h>
|
||||
+#endif
|
||||
|
||||
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
|
||||
|
||||
@@ -2216,7 +2219,10 @@ void os::print_os_info(outputStream* st) {
|
||||
|
||||
os::Posix::print_load_average(st);
|
||||
|
||||
- os::Linux::print_full_memory_info(st);
|
||||
+ os::Linux::print_system_memory_info(st);
|
||||
+ st->cr();
|
||||
+
|
||||
+ os::Linux::print_process_memory_info(st);
|
||||
|
||||
os::Linux::print_container_info(st);
|
||||
}
|
||||
@@ -2278,12 +2284,69 @@ void os::Linux::print_libversion_info(outputStream* st) {
|
||||
st->cr();
|
||||
}
|
||||
|
||||
-void os::Linux::print_full_memory_info(outputStream* st) {
|
||||
+void os::Linux::print_system_memory_info(outputStream* st) {
|
||||
st->print("\n/proc/meminfo:\n");
|
||||
_print_ascii_file("/proc/meminfo", st);
|
||||
st->cr();
|
||||
}
|
||||
|
||||
+void os::Linux::print_process_memory_info(outputStream* st) {
|
||||
+
|
||||
+ st->print_cr("Process Memory:");
|
||||
+
|
||||
+ // Print virtual and resident set size; peak values; swap; and for
|
||||
+ // rss its components if the kernel is recent enough.
|
||||
+ ssize_t vmsize = -1, vmpeak = -1, vmswap = -1,
|
||||
+ vmrss = -1, vmhwm = -1, rssanon = -1, rssfile = -1, rssshmem = -1;
|
||||
+ const int num_values = 8;
|
||||
+ int num_found = 0;
|
||||
+ FILE* f = ::fopen("/proc/self/status", "r");
|
||||
+ char buf[256];
|
||||
+ while (::fgets(buf, sizeof(buf), f) != NULL && num_found < num_values) {
|
||||
+ if ( (vmsize == -1 && sscanf(buf, "VmSize: " SSIZE_FORMAT " kB", &vmsize) == 1) ||
|
||||
+ (vmpeak == -1 && sscanf(buf, "VmPeak: " SSIZE_FORMAT " kB", &vmpeak) == 1) ||
|
||||
+ (vmswap == -1 && sscanf(buf, "VmSwap: " SSIZE_FORMAT " kB", &vmswap) == 1) ||
|
||||
+ (vmhwm == -1 && sscanf(buf, "VmHWM: " SSIZE_FORMAT " kB", &vmhwm) == 1) ||
|
||||
+ (vmrss == -1 && sscanf(buf, "VmRSS: " SSIZE_FORMAT " kB", &vmrss) == 1) ||
|
||||
+ (rssanon == -1 && sscanf(buf, "RssAnon: " SSIZE_FORMAT " kB", &rssanon) == 1) ||
|
||||
+ (rssfile == -1 && sscanf(buf, "RssFile: " SSIZE_FORMAT " kB", &rssfile) == 1) ||
|
||||
+ (rssshmem == -1 && sscanf(buf, "RssShmem: " SSIZE_FORMAT " kB", &rssshmem) == 1)
|
||||
+ )
|
||||
+ {
|
||||
+ num_found ++;
|
||||
+ }
|
||||
+ }
|
||||
+ st->print_cr("Virtual Size: " SSIZE_FORMAT "K (peak: " SSIZE_FORMAT "K)", vmsize, vmpeak);
|
||||
+ st->print("Resident Set Size: " SSIZE_FORMAT "K (peak: " SSIZE_FORMAT "K)", vmrss, vmhwm);
|
||||
+ if (rssanon != -1) { // requires kernel >= 4.5
|
||||
+ st->print(" (anon: " SSIZE_FORMAT "K, file: " SSIZE_FORMAT "K, shmem: " SSIZE_FORMAT "K)",
|
||||
+ rssanon, rssfile, rssshmem);
|
||||
+ }
|
||||
+ st->cr();
|
||||
+ if (vmswap != -1) { // requires kernel >= 2.6.34
|
||||
+ st->print_cr("Swapped out: " SSIZE_FORMAT "K", vmswap);
|
||||
+ }
|
||||
+
|
||||
+ // Print glibc outstanding allocations.
|
||||
+ // (note: there is no implementation of mallinfo for muslc)
|
||||
+#ifdef __GLIBC__
|
||||
+ struct mallinfo mi = ::mallinfo();
|
||||
+
|
||||
+ // mallinfo is an old API. Member names mean next to nothing and, beyond that, are int.
|
||||
+ // So values may have wrapped around. Still useful enough to see how much glibc thinks
|
||||
+ // we allocated.
|
||||
+ const size_t total_allocated = (size_t)(unsigned)mi.uordblks;
|
||||
+ st->print("C-Heap outstanding allocations: " SIZE_FORMAT "K", total_allocated / K);
|
||||
+ // Since mallinfo members are int, glibc values may have wrapped. Warn about this.
|
||||
+ if ((vmrss * K) > UINT_MAX && (vmrss * K) > (total_allocated + UINT_MAX)) {
|
||||
+ st->print(" (may have wrapped)");
|
||||
+ }
|
||||
+ st->cr();
|
||||
+
|
||||
+#endif // __GLIBC__
|
||||
+
|
||||
+}
|
||||
+
|
||||
void os::Linux::print_container_info(outputStream* st) {
|
||||
if (!OSContainer::is_containerized()) {
|
||||
return;
|
||||
diff --git a/hotspot/src/os/linux/vm/os_linux.hpp b/hotspot/src/os/linux/vm/os_linux.hpp
|
||||
index c674882..066b03a 100644
|
||||
--- a/hotspot/src/os/linux/vm/os_linux.hpp
|
||||
+++ b/hotspot/src/os/linux/vm/os_linux.hpp
|
||||
@@ -120,7 +120,8 @@ class Linux {
|
||||
static bool release_memory_special_shm(char* base, size_t bytes);
|
||||
static bool release_memory_special_huge_tlbfs(char* base, size_t bytes);
|
||||
|
||||
- static void print_full_memory_info(outputStream* st);
|
||||
+ static void print_process_memory_info(outputStream* st);
|
||||
+ static void print_system_memory_info(outputStream* st);
|
||||
static void print_container_info(outputStream* st);
|
||||
static void print_distro_info(outputStream* st);
|
||||
static void print_libversion_info(outputStream* st);
|
||||
--
|
||||
1.8.3.1
|
||||
73
8261167-print_process_memory_info-add-a-close-call-a.patch
Normal file
73
8261167-print_process_memory_info-add-a-close-call-a.patch
Normal file
@ -0,0 +1,73 @@
|
||||
From 959f2dfd0868274f202c313a24784b0be8da3d32 Mon Sep 17 00:00:00 2001
|
||||
From: eapen <zhangyipeng7@huawei.com>
|
||||
Date: Mon, 12 Dec 2022 17:00:02 +0800
|
||||
Subject: [PATCH 11/33] I68TO2: 8261167: print_process_memory_info add a close call
|
||||
after fopen
|
||||
---
|
||||
hotspot/src/os/linux/vm/os_linux.cpp | 50 ++++++++++++++++++++----------------
|
||||
1 file changed, 28 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp
|
||||
index 4c265d5..1a3504f 100644
|
||||
--- a/hotspot/src/os/linux/vm/os_linux.cpp
|
||||
+++ b/hotspot/src/os/linux/vm/os_linux.cpp
|
||||
@@ -2302,29 +2302,35 @@ void os::Linux::print_process_memory_info(outputStream* st) {
|
||||
int num_found = 0;
|
||||
FILE* f = ::fopen("/proc/self/status", "r");
|
||||
char buf[256];
|
||||
- while (::fgets(buf, sizeof(buf), f) != NULL && num_found < num_values) {
|
||||
- if ( (vmsize == -1 && sscanf(buf, "VmSize: " SSIZE_FORMAT " kB", &vmsize) == 1) ||
|
||||
- (vmpeak == -1 && sscanf(buf, "VmPeak: " SSIZE_FORMAT " kB", &vmpeak) == 1) ||
|
||||
- (vmswap == -1 && sscanf(buf, "VmSwap: " SSIZE_FORMAT " kB", &vmswap) == 1) ||
|
||||
- (vmhwm == -1 && sscanf(buf, "VmHWM: " SSIZE_FORMAT " kB", &vmhwm) == 1) ||
|
||||
- (vmrss == -1 && sscanf(buf, "VmRSS: " SSIZE_FORMAT " kB", &vmrss) == 1) ||
|
||||
- (rssanon == -1 && sscanf(buf, "RssAnon: " SSIZE_FORMAT " kB", &rssanon) == 1) ||
|
||||
- (rssfile == -1 && sscanf(buf, "RssFile: " SSIZE_FORMAT " kB", &rssfile) == 1) ||
|
||||
- (rssshmem == -1 && sscanf(buf, "RssShmem: " SSIZE_FORMAT " kB", &rssshmem) == 1)
|
||||
- )
|
||||
- {
|
||||
- num_found ++;
|
||||
+ if (f != NULL) {
|
||||
+ while (::fgets(buf, sizeof(buf), f) != NULL && num_found < num_values) {
|
||||
+ if ( (vmsize == -1 && sscanf(buf, "VmSize: " SSIZE_FORMAT " kB", &vmsize) == 1) ||
|
||||
+ (vmpeak == -1 && sscanf(buf, "VmPeak: " SSIZE_FORMAT " kB", &vmpeak) == 1) ||
|
||||
+ (vmswap == -1 && sscanf(buf, "VmSwap: " SSIZE_FORMAT " kB", &vmswap) == 1) ||
|
||||
+ (vmhwm == -1 && sscanf(buf, "VmHWM: " SSIZE_FORMAT " kB", &vmhwm) == 1) ||
|
||||
+ (vmrss == -1 && sscanf(buf, "VmRSS: " SSIZE_FORMAT " kB", &vmrss) == 1) ||
|
||||
+ (rssanon == -1 && sscanf(buf, "RssAnon: " SSIZE_FORMAT " kB", &rssanon) == 1) ||
|
||||
+ (rssfile == -1 && sscanf(buf, "RssFile: " SSIZE_FORMAT " kB", &rssfile) == 1) ||
|
||||
+ (rssshmem == -1 && sscanf(buf, "RssShmem: " SSIZE_FORMAT " kB", &rssshmem) == 1)
|
||||
+ )
|
||||
+ {
|
||||
+ num_found ++;
|
||||
+ }
|
||||
}
|
||||
- }
|
||||
- st->print_cr("Virtual Size: " SSIZE_FORMAT "K (peak: " SSIZE_FORMAT "K)", vmsize, vmpeak);
|
||||
- st->print("Resident Set Size: " SSIZE_FORMAT "K (peak: " SSIZE_FORMAT "K)", vmrss, vmhwm);
|
||||
- if (rssanon != -1) { // requires kernel >= 4.5
|
||||
- st->print(" (anon: " SSIZE_FORMAT "K, file: " SSIZE_FORMAT "K, shmem: " SSIZE_FORMAT "K)",
|
||||
- rssanon, rssfile, rssshmem);
|
||||
- }
|
||||
- st->cr();
|
||||
- if (vmswap != -1) { // requires kernel >= 2.6.34
|
||||
- st->print_cr("Swapped out: " SSIZE_FORMAT "K", vmswap);
|
||||
+ fclose(f);
|
||||
+
|
||||
+ st->print_cr("Virtual Size: " SSIZE_FORMAT "K (peak: " SSIZE_FORMAT "K)", vmsize, vmpeak);
|
||||
+ st->print("Resident Set Size: " SSIZE_FORMAT "K (peak: " SSIZE_FORMAT "K)", vmrss, vmhwm);
|
||||
+ if (rssanon != -1) { // requires kernel >= 4.5
|
||||
+ st->print(" (anon: " SSIZE_FORMAT "K, file: " SSIZE_FORMAT "K, shmem: " SSIZE_FORMAT "K)",
|
||||
+ rssanon, rssfile, rssshmem);
|
||||
+ }
|
||||
+ st->cr();
|
||||
+ if (vmswap != -1) { // requires kernel >= 2.6.34
|
||||
+ st->print_cr("Swapped out: " SSIZE_FORMAT "K", vmswap);
|
||||
+ }
|
||||
+ } else {
|
||||
+ st->print_cr("Could not open /proc/self/status to get process memory related information");
|
||||
}
|
||||
|
||||
// Print glibc outstanding allocations.
|
||||
--
|
||||
1.8.3.1
|
||||
121
8263185-Mallinfo-deprecated-in-glibc-2.33.patch
Normal file
121
8263185-Mallinfo-deprecated-in-glibc-2.33.patch
Normal file
@ -0,0 +1,121 @@
|
||||
From ccd4293dbec4b1048bf7eb342b8de8241a3667d4 Mon Sep 17 00:00:00 2001
|
||||
From: eapen <zhangyipeng7@huawei.com>
|
||||
Date: Mon, 12 Dec 2022 18:44:43 +0800
|
||||
Subject: [PATCH 13/33] I68TO2: 8263185: Mallinfo deprecated in glibc 2.33
|
||||
---
|
||||
hotspot/src/os/linux/vm/os_linux.cpp | 39 ++++++++++++++++++++++++++----------
|
||||
hotspot/src/os/linux/vm/os_linux.hpp | 34 +++++++++++++++++++++++++++++++
|
||||
2 files changed, 62 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp
|
||||
index c687b1c..099dafa 100644
|
||||
--- a/hotspot/src/os/linux/vm/os_linux.cpp
|
||||
+++ b/hotspot/src/os/linux/vm/os_linux.cpp
|
||||
@@ -152,6 +152,11 @@ const char * os::Linux::_glibc_version = NULL;
|
||||
const char * os::Linux::_libpthread_version = NULL;
|
||||
pthread_condattr_t os::Linux::_condattr[1];
|
||||
|
||||
+#ifdef __GLIBC__
|
||||
+os::Linux::mallinfo_func_t os::Linux::_mallinfo = NULL;
|
||||
+os::Linux::mallinfo2_func_t os::Linux::_mallinfo2 = NULL;
|
||||
+#endif // __GLIBC__
|
||||
+
|
||||
static jlong initial_time_count=0;
|
||||
|
||||
static int clock_tics_per_sec = 100;
|
||||
@@ -2343,18 +2348,25 @@ void os::Linux::print_process_memory_info(outputStream* st) {
|
||||
// Print glibc outstanding allocations.
|
||||
// (note: there is no implementation of mallinfo for muslc)
|
||||
#ifdef __GLIBC__
|
||||
- struct mallinfo mi = ::mallinfo();
|
||||
-
|
||||
- // mallinfo is an old API. Member names mean next to nothing and, beyond that, are int.
|
||||
- // So values may have wrapped around. Still useful enough to see how much glibc thinks
|
||||
- // we allocated.
|
||||
- const size_t total_allocated = (size_t)(unsigned)mi.uordblks;
|
||||
- st->print("C-Heap outstanding allocations: " SIZE_FORMAT "K", total_allocated / K);
|
||||
- // Since mallinfo members are int, glibc values may have wrapped. Warn about this.
|
||||
- if ((info.vmrss * K) > UINT_MAX && (info.vmrss * K) > (total_allocated + UINT_MAX)) {
|
||||
- st->print(" (may have wrapped)");
|
||||
+ size_t total_allocated = 0;
|
||||
+ bool might_have_wrapped = false;
|
||||
+ if (_mallinfo2 != NULL) {
|
||||
+ struct glibc_mallinfo2 mi = _mallinfo2();
|
||||
+ total_allocated = mi.uordblks;
|
||||
+ } else if (_mallinfo != NULL) {
|
||||
+ // mallinfo is an old API. Member names mean next to nothing and, beyond that, are int.
|
||||
+ // So values may have wrapped around. Still useful enough to see how much glibc thinks
|
||||
+ // we allocated.
|
||||
+ struct glibc_mallinfo mi = _mallinfo();
|
||||
+ total_allocated = (size_t)(unsigned)mi.uordblks;
|
||||
+ // Since mallinfo members are int, glibc values may have wrapped. Warn about this.
|
||||
+ might_have_wrapped = (info.vmrss * K) > UINT_MAX && (info.vmrss * K) > (total_allocated + UINT_MAX);
|
||||
+ }
|
||||
+ if (_mallinfo2 != NULL || _mallinfo != NULL) {
|
||||
+ st->print_cr("C-Heap outstanding allocations: " SIZE_FORMAT "K%s",
|
||||
+ total_allocated / K,
|
||||
+ might_have_wrapped ? " (may have wrapped)" : "");
|
||||
}
|
||||
- st->cr();
|
||||
|
||||
#endif // __GLIBC__
|
||||
|
||||
@@ -5174,6 +5186,11 @@ void os::init(void) {
|
||||
|
||||
Linux::initialize_system_info();
|
||||
|
||||
+#ifdef __GLIBC__
|
||||
+ Linux::_mallinfo = CAST_TO_FN_PTR(Linux::mallinfo_func_t, dlsym(RTLD_DEFAULT, "mallinfo"));
|
||||
+ Linux::_mallinfo2 = CAST_TO_FN_PTR(Linux::mallinfo2_func_t, dlsym(RTLD_DEFAULT, "mallinfo2"));
|
||||
+#endif // __GLIBC__
|
||||
+
|
||||
// _main_thread points to the thread that created/loaded the JVM.
|
||||
Linux::_main_thread = pthread_self();
|
||||
|
||||
diff --git a/hotspot/src/os/linux/vm/os_linux.hpp b/hotspot/src/os/linux/vm/os_linux.hpp
|
||||
index 2c4efff..2bb3fd2 100644
|
||||
--- a/hotspot/src/os/linux/vm/os_linux.hpp
|
||||
+++ b/hotspot/src/os/linux/vm/os_linux.hpp
|
||||
@@ -338,6 +338,40 @@ private:
|
||||
};
|
||||
static NumaAllocationPolicy _current_numa_policy;
|
||||
|
||||
+#ifdef __GLIBC__
|
||||
+ struct glibc_mallinfo {
|
||||
+ int arena;
|
||||
+ int ordblks;
|
||||
+ int smblks;
|
||||
+ int hblks;
|
||||
+ int hblkhd;
|
||||
+ int usmblks;
|
||||
+ int fsmblks;
|
||||
+ int uordblks;
|
||||
+ int fordblks;
|
||||
+ int keepcost;
|
||||
+ };
|
||||
+
|
||||
+ struct glibc_mallinfo2 {
|
||||
+ size_t arena;
|
||||
+ size_t ordblks;
|
||||
+ size_t smblks;
|
||||
+ size_t hblks;
|
||||
+ size_t hblkhd;
|
||||
+ size_t usmblks;
|
||||
+ size_t fsmblks;
|
||||
+ size_t uordblks;
|
||||
+ size_t fordblks;
|
||||
+ size_t keepcost;
|
||||
+ };
|
||||
+
|
||||
+ typedef struct glibc_mallinfo (*mallinfo_func_t)(void);
|
||||
+ typedef struct glibc_mallinfo2 (*mallinfo2_func_t)(void);
|
||||
+
|
||||
+ static mallinfo_func_t _mallinfo;
|
||||
+ static mallinfo2_func_t _mallinfo2;
|
||||
+#endif
|
||||
+
|
||||
public:
|
||||
static int sched_getcpu() { return _sched_getcpu != NULL ? _sched_getcpu() : -1; }
|
||||
static int numa_node_to_cpus(int node, unsigned long *buffer, int bufferlen) {
|
||||
--
|
||||
1.8.3.1
|
||||
678
8268893-jcmd-to-trim-the-glibc-heap.patch
Normal file
678
8268893-jcmd-to-trim-the-glibc-heap.patch
Normal file
@ -0,0 +1,678 @@
|
||||
From 1b97a08d822b7e2388ded07c696fffe70b39697a Mon Sep 17 00:00:00 2001
|
||||
From: eapen <zhangyipeng7@huawei.com>
|
||||
Date: Mon, 12 Dec 2022 17:40:09 +0800
|
||||
Subject: [PATCH 12/33] I68TO2: 8268893: jcmd to trim the glibc heap
|
||||
---
|
||||
hotspot/src/os/linux/vm/os_linux.cpp | 57 ++++---
|
||||
hotspot/src/os/linux/vm/os_linux.hpp | 17 ++
|
||||
hotspot/src/os/linux/vm/trimCHeapDCmd.cpp | 77 +++++++++
|
||||
hotspot/src/os/linux/vm/trimCHeapDCmd.hpp | 52 ++++++
|
||||
.../src/share/vm/services/diagnosticCommand.cpp | 7 +
|
||||
.../test/serviceability/dcmd/TrimLibcHeapTest.java | 53 ++++++
|
||||
.../oracle/java/testlibrary/CommandExecutor.java | 73 ++++++++
|
||||
.../java/testlibrary/CommandExecutorException.java | 36 ++++
|
||||
.../com/oracle/java/testlibrary/JMXExecutor.java | 185 +++++++++++++++++++++
|
||||
9 files changed, 532 insertions(+), 25 deletions(-)
|
||||
create mode 100644 hotspot/src/os/linux/vm/trimCHeapDCmd.cpp
|
||||
create mode 100644 hotspot/src/os/linux/vm/trimCHeapDCmd.hpp
|
||||
create mode 100644 hotspot/test/serviceability/dcmd/TrimLibcHeapTest.java
|
||||
create mode 100644 hotspot/test/testlibrary/com/oracle/java/testlibrary/CommandExecutor.java
|
||||
create mode 100644 hotspot/test/testlibrary/com/oracle/java/testlibrary/CommandExecutorException.java
|
||||
create mode 100644 hotspot/test/testlibrary/com/oracle/java/testlibrary/JMXExecutor.java
|
||||
|
||||
diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp
|
||||
index 1a3504f..c687b1c 100644
|
||||
--- a/hotspot/src/os/linux/vm/os_linux.cpp
|
||||
+++ b/hotspot/src/os/linux/vm/os_linux.cpp
|
||||
@@ -2290,44 +2290,51 @@ void os::Linux::print_system_memory_info(outputStream* st) {
|
||||
st->cr();
|
||||
}
|
||||
|
||||
-void os::Linux::print_process_memory_info(outputStream* st) {
|
||||
-
|
||||
- st->print_cr("Process Memory:");
|
||||
-
|
||||
- // Print virtual and resident set size; peak values; swap; and for
|
||||
- // rss its components if the kernel is recent enough.
|
||||
- ssize_t vmsize = -1, vmpeak = -1, vmswap = -1,
|
||||
- vmrss = -1, vmhwm = -1, rssanon = -1, rssfile = -1, rssshmem = -1;
|
||||
- const int num_values = 8;
|
||||
- int num_found = 0;
|
||||
+bool os::Linux::query_process_memory_info(os::Linux::meminfo_t* info) {
|
||||
FILE* f = ::fopen("/proc/self/status", "r");
|
||||
+ const int num_values = sizeof(os::Linux::meminfo_t) / sizeof(size_t);
|
||||
+ int num_found = 0;
|
||||
char buf[256];
|
||||
+ info->vmsize = info->vmpeak = info->vmrss = info->vmhwm = info->vmswap =
|
||||
+ info->rssanon = info->rssfile = info->rssshmem = -1;
|
||||
if (f != NULL) {
|
||||
while (::fgets(buf, sizeof(buf), f) != NULL && num_found < num_values) {
|
||||
- if ( (vmsize == -1 && sscanf(buf, "VmSize: " SSIZE_FORMAT " kB", &vmsize) == 1) ||
|
||||
- (vmpeak == -1 && sscanf(buf, "VmPeak: " SSIZE_FORMAT " kB", &vmpeak) == 1) ||
|
||||
- (vmswap == -1 && sscanf(buf, "VmSwap: " SSIZE_FORMAT " kB", &vmswap) == 1) ||
|
||||
- (vmhwm == -1 && sscanf(buf, "VmHWM: " SSIZE_FORMAT " kB", &vmhwm) == 1) ||
|
||||
- (vmrss == -1 && sscanf(buf, "VmRSS: " SSIZE_FORMAT " kB", &vmrss) == 1) ||
|
||||
- (rssanon == -1 && sscanf(buf, "RssAnon: " SSIZE_FORMAT " kB", &rssanon) == 1) ||
|
||||
- (rssfile == -1 && sscanf(buf, "RssFile: " SSIZE_FORMAT " kB", &rssfile) == 1) ||
|
||||
- (rssshmem == -1 && sscanf(buf, "RssShmem: " SSIZE_FORMAT " kB", &rssshmem) == 1)
|
||||
+ if ( (info->vmsize == -1 && sscanf(buf, "VmSize: " SSIZE_FORMAT " kB", &info->vmsize) == 1) ||
|
||||
+ (info->vmpeak == -1 && sscanf(buf, "VmPeak: " SSIZE_FORMAT " kB", &info->vmpeak) == 1) ||
|
||||
+ (info->vmswap == -1 && sscanf(buf, "VmSwap: " SSIZE_FORMAT " kB", &info->vmswap) == 1) ||
|
||||
+ (info->vmhwm == -1 && sscanf(buf, "VmHWM: " SSIZE_FORMAT " kB", &info->vmhwm) == 1) ||
|
||||
+ (info->vmrss == -1 && sscanf(buf, "VmRSS: " SSIZE_FORMAT " kB", &info->vmrss) == 1) ||
|
||||
+ (info->rssanon == -1 && sscanf(buf, "RssAnon: " SSIZE_FORMAT " kB", &info->rssanon) == 1) || // Needs Linux 4.5
|
||||
+ (info->rssfile == -1 && sscanf(buf, "RssFile: " SSIZE_FORMAT " kB", &info->rssfile) == 1) || // Needs Linux 4.5
|
||||
+ (info->rssshmem == -1 && sscanf(buf, "RssShmem: " SSIZE_FORMAT " kB", &info->rssshmem) == 1) // Needs Linux 4.5
|
||||
)
|
||||
{
|
||||
num_found ++;
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
+ return true;
|
||||
+ }
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+void os::Linux::print_process_memory_info(outputStream* st) {
|
||||
|
||||
- st->print_cr("Virtual Size: " SSIZE_FORMAT "K (peak: " SSIZE_FORMAT "K)", vmsize, vmpeak);
|
||||
- st->print("Resident Set Size: " SSIZE_FORMAT "K (peak: " SSIZE_FORMAT "K)", vmrss, vmhwm);
|
||||
- if (rssanon != -1) { // requires kernel >= 4.5
|
||||
+ st->print_cr("Process Memory:");
|
||||
+
|
||||
+ // Print virtual and resident set size; peak values; swap; and for
|
||||
+ // rss its components if the kernel is recent enough.
|
||||
+ meminfo_t info;
|
||||
+ if (query_process_memory_info(&info)) {
|
||||
+ st->print_cr("Virtual Size: " SSIZE_FORMAT "K (peak: " SSIZE_FORMAT "K)", info.vmsize, info.vmpeak);
|
||||
+ st->print("Resident Set Size: " SSIZE_FORMAT "K (peak: " SSIZE_FORMAT "K)", info.vmrss, info.vmhwm);
|
||||
+ if (info.rssanon != -1) { // requires kernel >= 4.5
|
||||
st->print(" (anon: " SSIZE_FORMAT "K, file: " SSIZE_FORMAT "K, shmem: " SSIZE_FORMAT "K)",
|
||||
- rssanon, rssfile, rssshmem);
|
||||
+ info.rssanon, info.rssfile, info.rssshmem);
|
||||
}
|
||||
st->cr();
|
||||
- if (vmswap != -1) { // requires kernel >= 2.6.34
|
||||
- st->print_cr("Swapped out: " SSIZE_FORMAT "K", vmswap);
|
||||
+ if (info.vmswap != -1) { // requires kernel >= 2.6.34
|
||||
+ st->print_cr("Swapped out: " SSIZE_FORMAT "K", info.vmswap);
|
||||
}
|
||||
} else {
|
||||
st->print_cr("Could not open /proc/self/status to get process memory related information");
|
||||
@@ -2344,7 +2351,7 @@ void os::Linux::print_process_memory_info(outputStream* st) {
|
||||
const size_t total_allocated = (size_t)(unsigned)mi.uordblks;
|
||||
st->print("C-Heap outstanding allocations: " SIZE_FORMAT "K", total_allocated / K);
|
||||
// Since mallinfo members are int, glibc values may have wrapped. Warn about this.
|
||||
- if ((vmrss * K) > UINT_MAX && (vmrss * K) > (total_allocated + UINT_MAX)) {
|
||||
+ if ((info.vmrss * K) > UINT_MAX && (info.vmrss * K) > (total_allocated + UINT_MAX)) {
|
||||
st->print(" (may have wrapped)");
|
||||
}
|
||||
st->cr();
|
||||
diff --git a/hotspot/src/os/linux/vm/os_linux.hpp b/hotspot/src/os/linux/vm/os_linux.hpp
|
||||
index 066b03a..2c4efff 100644
|
||||
--- a/hotspot/src/os/linux/vm/os_linux.hpp
|
||||
+++ b/hotspot/src/os/linux/vm/os_linux.hpp
|
||||
@@ -243,6 +243,23 @@ class Linux {
|
||||
public:
|
||||
static pthread_condattr_t* condAttr() { return _condattr; }
|
||||
|
||||
+ // Output structure for query_process_memory_info()
|
||||
+ struct meminfo_t {
|
||||
+ ssize_t vmsize; // current virtual size
|
||||
+ ssize_t vmpeak; // peak virtual size
|
||||
+ ssize_t vmrss; // current resident set size
|
||||
+ ssize_t vmhwm; // peak resident set size
|
||||
+ ssize_t vmswap; // swapped out
|
||||
+ ssize_t rssanon; // resident set size (anonymous mappings, needs 4.5)
|
||||
+ ssize_t rssfile; // resident set size (file mappings, needs 4.5)
|
||||
+ ssize_t rssshmem; // resident set size (shared mappings, needs 4.5)
|
||||
+ };
|
||||
+
|
||||
+ // Attempts to query memory information about the current process and return it in the output structure.
|
||||
+ // May fail (returns false) or succeed (returns true) but not all output fields are available; unavailable
|
||||
+ // fields will contain -1.
|
||||
+ static bool query_process_memory_info(meminfo_t* info);
|
||||
+
|
||||
// Stack repair handling
|
||||
|
||||
// none present
|
||||
diff --git a/hotspot/src/os/linux/vm/trimCHeapDCmd.cpp b/hotspot/src/os/linux/vm/trimCHeapDCmd.cpp
|
||||
new file mode 100644
|
||||
index 0000000..95d03d9
|
||||
--- /dev/null
|
||||
+++ b/hotspot/src/os/linux/vm/trimCHeapDCmd.cpp
|
||||
@@ -0,0 +1,77 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2021 SAP SE. All rights reserved.
|
||||
+ * Copyright (c) 2021, 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
|
||||
+ * under the terms of the GNU General Public License version 2 only, as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
+ * version 2 for more details (a copy is included in the LICENSE file that
|
||||
+ * accompanied this code).
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License version
|
||||
+ * 2 along with this work; if not, write to the Free Software Foundation,
|
||||
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
+ *
|
||||
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
+ * or visit www.oracle.com if you need additional information or have any
|
||||
+ * questions.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include "precompiled.hpp"
|
||||
+#include "runtime/os.hpp"
|
||||
+#include "utilities/debug.hpp"
|
||||
+#include "utilities/ostream.hpp"
|
||||
+#include "trimCHeapDCmd.hpp"
|
||||
+
|
||||
+#include <malloc.h>
|
||||
+
|
||||
+void TrimCLibcHeapDCmd::execute(DCmdSource source, TRAPS) {
|
||||
+#ifdef __GLIBC__
|
||||
+ stringStream ss_report(1024); // Note: before calling trim
|
||||
+
|
||||
+ os::Linux::meminfo_t info1;
|
||||
+ os::Linux::meminfo_t info2;
|
||||
+ // Query memory before...
|
||||
+ bool have_info1 = os::Linux::query_process_memory_info(&info1);
|
||||
+
|
||||
+ _output->print_cr("Attempting trim...");
|
||||
+ ::malloc_trim(0);
|
||||
+ _output->print_cr("Done.");
|
||||
+
|
||||
+ // ...and after trim.
|
||||
+ bool have_info2 = os::Linux::query_process_memory_info(&info2);
|
||||
+
|
||||
+ // Print report both to output stream as well to UL
|
||||
+ bool wrote_something = false;
|
||||
+ if (have_info1 && have_info2) {
|
||||
+ if (info1.vmsize != -1 && info2.vmsize != -1) {
|
||||
+ ss_report.print_cr("Virtual size before: " SSIZE_FORMAT "k, after: " SSIZE_FORMAT "k, (" SSIZE_FORMAT "k)",
|
||||
+ info1.vmsize, info2.vmsize, (info2.vmsize - info1.vmsize));
|
||||
+ wrote_something = true;
|
||||
+ }
|
||||
+ if (info1.vmrss != -1 && info2.vmrss != -1) {
|
||||
+ ss_report.print_cr("RSS before: " SSIZE_FORMAT "k, after: " SSIZE_FORMAT "k, (" SSIZE_FORMAT "k)",
|
||||
+ info1.vmrss, info2.vmrss, (info2.vmrss - info1.vmrss));
|
||||
+ wrote_something = true;
|
||||
+ }
|
||||
+ if (info1.vmswap != -1 && info2.vmswap != -1) {
|
||||
+ ss_report.print_cr("Swap before: " SSIZE_FORMAT "k, after: " SSIZE_FORMAT "k, (" SSIZE_FORMAT "k)",
|
||||
+ info1.vmswap, info2.vmswap, (info2.vmswap - info1.vmswap));
|
||||
+ wrote_something = true;
|
||||
+ }
|
||||
+ }
|
||||
+ if (!wrote_something) {
|
||||
+ ss_report.print_raw("No details available.");
|
||||
+ }
|
||||
+
|
||||
+ _output->print_raw(ss_report.base());
|
||||
+#else
|
||||
+ _output->print_cr("Not available.");
|
||||
+#endif
|
||||
+}
|
||||
diff --git a/hotspot/src/os/linux/vm/trimCHeapDCmd.hpp b/hotspot/src/os/linux/vm/trimCHeapDCmd.hpp
|
||||
new file mode 100644
|
||||
index 0000000..4c5b5cc
|
||||
--- /dev/null
|
||||
+++ b/hotspot/src/os/linux/vm/trimCHeapDCmd.hpp
|
||||
@@ -0,0 +1,52 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2021 SAP SE. All rights reserved.
|
||||
+ * Copyright (c) 2021, 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
|
||||
+ * under the terms of the GNU General Public License version 2 only, as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
+ * version 2 for more details (a copy is included in the LICENSE file that
|
||||
+ * accompanied this code).
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License version
|
||||
+ * 2 along with this work; if not, write to the Free Software Foundation,
|
||||
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
+ *
|
||||
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
+ * or visit www.oracle.com if you need additional information or have any
|
||||
+ * questions.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#ifndef OS_LINUX_TRIMCHEAPDCMD_HPP
|
||||
+#define OS_LINUX_TRIMCHEAPDCMD_HPP
|
||||
+
|
||||
+#include "services/diagnosticCommand.hpp"
|
||||
+
|
||||
+class outputStream;
|
||||
+
|
||||
+class TrimCLibcHeapDCmd : public DCmd {
|
||||
+public:
|
||||
+ TrimCLibcHeapDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
|
||||
+ static const char* name() {
|
||||
+ return "System.trim_native_heap";
|
||||
+ }
|
||||
+ static const char* description() {
|
||||
+ return "Attempts to free up memory by trimming the C-heap.";
|
||||
+ }
|
||||
+ static const char* impact() {
|
||||
+ return "Low";
|
||||
+ }
|
||||
+ static const JavaPermission permission() {
|
||||
+ JavaPermission p = { "java.lang.management.ManagementPermission", "control", NULL };
|
||||
+ return p;
|
||||
+ }
|
||||
+ virtual void execute(DCmdSource source, TRAPS);
|
||||
+};
|
||||
+
|
||||
+#endif // OS_LINUX_TRIMCHEAPDCMD_HPP
|
||||
diff --git a/hotspot/src/share/vm/services/diagnosticCommand.cpp b/hotspot/src/share/vm/services/diagnosticCommand.cpp
|
||||
index 358ec6e..60417b5 100644
|
||||
--- a/hotspot/src/share/vm/services/diagnosticCommand.cpp
|
||||
+++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp
|
||||
@@ -36,6 +36,10 @@
|
||||
#include "utilities/macros.hpp"
|
||||
#include "oops/objArrayOop.hpp"
|
||||
|
||||
+#ifdef LINUX
|
||||
+#include "trimCHeapDCmd.hpp"
|
||||
+#endif
|
||||
+
|
||||
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
|
||||
|
||||
void DCmdRegistrant::register_dcmds(){
|
||||
@@ -65,6 +69,9 @@ void DCmdRegistrant::register_dcmds(){
|
||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(full_export, true, false));
|
||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RotateGCLogDCmd>(full_export, true, false));
|
||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassLoaderStatsDCmd>(full_export, true, false));
|
||||
+#ifdef LINUX
|
||||
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<TrimCLibcHeapDCmd>(full_export, true, false));
|
||||
+#endif // LINUX
|
||||
|
||||
// Enhanced JMX Agent Support
|
||||
// These commands won't be exported via the DiagnosticCommandMBean until an
|
||||
diff --git a/hotspot/test/serviceability/dcmd/TrimLibcHeapTest.java b/hotspot/test/serviceability/dcmd/TrimLibcHeapTest.java
|
||||
new file mode 100644
|
||||
index 0000000..0fe8e35
|
||||
--- /dev/null
|
||||
+++ b/hotspot/test/serviceability/dcmd/TrimLibcHeapTest.java
|
||||
@@ -0,0 +1,53 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2021 SAP SE. All rights reserved.
|
||||
+ * Copyright (c) 2021, 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
|
||||
+ * under the terms of the GNU General Public License version 2 only, as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
+ * version 2 for more details (a copy is included in the LICENSE file that
|
||||
+ * accompanied this code).
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License version
|
||||
+ * 2 along with this work; if not, write to the Free Software Foundation,
|
||||
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
+ *
|
||||
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
+ * or visit www.oracle.com if you need additional information or have any
|
||||
+ * questions.
|
||||
+ */
|
||||
+
|
||||
+import org.testng.annotations.Test;
|
||||
+import com.oracle.java.testlibrary.*;
|
||||
+
|
||||
+/*
|
||||
+ * @test
|
||||
+ * @summary Test of diagnostic command VM.trim_libc_heap
|
||||
+ * @library /testlibrary
|
||||
+ * @requires os.family == "linux"
|
||||
+ * @modules java.base/jdk.internal.misc
|
||||
+ * java.compiler
|
||||
+ * java.management
|
||||
+ * jdk.internal.jvmstat/sun.jvmstat.monitor
|
||||
+ * @run testng TrimLibcHeapTest
|
||||
+ */
|
||||
+public class TrimLibcHeapTest {
|
||||
+ public void run(CommandExecutor executor) {
|
||||
+ OutputAnalyzer output = executor.execute("System.trim_native_heap");
|
||||
+ output.reportDiagnosticSummary();
|
||||
+ output.shouldMatch("(Done|Not available)"); // Not available could happen on Linux + non-glibc (eg. muslc)
|
||||
+ if (output.firstMatch("Done") != null) {
|
||||
+ output.shouldMatch("(Virtual size before|RSS before|Swap before|No details available)");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void jmx() {
|
||||
+ run(new JMXExecutor());
|
||||
+ }
|
||||
+}
|
||||
diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/CommandExecutor.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/CommandExecutor.java
|
||||
new file mode 100644
|
||||
index 0000000..e95a437
|
||||
--- /dev/null
|
||||
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/CommandExecutor.java
|
||||
@@ -0,0 +1,73 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2015, 2016, 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
|
||||
+ * under the terms of the GNU General Public License version 2 only, as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
+ * version 2 for more details (a copy is included in the LICENSE file that
|
||||
+ * accompanied this code).
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License version
|
||||
+ * 2 along with this work; if not, write to the Free Software Foundation,
|
||||
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
+ *
|
||||
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
+ * or visit www.oracle.com if you need additional information or have any
|
||||
+ * questions.
|
||||
+ */
|
||||
+
|
||||
+package com.oracle.java.testlibrary;
|
||||
+
|
||||
+/**
|
||||
+ * Abstract base class for Diagnostic Command executors
|
||||
+ */
|
||||
+public abstract class CommandExecutor {
|
||||
+
|
||||
+ /**
|
||||
+ * Execute a diagnostic command
|
||||
+ *
|
||||
+ * @param cmd The diagnostic command to execute
|
||||
+ * @return an {@link jdk.testlibrary.OutputAnalyzer} encapsulating the output of the command
|
||||
+ * @throws CommandExecutorException if there is an exception on the "calling side" while trying to execute the
|
||||
+ * Diagnostic Command. Exceptions thrown on the remote side are available as textual representations in
|
||||
+ * stderr, regardless of the specific executor used.
|
||||
+ */
|
||||
+ public final OutputAnalyzer execute(String cmd) throws CommandExecutorException {
|
||||
+ return execute(cmd, false);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Execute a diagnostic command
|
||||
+ *
|
||||
+ * @param cmd The diagnostic command to execute
|
||||
+ * @param silent Do not print the command output
|
||||
+ * @return an {@link jdk.testlibrary.OutputAnalyzer} encapsulating the output of the command
|
||||
+ * @throws CommandExecutorException if there is an exception on the "calling side" while trying to execute the
|
||||
+ * Diagnostic Command. Exceptions thrown on the remote side are available as textual representations in
|
||||
+ * stderr, regardless of the specific executor used.
|
||||
+ */
|
||||
+ public final OutputAnalyzer execute(String cmd, boolean silent) throws CommandExecutorException {
|
||||
+ if (!silent) {
|
||||
+ System.out.printf("Running DCMD '%s' through '%s'%n", cmd, this.getClass().getSimpleName());
|
||||
+ }
|
||||
+
|
||||
+ OutputAnalyzer oa = executeImpl(cmd);
|
||||
+
|
||||
+ if (!silent) {
|
||||
+ System.out.println("---------------- stdout ----------------");
|
||||
+ System.out.println(oa.getStdout());
|
||||
+ System.out.println("---------------- stderr ----------------");
|
||||
+ System.out.println(oa.getStderr());
|
||||
+ System.out.println("----------------------------------------");
|
||||
+ System.out.println();
|
||||
+ }
|
||||
+ return oa;
|
||||
+ }
|
||||
+
|
||||
+ protected abstract OutputAnalyzer executeImpl(String cmd) throws CommandExecutorException;
|
||||
+}
|
||||
diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/CommandExecutorException.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/CommandExecutorException.java
|
||||
new file mode 100644
|
||||
index 0000000..1857a23
|
||||
--- /dev/null
|
||||
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/CommandExecutorException.java
|
||||
@@ -0,0 +1,36 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2015, 2016, 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
|
||||
+ * under the terms of the GNU General Public License version 2 only, as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
+ * version 2 for more details (a copy is included in the LICENSE file that
|
||||
+ * accompanied this code).
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License version
|
||||
+ * 2 along with this work; if not, write to the Free Software Foundation,
|
||||
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
+ *
|
||||
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
+ * or visit www.oracle.com if you need additional information or have any
|
||||
+ * questions.
|
||||
+ */
|
||||
+
|
||||
+package com.oracle.java.testlibrary;
|
||||
+
|
||||
+/**
|
||||
+ * CommandExecutorException encapsulates exceptions thrown (on the "calling side") from the execution of Diagnostic
|
||||
+ * Commands
|
||||
+ */
|
||||
+public class CommandExecutorException extends RuntimeException {
|
||||
+ private static final long serialVersionUID = -7039597746579144280L;
|
||||
+
|
||||
+ public CommandExecutorException(String message, Throwable e) {
|
||||
+ super(message, e);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/JMXExecutor.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/JMXExecutor.java
|
||||
new file mode 100644
|
||||
index 0000000..317fc5c
|
||||
--- /dev/null
|
||||
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/JMXExecutor.java
|
||||
@@ -0,0 +1,185 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2015, 2016, 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
|
||||
+ * under the terms of the GNU General Public License version 2 only, as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
+ * version 2 for more details (a copy is included in the LICENSE file that
|
||||
+ * accompanied this code).
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License version
|
||||
+ * 2 along with this work; if not, write to the Free Software Foundation,
|
||||
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
+ *
|
||||
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
+ * or visit www.oracle.com if you need additional information or have any
|
||||
+ * questions.
|
||||
+ */
|
||||
+
|
||||
+package com.oracle.java.testlibrary;
|
||||
+
|
||||
+import javax.management.*;
|
||||
+import javax.management.remote.JMXConnector;
|
||||
+import javax.management.remote.JMXConnectorFactory;
|
||||
+import javax.management.remote.JMXServiceURL;
|
||||
+
|
||||
+import java.io.IOException;
|
||||
+import java.io.PrintWriter;
|
||||
+import java.io.StringWriter;
|
||||
+
|
||||
+import java.lang.management.ManagementFactory;
|
||||
+
|
||||
+import java.util.HashMap;
|
||||
+
|
||||
+/**
|
||||
+ * Executes Diagnostic Commands on the target VM (specified by a host/port combination or a full JMX Service URL) using
|
||||
+ * the JMX interface. If the target is not the current VM, the JMX Remote interface must be enabled beforehand.
|
||||
+ */
|
||||
+public class JMXExecutor extends CommandExecutor {
|
||||
+
|
||||
+ private final MBeanServerConnection mbs;
|
||||
+
|
||||
+ /**
|
||||
+ * Instantiates a new JMXExecutor targeting the current VM
|
||||
+ */
|
||||
+ public JMXExecutor() {
|
||||
+ super();
|
||||
+ mbs = ManagementFactory.getPlatformMBeanServer();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Instantiates a new JMXExecutor targeting the VM indicated by the given host/port combination or a full JMX
|
||||
+ * Service URL
|
||||
+ *
|
||||
+ * @param target a host/port combination on the format "host:port" or a full JMX Service URL of the target VM
|
||||
+ */
|
||||
+ public JMXExecutor(String target) {
|
||||
+ String urlStr;
|
||||
+
|
||||
+ if (target.matches("^\\w[\\w\\-]*(\\.[\\w\\-]+)*:\\d+$")) {
|
||||
+ /* Matches "hostname:port" */
|
||||
+ urlStr = String.format("service:jmx:rmi:///jndi/rmi://%s/jmxrmi", target);
|
||||
+ } else if (target.startsWith("service:")) {
|
||||
+ urlStr = target;
|
||||
+ } else {
|
||||
+ throw new IllegalArgumentException("Could not recognize target string: " + target);
|
||||
+ }
|
||||
+
|
||||
+ try {
|
||||
+ JMXServiceURL url = new JMXServiceURL(urlStr);
|
||||
+ JMXConnector c = JMXConnectorFactory.connect(url, new HashMap<>());
|
||||
+ mbs = c.getMBeanServerConnection();
|
||||
+ } catch (IOException e) {
|
||||
+ throw new CommandExecutorException("Could not initiate connection to target: " + target, e);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ protected OutputAnalyzer executeImpl(String cmd) throws CommandExecutorException {
|
||||
+ String stdout = "";
|
||||
+ String stderr = "";
|
||||
+
|
||||
+ String[] cmdParts = cmd.split(" ", 2);
|
||||
+ String operation = commandToMethodName(cmdParts[0]);
|
||||
+ Object[] dcmdArgs = produceArguments(cmdParts);
|
||||
+ String[] signature = {String[].class.getName()};
|
||||
+
|
||||
+ ObjectName beanName = getMBeanName();
|
||||
+
|
||||
+ try {
|
||||
+ stdout = (String) mbs.invoke(beanName, operation, dcmdArgs, signature);
|
||||
+ }
|
||||
+
|
||||
+ /* Failures on the "local" side, the one invoking the command. */
|
||||
+ catch (ReflectionException e) {
|
||||
+ Throwable cause = e.getCause();
|
||||
+ if (cause instanceof NoSuchMethodException) {
|
||||
+ /* We want JMXExecutor to match the behavior of the other CommandExecutors */
|
||||
+ String message = "Unknown diagnostic command: " + operation;
|
||||
+ stderr = exceptionTraceAsString(new IllegalArgumentException(message, e));
|
||||
+ } else {
|
||||
+ rethrowExecutorException(operation, dcmdArgs, e);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Failures on the "local" side, the one invoking the command. */
|
||||
+ catch (InstanceNotFoundException | IOException e) {
|
||||
+ rethrowExecutorException(operation, dcmdArgs, e);
|
||||
+ }
|
||||
+
|
||||
+ /* Failures on the remote side, the one executing the invoked command. */
|
||||
+ catch (MBeanException e) {
|
||||
+ stdout = exceptionTraceAsString(e);
|
||||
+ }
|
||||
+
|
||||
+ return new OutputAnalyzer(stdout, stderr);
|
||||
+ }
|
||||
+
|
||||
+ private void rethrowExecutorException(String operation, Object[] dcmdArgs,
|
||||
+ Exception e) throws CommandExecutorException {
|
||||
+ String message = String.format("Could not invoke: %s %s", operation,
|
||||
+ String.join(" ", (String[]) dcmdArgs[0]));
|
||||
+ throw new CommandExecutorException(message, e);
|
||||
+ }
|
||||
+
|
||||
+ private ObjectName getMBeanName() throws CommandExecutorException {
|
||||
+ String MBeanName = "com.sun.management:type=DiagnosticCommand";
|
||||
+
|
||||
+ try {
|
||||
+ return new ObjectName(MBeanName);
|
||||
+ } catch (MalformedObjectNameException e) {
|
||||
+ String message = "MBean not found: " + MBeanName;
|
||||
+ throw new CommandExecutorException(message, e);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private Object[] produceArguments(String[] cmdParts) {
|
||||
+ Object[] dcmdArgs = {new String[0]}; /* Default: No arguments */
|
||||
+
|
||||
+ if (cmdParts.length == 2) {
|
||||
+ dcmdArgs[0] = cmdParts[1].split(" ");
|
||||
+ }
|
||||
+ return dcmdArgs;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Convert from diagnostic command to MBean method name
|
||||
+ *
|
||||
+ * Examples:
|
||||
+ * help --> help
|
||||
+ * VM.version --> vmVersion
|
||||
+ * VM.command_line --> vmCommandLine
|
||||
+ */
|
||||
+ private static String commandToMethodName(String cmd) {
|
||||
+ String operation = "";
|
||||
+ boolean up = false; /* First letter is to be lower case */
|
||||
+
|
||||
+ /*
|
||||
+ * If a '.' or '_' is encountered it is not copied,
|
||||
+ * instead the next character will be converted to upper case
|
||||
+ */
|
||||
+ for (char c : cmd.toCharArray()) {
|
||||
+ if (('.' == c) || ('_' == c)) {
|
||||
+ up = true;
|
||||
+ } else if (up) {
|
||||
+ operation = operation.concat(Character.toString(c).toUpperCase());
|
||||
+ up = false;
|
||||
+ } else {
|
||||
+ operation = operation.concat(Character.toString(c).toLowerCase());
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return operation;
|
||||
+ }
|
||||
+
|
||||
+ private static String exceptionTraceAsString(Throwable cause) {
|
||||
+ StringWriter sw = new StringWriter();
|
||||
+ cause.printStackTrace(new PrintWriter(sw));
|
||||
+ return sw.toString();
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
--
|
||||
1.8.3.1
|
||||
430
8275775-Add-jcmd-VM.classes-to-print-details-of-all-.patch
Normal file
430
8275775-Add-jcmd-VM.classes-to-print-details-of-all-.patch
Normal file
@ -0,0 +1,430 @@
|
||||
From c427ef7ceeea1fb8f8ebd035e59b6f06b5ec34c1 Mon Sep 17 00:00:00 2001
|
||||
From: eapen <zhangyipeng7@huawei.com>
|
||||
Date: Tue, 13 Dec 2022 21:06:41 +0800
|
||||
Subject: [PATCH 15/33] I68TO2: 8275775: Add jcmd VM.classes to print details of all
|
||||
classes
|
||||
---
|
||||
hotspot/src/share/vm/oops/instanceKlass.cpp | 56 ++++++++++++++++++++--
|
||||
hotspot/src/share/vm/oops/instanceKlass.hpp | 17 ++++---
|
||||
hotspot/src/share/vm/runtime/fieldDescriptor.cpp | 4 +-
|
||||
hotspot/src/share/vm/runtime/fieldDescriptor.hpp | 4 +-
|
||||
hotspot/src/share/vm/runtime/globals.hpp | 2 +-
|
||||
hotspot/src/share/vm/runtime/vm_operations.hpp | 1 +
|
||||
.../src/share/vm/services/diagnosticCommand.cpp | 53 ++++++++++++++++++++
|
||||
.../src/share/vm/services/diagnosticCommand.hpp | 23 +++++++++
|
||||
hotspot/test/runtime/CommandLine/PrintClasses.java | 51 ++++++++++++++++++++
|
||||
9 files changed, 195 insertions(+), 16 deletions(-)
|
||||
create mode 100644 hotspot/test/runtime/CommandLine/PrintClasses.java
|
||||
|
||||
diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp
|
||||
index 2a9cd92..538645b 100644
|
||||
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp
|
||||
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp
|
||||
@@ -1799,6 +1799,52 @@ Method* InstanceKlass::lookup_method_in_all_interfaces(Symbol* name,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+PrintClassClosure::PrintClassClosure(outputStream* st, bool verbose)
|
||||
+ :_st(st), _verbose(verbose) {
|
||||
+ ResourceMark rm;
|
||||
+ _st->print("%-18s ", "KlassAddr");
|
||||
+ _st->print("%-4s ", "Size");
|
||||
+ _st->print("%-20s ", "State");
|
||||
+ _st->print("%-7s ", "Flags");
|
||||
+ _st->print("%-5s ", "ClassName");
|
||||
+ _st->cr();
|
||||
+}
|
||||
+
|
||||
+void PrintClassClosure::do_klass(Klass* k) {
|
||||
+ ResourceMark rm;
|
||||
+ // klass pointer
|
||||
+ _st->print(INTPTR_FORMAT " ", p2i(k));
|
||||
+ // klass size
|
||||
+ _st->print("%4d ", k->size());
|
||||
+ // initialization state
|
||||
+ if (k->oop_is_instance()) {
|
||||
+ _st->print("%-20s ",InstanceKlass::cast(k)->init_state_name());
|
||||
+ } else {
|
||||
+ _st->print("%-20s ","");
|
||||
+ }
|
||||
+ // misc flags(Changes should synced with ClassesDCmd::ClassesDCmd help doc)
|
||||
+ char buf[10];
|
||||
+ int i = 0;
|
||||
+ if (k->has_finalizer()) buf[i++] = 'F';
|
||||
+ if (k->has_final_method()) buf[i++] = 'f';
|
||||
+ if (k->oop_is_instance()) {
|
||||
+ InstanceKlass* ik = InstanceKlass::cast(k);
|
||||
+ if (ik->is_rewritten()) buf[i++] = 'W';
|
||||
+ if (ik->is_contended()) buf[i++] = 'C';
|
||||
+ if (ik->has_been_redefined()) buf[i++] = 'R';
|
||||
+ if (ik->is_shared()) buf[i++] = 'S';
|
||||
+ }
|
||||
+ buf[i++] = '\0';
|
||||
+ _st->print("%-7s ", buf);
|
||||
+ // klass name
|
||||
+ _st->print("%-5s ", k->external_name());
|
||||
+ // end
|
||||
+ _st->cr();
|
||||
+ if (_verbose) {
|
||||
+ k->print_on(_st);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/* jni_id_for_impl for jfieldIds only */
|
||||
JNIid* InstanceKlass::jni_id_for_impl(instanceKlassHandle this_oop, int offset) {
|
||||
MutexLocker ml(JfieldIdCreation_lock);
|
||||
@@ -3244,7 +3290,6 @@ oop InstanceKlass::add_member_name(Handle mem_name, bool intern) {
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// Printing
|
||||
|
||||
-#ifndef PRODUCT
|
||||
|
||||
#define BULLET " - "
|
||||
|
||||
@@ -3264,6 +3309,10 @@ static void print_vtable(intptr_t* start, int len, outputStream* st) {
|
||||
}
|
||||
}
|
||||
|
||||
+const char* InstanceKlass::init_state_name() const {
|
||||
+ return state_names[_init_state];
|
||||
+}
|
||||
+
|
||||
void InstanceKlass::print_on(outputStream* st) const {
|
||||
assert(is_klass(), "must be klass");
|
||||
Klass::print_on(st);
|
||||
@@ -3271,7 +3320,7 @@ void InstanceKlass::print_on(outputStream* st) const {
|
||||
st->print(BULLET"instance size: %d", size_helper()); st->cr();
|
||||
st->print(BULLET"klass size: %d", size()); st->cr();
|
||||
st->print(BULLET"access: "); access_flags().print_on(st); st->cr();
|
||||
- st->print(BULLET"state: "); st->print_cr("%s", state_names[_init_state]);
|
||||
+ st->print(BULLET"state: "); st->print_cr("%s", init_state_name());
|
||||
st->print(BULLET"name: "); name()->print_value_on(st); st->cr();
|
||||
st->print(BULLET"super: "); super()->print_value_on_maybe_null(st); st->cr();
|
||||
st->print(BULLET"sub: ");
|
||||
@@ -3380,7 +3429,6 @@ void InstanceKlass::print_on(outputStream* st) const {
|
||||
st->cr();
|
||||
}
|
||||
|
||||
-#endif //PRODUCT
|
||||
|
||||
void InstanceKlass::print_value_on(outputStream* st) const {
|
||||
assert(is_klass(), "must be klass");
|
||||
@@ -3388,7 +3436,6 @@ void InstanceKlass::print_value_on(outputStream* st) const {
|
||||
name()->print_value_on(st);
|
||||
}
|
||||
|
||||
-#ifndef PRODUCT
|
||||
|
||||
void FieldPrinter::do_field(fieldDescriptor* fd) {
|
||||
_st->print(BULLET);
|
||||
@@ -3449,7 +3496,6 @@ void InstanceKlass::oop_print_on(oop obj, outputStream* st) {
|
||||
}
|
||||
}
|
||||
|
||||
-#endif //PRODUCT
|
||||
|
||||
void InstanceKlass::oop_print_value_on(oop obj, outputStream* st) {
|
||||
st->print("a ");
|
||||
diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp
|
||||
index 43919e8..6e36fa4 100644
|
||||
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp
|
||||
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp
|
||||
@@ -99,7 +99,6 @@ public:
|
||||
virtual void do_field(fieldDescriptor* fd) = 0;
|
||||
};
|
||||
|
||||
-#ifndef PRODUCT
|
||||
// Print fields.
|
||||
// If "obj" argument to constructor is NULL, prints static fields, otherwise prints non-static fields.
|
||||
class FieldPrinter: public FieldClosure {
|
||||
@@ -109,7 +108,6 @@ class FieldPrinter: public FieldClosure {
|
||||
FieldPrinter(outputStream* st, oop obj = NULL) : _obj(obj), _st(st) {}
|
||||
void do_field(fieldDescriptor* fd);
|
||||
};
|
||||
-#endif // !PRODUCT
|
||||
|
||||
// ValueObjs embedded in klass. Describes where oops are located in instances of
|
||||
// this klass.
|
||||
@@ -462,6 +460,7 @@ class InstanceKlass: public Klass {
|
||||
bool is_in_error_state() const { return _init_state == initialization_error; }
|
||||
bool is_reentrant_initialization(Thread *thread) { return thread == _init_thread; }
|
||||
ClassState init_state() { return (ClassState)_init_state; }
|
||||
+ const char* init_state_name() const;
|
||||
bool is_rewritten() const { return (_misc_flags & _misc_rewritten) != 0; }
|
||||
|
||||
// defineClass specified verification
|
||||
@@ -1174,16 +1173,13 @@ public:
|
||||
|
||||
public:
|
||||
// Printing
|
||||
-#ifndef PRODUCT
|
||||
void print_on(outputStream* st) const;
|
||||
-#endif
|
||||
void print_value_on(outputStream* st) const;
|
||||
|
||||
void oop_print_value_on(oop obj, outputStream* st);
|
||||
|
||||
-#ifndef PRODUCT
|
||||
void oop_print_on (oop obj, outputStream* st);
|
||||
-
|
||||
+#ifndef PRODUCT
|
||||
void print_dependent_nmethods(bool verbose = false);
|
||||
bool is_dependent_nmethod(nmethod* nm);
|
||||
#endif
|
||||
@@ -1217,6 +1213,15 @@ inline u2 InstanceKlass::next_method_idnum() {
|
||||
}
|
||||
}
|
||||
|
||||
+class PrintClassClosure : public KlassClosure {
|
||||
+private:
|
||||
+ outputStream* _st;
|
||||
+ bool _verbose;
|
||||
+public:
|
||||
+ PrintClassClosure(outputStream* st, bool verbose);
|
||||
+
|
||||
+ void do_klass(Klass* k);
|
||||
+};
|
||||
|
||||
/* JNIid class for jfieldIDs only */
|
||||
class JNIid: public CHeapObj<mtClass> {
|
||||
diff --git a/hotspot/src/share/vm/runtime/fieldDescriptor.cpp b/hotspot/src/share/vm/runtime/fieldDescriptor.cpp
|
||||
index 610402d..288e82d 100644
|
||||
--- a/hotspot/src/share/vm/runtime/fieldDescriptor.cpp
|
||||
+++ b/hotspot/src/share/vm/runtime/fieldDescriptor.cpp
|
||||
@@ -123,6 +123,8 @@ void fieldDescriptor::verify() const {
|
||||
}
|
||||
}
|
||||
|
||||
+#endif /* PRODUCT */
|
||||
+
|
||||
void fieldDescriptor::print_on(outputStream* st) const {
|
||||
access_flags().print_on(st);
|
||||
name()->print_value_on(st);
|
||||
@@ -206,5 +208,3 @@ void fieldDescriptor::print_on_for(outputStream* st, oop obj) {
|
||||
st->print(" (%x)", as_int);
|
||||
}
|
||||
}
|
||||
-
|
||||
-#endif /* PRODUCT */
|
||||
diff --git a/hotspot/src/share/vm/runtime/fieldDescriptor.hpp b/hotspot/src/share/vm/runtime/fieldDescriptor.hpp
|
||||
index 1810a16..f7e9a26 100644
|
||||
--- a/hotspot/src/share/vm/runtime/fieldDescriptor.hpp
|
||||
+++ b/hotspot/src/share/vm/runtime/fieldDescriptor.hpp
|
||||
@@ -129,8 +129,8 @@ class fieldDescriptor VALUE_OBJ_CLASS_SPEC {
|
||||
|
||||
// Print
|
||||
void print() { print_on(tty); }
|
||||
- void print_on(outputStream* st) const PRODUCT_RETURN;
|
||||
- void print_on_for(outputStream* st, oop obj) PRODUCT_RETURN;
|
||||
+ void print_on(outputStream* st) const;
|
||||
+ void print_on_for(outputStream* st, oop obj);
|
||||
void verify() const PRODUCT_RETURN;
|
||||
};
|
||||
|
||||
diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
|
||||
index ec48c48..41b1392 100644
|
||||
--- a/hotspot/src/share/vm/runtime/globals.hpp
|
||||
+++ b/hotspot/src/share/vm/runtime/globals.hpp
|
||||
@@ -3097,7 +3097,7 @@ class CommandLineFlags {
|
||||
notproduct(intx, MaxElementPrintSize, 256, \
|
||||
"maximum number of elements to print") \
|
||||
\
|
||||
- notproduct(intx, MaxSubklassPrintSize, 4, \
|
||||
+ product(intx, MaxSubklassPrintSize, 4, \
|
||||
"maximum number of subklasses to print when printing klass") \
|
||||
\
|
||||
product(intx, MaxInlineLevel, 9, \
|
||||
diff --git a/hotspot/src/share/vm/runtime/vm_operations.hpp b/hotspot/src/share/vm/runtime/vm_operations.hpp
|
||||
index 8c6795a..a8ba78b 100644
|
||||
--- a/hotspot/src/share/vm/runtime/vm_operations.hpp
|
||||
+++ b/hotspot/src/share/vm/runtime/vm_operations.hpp
|
||||
@@ -99,6 +99,7 @@
|
||||
template(WhiteBoxOperation) \
|
||||
template(ClassLoaderStatsOperation) \
|
||||
template(JFROldObject) \
|
||||
+ template(PrintClasses) \
|
||||
|
||||
class VM_Operation: public CHeapObj<mtInternal> {
|
||||
public:
|
||||
diff --git a/hotspot/src/share/vm/services/diagnosticCommand.cpp b/hotspot/src/share/vm/services/diagnosticCommand.cpp
|
||||
index 60417b5..e4e6185 100644
|
||||
--- a/hotspot/src/share/vm/services/diagnosticCommand.cpp
|
||||
+++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp
|
||||
@@ -64,6 +64,7 @@ void DCmdRegistrant::register_dcmds(){
|
||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HeapDumpDCmd>(DCmd_Source_Internal | DCmd_Source_AttachAPI, true, false));
|
||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<DynamicCDSDumpDCmd>(DCmd_Source_Internal | DCmd_Source_AttachAPI, true, false));
|
||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassHistogramDCmd>(full_export, true, false));
|
||||
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassesDCmd>(full_export, true, false));
|
||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassStatsDCmd>(full_export, true, false));
|
||||
#endif // INCLUDE_SERVICES
|
||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(full_export, true, false));
|
||||
@@ -98,9 +99,14 @@ HelpDCmd::HelpDCmd(outputStream* output, bool heap) : DCmdWithParser(output, hea
|
||||
_dcmdparser.add_dcmd_argument(&_cmd);
|
||||
};
|
||||
|
||||
+static int compare_strings(const char** s1, const char** s2) {
|
||||
+ return ::strcmp(*s1, *s2);
|
||||
+}
|
||||
+
|
||||
void HelpDCmd::execute(DCmdSource source, TRAPS) {
|
||||
if (_all.value()) {
|
||||
GrowableArray<const char*>* cmd_list = DCmdFactory::DCmd_list(source);
|
||||
+ cmd_list->sort(compare_strings);
|
||||
for (int i = 0; i < cmd_list->length(); i++) {
|
||||
DCmdFactory* factory = DCmdFactory::factory(source, cmd_list->at(i),
|
||||
strlen(cmd_list->at(i)));
|
||||
@@ -141,6 +147,7 @@ void HelpDCmd::execute(DCmdSource source, TRAPS) {
|
||||
} else {
|
||||
output()->print_cr("The following commands are available:");
|
||||
GrowableArray<const char *>* cmd_list = DCmdFactory::DCmd_list(source);
|
||||
+ cmd_list->sort(compare_strings);
|
||||
for (int i = 0; i < cmd_list->length(); i++) {
|
||||
DCmdFactory* factory = DCmdFactory::factory(source, cmd_list->at(i),
|
||||
strlen(cmd_list->at(i)));
|
||||
@@ -419,6 +426,52 @@ int ClassHistogramDCmd::num_arguments() {
|
||||
}
|
||||
}
|
||||
|
||||
+ClassesDCmd::ClassesDCmd(outputStream* output, bool heap) :
|
||||
+ DCmdWithParser(output, heap),
|
||||
+ _verbose("-verbose",
|
||||
+ "Dump the detailed content of a Java class. "
|
||||
+ "Some classes are annotated with flags: "
|
||||
+ "F = has, or inherits, a non-empty finalize method, "
|
||||
+ "f = has final method, "
|
||||
+ "W = methods rewritten, "
|
||||
+ "C = marked with @Contended annotation, "
|
||||
+ "R = has been redefined, "
|
||||
+ "S = is shared class",
|
||||
+ "BOOLEAN", false, "false") {
|
||||
+ _dcmdparser.add_dcmd_option(&_verbose);
|
||||
+}
|
||||
+
|
||||
+class VM_PrintClasses : public VM_Operation {
|
||||
+private:
|
||||
+ outputStream* _out;
|
||||
+ bool _verbose;
|
||||
+public:
|
||||
+ VM_PrintClasses(outputStream* out, bool verbose) : _out(out), _verbose(verbose) {}
|
||||
+
|
||||
+ virtual VMOp_Type type() const { return VMOp_PrintClasses; }
|
||||
+
|
||||
+ virtual void doit() {
|
||||
+ PrintClassClosure closure(_out, _verbose);
|
||||
+ ClassLoaderDataGraph::classes_do(&closure);
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+void ClassesDCmd::execute(DCmdSource source, TRAPS) {
|
||||
+ VM_PrintClasses vmop(output(), _verbose.is_set());
|
||||
+ VMThread::execute(&vmop);
|
||||
+}
|
||||
+
|
||||
+int ClassesDCmd::num_arguments() {
|
||||
+ ResourceMark rm;
|
||||
+ ClassesDCmd* dcmd = new ClassesDCmd(NULL, false);
|
||||
+ if (dcmd != NULL) {
|
||||
+ DCmdMark mark(dcmd);
|
||||
+ return dcmd->_dcmdparser.num_arguments();
|
||||
+ } else {
|
||||
+ return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
#define DEFAULT_COLUMNS "InstBytes,KlassBytes,CpAll,annotations,MethodCount,Bytecodes,MethodAll,ROAll,RWAll,Total"
|
||||
ClassStatsDCmd::ClassStatsDCmd(outputStream* output, bool heap) :
|
||||
DCmdWithParser(output, heap),
|
||||
diff --git a/hotspot/src/share/vm/services/diagnosticCommand.hpp b/hotspot/src/share/vm/services/diagnosticCommand.hpp
|
||||
index e28011f..f86ab5f 100644
|
||||
--- a/hotspot/src/share/vm/services/diagnosticCommand.hpp
|
||||
+++ b/hotspot/src/share/vm/services/diagnosticCommand.hpp
|
||||
@@ -314,6 +314,29 @@ public:
|
||||
virtual void execute(DCmdSource source, TRAPS);
|
||||
};
|
||||
|
||||
+class ClassesDCmd : public DCmdWithParser {
|
||||
+protected:
|
||||
+ DCmdArgument<bool> _verbose;
|
||||
+public:
|
||||
+ ClassesDCmd(outputStream* output, bool heap);
|
||||
+ static const char* name() {
|
||||
+ return "VM.classes";
|
||||
+ }
|
||||
+ static const char* description() {
|
||||
+ return "Print all loaded classes";
|
||||
+ }
|
||||
+ static const char* impact() {
|
||||
+ return "Medium: Depends on number of loaded classes.";
|
||||
+ }
|
||||
+ static const JavaPermission permission() {
|
||||
+ JavaPermission p = {"java.lang.management.ManagementPermission",
|
||||
+ "monitor", NULL};
|
||||
+ return p;
|
||||
+ }
|
||||
+ static int num_arguments();
|
||||
+ virtual void execute(DCmdSource source, TRAPS);
|
||||
+};
|
||||
+
|
||||
class ClassStatsDCmd : public DCmdWithParser {
|
||||
protected:
|
||||
DCmdArgument<bool> _all;
|
||||
diff --git a/hotspot/test/runtime/CommandLine/PrintClasses.java b/hotspot/test/runtime/CommandLine/PrintClasses.java
|
||||
new file mode 100644
|
||||
index 0000000..7c1d4db
|
||||
--- /dev/null
|
||||
+++ b/hotspot/test/runtime/CommandLine/PrintClasses.java
|
||||
@@ -0,0 +1,51 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2022, Alibaba Group Holding Limited. All rights reserved.
|
||||
+ * Copyright (c) 2022, Huawei Technologies Co., Ltd. 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
|
||||
+ * under the terms of the GNU General Public License version 2 only, as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
+ * version 2 for more details (a copy is included in the LICENSE file that
|
||||
+ * accompanied this code).
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License version
|
||||
+ * 2 along with this work; if not, write to the Free Software Foundation,
|
||||
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
+ *
|
||||
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
+ * or visit www.oracle.com if you need additional information or have any
|
||||
+ * questions.
|
||||
+ */
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * @test
|
||||
+ * @bug 8275775
|
||||
+ * @summary Test jcmd VM.classes
|
||||
+ * @library /testlibrary
|
||||
+ * @run main/othervm PrintClasses
|
||||
+ */
|
||||
+
|
||||
+import com.oracle.java.testlibrary.*;
|
||||
+
|
||||
+public class PrintClasses {
|
||||
+ public static void main(String args[]) throws Exception {
|
||||
+ String pid = Integer.toString(ProcessTools.getProcessId());
|
||||
+ ProcessBuilder pb = new ProcessBuilder();
|
||||
+
|
||||
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.classes"});
|
||||
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
|
||||
+ output.shouldNotContain("instance size");
|
||||
+ output.shouldContain(PrintClasses.class.getSimpleName());
|
||||
+
|
||||
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.classes", "-verbose"});
|
||||
+ output = new OutputAnalyzer(pb.start());
|
||||
+ output.shouldContain("instance size");
|
||||
+ output.shouldContain(PrintClasses.class.getSimpleName());
|
||||
+ }
|
||||
+}
|
||||
\ No newline at end of file
|
||||
--
|
||||
1.8.3.1
|
||||
1503
8293114-GC-should-trim-the-native-heap-and-bug-fix.patch
Normal file
1503
8293114-GC-should-trim-the-native-heap-and-bug-fix.patch
Normal file
File diff suppressed because it is too large
Load Diff
526
8294357-tz-Update-Timezone-Data-to-2022d.patch
Normal file
526
8294357-tz-Update-Timezone-Data-to-2022d.patch
Normal file
@ -0,0 +1,526 @@
|
||||
From 78c19b03f00f61f673311cf3c70a21ce25933eec Mon Sep 17 00:00:00 2001
|
||||
From: eapen <zhangyipeng7@huawei.com>
|
||||
Date: Wed, 30 Nov 2022 11:39:58 +0000
|
||||
Subject: [PATCH 07/33] I68TO2: 8294357: (tz) Update Timezone Data to 2022d
|
||||
---
|
||||
jdk/make/data/tzdata/VERSION | 2 +-
|
||||
jdk/make/data/tzdata/asia | 30 +++++++----
|
||||
jdk/make/data/tzdata/backward | 2 +
|
||||
jdk/make/data/tzdata/europe | 58 ++++------------------
|
||||
jdk/make/data/tzdata/southamerica | 10 +++-
|
||||
jdk/make/data/tzdata/zone.tab | 2 -
|
||||
.../classes/sun/util/calendar/ZoneInfoFile.java | 9 +---
|
||||
jdk/test/java/util/TimeZone/TimeZoneData/VERSION | 2 +-
|
||||
.../java/util/TimeZone/TimeZoneData/aliases.txt | 2 +
|
||||
.../util/TimeZone/TimeZoneData/displaynames.txt | 2 -
|
||||
jdk/test/sun/util/calendar/zi/TestZoneInfo310.java | 15 ++++--
|
||||
jdk/test/sun/util/calendar/zi/tzdata/VERSION | 2 +-
|
||||
jdk/test/sun/util/calendar/zi/tzdata/asia | 30 +++++++----
|
||||
jdk/test/sun/util/calendar/zi/tzdata/backward | 2 +
|
||||
jdk/test/sun/util/calendar/zi/tzdata/europe | 58 ++++------------------
|
||||
jdk/test/sun/util/calendar/zi/tzdata/southamerica | 10 +++-
|
||||
jdk/test/sun/util/calendar/zi/tzdata/zone.tab | 2 -
|
||||
17 files changed, 99 insertions(+), 139 deletions(-)
|
||||
|
||||
diff --git a/jdk/make/data/tzdata/VERSION b/jdk/make/data/tzdata/VERSION
|
||||
index decb871..889d0e6 100644
|
||||
--- a/jdk/make/data/tzdata/VERSION
|
||||
+++ b/jdk/make/data/tzdata/VERSION
|
||||
@@ -21,4 +21,4 @@
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
-tzdata2022c
|
||||
+tzdata2022d
|
||||
diff --git a/jdk/make/data/tzdata/asia b/jdk/make/data/tzdata/asia
|
||||
index 6cb6d2c..1dc7d34 100644
|
||||
--- a/jdk/make/data/tzdata/asia
|
||||
+++ b/jdk/make/data/tzdata/asia
|
||||
@@ -3398,10 +3398,6 @@ Zone Asia/Karachi 4:28:12 - LMT 1907
|
||||
# The winter time in 2015 started on October 23 at 01:00.
|
||||
# https://wafa.ps/ar_page.aspx?id=CgpCdYa670694628582aCgpCdY
|
||||
# http://www.palestinecabinet.gov.ps/portal/meeting/details/27583
|
||||
-#
|
||||
-# From Paul Eggert (2019-04-10):
|
||||
-# For now, guess spring-ahead transitions are at 00:00 on the Saturday
|
||||
-# preceding March's last Sunday (i.e., Sat>=24).
|
||||
|
||||
# From P Chan (2021-10-18):
|
||||
# http://wafa.ps/Pages/Details/34701
|
||||
@@ -3418,6 +3414,18 @@ Zone Asia/Karachi 4:28:12 - LMT 1907
|
||||
# From Heba Hamad (2022-03-10):
|
||||
# summer time will begin in Palestine from Sunday 03-27-2022, 00:00 AM.
|
||||
|
||||
+# From Heba Hamad (2022-08-30):
|
||||
+# winter time will begin in Palestine from Saturday 10-29, 02:00 AM by
|
||||
+# 60 minutes backwards. Also the state of Palestine adopted the summer
|
||||
+# and winter time for the years: 2023,2024,2025,2026 ...
|
||||
+# https://mm.icann.org/pipermail/tz/attachments/20220830/9f024566/Time-0001.pdf
|
||||
+# (2022-08-31): ... the Saturday before the last Sunday in March and October
|
||||
+# at 2:00 AM ,for the years from 2023 to 2026.
|
||||
+# (2022-09-05): https://mtit.pna.ps/Site/New/1453
|
||||
+#
|
||||
+# From Paul Eggert (2022-08-31):
|
||||
+# For now, assume that this rule will also be used after 2026.
|
||||
+
|
||||
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
|
||||
Rule EgyptAsia 1957 only - May 10 0:00 1:00 S
|
||||
Rule EgyptAsia 1957 1958 - Oct 1 0:00 0 -
|
||||
@@ -3448,14 +3456,16 @@ Rule Palestine 2013 only - Sep 27 0:00 0 -
|
||||
Rule Palestine 2014 only - Oct 24 0:00 0 -
|
||||
Rule Palestine 2015 only - Mar 28 0:00 1:00 S
|
||||
Rule Palestine 2015 only - Oct 23 1:00 0 -
|
||||
-Rule Palestine 2016 2018 - Mar Sat>=24 1:00 1:00 S
|
||||
-Rule Palestine 2016 2018 - Oct Sat>=24 1:00 0 -
|
||||
+Rule Palestine 2016 2018 - Mar Sat<=30 1:00 1:00 S
|
||||
+Rule Palestine 2016 2018 - Oct Sat<=30 1:00 0 -
|
||||
Rule Palestine 2019 only - Mar 29 0:00 1:00 S
|
||||
-Rule Palestine 2019 only - Oct Sat>=24 0:00 0 -
|
||||
-Rule Palestine 2020 2021 - Mar Sat>=24 0:00 1:00 S
|
||||
+Rule Palestine 2019 only - Oct Sat<=30 0:00 0 -
|
||||
+Rule Palestine 2020 2021 - Mar Sat<=30 0:00 1:00 S
|
||||
Rule Palestine 2020 only - Oct 24 1:00 0 -
|
||||
-Rule Palestine 2021 max - Oct Fri>=23 1:00 0 -
|
||||
-Rule Palestine 2022 max - Mar Sun>=25 0:00 1:00 S
|
||||
+Rule Palestine 2021 only - Oct 29 1:00 0 -
|
||||
+Rule Palestine 2022 only - Mar 27 0:00 1:00 S
|
||||
+Rule Palestine 2022 max - Oct Sat<=30 2:00 0 -
|
||||
+Rule Palestine 2023 max - Mar Sat<=30 2:00 1:00 S
|
||||
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
Zone Asia/Gaza 2:17:52 - LMT 1900 Oct
|
||||
diff --git a/jdk/make/data/tzdata/backward b/jdk/make/data/tzdata/backward
|
||||
index d4a29e8..7765d99 100644
|
||||
--- a/jdk/make/data/tzdata/backward
|
||||
+++ b/jdk/make/data/tzdata/backward
|
||||
@@ -113,6 +113,8 @@ Link Etc/UTC Etc/UCT
|
||||
Link Europe/London Europe/Belfast
|
||||
Link Europe/Kyiv Europe/Kiev
|
||||
Link Europe/Chisinau Europe/Tiraspol
|
||||
+Link Europe/Kyiv Europe/Uzhgorod
|
||||
+Link Europe/Kyiv Europe/Zaporozhye
|
||||
Link Europe/London GB
|
||||
Link Europe/London GB-Eire
|
||||
Link Etc/GMT GMT+0
|
||||
diff --git a/jdk/make/data/tzdata/europe b/jdk/make/data/tzdata/europe
|
||||
index f7eb7a3..9e0a538 100644
|
||||
--- a/jdk/make/data/tzdata/europe
|
||||
+++ b/jdk/make/data/tzdata/europe
|
||||
@@ -2638,10 +2638,14 @@ Zone Europe/Simferopol 2:16:24 - LMT 1880
|
||||
# From Alexander Krivenyshev (2014-03-17):
|
||||
# time change at 2:00 (2am) on March 30, 2014
|
||||
# https://vz.ru/news/2014/3/17/677464.html
|
||||
-# From Paul Eggert (2014-03-30):
|
||||
-# Simferopol and Sevastopol reportedly changed their central town clocks
|
||||
-# late the previous day, but this appears to have been ceremonial
|
||||
-# and the discrepancies are small enough to not worry about.
|
||||
+# From Tim Parenti (2022-07-01), per Paul Eggert (2014-03-30):
|
||||
+# The clocks at the railway station in Simferopol were put forward from 22:00
|
||||
+# to 24:00 the previous day in a "symbolic ceremony"; however, per
|
||||
+# contemporaneous news reports, "ordinary Crimeans [made] the daylight savings
|
||||
+# time switch at 2am" on Sunday.
|
||||
+# https://www.business-standard.com/article/pti-stories/crimea-to-set-clocks-to-russia-time-114033000014_1.html
|
||||
+# https://www.reuters.com/article/us-ukraine-crisis-crimea-time/crimea-switches-to-moscow-time-amid-incorporation-frenzy-idUKBREA2S0LT20140329
|
||||
+# https://www.bbc.com/news/av/world-europe-26806583
|
||||
2:00 EU EE%sT 2014 Mar 30 2:00
|
||||
4:00 - MSK 2014 Oct 26 2:00s
|
||||
3:00 - MSK
|
||||
@@ -3774,8 +3778,8 @@ Link Europe/Istanbul Asia/Istanbul # Istanbul is in both continents.
|
||||
# US colleague David Cochrane) are still trying to get more
|
||||
# information upon these local deviations from Kiev rules.
|
||||
#
|
||||
-# From Paul Eggert (2022-02-08):
|
||||
-# For now, assume that Ukraine's other three zones followed the same rules,
|
||||
+# From Paul Eggert (2022-08-27):
|
||||
+# For now, assume that Ukraine's zones all followed the same rules,
|
||||
# except that Crimea switched to Moscow time in 1994 as described elsewhere.
|
||||
|
||||
# From Igor Karpov, who works for the Ukrainian Ministry of Justice,
|
||||
@@ -3845,21 +3849,7 @@ Link Europe/Istanbul Asia/Istanbul # Istanbul is in both continents.
|
||||
# * Ukrainian Government's Resolution of 20.03.1992, No. 139.
|
||||
# http://www.uazakon.com/documents/date_8u/pg_grcasa.htm
|
||||
|
||||
-# From Paul Eggert (2022-04-12):
|
||||
-# As is usual in tzdb, Ukrainian zones use the most common English spellings.
|
||||
-# In particular, tzdb's name Europe/Kyiv uses the most common spelling in
|
||||
-# English for Ukraine's capital. Although tzdb's former name was Europe/Kiev,
|
||||
-# "Kyiv" is now more common due to widespread reporting of the current conflict.
|
||||
-# Conversely, tzdb continues to use the names Europe/Uzhgorod and
|
||||
-# Europe/Zaporozhye; this is similar to tzdb's use of Europe/Prague, which is
|
||||
-# certainly wrong as a transliteration of the Czech "Praha".
|
||||
-# English-language spelling of Ukrainian names is in flux, and
|
||||
-# some day "Uzhhorod" or "Zaporizhzhia" may become substantially more
|
||||
-# common in English; in the meantime, do not change these
|
||||
-# English spellings as that means less disruption for our users.
|
||||
-
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
-# This represents most of Ukraine. See above for the spelling of "Kyiv".
|
||||
Zone Europe/Kyiv 2:02:04 - LMT 1880
|
||||
2:02:04 - KMT 1924 May 2 # Kyiv Mean Time
|
||||
2:00 - EET 1930 Jun 21
|
||||
@@ -3869,34 +3859,6 @@ Zone Europe/Kyiv 2:02:04 - LMT 1880
|
||||
2:00 1:00 EEST 1991 Sep 29 3:00
|
||||
2:00 C-Eur EE%sT 1996 May 13
|
||||
2:00 EU EE%sT
|
||||
-# Transcarpathia used CET 1990/1991.
|
||||
-# "Uzhhorod" is the transliteration of the Rusyn/Ukrainian pronunciation, but
|
||||
-# "Uzhgorod" is more common in English.
|
||||
-Zone Europe/Uzhgorod 1:29:12 - LMT 1890 Oct
|
||||
- 1:00 - CET 1940
|
||||
- 1:00 C-Eur CE%sT 1944 Oct
|
||||
- 1:00 1:00 CEST 1944 Oct 26
|
||||
- 1:00 - CET 1945 Jun 29
|
||||
- 3:00 Russia MSK/MSD 1990
|
||||
- 3:00 - MSK 1990 Jul 1 2:00
|
||||
- 1:00 - CET 1991 Mar 31 3:00
|
||||
- 2:00 - EET 1992 Mar 20
|
||||
- 2:00 C-Eur EE%sT 1996 May 13
|
||||
- 2:00 EU EE%sT
|
||||
-# Zaporozh'ye and eastern Lugansk oblasts observed DST 1990/1991.
|
||||
-# "Zaporizhzhia" is the transliteration of the Ukrainian name, but
|
||||
-# "Zaporozh'ye" is more common in English. Use the common English
|
||||
-# spelling, except omit the apostrophe as it is not allowed in
|
||||
-# portable Posix file names.
|
||||
-Zone Europe/Zaporozhye 2:20:40 - LMT 1880
|
||||
- 2:20 - +0220 1924 May 2
|
||||
- 2:00 - EET 1930 Jun 21
|
||||
- 3:00 - MSK 1941 Aug 25
|
||||
- 1:00 C-Eur CE%sT 1943 Oct 25
|
||||
- 3:00 Russia MSK/MSD 1991 Mar 31 2:00
|
||||
- 2:00 E-Eur EE%sT 1992 Mar 20
|
||||
- 2:00 C-Eur EE%sT 1996 May 13
|
||||
- 2:00 EU EE%sT
|
||||
|
||||
# Vatican City
|
||||
# See Europe/Rome.
|
||||
diff --git a/jdk/make/data/tzdata/southamerica b/jdk/make/data/tzdata/southamerica
|
||||
index 13ec081..3c0e0e2 100644
|
||||
--- a/jdk/make/data/tzdata/southamerica
|
||||
+++ b/jdk/make/data/tzdata/southamerica
|
||||
@@ -1332,8 +1332,14 @@ Zone America/Rio_Branco -4:31:12 - LMT 1914
|
||||
# for America/Santiago will start on midnight of September 11th;
|
||||
# and will end on April 1st, 2023. Magallanes region (America/Punta_Arenas)
|
||||
# will keep UTC -3 "indefinitely"... This is because on September 4th
|
||||
-# we will have a voting whether to approve a new Constitution....
|
||||
-# https://www.interior.gob.cl/noticias/2022/08/09/comunicado-el-proximo-sabado-10-de-septiembre-los-relojes-se-deben-adelantar-una-hora/
|
||||
+# we will have a voting whether to approve a new Constitution.
|
||||
+#
|
||||
+# From Eduardo Romero Urra (2022-08-17):
|
||||
+# https://www.diariooficial.interior.gob.cl/publicaciones/2022/08/13/43327/01/2172567.pdf
|
||||
+#
|
||||
+# From Paul Eggert (2022-08-17):
|
||||
+# Although the presidential decree stops at fall 2026, assume that
|
||||
+# similar DST rules will continue thereafter.
|
||||
|
||||
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
|
||||
Rule Chile 1927 1931 - Sep 1 0:00 1:00 -
|
||||
diff --git a/jdk/make/data/tzdata/zone.tab b/jdk/make/data/tzdata/zone.tab
|
||||
index 51b65fa..ee02519 100644
|
||||
--- a/jdk/make/data/tzdata/zone.tab
|
||||
+++ b/jdk/make/data/tzdata/zone.tab
|
||||
@@ -424,8 +424,6 @@ TV -0831+17913 Pacific/Funafuti
|
||||
TW +2503+12130 Asia/Taipei
|
||||
TZ -0648+03917 Africa/Dar_es_Salaam
|
||||
UA +5026+03031 Europe/Kyiv Ukraine (most areas)
|
||||
-UA +4837+02218 Europe/Uzhgorod Transcarpathia
|
||||
-UA +4750+03510 Europe/Zaporozhye Zaporozhye and east Lugansk
|
||||
UG +0019+03225 Africa/Kampala
|
||||
UM +2813-17722 Pacific/Midway Midway Islands
|
||||
UM +1917+16637 Pacific/Wake Wake Island
|
||||
diff --git a/jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java b/jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java
|
||||
index 43bddd5..4b84cda 100644
|
||||
--- a/jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java
|
||||
+++ b/jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java
|
||||
@@ -573,12 +573,8 @@ public final class ZoneInfoFile {
|
||||
// we can then pass in the dom = -1, dow > 0 into ZoneInfo
|
||||
//
|
||||
// hacking, assume the >=24 is the result of ZRB optimization for
|
||||
- // "last", it works for now. From tzdata2020d this hacking
|
||||
- // will not work for Asia/Gaza and Asia/Hebron which follow
|
||||
- // Palestine DST rules.
|
||||
- if (dom < 0 || dom >= 24 &&
|
||||
- !(zoneId.equals("Asia/Gaza") ||
|
||||
- zoneId.equals("Asia/Hebron"))) {
|
||||
+ // "last", it works for now.
|
||||
+ if (dom < 0 || dom >= 24) {
|
||||
params[1] = -1;
|
||||
params[2] = toCalendarDOW[dow];
|
||||
} else {
|
||||
@@ -600,7 +596,6 @@ public final class ZoneInfoFile {
|
||||
params[7] = 0;
|
||||
} else {
|
||||
// hacking: see comment above
|
||||
- // No need of hacking for Asia/Gaza and Asia/Hebron from tz2021e
|
||||
if (dom < 0 || dom >= 24) {
|
||||
params[6] = -1;
|
||||
params[7] = toCalendarDOW[dow];
|
||||
diff --git a/jdk/test/java/util/TimeZone/TimeZoneData/VERSION b/jdk/test/java/util/TimeZone/TimeZoneData/VERSION
|
||||
index c32bee3..7147016 100644
|
||||
--- a/jdk/test/java/util/TimeZone/TimeZoneData/VERSION
|
||||
+++ b/jdk/test/java/util/TimeZone/TimeZoneData/VERSION
|
||||
@@ -1 +1 @@
|
||||
-tzdata2022c
|
||||
+tzdata2022d
|
||||
diff --git a/jdk/test/java/util/TimeZone/TimeZoneData/aliases.txt b/jdk/test/java/util/TimeZone/TimeZoneData/aliases.txt
|
||||
index a5e6428..e3ce742 100644
|
||||
--- a/jdk/test/java/util/TimeZone/TimeZoneData/aliases.txt
|
||||
+++ b/jdk/test/java/util/TimeZone/TimeZoneData/aliases.txt
|
||||
@@ -183,6 +183,8 @@ Link Etc/UTC Etc/UCT
|
||||
Link Europe/London Europe/Belfast
|
||||
Link Europe/Kyiv Europe/Kiev
|
||||
Link Europe/Chisinau Europe/Tiraspol
|
||||
+Link Europe/Kyiv Europe/Uzhgorod
|
||||
+Link Europe/Kyiv Europe/Zaporozhye
|
||||
Link Europe/London GB
|
||||
Link Europe/London GB-Eire
|
||||
Link Etc/GMT GMT+0
|
||||
diff --git a/jdk/test/java/util/TimeZone/TimeZoneData/displaynames.txt b/jdk/test/java/util/TimeZone/TimeZoneData/displaynames.txt
|
||||
index fc14853..b382395 100644
|
||||
--- a/jdk/test/java/util/TimeZone/TimeZoneData/displaynames.txt
|
||||
+++ b/jdk/test/java/util/TimeZone/TimeZoneData/displaynames.txt
|
||||
@@ -163,11 +163,9 @@ Europe/Simferopol MSK
|
||||
Europe/Sofia EET EEST
|
||||
Europe/Tallinn EET EEST
|
||||
Europe/Tirane CET CEST
|
||||
-Europe/Uzhgorod EET EEST
|
||||
Europe/Vienna CET CEST
|
||||
Europe/Vilnius EET EEST
|
||||
Europe/Warsaw CET CEST
|
||||
-Europe/Zaporozhye EET EEST
|
||||
Europe/Zurich CET CEST
|
||||
HST HST
|
||||
MET MET MEST
|
||||
diff --git a/jdk/test/sun/util/calendar/zi/TestZoneInfo310.java b/jdk/test/sun/util/calendar/zi/TestZoneInfo310.java
|
||||
index 3aad69f..c682531 100644
|
||||
--- a/jdk/test/sun/util/calendar/zi/TestZoneInfo310.java
|
||||
+++ b/jdk/test/sun/util/calendar/zi/TestZoneInfo310.java
|
||||
@@ -173,10 +173,19 @@ public class TestZoneInfo310 {
|
||||
* Temporary ignoring the failing TimeZones which are having zone
|
||||
* rules defined till year 2037 and/or above and have negative DST
|
||||
* save time in IANA tzdata. This bug is tracked via JDK-8223388.
|
||||
+ *
|
||||
+ * Tehran/Iran rule has rules beyond 2037, in which javazic assumes
|
||||
+ * to be the last year. Thus javazic's rule is based on year 2037
|
||||
+ * (Mar 20th/Sep 20th are the cutover dates), while the real rule
|
||||
+ * has year 2087 where Mar 21st/Sep 21st are the cutover dates.
|
||||
*/
|
||||
- if (zid.equals("Africa/Casablanca") || zid.equals("Africa/El_Aaiun")
|
||||
- || zid.equals("Asia/Tehran") || zid.equals("Iran")) {
|
||||
- continue;
|
||||
+ if (zid.equals("Africa/Casablanca") || // uses "Morocco" rule
|
||||
+ zid.equals("Africa/El_Aaiun") || // uses "Morocco" rule
|
||||
+ zid.equals("Asia/Tehran") || // last rule mismatch
|
||||
+ zid.equals("Asia/Gaza") || // uses "Palestine" rule
|
||||
+ zid.equals("Asia/Hebron") || // uses "Palestine" rule
|
||||
+ zid.equals("Iran")) { // last rule mismatch
|
||||
+ continue;
|
||||
}
|
||||
if (! zi.equalsTo(ziOLD)) {
|
||||
System.out.println(zi.diffsTo(ziOLD));
|
||||
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/VERSION b/jdk/test/sun/util/calendar/zi/tzdata/VERSION
|
||||
index decb871..889d0e6 100644
|
||||
--- a/jdk/test/sun/util/calendar/zi/tzdata/VERSION
|
||||
+++ b/jdk/test/sun/util/calendar/zi/tzdata/VERSION
|
||||
@@ -21,4 +21,4 @@
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
-tzdata2022c
|
||||
+tzdata2022d
|
||||
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/asia b/jdk/test/sun/util/calendar/zi/tzdata/asia
|
||||
index 6cb6d2c..1dc7d34 100644
|
||||
--- a/jdk/test/sun/util/calendar/zi/tzdata/asia
|
||||
+++ b/jdk/test/sun/util/calendar/zi/tzdata/asia
|
||||
@@ -3398,10 +3398,6 @@ Zone Asia/Karachi 4:28:12 - LMT 1907
|
||||
# The winter time in 2015 started on October 23 at 01:00.
|
||||
# https://wafa.ps/ar_page.aspx?id=CgpCdYa670694628582aCgpCdY
|
||||
# http://www.palestinecabinet.gov.ps/portal/meeting/details/27583
|
||||
-#
|
||||
-# From Paul Eggert (2019-04-10):
|
||||
-# For now, guess spring-ahead transitions are at 00:00 on the Saturday
|
||||
-# preceding March's last Sunday (i.e., Sat>=24).
|
||||
|
||||
# From P Chan (2021-10-18):
|
||||
# http://wafa.ps/Pages/Details/34701
|
||||
@@ -3418,6 +3414,18 @@ Zone Asia/Karachi 4:28:12 - LMT 1907
|
||||
# From Heba Hamad (2022-03-10):
|
||||
# summer time will begin in Palestine from Sunday 03-27-2022, 00:00 AM.
|
||||
|
||||
+# From Heba Hamad (2022-08-30):
|
||||
+# winter time will begin in Palestine from Saturday 10-29, 02:00 AM by
|
||||
+# 60 minutes backwards. Also the state of Palestine adopted the summer
|
||||
+# and winter time for the years: 2023,2024,2025,2026 ...
|
||||
+# https://mm.icann.org/pipermail/tz/attachments/20220830/9f024566/Time-0001.pdf
|
||||
+# (2022-08-31): ... the Saturday before the last Sunday in March and October
|
||||
+# at 2:00 AM ,for the years from 2023 to 2026.
|
||||
+# (2022-09-05): https://mtit.pna.ps/Site/New/1453
|
||||
+#
|
||||
+# From Paul Eggert (2022-08-31):
|
||||
+# For now, assume that this rule will also be used after 2026.
|
||||
+
|
||||
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
|
||||
Rule EgyptAsia 1957 only - May 10 0:00 1:00 S
|
||||
Rule EgyptAsia 1957 1958 - Oct 1 0:00 0 -
|
||||
@@ -3448,14 +3456,16 @@ Rule Palestine 2013 only - Sep 27 0:00 0 -
|
||||
Rule Palestine 2014 only - Oct 24 0:00 0 -
|
||||
Rule Palestine 2015 only - Mar 28 0:00 1:00 S
|
||||
Rule Palestine 2015 only - Oct 23 1:00 0 -
|
||||
-Rule Palestine 2016 2018 - Mar Sat>=24 1:00 1:00 S
|
||||
-Rule Palestine 2016 2018 - Oct Sat>=24 1:00 0 -
|
||||
+Rule Palestine 2016 2018 - Mar Sat<=30 1:00 1:00 S
|
||||
+Rule Palestine 2016 2018 - Oct Sat<=30 1:00 0 -
|
||||
Rule Palestine 2019 only - Mar 29 0:00 1:00 S
|
||||
-Rule Palestine 2019 only - Oct Sat>=24 0:00 0 -
|
||||
-Rule Palestine 2020 2021 - Mar Sat>=24 0:00 1:00 S
|
||||
+Rule Palestine 2019 only - Oct Sat<=30 0:00 0 -
|
||||
+Rule Palestine 2020 2021 - Mar Sat<=30 0:00 1:00 S
|
||||
Rule Palestine 2020 only - Oct 24 1:00 0 -
|
||||
-Rule Palestine 2021 max - Oct Fri>=23 1:00 0 -
|
||||
-Rule Palestine 2022 max - Mar Sun>=25 0:00 1:00 S
|
||||
+Rule Palestine 2021 only - Oct 29 1:00 0 -
|
||||
+Rule Palestine 2022 only - Mar 27 0:00 1:00 S
|
||||
+Rule Palestine 2022 max - Oct Sat<=30 2:00 0 -
|
||||
+Rule Palestine 2023 max - Mar Sat<=30 2:00 1:00 S
|
||||
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
Zone Asia/Gaza 2:17:52 - LMT 1900 Oct
|
||||
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/backward b/jdk/test/sun/util/calendar/zi/tzdata/backward
|
||||
index d4a29e8..7765d99 100644
|
||||
--- a/jdk/test/sun/util/calendar/zi/tzdata/backward
|
||||
+++ b/jdk/test/sun/util/calendar/zi/tzdata/backward
|
||||
@@ -113,6 +113,8 @@ Link Etc/UTC Etc/UCT
|
||||
Link Europe/London Europe/Belfast
|
||||
Link Europe/Kyiv Europe/Kiev
|
||||
Link Europe/Chisinau Europe/Tiraspol
|
||||
+Link Europe/Kyiv Europe/Uzhgorod
|
||||
+Link Europe/Kyiv Europe/Zaporozhye
|
||||
Link Europe/London GB
|
||||
Link Europe/London GB-Eire
|
||||
Link Etc/GMT GMT+0
|
||||
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/europe b/jdk/test/sun/util/calendar/zi/tzdata/europe
|
||||
index f7eb7a3..9e0a538 100644
|
||||
--- a/jdk/test/sun/util/calendar/zi/tzdata/europe
|
||||
+++ b/jdk/test/sun/util/calendar/zi/tzdata/europe
|
||||
@@ -2638,10 +2638,14 @@ Zone Europe/Simferopol 2:16:24 - LMT 1880
|
||||
# From Alexander Krivenyshev (2014-03-17):
|
||||
# time change at 2:00 (2am) on March 30, 2014
|
||||
# https://vz.ru/news/2014/3/17/677464.html
|
||||
-# From Paul Eggert (2014-03-30):
|
||||
-# Simferopol and Sevastopol reportedly changed their central town clocks
|
||||
-# late the previous day, but this appears to have been ceremonial
|
||||
-# and the discrepancies are small enough to not worry about.
|
||||
+# From Tim Parenti (2022-07-01), per Paul Eggert (2014-03-30):
|
||||
+# The clocks at the railway station in Simferopol were put forward from 22:00
|
||||
+# to 24:00 the previous day in a "symbolic ceremony"; however, per
|
||||
+# contemporaneous news reports, "ordinary Crimeans [made] the daylight savings
|
||||
+# time switch at 2am" on Sunday.
|
||||
+# https://www.business-standard.com/article/pti-stories/crimea-to-set-clocks-to-russia-time-114033000014_1.html
|
||||
+# https://www.reuters.com/article/us-ukraine-crisis-crimea-time/crimea-switches-to-moscow-time-amid-incorporation-frenzy-idUKBREA2S0LT20140329
|
||||
+# https://www.bbc.com/news/av/world-europe-26806583
|
||||
2:00 EU EE%sT 2014 Mar 30 2:00
|
||||
4:00 - MSK 2014 Oct 26 2:00s
|
||||
3:00 - MSK
|
||||
@@ -3774,8 +3778,8 @@ Link Europe/Istanbul Asia/Istanbul # Istanbul is in both continents.
|
||||
# US colleague David Cochrane) are still trying to get more
|
||||
# information upon these local deviations from Kiev rules.
|
||||
#
|
||||
-# From Paul Eggert (2022-02-08):
|
||||
-# For now, assume that Ukraine's other three zones followed the same rules,
|
||||
+# From Paul Eggert (2022-08-27):
|
||||
+# For now, assume that Ukraine's zones all followed the same rules,
|
||||
# except that Crimea switched to Moscow time in 1994 as described elsewhere.
|
||||
|
||||
# From Igor Karpov, who works for the Ukrainian Ministry of Justice,
|
||||
@@ -3845,21 +3849,7 @@ Link Europe/Istanbul Asia/Istanbul # Istanbul is in both continents.
|
||||
# * Ukrainian Government's Resolution of 20.03.1992, No. 139.
|
||||
# http://www.uazakon.com/documents/date_8u/pg_grcasa.htm
|
||||
|
||||
-# From Paul Eggert (2022-04-12):
|
||||
-# As is usual in tzdb, Ukrainian zones use the most common English spellings.
|
||||
-# In particular, tzdb's name Europe/Kyiv uses the most common spelling in
|
||||
-# English for Ukraine's capital. Although tzdb's former name was Europe/Kiev,
|
||||
-# "Kyiv" is now more common due to widespread reporting of the current conflict.
|
||||
-# Conversely, tzdb continues to use the names Europe/Uzhgorod and
|
||||
-# Europe/Zaporozhye; this is similar to tzdb's use of Europe/Prague, which is
|
||||
-# certainly wrong as a transliteration of the Czech "Praha".
|
||||
-# English-language spelling of Ukrainian names is in flux, and
|
||||
-# some day "Uzhhorod" or "Zaporizhzhia" may become substantially more
|
||||
-# common in English; in the meantime, do not change these
|
||||
-# English spellings as that means less disruption for our users.
|
||||
-
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
-# This represents most of Ukraine. See above for the spelling of "Kyiv".
|
||||
Zone Europe/Kyiv 2:02:04 - LMT 1880
|
||||
2:02:04 - KMT 1924 May 2 # Kyiv Mean Time
|
||||
2:00 - EET 1930 Jun 21
|
||||
@@ -3869,34 +3859,6 @@ Zone Europe/Kyiv 2:02:04 - LMT 1880
|
||||
2:00 1:00 EEST 1991 Sep 29 3:00
|
||||
2:00 C-Eur EE%sT 1996 May 13
|
||||
2:00 EU EE%sT
|
||||
-# Transcarpathia used CET 1990/1991.
|
||||
-# "Uzhhorod" is the transliteration of the Rusyn/Ukrainian pronunciation, but
|
||||
-# "Uzhgorod" is more common in English.
|
||||
-Zone Europe/Uzhgorod 1:29:12 - LMT 1890 Oct
|
||||
- 1:00 - CET 1940
|
||||
- 1:00 C-Eur CE%sT 1944 Oct
|
||||
- 1:00 1:00 CEST 1944 Oct 26
|
||||
- 1:00 - CET 1945 Jun 29
|
||||
- 3:00 Russia MSK/MSD 1990
|
||||
- 3:00 - MSK 1990 Jul 1 2:00
|
||||
- 1:00 - CET 1991 Mar 31 3:00
|
||||
- 2:00 - EET 1992 Mar 20
|
||||
- 2:00 C-Eur EE%sT 1996 May 13
|
||||
- 2:00 EU EE%sT
|
||||
-# Zaporozh'ye and eastern Lugansk oblasts observed DST 1990/1991.
|
||||
-# "Zaporizhzhia" is the transliteration of the Ukrainian name, but
|
||||
-# "Zaporozh'ye" is more common in English. Use the common English
|
||||
-# spelling, except omit the apostrophe as it is not allowed in
|
||||
-# portable Posix file names.
|
||||
-Zone Europe/Zaporozhye 2:20:40 - LMT 1880
|
||||
- 2:20 - +0220 1924 May 2
|
||||
- 2:00 - EET 1930 Jun 21
|
||||
- 3:00 - MSK 1941 Aug 25
|
||||
- 1:00 C-Eur CE%sT 1943 Oct 25
|
||||
- 3:00 Russia MSK/MSD 1991 Mar 31 2:00
|
||||
- 2:00 E-Eur EE%sT 1992 Mar 20
|
||||
- 2:00 C-Eur EE%sT 1996 May 13
|
||||
- 2:00 EU EE%sT
|
||||
|
||||
# Vatican City
|
||||
# See Europe/Rome.
|
||||
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/southamerica b/jdk/test/sun/util/calendar/zi/tzdata/southamerica
|
||||
index 13ec081..3c0e0e2 100644
|
||||
--- a/jdk/test/sun/util/calendar/zi/tzdata/southamerica
|
||||
+++ b/jdk/test/sun/util/calendar/zi/tzdata/southamerica
|
||||
@@ -1332,8 +1332,14 @@ Zone America/Rio_Branco -4:31:12 - LMT 1914
|
||||
# for America/Santiago will start on midnight of September 11th;
|
||||
# and will end on April 1st, 2023. Magallanes region (America/Punta_Arenas)
|
||||
# will keep UTC -3 "indefinitely"... This is because on September 4th
|
||||
-# we will have a voting whether to approve a new Constitution....
|
||||
-# https://www.interior.gob.cl/noticias/2022/08/09/comunicado-el-proximo-sabado-10-de-septiembre-los-relojes-se-deben-adelantar-una-hora/
|
||||
+# we will have a voting whether to approve a new Constitution.
|
||||
+#
|
||||
+# From Eduardo Romero Urra (2022-08-17):
|
||||
+# https://www.diariooficial.interior.gob.cl/publicaciones/2022/08/13/43327/01/2172567.pdf
|
||||
+#
|
||||
+# From Paul Eggert (2022-08-17):
|
||||
+# Although the presidential decree stops at fall 2026, assume that
|
||||
+# similar DST rules will continue thereafter.
|
||||
|
||||
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
|
||||
Rule Chile 1927 1931 - Sep 1 0:00 1:00 -
|
||||
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/zone.tab b/jdk/test/sun/util/calendar/zi/tzdata/zone.tab
|
||||
index 51b65fa..ee02519 100644
|
||||
--- a/jdk/test/sun/util/calendar/zi/tzdata/zone.tab
|
||||
+++ b/jdk/test/sun/util/calendar/zi/tzdata/zone.tab
|
||||
@@ -424,8 +424,6 @@ TV -0831+17913 Pacific/Funafuti
|
||||
TW +2503+12130 Asia/Taipei
|
||||
TZ -0648+03917 Africa/Dar_es_Salaam
|
||||
UA +5026+03031 Europe/Kyiv Ukraine (most areas)
|
||||
-UA +4837+02218 Europe/Uzhgorod Transcarpathia
|
||||
-UA +4750+03510 Europe/Zaporozhye Zaporozhye and east Lugansk
|
||||
UG +0019+03225 Africa/Kampala
|
||||
UM +2813-17722 Pacific/Midway Midway Islands
|
||||
UM +1917+16637 Pacific/Wake Wake Island
|
||||
--
|
||||
1.8.3.1
|
||||
4516
8296108-tz-Update-Timezone-Data-to-2022f.patch
Normal file
4516
8296108-tz-Update-Timezone-Data-to-2022f.patch
Normal file
File diff suppressed because it is too large
Load Diff
826
8296241-tz-Update-Timezone-Data-to-2022e.patch
Normal file
826
8296241-tz-Update-Timezone-Data-to-2022e.patch
Normal file
@ -0,0 +1,826 @@
|
||||
From d31b6120315ecc095ddffa7a5fb92c53bb70bc3b Mon Sep 17 00:00:00 2001
|
||||
From: eapen <zhangyipeng7@huawei.com>
|
||||
Date: Wed, 30 Nov 2022 14:57:07 +0000
|
||||
Subject: [PATCH 08/33] I68TO2: 8296241: (tz) Update Timezone Data to 2022e
|
||||
---
|
||||
jdk/make/data/tzdata/VERSION | 2 +-
|
||||
jdk/make/data/tzdata/asia | 36 +++++++---
|
||||
jdk/make/data/tzdata/europe | 2 +-
|
||||
jdk/make/data/tzdata/northamerica | 84 ++++++++++------------
|
||||
jdk/test/java/util/TimeZone/TimeZoneData/VERSION | 2 +-
|
||||
.../util/TimeZone/TimeZoneData/displaynames.txt | 2 -
|
||||
jdk/test/sun/util/calendar/zi/tzdata/VERSION | 2 +-
|
||||
jdk/test/sun/util/calendar/zi/tzdata/asia | 36 +++++++---
|
||||
jdk/test/sun/util/calendar/zi/tzdata/europe | 2 +-
|
||||
jdk/test/sun/util/calendar/zi/tzdata/northamerica | 84 ++++++++++------------
|
||||
10 files changed, 135 insertions(+), 117 deletions(-)
|
||||
|
||||
diff --git a/jdk/make/data/tzdata/VERSION b/jdk/make/data/tzdata/VERSION
|
||||
index 889d0e6..b8cb36e 100644
|
||||
--- a/jdk/make/data/tzdata/VERSION
|
||||
+++ b/jdk/make/data/tzdata/VERSION
|
||||
@@ -21,4 +21,4 @@
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
-tzdata2022d
|
||||
+tzdata2022e
|
||||
diff --git a/jdk/make/data/tzdata/asia b/jdk/make/data/tzdata/asia
|
||||
index 1dc7d34..f1771e4 100644
|
||||
--- a/jdk/make/data/tzdata/asia
|
||||
+++ b/jdk/make/data/tzdata/asia
|
||||
@@ -2254,6 +2254,17 @@ Zone Asia/Tokyo 9:18:59 - LMT 1887 Dec 31 15:00u
|
||||
# From the Arabic version, it seems to say it would be at midnight
|
||||
# (assume 24:00) on the last Thursday in February, starting from 2022.
|
||||
|
||||
+# From Issam Al-Zuwairi (2022-10-05):
|
||||
+# The Council of Ministers in Jordan decided Wednesday 5th October 2022,
|
||||
+# that daylight saving time (DST) will be throughout the year....
|
||||
+#
|
||||
+# From Brian Inglis (2022-10-06):
|
||||
+# https://petra.gov.jo/Include/InnerPage.jsp?ID=45567&lang=en&name=en_news
|
||||
+#
|
||||
+# From Paul Eggert (2022-10-05):
|
||||
+# Like Syria, model this as a transition from EEST +03 (DST) to plain +03
|
||||
+# (non-DST) at the point where DST would otherwise have ended.
|
||||
+
|
||||
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
|
||||
Rule Jordan 1973 only - Jun 6 0:00 1:00 S
|
||||
Rule Jordan 1973 1975 - Oct 1 0:00 0 -
|
||||
@@ -2285,11 +2296,12 @@ Rule Jordan 2005 only - Sep lastFri 0:00s 0 -
|
||||
Rule Jordan 2006 2011 - Oct lastFri 0:00s 0 -
|
||||
Rule Jordan 2013 only - Dec 20 0:00 0 -
|
||||
Rule Jordan 2014 2021 - Mar lastThu 24:00 1:00 S
|
||||
-Rule Jordan 2014 max - Oct lastFri 0:00s 0 -
|
||||
-Rule Jordan 2022 max - Feb lastThu 24:00 1:00 S
|
||||
+Rule Jordan 2014 2022 - Oct lastFri 0:00s 0 -
|
||||
+Rule Jordan 2022 only - Feb lastThu 24:00 1:00 S
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
Zone Asia/Amman 2:23:44 - LMT 1931
|
||||
- 2:00 Jordan EE%sT
|
||||
+ 2:00 Jordan EE%sT 2022 Oct 28 0:00s
|
||||
+ 3:00 - +03
|
||||
|
||||
|
||||
# Kazakhstan
|
||||
@@ -3838,19 +3850,27 @@ Rule Syria 2007 only - Nov Fri>=1 0:00 0 -
|
||||
# Our brief summary:
|
||||
# https://www.timeanddate.com/news/time/syria-dst-2012.html
|
||||
|
||||
-# From Arthur David Olson (2012-03-27):
|
||||
-# Assume last Friday in March going forward XXX.
|
||||
+# From Steffen Thorsen (2022-10-05):
|
||||
+# Syria is adopting year-round DST, starting this autumn....
|
||||
+# From https://www.enabbaladi.net/archives/607812
|
||||
+# "This [the decision] came after the weekly government meeting today,
|
||||
+# Tuesday 4 October ..."
|
||||
+#
|
||||
+# From Paul Eggert (2022-10-05):
|
||||
+# Like Jordan, model this as a transition from EEST +03 (DST) to plain +03
|
||||
+# (non-DST) at the point where DST would otherwise have ended.
|
||||
|
||||
Rule Syria 2008 only - Apr Fri>=1 0:00 1:00 S
|
||||
Rule Syria 2008 only - Nov 1 0:00 0 -
|
||||
Rule Syria 2009 only - Mar lastFri 0:00 1:00 S
|
||||
Rule Syria 2010 2011 - Apr Fri>=1 0:00 1:00 S
|
||||
-Rule Syria 2012 max - Mar lastFri 0:00 1:00 S
|
||||
-Rule Syria 2009 max - Oct lastFri 0:00 0 -
|
||||
+Rule Syria 2012 2022 - Mar lastFri 0:00 1:00 S
|
||||
+Rule Syria 2009 2022 - Oct lastFri 0:00 0 -
|
||||
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
Zone Asia/Damascus 2:25:12 - LMT 1920 # Dimashq
|
||||
- 2:00 Syria EE%sT
|
||||
+ 2:00 Syria EE%sT 2022 Oct 28 0:00
|
||||
+ 3:00 - +03
|
||||
|
||||
# Tajikistan
|
||||
# From Shanks & Pottenger.
|
||||
diff --git a/jdk/make/data/tzdata/europe b/jdk/make/data/tzdata/europe
|
||||
index 9e0a538..930cede 100644
|
||||
--- a/jdk/make/data/tzdata/europe
|
||||
+++ b/jdk/make/data/tzdata/europe
|
||||
@@ -3417,7 +3417,7 @@ Zone Europe/Madrid -0:14:44 - LMT 1901 Jan 1 0:00u
|
||||
0:00 Spain WE%sT 1940 Mar 16 23:00
|
||||
1:00 Spain CE%sT 1979
|
||||
1:00 EU CE%sT
|
||||
-Zone Africa/Ceuta -0:21:16 - LMT 1900 Dec 31 23:38:44
|
||||
+Zone Africa/Ceuta -0:21:16 - LMT 1901 Jan 1 0:00u
|
||||
0:00 - WET 1918 May 6 23:00
|
||||
0:00 1:00 WEST 1918 Oct 7 23:00
|
||||
0:00 - WET 1924
|
||||
diff --git a/jdk/make/data/tzdata/northamerica b/jdk/make/data/tzdata/northamerica
|
||||
index 114cef1..ce4ee74 100644
|
||||
--- a/jdk/make/data/tzdata/northamerica
|
||||
+++ b/jdk/make/data/tzdata/northamerica
|
||||
@@ -462,7 +462,7 @@ Rule Chicago 1922 1966 - Apr lastSun 2:00 1:00 D
|
||||
Rule Chicago 1922 1954 - Sep lastSun 2:00 0 S
|
||||
Rule Chicago 1955 1966 - Oct lastSun 2:00 0 S
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
-Zone America/Chicago -5:50:36 - LMT 1883 Nov 18 12:09:24
|
||||
+Zone America/Chicago -5:50:36 - LMT 1883 Nov 18 18:00u
|
||||
-6:00 US C%sT 1920
|
||||
-6:00 Chicago C%sT 1936 Mar 1 2:00
|
||||
-5:00 - EST 1936 Nov 15 2:00
|
||||
@@ -471,7 +471,7 @@ Zone America/Chicago -5:50:36 - LMT 1883 Nov 18 12:09:24
|
||||
-6:00 Chicago C%sT 1967
|
||||
-6:00 US C%sT
|
||||
# Oliver County, ND switched from mountain to central time on 1992-10-25.
|
||||
-Zone America/North_Dakota/Center -6:45:12 - LMT 1883 Nov 18 12:14:48
|
||||
+Zone America/North_Dakota/Center -6:45:12 - LMT 1883 Nov 18 19:00u
|
||||
-7:00 US M%sT 1992 Oct 25 2:00
|
||||
-6:00 US C%sT
|
||||
# Morton County, ND, switched from mountain to central time on
|
||||
@@ -481,7 +481,7 @@ Zone America/North_Dakota/Center -6:45:12 - LMT 1883 Nov 18 12:14:48
|
||||
# Jones, Mellette, and Todd Counties in South Dakota;
|
||||
# but in practice these other counties were already observing central time.
|
||||
# See <http://www.epa.gov/fedrgstr/EPA-IMPACT/2003/October/Day-28/i27056.htm>.
|
||||
-Zone America/North_Dakota/New_Salem -6:45:39 - LMT 1883 Nov 18 12:14:21
|
||||
+Zone America/North_Dakota/New_Salem -6:45:39 - LMT 1883 Nov 18 19:00u
|
||||
-7:00 US M%sT 2003 Oct 26 2:00
|
||||
-6:00 US C%sT
|
||||
|
||||
@@ -498,7 +498,7 @@ Zone America/North_Dakota/New_Salem -6:45:39 - LMT 1883 Nov 18 12:14:21
|
||||
# largest city in Mercer County). Google Maps places Beulah's city hall
|
||||
# at 47° 15' 51" N, 101° 46' 40" W, which yields an offset of 6h47'07".
|
||||
|
||||
-Zone America/North_Dakota/Beulah -6:47:07 - LMT 1883 Nov 18 12:12:53
|
||||
+Zone America/North_Dakota/Beulah -6:47:07 - LMT 1883 Nov 18 19:00u
|
||||
-7:00 US M%sT 2010 Nov 7 2:00
|
||||
-6:00 US C%sT
|
||||
|
||||
@@ -530,7 +530,7 @@ Rule Denver 1921 only - May 22 2:00 0 S
|
||||
Rule Denver 1965 1966 - Apr lastSun 2:00 1:00 D
|
||||
Rule Denver 1965 1966 - Oct lastSun 2:00 0 S
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
-Zone America/Denver -6:59:56 - LMT 1883 Nov 18 12:00:04
|
||||
+Zone America/Denver -6:59:56 - LMT 1883 Nov 18 19:00u
|
||||
-7:00 US M%sT 1920
|
||||
-7:00 Denver M%sT 1942
|
||||
-7:00 US M%sT 1946
|
||||
@@ -583,7 +583,7 @@ Rule CA 1950 1966 - Apr lastSun 1:00 1:00 D
|
||||
Rule CA 1950 1961 - Sep lastSun 2:00 0 S
|
||||
Rule CA 1962 1966 - Oct lastSun 2:00 0 S
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
-Zone America/Los_Angeles -7:52:58 - LMT 1883 Nov 18 12:07:02
|
||||
+Zone America/Los_Angeles -7:52:58 - LMT 1883 Nov 18 20:00u
|
||||
-8:00 US P%sT 1946
|
||||
-8:00 CA P%sT 1967
|
||||
-8:00 US P%sT
|
||||
@@ -845,7 +845,7 @@ Zone Pacific/Honolulu -10:31:26 - LMT 1896 Jan 13 12:00
|
||||
# Go with the Arizona State Library instead.
|
||||
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
-Zone America/Phoenix -7:28:18 - LMT 1883 Nov 18 11:31:42
|
||||
+Zone America/Phoenix -7:28:18 - LMT 1883 Nov 18 19:00u
|
||||
-7:00 US M%sT 1944 Jan 1 0:01
|
||||
-7:00 - MST 1944 Apr 1 0:01
|
||||
-7:00 US M%sT 1944 Oct 1 0:01
|
||||
@@ -873,7 +873,7 @@ Link America/Phoenix America/Creston
|
||||
# switched four weeks late in 1974.
|
||||
#
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
-Zone America/Boise -7:44:49 - LMT 1883 Nov 18 12:15:11
|
||||
+Zone America/Boise -7:44:49 - LMT 1883 Nov 18 20:00u
|
||||
-8:00 US P%sT 1923 May 13 2:00
|
||||
-7:00 US M%sT 1974
|
||||
-7:00 - MST 1974 Feb 3 2:00
|
||||
@@ -945,7 +945,7 @@ Rule Indianapolis 1941 only - Jun 22 2:00 1:00 D
|
||||
Rule Indianapolis 1941 1954 - Sep lastSun 2:00 0 S
|
||||
Rule Indianapolis 1946 1954 - Apr lastSun 2:00 1:00 D
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
-Zone America/Indiana/Indianapolis -5:44:38 - LMT 1883 Nov 18 12:15:22
|
||||
+Zone America/Indiana/Indianapolis -5:44:38 - LMT 1883 Nov 18 18:00u
|
||||
-6:00 US C%sT 1920
|
||||
-6:00 Indianapolis C%sT 1942
|
||||
-6:00 US C%sT 1946
|
||||
@@ -965,7 +965,7 @@ Rule Marengo 1951 only - Sep lastSun 2:00 0 S
|
||||
Rule Marengo 1954 1960 - Apr lastSun 2:00 1:00 D
|
||||
Rule Marengo 1954 1960 - Sep lastSun 2:00 0 S
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
-Zone America/Indiana/Marengo -5:45:23 - LMT 1883 Nov 18 12:14:37
|
||||
+Zone America/Indiana/Marengo -5:45:23 - LMT 1883 Nov 18 18:00u
|
||||
-6:00 US C%sT 1951
|
||||
-6:00 Marengo C%sT 1961 Apr 30 2:00
|
||||
-5:00 - EST 1969
|
||||
@@ -989,7 +989,7 @@ Rule Vincennes 1960 only - Oct lastSun 2:00 0 S
|
||||
Rule Vincennes 1961 only - Sep lastSun 2:00 0 S
|
||||
Rule Vincennes 1962 1963 - Oct lastSun 2:00 0 S
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
-Zone America/Indiana/Vincennes -5:50:07 - LMT 1883 Nov 18 12:09:53
|
||||
+Zone America/Indiana/Vincennes -5:50:07 - LMT 1883 Nov 18 18:00u
|
||||
-6:00 US C%sT 1946
|
||||
-6:00 Vincennes C%sT 1964 Apr 26 2:00
|
||||
-5:00 - EST 1969
|
||||
@@ -1009,7 +1009,7 @@ Rule Perry 1955 1960 - Sep lastSun 2:00 0 S
|
||||
Rule Perry 1956 1963 - Apr lastSun 2:00 1:00 D
|
||||
Rule Perry 1961 1963 - Oct lastSun 2:00 0 S
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
-Zone America/Indiana/Tell_City -5:47:03 - LMT 1883 Nov 18 12:12:57
|
||||
+Zone America/Indiana/Tell_City -5:47:03 - LMT 1883 Nov 18 18:00u
|
||||
-6:00 US C%sT 1946
|
||||
-6:00 Perry C%sT 1964 Apr 26 2:00
|
||||
-5:00 - EST 1967 Oct 29 2:00
|
||||
@@ -1026,7 +1026,7 @@ Rule Pike 1955 1960 - Sep lastSun 2:00 0 S
|
||||
Rule Pike 1956 1964 - Apr lastSun 2:00 1:00 D
|
||||
Rule Pike 1961 1964 - Oct lastSun 2:00 0 S
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
-Zone America/Indiana/Petersburg -5:49:07 - LMT 1883 Nov 18 12:10:53
|
||||
+Zone America/Indiana/Petersburg -5:49:07 - LMT 1883 Nov 18 18:00u
|
||||
-6:00 US C%sT 1955
|
||||
-6:00 Pike C%sT 1965 Apr 25 2:00
|
||||
-5:00 - EST 1966 Oct 30 2:00
|
||||
@@ -1048,7 +1048,7 @@ Rule Starke 1955 1956 - Oct lastSun 2:00 0 S
|
||||
Rule Starke 1957 1958 - Sep lastSun 2:00 0 S
|
||||
Rule Starke 1959 1961 - Oct lastSun 2:00 0 S
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
-Zone America/Indiana/Knox -5:46:30 - LMT 1883 Nov 18 12:13:30
|
||||
+Zone America/Indiana/Knox -5:46:30 - LMT 1883 Nov 18 18:00u
|
||||
-6:00 US C%sT 1947
|
||||
-6:00 Starke C%sT 1962 Apr 29 2:00
|
||||
-5:00 - EST 1963 Oct 27 2:00
|
||||
@@ -1064,7 +1064,7 @@ Rule Pulaski 1946 1954 - Sep lastSun 2:00 0 S
|
||||
Rule Pulaski 1955 1956 - Oct lastSun 2:00 0 S
|
||||
Rule Pulaski 1957 1960 - Sep lastSun 2:00 0 S
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
-Zone America/Indiana/Winamac -5:46:25 - LMT 1883 Nov 18 12:13:35
|
||||
+Zone America/Indiana/Winamac -5:46:25 - LMT 1883 Nov 18 18:00u
|
||||
-6:00 US C%sT 1946
|
||||
-6:00 Pulaski C%sT 1961 Apr 30 2:00
|
||||
-5:00 - EST 1969
|
||||
@@ -1075,7 +1075,7 @@ Zone America/Indiana/Winamac -5:46:25 - LMT 1883 Nov 18 12:13:35
|
||||
#
|
||||
# Switzerland County, Indiana, did not observe DST from 1973 through 2005.
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
-Zone America/Indiana/Vevay -5:40:16 - LMT 1883 Nov 18 12:19:44
|
||||
+Zone America/Indiana/Vevay -5:40:16 - LMT 1883 Nov 18 18:00u
|
||||
-6:00 US C%sT 1954 Apr 25 2:00
|
||||
-5:00 - EST 1969
|
||||
-5:00 US E%sT 1973
|
||||
@@ -1111,7 +1111,7 @@ Rule Louisville 1950 1961 - Apr lastSun 2:00 1:00 D
|
||||
Rule Louisville 1950 1955 - Sep lastSun 2:00 0 S
|
||||
Rule Louisville 1956 1961 - Oct lastSun 2:00 0 S
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
-Zone America/Kentucky/Louisville -5:43:02 - LMT 1883 Nov 18 12:16:58
|
||||
+Zone America/Kentucky/Louisville -5:43:02 - LMT 1883 Nov 18 18:00u
|
||||
-6:00 US C%sT 1921
|
||||
-6:00 Louisville C%sT 1942
|
||||
-6:00 US C%sT 1946
|
||||
@@ -1145,7 +1145,7 @@ Zone America/Kentucky/Louisville -5:43:02 - LMT 1883 Nov 18 12:16:58
|
||||
# Federal Register 65, 160 (2000-08-17), pp 50154-50158.
|
||||
# https://www.gpo.gov/fdsys/pkg/FR-2000-08-17/html/00-20854.htm
|
||||
#
|
||||
-Zone America/Kentucky/Monticello -5:39:24 - LMT 1883 Nov 18 12:20:36
|
||||
+Zone America/Kentucky/Monticello -5:39:24 - LMT 1883 Nov 18 18:00u
|
||||
-6:00 US C%sT 1946
|
||||
-6:00 - CST 1968
|
||||
-6:00 US C%sT 2000 Oct 29 2:00
|
||||
@@ -2640,6 +2640,8 @@ Zone America/Dawson -9:17:40 - LMT 1900 Aug 20
|
||||
# longitude they are located at.
|
||||
|
||||
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
|
||||
+Rule Mexico 1931 only - May 1 23:00 1:00 D
|
||||
+Rule Mexico 1931 only - Oct 1 0:00 0 S
|
||||
Rule Mexico 1939 only - Feb 5 0:00 1:00 D
|
||||
Rule Mexico 1939 only - Jun 25 0:00 0 S
|
||||
Rule Mexico 1940 only - Dec 9 0:00 1:00 D
|
||||
@@ -2656,13 +2658,13 @@ Rule Mexico 2002 max - Apr Sun>=1 2:00 1:00 D
|
||||
Rule Mexico 2002 max - Oct lastSun 2:00 0 S
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
# Quintana Roo; represented by Cancún
|
||||
-Zone America/Cancun -5:47:04 - LMT 1922 Jan 1 0:12:56
|
||||
+Zone America/Cancun -5:47:04 - LMT 1922 Jan 1 6:00u
|
||||
-6:00 - CST 1981 Dec 23
|
||||
-5:00 Mexico E%sT 1998 Aug 2 2:00
|
||||
-6:00 Mexico C%sT 2015 Feb 1 2:00
|
||||
-5:00 - EST
|
||||
# Campeche, Yucatán; represented by Mérida
|
||||
-Zone America/Merida -5:58:28 - LMT 1922 Jan 1 0:01:32
|
||||
+Zone America/Merida -5:58:28 - LMT 1922 Jan 1 6:00u
|
||||
-6:00 - CST 1981 Dec 23
|
||||
-5:00 - EST 1982 Dec 2
|
||||
-6:00 Mexico C%sT
|
||||
@@ -2676,23 +2678,21 @@ Zone America/Merida -5:58:28 - LMT 1922 Jan 1 0:01:32
|
||||
# See: Inicia mañana Horario de Verano en zona fronteriza, El Universal,
|
||||
# 2016-03-12
|
||||
# http://www.eluniversal.com.mx/articulo/estados/2016/03/12/inicia-manana-horario-de-verano-en-zona-fronteriza
|
||||
-Zone America/Matamoros -6:40:00 - LMT 1921 Dec 31 23:20:00
|
||||
+Zone America/Matamoros -6:30:00 - LMT 1922 Jan 1 6:00u
|
||||
-6:00 - CST 1988
|
||||
-6:00 US C%sT 1989
|
||||
-6:00 Mexico C%sT 2010
|
||||
-6:00 US C%sT
|
||||
# Durango; Coahuila, Nuevo León, Tamaulipas (away from US border)
|
||||
-Zone America/Monterrey -6:41:16 - LMT 1921 Dec 31 23:18:44
|
||||
+Zone America/Monterrey -6:41:16 - LMT 1922 Jan 1 6:00u
|
||||
-6:00 - CST 1988
|
||||
-6:00 US C%sT 1989
|
||||
-6:00 Mexico C%sT
|
||||
# Central Mexico
|
||||
-Zone America/Mexico_City -6:36:36 - LMT 1922 Jan 1 0:23:24
|
||||
+Zone America/Mexico_City -6:36:36 - LMT 1922 Jan 1 7:00u
|
||||
-7:00 - MST 1927 Jun 10 23:00
|
||||
-6:00 - CST 1930 Nov 15
|
||||
- -7:00 - MST 1931 May 1 23:00
|
||||
- -6:00 - CST 1931 Oct
|
||||
- -7:00 - MST 1932 Apr 1
|
||||
+ -7:00 Mexico M%sT 1932 Apr 1
|
||||
-6:00 Mexico C%sT 2001 Sep 30 2:00
|
||||
-6:00 - CST 2002 Feb 20
|
||||
-6:00 Mexico C%sT
|
||||
@@ -2700,35 +2700,29 @@ Zone America/Mexico_City -6:36:36 - LMT 1922 Jan 1 0:23:24
|
||||
# This includes the municipalities of Janos, Ascensión, Juárez, Guadalupe,
|
||||
# Práxedis G Guerrero, Coyame del Sotol, Ojinaga, and Manuel Benavides.
|
||||
# (See the 2016-03-12 El Universal source mentioned above.)
|
||||
-Zone America/Ojinaga -6:57:40 - LMT 1922 Jan 1 0:02:20
|
||||
+Zone America/Ojinaga -6:57:40 - LMT 1922 Jan 1 7:00u
|
||||
-7:00 - MST 1927 Jun 10 23:00
|
||||
-6:00 - CST 1930 Nov 15
|
||||
- -7:00 - MST 1931 May 1 23:00
|
||||
- -6:00 - CST 1931 Oct
|
||||
- -7:00 - MST 1932 Apr 1
|
||||
+ -7:00 Mexico M%sT 1932 Apr 1
|
||||
-6:00 - CST 1996
|
||||
-6:00 Mexico C%sT 1998
|
||||
-6:00 - CST 1998 Apr Sun>=1 3:00
|
||||
-7:00 Mexico M%sT 2010
|
||||
-7:00 US M%sT
|
||||
# Chihuahua (away from US border)
|
||||
-Zone America/Chihuahua -7:04:20 - LMT 1921 Dec 31 23:55:40
|
||||
+Zone America/Chihuahua -7:04:20 - LMT 1922 Jan 1 7:00u
|
||||
-7:00 - MST 1927 Jun 10 23:00
|
||||
-6:00 - CST 1930 Nov 15
|
||||
- -7:00 - MST 1931 May 1 23:00
|
||||
- -6:00 - CST 1931 Oct
|
||||
- -7:00 - MST 1932 Apr 1
|
||||
+ -7:00 Mexico M%sT 1932 Apr 1
|
||||
-6:00 - CST 1996
|
||||
-6:00 Mexico C%sT 1998
|
||||
-6:00 - CST 1998 Apr Sun>=1 3:00
|
||||
-7:00 Mexico M%sT
|
||||
# Sonora
|
||||
-Zone America/Hermosillo -7:23:52 - LMT 1921 Dec 31 23:36:08
|
||||
+Zone America/Hermosillo -7:23:52 - LMT 1922 Jan 1 7:00u
|
||||
-7:00 - MST 1927 Jun 10 23:00
|
||||
-6:00 - CST 1930 Nov 15
|
||||
- -7:00 - MST 1931 May 1 23:00
|
||||
- -6:00 - CST 1931 Oct
|
||||
- -7:00 - MST 1932 Apr 1
|
||||
+ -7:00 Mexico M%sT 1932 Apr 1
|
||||
-6:00 - CST 1942 Apr 24
|
||||
-7:00 - MST 1949 Jan 14
|
||||
-8:00 - PST 1970
|
||||
@@ -2763,24 +2757,20 @@ Zone America/Hermosillo -7:23:52 - LMT 1921 Dec 31 23:36:08
|
||||
# Use "Bahia_Banderas" to keep the name to fourteen characters.
|
||||
|
||||
# Mazatlán
|
||||
-Zone America/Mazatlan -7:05:40 - LMT 1921 Dec 31 23:54:20
|
||||
+Zone America/Mazatlan -7:05:40 - LMT 1922 Jan 1 7:00u
|
||||
-7:00 - MST 1927 Jun 10 23:00
|
||||
-6:00 - CST 1930 Nov 15
|
||||
- -7:00 - MST 1931 May 1 23:00
|
||||
- -6:00 - CST 1931 Oct
|
||||
- -7:00 - MST 1932 Apr 1
|
||||
+ -7:00 Mexico M%sT 1932 Apr 1
|
||||
-6:00 - CST 1942 Apr 24
|
||||
-7:00 - MST 1949 Jan 14
|
||||
-8:00 - PST 1970
|
||||
-7:00 Mexico M%sT
|
||||
|
||||
# Bahía de Banderas
|
||||
-Zone America/Bahia_Banderas -7:01:00 - LMT 1921 Dec 31 23:59:00
|
||||
+Zone America/Bahia_Banderas -7:01:00 - LMT 1922 Jan 1 7:00u
|
||||
-7:00 - MST 1927 Jun 10 23:00
|
||||
-6:00 - CST 1930 Nov 15
|
||||
- -7:00 - MST 1931 May 1 23:00
|
||||
- -6:00 - CST 1931 Oct
|
||||
- -7:00 - MST 1932 Apr 1
|
||||
+ -7:00 Mexico M%sT 1932 Apr 1
|
||||
-6:00 - CST 1942 Apr 24
|
||||
-7:00 - MST 1949 Jan 14
|
||||
-8:00 - PST 1970
|
||||
@@ -2788,7 +2778,7 @@ Zone America/Bahia_Banderas -7:01:00 - LMT 1921 Dec 31 23:59:00
|
||||
-6:00 Mexico C%sT
|
||||
|
||||
# Baja California
|
||||
-Zone America/Tijuana -7:48:04 - LMT 1922 Jan 1 0:11:56
|
||||
+Zone America/Tijuana -7:48:04 - LMT 1922 Jan 1 7:00u
|
||||
-7:00 - MST 1924
|
||||
-8:00 - PST 1927 Jun 10 23:00
|
||||
-7:00 - MST 1930 Nov 15
|
||||
diff --git a/jdk/test/java/util/TimeZone/TimeZoneData/VERSION b/jdk/test/java/util/TimeZone/TimeZoneData/VERSION
|
||||
index 7147016..0cad939 100644
|
||||
--- a/jdk/test/java/util/TimeZone/TimeZoneData/VERSION
|
||||
+++ b/jdk/test/java/util/TimeZone/TimeZoneData/VERSION
|
||||
@@ -1 +1 @@
|
||||
-tzdata2022d
|
||||
+tzdata2022e
|
||||
diff --git a/jdk/test/java/util/TimeZone/TimeZoneData/displaynames.txt b/jdk/test/java/util/TimeZone/TimeZoneData/displaynames.txt
|
||||
index b382395..2f2786f 100644
|
||||
--- a/jdk/test/java/util/TimeZone/TimeZoneData/displaynames.txt
|
||||
+++ b/jdk/test/java/util/TimeZone/TimeZoneData/displaynames.txt
|
||||
@@ -97,9 +97,7 @@ America/Winnipeg CST CDT
|
||||
America/Yakutat AKST AKDT
|
||||
America/Yellowknife MST MDT
|
||||
Antarctica/Macquarie AEST AEDT
|
||||
-Asia/Amman EET EEST
|
||||
Asia/Beirut EET EEST
|
||||
-Asia/Damascus EET EEST
|
||||
Asia/Famagusta EET EEST
|
||||
Asia/Gaza EET EEST
|
||||
Asia/Hebron EET EEST
|
||||
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/VERSION b/jdk/test/sun/util/calendar/zi/tzdata/VERSION
|
||||
index 889d0e6..b8cb36e 100644
|
||||
--- a/jdk/test/sun/util/calendar/zi/tzdata/VERSION
|
||||
+++ b/jdk/test/sun/util/calendar/zi/tzdata/VERSION
|
||||
@@ -21,4 +21,4 @@
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
-tzdata2022d
|
||||
+tzdata2022e
|
||||
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/asia b/jdk/test/sun/util/calendar/zi/tzdata/asia
|
||||
index 1dc7d34..f1771e4 100644
|
||||
--- a/jdk/test/sun/util/calendar/zi/tzdata/asia
|
||||
+++ b/jdk/test/sun/util/calendar/zi/tzdata/asia
|
||||
@@ -2254,6 +2254,17 @@ Zone Asia/Tokyo 9:18:59 - LMT 1887 Dec 31 15:00u
|
||||
# From the Arabic version, it seems to say it would be at midnight
|
||||
# (assume 24:00) on the last Thursday in February, starting from 2022.
|
||||
|
||||
+# From Issam Al-Zuwairi (2022-10-05):
|
||||
+# The Council of Ministers in Jordan decided Wednesday 5th October 2022,
|
||||
+# that daylight saving time (DST) will be throughout the year....
|
||||
+#
|
||||
+# From Brian Inglis (2022-10-06):
|
||||
+# https://petra.gov.jo/Include/InnerPage.jsp?ID=45567&lang=en&name=en_news
|
||||
+#
|
||||
+# From Paul Eggert (2022-10-05):
|
||||
+# Like Syria, model this as a transition from EEST +03 (DST) to plain +03
|
||||
+# (non-DST) at the point where DST would otherwise have ended.
|
||||
+
|
||||
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
|
||||
Rule Jordan 1973 only - Jun 6 0:00 1:00 S
|
||||
Rule Jordan 1973 1975 - Oct 1 0:00 0 -
|
||||
@@ -2285,11 +2296,12 @@ Rule Jordan 2005 only - Sep lastFri 0:00s 0 -
|
||||
Rule Jordan 2006 2011 - Oct lastFri 0:00s 0 -
|
||||
Rule Jordan 2013 only - Dec 20 0:00 0 -
|
||||
Rule Jordan 2014 2021 - Mar lastThu 24:00 1:00 S
|
||||
-Rule Jordan 2014 max - Oct lastFri 0:00s 0 -
|
||||
-Rule Jordan 2022 max - Feb lastThu 24:00 1:00 S
|
||||
+Rule Jordan 2014 2022 - Oct lastFri 0:00s 0 -
|
||||
+Rule Jordan 2022 only - Feb lastThu 24:00 1:00 S
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
Zone Asia/Amman 2:23:44 - LMT 1931
|
||||
- 2:00 Jordan EE%sT
|
||||
+ 2:00 Jordan EE%sT 2022 Oct 28 0:00s
|
||||
+ 3:00 - +03
|
||||
|
||||
|
||||
# Kazakhstan
|
||||
@@ -3838,19 +3850,27 @@ Rule Syria 2007 only - Nov Fri>=1 0:00 0 -
|
||||
# Our brief summary:
|
||||
# https://www.timeanddate.com/news/time/syria-dst-2012.html
|
||||
|
||||
-# From Arthur David Olson (2012-03-27):
|
||||
-# Assume last Friday in March going forward XXX.
|
||||
+# From Steffen Thorsen (2022-10-05):
|
||||
+# Syria is adopting year-round DST, starting this autumn....
|
||||
+# From https://www.enabbaladi.net/archives/607812
|
||||
+# "This [the decision] came after the weekly government meeting today,
|
||||
+# Tuesday 4 October ..."
|
||||
+#
|
||||
+# From Paul Eggert (2022-10-05):
|
||||
+# Like Jordan, model this as a transition from EEST +03 (DST) to plain +03
|
||||
+# (non-DST) at the point where DST would otherwise have ended.
|
||||
|
||||
Rule Syria 2008 only - Apr Fri>=1 0:00 1:00 S
|
||||
Rule Syria 2008 only - Nov 1 0:00 0 -
|
||||
Rule Syria 2009 only - Mar lastFri 0:00 1:00 S
|
||||
Rule Syria 2010 2011 - Apr Fri>=1 0:00 1:00 S
|
||||
-Rule Syria 2012 max - Mar lastFri 0:00 1:00 S
|
||||
-Rule Syria 2009 max - Oct lastFri 0:00 0 -
|
||||
+Rule Syria 2012 2022 - Mar lastFri 0:00 1:00 S
|
||||
+Rule Syria 2009 2022 - Oct lastFri 0:00 0 -
|
||||
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
Zone Asia/Damascus 2:25:12 - LMT 1920 # Dimashq
|
||||
- 2:00 Syria EE%sT
|
||||
+ 2:00 Syria EE%sT 2022 Oct 28 0:00
|
||||
+ 3:00 - +03
|
||||
|
||||
# Tajikistan
|
||||
# From Shanks & Pottenger.
|
||||
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/europe b/jdk/test/sun/util/calendar/zi/tzdata/europe
|
||||
index 9e0a538..930cede 100644
|
||||
--- a/jdk/test/sun/util/calendar/zi/tzdata/europe
|
||||
+++ b/jdk/test/sun/util/calendar/zi/tzdata/europe
|
||||
@@ -3417,7 +3417,7 @@ Zone Europe/Madrid -0:14:44 - LMT 1901 Jan 1 0:00u
|
||||
0:00 Spain WE%sT 1940 Mar 16 23:00
|
||||
1:00 Spain CE%sT 1979
|
||||
1:00 EU CE%sT
|
||||
-Zone Africa/Ceuta -0:21:16 - LMT 1900 Dec 31 23:38:44
|
||||
+Zone Africa/Ceuta -0:21:16 - LMT 1901 Jan 1 0:00u
|
||||
0:00 - WET 1918 May 6 23:00
|
||||
0:00 1:00 WEST 1918 Oct 7 23:00
|
||||
0:00 - WET 1924
|
||||
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/northamerica b/jdk/test/sun/util/calendar/zi/tzdata/northamerica
|
||||
index 114cef1..ce4ee74 100644
|
||||
--- a/jdk/test/sun/util/calendar/zi/tzdata/northamerica
|
||||
+++ b/jdk/test/sun/util/calendar/zi/tzdata/northamerica
|
||||
@@ -462,7 +462,7 @@ Rule Chicago 1922 1966 - Apr lastSun 2:00 1:00 D
|
||||
Rule Chicago 1922 1954 - Sep lastSun 2:00 0 S
|
||||
Rule Chicago 1955 1966 - Oct lastSun 2:00 0 S
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
-Zone America/Chicago -5:50:36 - LMT 1883 Nov 18 12:09:24
|
||||
+Zone America/Chicago -5:50:36 - LMT 1883 Nov 18 18:00u
|
||||
-6:00 US C%sT 1920
|
||||
-6:00 Chicago C%sT 1936 Mar 1 2:00
|
||||
-5:00 - EST 1936 Nov 15 2:00
|
||||
@@ -471,7 +471,7 @@ Zone America/Chicago -5:50:36 - LMT 1883 Nov 18 12:09:24
|
||||
-6:00 Chicago C%sT 1967
|
||||
-6:00 US C%sT
|
||||
# Oliver County, ND switched from mountain to central time on 1992-10-25.
|
||||
-Zone America/North_Dakota/Center -6:45:12 - LMT 1883 Nov 18 12:14:48
|
||||
+Zone America/North_Dakota/Center -6:45:12 - LMT 1883 Nov 18 19:00u
|
||||
-7:00 US M%sT 1992 Oct 25 2:00
|
||||
-6:00 US C%sT
|
||||
# Morton County, ND, switched from mountain to central time on
|
||||
@@ -481,7 +481,7 @@ Zone America/North_Dakota/Center -6:45:12 - LMT 1883 Nov 18 12:14:48
|
||||
# Jones, Mellette, and Todd Counties in South Dakota;
|
||||
# but in practice these other counties were already observing central time.
|
||||
# See <http://www.epa.gov/fedrgstr/EPA-IMPACT/2003/October/Day-28/i27056.htm>.
|
||||
-Zone America/North_Dakota/New_Salem -6:45:39 - LMT 1883 Nov 18 12:14:21
|
||||
+Zone America/North_Dakota/New_Salem -6:45:39 - LMT 1883 Nov 18 19:00u
|
||||
-7:00 US M%sT 2003 Oct 26 2:00
|
||||
-6:00 US C%sT
|
||||
|
||||
@@ -498,7 +498,7 @@ Zone America/North_Dakota/New_Salem -6:45:39 - LMT 1883 Nov 18 12:14:21
|
||||
# largest city in Mercer County). Google Maps places Beulah's city hall
|
||||
# at 47° 15' 51" N, 101° 46' 40" W, which yields an offset of 6h47'07".
|
||||
|
||||
-Zone America/North_Dakota/Beulah -6:47:07 - LMT 1883 Nov 18 12:12:53
|
||||
+Zone America/North_Dakota/Beulah -6:47:07 - LMT 1883 Nov 18 19:00u
|
||||
-7:00 US M%sT 2010 Nov 7 2:00
|
||||
-6:00 US C%sT
|
||||
|
||||
@@ -530,7 +530,7 @@ Rule Denver 1921 only - May 22 2:00 0 S
|
||||
Rule Denver 1965 1966 - Apr lastSun 2:00 1:00 D
|
||||
Rule Denver 1965 1966 - Oct lastSun 2:00 0 S
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
-Zone America/Denver -6:59:56 - LMT 1883 Nov 18 12:00:04
|
||||
+Zone America/Denver -6:59:56 - LMT 1883 Nov 18 19:00u
|
||||
-7:00 US M%sT 1920
|
||||
-7:00 Denver M%sT 1942
|
||||
-7:00 US M%sT 1946
|
||||
@@ -583,7 +583,7 @@ Rule CA 1950 1966 - Apr lastSun 1:00 1:00 D
|
||||
Rule CA 1950 1961 - Sep lastSun 2:00 0 S
|
||||
Rule CA 1962 1966 - Oct lastSun 2:00 0 S
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
-Zone America/Los_Angeles -7:52:58 - LMT 1883 Nov 18 12:07:02
|
||||
+Zone America/Los_Angeles -7:52:58 - LMT 1883 Nov 18 20:00u
|
||||
-8:00 US P%sT 1946
|
||||
-8:00 CA P%sT 1967
|
||||
-8:00 US P%sT
|
||||
@@ -845,7 +845,7 @@ Zone Pacific/Honolulu -10:31:26 - LMT 1896 Jan 13 12:00
|
||||
# Go with the Arizona State Library instead.
|
||||
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
-Zone America/Phoenix -7:28:18 - LMT 1883 Nov 18 11:31:42
|
||||
+Zone America/Phoenix -7:28:18 - LMT 1883 Nov 18 19:00u
|
||||
-7:00 US M%sT 1944 Jan 1 0:01
|
||||
-7:00 - MST 1944 Apr 1 0:01
|
||||
-7:00 US M%sT 1944 Oct 1 0:01
|
||||
@@ -873,7 +873,7 @@ Link America/Phoenix America/Creston
|
||||
# switched four weeks late in 1974.
|
||||
#
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
-Zone America/Boise -7:44:49 - LMT 1883 Nov 18 12:15:11
|
||||
+Zone America/Boise -7:44:49 - LMT 1883 Nov 18 20:00u
|
||||
-8:00 US P%sT 1923 May 13 2:00
|
||||
-7:00 US M%sT 1974
|
||||
-7:00 - MST 1974 Feb 3 2:00
|
||||
@@ -945,7 +945,7 @@ Rule Indianapolis 1941 only - Jun 22 2:00 1:00 D
|
||||
Rule Indianapolis 1941 1954 - Sep lastSun 2:00 0 S
|
||||
Rule Indianapolis 1946 1954 - Apr lastSun 2:00 1:00 D
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
-Zone America/Indiana/Indianapolis -5:44:38 - LMT 1883 Nov 18 12:15:22
|
||||
+Zone America/Indiana/Indianapolis -5:44:38 - LMT 1883 Nov 18 18:00u
|
||||
-6:00 US C%sT 1920
|
||||
-6:00 Indianapolis C%sT 1942
|
||||
-6:00 US C%sT 1946
|
||||
@@ -965,7 +965,7 @@ Rule Marengo 1951 only - Sep lastSun 2:00 0 S
|
||||
Rule Marengo 1954 1960 - Apr lastSun 2:00 1:00 D
|
||||
Rule Marengo 1954 1960 - Sep lastSun 2:00 0 S
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
-Zone America/Indiana/Marengo -5:45:23 - LMT 1883 Nov 18 12:14:37
|
||||
+Zone America/Indiana/Marengo -5:45:23 - LMT 1883 Nov 18 18:00u
|
||||
-6:00 US C%sT 1951
|
||||
-6:00 Marengo C%sT 1961 Apr 30 2:00
|
||||
-5:00 - EST 1969
|
||||
@@ -989,7 +989,7 @@ Rule Vincennes 1960 only - Oct lastSun 2:00 0 S
|
||||
Rule Vincennes 1961 only - Sep lastSun 2:00 0 S
|
||||
Rule Vincennes 1962 1963 - Oct lastSun 2:00 0 S
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
-Zone America/Indiana/Vincennes -5:50:07 - LMT 1883 Nov 18 12:09:53
|
||||
+Zone America/Indiana/Vincennes -5:50:07 - LMT 1883 Nov 18 18:00u
|
||||
-6:00 US C%sT 1946
|
||||
-6:00 Vincennes C%sT 1964 Apr 26 2:00
|
||||
-5:00 - EST 1969
|
||||
@@ -1009,7 +1009,7 @@ Rule Perry 1955 1960 - Sep lastSun 2:00 0 S
|
||||
Rule Perry 1956 1963 - Apr lastSun 2:00 1:00 D
|
||||
Rule Perry 1961 1963 - Oct lastSun 2:00 0 S
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
-Zone America/Indiana/Tell_City -5:47:03 - LMT 1883 Nov 18 12:12:57
|
||||
+Zone America/Indiana/Tell_City -5:47:03 - LMT 1883 Nov 18 18:00u
|
||||
-6:00 US C%sT 1946
|
||||
-6:00 Perry C%sT 1964 Apr 26 2:00
|
||||
-5:00 - EST 1967 Oct 29 2:00
|
||||
@@ -1026,7 +1026,7 @@ Rule Pike 1955 1960 - Sep lastSun 2:00 0 S
|
||||
Rule Pike 1956 1964 - Apr lastSun 2:00 1:00 D
|
||||
Rule Pike 1961 1964 - Oct lastSun 2:00 0 S
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
-Zone America/Indiana/Petersburg -5:49:07 - LMT 1883 Nov 18 12:10:53
|
||||
+Zone America/Indiana/Petersburg -5:49:07 - LMT 1883 Nov 18 18:00u
|
||||
-6:00 US C%sT 1955
|
||||
-6:00 Pike C%sT 1965 Apr 25 2:00
|
||||
-5:00 - EST 1966 Oct 30 2:00
|
||||
@@ -1048,7 +1048,7 @@ Rule Starke 1955 1956 - Oct lastSun 2:00 0 S
|
||||
Rule Starke 1957 1958 - Sep lastSun 2:00 0 S
|
||||
Rule Starke 1959 1961 - Oct lastSun 2:00 0 S
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
-Zone America/Indiana/Knox -5:46:30 - LMT 1883 Nov 18 12:13:30
|
||||
+Zone America/Indiana/Knox -5:46:30 - LMT 1883 Nov 18 18:00u
|
||||
-6:00 US C%sT 1947
|
||||
-6:00 Starke C%sT 1962 Apr 29 2:00
|
||||
-5:00 - EST 1963 Oct 27 2:00
|
||||
@@ -1064,7 +1064,7 @@ Rule Pulaski 1946 1954 - Sep lastSun 2:00 0 S
|
||||
Rule Pulaski 1955 1956 - Oct lastSun 2:00 0 S
|
||||
Rule Pulaski 1957 1960 - Sep lastSun 2:00 0 S
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
-Zone America/Indiana/Winamac -5:46:25 - LMT 1883 Nov 18 12:13:35
|
||||
+Zone America/Indiana/Winamac -5:46:25 - LMT 1883 Nov 18 18:00u
|
||||
-6:00 US C%sT 1946
|
||||
-6:00 Pulaski C%sT 1961 Apr 30 2:00
|
||||
-5:00 - EST 1969
|
||||
@@ -1075,7 +1075,7 @@ Zone America/Indiana/Winamac -5:46:25 - LMT 1883 Nov 18 12:13:35
|
||||
#
|
||||
# Switzerland County, Indiana, did not observe DST from 1973 through 2005.
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
-Zone America/Indiana/Vevay -5:40:16 - LMT 1883 Nov 18 12:19:44
|
||||
+Zone America/Indiana/Vevay -5:40:16 - LMT 1883 Nov 18 18:00u
|
||||
-6:00 US C%sT 1954 Apr 25 2:00
|
||||
-5:00 - EST 1969
|
||||
-5:00 US E%sT 1973
|
||||
@@ -1111,7 +1111,7 @@ Rule Louisville 1950 1961 - Apr lastSun 2:00 1:00 D
|
||||
Rule Louisville 1950 1955 - Sep lastSun 2:00 0 S
|
||||
Rule Louisville 1956 1961 - Oct lastSun 2:00 0 S
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
-Zone America/Kentucky/Louisville -5:43:02 - LMT 1883 Nov 18 12:16:58
|
||||
+Zone America/Kentucky/Louisville -5:43:02 - LMT 1883 Nov 18 18:00u
|
||||
-6:00 US C%sT 1921
|
||||
-6:00 Louisville C%sT 1942
|
||||
-6:00 US C%sT 1946
|
||||
@@ -1145,7 +1145,7 @@ Zone America/Kentucky/Louisville -5:43:02 - LMT 1883 Nov 18 12:16:58
|
||||
# Federal Register 65, 160 (2000-08-17), pp 50154-50158.
|
||||
# https://www.gpo.gov/fdsys/pkg/FR-2000-08-17/html/00-20854.htm
|
||||
#
|
||||
-Zone America/Kentucky/Monticello -5:39:24 - LMT 1883 Nov 18 12:20:36
|
||||
+Zone America/Kentucky/Monticello -5:39:24 - LMT 1883 Nov 18 18:00u
|
||||
-6:00 US C%sT 1946
|
||||
-6:00 - CST 1968
|
||||
-6:00 US C%sT 2000 Oct 29 2:00
|
||||
@@ -2640,6 +2640,8 @@ Zone America/Dawson -9:17:40 - LMT 1900 Aug 20
|
||||
# longitude they are located at.
|
||||
|
||||
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
|
||||
+Rule Mexico 1931 only - May 1 23:00 1:00 D
|
||||
+Rule Mexico 1931 only - Oct 1 0:00 0 S
|
||||
Rule Mexico 1939 only - Feb 5 0:00 1:00 D
|
||||
Rule Mexico 1939 only - Jun 25 0:00 0 S
|
||||
Rule Mexico 1940 only - Dec 9 0:00 1:00 D
|
||||
@@ -2656,13 +2658,13 @@ Rule Mexico 2002 max - Apr Sun>=1 2:00 1:00 D
|
||||
Rule Mexico 2002 max - Oct lastSun 2:00 0 S
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
# Quintana Roo; represented by Cancún
|
||||
-Zone America/Cancun -5:47:04 - LMT 1922 Jan 1 0:12:56
|
||||
+Zone America/Cancun -5:47:04 - LMT 1922 Jan 1 6:00u
|
||||
-6:00 - CST 1981 Dec 23
|
||||
-5:00 Mexico E%sT 1998 Aug 2 2:00
|
||||
-6:00 Mexico C%sT 2015 Feb 1 2:00
|
||||
-5:00 - EST
|
||||
# Campeche, Yucatán; represented by Mérida
|
||||
-Zone America/Merida -5:58:28 - LMT 1922 Jan 1 0:01:32
|
||||
+Zone America/Merida -5:58:28 - LMT 1922 Jan 1 6:00u
|
||||
-6:00 - CST 1981 Dec 23
|
||||
-5:00 - EST 1982 Dec 2
|
||||
-6:00 Mexico C%sT
|
||||
@@ -2676,23 +2678,21 @@ Zone America/Merida -5:58:28 - LMT 1922 Jan 1 0:01:32
|
||||
# See: Inicia mañana Horario de Verano en zona fronteriza, El Universal,
|
||||
# 2016-03-12
|
||||
# http://www.eluniversal.com.mx/articulo/estados/2016/03/12/inicia-manana-horario-de-verano-en-zona-fronteriza
|
||||
-Zone America/Matamoros -6:40:00 - LMT 1921 Dec 31 23:20:00
|
||||
+Zone America/Matamoros -6:30:00 - LMT 1922 Jan 1 6:00u
|
||||
-6:00 - CST 1988
|
||||
-6:00 US C%sT 1989
|
||||
-6:00 Mexico C%sT 2010
|
||||
-6:00 US C%sT
|
||||
# Durango; Coahuila, Nuevo León, Tamaulipas (away from US border)
|
||||
-Zone America/Monterrey -6:41:16 - LMT 1921 Dec 31 23:18:44
|
||||
+Zone America/Monterrey -6:41:16 - LMT 1922 Jan 1 6:00u
|
||||
-6:00 - CST 1988
|
||||
-6:00 US C%sT 1989
|
||||
-6:00 Mexico C%sT
|
||||
# Central Mexico
|
||||
-Zone America/Mexico_City -6:36:36 - LMT 1922 Jan 1 0:23:24
|
||||
+Zone America/Mexico_City -6:36:36 - LMT 1922 Jan 1 7:00u
|
||||
-7:00 - MST 1927 Jun 10 23:00
|
||||
-6:00 - CST 1930 Nov 15
|
||||
- -7:00 - MST 1931 May 1 23:00
|
||||
- -6:00 - CST 1931 Oct
|
||||
- -7:00 - MST 1932 Apr 1
|
||||
+ -7:00 Mexico M%sT 1932 Apr 1
|
||||
-6:00 Mexico C%sT 2001 Sep 30 2:00
|
||||
-6:00 - CST 2002 Feb 20
|
||||
-6:00 Mexico C%sT
|
||||
@@ -2700,35 +2700,29 @@ Zone America/Mexico_City -6:36:36 - LMT 1922 Jan 1 0:23:24
|
||||
# This includes the municipalities of Janos, Ascensión, Juárez, Guadalupe,
|
||||
# Práxedis G Guerrero, Coyame del Sotol, Ojinaga, and Manuel Benavides.
|
||||
# (See the 2016-03-12 El Universal source mentioned above.)
|
||||
-Zone America/Ojinaga -6:57:40 - LMT 1922 Jan 1 0:02:20
|
||||
+Zone America/Ojinaga -6:57:40 - LMT 1922 Jan 1 7:00u
|
||||
-7:00 - MST 1927 Jun 10 23:00
|
||||
-6:00 - CST 1930 Nov 15
|
||||
- -7:00 - MST 1931 May 1 23:00
|
||||
- -6:00 - CST 1931 Oct
|
||||
- -7:00 - MST 1932 Apr 1
|
||||
+ -7:00 Mexico M%sT 1932 Apr 1
|
||||
-6:00 - CST 1996
|
||||
-6:00 Mexico C%sT 1998
|
||||
-6:00 - CST 1998 Apr Sun>=1 3:00
|
||||
-7:00 Mexico M%sT 2010
|
||||
-7:00 US M%sT
|
||||
# Chihuahua (away from US border)
|
||||
-Zone America/Chihuahua -7:04:20 - LMT 1921 Dec 31 23:55:40
|
||||
+Zone America/Chihuahua -7:04:20 - LMT 1922 Jan 1 7:00u
|
||||
-7:00 - MST 1927 Jun 10 23:00
|
||||
-6:00 - CST 1930 Nov 15
|
||||
- -7:00 - MST 1931 May 1 23:00
|
||||
- -6:00 - CST 1931 Oct
|
||||
- -7:00 - MST 1932 Apr 1
|
||||
+ -7:00 Mexico M%sT 1932 Apr 1
|
||||
-6:00 - CST 1996
|
||||
-6:00 Mexico C%sT 1998
|
||||
-6:00 - CST 1998 Apr Sun>=1 3:00
|
||||
-7:00 Mexico M%sT
|
||||
# Sonora
|
||||
-Zone America/Hermosillo -7:23:52 - LMT 1921 Dec 31 23:36:08
|
||||
+Zone America/Hermosillo -7:23:52 - LMT 1922 Jan 1 7:00u
|
||||
-7:00 - MST 1927 Jun 10 23:00
|
||||
-6:00 - CST 1930 Nov 15
|
||||
- -7:00 - MST 1931 May 1 23:00
|
||||
- -6:00 - CST 1931 Oct
|
||||
- -7:00 - MST 1932 Apr 1
|
||||
+ -7:00 Mexico M%sT 1932 Apr 1
|
||||
-6:00 - CST 1942 Apr 24
|
||||
-7:00 - MST 1949 Jan 14
|
||||
-8:00 - PST 1970
|
||||
@@ -2763,24 +2757,20 @@ Zone America/Hermosillo -7:23:52 - LMT 1921 Dec 31 23:36:08
|
||||
# Use "Bahia_Banderas" to keep the name to fourteen characters.
|
||||
|
||||
# Mazatlán
|
||||
-Zone America/Mazatlan -7:05:40 - LMT 1921 Dec 31 23:54:20
|
||||
+Zone America/Mazatlan -7:05:40 - LMT 1922 Jan 1 7:00u
|
||||
-7:00 - MST 1927 Jun 10 23:00
|
||||
-6:00 - CST 1930 Nov 15
|
||||
- -7:00 - MST 1931 May 1 23:00
|
||||
- -6:00 - CST 1931 Oct
|
||||
- -7:00 - MST 1932 Apr 1
|
||||
+ -7:00 Mexico M%sT 1932 Apr 1
|
||||
-6:00 - CST 1942 Apr 24
|
||||
-7:00 - MST 1949 Jan 14
|
||||
-8:00 - PST 1970
|
||||
-7:00 Mexico M%sT
|
||||
|
||||
# Bahía de Banderas
|
||||
-Zone America/Bahia_Banderas -7:01:00 - LMT 1921 Dec 31 23:59:00
|
||||
+Zone America/Bahia_Banderas -7:01:00 - LMT 1922 Jan 1 7:00u
|
||||
-7:00 - MST 1927 Jun 10 23:00
|
||||
-6:00 - CST 1930 Nov 15
|
||||
- -7:00 - MST 1931 May 1 23:00
|
||||
- -6:00 - CST 1931 Oct
|
||||
- -7:00 - MST 1932 Apr 1
|
||||
+ -7:00 Mexico M%sT 1932 Apr 1
|
||||
-6:00 - CST 1942 Apr 24
|
||||
-7:00 - MST 1949 Jan 14
|
||||
-8:00 - PST 1970
|
||||
@@ -2788,7 +2778,7 @@ Zone America/Bahia_Banderas -7:01:00 - LMT 1921 Dec 31 23:59:00
|
||||
-6:00 Mexico C%sT
|
||||
|
||||
# Baja California
|
||||
-Zone America/Tijuana -7:48:04 - LMT 1922 Jan 1 0:11:56
|
||||
+Zone America/Tijuana -7:48:04 - LMT 1922 Jan 1 7:00u
|
||||
-7:00 - MST 1924
|
||||
-8:00 - PST 1927 Jun 10 23:00
|
||||
-7:00 - MST 1930 Nov 15
|
||||
--
|
||||
1.8.3.1
|
||||
42
8296480-Fix-the-problem-that-the-TestPolicy.java-cas.patch
Normal file
42
8296480-Fix-the-problem-that-the-TestPolicy.java-cas.patch
Normal file
@ -0,0 +1,42 @@
|
||||
From 6d1c5b1ee82b2b2481a16f3510078fdc7ddc08f9 Mon Sep 17 00:00:00 2001
|
||||
From: eapen <zhangyipeng7@huawei.com>
|
||||
Date: Tue, 15 Nov 2022 11:26:33 +0800
|
||||
Subject: [PATCH 04/33] 8296480: Fix the problem that the TestPolicy.java case
|
||||
fails because the certificate expires.
|
||||
---
|
||||
jdk/test/java/security/cert/pkix/policyChanges/TestPolicy.java | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/jdk/test/java/security/cert/pkix/policyChanges/TestPolicy.java b/jdk/test/java/security/cert/pkix/policyChanges/TestPolicy.java
|
||||
index a92eee2..b37debf 100644
|
||||
--- a/jdk/test/java/security/cert/pkix/policyChanges/TestPolicy.java
|
||||
+++ b/jdk/test/java/security/cert/pkix/policyChanges/TestPolicy.java
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
+ * Copyright (c) 2002, 2022, 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
|
||||
@@ -34,6 +34,7 @@
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
+import java.text.DateFormat;
|
||||
import java.util.*;
|
||||
|
||||
import java.security.Security;
|
||||
@@ -97,6 +98,10 @@ public class TestPolicy {
|
||||
params.setRevocationEnabled(false);
|
||||
params.setInitialPolicies(testCase.initialPolicies);
|
||||
|
||||
+ // Certs expired on 7th Nov 2022
|
||||
+ params.setDate(DateFormat.getDateInstance(DateFormat.MEDIUM,
|
||||
+ Locale.US).parse("June 01, 2022"));
|
||||
+
|
||||
CertPath path = factory.generateCertPath(Arrays.asList(new X509Certificate[] {ee, ca}));
|
||||
|
||||
PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult)validator.validate(path, params);
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
39
8296485-BuildEEBasicConstraints.java-test-fails-with.patch
Normal file
39
8296485-BuildEEBasicConstraints.java-test-fails-with.patch
Normal file
@ -0,0 +1,39 @@
|
||||
From b8aedd236ca707cfc15eb5daf91aab697a8014ed Mon Sep 17 00:00:00 2001
|
||||
From: eapen <zhangyipeng7@huawei.com>
|
||||
Date: Wed, 23 Nov 2022 08:31:14 +0800
|
||||
Subject: [PATCH 06/33] I68TO2: 8296485: BuildEEBasicConstraints.java test fails with
|
||||
SunCertPathBuilderException
|
||||
---
|
||||
.../CertPathBuilder/targetConstraints/BuildEEBasicConstraints.java | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/jdk/test/java/security/cert/CertPathBuilder/targetConstraints/BuildEEBasicConstraints.java b/jdk/test/java/security/cert/CertPathBuilder/targetConstraints/BuildEEBasicConstraints.java
|
||||
index 6be5562..44926d2 100644
|
||||
--- a/jdk/test/java/security/cert/CertPathBuilder/targetConstraints/BuildEEBasicConstraints.java
|
||||
+++ b/jdk/test/java/security/cert/CertPathBuilder/targetConstraints/BuildEEBasicConstraints.java
|
||||
@@ -46,9 +46,11 @@ import java.security.cert.PKIXCertPathBuilderResult;
|
||||
import java.security.cert.TrustAnchor;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.security.cert.X509CertSelector;
|
||||
+import java.text.DateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
+import java.util.Locale;
|
||||
|
||||
public final class BuildEEBasicConstraints {
|
||||
|
||||
@@ -65,6 +67,11 @@ public final class BuildEEBasicConstraints {
|
||||
PKIXBuilderParameters params = new PKIXBuilderParameters
|
||||
(Collections.singleton(anchor), sel);
|
||||
params.setRevocationEnabled(false);
|
||||
+
|
||||
+ // Certs expired on 7th Nov 2022
|
||||
+ params.setDate(DateFormat.getDateInstance(DateFormat.MEDIUM,
|
||||
+ Locale.US).parse("June 01, 2022"));
|
||||
+
|
||||
X509Certificate eeCert = CertUtils.getCertFromFile("ee.cer");
|
||||
X509Certificate caCert = CertUtils.getCertFromFile("ca.cer");
|
||||
ArrayList<X509Certificate> certs = new ArrayList<X509Certificate>();
|
||||
--
|
||||
1.8.3.1
|
||||
38
Fix-AsyncGCLog-s-content-consistent-bug.patch
Normal file
38
Fix-AsyncGCLog-s-content-consistent-bug.patch
Normal file
@ -0,0 +1,38 @@
|
||||
From a9c12b1881b227e537089c14bfcc3a00cfc7c1ac Mon Sep 17 00:00:00 2001
|
||||
From: eapen <zhangyipeng7@huawei.com>
|
||||
Date: Mon, 19 Dec 2022 21:12:55 +0800
|
||||
Subject: [PATCH 33/33] I68TO2: Fix AsyncGCLog's content consistent bug
|
||||
---
|
||||
hotspot/src/share/vm/runtime/java.cpp | 10 +++++-----
|
||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/hotspot/src/share/vm/runtime/java.cpp b/hotspot/src/share/vm/runtime/java.cpp
|
||||
index e2194dd..5b82a7a 100644
|
||||
--- a/hotspot/src/share/vm/runtime/java.cpp
|
||||
+++ b/hotspot/src/share/vm/runtime/java.cpp
|
||||
@@ -516,11 +516,6 @@ void before_exit(JavaThread * thread) {
|
||||
// Stop concurrent GC threads
|
||||
Universe::heap()->stop();
|
||||
|
||||
- // Stop async log writer thread
|
||||
- if (UseAsyncGCLog) {
|
||||
- AsyncLogWriter::instance()->stop();
|
||||
- }
|
||||
-
|
||||
// Print GC/heap related information.
|
||||
if (PrintGCDetails) {
|
||||
Universe::print();
|
||||
@@ -584,6 +579,11 @@ void before_exit(JavaThread * thread) {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Stop async log writer thread
|
||||
+ if (UseAsyncGCLog) {
|
||||
+ AsyncLogWriter::instance()->stop();
|
||||
+ }
|
||||
+
|
||||
#undef BEFORE_EXIT_NOT_RUN
|
||||
#undef BEFORE_EXIT_RUNNING
|
||||
#undef BEFORE_EXIT_DONE
|
||||
--
|
||||
1.8.3.1
|
||||
30
Fix-compactibleFreeListSpace-block_size_no_stall-cra.patch
Normal file
30
Fix-compactibleFreeListSpace-block_size_no_stall-cra.patch
Normal file
@ -0,0 +1,30 @@
|
||||
From 3d9fd51e13f76861e21293143b23c6936e030dfc Mon Sep 17 00:00:00 2001
|
||||
From: eapen <zhangyipeng7@huawei.com>
|
||||
Date: Wed, 14 Dec 2022 16:54:06 +0800
|
||||
Subject: [PATCH 16/33] I68TO2: Fix compactibleFreeListSpace::block_size_no_stall crash
|
||||
when use JMap parallel inspection of CMS GC
|
||||
---
|
||||
.../concurrentMarkSweep/concurrentMarkSweepGeneration.cpp | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
|
||||
index d31f9a5..c923e85 100644
|
||||
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
|
||||
@@ -2896,10 +2896,11 @@ void ConcurrentMarkSweepGeneration::object_iterate_block(ObjectClosure *cl, size
|
||||
}
|
||||
}
|
||||
}
|
||||
- if (prev_obj < span.end()) {
|
||||
- HeapWord *cur, *limit;
|
||||
+ HeapWord *limit = MIN2(cmsSpace()->end(), span.end());
|
||||
+ if (prev_obj < limit) {
|
||||
+ HeapWord *cur;
|
||||
size_t curSize;
|
||||
- for (cur = prev_obj, limit = span.end(); cur < limit; cur += curSize) {
|
||||
+ for (cur = prev_obj; cur < limit; cur += curSize) {
|
||||
curSize = cmsSpace()->block_size_no_stall(cur, _collector);
|
||||
if (curSize == 0) {
|
||||
break;
|
||||
--
|
||||
1.8.3.1
|
||||
116
Fix-the-crash-that-occurs-when-the-process-exits-due.patch
Normal file
116
Fix-the-crash-that-occurs-when-the-process-exits-due.patch
Normal file
@ -0,0 +1,116 @@
|
||||
From e635dce083e968ed54f8c7b7b059ce8c3c9ee717 Mon Sep 17 00:00:00 2001
|
||||
From: eapen <zhangyipeng7@huawei.com>
|
||||
Date: Fri, 16 Dec 2022 16:00:25 +0800
|
||||
Subject: [PATCH 32/33] I68TO2: Fix the crash that occurs when the process exits due to
|
||||
the mixed use of GCTrimNativeHeap and UseAsyncGCLog
|
||||
---
|
||||
hotspot/src/share/vm/runtime/java.cpp | 6 +++++
|
||||
hotspot/src/share/vm/runtime/logAsyncWriter.cpp | 35 ++++++++++++++++++++++++-
|
||||
hotspot/src/share/vm/runtime/logAsyncWriter.hpp | 4 +++
|
||||
3 files changed, 44 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hotspot/src/share/vm/runtime/java.cpp b/hotspot/src/share/vm/runtime/java.cpp
|
||||
index 54b980d..e2194dd 100644
|
||||
--- a/hotspot/src/share/vm/runtime/java.cpp
|
||||
+++ b/hotspot/src/share/vm/runtime/java.cpp
|
||||
@@ -54,6 +54,7 @@
|
||||
#include "runtime/init.hpp"
|
||||
#include "runtime/interfaceSupport.hpp"
|
||||
#include "runtime/java.hpp"
|
||||
+#include "runtime/logAsyncWriter.hpp"
|
||||
#include "runtime/memprofiler.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/statSampler.hpp"
|
||||
@@ -515,6 +516,11 @@ void before_exit(JavaThread * thread) {
|
||||
// Stop concurrent GC threads
|
||||
Universe::heap()->stop();
|
||||
|
||||
+ // Stop async log writer thread
|
||||
+ if (UseAsyncGCLog) {
|
||||
+ AsyncLogWriter::instance()->stop();
|
||||
+ }
|
||||
+
|
||||
// Print GC/heap related information.
|
||||
if (PrintGCDetails) {
|
||||
Universe::print();
|
||||
diff --git a/hotspot/src/share/vm/runtime/logAsyncWriter.cpp b/hotspot/src/share/vm/runtime/logAsyncWriter.cpp
|
||||
index 750a23f..7722020 100644
|
||||
--- a/hotspot/src/share/vm/runtime/logAsyncWriter.cpp
|
||||
+++ b/hotspot/src/share/vm/runtime/logAsyncWriter.cpp
|
||||
@@ -63,7 +63,7 @@ void AsyncLogWriter::enqueue(const char* msg) {
|
||||
AsyncLogWriter::AsyncLogWriter()
|
||||
: NamedThread(),
|
||||
_lock(1), _sem(0), _io_sem(1),
|
||||
- _initialized(false),
|
||||
+ _initialized(false),_should_terminate(false),_has_terminated(false),
|
||||
_buffer_max_size(AsyncLogBufferSize / sizeof(AsyncLogMessage)) {
|
||||
if (os::create_thread(this, os::asynclog_thread)) {
|
||||
_initialized = true;
|
||||
@@ -124,6 +124,10 @@ void AsyncLogWriter::run() {
|
||||
// The value of a semphore cannot be negative. Therefore, the current thread falls asleep
|
||||
// when its value is zero. It will be waken up when new messages are enqueued.
|
||||
_sem.wait();
|
||||
+ if (_should_terminate) {
|
||||
+ terminate();
|
||||
+ break;
|
||||
+ }
|
||||
write();
|
||||
}
|
||||
}
|
||||
@@ -162,3 +166,32 @@ void AsyncLogWriter::print_on(outputStream* st) const{
|
||||
Thread::print_on(st);
|
||||
st->cr();
|
||||
}
|
||||
+
|
||||
+void AsyncLogWriter::stop() {
|
||||
+ {
|
||||
+ MutexLockerEx ml(Terminator_lock);
|
||||
+ _should_terminate = true;
|
||||
+ }
|
||||
+ {
|
||||
+ _sem.signal();
|
||||
+ }
|
||||
+ {
|
||||
+ MutexLockerEx ml(Terminator_lock);
|
||||
+ while (!_has_terminated) {
|
||||
+ Terminator_lock->wait();
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void AsyncLogWriter::terminate() {
|
||||
+ // Signal that it is terminated
|
||||
+ {
|
||||
+ MutexLockerEx mu(Terminator_lock,
|
||||
+ Mutex::_no_safepoint_check_flag);
|
||||
+ _has_terminated = true;
|
||||
+ Terminator_lock->notify();
|
||||
+ }
|
||||
+
|
||||
+ // Thread destructor usually does this..
|
||||
+ ThreadLocalStorage::set_thread(NULL);
|
||||
+}
|
||||
diff --git a/hotspot/src/share/vm/runtime/logAsyncWriter.hpp b/hotspot/src/share/vm/runtime/logAsyncWriter.hpp
|
||||
index 5242426..54e5d48 100644
|
||||
--- a/hotspot/src/share/vm/runtime/logAsyncWriter.hpp
|
||||
+++ b/hotspot/src/share/vm/runtime/logAsyncWriter.hpp
|
||||
@@ -136,6 +136,8 @@ class AsyncLogWriter : public NamedThread {
|
||||
Semaphore _io_sem;
|
||||
|
||||
volatile bool _initialized;
|
||||
+ volatile bool _should_terminate;
|
||||
+ volatile bool _has_terminated;
|
||||
AsyncLogBuffer _buffer;
|
||||
|
||||
const size_t _buffer_max_size;
|
||||
@@ -153,6 +155,8 @@ class AsyncLogWriter : public NamedThread {
|
||||
static void flush();
|
||||
// Printing
|
||||
void print_on(outputStream* st) const;
|
||||
+ void stop();
|
||||
+ void terminate();
|
||||
|
||||
};
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
67
Print-class-loading-details-when-enable-TraceClassLo.patch
Normal file
67
Print-class-loading-details-when-enable-TraceClassLo.patch
Normal file
@ -0,0 +1,67 @@
|
||||
From 3b427b4702ac1ccdfa47fc46522fc06884abf394 Mon Sep 17 00:00:00 2001
|
||||
From: eapen <zhangyipeng7@huawei.com>
|
||||
Date: Fri, 16 Dec 2022 09:23:41 +0800
|
||||
Subject: [PATCH 24/33] I68TO2: Print class loading details when enable
|
||||
TraceClassLoading
|
||||
---
|
||||
hotspot/src/share/vm/classfile/classFileParser.cpp | 25 +++++++++++++++++++---
|
||||
hotspot/src/share/vm/runtime/globals.hpp | 8 +++++++
|
||||
2 files changed, 30 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp
|
||||
index ae91995..3ec6aec 100644
|
||||
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp
|
||||
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp
|
||||
@@ -4323,9 +4323,28 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
||||
if (TraceClassLoading) {
|
||||
ResourceMark rm;
|
||||
// print in a single call to reduce interleaving of output
|
||||
- if (cfs->source() != NULL) {
|
||||
- tty->print("[Loaded %s from %s]\n", this_klass->external_name(),
|
||||
- cfs->source());
|
||||
+ const char* source = cfs->source();
|
||||
+ if (source != NULL && PrintClassLoadingDetails) {
|
||||
+ tty->date_stamp(true);
|
||||
+ OSThread* osThread = THREAD->osthread();
|
||||
+ if (osThread != NULL) {
|
||||
+ tty->print("%d ", osThread->thread_id());
|
||||
+ }
|
||||
+ const char* loader_name = class_loader.is_null()
|
||||
+ ? "bootstrap"
|
||||
+ : InstanceKlass::cast(class_loader->klass())->external_name();
|
||||
+ const char* klass_name = this_klass->external_name();
|
||||
+ tty->print(" [Loaded %s from %s by classloader %s]\n", klass_name,
|
||||
+ source, loader_name);
|
||||
+ if (PrintThreadStackOnLoadingClass != NULL && klass_name != NULL &&
|
||||
+ strstr(klass_name, PrintThreadStackOnLoadingClass) && THREAD->is_Java_thread()) {
|
||||
+ JavaThread* javaThread = ((JavaThread*) THREAD);
|
||||
+ javaThread->print_on(tty);
|
||||
+ javaThread->print_stack_on(tty);
|
||||
+ }
|
||||
+ } else if (source != NULL) {
|
||||
+ tty->print("[Loaded %s from %s]\n", this_klass->external_name(),
|
||||
+ source);
|
||||
} else if (class_loader.is_null()) {
|
||||
Klass* caller =
|
||||
THREAD->is_Java_thread()
|
||||
diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
|
||||
index d1e3cda..14c3c89 100644
|
||||
--- a/hotspot/src/share/vm/runtime/globals.hpp
|
||||
+++ b/hotspot/src/share/vm/runtime/globals.hpp
|
||||
@@ -951,6 +951,14 @@ class CommandLineFlags {
|
||||
product(ccstrlist, OnOutOfMemoryError, "", \
|
||||
"Run user-defined commands on first java.lang.OutOfMemoryError") \
|
||||
\
|
||||
+ manageable(bool, PrintClassLoadingDetails, false, \
|
||||
+ "Print class loading details (including date stamps, thread id " \
|
||||
+ "and effective class loaders) when enable TraceClassLoading") \
|
||||
+ \
|
||||
+ manageable(ccstr, PrintThreadStackOnLoadingClass, NULL, \
|
||||
+ "Print thread stack when the specified class is loaded when " \
|
||||
+ "enable PrintClassLoadingDetails") \
|
||||
+ \
|
||||
manageable(bool, HeapDumpBeforeFullGC, false, \
|
||||
"Dump heap to file before any major stop-the-world GC") \
|
||||
\
|
||||
--
|
||||
1.8.3.1
|
||||
23
fix-the-length-value-of-ciBlock-in-ciMethodBlocks.cp.patch
Normal file
23
fix-the-length-value-of-ciBlock-in-ciMethodBlocks.cp.patch
Normal file
@ -0,0 +1,23 @@
|
||||
From 102b398cc59e95cb4f5327b9c8fc9a3c5594acce Mon Sep 17 00:00:00 2001
|
||||
From: eapen <zhangyipeng7@huawei.com>
|
||||
Date: Tue, 29 Nov 2022 09:23:01 +0800
|
||||
Subject: [PATCH 29/33] I68TO2: fix the length value of ciBlock in ciMethodBlocks.cpp
|
||||
---
|
||||
hotspot/src/share/vm/ci/ciMethodBlocks.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hotspot/src/share/vm/ci/ciMethodBlocks.cpp b/hotspot/src/share/vm/ci/ciMethodBlocks.cpp
|
||||
index 614e75d..3ce828e 100644
|
||||
--- a/hotspot/src/share/vm/ci/ciMethodBlocks.cpp
|
||||
+++ b/hotspot/src/share/vm/ci/ciMethodBlocks.cpp
|
||||
@@ -372,7 +372,7 @@ static const char *flagnames[] = {
|
||||
|
||||
void ciBlock::dump() {
|
||||
tty->print(" [%d .. %d), {", _start_bci, _limit_bci);
|
||||
- for (int i = 0; i < 8; i++) {
|
||||
+ for (int i = 0; i < 7; i++) {
|
||||
if ((_flags & (1 << i)) != 0) {
|
||||
tty->print(" %s", flagnames[i]);
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
@ -916,7 +916,7 @@ Provides: java-%{javaver}-%{origin}-accessibility%{?1} = %{epoch}:%{version}-%{r
|
||||
|
||||
Name: java-%{javaver}-%{origin}
|
||||
Version: %{javaver}.%{updatever}.%{buildver}
|
||||
Release: 4
|
||||
Release: 5
|
||||
# java-1.5.0-ibm from jpackage.org set Epoch to 1 for unknown reasons
|
||||
# and this change was brought into RHEL-4. java-1.5.0-ibm packages
|
||||
# also included the epoch in their virtual provides. This created a
|
||||
@ -1153,6 +1153,35 @@ Patch264: 8287109-Distrust-failed-with-CertificateExpired.patch
|
||||
Patch265: cve-2022-37434-Fix-a-bug-when-getting-a-gzip-header-extra-field-with-inflate.patch
|
||||
Patch266: 8065895-Synchronous-signals-during-error-reporting-may-terminate-or-hang-vm-process.patch
|
||||
Patch267: Huawei-fix-windows-build-Dynamic-CDS-failure.patch
|
||||
Patch268: 8296480-Fix-the-problem-that-the-TestPolicy.java-cas.patch
|
||||
Patch269: 8296485-BuildEEBasicConstraints.java-test-fails-with.patch
|
||||
Patch270: 8294357-tz-Update-Timezone-Data-to-2022d.patch
|
||||
Patch271: 8296241-tz-Update-Timezone-Data-to-2022e.patch
|
||||
Patch272: 8296108-tz-Update-Timezone-Data-to-2022f.patch
|
||||
Patch273: 8257695-linux-Add-process-memory-information-to-hs-e.patch
|
||||
Patch274: 8261167-print_process_memory_info-add-a-close-call-a.patch
|
||||
Patch275: 8268893-jcmd-to-trim-the-glibc-heap.patch
|
||||
Patch276: 8263185-Mallinfo-deprecated-in-glibc-2.33.patch
|
||||
Patch277: 8293114-GC-should-trim-the-native-heap-and-bug-fix.patch
|
||||
Patch278: 8275775-Add-jcmd-VM.classes-to-print-details-of-all-.patch
|
||||
Patch279: Fix-compactibleFreeListSpace-block_size_no_stall-cra.patch
|
||||
Patch280: 8203682-Add-jcmd-VM.classloaders-command-to-print-ou.patch
|
||||
Patch281: 8229517-Support-for-optional-asynchronous-buffered-l.patch
|
||||
Patch282: 8189688-NMT-Report-per-class-load-metadata-informati.patch
|
||||
Patch283: 8219584-Try-to-dump-error-file-by-thread-which-cause.patch
|
||||
Patch284: 8204595-add-more-thread-related-system-settings-info.patch
|
||||
Patch285: 8198553-jcmd-separate-Metaspace-statistics-from-NMT.patch
|
||||
Patch286: 8242181-Show-source-information-when-printing-native.patch
|
||||
Patch287: Print-class-loading-details-when-enable-TraceClassLo.patch
|
||||
Patch288: 8200720-Print-additional-information-in-thread-dump-.patch
|
||||
Patch289: support-numactl-for-hadoop-yarn.patch
|
||||
Patch290: 8232069-enable-shutdown-UseCompressedClassPointers-U.patch
|
||||
Patch291: 8065402-G1-does-not-expand-marking-stack-when-mark-s.patch
|
||||
Patch292: fix-the-length-value-of-ciBlock-in-ciMethodBlocks.cp.patch
|
||||
Patch293: 8140594-Various-minor-code-improvements-compiler.patch
|
||||
Patch294: Fix-the-crash-that-occurs-when-the-process-exits-due.patch
|
||||
Patch295: Fix-AsyncGCLog-s-content-consistent-bug.patch
|
||||
|
||||
|
||||
#############################################
|
||||
#
|
||||
@ -1646,6 +1675,34 @@ pushd %{top_level_dir_name}
|
||||
%patch265 -p1
|
||||
%patch266 -p1
|
||||
%patch267 -p1
|
||||
%patch268 -p1
|
||||
%patch269 -p1
|
||||
%patch270 -p1
|
||||
%patch271 -p1
|
||||
%patch272 -p1
|
||||
%patch273 -p1
|
||||
%patch274 -p1
|
||||
%patch275 -p1
|
||||
%patch276 -p1
|
||||
%patch277 -p1
|
||||
%patch278 -p1
|
||||
%patch279 -p1
|
||||
%patch280 -p1
|
||||
%patch281 -p1
|
||||
%patch282 -p1
|
||||
%patch283 -p1
|
||||
%patch284 -p1
|
||||
%patch285 -p1
|
||||
%patch286 -p1
|
||||
%patch287 -p1
|
||||
%patch288 -p1
|
||||
%patch289 -p1
|
||||
%patch290 -p1
|
||||
%patch291 -p1
|
||||
%patch292 -p1
|
||||
%patch293 -p1
|
||||
%patch294 -p1
|
||||
%patch295 -p1
|
||||
popd
|
||||
|
||||
# System library fixes
|
||||
@ -2270,6 +2327,36 @@ cjc.mainProgram(arg)
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Wed Jan 11 2023 eapen<zhangyipeng7@huawei.com> - 1:1.8.0.352-b08.5
|
||||
- add 8296480-Fix-the-problem-that-the-TestPolicy.java-cas.patch
|
||||
- add 8296485-BuildEEBasicConstraints.java-test-fails-with.patch
|
||||
- add 8294357-tz-Update-Timezone-Data-to-2022d.patch
|
||||
- add 8296241-tz-Update-Timezone-Data-to-2022e.patch
|
||||
- add 8296108-tz-Update-Timezone-Data-to-2022f.patch
|
||||
- add 8257695-linux-Add-process-memory-information-to-hs-e.patch
|
||||
- add 8261167-print_process_memory_info-add-a-close-call-a.patch
|
||||
- add 8268893-jcmd-to-trim-the-glibc-heap.patch
|
||||
- add 8263185-Mallinfo-deprecated-in-glibc-2.33.patch
|
||||
- add 8293114-GC-should-trim-the-native-heap-and-bug-fix.patch
|
||||
- add 8275775-Add-jcmd-VM.classes-to-print-details-of-all-.patch
|
||||
- add Fix-compactibleFreeListSpace-block_size_no_stall-cra.patch
|
||||
- add 8203682-Add-jcmd-VM.classloaders-command-to-print-ou.patch
|
||||
- add 8229517-Support-for-optional-asynchronous-buffered-l.patch
|
||||
- add 8189688-NMT-Report-per-class-load-metadata-informati.patch
|
||||
- add 8219584-Try-to-dump-error-file-by-thread-which-cause.patch
|
||||
- add 8204595-add-more-thread-related-system-settings-info.patch
|
||||
- add 8198553-jcmd-separate-Metaspace-statistics-from-NMT.patch
|
||||
- add 8242181-Show-source-information-when-printing-native.patch
|
||||
- add Print-class-loading-details-when-enable-TraceClassLo.patch
|
||||
- add 8200720-Print-additional-information-in-thread-dump-.patch
|
||||
- add support-numactl-for-hadoop-yarn.patch
|
||||
- add 8232069-enable-shutdown-UseCompressedClassPointers-U.patch
|
||||
- add 8065402-G1-does-not-expand-marking-stack-when-mark-s.patch
|
||||
- add fix-the-length-value-of-ciBlock-in-ciMethodBlocks.cp.patch
|
||||
- add 8140594-Various-minor-code-improvements-compiler.patch
|
||||
- add Fix-the-crash-that-occurs-when-the-process-exits-due.patch
|
||||
- add Fix-AsyncGCLog-s-content-consistent-bug.patch
|
||||
|
||||
* Tue Oct 25 2022 kuenking111<wangkun49@huawei.com> - 1:1.8.0.352-b08.4
|
||||
- add Huawei-fix-windows-build-Dynamic-CDS-failure.patch
|
||||
|
||||
|
||||
599
support-numactl-for-hadoop-yarn.patch
Normal file
599
support-numactl-for-hadoop-yarn.patch
Normal file
@ -0,0 +1,599 @@
|
||||
From db8bc872fb7a132cb3c2363dcb3a7aa8b0a5827e Mon Sep 17 00:00:00 2001
|
||||
From: eapen <zhangyipeng7@huawei.com>
|
||||
Date: Mon, 25 Jul 2022 16:41:24 +0800
|
||||
Subject: [PATCH 26/33] I68TO2: support numactl for hadoop yarn
|
||||
---
|
||||
hotspot/make/aix/makefiles/mapfile-vers-debug | 1 +
|
||||
hotspot/make/aix/makefiles/mapfile-vers-product | 1 +
|
||||
hotspot/make/linux/makefiles/mapfile-vers-debug | 1 +
|
||||
hotspot/make/linux/makefiles/mapfile-vers-product | 1 +
|
||||
hotspot/make/solaris/makefiles/mapfile-vers | 1 +
|
||||
hotspot/make/windows/jvmexp.lcf | 1 +
|
||||
hotspot/make/windows/jvmexp_g.lcf | 1 +
|
||||
hotspot/make/windows/makefiles/vm.make | 1 +
|
||||
hotspot/src/os/linux/vm/os_linux.cpp | 91 +++++++++++++++++++
|
||||
hotspot/src/os/linux/vm/os_linux.hpp | 51 +++++++++++
|
||||
hotspot/src/share/vm/prims/jni.cpp | 6 ++
|
||||
hotspot/src/share/vm/prims/jni.h | 3 +
|
||||
hotspot/src/share/vm/runtime/globals.hpp | 13 +++
|
||||
.../runtime/containers/docker/CPUSetsReader.java | 9 ++
|
||||
.../runtime/containers/docker/TestNUMANodes.java | 102 +++++++++++++++++++++
|
||||
jdk/src/share/bin/java.c | 2 +
|
||||
jdk/src/share/bin/java.h | 3 +
|
||||
jdk/src/share/javavm/export/jni.h | 3 +
|
||||
jdk/src/solaris/bin/java_md_solinux.c | 7 ++
|
||||
19 files changed, 298 insertions(+)
|
||||
create mode 100644 hotspot/test/runtime/containers/docker/TestNUMANodes.java
|
||||
|
||||
diff --git a/hotspot/make/aix/makefiles/mapfile-vers-debug b/hotspot/make/aix/makefiles/mapfile-vers-debug
|
||||
index 760f955..127794c 100644
|
||||
--- a/hotspot/make/aix/makefiles/mapfile-vers-debug
|
||||
+++ b/hotspot/make/aix/makefiles/mapfile-vers-debug
|
||||
@@ -28,6 +28,7 @@ SUNWprivate_1.1 {
|
||||
global:
|
||||
# JNI
|
||||
JNI_CreateJavaVM;
|
||||
+ JNI_SetCParam;
|
||||
JNI_GetCreatedJavaVMs;
|
||||
JNI_GetDefaultJavaVMInitArgs;
|
||||
|
||||
diff --git a/hotspot/make/aix/makefiles/mapfile-vers-product b/hotspot/make/aix/makefiles/mapfile-vers-product
|
||||
index e84b671..2bbfb32 100644
|
||||
--- a/hotspot/make/aix/makefiles/mapfile-vers-product
|
||||
+++ b/hotspot/make/aix/makefiles/mapfile-vers-product
|
||||
@@ -28,6 +28,7 @@ SUNWprivate_1.1 {
|
||||
global:
|
||||
# JNI
|
||||
JNI_CreateJavaVM;
|
||||
+ JNI_SetCParam;
|
||||
JNI_GetCreatedJavaVMs;
|
||||
JNI_GetDefaultJavaVMInitArgs;
|
||||
|
||||
diff --git a/hotspot/make/linux/makefiles/mapfile-vers-debug b/hotspot/make/linux/makefiles/mapfile-vers-debug
|
||||
index 48b4f9d..1ebe436 100644
|
||||
--- a/hotspot/make/linux/makefiles/mapfile-vers-debug
|
||||
+++ b/hotspot/make/linux/makefiles/mapfile-vers-debug
|
||||
@@ -28,6 +28,7 @@ SUNWprivate_1.1 {
|
||||
global:
|
||||
# JNI
|
||||
JNI_CreateJavaVM;
|
||||
+ JNI_SetCParam;
|
||||
JNI_GetCreatedJavaVMs;
|
||||
JNI_GetDefaultJavaVMInitArgs;
|
||||
|
||||
diff --git a/hotspot/make/linux/makefiles/mapfile-vers-product b/hotspot/make/linux/makefiles/mapfile-vers-product
|
||||
index d4100d7..75e5278 100644
|
||||
--- a/hotspot/make/linux/makefiles/mapfile-vers-product
|
||||
+++ b/hotspot/make/linux/makefiles/mapfile-vers-product
|
||||
@@ -28,6 +28,7 @@ SUNWprivate_1.1 {
|
||||
global:
|
||||
# JNI
|
||||
JNI_CreateJavaVM;
|
||||
+ JNI_SetCParam;
|
||||
JNI_GetCreatedJavaVMs;
|
||||
JNI_GetDefaultJavaVMInitArgs;
|
||||
|
||||
diff --git a/hotspot/make/solaris/makefiles/mapfile-vers b/hotspot/make/solaris/makefiles/mapfile-vers
|
||||
index 26288b7..41045dd 100644
|
||||
--- a/hotspot/make/solaris/makefiles/mapfile-vers
|
||||
+++ b/hotspot/make/solaris/makefiles/mapfile-vers
|
||||
@@ -28,6 +28,7 @@ SUNWprivate_1.1 {
|
||||
global:
|
||||
# JNI
|
||||
JNI_CreateJavaVM;
|
||||
+ JNI_SetCParam;
|
||||
JNI_GetCreatedJavaVMs;
|
||||
JNI_GetDefaultJavaVMInitArgs;
|
||||
|
||||
diff --git a/hotspot/make/windows/jvmexp.lcf b/hotspot/make/windows/jvmexp.lcf
|
||||
index 6489d02..4bba798 100644
|
||||
--- a/hotspot/make/windows/jvmexp.lcf
|
||||
+++ b/hotspot/make/windows/jvmexp.lcf
|
||||
@@ -1,5 +1,6 @@
|
||||
-export:JNI_GetDefaultJavaVMInitArgs
|
||||
-export:JNI_CreateJavaVM
|
||||
+-export:JNI_SetCParam;
|
||||
-export:JNI_GetCreatedJavaVMs
|
||||
|
||||
-export:jio_snprintf
|
||||
diff --git a/hotspot/make/windows/jvmexp_g.lcf b/hotspot/make/windows/jvmexp_g.lcf
|
||||
index 6489d02..4bba798 100644
|
||||
--- a/hotspot/make/windows/jvmexp_g.lcf
|
||||
+++ b/hotspot/make/windows/jvmexp_g.lcf
|
||||
@@ -1,5 +1,6 @@
|
||||
-export:JNI_GetDefaultJavaVMInitArgs
|
||||
-export:JNI_CreateJavaVM
|
||||
+-export:JNI_SetCParam;
|
||||
-export:JNI_GetCreatedJavaVMs
|
||||
|
||||
-export:jio_snprintf
|
||||
diff --git a/hotspot/make/windows/makefiles/vm.make b/hotspot/make/windows/makefiles/vm.make
|
||||
index 5322a4b..fd5e5d2 100644
|
||||
--- a/hotspot/make/windows/makefiles/vm.make
|
||||
+++ b/hotspot/make/windows/makefiles/vm.make
|
||||
@@ -86,6 +86,7 @@ AGCT_EXPORT=/export:AsyncGetCallTrace
|
||||
LD_FLAGS=$(LD_FLAGS) $(STACK_SIZE) /subsystem:windows /dll /base:0x8000000 \
|
||||
/export:JNI_GetDefaultJavaVMInitArgs \
|
||||
/export:JNI_CreateJavaVM \
|
||||
+ /export:JNI_SetCParam \
|
||||
/export:JVM_FindClassFromBootLoader \
|
||||
/export:JNI_GetCreatedJavaVMs \
|
||||
/export:jio_snprintf \
|
||||
diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp
|
||||
index 1ec68ab..ab28ee3 100644
|
||||
--- a/hotspot/src/os/linux/vm/os_linux.cpp
|
||||
+++ b/hotspot/src/os/linux/vm/os_linux.cpp
|
||||
@@ -133,6 +133,8 @@ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
|
||||
#define LARGEPAGES_BIT (1 << 6)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// global variables
|
||||
+extern char** argv_for_execvp;
|
||||
+
|
||||
julong os::Linux::_physical_memory = 0;
|
||||
|
||||
address os::Linux::_initial_thread_stack_bottom = NULL;
|
||||
@@ -3129,6 +3131,77 @@ void* os::Linux::libnuma_v2_dlsym(void* handle, const char* name) {
|
||||
return dlvsym(handle, name, "libnuma_1.2");
|
||||
}
|
||||
|
||||
+void os::Linux::parse_numa_nodes() {
|
||||
+ if (NUMANodes == NULL && NUMANodesRandom == 0) {
|
||||
+ return;
|
||||
+ }
|
||||
+ const char* numa_nodes = NUMANodes;
|
||||
+ // Max length for "%d-%d" is 24
|
||||
+ char buf[24] = {0};
|
||||
+ if (NUMANodesRandom != 0) {
|
||||
+ int nodes_to_bind = NUMANodesRandom;
|
||||
+ int nodes_num = Linux::numa_max_node() + 1;
|
||||
+ const int MAX_NUMA = 1000000;
|
||||
+ if (nodes_num > 0 &&
|
||||
+ nodes_num < MAX_NUMA &&
|
||||
+ nodes_to_bind > 0 &&
|
||||
+ nodes_to_bind < nodes_num) {
|
||||
+ int bound = 1;
|
||||
+ while (bound < nodes_to_bind) {
|
||||
+ bound *= 2;
|
||||
+ }
|
||||
+ struct timeval tv;
|
||||
+ gettimeofday(&tv,NULL);
|
||||
+ srand(tv.tv_usec);
|
||||
+ int first = 0;
|
||||
+ if (nodes_num > bound) {
|
||||
+ first = rand() % (nodes_num / bound) * bound;
|
||||
+ }
|
||||
+ if (bound != nodes_to_bind) {
|
||||
+ first += rand() % (1 + bound - nodes_to_bind);
|
||||
+ }
|
||||
+ sprintf(buf, "%d-%d", first, first + nodes_to_bind - 1);
|
||||
+ numa_nodes = buf;
|
||||
+ if (LogNUMANodes) {
|
||||
+ warning("NUMANodes is converted to %s, with total %d nodes!", buf, nodes_num);
|
||||
+ }
|
||||
+ } else {
|
||||
+ if (LogNUMANodes) {
|
||||
+ warning("The count of nodes to bind should be less that the count of all nodes, Skip!");
|
||||
+ }
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ bitmask* mask = os::Linux::numa_parse_nodestring_all(numa_nodes);
|
||||
+ if (!mask) {
|
||||
+ if (LogNUMANodes) {
|
||||
+ warning("<%s> is invalid", numa_nodes);
|
||||
+ }
|
||||
+ return;
|
||||
+ }
|
||||
+ if (os::Linux::numa_bitmask_equal(mask, os::Linux::_numa_membind_bitmask)) {
|
||||
+ os::Linux::numa_bitmask_free(mask);
|
||||
+ if (LogNUMANodes) {
|
||||
+ warning("Mempolicy is not changed, param: %s", numa_nodes);
|
||||
+ }
|
||||
+ return;
|
||||
+ }
|
||||
+ errno = 0;
|
||||
+ os::Linux::numa_run_on_node_mask(mask);
|
||||
+ if (errno) {
|
||||
+ perror("sched_setaffinity");
|
||||
+ }
|
||||
+ errno = 0;
|
||||
+ os::Linux::numa_set_membind(mask);
|
||||
+ int errtmp = errno;
|
||||
+ os::Linux::numa_bitmask_free(mask);
|
||||
+ if (errtmp) {
|
||||
+ perror("numa_set_membind");
|
||||
+ } else {
|
||||
+ execvp(*argv_for_execvp, argv_for_execvp);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
bool os::Linux::libnuma_init() {
|
||||
// sched_getcpu() should be in libc.
|
||||
set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t,
|
||||
@@ -3169,6 +3242,16 @@ bool os::Linux::libnuma_init() {
|
||||
libnuma_dlsym(handle, "numa_move_pages")));
|
||||
set_numa_run_on_node(CAST_TO_FN_PTR(numa_run_on_node_func_t,
|
||||
libnuma_dlsym(handle, "numa_run_on_node")));
|
||||
+ set_numa_parse_nodestring_all(CAST_TO_FN_PTR(numa_parse_nodestring_all_func_t,
|
||||
+ libnuma_dlsym(handle, "numa_parse_nodestring_all")));
|
||||
+ set_numa_run_on_node_mask(CAST_TO_FN_PTR(numa_run_on_node_mask_func_t,
|
||||
+ libnuma_v2_dlsym(handle, "numa_run_on_node_mask")));
|
||||
+ set_numa_bitmask_equal(CAST_TO_FN_PTR(numa_bitmask_equal_func_t,
|
||||
+ libnuma_v2_dlsym(handle, "numa_bitmask_equal")));
|
||||
+ set_numa_set_membind(CAST_TO_FN_PTR(numa_set_membind_func_t,
|
||||
+ libnuma_v2_dlsym(handle, "numa_set_membind")));
|
||||
+ set_numa_bitmask_free(CAST_TO_FN_PTR(numa_bitmask_free_func_t,
|
||||
+ libnuma_dlsym(handle, "numa_bitmask_free")));
|
||||
|
||||
if (numa_available() != -1) {
|
||||
set_numa_all_nodes((unsigned long*)libnuma_dlsym(handle, "numa_all_nodes"));
|
||||
@@ -3176,6 +3259,9 @@ bool os::Linux::libnuma_init() {
|
||||
set_numa_nodes_ptr((struct bitmask **)libnuma_dlsym(handle, "numa_nodes_ptr"));
|
||||
set_numa_interleave_bitmask(_numa_get_interleave_mask());
|
||||
set_numa_membind_bitmask(_numa_get_membind());
|
||||
+ if (isbound_to_all_node()) {
|
||||
+ parse_numa_nodes();
|
||||
+ }
|
||||
// Create an index -> node mapping, since nodes are not always consecutive
|
||||
_nindex_to_node = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<int>(0, true);
|
||||
rebuild_nindex_to_node_map();
|
||||
@@ -3295,6 +3381,11 @@ os::Linux::numa_get_membind_func_t os::Linux::_numa_get_membind;
|
||||
os::Linux::numa_get_interleave_mask_func_t os::Linux::_numa_get_interleave_mask;
|
||||
os::Linux::numa_move_pages_func_t os::Linux::_numa_move_pages;
|
||||
os::Linux::numa_run_on_node_func_t os::Linux::_numa_run_on_node;
|
||||
+os::Linux::numa_parse_nodestring_all_func_t os::Linux::_numa_parse_nodestring_all;
|
||||
+os::Linux::numa_run_on_node_mask_func_t os::Linux::_numa_run_on_node_mask;
|
||||
+os::Linux::numa_bitmask_equal_func_t os::Linux::_numa_bitmask_equal;
|
||||
+os::Linux::numa_set_membind_func_t os::Linux::_numa_set_membind;
|
||||
+os::Linux::numa_bitmask_free_func_t os::Linux::_numa_bitmask_free;
|
||||
os::Linux::NumaAllocationPolicy os::Linux::_current_numa_policy;
|
||||
unsigned long* os::Linux::_numa_all_nodes;
|
||||
struct bitmask* os::Linux::_numa_all_nodes_ptr;
|
||||
diff --git a/hotspot/src/os/linux/vm/os_linux.hpp b/hotspot/src/os/linux/vm/os_linux.hpp
|
||||
index 4ee2c9b..18ac68f 100644
|
||||
--- a/hotspot/src/os/linux/vm/os_linux.hpp
|
||||
+++ b/hotspot/src/os/linux/vm/os_linux.hpp
|
||||
@@ -195,6 +195,7 @@ class Linux {
|
||||
static bool is_floating_stack() { return _is_floating_stack; }
|
||||
|
||||
static void libpthread_init();
|
||||
+ static void parse_numa_nodes();
|
||||
static bool libnuma_init();
|
||||
static void* libnuma_dlsym(void* handle, const char* name);
|
||||
// libnuma v2 (libnuma_1.2) symbols
|
||||
@@ -283,6 +284,11 @@ private:
|
||||
typedef struct bitmask* (*numa_get_interleave_mask_func_t)(void);
|
||||
typedef long (*numa_move_pages_func_t)(int pid, unsigned long count, void **pages, const int *nodes, int *status, int flags);
|
||||
typedef int (*numa_run_on_node_func_t)(int node);
|
||||
+ typedef struct bitmask* (*numa_parse_nodestring_all_func_t)(const char*);
|
||||
+ typedef int (*numa_run_on_node_mask_func_t)(struct bitmask* mask);
|
||||
+ typedef void (*numa_set_membind_func_t)(struct bitmask* mask);
|
||||
+ typedef int (*numa_bitmask_equal_func_t)(struct bitmask* mask, struct bitmask* mask1);
|
||||
+ typedef void (*numa_bitmask_free_func_t)(struct bitmask* mask);
|
||||
|
||||
typedef void (*numa_set_bind_policy_func_t)(int policy);
|
||||
typedef int (*numa_bitmask_isbitset_func_t)(struct bitmask *bmp, unsigned int n);
|
||||
@@ -303,6 +309,11 @@ private:
|
||||
static numa_get_interleave_mask_func_t _numa_get_interleave_mask;
|
||||
static numa_move_pages_func_t _numa_move_pages;
|
||||
static numa_run_on_node_func_t _numa_run_on_node;
|
||||
+ static numa_parse_nodestring_all_func_t _numa_parse_nodestring_all;
|
||||
+ static numa_run_on_node_mask_func_t _numa_run_on_node_mask;
|
||||
+ static numa_bitmask_equal_func_t _numa_bitmask_equal;
|
||||
+ static numa_set_membind_func_t _numa_set_membind;
|
||||
+ static numa_bitmask_free_func_t _numa_bitmask_free;
|
||||
|
||||
static unsigned long* _numa_all_nodes;
|
||||
static struct bitmask* _numa_all_nodes_ptr;
|
||||
@@ -325,6 +336,11 @@ private:
|
||||
static void set_numa_get_interleave_mask(numa_get_interleave_mask_func_t func) { _numa_get_interleave_mask = func; }
|
||||
static void set_numa_move_pages(numa_move_pages_func_t func) { _numa_move_pages = func; }
|
||||
static void set_numa_run_on_node(numa_run_on_node_func_t func) { _numa_run_on_node = func; }
|
||||
+ static void set_numa_parse_nodestring_all(numa_parse_nodestring_all_func_t func) { _numa_parse_nodestring_all = func; }
|
||||
+ static void set_numa_run_on_node_mask(numa_run_on_node_mask_func_t func) { _numa_run_on_node_mask = func; }
|
||||
+ static void set_numa_bitmask_equal(numa_bitmask_equal_func_t func) { _numa_bitmask_equal = func; }
|
||||
+ static void set_numa_set_membind(numa_set_membind_func_t func) { _numa_set_membind = func; }
|
||||
+ static void set_numa_bitmask_free(numa_bitmask_free_func_t func) { _numa_bitmask_free = func; }
|
||||
static void set_numa_all_nodes(unsigned long* ptr) { _numa_all_nodes = ptr; }
|
||||
static void set_numa_all_nodes_ptr(struct bitmask **ptr) { _numa_all_nodes_ptr = (ptr == NULL ? NULL : *ptr); }
|
||||
static void set_numa_nodes_ptr(struct bitmask **ptr) { _numa_nodes_ptr = (ptr == NULL ? NULL : *ptr); }
|
||||
@@ -472,6 +488,41 @@ public:
|
||||
static mallinfo_retval_t get_mallinfo(glibc_mallinfo2* out);
|
||||
#endif
|
||||
|
||||
+ static bool isbound_to_all_node() {
|
||||
+ if (_numa_membind_bitmask != NULL && _numa_max_node != NULL && _numa_bitmask_isbitset != NULL) {
|
||||
+ unsigned int highest_node_number = _numa_max_node();
|
||||
+ for (unsigned int node = 0; node <= highest_node_number; node++) {
|
||||
+ if (!_numa_bitmask_isbitset(_numa_membind_bitmask, node)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ static bitmask* numa_parse_nodestring_all(const char* s) {
|
||||
+ return _numa_parse_nodestring_all != NULL ? _numa_parse_nodestring_all(s) : NULL;
|
||||
+ }
|
||||
+
|
||||
+ static int numa_run_on_node_mask(bitmask* bitmask) {
|
||||
+ return _numa_run_on_node_mask != NULL ? _numa_run_on_node_mask(bitmask) : -1;
|
||||
+ }
|
||||
+
|
||||
+ static int numa_bitmask_equal(bitmask* bitmask, struct bitmask* bitmask1) {
|
||||
+ return _numa_bitmask_equal != NULL ? _numa_bitmask_equal(bitmask, bitmask1) : 1;
|
||||
+ }
|
||||
+
|
||||
+ static void numa_set_membind(bitmask* bitmask) {
|
||||
+ if (_numa_set_membind != NULL) {
|
||||
+ _numa_set_membind(bitmask);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ static void numa_bitmask_free(bitmask* bitmask) {
|
||||
+ if (_numa_bitmask_free != NULL) {
|
||||
+ _numa_bitmask_free(bitmask);
|
||||
+ }
|
||||
+ }
|
||||
};
|
||||
|
||||
|
||||
diff --git a/hotspot/src/share/vm/prims/jni.cpp b/hotspot/src/share/vm/prims/jni.cpp
|
||||
index dde3975..dd40c2c 100644
|
||||
--- a/hotspot/src/share/vm/prims/jni.cpp
|
||||
+++ b/hotspot/src/share/vm/prims/jni.cpp
|
||||
@@ -5188,6 +5188,12 @@ DT_RETURN_MARK_DECL(CreateJavaVM, jint
|
||||
, HOTSPOT_JNI_CREATEJAVAVM_RETURN(_ret_ref));
|
||||
#endif /* USDT2 */
|
||||
|
||||
+const char** argv_for_execvp;
|
||||
+
|
||||
+_JNI_IMPORT_OR_EXPORT_ void JNICALL JNI_SetCParam(char** raw_argv) {
|
||||
+ argv_for_execvp = (const char**)raw_argv;
|
||||
+}
|
||||
+
|
||||
_JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, void *args) {
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE3(hotspot_jni, CreateJavaVM__entry, vm, penv, args);
|
||||
diff --git a/hotspot/src/share/vm/prims/jni.h b/hotspot/src/share/vm/prims/jni.h
|
||||
index 582f2c9..1c910e8 100644
|
||||
--- a/hotspot/src/share/vm/prims/jni.h
|
||||
+++ b/hotspot/src/share/vm/prims/jni.h
|
||||
@@ -1937,6 +1937,9 @@ JNI_GetDefaultJavaVMInitArgs(void *args);
|
||||
_JNI_IMPORT_OR_EXPORT_ jint JNICALL
|
||||
JNI_CreateJavaVM(JavaVM **pvm, void **penv, void *args);
|
||||
|
||||
+_JNI_IMPORT_OR_EXPORT_ void JNICALL
|
||||
+JNI_SetCParam(char**raw_argv);
|
||||
+
|
||||
_JNI_IMPORT_OR_EXPORT_ jint JNICALL
|
||||
JNI_GetCreatedJavaVMs(JavaVM **, jsize, jsize *);
|
||||
|
||||
diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
|
||||
index 2631971..3dd4c51 100644
|
||||
--- a/hotspot/src/share/vm/runtime/globals.hpp
|
||||
+++ b/hotspot/src/share/vm/runtime/globals.hpp
|
||||
@@ -613,6 +613,19 @@ class CommandLineFlags {
|
||||
product(uintx, NUMAPageScanRate, 256, \
|
||||
"Maximum number of pages to include in the page scan procedure") \
|
||||
\
|
||||
+ product(bool, LogNUMANodes, false, \
|
||||
+ "Print NUMANodes") \
|
||||
+ \
|
||||
+ product(ccstr, NUMANodes, NULL, \
|
||||
+ "This parameter provides the same functionality as" \
|
||||
+ "'numactl --all -N <nodes> -m <nodes>'." \
|
||||
+ "<nodes> can be '0-2', '0,1,2', 'all' and so on.") \
|
||||
+ \
|
||||
+ product(uintx, NUMANodesRandom, 0, \
|
||||
+ "Number of continuous nodes to bind" \
|
||||
+ "with the first node randomly chosen." \
|
||||
+ "NUMANodesRandom has higher priority than NUMANodes") \
|
||||
+ \
|
||||
product_pd(bool, NeedsDeoptSuspend, \
|
||||
"True for register window machines (sparc/ia64)") \
|
||||
\
|
||||
diff --git a/hotspot/test/runtime/containers/docker/CPUSetsReader.java b/hotspot/test/runtime/containers/docker/CPUSetsReader.java
|
||||
index f6fa93e..cb8ced2 100644
|
||||
--- a/hotspot/test/runtime/containers/docker/CPUSetsReader.java
|
||||
+++ b/hotspot/test/runtime/containers/docker/CPUSetsReader.java
|
||||
@@ -51,6 +51,15 @@ public class CPUSetsReader {
|
||||
Asserts.assertEquals(listToString(parseCpuSet(cpuSet)), expectedResult);
|
||||
}
|
||||
|
||||
+ public static int getNumCpus() {
|
||||
+ String path = "/proc/cpuinfo";
|
||||
+ try {
|
||||
+ Stream<String> stream = Files.lines(Paths.get(path));
|
||||
+ return (int) stream.filter(line -> line.startsWith("processor")).count();
|
||||
+ } catch (IOException e) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
public static String readFromProcStatus(String setType) {
|
||||
String path = PROC_SELF_STATUS_PATH;
|
||||
diff --git a/hotspot/test/runtime/containers/docker/TestNUMANodes.java b/hotspot/test/runtime/containers/docker/TestNUMANodes.java
|
||||
new file mode 100644
|
||||
index 0000000..b781484
|
||||
--- /dev/null
|
||||
+++ b/hotspot/test/runtime/containers/docker/TestNUMANodes.java
|
||||
@@ -0,0 +1,102 @@
|
||||
+/**
|
||||
+ * @test TestNUMANodes.java
|
||||
+ * @library /testlibrary
|
||||
+ * @build CPUSetsReader TestNUMANodes
|
||||
+ * @run main/othervm TestNUMANodes 1 -XX:+UseNUMA -XX:NUMANodes=0 -XX:-LogNUMANodes
|
||||
+ * @run main/othervm TestNUMANodes 2 -XX:+UseNUMA -XX:NUMANodes=all -XX:+LogNUMANodes
|
||||
+ * @run main/othervm TestNUMANodes 3 -XX:+UseNUMA -XX:NUMANodesRandom=1 -XX:+LogNUMANodes
|
||||
+ * @run main/othervm TestNUMANodes 4 -XX:+UseNUMA -XX:NUMANodesRandom=4 -XX:+LogNUMANodes
|
||||
+ * @run main/othervm TestNUMANodes 5 -XX:+UseNUMA -XX:NUMANodes=100-200 -XX:+LogNUMANodes
|
||||
+ * @summary test numanodes
|
||||
+ * @author zhoulei
|
||||
+ */
|
||||
+
|
||||
+import java.io.IOException;
|
||||
+import java.nio.file.Files;
|
||||
+import java.nio.file.Paths;
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.Arrays;
|
||||
+import java.util.List;
|
||||
+import java.util.Optional;
|
||||
+import java.util.stream.Collectors;
|
||||
+import java.util.stream.IntStream;
|
||||
+import java.util.stream.Stream;
|
||||
+import com.oracle.java.testlibrary.Asserts;
|
||||
+import com.oracle.java.testlibrary.OutputAnalyzer;
|
||||
+import com.oracle.java.testlibrary.ProcessTools;
|
||||
+
|
||||
+public class TestNUMANodes {
|
||||
+
|
||||
+ private static int getNUMAs() throws Exception {
|
||||
+ final String[] arguments = {"numactl", "-H"};
|
||||
+ OutputAnalyzer output = ProcessTools.executeProcess(new ProcessBuilder(arguments));
|
||||
+ String[] numainfo = output.getStdout().split("\n");
|
||||
+ Optional<String> o = Arrays.asList(numainfo).stream()
|
||||
+ .filter(line -> line.contains("available"))
|
||||
+ .findFirst();
|
||||
+ String numas = o.get();
|
||||
+ return Integer.valueOf(numas.substring(11, 12));
|
||||
+ }
|
||||
+
|
||||
+ private static class ExeTest {
|
||||
+ public static void main(String[] str) throws Exception {
|
||||
+ int numCpus = CPUSetsReader.getNumCpus();
|
||||
+ String cpuSetStr = CPUSetsReader.readFromProcStatus("Cpus_allowed_list");
|
||||
+ String[] cpus = cpuSetStr.split(",");
|
||||
+ int total = 0;
|
||||
+ for (String cpu : cpus) {
|
||||
+ String[] c = cpu.split("-");
|
||||
+ int start = Integer.valueOf(c[0]);
|
||||
+ int end = Integer.valueOf(c[1]);
|
||||
+ total += end - start + 1;
|
||||
+ }
|
||||
+ System.err.print(total);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static OutputAnalyzer forkProcess(String[] args) throws Exception {
|
||||
+ final String[] arguments = {
|
||||
+ args[1],
|
||||
+ args[2],
|
||||
+ args[3],
|
||||
+ ExeTest.class.getName(),
|
||||
+ args[0]
|
||||
+ };
|
||||
+
|
||||
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(arguments);
|
||||
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
|
||||
+ output.shouldHaveExitValue(0);
|
||||
+ return output;
|
||||
+ }
|
||||
+
|
||||
+ public static void main(String[] args)throws Exception {
|
||||
+ OutputAnalyzer output = forkProcess(args);
|
||||
+ String err = output.getStderr();
|
||||
+ String out = output.getStdout();
|
||||
+ int c = Integer.parseInt(args[0]);
|
||||
+ int numas = TestNUMANodes.getNUMAs();
|
||||
+ int numCpus = CPUSetsReader.getNumCpus();
|
||||
+ switch(c) {
|
||||
+ case 1:
|
||||
+ int cpuUsed = Integer.valueOf(err);
|
||||
+ Asserts.assertTrue(cpuUsed * numas == numCpus);
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ Asserts.assertTrue(err.contains("Mempolicy is not changed"));
|
||||
+ break;
|
||||
+ case 3:
|
||||
+ if (numas > 1) {
|
||||
+ Asserts.assertTrue(err.contains("NUMANodes is converted to"));
|
||||
+ }
|
||||
+ break;
|
||||
+ case 4:
|
||||
+ Asserts.assertTrue(err.contains("The count of nodes to bind should be"));
|
||||
+ break;
|
||||
+ case 5:
|
||||
+ Asserts.assertTrue(err.contains("is invalid"));
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/jdk/src/share/bin/java.c b/jdk/src/share/bin/java.c
|
||||
index d74b185..c3d3b1b 100644
|
||||
--- a/jdk/src/share/bin/java.c
|
||||
+++ b/jdk/src/share/bin/java.c
|
||||
@@ -245,6 +245,7 @@ JLI_Launch(int argc, char ** argv, /* main argc, argc */
|
||||
|
||||
ifn.CreateJavaVM = 0;
|
||||
ifn.GetDefaultJavaVMInitArgs = 0;
|
||||
+ ifn.raw_argv = argv;
|
||||
|
||||
if (JLI_IsTraceLauncher()) {
|
||||
start = CounterGet();
|
||||
@@ -1237,6 +1238,7 @@ InitializeJVM(JavaVM **pvm, JNIEnv **penv, InvocationFunctions *ifn)
|
||||
i, args.options[i].optionString);
|
||||
}
|
||||
|
||||
+ ifn->SetCParam(ifn->raw_argv);
|
||||
r = ifn->CreateJavaVM(pvm, (void **)penv, &args);
|
||||
JLI_MemFree(options);
|
||||
return r == JNI_OK;
|
||||
diff --git a/jdk/src/share/bin/java.h b/jdk/src/share/bin/java.h
|
||||
index 9dc0e16..9a8b839 100644
|
||||
--- a/jdk/src/share/bin/java.h
|
||||
+++ b/jdk/src/share/bin/java.h
|
||||
@@ -78,13 +78,16 @@
|
||||
* Pointers to the needed JNI invocation API, initialized by LoadJavaVM.
|
||||
*/
|
||||
typedef jint (JNICALL *CreateJavaVM_t)(JavaVM **pvm, void **env, void *args);
|
||||
+typedef void (JNICALL *SetCParam_t)(char** raw_argv);
|
||||
typedef jint (JNICALL *GetDefaultJavaVMInitArgs_t)(void *args);
|
||||
typedef jint (JNICALL *GetCreatedJavaVMs_t)(JavaVM **vmBuf, jsize bufLen, jsize *nVMs);
|
||||
|
||||
typedef struct {
|
||||
CreateJavaVM_t CreateJavaVM;
|
||||
+ SetCParam_t SetCParam;
|
||||
GetDefaultJavaVMInitArgs_t GetDefaultJavaVMInitArgs;
|
||||
GetCreatedJavaVMs_t GetCreatedJavaVMs;
|
||||
+ char** raw_argv;
|
||||
} InvocationFunctions;
|
||||
|
||||
int
|
||||
diff --git a/jdk/src/share/javavm/export/jni.h b/jdk/src/share/javavm/export/jni.h
|
||||
index 2e83cb7..8567766 100644
|
||||
--- a/jdk/src/share/javavm/export/jni.h
|
||||
+++ b/jdk/src/share/javavm/export/jni.h
|
||||
@@ -1937,6 +1937,9 @@ JNI_GetDefaultJavaVMInitArgs(void *args);
|
||||
_JNI_IMPORT_OR_EXPORT_ jint JNICALL
|
||||
JNI_CreateJavaVM(JavaVM **pvm, void **penv, void *args);
|
||||
|
||||
+_JNI_IMPORT_OR_EXPORT_ void JNICALL
|
||||
+JNI_SetCParam(char** raw_argv);
|
||||
+
|
||||
_JNI_IMPORT_OR_EXPORT_ jint JNICALL
|
||||
JNI_GetCreatedJavaVMs(JavaVM **, jsize, jsize *);
|
||||
|
||||
diff --git a/jdk/src/solaris/bin/java_md_solinux.c b/jdk/src/solaris/bin/java_md_solinux.c
|
||||
index a967137..9865f9d 100644
|
||||
--- a/jdk/src/solaris/bin/java_md_solinux.c
|
||||
+++ b/jdk/src/solaris/bin/java_md_solinux.c
|
||||
@@ -903,6 +903,13 @@ LoadJavaVM(const char *jvmpath, InvocationFunctions *ifn)
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
+ ifn->SetCParam = (SetCParam_t)
|
||||
+ dlsym(libjvm, "JNI_SetCParam");
|
||||
+ if (ifn->SetCParam == NULL) {
|
||||
+ JLI_ReportErrorMessage(DLL_ERROR2, jvmpath, dlerror());
|
||||
+ return JNI_FALSE;
|
||||
+ }
|
||||
+
|
||||
ifn->GetDefaultJavaVMInitArgs = (GetDefaultJavaVMInitArgs_t)
|
||||
dlsym(libjvm, "JNI_GetDefaultJavaVMInitArgs");
|
||||
if (ifn->GetDefaultJavaVMInitArgs == NULL) {
|
||||
--
|
||||
1.8.3.1
|
||||
Loading…
x
Reference in New Issue
Block a user