mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2026-01-03 15:11:41 +01:00
Compare commits
4 Commits
jb25-b47.2
...
jbr25.47
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
74f23d313d | ||
|
|
1bc7ebdbb5 | ||
|
|
ab91dd4ecd | ||
|
|
b85179f8b3 |
@@ -211,7 +211,7 @@ void LambdaFormInvokers::regenerate_class(char* class_name, ClassFileStream& st,
|
||||
class_name_sym,
|
||||
cld,
|
||||
cl_info,
|
||||
false, // pick_newest
|
||||
nullptr,
|
||||
CHECK);
|
||||
|
||||
assert(result->java_mirror() != nullptr, "must be");
|
||||
|
||||
@@ -5269,7 +5269,7 @@ ClassFileParser::ClassFileParser(ClassFileStream* stream,
|
||||
ClassLoaderData* loader_data,
|
||||
const ClassLoadInfo* cl_info,
|
||||
Publicity pub_level,
|
||||
const bool pick_newest,
|
||||
Old2NewKlassMap* old_2_new_klass_map,
|
||||
TRAPS) :
|
||||
_stream(stream),
|
||||
_class_name(nullptr),
|
||||
@@ -5329,7 +5329,7 @@ ClassFileParser::ClassFileParser(ClassFileStream* stream,
|
||||
_has_finalizer(false),
|
||||
_has_empty_finalizer(false),
|
||||
_max_bootstrap_specifier_index(-1),
|
||||
_pick_newest(pick_newest) {
|
||||
_old_2_new_klass_map(old_2_new_klass_map) {
|
||||
|
||||
_class_name = name != nullptr ? name : vmSymbols::unknown_class_name();
|
||||
_class_name->increment_refcount();
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "oops/instanceKlass.hpp"
|
||||
#include "oops/typeArrayOop.hpp"
|
||||
#include "utilities/accessFlags.hpp"
|
||||
#include "classFileParserDCEVM.hpp"
|
||||
|
||||
class Annotations;
|
||||
template <typename T>
|
||||
@@ -198,7 +199,7 @@ class ClassFileParser {
|
||||
int _max_bootstrap_specifier_index; // detects BSS values
|
||||
|
||||
// (DCEVM) Enhanced class redefinition
|
||||
const bool _pick_newest;
|
||||
const Old2NewKlassMap* _old_2_new_klass_map;
|
||||
|
||||
void parse_stream(const ClassFileStream* const stream, TRAPS);
|
||||
|
||||
@@ -488,7 +489,13 @@ class ClassFileParser {
|
||||
|
||||
void update_class_name(Symbol* new_name);
|
||||
// (DCEVM) Enhanced class redefinition
|
||||
inline const Klass* maybe_newest(const Klass* klass) const { return klass != NULL && _pick_newest ? klass->newest_version() : klass; }
|
||||
inline const Klass* maybe_newest(Klass* klass) const {
|
||||
if (klass != nullptr && _old_2_new_klass_map != nullptr) {
|
||||
Klass** new_klass = _old_2_new_klass_map->get(klass);
|
||||
return (new_klass != nullptr) ? *new_klass : klass;
|
||||
}
|
||||
return klass;
|
||||
}
|
||||
|
||||
public:
|
||||
ClassFileParser(ClassFileStream* stream,
|
||||
@@ -496,7 +503,7 @@ class ClassFileParser {
|
||||
ClassLoaderData* loader_data,
|
||||
const ClassLoadInfo* cl_info,
|
||||
Publicity pub_level,
|
||||
const bool pick_newest,
|
||||
Old2NewKlassMap* old_2_new_klass_map,
|
||||
TRAPS);
|
||||
|
||||
~ClassFileParser();
|
||||
|
||||
38
src/hotspot/share/classfile/classFileParserDCEVM.hpp
Normal file
38
src/hotspot/share/classfile/classFileParserDCEVM.hpp
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_CLASSFILE_CLASSFILEPARSER_DCEVM_HPP
|
||||
#define SHARE_CLASSFILE_CLASSFILEPARSER_DCEVM_HPP
|
||||
|
||||
#include "utilities/resourceHash.hpp"
|
||||
#include "memory/allocation.hpp"
|
||||
#include "oops/klass.hpp"
|
||||
|
||||
inline bool old2new_ptr_equals(Klass* const& a, Klass* const& b) { return a == b; }
|
||||
inline unsigned old2new_ptr_hash(Klass* const& p) { return (unsigned)((uintptr_t)p * 2654435761u); }
|
||||
|
||||
using Old2NewKlassMap =
|
||||
ResourceHashtable<Klass*, Klass*, 1031, AnyObj::C_HEAP, mtInternal, old2new_ptr_hash, old2new_ptr_equals>;
|
||||
|
||||
#endif //SHARE_CLASSFILE_CLASSFILEPARSER_DCEVM_HPP
|
||||
@@ -1112,7 +1112,7 @@ InstanceKlass* ClassLoader::load_class(Symbol* name, PackageEntry* pkg_entry, bo
|
||||
name,
|
||||
loader_data,
|
||||
cl_info,
|
||||
false, // pick_newest
|
||||
nullptr,
|
||||
CHECK_NULL);
|
||||
result->set_classpath_index(classpath_index);
|
||||
return result;
|
||||
|
||||
@@ -85,7 +85,7 @@ InstanceKlass* KlassFactory::check_shared_class_file_load_hook(
|
||||
loader_data,
|
||||
&cl_info,
|
||||
ClassFileParser::BROADCAST, // publicity level
|
||||
false,
|
||||
nullptr,
|
||||
CHECK_NULL);
|
||||
const ClassInstanceInfo* cl_inst_info = cl_info.class_hidden_info_ptr();
|
||||
InstanceKlass* new_ik = parser.create_instance_klass(true, // changed_by_loadhook
|
||||
@@ -172,7 +172,7 @@ InstanceKlass* KlassFactory::create_from_stream(ClassFileStream* stream,
|
||||
Symbol* name,
|
||||
ClassLoaderData* loader_data,
|
||||
const ClassLoadInfo& cl_info,
|
||||
const bool pick_newest,
|
||||
Old2NewKlassMap* old_2_new_klass_map,
|
||||
TRAPS) {
|
||||
assert(stream != nullptr, "invariant");
|
||||
assert(loader_data != nullptr, "invariant");
|
||||
@@ -202,7 +202,7 @@ InstanceKlass* KlassFactory::create_from_stream(ClassFileStream* stream,
|
||||
loader_data,
|
||||
&cl_info,
|
||||
ClassFileParser::BROADCAST, // publicity level
|
||||
pick_newest,
|
||||
old_2_new_klass_map,
|
||||
CHECK_NULL);
|
||||
|
||||
const ClassInstanceInfo* cl_inst_info = cl_info.class_hidden_info_ptr();
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "memory/allStatic.hpp"
|
||||
#include "runtime/handles.hpp"
|
||||
#include "classfile/classFileParserDCEVM.hpp"
|
||||
|
||||
class ClassFileStream;
|
||||
class ClassLoaderData;
|
||||
@@ -64,7 +65,7 @@ class KlassFactory : AllStatic {
|
||||
Symbol* name,
|
||||
ClassLoaderData* loader_data,
|
||||
const ClassLoadInfo& cl_info,
|
||||
const bool pick_newest,
|
||||
Old2NewKlassMap* old_2_new_klass_map,
|
||||
TRAPS);
|
||||
static InstanceKlass* check_shared_class_file_load_hook(
|
||||
InstanceKlass* ik,
|
||||
|
||||
@@ -787,6 +787,7 @@ InstanceKlass* SystemDictionary::resolve_hidden_class_from_stream(
|
||||
Handle class_loader,
|
||||
const ClassLoadInfo& cl_info,
|
||||
InstanceKlass* old_klass,
|
||||
Old2NewKlassMap* old_2_new_klass_map,
|
||||
TRAPS) {
|
||||
|
||||
EventClassLoad class_load_start_event;
|
||||
@@ -808,7 +809,7 @@ InstanceKlass* SystemDictionary::resolve_hidden_class_from_stream(
|
||||
class_name,
|
||||
loader_data,
|
||||
cl_info,
|
||||
is_redefining, // pick_newest
|
||||
old_2_new_klass_map, // pick_newest
|
||||
CHECK_NULL);
|
||||
assert(k != nullptr, "no klass created");
|
||||
if (is_redefining && k != nullptr) {
|
||||
@@ -851,6 +852,7 @@ InstanceKlass* SystemDictionary::resolve_class_from_stream(
|
||||
Handle class_loader,
|
||||
const ClassLoadInfo& cl_info,
|
||||
InstanceKlass* old_klass,
|
||||
Old2NewKlassMap* old_2_new_klass_map,
|
||||
TRAPS) {
|
||||
|
||||
HandleMark hm(THREAD);
|
||||
@@ -881,7 +883,7 @@ InstanceKlass* SystemDictionary::resolve_class_from_stream(
|
||||
#endif
|
||||
|
||||
if (k == nullptr) {
|
||||
k = KlassFactory::create_from_stream(st, class_name, loader_data, cl_info, is_redefining, CHECK_NULL);
|
||||
k = KlassFactory::create_from_stream(st, class_name, loader_data, cl_info, old_2_new_klass_map, CHECK_NULL);
|
||||
}
|
||||
|
||||
if (is_redefining && k != nullptr) {
|
||||
@@ -921,11 +923,12 @@ InstanceKlass* SystemDictionary::resolve_from_stream(ClassFileStream* st,
|
||||
Handle class_loader,
|
||||
const ClassLoadInfo& cl_info,
|
||||
InstanceKlass* old_klass,
|
||||
Old2NewKlassMap* old_2_new_klass_map,
|
||||
TRAPS) {
|
||||
if (cl_info.is_hidden()) {
|
||||
return resolve_hidden_class_from_stream(st, class_name, class_loader, cl_info, old_klass, CHECK_NULL);
|
||||
return resolve_hidden_class_from_stream(st, class_name, class_loader, cl_info, old_klass, old_2_new_klass_map, CHECK_NULL);
|
||||
} else {
|
||||
return resolve_class_from_stream(st, class_name, class_loader, cl_info, old_klass, CHECK_NULL);
|
||||
return resolve_class_from_stream(st, class_name, class_loader, cl_info, old_klass, old_2_new_klass_map, CHECK_NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2340,7 +2343,7 @@ Handle SystemDictionary::link_method_handle_constant(Klass* caller,
|
||||
|
||||
// call java.lang.invoke.MethodHandleNatives::linkMethodHandleConstant(Class caller, int refKind, Class callee, String name, Object type) -> MethodHandle
|
||||
JavaCallArguments args;
|
||||
args.push_oop(Handle(THREAD, caller->newest_version()->java_mirror())); // the referring class
|
||||
args.push_oop(Handle(THREAD, caller->active_version()->java_mirror())); // the referring class
|
||||
args.push_int(ref_kind);
|
||||
args.push_oop(Handle(THREAD, callee->java_mirror())); // the target class
|
||||
args.push_oop(name_str);
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "runtime/handles.hpp"
|
||||
#include "runtime/signature.hpp"
|
||||
#include "utilities/vmEnums.hpp"
|
||||
#include "classfile/classFileParserDCEVM.hpp"
|
||||
|
||||
// The dictionary in each ClassLoaderData stores all loaded classes, either
|
||||
// initiatied by its class loader or defined by its class loader:
|
||||
@@ -126,6 +127,7 @@ class SystemDictionary : AllStatic {
|
||||
Handle class_loader,
|
||||
const ClassLoadInfo& cl_info,
|
||||
InstanceKlass* old_klass,
|
||||
Old2NewKlassMap* old_2_new_klass_map,
|
||||
TRAPS);
|
||||
|
||||
// Resolve a class from stream (called by jni_DefineClass and JVM_DefineClass)
|
||||
@@ -135,6 +137,7 @@ class SystemDictionary : AllStatic {
|
||||
Handle class_loader,
|
||||
const ClassLoadInfo& cl_info,
|
||||
InstanceKlass* old_klass,
|
||||
Old2NewKlassMap* old_2_new_klass_map,
|
||||
TRAPS);
|
||||
|
||||
static oop get_system_class_loader_impl(TRAPS);
|
||||
@@ -147,6 +150,7 @@ class SystemDictionary : AllStatic {
|
||||
Handle class_loader,
|
||||
const ClassLoadInfo& cl_info,
|
||||
InstanceKlass* old_klass,
|
||||
Old2NewKlassMap* old_2_new_klass_map,
|
||||
TRAPS);
|
||||
|
||||
// Lookup an already loaded class. If not found null is returned.
|
||||
|
||||
@@ -322,8 +322,8 @@ void LinkResolver::check_klass_accessibility(Klass* ref_klass, Klass* sel_klass,
|
||||
Klass* refKlassNewest = ref_klass;
|
||||
Klass* baseKlassNewest = base_klass;
|
||||
if (AllowEnhancedClassRedefinition) {
|
||||
refKlassNewest = ref_klass->newest_version();
|
||||
baseKlassNewest = base_klass->newest_version();
|
||||
refKlassNewest = ref_klass->active_version();
|
||||
baseKlassNewest = base_klass->active_version();
|
||||
}
|
||||
Reflection::VerifyClassAccessResults vca_result =
|
||||
Reflection::verify_class_access(refKlassNewest, InstanceKlass::cast(baseKlassNewest), true);
|
||||
@@ -589,7 +589,7 @@ void LinkResolver::check_method_accessability(Klass* ref_klass,
|
||||
// to be false (so we'll short-circuit out of these tests).
|
||||
if (sel_method->name() == vmSymbols::clone_name() &&
|
||||
( (!AllowEnhancedClassRedefinition && sel_klass == vmClasses::Object_klass()) ||
|
||||
(AllowEnhancedClassRedefinition && sel_klass->newest_version() == vmClasses::Object_klass()->newest_version()) ) &&
|
||||
(AllowEnhancedClassRedefinition && sel_klass->active_version() == vmClasses::Object_klass()->active_version()) ) &&
|
||||
resolved_klass->is_array_klass()) {
|
||||
// We need to change "protected" to "public".
|
||||
assert(flags.is_protected(), "clone not protected?");
|
||||
@@ -765,7 +765,7 @@ Method* LinkResolver::resolve_method(const LinkInfo& link_info,
|
||||
Bytecodes::Code code, TRAPS) {
|
||||
|
||||
Handle nested_exception;
|
||||
Klass* resolved_klass = link_info.resolved_klass();
|
||||
Klass* resolved_klass = link_info.resolved_klass()->active_version();
|
||||
|
||||
// 1. For invokevirtual, cannot call an interface method
|
||||
if (code == Bytecodes::_invokevirtual && resolved_klass->is_interface()) {
|
||||
|
||||
@@ -1698,7 +1698,7 @@ static InstanceKlass* create_new_instance_klass(InstanceKlass* ik, ClassFileStre
|
||||
cld,
|
||||
&cl_info,
|
||||
ClassFileParser::INTERNAL, // internal visibility
|
||||
false,
|
||||
nullptr,
|
||||
THREAD);
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
log_pending_exception(PENDING_EXCEPTION);
|
||||
|
||||
@@ -1564,12 +1564,26 @@ bool InstanceKlass::implements_interface(Klass* k) const {
|
||||
|
||||
|
||||
// (DCEVM)
|
||||
bool InstanceKlass::implements_interface_any_version(Klass* k) const {
|
||||
k = k->newest_version();
|
||||
if (this->newest_version() == k) return true;
|
||||
bool InstanceKlass::implements_interface_dcevm(Klass* k, Old2NewKlassMap* old_2_new_klass_map) const {
|
||||
Klass** new_klass = old_2_new_klass_map->get(k);
|
||||
if (new_klass != nullptr) {
|
||||
k = *new_klass;
|
||||
}
|
||||
Klass* this_klass = (Klass*) this;
|
||||
Klass** new_this = old_2_new_klass_map->get(this_klass);
|
||||
if (new_this != nullptr) {
|
||||
this_klass = *new_this;
|
||||
}
|
||||
|
||||
if (this_klass == k) return true;
|
||||
assert(k->is_interface(), "should be an interface class");
|
||||
for (int i = 0; i < transitive_interfaces()->length(); i++) {
|
||||
if (transitive_interfaces()->at(i)->newest_version() == k) {
|
||||
Klass* ti = (Klass*) transitive_interfaces()->at(i);
|
||||
Klass** new_ti = old_2_new_klass_map->get(ti);
|
||||
if (new_ti != nullptr) {
|
||||
ti = *new_ti;
|
||||
}
|
||||
if (ti == k) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -4609,15 +4623,19 @@ Method* InstanceKlass::method_with_idnum(int idnum) {
|
||||
|
||||
Method* InstanceKlass::method_with_orig_idnum(int idnum) {
|
||||
if (idnum >= methods()->length()) {
|
||||
return nullptr;
|
||||
}
|
||||
Method* m = methods()->at(idnum);
|
||||
if (m != nullptr && m->orig_method_idnum() == idnum) {
|
||||
return m;
|
||||
// (DCEVM) The provided idnum may exceed the current number of methods.
|
||||
if (!AllowEnhancedClassRedefinition) {
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
Method* m = methods()->at(idnum);
|
||||
if (m != nullptr && m->orig_method_idnum() == idnum) {
|
||||
return m;
|
||||
}
|
||||
}
|
||||
// Obsolete method idnum does not match the original idnum
|
||||
for (int index = 0; index < methods()->length(); ++index) {
|
||||
m = methods()->at(index);
|
||||
Method* m = methods()->at(index);
|
||||
if (m->orig_method_idnum() == idnum) {
|
||||
return m;
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "utilities/align.hpp"
|
||||
#include "utilities/growableArray.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#include "classfile/classFileParserDCEVM.hpp"
|
||||
#if INCLUDE_JFR
|
||||
#include "jfr/support/jfrKlassExtension.hpp"
|
||||
#endif
|
||||
@@ -877,9 +878,11 @@ public:
|
||||
|
||||
// subclass/subinterface checks
|
||||
bool implements_interface(Klass* k) const;
|
||||
bool implements_interface_any_version(Klass* k) const;
|
||||
bool is_same_or_direct_interface(Klass* k) const;
|
||||
|
||||
// (DCEVM)
|
||||
bool implements_interface_dcevm(Klass* k, Old2NewKlassMap* old_2_new_klass_map) const;
|
||||
|
||||
#ifdef ASSERT
|
||||
// check whether this class or one of its superclasses was redefined
|
||||
bool has_redefined_this_or_super() const;
|
||||
|
||||
@@ -870,7 +870,7 @@ public:
|
||||
void release_C_heap_structures();
|
||||
|
||||
Method* get_new_method() const {
|
||||
InstanceKlass* holder = InstanceKlass::cast(method_holder()->newest_version());
|
||||
InstanceKlass* holder = InstanceKlass::cast(method_holder()->active_version());
|
||||
Method* new_method = holder->method_with_idnum(orig_method_idnum());
|
||||
|
||||
assert(new_method != nullptr, "method_with_idnum() should not be null");
|
||||
|
||||
@@ -303,10 +303,12 @@ JNI_ENTRY(jclass, jni_DefineClass(JNIEnv *env, const char *name, jobject loaderR
|
||||
Handle class_loader (THREAD, JNIHandles::resolve(loaderRef));
|
||||
Handle protection_domain;
|
||||
ClassLoadInfo cl_info(protection_domain);
|
||||
Klass* k = SystemDictionary::resolve_from_stream(&st, class_name,
|
||||
Klass* k = SystemDictionary::resolve_from_stream(&st,
|
||||
class_name,
|
||||
class_loader,
|
||||
cl_info,
|
||||
nullptr,
|
||||
nullptr,
|
||||
CHECK_NULL);
|
||||
|
||||
if (log_is_enabled(Debug, class, resolve)) {
|
||||
|
||||
@@ -887,6 +887,7 @@ static jclass jvm_define_class_common(const char *name,
|
||||
class_loader,
|
||||
cl_info,
|
||||
nullptr,
|
||||
nullptr,
|
||||
CHECK_NULL);
|
||||
|
||||
if (log_is_enabled(Debug, class, resolve)) {
|
||||
@@ -975,6 +976,7 @@ static jclass jvm_lookup_define_class(jclass lookup, const char *name,
|
||||
class_loader,
|
||||
cl_info,
|
||||
nullptr,
|
||||
nullptr,
|
||||
CHECK_NULL);
|
||||
|
||||
if (log_is_enabled(Debug, class, resolve)) {
|
||||
@@ -992,6 +994,7 @@ static jclass jvm_lookup_define_class(jclass lookup, const char *name,
|
||||
class_loader,
|
||||
cl_info,
|
||||
nullptr,
|
||||
nullptr,
|
||||
CHECK_NULL);
|
||||
|
||||
// The hidden class loader data has been artificially been kept alive to
|
||||
|
||||
@@ -562,6 +562,12 @@ void VM_EnhancedRedefineClasses::doit() {
|
||||
// before the stack walk again.
|
||||
|
||||
for (int i = 0; i < _new_classes->length(); i++) {
|
||||
Klass *new_class = _new_classes->at(i);
|
||||
new_class->old_version()->set_new_version(new_class);
|
||||
}
|
||||
|
||||
for (int i = 0; i < _new_classes->length(); i++) {
|
||||
Klass* new_class = _new_classes->at(i);
|
||||
redefine_single_class(current, _new_classes->at(i));
|
||||
}
|
||||
|
||||
@@ -807,8 +813,8 @@ void VM_EnhancedRedefineClasses::doit_epilogue() {
|
||||
_new_classes = nullptr;
|
||||
if (_affected_klasses != nullptr) {
|
||||
delete _affected_klasses;
|
||||
_affected_klasses = nullptr;
|
||||
}
|
||||
_affected_klasses = nullptr;
|
||||
|
||||
// Reset the_class_oop to null for error printing.
|
||||
_the_class_oop = nullptr;
|
||||
@@ -859,11 +865,12 @@ jvmtiError VM_EnhancedRedefineClasses::load_new_class_versions(TRAPS) {
|
||||
|
||||
_affected_klasses = new (mtInternal) GrowableArray<Klass*>(_class_count, mtInternal);
|
||||
_new_classes = new (mtInternal) GrowableArray<InstanceKlass*>(_class_count, mtInternal);
|
||||
Old2NewKlassMap old_2_new_klass_map;
|
||||
|
||||
ResourceMark rm(THREAD);
|
||||
|
||||
// Retrieve an array of all classes that need to be redefined into _affected_klasses
|
||||
jvmtiError err = find_sorted_affected_classes(true, nullptr, THREAD);
|
||||
jvmtiError err = find_sorted_affected_classes(true, nullptr, &old_2_new_klass_map, THREAD);
|
||||
if (err != JVMTI_ERROR_NONE) {
|
||||
return err;
|
||||
}
|
||||
@@ -873,7 +880,7 @@ jvmtiError VM_EnhancedRedefineClasses::load_new_class_versions(TRAPS) {
|
||||
GrowableArray<Klass*>* prev_affected_klasses = new (mtInternal) GrowableArray<Klass*>(_class_count, mtInternal);
|
||||
|
||||
do {
|
||||
err = load_new_class_versions_single_step(THREAD);
|
||||
err = load_new_class_versions_single_step(&old_2_new_klass_map, THREAD);
|
||||
if (err != JVMTI_ERROR_NONE) {
|
||||
delete prev_affected_klasses;
|
||||
return err;
|
||||
@@ -886,7 +893,7 @@ jvmtiError VM_EnhancedRedefineClasses::load_new_class_versions(TRAPS) {
|
||||
_affected_klasses->clear();
|
||||
}
|
||||
|
||||
err = find_sorted_affected_classes(false, prev_affected_klasses, THREAD);
|
||||
err = find_sorted_affected_classes(false, prev_affected_klasses, &old_2_new_klass_map, THREAD);
|
||||
if (err != JVMTI_ERROR_NONE) {
|
||||
delete prev_affected_klasses;
|
||||
return err;
|
||||
@@ -900,8 +907,8 @@ jvmtiError VM_EnhancedRedefineClasses::load_new_class_versions(TRAPS) {
|
||||
for (int i = 0; i < _affected_klasses->length(); i++) {
|
||||
Klass* the_class = _affected_klasses->at(i);
|
||||
if (the_class != nullptr) {
|
||||
assert (the_class->new_version() != nullptr, "new version must be present");
|
||||
InstanceKlass *new_class(InstanceKlass::cast(the_class->new_version()));
|
||||
assert (old_2_new_klass_map.contains(the_class), "new version must be present");
|
||||
InstanceKlass *new_class(InstanceKlass::cast(*old_2_new_klass_map.get(the_class)));
|
||||
new_class->link_class(THREAD);
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
Symbol *ex_name = PENDING_EXCEPTION->klass()->name();
|
||||
@@ -918,7 +925,7 @@ jvmtiError VM_EnhancedRedefineClasses::load_new_class_versions(TRAPS) {
|
||||
return JVMTI_ERROR_NONE;
|
||||
}
|
||||
|
||||
jvmtiError VM_EnhancedRedefineClasses::load_new_class_versions_single_step(TRAPS) {
|
||||
jvmtiError VM_EnhancedRedefineClasses::load_new_class_versions_single_step(Old2NewKlassMap* old_2_new_klass_map, TRAPS) {
|
||||
|
||||
// thread local state - used to transfer class_being_redefined object to SystemDictonery::resolve_from_stream
|
||||
JvmtiThreadState *state = JvmtiThreadState::state_for(JavaThread::current());
|
||||
@@ -933,10 +940,16 @@ jvmtiError VM_EnhancedRedefineClasses::load_new_class_versions_single_step(TRAPS
|
||||
HandleMark hm(THREAD);
|
||||
InstanceKlass* the_class = InstanceKlass::cast(_affected_klasses->at(i));
|
||||
|
||||
if (the_class->new_version() != nullptr) {
|
||||
if (old_2_new_klass_map->contains(the_class)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (the_class->new_version() != nullptr) {
|
||||
// the_class was redefined and now has a new version
|
||||
log_trace(redefine, class, load)("Class redefinition detected: '%s' has a new version.", the_class->name()->as_C_string());
|
||||
_affected_klasses->at_put(i, the_class);
|
||||
}
|
||||
|
||||
Symbol* the_class_sym = the_class->name();
|
||||
|
||||
// Ensure class is linked before redefine
|
||||
@@ -1013,6 +1026,7 @@ jvmtiError VM_EnhancedRedefineClasses::load_new_class_versions_single_step(TRAPS
|
||||
the_class_loader,
|
||||
cl_info,
|
||||
the_class,
|
||||
old_2_new_klass_map,
|
||||
THREAD);
|
||||
|
||||
if (!HAS_PENDING_EXCEPTION) {
|
||||
@@ -1039,6 +1053,7 @@ jvmtiError VM_EnhancedRedefineClasses::load_new_class_versions_single_step(TRAPS
|
||||
the_class_loader,
|
||||
cl_info,
|
||||
the_class,
|
||||
old_2_new_klass_map,
|
||||
THREAD);
|
||||
}
|
||||
// Clear class_being_redefined just to be sure.
|
||||
@@ -1077,7 +1092,7 @@ jvmtiError VM_EnhancedRedefineClasses::load_new_class_versions_single_step(TRAPS
|
||||
the_class->clear_redefinition_flag(Klass::PrimaryRedefine);
|
||||
|
||||
InstanceKlass* new_class = k;
|
||||
the_class->set_new_version(new_class);
|
||||
old_2_new_klass_map->put(the_class, new_class);
|
||||
_new_classes->append(new_class);
|
||||
|
||||
if (the_class == vmClasses::Reference_klass()) {
|
||||
@@ -1096,7 +1111,7 @@ jvmtiError VM_EnhancedRedefineClasses::load_new_class_versions_single_step(TRAPS
|
||||
if (not_changed) {
|
||||
redefinition_flags = Klass::NoRedefinition;
|
||||
} else {
|
||||
redefinition_flags = calculate_redefinition_flags(new_class);
|
||||
redefinition_flags = calculate_redefinition_flags(new_class, old_2_new_klass_map);
|
||||
if (redefinition_flags >= Klass::RemoveSuperType) {
|
||||
return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED;
|
||||
}
|
||||
@@ -1130,7 +1145,8 @@ jvmtiError VM_EnhancedRedefineClasses::load_new_class_versions_single_step(TRAPS
|
||||
}
|
||||
|
||||
// Calculated the difference between new and old class (field change, method change, supertype change, ...).
|
||||
int VM_EnhancedRedefineClasses::calculate_redefinition_flags(InstanceKlass* new_class) {
|
||||
int VM_EnhancedRedefineClasses::calculate_redefinition_flags(InstanceKlass* new_class,
|
||||
Old2NewKlassMap* old_2_new_klass_map) {
|
||||
int result = Klass::NoRedefinition;
|
||||
log_debug(redefine, class, load)("Comparing different class versions of class %s",new_class->name()->as_C_string());
|
||||
|
||||
@@ -1151,7 +1167,8 @@ int VM_EnhancedRedefineClasses::calculate_redefinition_flags(InstanceKlass* new_
|
||||
// Super class changed
|
||||
Klass* cur_klass = the_class->super();
|
||||
while (cur_klass != nullptr) {
|
||||
if (!new_class->is_subclass_of(cur_klass->newest_version())) {
|
||||
Klass** new_cur_klass = old_2_new_klass_map->get(cur_klass);
|
||||
if (!new_class->is_subclass_of(new_cur_klass != nullptr ? *new_cur_klass : cur_klass)) {
|
||||
log_info(redefine, class, load)("removed super class %s", cur_klass->name()->as_C_string());
|
||||
result = result | Klass::RemoveSuperType | Klass::ModifyInstances | Klass::ModifyClass;
|
||||
}
|
||||
@@ -1174,7 +1191,7 @@ int VM_EnhancedRedefineClasses::calculate_redefinition_flags(InstanceKlass* new_
|
||||
Array<InstanceKlass*>* old_interfaces = the_class->transitive_interfaces();
|
||||
for (i = 0; i < old_interfaces->length(); i++) {
|
||||
InstanceKlass* old_interface = InstanceKlass::cast(old_interfaces->at(i));
|
||||
if (!new_class->implements_interface_any_version(old_interface)) {
|
||||
if (!new_class->implements_interface_dcevm(old_interface, old_2_new_klass_map)) {
|
||||
result = result | Klass::RemoveSuperType | Klass::ModifyClass;
|
||||
log_info(redefine, class, load)("removed interface %s", old_interface->name()->as_C_string());
|
||||
}
|
||||
@@ -1183,7 +1200,7 @@ int VM_EnhancedRedefineClasses::calculate_redefinition_flags(InstanceKlass* new_
|
||||
// Interfaces added?
|
||||
Array<InstanceKlass*>* new_interfaces = new_class->transitive_interfaces();
|
||||
for (i = 0; i<new_interfaces->length(); i++) {
|
||||
if (!the_class->implements_interface_any_version(new_interfaces->at(i))) {
|
||||
if (!the_class->implements_interface_dcevm(new_interfaces->at(i), old_2_new_klass_map)) {
|
||||
result = result | Klass::ModifyClass;
|
||||
log_info(redefine, class, load)("added interface %s", new_interfaces->at(i)->name()->as_C_string());
|
||||
}
|
||||
@@ -1527,17 +1544,17 @@ void VM_EnhancedRedefineClasses::calculate_instance_update_information(Klass* ne
|
||||
}
|
||||
} else {
|
||||
FieldInfo internal_field = holder->field(fd->index());
|
||||
InstanceKlass* old_klass = InstanceKlass::cast(holder->old_version());
|
||||
int java_fields_count = old_klass->java_fields_count();
|
||||
InstanceKlass* maybe_old_klass = holder->is_redefining() ? InstanceKlass::cast(holder->old_version()) : holder;
|
||||
int java_fields_count = maybe_old_klass->java_fields_count();
|
||||
int num_injected;
|
||||
const InjectedField* const injected = JavaClasses::get_injected(old_klass->name(), &num_injected);
|
||||
const InjectedField* const injected = JavaClasses::get_injected(maybe_old_klass->name(), &num_injected);
|
||||
for (int i = java_fields_count; i < java_fields_count+num_injected; i++) {
|
||||
FieldInfo old_field = old_klass->field(i);
|
||||
if (old_field.field_flags().is_injected() &&
|
||||
FieldInfo maybe_old_field = maybe_old_klass->field(i);
|
||||
if (maybe_old_field.field_flags().is_injected() &&
|
||||
internal_field.field_flags().is_injected() &&
|
||||
old_field.lookup_symbol(old_field.name_index()) == internal_field.lookup_symbol(internal_field.name_index())) {
|
||||
copy(old_field.offset(), type2aelembytes(Signature::basic_type(internal_field.signature_injected_dcevm())));
|
||||
if (old_field.offset() < internal_field.offset()) {
|
||||
maybe_old_field.lookup_symbol(maybe_old_field.name_index()) == internal_field.lookup_symbol(internal_field.name_index())) {
|
||||
copy(maybe_old_field.offset(), type2aelembytes(Signature::basic_type(internal_field.signature_injected_dcevm())));
|
||||
if (maybe_old_field.offset() < internal_field.offset()) {
|
||||
_copy_backwards = true;
|
||||
}
|
||||
break;
|
||||
@@ -2286,7 +2303,10 @@ class AffectedKlassClosure : public KlassClosure {
|
||||
|
||||
// Find all affected classes by current redefinition (either because of redefine, class hierarchy or interface change).
|
||||
// Affected classes are stored in _affected_klasses and parent classes always precedes child class.
|
||||
jvmtiError VM_EnhancedRedefineClasses::find_sorted_affected_classes(bool do_initial_mark, GrowableArray<Klass*>* prev_affected_klasses, TRAPS) {
|
||||
jvmtiError VM_EnhancedRedefineClasses::find_sorted_affected_classes(bool do_initial_mark,
|
||||
GrowableArray<Klass*>* prev_affected_klasses,
|
||||
Old2NewKlassMap* old_2_new_klass_map,
|
||||
TRAPS) {
|
||||
if (do_initial_mark) {
|
||||
for (int i = 0; i < _class_count; i++) {
|
||||
InstanceKlass* klass = get_ik(_class_defs[i].klass);
|
||||
@@ -2316,7 +2336,7 @@ jvmtiError VM_EnhancedRedefineClasses::find_sorted_affected_classes(bool do_init
|
||||
log_trace(redefine, class, load)("%d classes affected", _affected_klasses->length());
|
||||
|
||||
// Sort the affected klasses such that a supertype is always on a smaller array index than its subtype.
|
||||
jvmtiError result = do_topological_class_sorting(THREAD);
|
||||
jvmtiError result = do_topological_class_sorting(old_2_new_klass_map, THREAD);
|
||||
|
||||
if (log_is_enabled(Trace, redefine, class, load)) {
|
||||
log_trace(redefine, class, load)("redefine order:");
|
||||
@@ -2342,7 +2362,7 @@ struct KlassPair {
|
||||
// Affected flag is cleared (clear_redefinition_flag(Klass::MarkedAsAffected))
|
||||
// For each dependency create a KlassPair instance. Finally, affected classes (_affected_klasses) are sorted according to pairs.
|
||||
// TODO - the class file is potentially parsed multiple times - introduce a cache?
|
||||
jvmtiError VM_EnhancedRedefineClasses::do_topological_class_sorting(TRAPS) {
|
||||
jvmtiError VM_EnhancedRedefineClasses::do_topological_class_sorting(Old2NewKlassMap* old_2_new_klass_map, TRAPS) {
|
||||
ResourceMark mark(THREAD);
|
||||
|
||||
// Collect dependencies
|
||||
@@ -2363,7 +2383,7 @@ jvmtiError VM_EnhancedRedefineClasses::do_topological_class_sorting(TRAPS) {
|
||||
klass->class_loader_data(),
|
||||
&cl_info,
|
||||
ClassFileParser::INTERNAL, // publicity level
|
||||
true,
|
||||
old_2_new_klass_map,
|
||||
THREAD);
|
||||
|
||||
const Klass* super_klass = parser.super_klass();
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "oops/objArrayOop.hpp"
|
||||
#include "gc/shared/gcVMOperations.hpp"
|
||||
#include "../../../java.base/unix/native/include/jni_md.h"
|
||||
#include "classfile/classFileParserDCEVM.hpp"
|
||||
|
||||
//
|
||||
// Enhanced class redefiner.
|
||||
@@ -112,16 +113,19 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {
|
||||
//
|
||||
// The result is sotred in _affected_klasses(old definitions) and _new_classes(new definitions) arrays.
|
||||
jvmtiError load_new_class_versions(TRAPS);
|
||||
jvmtiError load_new_class_versions_single_step(TRAPS);
|
||||
jvmtiError load_new_class_versions_single_step(Old2NewKlassMap* old_2_new_klass_map, TRAPS);
|
||||
|
||||
// Searches for all affected classes and performs a sorting such tha
|
||||
// a supertype is always before a subtype.
|
||||
jvmtiError find_sorted_affected_classes(bool do_initial_mark, GrowableArray<Klass*>* prev_affected_klasses, TRAPS);
|
||||
jvmtiError find_sorted_affected_classes(bool do_initial_mark,
|
||||
GrowableArray<Klass*>* prev_affected_klasses,
|
||||
Old2NewKlassMap* old_2_new_klass_map,
|
||||
TRAPS);
|
||||
|
||||
jvmtiError do_topological_class_sorting(TRAPS);
|
||||
jvmtiError do_topological_class_sorting(Old2NewKlassMap* old_2_new_klass_map, TRAPS);
|
||||
|
||||
jvmtiError find_class_bytes(InstanceKlass* the_class, const unsigned char **class_bytes, jint *class_byte_count, jboolean *not_changed);
|
||||
int calculate_redefinition_flags(InstanceKlass* new_class);
|
||||
int calculate_redefinition_flags(InstanceKlass* new_class, Old2NewKlassMap* old_2_new_klass_map);
|
||||
void calculate_instance_update_information(Klass* new_version);
|
||||
|
||||
void rollback();
|
||||
@@ -149,7 +153,6 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {
|
||||
// and in all direct and indirect subclasses.
|
||||
void increment_class_counter(Thread* current, InstanceKlass *ik);
|
||||
|
||||
|
||||
void flush_dependent_code();
|
||||
|
||||
u8 next_id();
|
||||
@@ -158,14 +161,6 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {
|
||||
|
||||
static void dump_methods();
|
||||
|
||||
// Check that there are no old or obsolete methods
|
||||
class CheckClass : public KlassClosure {
|
||||
Thread* _thread;
|
||||
public:
|
||||
CheckClass(Thread* t) : _thread(t) {}
|
||||
void do_klass(Klass* k);
|
||||
};
|
||||
|
||||
// Unevolving classes may point to methods of the_class directly
|
||||
// from their constant pool caches, itables, and/or vtables. We
|
||||
// use the ClassLoaderDataGraph::classes_do() facility and this helper
|
||||
|
||||
@@ -90,6 +90,8 @@
|
||||
// FIXLATER: hook into JvmtiTrace
|
||||
#define TraceJVMTICalls false
|
||||
|
||||
static volatile int _active_redefinitions = 0;
|
||||
|
||||
JvmtiEnv::JvmtiEnv(jint version) : JvmtiEnvBase(version) {
|
||||
}
|
||||
|
||||
@@ -486,10 +488,14 @@ JvmtiEnv::RetransformClasses(jint class_count, const jclass* classes) {
|
||||
if (AllowEnhancedClassRedefinition) {
|
||||
// MutexLocker sd_mutex(EnhancedRedefineClasses_lock, Monitor::_no_safepoint_check_flag);
|
||||
// Stop compilation to avoid compilator race condition (crashes) with advanced redefinition
|
||||
Atomic::add(&_active_redefinitions, 1);
|
||||
CompileBroker::stopCompilationBeforeEnhancedRedefinition();
|
||||
VM_EnhancedRedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_retransform);
|
||||
VMThread::execute(&op);
|
||||
CompileBroker::releaseCompilationAfterEnhancedRedefinition();
|
||||
Atomic::sub(&_active_redefinitions, 1);
|
||||
if (_active_redefinitions == 0) {
|
||||
CompileBroker::releaseCompilationAfterEnhancedRedefinition();
|
||||
}
|
||||
op_id = op.id();
|
||||
error = (op.check_error());
|
||||
} else {
|
||||
|
||||
@@ -1378,7 +1378,7 @@ jvmtiError VM_RedefineClasses::load_new_class_versions() {
|
||||
the_class->name(),
|
||||
the_class->class_loader_data(),
|
||||
cl_info,
|
||||
false,
|
||||
nullptr,
|
||||
THREAD);
|
||||
|
||||
// Clear class_being_redefined just to be sure.
|
||||
|
||||
@@ -9,7 +9,7 @@ javax/swing/JComponent/7154030/bug7154030.java JBR-7713 macosx-aarch64
|
||||
javax/swing/JDialog/Transparency/TransparencyTest.java JBR-7554 macosx-aarch64
|
||||
javax/swing/JSplitPane/4820080/JSplitPaneDragColorTest.java JBR-7247 macosx-all
|
||||
javax/swing/JWindow/ShapedAndTranslucentWindows/PerPixelTranslucentCanvas.java JBR-7404 macosx-all
|
||||
javax/swing/JWindow/ShapedAndTranslucentWindows/TranslucentPerPixelTranslucentGradient.java JBR-8327 macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4
|
||||
javax/swing/JWindow/ShapedAndTranslucentWindows/TranslucentPerPixelTranslucentGradient.java JBR-8327 macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1
|
||||
javax/swing/plaf/aqua/CustomComboBoxFocusTest.java JBR-5190 macosx-all
|
||||
javax/swing/SwingGraphics/TranslateTest.java JBR-7510 macosx-aarch64
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ java/awt/Graphics2D/TextPerf.java JBR-8541 linux-all,windows-all
|
||||
java/awt/MenuItem/EnableTest.java JBR-8543 windows-all
|
||||
java/awt/Robot/NonEmptyErrorStream.java JBR-6275 macosx-all
|
||||
|
||||
javax/swing/UI/UnninstallUIMemoryLeaks/UnninstallUIMemoryLeaks.java JBR-5952,8340330,JBR-6274 windows-all,macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-all
|
||||
javax/swing/UI/UnninstallUIMemoryLeaks/UnninstallUIMemoryLeaks.java JBR-5952,8340330,JBR-6274 windows-all,macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1,macosx-all
|
||||
|
||||
jb/build/ResolveSymbolsTest/ResolveSymbolsRealEnv.java JBR-8544 linux-all
|
||||
jb/java/awt/Window/UndecoratedDialogInTransientsChain.java JBR-8710 windows-aarch64
|
||||
@@ -23,7 +23,7 @@ java/awt/PopupMenu/PopupMenuLocation.java 8238720,JBR-5442 windows-all,linux-all
|
||||
java/awt/Robot/CheckCommonColors/CheckCommonColors.java 8253184,JBR-5510,JBR-5442,JBR-6092 windows-all,linux-all,macosx-aarch64
|
||||
java/awt/Robot/HiDPIScreenCapture/ScreenCaptureTest.java 8253184,JBR-5442 windows-all,linux-all
|
||||
java/awt/Robot/MouseLocationOnScreen/MouseLocationOnScreen.java JBR-5390 macosx-all,linux-all
|
||||
java/awt/Robot/NonEmptyErrorStream.java JBR-5442,8340330,JBR-5510,JBR-8299 linux-all,macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,linux-5.18.2-arch1-1,linux-aarch64
|
||||
java/awt/Robot/NonEmptyErrorStream.java JBR-5442,8340330,JBR-5510,JBR-8299 linux-all,macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1,linux-5.18.2-arch1-1,linux-aarch64
|
||||
java/awt/Robot/RobotMoveMultiscreen.java JBR-5442 linux-all
|
||||
java/awt/Toolkit/AWTEventListenerProxyTest/AWTEventListenerProxyTest.java JBR-6065 windows-all
|
||||
java/awt/Window/SlowMotion/SlowMotion.java JBR-5442 linux-all
|
||||
|
||||
@@ -143,7 +143,7 @@ java/awt/Frame/DisposeTest.java JBR-7937,JBR-8718 macosx-aarch64,linux-5.18.2-ar
|
||||
java/awt/Frame/MaximizedUndecorated/MaximizedUndecorated.java 8022302 generic-all
|
||||
java/awt/Frame/MaximizeUndecoratedTest.java JBR-8064 linux-all
|
||||
java/awt/Frame/MaximizedToIconified/MaximizedToIconified.java JBR-7509 macosx-all
|
||||
java/awt/Frame/MaximizedToMaximized/MaximizedToMaximized.java JBR-7947 macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4
|
||||
java/awt/Frame/MaximizedToMaximized/MaximizedToMaximized.java JBR-7947 macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1
|
||||
java/awt/Frame/MaximizedToOppositeScreen/MaximizedToOppositeScreenBig.java JBR-5303 windows-all
|
||||
java/awt/Frame/RestoreToOppositeScreen/RestoreToOppositeScreen.java 8286840 linux-all
|
||||
java/awt/Frame/InitialIconifiedTest.java 7144049,8203920 macosx-all,linux-all
|
||||
@@ -436,7 +436,7 @@ java/awt/Frame/MiscUndecorated/ActiveSwingWindowTest.java JBR-5210 windows-all
|
||||
java/awt/Frame/MiscUndecorated/FrameCloseTest.java JBR-5210 windows-all
|
||||
java/awt/Frame/MiscUndecorated/RepaintTest.java 8266244,JBR-5786 macosx-aarch64,generic-all
|
||||
java/awt/Robot/HiDPIMouseClick/HiDPIRobotMouseClick.java 8253184 windows-all
|
||||
java/awt/Robot/NonEmptyErrorStream.java 8340330,JBR-5510,JBR-8299 macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,linux-5.18.2-arch1-1,linux-aarch64
|
||||
java/awt/Robot/NonEmptyErrorStream.java 8340330,JBR-5510,JBR-8299 macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1,linux-5.18.2-arch1-1,linux-aarch64
|
||||
java/awt/Robot/RobotExtraButton/RobotExtraButton.java JBR-6554 linux-all
|
||||
java/awt/Modal/FileDialog/FileDialogAppModal1Test.java 7186009,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/FileDialog/FileDialogAppModal2Test.java 7186009,8253184 macosx-all,windows-all
|
||||
@@ -1010,11 +1010,12 @@ javax/swing/plaf/basic/BasicComboPopup/JComboBoxPopupLocation/JComboBoxPopupLoca
|
||||
javax/swing/plaf/basic/BasicDirectoryModel/LoaderThreadCount.java 8333880 windows-all
|
||||
javax/swing/plaf/basic/BasicHTML/4251579/bug4251579.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
|
||||
javax/swing/plaf/basic/BasicMenuUI/4983388/bug4983388.java 8253184 windows-all
|
||||
javax/swing/plaf/basic/BasicRootPaneUI/HiddenDefaultButtonTest.java JBR-8795 linux-aarch64
|
||||
javax/swing/plaf/basic/BasicTableHeaderUI/6394566/bug6394566.java JBR-5846 windows-all
|
||||
javax/swing/plaf/basic/BasicTextUI/8001470/bug8001470.java 8233177 linux-all,windows-all
|
||||
javax/swing/plaf/basic/BasicTreeUI/8023474/bug8023474.java 8253184 linux-all,windows-all
|
||||
javax/swing/plaf/nimbus/8041642/bug8041642.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
|
||||
javax/swing/plaf/nimbus/8057791/bug8057791.java 8253184,JBR-5510,JBR-8300 windows-all,linux-5.18.2-arch1-1,macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4
|
||||
javax/swing/plaf/nimbus/8057791/bug8057791.java 8253184,JBR-5510,JBR-8300 windows-all,linux-5.18.2-arch1-1,macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1
|
||||
javax/swing/plaf/nimbus/TestNimbusBGColor.java JBR-6464,JBR-5510 windows-all,linux-5.18.2-arch1-1
|
||||
javax/swing/plaf/nimbus/TestNimbusOverride.java 8253184,JBR-5829 windows-all,linux-all
|
||||
javax/swing/plaf/nimbus/TestNimbusTabbedPaneIconPosition.java JBR-8718 linux-5.18.2-arch1-1
|
||||
@@ -1045,6 +1046,7 @@ javax/swing/JComboBox/bug4924758.java JBR-5846 windows-all
|
||||
javax/swing/JComboBox/bug4996503.java JBR-5799 windows-aarch64
|
||||
javax/swing/JComboBox/bug5029504.java JBR-5799 windows-all
|
||||
javax/swing/JComboBox/ConsumedKeyTest/ConsumedKeyTest.java JBR-5210 windows-all
|
||||
javax/swing/JComboBox/EditableComboBoxPopupPos.java JBR-8793 windows-x64
|
||||
javax/swing/JComboBox/TestComboBoxComponentRendering.java JBR-8270 linux-all
|
||||
javax/swing/JComponent/6683775/bug6683775.java 8172337 generic-all
|
||||
javax/swing/JDialog/Transparency/TransparencyTest.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
|
||||
@@ -1126,8 +1128,8 @@ javax/swing/JSplitPane/4885629/bug4885629.java JBR-5510 linux-5.18.2-arch1-1
|
||||
javax/swing/JTabbedPane/4361477/bug4361477.java JBR-5932 linux-all
|
||||
javax/swing/JTabbedPane/8007563/Test8007563.java 8051591 generic-all
|
||||
javax/swing/JTabbedPane/4624207/bug4624207.java 8064922,8197552,JBR-6235 macosx-all,windows-all,linux-all 8064922:macosx-all, 8197552:windows-all
|
||||
javax/swing/JTabbedPane/TestBackgroundScrollPolicy.java 8253184,JBR-8498,JBR-8718 windows-all,macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,linux-5.18.2-arch1-1
|
||||
javax/swing/JTabbedPane/TestJTabbedPaneBackgroundColor.java JBR-8718 linux-5.18.2-arch1-1
|
||||
javax/swing/JTabbedPane/TestBackgroundScrollPolicy.java 8253184,JBR-8498,JBR-8718 windows-all,macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1,linux-5.18.2-arch1-1
|
||||
javax/swing/JTabbedPane/TestJTabbedPaneBackgroundColor.java JBR-8718,JBR-8493 linux-5.18.2-arch1-1,macosx-15.4.1
|
||||
javax/swing/JToggleButton/TestSelectedKey.java JBR-5846 windows-all
|
||||
javax/swing/JToolBar/4529206/bug4529206.java JBR-5387 linux-all
|
||||
javax/swing/JToolTip/6219960/bug6219960.java 8253184 windows-all
|
||||
@@ -1181,7 +1183,7 @@ javax/swing/text/JTextComponent/5074573/bug5074573.java CODETOOLS-7901623,JBR-53
|
||||
javax/swing/text/JTextComponent/6361367/bug6361367.java JBR-5210 windows-all
|
||||
javax/swing/text/View/8014863/bug8014863.java JBR-5541 windows-all,linux-all
|
||||
javax/swing/text/View/8156217/FPMethodCalledTest.java JBR-5542 linux-all
|
||||
javax/swing/UI/UnninstallUIMemoryLeaks/UnninstallUIMemoryLeaks.java JBR-5952,8340330 windows-all,macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4
|
||||
javax/swing/UI/UnninstallUIMemoryLeaks/UnninstallUIMemoryLeaks.java JBR-5952,8340330 windows-all,macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1
|
||||
java/awt/Robot/CheckCommonColors/CheckCommonColors.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
|
||||
java/awt/Robot/HiDPIScreenCapture/HiDPIRobotScreenCaptureTest.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
|
||||
java/awt/Robot/HiDPIScreenCapture/ScreenCaptureTest.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
|
||||
@@ -1286,9 +1288,9 @@ jdk/jfr/startupargs/TestStartName.java 8214685 windows-
|
||||
jdk/jfr/startupargs/TestStartDuration.java 8214685 windows-x64
|
||||
jdk/jfr/jvm/TestWaste.java 8282427 generic-all
|
||||
jdk/jfr/api/consumer/recordingstream/TestOnEvent.java 8255404 linux-x64
|
||||
jdk/jfr/api/consumer/streaming/TestOutOfProcessMigration.java JBR-8460 macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4
|
||||
jdk/jfr/api/consumer/streaming/TestJVMCrash.java JBR-8459 macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4
|
||||
jdk/jfr/api/consumer/streaming/TestJVMExit.java JBR-8460 macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4
|
||||
jdk/jfr/api/consumer/streaming/TestOutOfProcessMigration.java JBR-8460 macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1
|
||||
jdk/jfr/api/consumer/streaming/TestJVMCrash.java JBR-8459 macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1
|
||||
jdk/jfr/api/consumer/streaming/TestJVMExit.java JBR-8460 macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1
|
||||
|
||||
jdk/jfr/tool/TestPrint.java JBR-8704 macosx-all
|
||||
############################################################################
|
||||
@@ -1402,7 +1404,7 @@ com/sun/java/swing/plaf/windows/AltFocusIssueTest.java
|
||||
|
||||
jb/hotspot/AsyncProfilerRunnerTest.java JBR-7175 macosx-all
|
||||
|
||||
jb/java/awt/Graphics2D/TextRender/OGLMetalTextRender.java JBR-4091,JBR-5392 windows-aarch64,macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4
|
||||
jb/java/awt/Graphics2D/TextRender/OGLMetalTextRender.java JBR-4091,JBR-5392 windows-aarch64,macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1
|
||||
jb/java/awt/event/TouchScreenEvent/TouchScreenEventsTestLinux.sh JBR-4078 linux-all
|
||||
jb/java/awt/Font/Font467.java JBR-3960 generic-all
|
||||
jb/java/awt/image/BufferedFontRenderingTest.java JBR-6493 generic-all
|
||||
@@ -1506,7 +1508,7 @@ javax/swing/plaf/nimbus/8041642/ScrollBarThumbVisibleTest.java JBR-6485 linux-al
|
||||
javax/swing/text/CSSBorder/6796710/bug6796710.java JBR-6465 windows-all
|
||||
javax/swing/text/html/CSS/4530474/bug4530474.java JBR-5510,JBR-5951 linux-5.18.2-arch1-1,windows-x64
|
||||
jb/java/awt/CustomTitleBar/ActionListenerTest.java JBR-5819 macosx-all,windows-all
|
||||
jb/java/awt/CustomTitleBar/DialogNativeControlsTest.java JBR-5345 windows-x64
|
||||
jb/java/awt/CustomTitleBar/DialogNativeControlsTest.java JBR-8794 windows-aarch64
|
||||
jb/java/awt/CustomTitleBar/FrameNativeControlsTest.java JBR-5345 windows-all
|
||||
jb/java/awt/CustomTitleBar/JDialogNativeControlsTest.java JBR-5345 windows-x64
|
||||
jb/java/awt/CustomTitleBar/HitTestClientArea.java JBR-6675 windows-all
|
||||
|
||||
Reference in New Issue
Block a user