I8X6CH: upgrade to 8u402
This commit is contained in:
parent
dde58438ba
commit
53bdb4e2c0
@ -361,16 +361,6 @@ index d8143821b..1b7c768df 100644
|
|||||||
_igvn.hash_insert(n);
|
_igvn.hash_insert(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -541,8 +540,7 @@ bool PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) {
|
|
||||||
assert(check_iff->in(1)->Opcode() == Op_Conv2B &&
|
|
||||||
check_iff->in(1)->in(1)->Opcode() == Op_Opaque1, "");
|
|
||||||
Node* opq = check_iff->in(1)->in(1);
|
|
||||||
- _igvn.hash_delete(opq);
|
|
||||||
- opq->set_req(1, bol);
|
|
||||||
+ _igvn.replace_input_of(opq, 1, bol);
|
|
||||||
// Update ctrl.
|
|
||||||
set_ctrl(opq, check_iff->in(0));
|
|
||||||
set_ctrl(check_iff->in(1), check_iff->in(0));
|
|
||||||
@@ -712,7 +710,7 @@ bool PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) {
|
@@ -712,7 +710,7 @@ bool PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) {
|
||||||
incr->set_req(2,stride);
|
incr->set_req(2,stride);
|
||||||
incr = _igvn.register_new_node_with_optimizer(incr);
|
incr = _igvn.register_new_node_with_optimizer(incr);
|
||||||
|
|||||||
753
8057967-CallSite-dependency-tracking-scales-devastat.patch
Normal file
753
8057967-CallSite-dependency-tracking-scales-devastat.patch
Normal file
@ -0,0 +1,753 @@
|
|||||||
|
From 1059c5d5f9d1e50607c726b619f39ac68954bda7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: zhangyipeng <zhangyipeng7@huawei.com>
|
||||||
|
Date: Mon, 15 Jan 2024 11:40:07 +0800
|
||||||
|
Subject: [PATCH] [Backport]8057967: CallSite dependency tracking scales devastatingly
|
||||||
|
poorly
|
||||||
|
---
|
||||||
|
hotspot/src/share/vm/ci/ciCallSite.cpp | 19 +++
|
||||||
|
hotspot/src/share/vm/ci/ciCallSite.hpp | 1 +
|
||||||
|
hotspot/src/share/vm/classfile/javaClasses.cpp | 48 +++++-
|
||||||
|
hotspot/src/share/vm/classfile/javaClasses.hpp | 9 +-
|
||||||
|
hotspot/src/share/vm/classfile/vmSymbols.hpp | 4 +-
|
||||||
|
hotspot/src/share/vm/code/dependencies.cpp | 27 ++--
|
||||||
|
hotspot/src/share/vm/code/dependencies.hpp | 7 +-
|
||||||
|
hotspot/src/share/vm/memory/universe.cpp | 8 +-
|
||||||
|
hotspot/src/share/vm/prims/methodHandles.cpp | 50 +++++-
|
||||||
|
hotspot/src/share/vm/prims/methodHandles.hpp | 3 +
|
||||||
|
.../compiler/jsr292/CallSiteDepContextTest.java | 179 +++++++++++++++++++++
|
||||||
|
.../share/classes/java/lang/invoke/CallSite.java | 55 ++++++-
|
||||||
|
.../java/lang/invoke/MethodHandleNatives.java | 4 +
|
||||||
|
13 files changed, 385 insertions(+), 29 deletions(-)
|
||||||
|
create mode 100644 hotspot/test/compiler/jsr292/CallSiteDepContextTest.java
|
||||||
|
|
||||||
|
diff --git a/hotspot/src/share/vm/ci/ciCallSite.cpp b/hotspot/src/share/vm/ci/ciCallSite.cpp
|
||||||
|
index 794042a79..f58346aea 100644
|
||||||
|
--- a/hotspot/src/share/vm/ci/ciCallSite.cpp
|
||||||
|
+++ b/hotspot/src/share/vm/ci/ciCallSite.cpp
|
||||||
|
@@ -49,6 +49,25 @@ ciMethodHandle* ciCallSite::get_target() const {
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
+// ciCallSite::get_context
|
||||||
|
+//
|
||||||
|
+// Return the target MethodHandle of this CallSite.
|
||||||
|
+ciKlass* ciCallSite::get_context() {
|
||||||
|
+ assert(!is_constant_call_site(), "");
|
||||||
|
+
|
||||||
|
+ VM_ENTRY_MARK;
|
||||||
|
+ oop call_site_oop = get_oop();
|
||||||
|
+ InstanceKlass* ctxk = MethodHandles::get_call_site_context(call_site_oop);
|
||||||
|
+ if (ctxk == NULL) {
|
||||||
|
+ // The call site doesn't have a context associated. Set it to the default context.
|
||||||
|
+ oop def_context_oop = java_lang_invoke_CallSite::default_context();
|
||||||
|
+ java_lang_invoke_CallSite::set_context_cas(call_site_oop, def_context_oop, /*expected=*/NULL);
|
||||||
|
+ ctxk = MethodHandles::get_call_site_context(call_site_oop);
|
||||||
|
+ }
|
||||||
|
+ return (CURRENT_ENV->get_metadata(ctxk))->as_klass();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// ------------------------------------------------------------------
|
||||||
|
// ciCallSite::print
|
||||||
|
//
|
||||||
|
// Print debugging information about the CallSite.
|
||||||
|
diff --git a/hotspot/src/share/vm/ci/ciCallSite.hpp b/hotspot/src/share/vm/ci/ciCallSite.hpp
|
||||||
|
index 063f1e3a5..040e894d0 100644
|
||||||
|
--- a/hotspot/src/share/vm/ci/ciCallSite.hpp
|
||||||
|
+++ b/hotspot/src/share/vm/ci/ciCallSite.hpp
|
||||||
|
@@ -43,6 +43,7 @@ public:
|
||||||
|
|
||||||
|
// Return the target MethodHandle of this CallSite.
|
||||||
|
ciMethodHandle* get_target() const;
|
||||||
|
+ ciKlass* get_context();
|
||||||
|
|
||||||
|
void print();
|
||||||
|
};
|
||||||
|
diff --git a/hotspot/src/share/vm/classfile/javaClasses.cpp b/hotspot/src/share/vm/classfile/javaClasses.cpp
|
||||||
|
index 9db88611b..fc4165b04 100644
|
||||||
|
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp
|
||||||
|
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp
|
||||||
|
@@ -100,21 +100,22 @@ InjectedField* JavaClasses::get_injected(Symbol* class_name, int* field_count) {
|
||||||
|
static bool find_field(InstanceKlass* ik,
|
||||||
|
Symbol* name_symbol, Symbol* signature_symbol,
|
||||||
|
fieldDescriptor* fd,
|
||||||
|
- bool allow_super = false) {
|
||||||
|
- if (allow_super)
|
||||||
|
- return ik->find_field(name_symbol, signature_symbol, fd) != NULL;
|
||||||
|
- else
|
||||||
|
+ bool is_static = false, bool allow_super = false) {
|
||||||
|
+ if (allow_super || is_static) {
|
||||||
|
+ return ik->find_field(name_symbol, signature_symbol, is_static, fd) != NULL;
|
||||||
|
+ } else {
|
||||||
|
return ik->find_local_field(name_symbol, signature_symbol, fd);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helpful routine for computing field offsets at run time rather than hardcoding them
|
||||||
|
static void
|
||||||
|
compute_offset(int &dest_offset,
|
||||||
|
Klass* klass_oop, Symbol* name_symbol, Symbol* signature_symbol,
|
||||||
|
- bool allow_super = false) {
|
||||||
|
+ bool is_static = false, bool allow_super = false) {
|
||||||
|
fieldDescriptor fd;
|
||||||
|
InstanceKlass* ik = InstanceKlass::cast(klass_oop);
|
||||||
|
- if (!find_field(ik, name_symbol, signature_symbol, &fd, allow_super)) {
|
||||||
|
+ if (!find_field(ik, name_symbol, signature_symbol, &fd, is_static, allow_super)) {
|
||||||
|
ResourceMark rm;
|
||||||
|
tty->print_cr("Invalid layout of %s at %s", ik->external_name(), name_symbol->as_C_string());
|
||||||
|
#ifndef PRODUCT
|
||||||
|
@@ -3002,15 +3003,50 @@ int java_lang_invoke_MethodType::rtype_slot_count(oop mt) {
|
||||||
|
// Support for java_lang_invoke_CallSite
|
||||||
|
|
||||||
|
int java_lang_invoke_CallSite::_target_offset;
|
||||||
|
+int java_lang_invoke_CallSite::_context_offset;
|
||||||
|
+int java_lang_invoke_CallSite::_default_context_offset;
|
||||||
|
|
||||||
|
void java_lang_invoke_CallSite::compute_offsets() {
|
||||||
|
if (!EnableInvokeDynamic) return;
|
||||||
|
Klass* k = SystemDictionary::CallSite_klass();
|
||||||
|
if (k != NULL) {
|
||||||
|
compute_offset(_target_offset, k, vmSymbols::target_name(), vmSymbols::java_lang_invoke_MethodHandle_signature());
|
||||||
|
+ compute_offset(_context_offset, k, vmSymbols::context_name(), vmSymbols::sun_misc_Cleaner_signature());
|
||||||
|
+ compute_offset(_default_context_offset, k,
|
||||||
|
+ vmSymbols::DEFAULT_CONTEXT_name(), vmSymbols::sun_misc_Cleaner_signature(),
|
||||||
|
+ /*is_static=*/true, /*allow_super=*/false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+oop java_lang_invoke_CallSite::context_volatile(oop call_site) {
|
||||||
|
+ assert(java_lang_invoke_CallSite::is_instance(call_site), "");
|
||||||
|
+
|
||||||
|
+ oop dep_oop = call_site->obj_field_volatile(_context_offset);
|
||||||
|
+ return dep_oop;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void java_lang_invoke_CallSite::set_context_volatile(oop call_site, oop context) {
|
||||||
|
+ assert(java_lang_invoke_CallSite::is_instance(call_site), "");
|
||||||
|
+ call_site->obj_field_put_volatile(_context_offset, context);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+bool java_lang_invoke_CallSite::set_context_cas(oop call_site, oop context, oop expected) {
|
||||||
|
+ assert(java_lang_invoke_CallSite::is_instance(call_site), "");
|
||||||
|
+ HeapWord* context_addr = call_site->obj_field_addr<HeapWord>(_context_offset);
|
||||||
|
+ oop res = oopDesc::atomic_compare_exchange_oop(context, context_addr, expected, true);
|
||||||
|
+ bool success = (res == expected);
|
||||||
|
+ if (success) {
|
||||||
|
+ update_barrier_set((void*)context_addr, context);
|
||||||
|
+ }
|
||||||
|
+ return success;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+oop java_lang_invoke_CallSite::default_context() {
|
||||||
|
+ InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::CallSite_klass());
|
||||||
|
+ oop def_context_oop = ik->java_mirror()->obj_field(_default_context_offset);
|
||||||
|
+ assert(!oopDesc::is_null(def_context_oop), "");
|
||||||
|
+ return def_context_oop;
|
||||||
|
+}
|
||||||
|
|
||||||
|
// Support for java_security_AccessControlContext
|
||||||
|
|
||||||
|
diff --git a/hotspot/src/share/vm/classfile/javaClasses.hpp b/hotspot/src/share/vm/classfile/javaClasses.hpp
|
||||||
|
index d6e288fb8..35934319d 100644
|
||||||
|
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp
|
||||||
|
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp
|
||||||
|
@@ -1212,6 +1212,9 @@ class java_lang_invoke_CallSite: AllStatic {
|
||||||
|
|
||||||
|
private:
|
||||||
|
static int _target_offset;
|
||||||
|
+ static int _context_offset;
|
||||||
|
+ static int _default_context_offset;
|
||||||
|
+
|
||||||
|
|
||||||
|
static void compute_offsets();
|
||||||
|
|
||||||
|
@@ -1222,6 +1225,11 @@ public:
|
||||||
|
|
||||||
|
static volatile oop target_volatile(oop site) { return oop((oopDesc *)(site->obj_field_volatile(_target_offset))); }
|
||||||
|
static void set_target_volatile(oop site, oop target) { site->obj_field_put_volatile(_target_offset, target); }
|
||||||
|
+ static oop context_volatile(oop site);
|
||||||
|
+ static void set_context_volatile(oop site, oop context);
|
||||||
|
+ static bool set_context_cas (oop site, oop context, oop expected);
|
||||||
|
+
|
||||||
|
+ static oop default_context();
|
||||||
|
|
||||||
|
// Testers
|
||||||
|
static bool is_subclass(Klass* klass) {
|
||||||
|
@@ -1235,7 +1243,6 @@ public:
|
||||||
|
static int target_offset_in_bytes() { return _target_offset; }
|
||||||
|
};
|
||||||
|
|
||||||
|
-
|
||||||
|
// Interface to java.security.AccessControlContext objects
|
||||||
|
|
||||||
|
class java_security_AccessControlContext: AllStatic {
|
||||||
|
diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp
|
||||||
|
index 494fd9bdf..f92b709ed 100644
|
||||||
|
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp
|
||||||
|
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp
|
||||||
|
@@ -301,6 +301,7 @@
|
||||||
|
template(setTargetNormal_name, "setTargetNormal") \
|
||||||
|
template(setTargetVolatile_name, "setTargetVolatile") \
|
||||||
|
template(setTarget_signature, "(Ljava/lang/invoke/MethodHandle;)V") \
|
||||||
|
+ template(DEFAULT_CONTEXT_name, "DEFAULT_CONTEXT") \
|
||||||
|
NOT_LP64( do_alias(intptr_signature, int_signature) ) \
|
||||||
|
LP64_ONLY( do_alias(intptr_signature, long_signature) ) \
|
||||||
|
\
|
||||||
|
@@ -517,6 +518,7 @@
|
||||||
|
template(string_signature, "Ljava/lang/String;") \
|
||||||
|
template(reference_signature, "Ljava/lang/ref/Reference;") \
|
||||||
|
template(referencequeue_signature, "Ljava/lang/ref/ReferenceQueue;") \
|
||||||
|
+ template(sun_misc_Cleaner_signature, "Lsun/misc/Cleaner;") \
|
||||||
|
template(executable_signature, "Ljava/lang/reflect/Executable;") \
|
||||||
|
template(concurrenthashmap_signature, "Ljava/util/concurrent/ConcurrentHashMap;") \
|
||||||
|
template(String_StringBuilder_signature, "(Ljava/lang/String;)Ljava/lang/StringBuilder;") \
|
||||||
|
@@ -570,7 +572,7 @@
|
||||||
|
template(createGarbageCollectorMBean_signature, "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/management/GarbageCollectorMBean;") \
|
||||||
|
template(trigger_name, "trigger") \
|
||||||
|
template(clear_name, "clear") \
|
||||||
|
- template(trigger_method_signature, "(ILjava/lang/management/MemoryUsage;)V") \
|
||||||
|
+ template(trigger_method_signature, "(ILjava/lang/management/MemoryUsage;)V") \
|
||||||
|
template(startAgent_name, "startAgent") \
|
||||||
|
template(startRemoteAgent_name, "startRemoteManagementAgent") \
|
||||||
|
template(startLocalAgent_name, "startLocalManagementAgent") \
|
||||||
|
diff --git a/hotspot/src/share/vm/code/dependencies.cpp b/hotspot/src/share/vm/code/dependencies.cpp
|
||||||
|
index d1fe08b54..decbce8be 100644
|
||||||
|
--- a/hotspot/src/share/vm/code/dependencies.cpp
|
||||||
|
+++ b/hotspot/src/share/vm/code/dependencies.cpp
|
||||||
|
@@ -123,8 +123,9 @@ void Dependencies::assert_has_no_finalizable_subclasses(ciKlass* ctxk) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dependencies::assert_call_site_target_value(ciCallSite* call_site, ciMethodHandle* method_handle) {
|
||||||
|
- check_ctxk(call_site->klass());
|
||||||
|
- assert_common_2(call_site_target_value, call_site, method_handle);
|
||||||
|
+ ciKlass* ctxk = call_site->get_context();
|
||||||
|
+ check_ctxk(ctxk);
|
||||||
|
+ assert_common_3(call_site_target_value, ctxk, call_site, method_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function. If we are adding a new dep. under ctxk2,
|
||||||
|
@@ -396,7 +397,7 @@ int Dependencies::_dep_args[TYPE_LIMIT] = {
|
||||||
|
3, // unique_concrete_methods_2 ctxk, m1, m2
|
||||||
|
2, // unique_implementor ctxk, implementor
|
||||||
|
1, // no_finalizable_subclasses ctxk
|
||||||
|
- 2 // call_site_target_value call_site, method_handle
|
||||||
|
+ 3 // call_site_target_value ctxk, call_site, method_handle
|
||||||
|
};
|
||||||
|
|
||||||
|
const char* Dependencies::dep_name(Dependencies::DepType dept) {
|
||||||
|
@@ -598,7 +599,7 @@ void Dependencies::DepStream::log_dependency(Klass* witness) {
|
||||||
|
const int nargs = argument_count();
|
||||||
|
GrowableArray<DepArgument>* args = new GrowableArray<DepArgument>(nargs);
|
||||||
|
for (int j = 0; j < nargs; j++) {
|
||||||
|
- if (type() == call_site_target_value) {
|
||||||
|
+ if (is_oop_argument(j)) {
|
||||||
|
args->push(argument_oop(j));
|
||||||
|
} else {
|
||||||
|
args->push(argument(j));
|
||||||
|
@@ -726,7 +727,7 @@ Klass* Dependencies::DepStream::context_type() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some dependencies are using the klass of the first object
|
||||||
|
- // argument as implicit context type (e.g. call_site_target_value).
|
||||||
|
+ // argument as implicit context type.
|
||||||
|
{
|
||||||
|
int ctxkj = dep_implicit_context_arg(type());
|
||||||
|
if (ctxkj >= 0) {
|
||||||
|
@@ -1647,9 +1648,16 @@ Klass* Dependencies::check_has_no_finalizable_subclasses(Klass* ctxk, KlassDepCh
|
||||||
|
return find_finalizable_subclass(search_at);
|
||||||
|
}
|
||||||
|
|
||||||
|
-Klass* Dependencies::check_call_site_target_value(oop call_site, oop method_handle, CallSiteDepChange* changes) {
|
||||||
|
- assert(call_site ->is_a(SystemDictionary::CallSite_klass()), "sanity");
|
||||||
|
- assert(method_handle->is_a(SystemDictionary::MethodHandle_klass()), "sanity");
|
||||||
|
+Klass* Dependencies::check_call_site_target_value(Klass* recorded_ctxk, oop call_site, oop method_handle, CallSiteDepChange* changes) {
|
||||||
|
+ assert(call_site->is_a(SystemDictionary::CallSite_klass()), "sanity");
|
||||||
|
+ assert(!oopDesc::is_null(method_handle), "sanity");
|
||||||
|
+
|
||||||
|
+ Klass* call_site_ctxk = MethodHandles::get_call_site_context(call_site);
|
||||||
|
+ assert(!Klass::is_null(call_site_ctxk), "call site context should be initialized already");
|
||||||
|
+ if (recorded_ctxk != call_site_ctxk) {
|
||||||
|
+ // Stale context
|
||||||
|
+ return recorded_ctxk;
|
||||||
|
+ }
|
||||||
|
if (changes == NULL) {
|
||||||
|
// Validate all CallSites
|
||||||
|
if (java_lang_invoke_CallSite::target(call_site) != method_handle)
|
||||||
|
@@ -1664,7 +1672,6 @@ Klass* Dependencies::check_call_site_target_value(oop call_site, oop method_hand
|
||||||
|
return NULL; // assertion still valid
|
||||||
|
}
|
||||||
|
|
||||||
|
-
|
||||||
|
void Dependencies::DepStream::trace_and_log_witness(Klass* witness) {
|
||||||
|
if (witness != NULL) {
|
||||||
|
if (TraceDependencies) {
|
||||||
|
@@ -1728,7 +1735,7 @@ Klass* Dependencies::DepStream::check_call_site_dependency(CallSiteDepChange* ch
|
||||||
|
Klass* witness = NULL;
|
||||||
|
switch (type()) {
|
||||||
|
case call_site_target_value:
|
||||||
|
- witness = check_call_site_target_value(argument_oop(0), argument_oop(1), changes);
|
||||||
|
+ witness = check_call_site_target_value(context_type(), argument_oop(1), argument_oop(2), changes);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
witness = NULL;
|
||||||
|
diff --git a/hotspot/src/share/vm/code/dependencies.hpp b/hotspot/src/share/vm/code/dependencies.hpp
|
||||||
|
index 0392d4e3d..da2201c3f 100644
|
||||||
|
--- a/hotspot/src/share/vm/code/dependencies.hpp
|
||||||
|
+++ b/hotspot/src/share/vm/code/dependencies.hpp
|
||||||
|
@@ -176,7 +176,7 @@ class Dependencies: public ResourceObj {
|
||||||
|
klass_types = all_types & ~non_klass_types,
|
||||||
|
|
||||||
|
non_ctxk_types = (1 << evol_method),
|
||||||
|
- implicit_ctxk_types = (1 << call_site_target_value),
|
||||||
|
+ implicit_ctxk_types = 0,
|
||||||
|
explicit_ctxk_types = all_types & ~(non_ctxk_types | implicit_ctxk_types),
|
||||||
|
|
||||||
|
max_arg_count = 3, // current maximum number of arguments (incl. ctxk)
|
||||||
|
@@ -340,7 +340,7 @@ class Dependencies: public ResourceObj {
|
||||||
|
static Klass* check_exclusive_concrete_methods(Klass* ctxk, Method* m1, Method* m2,
|
||||||
|
KlassDepChange* changes = NULL);
|
||||||
|
static Klass* check_has_no_finalizable_subclasses(Klass* ctxk, KlassDepChange* changes = NULL);
|
||||||
|
- static Klass* check_call_site_target_value(oop call_site, oop method_handle, CallSiteDepChange* changes = NULL);
|
||||||
|
+ static Klass* check_call_site_target_value(Klass* recorded_ctxk, oop call_site, oop method_handle, CallSiteDepChange* changes = NULL);
|
||||||
|
// A returned Klass* is NULL if the dependency assertion is still
|
||||||
|
// valid. A non-NULL Klass* is a 'witness' to the assertion
|
||||||
|
// failure, a point in the class hierarchy where the assertion has
|
||||||
|
@@ -506,6 +506,7 @@ class Dependencies: public ResourceObj {
|
||||||
|
bool next();
|
||||||
|
|
||||||
|
DepType type() { return _type; }
|
||||||
|
+ bool is_oop_argument(int i) { return type() == call_site_target_value && i > 0; }
|
||||||
|
int argument_count() { return dep_args(type()); }
|
||||||
|
int argument_index(int i) { assert(0 <= i && i < argument_count(), "oob");
|
||||||
|
return _xi[i]; }
|
||||||
|
@@ -664,7 +665,7 @@ class CallSiteDepChange : public DepChange {
|
||||||
|
_method_handle(method_handle)
|
||||||
|
{
|
||||||
|
assert(_call_site() ->is_a(SystemDictionary::CallSite_klass()), "must be");
|
||||||
|
- assert(_method_handle()->is_a(SystemDictionary::MethodHandle_klass()), "must be");
|
||||||
|
+ assert(_method_handle.is_null() || _method_handle()->is_a(SystemDictionary::MethodHandle_klass()), "must be");
|
||||||
|
}
|
||||||
|
|
||||||
|
// What kind of DepChange is this?
|
||||||
|
diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp
|
||||||
|
index 23433d187..7028d378e 100644
|
||||||
|
--- a/hotspot/src/share/vm/memory/universe.cpp
|
||||||
|
+++ b/hotspot/src/share/vm/memory/universe.cpp
|
||||||
|
@@ -56,6 +56,7 @@
|
||||||
|
#include "oops/oop.inline.hpp"
|
||||||
|
#include "oops/typeArrayKlass.hpp"
|
||||||
|
#include "prims/jvmtiRedefineClassesTrace.hpp"
|
||||||
|
+#include "prims/methodHandles.hpp"
|
||||||
|
#include "runtime/arguments.hpp"
|
||||||
|
#include "runtime/deoptimization.hpp"
|
||||||
|
#include "runtime/fprofiler.hpp"
|
||||||
|
@@ -1233,8 +1234,11 @@ void Universe::flush_dependents_on(Handle call_site, Handle method_handle) {
|
||||||
|
int marked = 0;
|
||||||
|
{
|
||||||
|
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
||||||
|
- InstanceKlass* call_site_klass = InstanceKlass::cast(call_site->klass());
|
||||||
|
- marked = call_site_klass->mark_dependent_nmethods(changes);
|
||||||
|
+ InstanceKlass* ctxk = MethodHandles::get_call_site_context(call_site());
|
||||||
|
+ if (ctxk == NULL) {
|
||||||
|
+ return; // No dependencies to invalidate yet.
|
||||||
|
+ }
|
||||||
|
+ marked = ctxk->mark_dependent_nmethods(changes);
|
||||||
|
}
|
||||||
|
if (marked > 0) {
|
||||||
|
// At least one nmethod has been marked for deoptimization
|
||||||
|
diff --git a/hotspot/src/share/vm/prims/methodHandles.cpp b/hotspot/src/share/vm/prims/methodHandles.cpp
|
||||||
|
index 29598d500..c1cbabec2 100644
|
||||||
|
--- a/hotspot/src/share/vm/prims/methodHandles.cpp
|
||||||
|
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp
|
||||||
|
@@ -946,6 +946,24 @@ int MethodHandles::find_MemberNames(KlassHandle k,
|
||||||
|
return rfill + overflow;
|
||||||
|
}
|
||||||
|
|
||||||
|
+// Get context class for a CallSite instance: either extract existing context or use default one.
|
||||||
|
+InstanceKlass* MethodHandles::get_call_site_context(oop call_site) {
|
||||||
|
+ // In order to extract a context the following traversal is performed:
|
||||||
|
+ // CallSite.context => Cleaner.referent => Class._klass => Klass
|
||||||
|
+ assert(java_lang_invoke_CallSite::is_instance(call_site), "");
|
||||||
|
+ oop context_oop = java_lang_invoke_CallSite::context_volatile(call_site);
|
||||||
|
+ if (oopDesc::is_null(context_oop)) {
|
||||||
|
+ return NULL; // The context hasn't been initialized yet.
|
||||||
|
+ }
|
||||||
|
+ oop context_class_oop = java_lang_ref_Reference::referent(context_oop);
|
||||||
|
+ if (oopDesc::is_null(context_class_oop)) {
|
||||||
|
+ // The context reference was cleared by GC, so current dependency context
|
||||||
|
+ // isn't usable anymore. Context should be fetched from CallSite again.
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+ return InstanceKlass::cast(java_lang_Class::as_Klass(context_class_oop));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// MemberNameTable
|
||||||
|
//
|
||||||
|
@@ -1305,7 +1323,7 @@ JVM_END
|
||||||
|
|
||||||
|
JVM_ENTRY(void, MHN_setCallSiteTargetNormal(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) {
|
||||||
|
Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh));
|
||||||
|
- Handle target (THREAD, JNIHandles::resolve(target_jh));
|
||||||
|
+ Handle target (THREAD, JNIHandles::resolve_non_null(target_jh));
|
||||||
|
{
|
||||||
|
// Walk all nmethods depending on this call site.
|
||||||
|
MutexLocker mu(Compile_lock, thread);
|
||||||
|
@@ -1317,7 +1335,7 @@ JVM_END
|
||||||
|
|
||||||
|
JVM_ENTRY(void, MHN_setCallSiteTargetVolatile(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) {
|
||||||
|
Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh));
|
||||||
|
- Handle target (THREAD, JNIHandles::resolve(target_jh));
|
||||||
|
+ Handle target (THREAD, JNIHandles::resolve_non_null(target_jh));
|
||||||
|
{
|
||||||
|
// Walk all nmethods depending on this call site.
|
||||||
|
MutexLocker mu(Compile_lock, thread);
|
||||||
|
@@ -1327,6 +1345,33 @@ JVM_ENTRY(void, MHN_setCallSiteTargetVolatile(JNIEnv* env, jobject igcls, jobjec
|
||||||
|
}
|
||||||
|
JVM_END
|
||||||
|
|
||||||
|
+JVM_ENTRY(void, MHN_invalidateDependentNMethods(JNIEnv* env, jobject igcls, jobject call_site_jh)) {
|
||||||
|
+ Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh));
|
||||||
|
+ {
|
||||||
|
+ // Walk all nmethods depending on this call site.
|
||||||
|
+ MutexLocker mu1(Compile_lock, thread);
|
||||||
|
+
|
||||||
|
+ CallSiteDepChange changes(call_site(), Handle());
|
||||||
|
+
|
||||||
|
+ InstanceKlass* ctxk = MethodHandles::get_call_site_context(call_site());
|
||||||
|
+ if (ctxk == NULL) {
|
||||||
|
+ return; // No dependencies to invalidate yet.
|
||||||
|
+ }
|
||||||
|
+ int marked = 0;
|
||||||
|
+ {
|
||||||
|
+ MutexLockerEx mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
||||||
|
+ marked = ctxk->mark_dependent_nmethods(changes);
|
||||||
|
+ }
|
||||||
|
+ java_lang_invoke_CallSite::set_context_volatile(call_site(), NULL); // Reset call site to initial state
|
||||||
|
+ if (marked > 0) {
|
||||||
|
+ // At least one nmethod has been marked for deoptimization
|
||||||
|
+ VM_Deoptimize op;
|
||||||
|
+ VMThread::execute(&op);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+JVM_END
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* Throws a java/lang/UnsupportedOperationException unconditionally.
|
||||||
|
* This is required by the specification of MethodHandle.invoke if
|
||||||
|
@@ -1381,6 +1426,7 @@ static JNINativeMethod MHN_methods[] = {
|
||||||
|
{CC "objectFieldOffset", CC "(" MEM ")J", FN_PTR(MHN_objectFieldOffset)},
|
||||||
|
{CC "setCallSiteTargetNormal", CC "(" CS "" MH ")V", FN_PTR(MHN_setCallSiteTargetNormal)},
|
||||||
|
{CC "setCallSiteTargetVolatile", CC "(" CS "" MH ")V", FN_PTR(MHN_setCallSiteTargetVolatile)},
|
||||||
|
+ {CC"invalidateDependentNMethods", CC"("CS")V", FN_PTR(MHN_invalidateDependentNMethods)},
|
||||||
|
{CC "staticFieldOffset", CC "(" MEM ")J", FN_PTR(MHN_staticFieldOffset)},
|
||||||
|
{CC "staticFieldBase", CC "(" MEM ")" OBJ, FN_PTR(MHN_staticFieldBase)},
|
||||||
|
{CC "getMemberVMInfo", CC "(" MEM ")" OBJ, FN_PTR(MHN_getMemberVMInfo)}
|
||||||
|
diff --git a/hotspot/src/share/vm/prims/methodHandles.hpp b/hotspot/src/share/vm/prims/methodHandles.hpp
|
||||||
|
index db6e06180..4b6af60df 100644
|
||||||
|
--- a/hotspot/src/share/vm/prims/methodHandles.hpp
|
||||||
|
+++ b/hotspot/src/share/vm/prims/methodHandles.hpp
|
||||||
|
@@ -68,6 +68,9 @@ class MethodHandles: AllStatic {
|
||||||
|
// bit values for suppress argument to expand_MemberName:
|
||||||
|
enum { _suppress_defc = 1, _suppress_name = 2, _suppress_type = 4 };
|
||||||
|
|
||||||
|
+ // CallSite support
|
||||||
|
+ static InstanceKlass* get_call_site_context(oop call_site);
|
||||||
|
+
|
||||||
|
// Generate MethodHandles adapters.
|
||||||
|
static void generate_adapters();
|
||||||
|
|
||||||
|
diff --git a/hotspot/test/compiler/jsr292/CallSiteDepContextTest.java b/hotspot/test/compiler/jsr292/CallSiteDepContextTest.java
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..11e46ed03
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/hotspot/test/compiler/jsr292/CallSiteDepContextTest.java
|
||||||
|
@@ -0,0 +1,179 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright (c) 2015, 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 8057967
|
||||||
|
+ * @run main/bootclasspath -Xbatch java.lang.invoke.CallSiteDepContextTest
|
||||||
|
+ */
|
||||||
|
+package java.lang.invoke;
|
||||||
|
+
|
||||||
|
+import java.lang.ref.*;
|
||||||
|
+import jdk.internal.org.objectweb.asm.*;
|
||||||
|
+import sun.misc.Unsafe;
|
||||||
|
+
|
||||||
|
+import static jdk.internal.org.objectweb.asm.Opcodes.*;
|
||||||
|
+
|
||||||
|
+public class CallSiteDepContextTest {
|
||||||
|
+ static final Unsafe UNSAFE = Unsafe.getUnsafe();
|
||||||
|
+ static final MethodHandles.Lookup LOOKUP = MethodHandles.Lookup.IMPL_LOOKUP;
|
||||||
|
+ static final String CLASS_NAME = "java/lang/invoke/Test";
|
||||||
|
+ static final String METHOD_NAME = "m";
|
||||||
|
+ static final MethodType TYPE = MethodType.methodType(int.class);
|
||||||
|
+
|
||||||
|
+ static MutableCallSite mcs;
|
||||||
|
+ static MethodHandle bsmMH;
|
||||||
|
+
|
||||||
|
+ static {
|
||||||
|
+ try {
|
||||||
|
+ bsmMH = LOOKUP.findStatic(
|
||||||
|
+ CallSiteDepContextTest.class, "bootstrap",
|
||||||
|
+ MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class));
|
||||||
|
+ } catch(Throwable e) {
|
||||||
|
+ throw new InternalError(e);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static CallSite bootstrap(MethodHandles.Lookup caller,
|
||||||
|
+ String invokedName,
|
||||||
|
+ MethodType invokedType) {
|
||||||
|
+ return mcs;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ static class T {
|
||||||
|
+ static int f1() { return 1; }
|
||||||
|
+ static int f2() { return 2; }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ static byte[] getClassFile(String suffix) {
|
||||||
|
+ ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
||||||
|
+ MethodVisitor mv;
|
||||||
|
+ cw.visit(52, ACC_PUBLIC | ACC_SUPER, CLASS_NAME + suffix, null, "java/lang/Object", null);
|
||||||
|
+ {
|
||||||
|
+ mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, METHOD_NAME, TYPE.toMethodDescriptorString(), null, null);
|
||||||
|
+ mv.visitCode();
|
||||||
|
+ Handle bsm = new Handle(H_INVOKESTATIC,
|
||||||
|
+ "java/lang/invoke/CallSiteDepContextTest", "bootstrap",
|
||||||
|
+ bsmMH.type().toMethodDescriptorString());
|
||||||
|
+ mv.visitInvokeDynamicInsn("methodName", TYPE.toMethodDescriptorString(), bsm);
|
||||||
|
+ mv.visitInsn(IRETURN);
|
||||||
|
+ mv.visitMaxs(0, 0);
|
||||||
|
+ mv.visitEnd();
|
||||||
|
+ }
|
||||||
|
+ cw.visitEnd();
|
||||||
|
+ return cw.toByteArray();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private static void execute(int expected, MethodHandle... mhs) throws Throwable {
|
||||||
|
+ for (int i = 0; i < 20_000; i++) {
|
||||||
|
+ for (MethodHandle mh : mhs) {
|
||||||
|
+ int r = (int) mh.invokeExact();
|
||||||
|
+ if (r != expected) {
|
||||||
|
+ throw new Error(r + " != " + expected);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static void testSharedCallSite() throws Throwable {
|
||||||
|
+ Class<?> cls1 = UNSAFE.defineAnonymousClass(Object.class, getClassFile("CS_1"), null);
|
||||||
|
+ Class<?> cls2 = UNSAFE.defineAnonymousClass(Object.class, getClassFile("CS_2"), null);
|
||||||
|
+
|
||||||
|
+ MethodHandle[] mhs = new MethodHandle[] {
|
||||||
|
+ LOOKUP.findStatic(cls1, METHOD_NAME, TYPE),
|
||||||
|
+ LOOKUP.findStatic(cls2, METHOD_NAME, TYPE)
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ mcs = new MutableCallSite(LOOKUP.findStatic(T.class, "f1", TYPE));
|
||||||
|
+ execute(1, mhs);
|
||||||
|
+ mcs.setTarget(LOOKUP.findStatic(T.class, "f2", TYPE));
|
||||||
|
+ execute(2, mhs);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static void testNonBoundCallSite() throws Throwable {
|
||||||
|
+ mcs = new MutableCallSite(LOOKUP.findStatic(T.class, "f1", TYPE));
|
||||||
|
+
|
||||||
|
+ // mcs.context == null
|
||||||
|
+ MethodHandle mh = mcs.dynamicInvoker();
|
||||||
|
+ execute(1, mh);
|
||||||
|
+
|
||||||
|
+ // mcs.context == cls1
|
||||||
|
+ Class<?> cls1 = UNSAFE.defineAnonymousClass(Object.class, getClassFile("NonBound_1"), null);
|
||||||
|
+ MethodHandle mh1 = LOOKUP.findStatic(cls1, METHOD_NAME, TYPE);
|
||||||
|
+
|
||||||
|
+ execute(1, mh1);
|
||||||
|
+
|
||||||
|
+ mcs.setTarget(LOOKUP.findStatic(T.class, "f2", TYPE));
|
||||||
|
+
|
||||||
|
+ execute(2, mh, mh1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ static ReferenceQueue rq = new ReferenceQueue();
|
||||||
|
+ static PhantomReference ref;
|
||||||
|
+
|
||||||
|
+ public static void testGC() throws Throwable {
|
||||||
|
+ mcs = new MutableCallSite(LOOKUP.findStatic(T.class, "f1", TYPE));
|
||||||
|
+
|
||||||
|
+ Class<?>[] cls = new Class[] {
|
||||||
|
+ UNSAFE.defineAnonymousClass(Object.class, getClassFile("GC_1"), null),
|
||||||
|
+ UNSAFE.defineAnonymousClass(Object.class, getClassFile("GC_2"), null),
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ MethodHandle[] mhs = new MethodHandle[] {
|
||||||
|
+ LOOKUP.findStatic(cls[0], METHOD_NAME, TYPE),
|
||||||
|
+ LOOKUP.findStatic(cls[1], METHOD_NAME, TYPE),
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ // mcs.context == cls[0]
|
||||||
|
+ int r = (int) mhs[0].invokeExact();
|
||||||
|
+
|
||||||
|
+ execute(1, mhs);
|
||||||
|
+
|
||||||
|
+ ref = new PhantomReference<>(cls[0], rq);
|
||||||
|
+ cls[0] = UNSAFE.defineAnonymousClass(Object.class, getClassFile("GC_3"), null);
|
||||||
|
+ mhs[0] = LOOKUP.findStatic(cls[0], METHOD_NAME, TYPE);
|
||||||
|
+
|
||||||
|
+ do {
|
||||||
|
+ System.gc();
|
||||||
|
+ try {
|
||||||
|
+ Reference ref1 = rq.remove(1000);
|
||||||
|
+ if (ref1 == ref) {
|
||||||
|
+ ref1.clear();
|
||||||
|
+ System.gc(); // Ensure that the stale context is cleared
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ } catch(InterruptedException e) { /* ignore */ }
|
||||||
|
+ } while (true);
|
||||||
|
+
|
||||||
|
+ execute(1, mhs);
|
||||||
|
+ mcs.setTarget(LOOKUP.findStatic(T.class, "f2", TYPE));
|
||||||
|
+ execute(2, mhs);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static void main(String[] args) throws Throwable {
|
||||||
|
+ testSharedCallSite();
|
||||||
|
+ testNonBoundCallSite();
|
||||||
|
+ testGC();
|
||||||
|
+ System.out.println("TEST PASSED");
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/jdk/src/share/classes/java/lang/invoke/CallSite.java b/jdk/src/share/classes/java/lang/invoke/CallSite.java
|
||||||
|
index 10ac1c071..11e452b96 100644
|
||||||
|
--- a/jdk/src/share/classes/java/lang/invoke/CallSite.java
|
||||||
|
+++ b/jdk/src/share/classes/java/lang/invoke/CallSite.java
|
||||||
|
@@ -25,9 +25,10 @@
|
||||||
|
|
||||||
|
package java.lang.invoke;
|
||||||
|
|
||||||
|
-import sun.invoke.empty.Empty;
|
||||||
|
import static java.lang.invoke.MethodHandleStatics.*;
|
||||||
|
import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
|
||||||
|
+import java.lang.reflect.Field;
|
||||||
|
+import sun.misc.Cleaner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@code CallSite} is a holder for a variable {@link MethodHandle},
|
||||||
|
@@ -136,6 +137,50 @@ public class CallSite {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
+ * {@code CallSite} dependency context.
|
||||||
|
+ * VM uses context class to store nmethod dependencies on the call site target.
|
||||||
|
+ * Can be in 2 states: (a) null; or (b) {@code Cleaner} instance pointing to some Class instance.
|
||||||
|
+ * Lazily initialized when CallSite instance is linked to some indy call site or VM needs
|
||||||
|
+ * it to store dependencies. As a corollary, "null" context means there are no dependencies
|
||||||
|
+ * registered yet. {@code Cleaner} is used in 2 roles:
|
||||||
|
+ * (a) context class access for VM;
|
||||||
|
+ * (b) stale context class cleanup.
|
||||||
|
+ * {@code Cleaner} holds the context class until cleanup action is finished (see {@code PhantomReference}).
|
||||||
|
+ * Though it's impossible to get the context class using {@code Reference.get()}, VM extracts it directly
|
||||||
|
+ * from {@code Reference.referent} field.
|
||||||
|
+ */
|
||||||
|
+ private volatile Cleaner context = null;
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Default context.
|
||||||
|
+ * VM uses it to initialize non-linked CallSite context.
|
||||||
|
+ */
|
||||||
|
+ private static class DefaultContext {}
|
||||||
|
+ private static final Cleaner DEFAULT_CONTEXT = makeContext(DefaultContext.class, null);
|
||||||
|
+
|
||||||
|
+ private static Cleaner makeContext(Class<?> referent, final CallSite holder) {
|
||||||
|
+ return Cleaner.create(referent,
|
||||||
|
+ new Runnable() {
|
||||||
|
+ @Override public void run() {
|
||||||
|
+ MethodHandleNatives.invalidateDependentNMethods(holder);
|
||||||
|
+ }
|
||||||
|
+ });
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /** Initialize context class used for nmethod dependency tracking */
|
||||||
|
+ /*package-private*/
|
||||||
|
+ void initContext(Class<?> newContext) {
|
||||||
|
+ // If there are concurrent actions, exactly one succeeds.
|
||||||
|
+ if (context == null) {
|
||||||
|
+ UNSAFE.compareAndSwapObject(this, CONTEXT_OFFSET, /*expected=*/null, makeContext(newContext, this));
|
||||||
|
+ // No need to care about failed CAS attempt.
|
||||||
|
+ // Since initContext is called from indy call site linkage in newContext class, there's no risk
|
||||||
|
+ // that the context class becomes dead while corresponding context cleaner is alive (causing cleanup
|
||||||
|
+ // action in the wrong context).
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
* Returns the type of this call site's target.
|
||||||
|
* Although targets may change, any call site's type is permanent, and can never change to an unequal type.
|
||||||
|
* The {@code setTarget} method enforces this invariant by refusing any new target that does
|
||||||
|
@@ -246,11 +291,13 @@ public class CallSite {
|
||||||
|
}
|
||||||
|
|
||||||
|
// unsafe stuff:
|
||||||
|
- private static final long TARGET_OFFSET;
|
||||||
|
+ private static final long TARGET_OFFSET;
|
||||||
|
+ private static final long CONTEXT_OFFSET;
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
- TARGET_OFFSET = UNSAFE.objectFieldOffset(CallSite.class.getDeclaredField("target"));
|
||||||
|
- } catch (Exception ex) { throw new Error(ex); }
|
||||||
|
+ TARGET_OFFSET = UNSAFE.objectFieldOffset(CallSite.class.getDeclaredField("target"));
|
||||||
|
+ CONTEXT_OFFSET = UNSAFE.objectFieldOffset(CallSite.class.getDeclaredField("context"));
|
||||||
|
+ } catch (Exception ex) { throw newInternalError(ex); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/*package-private*/
|
||||||
|
diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java
|
||||||
|
index ecc146078..9a1343c50 100644
|
||||||
|
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java
|
||||||
|
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java
|
||||||
|
@@ -71,6 +71,9 @@ class MethodHandleNatives {
|
||||||
|
static native void setCallSiteTargetNormal(CallSite site, MethodHandle target);
|
||||||
|
static native void setCallSiteTargetVolatile(CallSite site, MethodHandle target);
|
||||||
|
|
||||||
|
+ /** Invalidate CallSite context: clean up dependent nmethods and reset call site context to initial state (null). */
|
||||||
|
+ static native void invalidateDependentNMethods(CallSite site);
|
||||||
|
+
|
||||||
|
private static native void registerNatives();
|
||||||
|
static {
|
||||||
|
registerNatives();
|
||||||
|
@@ -314,6 +317,7 @@ class MethodHandleNatives {
|
||||||
|
return Invokers.linkToTargetMethod(type);
|
||||||
|
} else {
|
||||||
|
appendixResult[0] = callSite;
|
||||||
|
+ callSite.initContext(caller);
|
||||||
|
return Invokers.linkToCallSiteMethod(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.12.3
|
||||||
|
|
||||||
1161
8079205-CallSite-dependency-tracking-is-broken-after.patch
Normal file
1161
8079205-CallSite-dependency-tracking-is-broken-after.patch
Normal file
File diff suppressed because it is too large
Load Diff
221
8177146-MethodHandles.Lookup-bind-allows-illegal-pro.patch
Normal file
221
8177146-MethodHandles.Lookup-bind-allows-illegal-pro.patch
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
From 5fbf4e8b326dd8453822ae40f3c6e4adffbf42ac Mon Sep 17 00:00:00 2001
|
||||||
|
From: zhangyipeng <zhangyipeng7@huawei.com>
|
||||||
|
Date: Fri, 3 Nov 2023 16:21:09 +0800
|
||||||
|
Subject: [PATCH] [Backport]8177146: MethodHandles.Lookup::bind allows illegal protected
|
||||||
|
access
|
||||||
|
|
||||||
|
---
|
||||||
|
.../classes/java/lang/invoke/MethodHandles.java | 22 +++--
|
||||||
|
.../lang/invoke/8177146/TestMethodHandleBind.java | 96 ++++++++++++++++++++++
|
||||||
|
jdk/test/java/lang/invoke/8177146/pkg/A.java | 40 +++++++++
|
||||||
|
3 files changed, 149 insertions(+), 9 deletions(-)
|
||||||
|
create mode 100644 jdk/test/java/lang/invoke/8177146/TestMethodHandleBind.java
|
||||||
|
create mode 100644 jdk/test/java/lang/invoke/8177146/pkg/A.java
|
||||||
|
|
||||||
|
diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java
|
||||||
|
index 7b9353ab0..62888c019 100644
|
||||||
|
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java
|
||||||
|
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java
|
||||||
|
@@ -1148,7 +1148,13 @@ return mh1;
|
||||||
|
public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
|
||||||
|
Class<? extends Object> refc = receiver.getClass(); // may get NPE
|
||||||
|
MemberName method = resolveOrFail(REF_invokeSpecial, refc, name, type);
|
||||||
|
- MethodHandle mh = getDirectMethodNoRestrict(REF_invokeSpecial, refc, method, findBoundCallerClass(method));
|
||||||
|
+ MethodHandle mh = getDirectMethodNoRestrictInvokeSpecial(refc, method, findBoundCallerClass(method));
|
||||||
|
+ if (!mh.type().leadingReferenceParameter().isAssignableFrom(receiver.getClass())) {
|
||||||
|
+ throw new IllegalAccessException("The restricted defining class " +
|
||||||
|
+ mh.type().leadingReferenceParameter().getName() +
|
||||||
|
+ " is not assignable from receiver class " +
|
||||||
|
+ receiver.getClass().getName());
|
||||||
|
+ }
|
||||||
|
return mh.bindArgumentL(0, receiver).setVarargs(method);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1591,7 +1597,7 @@ return mh1;
|
||||||
|
throw method.makeAccessException("caller class must be a subclass below the method", caller);
|
||||||
|
}
|
||||||
|
MethodType rawType = mh.type();
|
||||||
|
- if (rawType.parameterType(0) == caller) return mh;
|
||||||
|
+ if (caller.isAssignableFrom(rawType.parameterType(0))) return mh; // no need to restrict; already narrow
|
||||||
|
MethodType narrowType = rawType.changeParameterType(0, caller);
|
||||||
|
assert(!mh.isVarargsCollector()); // viewAsType will lose varargs-ness
|
||||||
|
assert(mh.viewAsTypeChecks(narrowType, true));
|
||||||
|
@@ -1604,11 +1610,11 @@ return mh1;
|
||||||
|
final boolean checkSecurity = true;
|
||||||
|
return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass);
|
||||||
|
}
|
||||||
|
- /** Check access and get the requested method, eliding receiver narrowing rules. */
|
||||||
|
- private MethodHandle getDirectMethodNoRestrict(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
|
||||||
|
+ /** Check access and get the requested method, for invokespecial with no restriction on the application of narrowing rules. */
|
||||||
|
+ private MethodHandle getDirectMethodNoRestrictInvokeSpecial(Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
|
||||||
|
final boolean doRestrict = false;
|
||||||
|
final boolean checkSecurity = true;
|
||||||
|
- return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass);
|
||||||
|
+ return getDirectMethodCommon(REF_invokeSpecial, refc, method, checkSecurity, doRestrict, callerClass);
|
||||||
|
}
|
||||||
|
/** Check access and get the requested method, eliding security manager checks. */
|
||||||
|
private MethodHandle getDirectMethodNoSecurityManager(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
|
||||||
|
@@ -1660,10 +1666,8 @@ return mh1;
|
||||||
|
DirectMethodHandle dmh = DirectMethodHandle.make(refKind, refc, method);
|
||||||
|
MethodHandle mh = dmh;
|
||||||
|
// Optionally narrow the receiver argument to refc using restrictReceiver.
|
||||||
|
- if (doRestrict &&
|
||||||
|
- (refKind == REF_invokeSpecial ||
|
||||||
|
- (MethodHandleNatives.refKindHasReceiver(refKind) &&
|
||||||
|
- restrictProtectedReceiver(method)))) {
|
||||||
|
+ if ((doRestrict && refKind == REF_invokeSpecial) ||
|
||||||
|
+ (MethodHandleNatives.refKindHasReceiver(refKind) && restrictProtectedReceiver(method))) {
|
||||||
|
mh = restrictReceiver(method, dmh, lookupClass());
|
||||||
|
}
|
||||||
|
mh = maybeBindCaller(method, mh, callerClass);
|
||||||
|
diff --git a/jdk/test/java/lang/invoke/8177146/TestMethodHandleBind.java b/jdk/test/java/lang/invoke/8177146/TestMethodHandleBind.java
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..134cc9f75
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/jdk/test/java/lang/invoke/8177146/TestMethodHandleBind.java
|
||||||
|
@@ -0,0 +1,96 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright (c) 2017, 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 8177146
|
||||||
|
+ * @run testng/othervm TestMethodHandleBind
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+import org.testng.annotations.Test;
|
||||||
|
+
|
||||||
|
+import java.lang.invoke.MethodHandle;
|
||||||
|
+import java.lang.invoke.MethodType;
|
||||||
|
+
|
||||||
|
+import static java.lang.invoke.MethodHandles.lookup;
|
||||||
|
+
|
||||||
|
+import static org.testng.Assert.*;
|
||||||
|
+
|
||||||
|
+public class TestMethodHandleBind extends pkg.A {
|
||||||
|
+ static class B extends TestMethodHandleBind {}
|
||||||
|
+
|
||||||
|
+ @Test
|
||||||
|
+ public void testInstanceOfCallerClass() throws Throwable {
|
||||||
|
+ MethodHandle bound = lookup().bind(new TestMethodHandleBind() , "m1", MethodType.methodType(String.class));
|
||||||
|
+ String x = (String)bound.invoke();
|
||||||
|
+ assertEquals(x, this.getClass().getSimpleName());
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Test
|
||||||
|
+ public void testInstanceOfCallerSubclass() throws Throwable {
|
||||||
|
+ MethodHandle bound = lookup().bind(new B() , "m1", MethodType.methodType(String.class));
|
||||||
|
+ // MethodHandle bound = lookup().findVirtual(B.class, "m1", MethodType.methodType(String.class)).bindTo(new B());
|
||||||
|
+ String x = (String)bound.invoke();
|
||||||
|
+ assertEquals(x, "B");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Test
|
||||||
|
+ public void testInstanceOfReceiverClass() throws Throwable {
|
||||||
|
+ try {
|
||||||
|
+ MethodHandle bound = lookup().bind(new pkg.A() , "m1", MethodType.methodType(String.class));
|
||||||
|
+ bound.invoke();
|
||||||
|
+ fail("IllegalAccessException expected");
|
||||||
|
+ } catch (IllegalAccessException e) {
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Test
|
||||||
|
+ public void testPublicMethod() throws Throwable {
|
||||||
|
+ MethodHandle bound = lookup().bind(new pkg.A() , "m2", MethodType.methodType(String.class));
|
||||||
|
+ String x = (String)bound.invoke();
|
||||||
|
+ assertEquals(x, "A");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Test
|
||||||
|
+ public void testPublicMethod2() throws Throwable {
|
||||||
|
+ MethodHandle bound = lookup().bind(new TestMethodHandleBind(), "m2", MethodType.methodType(String.class));
|
||||||
|
+ String x = (String)bound.invoke();
|
||||||
|
+ assertEquals(x, this.getClass().getSimpleName());
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Test
|
||||||
|
+ public void testInstanceOfCallerClassVarargs() throws Throwable {
|
||||||
|
+ MethodHandle bound = lookup().bind(new TestMethodHandleBind() , "m3", MethodType.methodType(String.class, String[].class));
|
||||||
|
+ String x = (String)bound.invoke("a", "b", "c");
|
||||||
|
+ assertEquals(x, this.getClass().getSimpleName() + "abc");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Test
|
||||||
|
+ public void testInstanceOfReceiverClassVarargs() throws Throwable {
|
||||||
|
+ try {
|
||||||
|
+ MethodHandle bound = lookup().bind(new pkg.A(), "m3", MethodType.methodType(String.class, String[].class));
|
||||||
|
+ bound.invoke();
|
||||||
|
+ fail("IllegalAccessException expected");
|
||||||
|
+ } catch (IllegalAccessException e) {
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/jdk/test/java/lang/invoke/8177146/pkg/A.java b/jdk/test/java/lang/invoke/8177146/pkg/A.java
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..f34d52b8e
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/jdk/test/java/lang/invoke/8177146/pkg/A.java
|
||||||
|
@@ -0,0 +1,40 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright (c) 2017, 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 pkg;
|
||||||
|
+
|
||||||
|
+public class A {
|
||||||
|
+ protected String m1() {
|
||||||
|
+ return this.getClass().getSimpleName();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public String m2() {
|
||||||
|
+ return this.getClass().getSimpleName();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ protected String m3(String... args) {
|
||||||
|
+ StringBuilder sb = new StringBuilder();
|
||||||
|
+ for (String s : args)
|
||||||
|
+ sb.append(s);
|
||||||
|
+ return this.getClass().getSimpleName() + sb.toString();
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.12.3
|
||||||
|
|
||||||
@ -12,22 +12,6 @@ Bug url: https://bugs.openjdk.java.net/browse/JDK-8203699
|
|||||||
2 files changed, 171 insertions(+)
|
2 files changed, 171 insertions(+)
|
||||||
create mode 100644 jdk/test/java/lang/invoke/lookup/TestDefenderMethodLookup.java
|
create mode 100644 jdk/test/java/lang/invoke/lookup/TestDefenderMethodLookup.java
|
||||||
|
|
||||||
diff --git a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
|
|
||||||
index f771c5f07..70ab1bcb8 100644
|
|
||||||
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
|
|
||||||
+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
|
|
||||||
@@ -1209,6 +1209,11 @@ void MacroAssembler::check_klass_subtype_slow_path(Register sub_klass,
|
|
||||||
mov(r0, super_klass);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ // Get super_klass value into r0 (even if it was in r5 or r2)
|
|
||||||
+ if (super_klass != r0) {
|
|
||||||
+ mov(r0, super_klass);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
#ifndef PRODUCT
|
|
||||||
mov(rscratch2, (address)&SharedRuntime::_partial_subtype_ctr);
|
|
||||||
Address pst_counter_addr(rscratch2);
|
|
||||||
diff --git a/jdk/test/java/lang/invoke/lookup/TestDefenderMethodLookup.java b/jdk/test/java/lang/invoke/lookup/TestDefenderMethodLookup.java
|
diff --git a/jdk/test/java/lang/invoke/lookup/TestDefenderMethodLookup.java b/jdk/test/java/lang/invoke/lookup/TestDefenderMethodLookup.java
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 000000000..8ab268b57
|
index 000000000..8ab268b57
|
||||||
|
|||||||
131
8260923-Add-more-tests-for-SSLSocket-input-output-sh.patch
Normal file
131
8260923-Add-more-tests-for-SSLSocket-input-output-sh.patch
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
From c3aae68d629a3adc02fb0764c95d922e716f0ee3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: zhangyipeng <zhangyipeng7@huawei.com>
|
||||||
|
Date: Mon, 15 Jan 2024 11:13:55 +0800
|
||||||
|
Subject: [PATCH] [Backport]8260923: Add more tests for SSLSocket input/output shutdown
|
||||||
|
---
|
||||||
|
.../ssl/SSLSocketImpl/SSLSocketCloseHang.java | 69 ++++++++++++++--------
|
||||||
|
1 file changed, 46 insertions(+), 23 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/jdk/test/sun/security/ssl/SSLSocketImpl/SSLSocketCloseHang.java b/jdk/test/sun/security/ssl/SSLSocketImpl/SSLSocketCloseHang.java
|
||||||
|
index f74c1fe76..ff6334feb 100644
|
||||||
|
--- a/jdk/test/sun/security/ssl/SSLSocketImpl/SSLSocketCloseHang.java
|
||||||
|
+++ b/jdk/test/sun/security/ssl/SSLSocketImpl/SSLSocketCloseHang.java
|
||||||
|
@@ -23,12 +23,17 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
- * @bug 8184328 8253368
|
||||||
|
+ * @bug 8184328 8253368 8260923
|
||||||
|
* @summary JDK8u131-b34-socketRead0 hang at SSL read
|
||||||
|
- * @run main/othervm SSLSocketCloseHang
|
||||||
|
- * @run main/othervm SSLSocketCloseHang shutdownInputTest
|
||||||
|
+ * @run main/othervm SSLSocketCloseHang TLSv1.2
|
||||||
|
+ * @run main/othervm SSLSocketCloseHang TLSv1.2 shutdownInput
|
||||||
|
+ * @run main/othervm SSLSocketCloseHang TLSv1.2 shutdownOutput
|
||||||
|
+ * @run main/othervm SSLSocketCloseHang TLSv1.3
|
||||||
|
+ * @run main/othervm SSLSocketCloseHang TLSv1.3 shutdownInput
|
||||||
|
+ * @run main/othervm SSLSocketCloseHang TLSv1.3 shutdownOutput
|
||||||
|
*/
|
||||||
|
|
||||||
|
+
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.*;
|
||||||
|
import java.util.*;
|
||||||
|
@@ -36,7 +41,6 @@ import java.security.*;
|
||||||
|
import javax.net.ssl.*;
|
||||||
|
|
||||||
|
public class SSLSocketCloseHang {
|
||||||
|
-
|
||||||
|
/*
|
||||||
|
* =============================================================
|
||||||
|
* Set the various variables needed for the tests, then
|
||||||
|
@@ -73,7 +77,7 @@ public class SSLSocketCloseHang {
|
||||||
|
*/
|
||||||
|
static boolean debug = false;
|
||||||
|
|
||||||
|
- static boolean shutdownInputTest = false;
|
||||||
|
+ static String socketCloseType;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the client or server is doing some kind of object creation
|
||||||
|
@@ -148,28 +152,45 @@ public class SSLSocketCloseHang {
|
||||||
|
Thread.sleep(500);
|
||||||
|
System.err.println("Client closing: " + System.nanoTime());
|
||||||
|
|
||||||
|
- if (shutdownInputTest) {
|
||||||
|
- try {
|
||||||
|
- sslSocket.shutdownInput();
|
||||||
|
- } catch (SSLException e) {
|
||||||
|
- if (!e.getMessage().contains
|
||||||
|
- ("closing inbound before receiving peer's close_notify")) {
|
||||||
|
- throw new RuntimeException("expected different exception message. " +
|
||||||
|
- e.getMessage());
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- if (!sslSocket.getSession().isValid()) {
|
||||||
|
- throw new RuntimeException("expected session to remain valid");
|
||||||
|
- }
|
||||||
|
+ closeConnection(sslSocket);
|
||||||
|
+
|
||||||
|
+ clientClosed = true;
|
||||||
|
+ System.err.println("Client closed: " + System.nanoTime());
|
||||||
|
+ }
|
||||||
|
|
||||||
|
+ private void closeConnection(SSLSocket sslSocket) throws IOException {
|
||||||
|
+ if ("shutdownInput".equals(socketCloseType)) {
|
||||||
|
+ shutdownInput(sslSocket);
|
||||||
|
+ // second call to shutdownInput() should just return,
|
||||||
|
+ // shouldn't throw any exception
|
||||||
|
+ sslSocket.shutdownInput();
|
||||||
|
+ // invoking shutdownOutput() just after shutdownInput()
|
||||||
|
+ sslSocket.shutdownOutput();
|
||||||
|
+ } else if ("shutdownOutput".equals(socketCloseType)) {
|
||||||
|
+ sslSocket.shutdownOutput();
|
||||||
|
+ // second call to shutdownInput() should just return,
|
||||||
|
+ // shouldn't throw any exception
|
||||||
|
+ sslSocket.shutdownOutput();
|
||||||
|
+ // invoking shutdownInput() just after shutdownOutput()
|
||||||
|
+ shutdownInput(sslSocket);
|
||||||
|
} else {
|
||||||
|
sslSocket.close();
|
||||||
|
}
|
||||||
|
+ }
|
||||||
|
|
||||||
|
-
|
||||||
|
-
|
||||||
|
- clientClosed = true;
|
||||||
|
- System.err.println("Client closed: " + System.nanoTime());
|
||||||
|
+ private void shutdownInput(SSLSocket sslSocket) throws IOException {
|
||||||
|
+ try {
|
||||||
|
+ sslSocket.shutdownInput();
|
||||||
|
+ } catch (SSLException e) {
|
||||||
|
+ if (!e.getMessage().contains
|
||||||
|
+ ("closing inbound before receiving peer's close_notify")) {
|
||||||
|
+ throw new RuntimeException("expected different exception "
|
||||||
|
+ + "message. " + e.getMessage());
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ if (!sslSocket.getSession().isValid()) {
|
||||||
|
+ throw new RuntimeException("expected session to remain valid");
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -197,11 +218,13 @@ public class SSLSocketCloseHang {
|
||||||
|
System.setProperty("javax.net.ssl.keyStorePassword", passwd);
|
||||||
|
System.setProperty("javax.net.ssl.trustStore", trustFilename);
|
||||||
|
System.setProperty("javax.net.ssl.trustStorePassword", passwd);
|
||||||
|
+ System.setProperty("jdk.tls.client.protocols", args[0]);
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
System.setProperty("javax.net.debug", "all");
|
||||||
|
|
||||||
|
- shutdownInputTest = args.length > 0 ? true : false;
|
||||||
|
+ socketCloseType = args.length > 1 ? args[1] : "";
|
||||||
|
+
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start the tests.
|
||||||
|
--
|
||||||
|
2.12.3
|
||||||
|
|
||||||
581
8273553-sun.security.ssl.SSLEngineImpl.closeInbound-.patch
Normal file
581
8273553-sun.security.ssl.SSLEngineImpl.closeInbound-.patch
Normal file
@ -0,0 +1,581 @@
|
|||||||
|
From 4e32bc622c1f73c2ab6a4ef4b4bbd92e381a3439 Mon Sep 17 00:00:00 2001
|
||||||
|
From: zhangyipeng <zhangyipeng7@huawei.com>
|
||||||
|
Date: Mon, 15 Jan 2024 11:11:41 +0800
|
||||||
|
Subject: [PATCH] [Backport]8273553: sun.security.ssl.SSLEngineImpl.closeInbound also has
|
||||||
|
similar error of JDK-8253368
|
||||||
|
---
|
||||||
|
.../classes/sun/security/ssl/SSLEngineImpl.java | 24 +-
|
||||||
|
.../classes/sun/security/ssl/SSLSocketImpl.java | 7 +-
|
||||||
|
.../SSLSocketSSLEngineCloseInbound.java | 491 +++++++++++++++++++++
|
||||||
|
3 files changed, 508 insertions(+), 14 deletions(-)
|
||||||
|
create mode 100644 jdk/test/sun/security/ssl/SSLSocketImpl/SSLSocketSSLEngineCloseInbound.java
|
||||||
|
|
||||||
|
diff --git a/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java b/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java
|
||||||
|
index 05ffb8a00..a9cc989f2 100644
|
||||||
|
--- a/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java
|
||||||
|
+++ b/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java
|
||||||
|
@@ -47,7 +47,7 @@ import javax.net.ssl.SSLProtocolException;
|
||||||
|
import javax.net.ssl.SSLSession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
- * Implementation of an non-blocking SSLEngine.
|
||||||
|
+ * Implementation of a non-blocking SSLEngine.
|
||||||
|
*
|
||||||
|
* @author Brad Wetmore
|
||||||
|
*/
|
||||||
|
@@ -230,7 +230,7 @@ final class SSLEngineImpl extends SSLEngine implements SSLTransport {
|
||||||
|
if (ciphertext == null && !conContext.isNegotiated &&
|
||||||
|
conContext.isInboundClosed() &&
|
||||||
|
hsStatus == HandshakeStatus.NEED_WRAP) {
|
||||||
|
- // Even the outboud is open, no futher data could be wrapped as:
|
||||||
|
+ // Even the outbound is open, no further data could be wrapped as:
|
||||||
|
// 1. the outbound is empty
|
||||||
|
// 2. no negotiated connection
|
||||||
|
// 3. the inbound has closed, cannot complete the handshake
|
||||||
|
@@ -631,17 +631,19 @@ final class SSLEngineImpl extends SSLEngine implements SSLTransport {
|
||||||
|
SSLLogger.finest("Closing inbound of SSLEngine");
|
||||||
|
}
|
||||||
|
|
||||||
|
- // Is it ready to close inbound?
|
||||||
|
- //
|
||||||
|
- // No need to throw exception if the initial handshake is not started.
|
||||||
|
- if (!conContext.isInputCloseNotified &&
|
||||||
|
- (conContext.isNegotiated || conContext.handshakeContext != null)) {
|
||||||
|
|
||||||
|
- throw conContext.fatal(Alert.INTERNAL_ERROR,
|
||||||
|
- "closing inbound before receiving peer's close_notify");
|
||||||
|
+ try {
|
||||||
|
+ // Is it ready to close inbound?
|
||||||
|
+ //
|
||||||
|
+ // No need to throw exception if the initial handshake is not started.
|
||||||
|
+ if (!conContext.isInputCloseNotified &&
|
||||||
|
+ (conContext.isNegotiated || conContext.handshakeContext != null)) {
|
||||||
|
+ throw new SSLException(
|
||||||
|
+ "closing inbound before receiving peer's close_notify");
|
||||||
|
+ }
|
||||||
|
+ } finally {
|
||||||
|
+ conContext.closeInbound();
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- conContext.closeInbound();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
diff --git a/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java b/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java
|
||||||
|
index 69c96f226..7e8b131bb 100644
|
||||||
|
--- a/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java
|
||||||
|
+++ b/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java
|
||||||
|
@@ -742,9 +742,10 @@ public final class SSLSocketImpl
|
||||||
|
// No need to throw exception if the initial handshake is not started.
|
||||||
|
try {
|
||||||
|
if (checkCloseNotify && !conContext.isInputCloseNotified &&
|
||||||
|
- (conContext.isNegotiated || conContext.handshakeContext != null)) {
|
||||||
|
- throw new SSLException(
|
||||||
|
- "closing inbound before receiving peer's close_notify");
|
||||||
|
+ (conContext.isNegotiated ||
|
||||||
|
+ conContext.handshakeContext != null)) {
|
||||||
|
+ throw new SSLException(
|
||||||
|
+ "closing inbound before receiving peer's close_notify");
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
conContext.closeInbound();
|
||||||
|
diff --git a/jdk/test/sun/security/ssl/SSLSocketImpl/SSLSocketSSLEngineCloseInbound.java b/jdk/test/sun/security/ssl/SSLSocketImpl/SSLSocketSSLEngineCloseInbound.java
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..abf1571ca
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/jdk/test/sun/security/ssl/SSLSocketImpl/SSLSocketSSLEngineCloseInbound.java
|
||||||
|
@@ -0,0 +1,491 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright (c) 2011, 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
|
||||||
|
+ * 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.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+//
|
||||||
|
+// SunJSSE does not support dynamic system properties, no way to re-use
|
||||||
|
+// system properties in samevm/agentvm mode.
|
||||||
|
+//
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * @test
|
||||||
|
+ * @bug 8273553 8253368
|
||||||
|
+ * @summary sun.security.ssl.SSLEngineImpl.closeInbound also has similar error
|
||||||
|
+ * of JDK-8253368
|
||||||
|
+ * @run main/othervm SSLSocketSSLEngineCloseInbound TLSv1.3
|
||||||
|
+ * @run main/othervm SSLSocketSSLEngineCloseInbound TLSv1.2
|
||||||
|
+ * @run main/othervm SSLSocketSSLEngineCloseInbound TLSv1.1
|
||||||
|
+ * @run main/othervm SSLSocketSSLEngineCloseInbound TLSv1
|
||||||
|
+ * @run main/othervm SSLSocketSSLEngineCloseInbound TLS
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * A SSLSocket/SSLEngine interop test case. This is not the way to
|
||||||
|
+ * code SSLEngine-based servers, but works for what we need to do here,
|
||||||
|
+ * which is to make sure that SSLEngine/SSLSockets can talk to each other.
|
||||||
|
+ * SSLEngines can use direct or indirect buffers, and different code
|
||||||
|
+ * is used to get at the buffer contents internally, so we test that here.
|
||||||
|
+ *
|
||||||
|
+ * The test creates one SSLSocket (client) and one SSLEngine (server).
|
||||||
|
+ * The SSLSocket talks to a raw ServerSocket, and the server code
|
||||||
|
+ * does the translation between byte [] and ByteBuffers that the SSLEngine
|
||||||
|
+ * can use. The "transport" layer consists of a Socket Input/OutputStream
|
||||||
|
+ * and two byte buffers for the SSLEngines: think of them
|
||||||
|
+ * as directly connected pipes.
|
||||||
|
+ *
|
||||||
|
+ * Again, this is a *very* simple example: real code will be much more
|
||||||
|
+ * involved. For example, different threading and I/O models could be
|
||||||
|
+ * used, transport mechanisms could close unexpectedly, and so on.
|
||||||
|
+ *
|
||||||
|
+ * When this application runs, notice that several messages
|
||||||
|
+ * (wrap/unwrap) pass before any application data is consumed or
|
||||||
|
+ * produced. (For more information, please see the SSL/TLS
|
||||||
|
+ * specifications.) There may several steps for a successful handshake,
|
||||||
|
+ * so it's typical to see the following series of operations:
|
||||||
|
+ *
|
||||||
|
+ * client server message
|
||||||
|
+ * ====== ====== =======
|
||||||
|
+ * write() ... ClientHello
|
||||||
|
+ * ... unwrap() ClientHello
|
||||||
|
+ * ... wrap() ServerHello/Certificate
|
||||||
|
+ * read() ... ServerHello/Certificate
|
||||||
|
+ * write() ... ClientKeyExchange
|
||||||
|
+ * write() ... ChangeCipherSpec
|
||||||
|
+ * write() ... Finished
|
||||||
|
+ * ... unwrap() ClientKeyExchange
|
||||||
|
+ * ... unwrap() ChangeCipherSpec
|
||||||
|
+ * ... unwrap() Finished
|
||||||
|
+ * ... wrap() ChangeCipherSpec
|
||||||
|
+ * ... wrap() Finished
|
||||||
|
+ * read() ... ChangeCipherSpec
|
||||||
|
+ * read() ... Finished
|
||||||
|
+ */
|
||||||
|
+import javax.net.ssl.*;
|
||||||
|
+import javax.net.ssl.SSLEngineResult.*;
|
||||||
|
+import java.io.*;
|
||||||
|
+import java.net.*;
|
||||||
|
+import java.security.*;
|
||||||
|
+import java.nio.*;
|
||||||
|
+
|
||||||
|
+public class SSLSocketSSLEngineCloseInbound {
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Enables logging of the SSL/TLS operations.
|
||||||
|
+ */
|
||||||
|
+ private static final boolean logging = true;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Enables the JSSE system debugging system property:
|
||||||
|
+ *
|
||||||
|
+ * -Djavax.net.debug=all
|
||||||
|
+ *
|
||||||
|
+ * This gives a lot of low-level information about operations underway,
|
||||||
|
+ * including specific handshake messages, and might be best examined
|
||||||
|
+ * after gaining some familiarity with this application.
|
||||||
|
+ */
|
||||||
|
+ private static final boolean debug = false;
|
||||||
|
+ private final SSLContext sslc;
|
||||||
|
+ private SSLEngine serverEngine; // server-side SSLEngine
|
||||||
|
+ private SSLSocket clientSocket;
|
||||||
|
+
|
||||||
|
+ private final byte[] serverMsg =
|
||||||
|
+ "Hi there Client, I'm a Server.".getBytes();
|
||||||
|
+ private final byte[] clientMsg =
|
||||||
|
+ "Hello Server, I'm a Client! Pleased to meet you!".getBytes();
|
||||||
|
+
|
||||||
|
+ private ByteBuffer serverOut; // write side of serverEngine
|
||||||
|
+ private ByteBuffer serverIn; // read side of serverEngine
|
||||||
|
+
|
||||||
|
+ private volatile Exception clientException;
|
||||||
|
+ private volatile Exception serverException;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * For data transport, this example uses local ByteBuffers.
|
||||||
|
+ */
|
||||||
|
+ private ByteBuffer cTOs; // "reliable" transport client->server
|
||||||
|
+ private ByteBuffer sTOc; // "reliable" transport server->client
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * The following is to set up the keystores/trust material.
|
||||||
|
+ */
|
||||||
|
+ private static final String pathToStores = "../../../../javax/net/ssl/etc";
|
||||||
|
+ private static final String keyStoreFile = "keystore";
|
||||||
|
+ private static final String trustStoreFile = "truststore";
|
||||||
|
+ private static final String keyFilename =
|
||||||
|
+ System.getProperty("test.src", ".") + "/" + pathToStores
|
||||||
|
+ + "/" + keyStoreFile;
|
||||||
|
+ private static final String trustFilename =
|
||||||
|
+ System.getProperty("test.src", ".") + "/" + pathToStores
|
||||||
|
+ + "/" + trustStoreFile;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Main entry point for this test.
|
||||||
|
+ */
|
||||||
|
+ public static void main(String[] args) throws Exception {
|
||||||
|
+ String protocol = args[0];
|
||||||
|
+
|
||||||
|
+ // reset security properties to make sure that the algorithms
|
||||||
|
+ // and keys used in this test are not disabled.
|
||||||
|
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
|
||||||
|
+ Security.setProperty("jdk.certpath.disabledAlgorithms", "");
|
||||||
|
+
|
||||||
|
+ if (debug) {
|
||||||
|
+ System.setProperty("javax.net.debug", "all");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Run the tests with direct and indirect buffers.
|
||||||
|
+ */
|
||||||
|
+ SSLSocketSSLEngineCloseInbound test =
|
||||||
|
+ new SSLSocketSSLEngineCloseInbound(protocol);
|
||||||
|
+ log("-------------------------------------");
|
||||||
|
+ log("Testing " + protocol + " for direct buffers ...");
|
||||||
|
+ test.runTest(true);
|
||||||
|
+
|
||||||
|
+ log("---------------------------------------");
|
||||||
|
+ log("Testing " + protocol + " for indirect buffers ...");
|
||||||
|
+ test.runTest(false);
|
||||||
|
+
|
||||||
|
+ log("Test Passed.");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Create an initialized SSLContext to use for these tests.
|
||||||
|
+ */
|
||||||
|
+ public SSLSocketSSLEngineCloseInbound(String protocol) throws Exception {
|
||||||
|
+
|
||||||
|
+ KeyStore ks = KeyStore.getInstance("JKS");
|
||||||
|
+ KeyStore ts = KeyStore.getInstance("JKS");
|
||||||
|
+
|
||||||
|
+ char[] passphrase = "passphrase".toCharArray();
|
||||||
|
+
|
||||||
|
+ try (FileInputStream keyFile = new FileInputStream(keyFilename);
|
||||||
|
+ FileInputStream trustFile = new FileInputStream(trustFilename)) {
|
||||||
|
+ ks.load(keyFile, passphrase);
|
||||||
|
+ ts.load(trustFile, passphrase);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
|
||||||
|
+ kmf.init(ks, passphrase);
|
||||||
|
+
|
||||||
|
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
|
||||||
|
+ tmf.init(ts);
|
||||||
|
+
|
||||||
|
+ SSLContext sslCtx = SSLContext.getInstance(protocol);
|
||||||
|
+
|
||||||
|
+ sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
|
||||||
|
+
|
||||||
|
+ sslc = sslCtx;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Run the test.
|
||||||
|
+ *
|
||||||
|
+ * Sit in a tight loop, with the server engine calling wrap/unwrap
|
||||||
|
+ * regardless of whether data is available or not. We do this until
|
||||||
|
+ * we get the application data. Then we shutdown and go to the next one.
|
||||||
|
+ *
|
||||||
|
+ * The main loop handles all the I/O phases of the SSLEngine's
|
||||||
|
+ * lifetime:
|
||||||
|
+ *
|
||||||
|
+ * initial handshaking
|
||||||
|
+ * application data transfer
|
||||||
|
+ * engine closing
|
||||||
|
+ *
|
||||||
|
+ * One could easily separate these phases into separate
|
||||||
|
+ * sections of code.
|
||||||
|
+ */
|
||||||
|
+ private void runTest(boolean direct) throws Exception {
|
||||||
|
+ clientSocket = null;
|
||||||
|
+
|
||||||
|
+ // generates the server-side Socket
|
||||||
|
+ try (ServerSocket serverSocket = new ServerSocket()) {
|
||||||
|
+ serverSocket.setReuseAddress(false);
|
||||||
|
+ serverSocket.bind(null);
|
||||||
|
+ int port = serverSocket.getLocalPort();
|
||||||
|
+ log("Port: " + port);
|
||||||
|
+ Thread thread = createClientThread(port);
|
||||||
|
+
|
||||||
|
+ createSSLEngine();
|
||||||
|
+ createBuffers(direct);
|
||||||
|
+
|
||||||
|
+ // server-side socket that will read
|
||||||
|
+ try (Socket socket = serverSocket.accept()) {
|
||||||
|
+ socket.setSoTimeout(500);
|
||||||
|
+
|
||||||
|
+ InputStream is = socket.getInputStream();
|
||||||
|
+ OutputStream os = socket.getOutputStream();
|
||||||
|
+
|
||||||
|
+ SSLEngineResult serverResult; // results from last operation
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Examining the SSLEngineResults could be much more involved,
|
||||||
|
+ * and may alter the overall flow of the application.
|
||||||
|
+ *
|
||||||
|
+ * For example, if we received a BUFFER_OVERFLOW when trying
|
||||||
|
+ * to write to the output pipe, we could reallocate a larger
|
||||||
|
+ * pipe, but instead we wait for the peer to drain it.
|
||||||
|
+ */
|
||||||
|
+ byte[] inbound = new byte[8192];
|
||||||
|
+ byte[] outbound = new byte[8192];
|
||||||
|
+
|
||||||
|
+ while (!isEngineClosed(serverEngine)) {
|
||||||
|
+ int len;
|
||||||
|
+
|
||||||
|
+ // Inbound data
|
||||||
|
+ log("================");
|
||||||
|
+
|
||||||
|
+ // Try reading Client side, even if it's already closed.
|
||||||
|
+ try {
|
||||||
|
+ len = is.read(inbound);
|
||||||
|
+ if (len > 0) {
|
||||||
|
+ cTOs.put(inbound, 0, len);
|
||||||
|
+ }
|
||||||
|
+ } catch (IOException e) {
|
||||||
|
+ /*
|
||||||
|
+ * swallow IO/SocketTimeoutExceptions. We'll do
|
||||||
|
+ * the testing/exit after the unwraps.
|
||||||
|
+ */
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ cTOs.flip();
|
||||||
|
+
|
||||||
|
+ serverResult = serverEngine.unwrap(cTOs, serverIn);
|
||||||
|
+ log("server unwrap: ", serverResult);
|
||||||
|
+ runDelegatedTasks(serverResult, serverEngine);
|
||||||
|
+ cTOs.compact();
|
||||||
|
+
|
||||||
|
+ // Outbound data
|
||||||
|
+ log("----");
|
||||||
|
+
|
||||||
|
+ // After we've received our app bytes, close input side
|
||||||
|
+ // and see what happens. Exit the test at the end.
|
||||||
|
+ if (serverIn.position() != 0) {
|
||||||
|
+ try {
|
||||||
|
+ serverEngine.closeInbound();
|
||||||
|
+ throw new Exception(
|
||||||
|
+ "No error shutting down client's input");
|
||||||
|
+ } catch (SSLException e) {
|
||||||
|
+ System.out.println(
|
||||||
|
+ "Server caught the right Exception");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (serverEngine.getSession().isValid()) {
|
||||||
|
+ System.out.println("Server session is still valid");
|
||||||
|
+ } else {
|
||||||
|
+ throw new Exception("Server session is not valid");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ serverResult = serverEngine.wrap(serverOut, sTOc);
|
||||||
|
+ log("server wrap: ", serverResult);
|
||||||
|
+ runDelegatedTasks(serverResult, serverEngine);
|
||||||
|
+
|
||||||
|
+ sTOc.flip();
|
||||||
|
+
|
||||||
|
+ if ((len = sTOc.remaining()) != 0) {
|
||||||
|
+ sTOc.get(outbound, 0, len);
|
||||||
|
+ os.write(outbound, 0, len);
|
||||||
|
+ // Give the other side a chance to process
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ sTOc.compact();
|
||||||
|
+ }
|
||||||
|
+ } catch (Exception e) {
|
||||||
|
+ serverException = e;
|
||||||
|
+ } finally {
|
||||||
|
+ // Wait for the client to join up with us.
|
||||||
|
+ if (thread != null) {
|
||||||
|
+ thread.join();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ } finally {
|
||||||
|
+ if (serverException != null) {
|
||||||
|
+ if (clientException != null) {
|
||||||
|
+ serverException.initCause(clientException);
|
||||||
|
+ }
|
||||||
|
+ throw serverException;
|
||||||
|
+ }
|
||||||
|
+ if (clientException != null) {
|
||||||
|
+ if (serverException != null) {
|
||||||
|
+ clientException.initCause(serverException);
|
||||||
|
+ }
|
||||||
|
+ throw clientException;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Create a client thread which does simple SSLSocket operations.
|
||||||
|
+ * We'll write and read one data packet.
|
||||||
|
+ */
|
||||||
|
+ private Thread createClientThread(final int port) {
|
||||||
|
+
|
||||||
|
+ Thread t = new Thread("ClientThread") {
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public void run() {
|
||||||
|
+ // client-side socket
|
||||||
|
+ try (SSLSocket sslSocket = (SSLSocket)sslc.getSocketFactory().
|
||||||
|
+ createSocket("localhost", port)) {
|
||||||
|
+ clientSocket = sslSocket;
|
||||||
|
+
|
||||||
|
+ OutputStream os = sslSocket.getOutputStream();
|
||||||
|
+
|
||||||
|
+ // write(byte[]) goes in one shot.
|
||||||
|
+ os.write(clientMsg);
|
||||||
|
+ os.flush();
|
||||||
|
+
|
||||||
|
+ try {
|
||||||
|
+ sslSocket.shutdownInput();
|
||||||
|
+ throw new Exception(
|
||||||
|
+ "No error shutting down client's input");
|
||||||
|
+ } catch (SSLException e) {
|
||||||
|
+ System.out.println("Client caught the right Exception");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (sslSocket.getSession().isValid()) {
|
||||||
|
+ System.out.println("Client session is still valid");
|
||||||
|
+ } else {
|
||||||
|
+ throw new Exception("Client's session is not valid");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // Give server a chance to read before we shutdown via
|
||||||
|
+ // the try-with-resources block.
|
||||||
|
+ Thread.sleep(2000);
|
||||||
|
+ } catch (Exception e) {
|
||||||
|
+ clientException = e;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ };
|
||||||
|
+ t.start();
|
||||||
|
+ return t;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Using the SSLContext created during object creation,
|
||||||
|
+ * create/configure the SSLEngines we'll use for this test.
|
||||||
|
+ */
|
||||||
|
+ private void createSSLEngine() {
|
||||||
|
+ /*
|
||||||
|
+ * Configure the serverEngine to act as a server in the SSL/TLS
|
||||||
|
+ * handshake.
|
||||||
|
+ */
|
||||||
|
+ serverEngine = sslc.createSSLEngine();
|
||||||
|
+ serverEngine.setUseClientMode(false);
|
||||||
|
+ serverEngine.getNeedClientAuth();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Create and size the buffers appropriately.
|
||||||
|
+ */
|
||||||
|
+ private void createBuffers(boolean direct) {
|
||||||
|
+
|
||||||
|
+ SSLSession session = serverEngine.getSession();
|
||||||
|
+ int appBufferMax = session.getApplicationBufferSize();
|
||||||
|
+ int netBufferMax = session.getPacketBufferSize();
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * We'll make the input buffers a bit bigger than the max needed
|
||||||
|
+ * size, so that unwrap()s following a successful data transfer
|
||||||
|
+ * won't generate BUFFER_OVERFLOWS.
|
||||||
|
+ *
|
||||||
|
+ * We'll use a mix of direct and indirect ByteBuffers for
|
||||||
|
+ * tutorial purposes only. In reality, only use direct
|
||||||
|
+ * ByteBuffers when they give a clear performance enhancement.
|
||||||
|
+ */
|
||||||
|
+ if (direct) {
|
||||||
|
+ serverIn = ByteBuffer.allocateDirect(appBufferMax + 50);
|
||||||
|
+ cTOs = ByteBuffer.allocateDirect(netBufferMax);
|
||||||
|
+ sTOc = ByteBuffer.allocateDirect(netBufferMax);
|
||||||
|
+ } else {
|
||||||
|
+ serverIn = ByteBuffer.allocate(appBufferMax + 50);
|
||||||
|
+ cTOs = ByteBuffer.allocate(netBufferMax);
|
||||||
|
+ sTOc = ByteBuffer.allocate(netBufferMax);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ serverOut = ByteBuffer.wrap(serverMsg);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * If the result indicates that we have outstanding tasks to do,
|
||||||
|
+ * go ahead and run them in this thread.
|
||||||
|
+ */
|
||||||
|
+ private static void runDelegatedTasks(SSLEngineResult result,
|
||||||
|
+ SSLEngine engine) throws Exception {
|
||||||
|
+
|
||||||
|
+ if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
|
||||||
|
+ Runnable runnable;
|
||||||
|
+ while ((runnable = engine.getDelegatedTask()) != null) {
|
||||||
|
+ log("\trunning delegated task...");
|
||||||
|
+ runnable.run();
|
||||||
|
+ }
|
||||||
|
+ HandshakeStatus hsStatus = engine.getHandshakeStatus();
|
||||||
|
+ if (hsStatus == HandshakeStatus.NEED_TASK) {
|
||||||
|
+ throw new Exception(
|
||||||
|
+ "handshake shouldn't need additional tasks");
|
||||||
|
+ }
|
||||||
|
+ log("\tnew HandshakeStatus: " + hsStatus);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private static boolean isEngineClosed(SSLEngine engine) {
|
||||||
|
+ return (engine.isOutboundDone() && engine.isInboundDone());
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Logging code
|
||||||
|
+ */
|
||||||
|
+ private static boolean resultOnce = true;
|
||||||
|
+
|
||||||
|
+ private static void log(String str, SSLEngineResult result) {
|
||||||
|
+ if (!logging) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ if (resultOnce) {
|
||||||
|
+ resultOnce = false;
|
||||||
|
+ log("The format of the SSLEngineResult is: \n"
|
||||||
|
+ + "\t\"getStatus() / getHandshakeStatus()\" +\n"
|
||||||
|
+ + "\t\"bytesConsumed() / bytesProduced()\"\n");
|
||||||
|
+ }
|
||||||
|
+ HandshakeStatus hsStatus = result.getHandshakeStatus();
|
||||||
|
+ log(str
|
||||||
|
+ + result.getStatus() + "/" + hsStatus + ", "
|
||||||
|
+ + result.bytesConsumed() + "/" + result.bytesProduced()
|
||||||
|
+ + " bytes");
|
||||||
|
+ if (hsStatus == HandshakeStatus.FINISHED) {
|
||||||
|
+ log("\t...ready for application data");
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private static void log(String str) {
|
||||||
|
+ if (logging) {
|
||||||
|
+ if (debug) {
|
||||||
|
+ System.err.println(str);
|
||||||
|
+ } else {
|
||||||
|
+ System.out.println(str);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.12.3
|
||||||
|
|
||||||
135
Add-CaptchaTest-and-fix-KAE-Testcases.patch
Normal file
135
Add-CaptchaTest-and-fix-KAE-Testcases.patch
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
diff --git a/jdk/test/java/awt/FontClass/CaptchaTest.java b/jdk/test/java/awt/FontClass/CaptchaTest.java
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..7f2ed1275
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/jdk/test/java/awt/FontClass/CaptchaTest.java
|
||||||
|
@@ -0,0 +1,53 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright © 2023 Xiaotao NAN. All rights reserved.
|
||||||
|
+ */
|
||||||
|
+import java.awt.Graphics2D;
|
||||||
|
+import java.awt.Color;
|
||||||
|
+import java.awt.Font;
|
||||||
|
+import java.awt.image.BufferedImage;
|
||||||
|
+import java.io.IOException;
|
||||||
|
+import java.util.Random;
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * @test
|
||||||
|
+ * @summary Check if the captcha can be successfully generated
|
||||||
|
+ * @author XiaotaoNAN
|
||||||
|
+ * I8ME2N(https://gitee.com/openeuler/bishengjdk-8/issues/I8ME2N?from=project-issue)
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+public class CaptchaTest {
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Check if the captcha can be successfully generated.
|
||||||
|
+ * @param n the number of digits int the captcha.
|
||||||
|
+ * @param fontName the font name.
|
||||||
|
+ * @throws IOException
|
||||||
|
+ */
|
||||||
|
+ public static String captchaTest(int n,String fontName) throws IOException {
|
||||||
|
+ int width = 100, height = 50;
|
||||||
|
+ BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||||
|
+ Graphics2D g = image.createGraphics();
|
||||||
|
+ g.setColor(Color.LIGHT_GRAY);
|
||||||
|
+ g.fillRect(0, 0, width, height);
|
||||||
|
+ String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||||
|
+ Random random = new Random();
|
||||||
|
+ StringBuilder sbuffer = new StringBuilder();
|
||||||
|
+ for (int i = 0; i < n; i++) {
|
||||||
|
+ int index = random.nextInt(chars.length());
|
||||||
|
+ char c = chars.charAt(index);
|
||||||
|
+ sbuffer.append(c);
|
||||||
|
+ g.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
|
||||||
|
+ g.setFont(new Font(fontName, Font.BOLD, 25));
|
||||||
|
+ g.drawString(Character.toString(c), 20 + i * 15, 25);
|
||||||
|
+ }
|
||||||
|
+ image.flush();
|
||||||
|
+ g.dispose();
|
||||||
|
+ return sbuffer.toString();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static void main(String[] args) throws IOException {
|
||||||
|
+ String captcha = captchaTest(4,"Times New Roman");
|
||||||
|
+ System.out.println(captcha);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+}
|
||||||
|
diff --git a/jdk/test/java/security/Provider/SunJCEValidator.java b/jdk/test/java/security/Provider/SunJCEValidator.java
|
||||||
|
index 314abb380..e6b9f18ad 100644
|
||||||
|
--- a/jdk/test/java/security/Provider/SunJCEValidator.java
|
||||||
|
+++ b/jdk/test/java/security/Provider/SunJCEValidator.java
|
||||||
|
@@ -37,10 +37,10 @@
|
||||||
|
*- @TestCaseType:Function test
|
||||||
|
*- @RequirementID:AR.SR.IREQ02758058.001.001
|
||||||
|
*- @RequirementName: java.security.Provider.getService() is synchronized and became scalability bottleneck
|
||||||
|
- *- @Condition:JDK8u302及以后
|
||||||
|
- *- @Brief:测试相应provider更改底层架构以后所提供的service是否与原先有差异(以openJDK8u302为准)
|
||||||
|
- * -#step:比较openJDK8u302 SunJceProvider与此特性修改后的SunJceProvider所提供的service是否一致
|
||||||
|
- *- @Expect:正常运行
|
||||||
|
+ *- @Condition:JDK8u302 and later
|
||||||
|
+ *- @Brief:Check whether the service provided by the corresponding provider after changing the underlying architecture is different from the original one (subject to openJDK8u302)
|
||||||
|
+ * -#step:Compare whether the service provided by openJDK8u302 SunJceProvider is consistent with the modified SunJceProvider with this feature
|
||||||
|
+ *- @Expect:Normal Running
|
||||||
|
*- @Priority:Level 1
|
||||||
|
*/
|
||||||
|
|
||||||
|
diff --git a/jdk/test/java/security/Provider/SunJSSEValidator.java b/jdk/test/java/security/Provider/SunJSSEValidator.java
|
||||||
|
index 5817c3b7f..0cf0663a4 100644
|
||||||
|
--- a/jdk/test/java/security/Provider/SunJSSEValidator.java
|
||||||
|
+++ b/jdk/test/java/security/Provider/SunJSSEValidator.java
|
||||||
|
@@ -37,10 +37,10 @@
|
||||||
|
*- @TestCaseType:Function test
|
||||||
|
*- @RequirementID:AR.SR.IREQ02758058.001.001
|
||||||
|
*- @RequirementName: java.security.Provider.getService() is synchronized and became scalability bottleneck
|
||||||
|
- *- @Condition:JDK8u302及以后
|
||||||
|
- *- @Brief:测试相应provider更改底层架构以后所提供的service是否与原先有差异(以openJDK8u302为准)
|
||||||
|
- * -#step:比较openJDK8u302 SunJSSEProvider与此特性修改后的SunJSSEProvider所提供的service是否一致
|
||||||
|
- *- @Expect:正常运行
|
||||||
|
+ *- @Condition:JDK8u302 and later
|
||||||
|
+ *- @Brief:Check whether the service provided by the corresponding provider after changing the underlying architecture is different from the original one (subject to openJDK8u302)
|
||||||
|
+ * -#step:Compare whether the service provided by openJDK8u302 SunJSSEProvider is consistent with the modified SunJSSEProvider with this feature
|
||||||
|
+ *- @Expect:Normal Running
|
||||||
|
*- @Priority:Level 1
|
||||||
|
*/
|
||||||
|
|
||||||
|
diff --git a/jdk/test/java/security/Provider/SunRsaSignValidator.java b/jdk/test/java/security/Provider/SunRsaSignValidator.java
|
||||||
|
index 66fb33a44..ddcf6107b 100644
|
||||||
|
--- a/jdk/test/java/security/Provider/SunRsaSignValidator.java
|
||||||
|
+++ b/jdk/test/java/security/Provider/SunRsaSignValidator.java
|
||||||
|
@@ -37,10 +37,10 @@
|
||||||
|
*- @TestCaseType:Function test
|
||||||
|
*- @RequirementID:AR.SR.IREQ02758058.001.001
|
||||||
|
*- @RequirementName: java.security.Provider.getService() is synchronized and became scalability bottleneck
|
||||||
|
- *- @Condition:JDK8u302及以后
|
||||||
|
- *- @Brief:测试相应provider更改底层架构以后所提供的service是否与原先有差异(以openJDK8u302为准)
|
||||||
|
- * -#step:比较openJDK8u302 SunRsaSignProvider与此特性修改后的SunRsaSignProvider所提供的service是否一致
|
||||||
|
- *- @Expect:正常运行
|
||||||
|
+ *- @Condition:JDK8u302 and later
|
||||||
|
+ *- @Brief:Check whether the service provided by the corresponding provider after changing the underlying architecture is different from the original one (subject to openJDK8u302).
|
||||||
|
+ * -#step:Compare whether the service provided by openJDK8u302 SunRsaSignProvider is consistent with the modified SunRsaSignProvider with this feature.
|
||||||
|
+ *- @Expect:Normal Running.
|
||||||
|
*- @Priority:Level 1
|
||||||
|
*/
|
||||||
|
|
||||||
|
diff --git a/jdk/test/java/security/Provider/SunValidator.java b/jdk/test/java/security/Provider/SunValidator.java
|
||||||
|
index 3f4b81222..b1fc38303 100644
|
||||||
|
--- a/jdk/test/java/security/Provider/SunValidator.java
|
||||||
|
+++ b/jdk/test/java/security/Provider/SunValidator.java
|
||||||
|
@@ -37,10 +37,10 @@
|
||||||
|
*- @TestCaseType:Function test
|
||||||
|
*- @RequirementID:AR.SR.IREQ02758058.001.001
|
||||||
|
*- @RequirementName: java.security.Provider.getService() is synchronized and became scalability bottleneck
|
||||||
|
- *- @Condition:JDK8u302及以后
|
||||||
|
- *- @Brief:测试相应provider更改底层架构以后所提供的service是否与原先有差异(以openJDK8u302为准)
|
||||||
|
- * -#step:比较openJDK8u302 SunProvider与此特性修改后的SunProvider所提供的service是否一致
|
||||||
|
- *- @Expect:正常运行
|
||||||
|
+ *- @Condition:JDK8u302 and later
|
||||||
|
+ *- @Brief:Check whether the service provided by the corresponding provider after changing the underlying architecture is different from the original one (subject to openJDK8u302).
|
||||||
|
+ * -#step:Compare whether the service provided by openJDK8u302 SunProvider is consistent with the modified SunProvider with this feature.
|
||||||
|
+ *- @Expect:Normal Running.
|
||||||
|
*- @Priority:Level 1
|
||||||
|
*/
|
||||||
|
|
||||||
38
Add-compiling-option-GS-when-building-windows-JDK.patch
Normal file
38
Add-compiling-option-GS-when-building-windows-JDK.patch
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
From 73ef8a1178d64c213de7f02c007fa35db391dac3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: zhangyipeng <zhangyipeng7@huawei.com>
|
||||||
|
Date: Sun, 12 Nov 2023 13:04:57 +0000
|
||||||
|
Subject: [PATCH] [Huawei]Add compiling option /GS when building windows JDK
|
||||||
|
---
|
||||||
|
common/autoconf/flags.m4 | 2 +-
|
||||||
|
common/autoconf/generated-configure.sh | 2 +-
|
||||||
|
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/common/autoconf/flags.m4 b/common/autoconf/flags.m4
|
||||||
|
index 71703a155..6474a0a47 100644
|
||||||
|
--- a/common/autoconf/flags.m4
|
||||||
|
+++ b/common/autoconf/flags.m4
|
||||||
|
@@ -566,7 +566,7 @@ AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK],
|
||||||
|
CXXFLAGS_JDK="$CXXFLAGS_JDK -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -DSTDC"
|
||||||
|
elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
|
||||||
|
CCXXFLAGS_JDK="$CCXXFLAGS $CCXXFLAGS_JDK \
|
||||||
|
- -Zi -MD -Zc:wchar_t- -W3 -wd4800 \
|
||||||
|
+ -GS -Zi -MD -Zc:wchar_t- -W3 -wd4800 \
|
||||||
|
-DWIN32_LEAN_AND_MEAN \
|
||||||
|
-D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE \
|
||||||
|
-DWIN32 -DIAL"
|
||||||
|
diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh
|
||||||
|
index 8fa28b61f..b296f81c2 100644
|
||||||
|
--- a/common/autoconf/generated-configure.sh
|
||||||
|
+++ b/common/autoconf/generated-configure.sh
|
||||||
|
@@ -43598,7 +43598,7 @@ $as_echo "$supports" >&6; }
|
||||||
|
CXXFLAGS_JDK="$CXXFLAGS_JDK -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -DSTDC"
|
||||||
|
elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
|
||||||
|
CCXXFLAGS_JDK="$CCXXFLAGS $CCXXFLAGS_JDK \
|
||||||
|
- -Zi -MD -Zc:wchar_t- -W3 -wd4800 \
|
||||||
|
+ -GS -Zi -MD -Zc:wchar_t- -W3 -wd4800 \
|
||||||
|
-DWIN32_LEAN_AND_MEAN \
|
||||||
|
-D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE \
|
||||||
|
-DWIN32 -DIAL"
|
||||||
|
--
|
||||||
|
2.12.3
|
||||||
|
|
||||||
30
Fix-for-JDK-8137099-for-G1-is-to-not-return-null-unt.patch
Normal file
30
Fix-for-JDK-8137099-for-G1-is-to-not-return-null-unt.patch
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
From ee7c3b3d5baee0a4d2de273c753e0b6b4a8b9b42 Mon Sep 17 00:00:00 2001
|
||||||
|
From: zhangyipeng <zhangyipeng7@huawei.com>
|
||||||
|
Date: Fri, 12 Jan 2024 10:53:02 +0800
|
||||||
|
Subject: [PATCH] [Huawei]Fix for JDK-8137099 for G1 is to not return null until full
|
||||||
|
GC has happened
|
||||||
|
---
|
||||||
|
hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp | 7 ++++---
|
||||||
|
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
|
||||||
|
index 1ce641cae..84d5d4d8b 100644
|
||||||
|
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
|
||||||
|
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
|
||||||
|
@@ -876,9 +876,10 @@ G1CollectedHeap::mem_allocate(size_t word_size,
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
- if (gclocker_retry_count > GCLockerRetryAllocationCount) {
|
||||||
|
- return NULL;
|
||||||
|
- }
|
||||||
|
+ // Fix for JDK-8137099 for G1 is to not return null until full GC has happened
|
||||||
|
+ // if (gclocker_retry_count > GCLockerRetryAllocationCount) {
|
||||||
|
+ // return NULL;
|
||||||
|
+ // }
|
||||||
|
assert(op.result() == NULL,
|
||||||
|
"the result should be NULL if the VM op did not succeed");
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.12.3
|
||||||
|
|
||||||
@ -64,15 +64,15 @@ diff --git a/jdk/src/share/classes/sun/security/util/DisabledAlgorithmConstraint
|
|||||||
index 51e62563..6ff26bf2 100644
|
index 51e62563..6ff26bf2 100644
|
||||||
--- a/jdk/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java
|
--- a/jdk/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java
|
||||||
+++ b/jdk/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java
|
+++ b/jdk/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java
|
||||||
@@ -96,7 +96,7 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
|
@@ -99,7 +99,7 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
|
||||||
new DisabledAlgorithmConstraints(PROPERTY_JAR_DISABLED_ALGS);
|
new DisabledAlgorithmConstraints(PROPERTY_JAR_DISABLED_ALGS);
|
||||||
}
|
}
|
||||||
|
|
||||||
- private final List<String> disabledAlgorithms;
|
- private final List<String> disabledAlgorithms;
|
||||||
+ private final Set<String> disabledAlgorithms;
|
+ private final Set<String> disabledAlgorithms;
|
||||||
private final Constraints algorithmConstraints;
|
private final Constraints algorithmConstraints;
|
||||||
|
private volatile SoftReference<Map<String, Boolean>> cacheRef =
|
||||||
public static DisabledAlgorithmConstraints certPathConstraints() {
|
new SoftReference<>(null);
|
||||||
@@ -128,11 +128,11 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
|
@@ -128,11 +128,11 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
|
||||||
public DisabledAlgorithmConstraints(String propertyName,
|
public DisabledAlgorithmConstraints(String propertyName,
|
||||||
AlgorithmDecomposer decomposer) {
|
AlgorithmDecomposer decomposer) {
|
||||||
|
|||||||
@ -91,7 +91,7 @@ index 00000000..9b614024
|
|||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/version.txt
|
+++ b/version.txt
|
||||||
@@ -0,0 +1 @@
|
@@ -0,0 +1 @@
|
||||||
+8.392.8.0.13
|
+8.402.8.0.13
|
||||||
--
|
--
|
||||||
2.23.0
|
2.23.0
|
||||||
|
|
||||||
|
|||||||
@ -40,13 +40,13 @@ index 54e1bfa0d..c1423dc5b 100644
|
|||||||
|
|
||||||
// The numbers of certs now.
|
// The numbers of certs now.
|
||||||
- private static final int COUNT = 83;
|
- private static final int COUNT = 83;
|
||||||
+ private static final int COUNT = 91;
|
+ private static final int COUNT = 100;
|
||||||
|
|
||||||
// SHA-256 of cacerts, can be generated with
|
// SHA-256 of cacerts, can be generated with
|
||||||
// shasum -a 256 cacerts | sed -e 's/../&:/g' | tr '[:lower:]' '[:upper:]' | cut -c1-95
|
// shasum -a 256 cacerts | sed -e 's/../&:/g' | tr '[:lower:]' '[:upper:]' | cut -c1-95
|
||||||
private static final String CHECKSUM
|
private static final String CHECKSUM
|
||||||
- = "2D:04:88:6C:52:53:54:EB:38:2D:BC:E0:AF:B7:82:F4:9E:32:A8:1A:1B:A3:AE:CF:25:CB:C2:F6:0F:4E:E1:20";
|
- = "2D:04:88:6C:52:53:54:EB:38:2D:BC:E0:AF:B7:82:F4:9E:32:A8:1A:1B:A3:AE:CF:25:CB:C2:F6:0F:4E:E1:20";
|
||||||
+ = "C2:9A:86:5C:47:0F:15:58:FB:D8:31:B5:29:BB:BE:A1:09:6F:9B:60:10:AF:8E:77:4A:AE:B7:66:BB:B1:58:34";
|
+ = "30:6A:9A:00:BF:95:59:BC:FB:4C:ED:89:F6:DB:50:25:8D:F6:D6:F0:BC:C8:FC:A3:E6:AF:62:7A:FD:F6:89:51";
|
||||||
// map of cert alias to SHA-256 fingerprint
|
// map of cert alias to SHA-256 fingerprint
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
private static final Map<String, String> FINGERPRINT_MAP
|
private static final Map<String, String> FINGERPRINT_MAP
|
||||||
|
|||||||
@ -3549,10 +3549,10 @@ index 000000000..c5322849e
|
|||||||
+ }
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+}
|
+}
|
||||||
diff --git a/jdk/test/lib/sun/hotspot/WhiteBox.java b/jdk/test/lib/sun/hotspot/WhiteBox.java
|
diff --git a/test/lib/sun/hotspot/WhiteBox.java b/test/lib/sun/hotspot/WhiteBox.java
|
||||||
index 9497c9530..a6d773bc8 100644
|
index 9497c9530..a6d773bc8 100644
|
||||||
--- a/jdk/test/lib/sun/hotspot/WhiteBox.java
|
--- a/test/lib/sun/hotspot/WhiteBox.java
|
||||||
+++ b/jdk/test/lib/sun/hotspot/WhiteBox.java
|
+++ b/test/lib/sun/hotspot/WhiteBox.java
|
||||||
@@ -141,6 +141,8 @@ public class WhiteBox {
|
@@ -141,6 +141,8 @@ public class WhiteBox {
|
||||||
public native int g1RegionSize();
|
public native int g1RegionSize();
|
||||||
public native MemoryUsage g1AuxiliaryMemoryUsage();
|
public native MemoryUsage g1AuxiliaryMemoryUsage();
|
||||||
|
|||||||
Binary file not shown.
@ -155,13 +155,13 @@
|
|||||||
%global origin_nice OpenJDK
|
%global origin_nice OpenJDK
|
||||||
%global top_level_dir_name %{origin}
|
%global top_level_dir_name %{origin}
|
||||||
%global repo jdk8u
|
%global repo jdk8u
|
||||||
%global revision jdk8u392-b08
|
%global revision jdk8u402-b06
|
||||||
%global full_revision %{repo}-%{revision}
|
%global full_revision %{repo}-%{revision}
|
||||||
# Define IcedTea version used for SystemTap tapsets and desktop files
|
# Define IcedTea version used for SystemTap tapsets and desktop files
|
||||||
%global icedteaver 3.15.0
|
%global icedteaver 3.15.0
|
||||||
|
|
||||||
%global updatever 392
|
%global updatever 402
|
||||||
%global buildver b08
|
%global buildver b06
|
||||||
# priority must be 7 digits in total. The expression is workarounding tip
|
# priority must be 7 digits in total. The expression is workarounding tip
|
||||||
%global priority 1800%{updatever}
|
%global priority 1800%{updatever}
|
||||||
|
|
||||||
@ -925,7 +925,7 @@ Provides: java-%{javaver}-%{origin}-accessibility%{?1} = %{epoch}:%{version}-%{r
|
|||||||
|
|
||||||
Name: java-%{javaver}-%{origin}
|
Name: java-%{javaver}-%{origin}
|
||||||
Version: %{javaver}.%{updatever}.%{buildver}
|
Version: %{javaver}.%{updatever}.%{buildver}
|
||||||
Release: 4
|
Release: 0
|
||||||
# java-1.5.0-ibm from jpackage.org set Epoch to 1 for unknown reasons
|
# 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
|
# 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
|
# also included the epoch in their virtual provides. This created a
|
||||||
@ -1289,6 +1289,14 @@ Patch407: 8278794-Infinite-loop-in-DeflaterOutputStream.finish.patch
|
|||||||
Patch408: 8312065-Socket.connect-does-not-timeout-when-profili.patch
|
Patch408: 8312065-Socket.connect-does-not-timeout-when-profili.patch
|
||||||
Patch409: Add-Problemlist.patch
|
Patch409: Add-Problemlist.patch
|
||||||
Patch410: Fix-an-error-caused-by-anonymous-when-AppCDS-generat.patch
|
Patch410: Fix-an-error-caused-by-anonymous-when-AppCDS-generat.patch
|
||||||
|
Patch411: Add-CaptchaTest-and-fix-KAE-Testcases.patch
|
||||||
|
Patch412: 8177146-MethodHandles.Lookup-bind-allows-illegal-pro.patch
|
||||||
|
Patch413: Add-compiling-option-GS-when-building-windows-JDK.patch
|
||||||
|
Patch414: Fix-for-JDK-8137099-for-G1-is-to-not-return-null-unt.patch
|
||||||
|
Patch415: 8273553-sun.security.ssl.SSLEngineImpl.closeInbound-.patch
|
||||||
|
Patch416: 8260923-Add-more-tests-for-SSLSocket-input-output-sh.patch
|
||||||
|
Patch417: 8057967-CallSite-dependency-tracking-scales-devastat.patch
|
||||||
|
Patch418: 8079205-CallSite-dependency-tracking-is-broken-after.patch
|
||||||
|
|
||||||
#############################################
|
#############################################
|
||||||
#
|
#
|
||||||
@ -1904,6 +1912,14 @@ pushd %{top_level_dir_name}
|
|||||||
%patch408 -p1
|
%patch408 -p1
|
||||||
%patch409 -p1
|
%patch409 -p1
|
||||||
%patch410 -p1
|
%patch410 -p1
|
||||||
|
%patch411 -p1
|
||||||
|
%patch412 -p1
|
||||||
|
%patch413 -p1
|
||||||
|
%patch414 -p1
|
||||||
|
%patch415 -p1
|
||||||
|
%patch416 -p1
|
||||||
|
%patch417 -p1
|
||||||
|
%patch418 -p1
|
||||||
|
|
||||||
%ifarch riscv64
|
%ifarch riscv64
|
||||||
%patch2000 -p1
|
%patch2000 -p1
|
||||||
@ -2555,6 +2571,23 @@ cjc.mainProgram(arg)
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Wed Jan 17 2024 Autistic_boyya <wangzhongyi7@huawei.com> - 1:1.8.0.402-b06.0
|
||||||
|
- modified 0019-8040213-C2-does-not-put-all-modified-nodes-on-IGVN-w.patch
|
||||||
|
- modified Improve_AlgorithmConstraints_checkAlgorithm_performance.patch
|
||||||
|
- modified add-missing-test-case.patch
|
||||||
|
- modified fix_X509TrustManagerImpl_symantec_distrust.patch
|
||||||
|
- modified g1gc-numa-aware-Implementation.patch
|
||||||
|
- modified update-cacerts-and-VerifyCACerts.java-test.patch
|
||||||
|
- modified 8203699.patch
|
||||||
|
- add Add-CaptchaTest-and-fix-KAE-Testcases.patch
|
||||||
|
- add 8177146-MethodHandles.Lookup-bind-allows-illegal-pro.patch
|
||||||
|
- add Add-compiling-option-GS-when-building-windows-JDK.patch
|
||||||
|
- add Fix-for-JDK-8137099-for-G1-is-to-not-return-null-unt.patch
|
||||||
|
- add 8273553-sun.security.ssl.SSLEngineImpl.closeInbound-.patch
|
||||||
|
- add 8260923-Add-more-tests-for-SSLSocket-input-output-sh.patch
|
||||||
|
- add 8057967-CallSite-dependency-tracking-scales-devastat.patch
|
||||||
|
- add 8079205-CallSite-dependency-tracking-is-broken-after.patch
|
||||||
|
|
||||||
* Wed Dec 20 2023 kuenking111 <wangkun49@huawei.com> - 1:1.8.0.392-b08.4
|
* Wed Dec 20 2023 kuenking111 <wangkun49@huawei.com> - 1:1.8.0.392-b08.4
|
||||||
- Add Fix-an-error-caused-by-anonymous-when-AppCDS-generat.patch
|
- Add Fix-an-error-caused-by-anonymous-when-AppCDS-generat.patch
|
||||||
|
|
||||||
|
|||||||
@ -257,13 +257,13 @@ index dd107fc..791ddb6 100644
|
|||||||
+ File.separator + "security" + File.separator + "cacerts";
|
+ File.separator + "security" + File.separator + "cacerts";
|
||||||
|
|
||||||
// The numbers of certs now.
|
// The numbers of certs now.
|
||||||
- private static final int COUNT = 97;
|
- private static final int COUNT = 106;
|
||||||
+ private static final int COUNT = 83;
|
+ private static final int COUNT = 83;
|
||||||
|
|
||||||
// SHA-256 of cacerts, can be generated with
|
// SHA-256 of cacerts, can be generated with
|
||||||
// shasum -a 256 cacerts | sed -e 's/../&:/g' | tr '[:lower:]' '[:upper:]' | cut -c1-95
|
// shasum -a 256 cacerts | sed -e 's/../&:/g' | tr '[:lower:]' '[:upper:]' | cut -c1-95
|
||||||
private static final String CHECKSUM
|
private static final String CHECKSUM
|
||||||
- = "88:72:92:56:FF:E5:A3:E4:39:98:6D:18:0B:BA:CC:0B:66:CB:1D:6D:52:CE:D7:C8:AD:63:B7:F1:5F:02:24:52";
|
- = "61:5F:6D:C5:9C:A3:8A:65:3F:CB:F9:F5:26:04:23:F4:53:A6:8C:B3:8B:2B:0A:F0:66:7D:9E:67:B9:4D:AC:B7";
|
||||||
+ = "2D:04:88:6C:52:53:54:EB:38:2D:BC:E0:AF:B7:82:F4:9E:32:A8:1A:1B:A3:AE:CF:25:CB:C2:F6:0F:4E:E1:20";
|
+ = "2D:04:88:6C:52:53:54:EB:38:2D:BC:E0:AF:B7:82:F4:9E:32:A8:1A:1B:A3:AE:CF:25:CB:C2:F6:0F:4E:E1:20";
|
||||||
// map of cert alias to SHA-256 fingerprint
|
// map of cert alias to SHA-256 fingerprint
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
@ -290,10 +290,10 @@ index dd107fc..791ddb6 100644
|
|||||||
put("geotrustprimaryca [jdk]",
|
put("geotrustprimaryca [jdk]",
|
||||||
"37:D5:10:06:C5:12:EA:AB:62:64:21:F1:EC:8C:92:01:3F:C5:F8:2A:E9:8E:E5:33:EB:46:19:B8:DE:B4:D0:6C");
|
"37:D5:10:06:C5:12:EA:AB:62:64:21:F1:EC:8C:92:01:3F:C5:F8:2A:E9:8E:E5:33:EB:46:19:B8:DE:B4:D0:6C");
|
||||||
put("geotrustprimarycag2 [jdk]",
|
put("geotrustprimarycag2 [jdk]",
|
||||||
@@ -163,10 +147,6 @@ public class VerifyCACerts {
|
@@ -165,10 +149,6 @@ public class VerifyCACerts {
|
||||||
"5D:56:49:9B:E4:D2:E0:8B:CF:CA:D0:8A:3E:38:72:3D:50:50:3B:DE:70:69:48:E4:2F:55:60:30:19:E5:28:AE");
|
|
||||||
put("letsencryptisrgx1 [jdk]",
|
|
||||||
"96:BC:EC:06:26:49:76:F3:74:60:77:9A:CF:28:C5:A7:CF:E8:A3:C0:AA:E1:1A:8F:FC:EE:05:C0:BD:DF:08:C6");
|
"96:BC:EC:06:26:49:76:F3:74:60:77:9A:CF:28:C5:A7:CF:E8:A3:C0:AA:E1:1A:8F:FC:EE:05:C0:BD:DF:08:C6");
|
||||||
|
put("letsencryptisrgx2 [jdk]",
|
||||||
|
"69:72:9B:8E:15:A8:6E:FC:17:7A:57:AF:B7:17:1D:FC:64:AD:D2:8C:2F:CA:8C:F1:50:7E:34:45:3C:CB:14:70");
|
||||||
- put("luxtrustglobalrootca [jdk]",
|
- put("luxtrustglobalrootca [jdk]",
|
||||||
- "A1:B2:DB:EB:64:E7:06:C6:16:9E:3C:41:18:B2:3B:AA:09:01:8A:84:27:66:6D:8B:F0:E2:88:91:EC:05:19:50");
|
- "A1:B2:DB:EB:64:E7:06:C6:16:9E:3C:41:18:B2:3B:AA:09:01:8A:84:27:66:6D:8B:F0:E2:88:91:EC:05:19:50");
|
||||||
- put("quovadisrootca [jdk]",
|
- put("quovadisrootca [jdk]",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user