Compare commits

...

3 Commits

Author SHA1 Message Date
Vitaly Provodin
c5d1efbfef update exclude list on results of 21.0.3_b521.1 test runs 2024-07-17 02:49:24 +04:00
MBaesken
1b966d8e90 8333542: Breakpoint in parallel code does not work #823 2024-07-13 04:43:44 +04:00
Konstantin Nisht
b220f0958a JBR-7392: Use NIO FS in ZipFile 2024-07-12 19:03:22 +04:00
24 changed files with 529 additions and 203 deletions

View File

@@ -789,6 +789,7 @@ int java_lang_Class::_class_loader_offset;
int java_lang_Class::_module_offset;
int java_lang_Class::_protection_domain_offset;
int java_lang_Class::_component_mirror_offset;
int java_lang_Class::_init_lock_offset;
int java_lang_Class::_signers_offset;
int java_lang_Class::_name_offset;
int java_lang_Class::_source_file_offset;
@@ -914,6 +915,12 @@ void java_lang_Class::initialize_mirror_fields(Klass* k,
Handle protection_domain,
Handle classData,
TRAPS) {
// Allocate a simple java object for a lock.
// This needs to be a java object because during class initialization
// it can be held across a java call.
typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK);
set_init_lock(mirror(), r);
// Set protection domain also
set_protection_domain(mirror(), protection_domain());
@@ -1135,6 +1142,10 @@ bool java_lang_Class::restore_archived_mirror(Klass *k,
if (!k->is_array_klass()) {
// - local static final fields with initial values were initialized at dump time
// create the init_lock
typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK_(false));
set_init_lock(mirror(), r);
if (protection_domain.not_null()) {
set_protection_domain(mirror(), protection_domain());
}
@@ -1199,6 +1210,15 @@ oop java_lang_Class::component_mirror(oop java_class) {
return java_class->obj_field(_component_mirror_offset);
}
oop java_lang_Class::init_lock(oop java_class) {
assert(_init_lock_offset != 0, "must be set");
return java_class->obj_field(_init_lock_offset);
}
void java_lang_Class::set_init_lock(oop java_class, oop init_lock) {
assert(_init_lock_offset != 0, "must be set");
java_class->obj_field_put(_init_lock_offset, init_lock);
}
objArrayOop java_lang_Class::signers(oop java_class) {
assert(_signers_offset != 0, "must be set");
return (objArrayOop)java_class->obj_field(_signers_offset);
@@ -1419,12 +1439,18 @@ void java_lang_Class::compute_offsets() {
InstanceKlass* k = vmClasses::Class_klass();
CLASS_FIELDS_DO(FIELD_COMPUTE_OFFSET);
// Init lock is a C union with component_mirror. Only instanceKlass mirrors have
// init_lock and only ArrayKlass mirrors have component_mirror. Since both are oops
// GC treats them the same.
_init_lock_offset = _component_mirror_offset;
CLASS_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
}
#if INCLUDE_CDS
void java_lang_Class::serialize_offsets(SerializeClosure* f) {
f->do_bool(&_offsets_computed);
f->do_u4((u4*)&_init_lock_offset);
CLASS_FIELDS_DO(FIELD_SERIALIZE_OFFSET);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2024, 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
@@ -224,6 +224,7 @@ class java_lang_Class : AllStatic {
static int _static_oop_field_count_offset;
static int _protection_domain_offset;
static int _init_lock_offset;
static int _signers_offset;
static int _class_loader_offset;
static int _module_offset;
@@ -238,6 +239,7 @@ class java_lang_Class : AllStatic {
static GrowableArray<Klass*>* _fixup_mirror_list;
static GrowableArray<Klass*>* _fixup_module_field_list;
static void set_init_lock(oop java_class, oop init_lock);
static void set_protection_domain(oop java_class, oop protection_domain);
static void set_class_loader(oop java_class, oop class_loader);
public: // DCEVM
@@ -292,6 +294,10 @@ class java_lang_Class : AllStatic {
// Support for embedded per-class oops
static oop protection_domain(oop java_class);
static oop init_lock(oop java_class);
static void clear_init_lock(oop java_class) {
set_init_lock(java_class, nullptr);
}
static oop component_mirror(oop java_class);
static objArrayOop signers(oop java_class);
static void set_signers(oop java_class, objArrayOop signers);

View File

@@ -1810,7 +1810,7 @@ void LinkResolver::resolve_invokedynamic(CallInfo& result, const constantPoolHan
// the interpreter or runtime performs a serialized check of
// the relevant ResolvedIndyEntry::method field. This is done by the caller
// of this method, via CPC::set_dynamic_call, which uses
// a lock to do the final serialization of updates
// an ObjectLocker to do the final serialization of updates
// to ResolvedIndyEntry state, including method.
// Log dynamic info to CDS classlist.

View File

@@ -51,6 +51,7 @@
#include "runtime/atomic.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/synchronizer.hpp"
#include "runtime/vm_version.hpp"
#include "utilities/macros.hpp"
@@ -251,7 +252,7 @@ void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_co
}
if (invoke_code == Bytecodes::_invokestatic) {
assert(method->method_holder()->is_initialized() ||
method->method_holder()->is_init_thread(JavaThread::current()),
method->method_holder()->is_reentrant_initialization(JavaThread::current()),
"invalid class initialization state for invoke_static");
if (!VM_Version::supports_fast_class_init_checks() && method->needs_clinit_barrier()) {
@@ -354,8 +355,18 @@ void ConstantPoolCacheEntry::set_method_handle_common(const constantPoolHandle&
// A losing writer waits on the lock until the winner writes f1 and leaves
// the lock, so that when the losing writer returns, he can use the linked
// cache entry.
// Lock fields to write
MutexLocker ml(cpool->pool_holder()->init_monitor());
JavaThread* current = JavaThread::current();
objArrayHandle resolved_references(current, cpool->resolved_references());
// Use the resolved_references() lock for this cpCache entry.
// resolved_references are created for all classes with Invokedynamic, MethodHandle
// or MethodType constant pool cache entries.
assert(resolved_references() != nullptr,
"a resolved_references array should have been created for this class");
ObjectLocker ol(resolved_references, current);
// TODO remove - not in 21
//ResolvedMethodEntry* method_entry = resolved_method_entry_at(method_index);
if (!is_f1_null()) {
return;
@@ -861,7 +872,14 @@ bool ConstantPoolCache::save_and_throw_indy_exc(
assert(PENDING_EXCEPTION->is_a(vmClasses::LinkageError_klass()),
"No LinkageError exception");
MutexLocker ml(THREAD, cpool->pool_holder()->init_monitor());
// Use the resolved_references() lock for this cpCache entry.
// resolved_references are created for all classes with Invokedynamic, MethodHandle
// or MethodType constant pool cache entries.
JavaThread* current = THREAD;
objArrayHandle resolved_references(current, cpool->resolved_references());
assert(resolved_references() != nullptr,
"a resolved_references array should have been created for this class");
ObjectLocker ol(resolved_references, current);
// if the indy_info is resolved or the indy_resolution_failed flag is set then another
// thread either succeeded in resolving the method or got a LinkageError
@@ -885,11 +903,21 @@ bool ConstantPoolCache::save_and_throw_indy_exc(
oop ConstantPoolCache::set_dynamic_call(const CallInfo &call_info, int index) {
ResourceMark rm;
MutexLocker ml(constant_pool()->pool_holder()->init_monitor());
// Use the resolved_references() lock for this cpCache entry.
// resolved_references are created for all classes with Invokedynamic, MethodHandle
// or MethodType constant pool cache entries.
JavaThread* current = JavaThread::current();
constantPoolHandle cp(current, constant_pool());
objArrayHandle resolved_references(current, cp->resolved_references());
assert(resolved_references() != nullptr,
"a resolved_references array should have been created for this class");
ObjectLocker ol(resolved_references, current);
assert(index >= 0, "Indy index must be positive at this point");
if (resolved_indy_entry_at(index)->method() != nullptr) {
return constant_pool()->resolved_reference_from_indy(index);
return cp->resolved_reference_from_indy(index);
}
if (resolved_indy_entry_at(index)->resolution_failed()) {
@@ -898,9 +926,7 @@ oop ConstantPoolCache::set_dynamic_call(const CallInfo &call_info, int index) {
guarantee(index >= 0, "Invalid indy index");
int encoded_index = ResolutionErrorTable::encode_cpcache_index(
ConstantPool::encode_invokedynamic_index(index));
JavaThread* THREAD = JavaThread::current(); // For exception macros.
constantPoolHandle cp(THREAD, constant_pool());
ConstantPool::throw_resolution_error(cp, encoded_index, THREAD);
ConstantPool::throw_resolution_error(cp, encoded_index, current);
return nullptr;
}
@@ -924,7 +950,6 @@ oop ConstantPoolCache::set_dynamic_call(const CallInfo &call_info, int index) {
if (has_appendix) {
const int appendix_index = resolved_indy_entry_at(index)->resolved_references_index();
objArrayOop resolved_references = constant_pool()->resolved_references();
assert(appendix_index >= 0 && appendix_index < resolved_references->length(), "oob");
assert(resolved_references->obj_at(appendix_index) == nullptr, "init just once");
resolved_references->obj_at_put(appendix_index, appendix());

View File

@@ -83,6 +83,7 @@
#include "runtime/mutexLocker.hpp"
#include "runtime/orderAccess.hpp"
#include "runtime/reflectionUtils.hpp"
#include "runtime/synchronizer.hpp"
#include "runtime/threads.hpp"
#include "services/classLoadingService.hpp"
#include "services/finalizerService.hpp"
@@ -504,10 +505,6 @@ Array<int>* InstanceKlass::create_new_default_vtable_indices(int len, TRAPS) {
return vtable_indices;
}
static Monitor* create_init_monitor(const char* name) {
return new Monitor(Mutex::safepoint, name);
}
InstanceKlass::InstanceKlass(const ClassFileParser& parser, KlassKind kind, ReferenceType reference_type) :
Klass(kind),
_nest_members(nullptr),
@@ -520,7 +517,6 @@ InstanceKlass::InstanceKlass(const ClassFileParser& parser, KlassKind kind, Refe
_nest_host_index(0),
_init_state(allocated),
_reference_type(reference_type),
_init_monitor(create_init_monitor("InstanceKlassInitMonitor_lock")),
_init_thread(nullptr)
{
set_vtable_length(parser.vtable_size());
@@ -748,6 +744,28 @@ objArrayOop InstanceKlass::signers() const {
return java_lang_Class::signers(java_mirror());
}
oop InstanceKlass::init_lock() const {
// return the init lock from the mirror
oop lock = java_lang_Class::init_lock(java_mirror());
// Prevent reordering with any access of initialization state
OrderAccess::loadload();
assert(lock != nullptr || !is_not_initialized(), // initialized or in_error state
"only fully initialized state can have a null lock");
return lock;
}
// Set the initialization lock to null so the object can be GC'ed. Any racing
// threads to get this lock will see a null lock and will not lock.
// That's okay because they all check for initialized state after getting
// the lock and return.
void InstanceKlass::fence_and_clear_init_lock() {
// make sure previous stores are all done, notably the init_state.
OrderAccess::storestore();
java_lang_Class::clear_init_lock(java_mirror());
assert(!is_not_initialized(), "class must be initialized now");
}
// See "The Virtual Machine Specification" section 2.16.5 for a detailed explanation of the class initialization
// process. The step comments refers to the procedure described in that section.
// Note: implementation moved to static method to expose the this pointer.
@@ -775,49 +793,6 @@ void InstanceKlass::link_class(TRAPS) {
}
}
void InstanceKlass::check_link_state_and_wait(JavaThread* current) {
MonitorLocker ml(current, _init_monitor);
bool debug_logging_enabled = log_is_enabled(Debug, class, init);
// Another thread is linking this class, wait.
while (is_being_linked() && !is_init_thread(current)) {
if (debug_logging_enabled) {
ResourceMark rm(current);
log_debug(class, init)("Thread \"%s\" waiting for linking of %s by thread \"%s\"",
current->name(), external_name(), init_thread_name());
}
ml.wait();
}
// This thread is recursively linking this class, continue
if (is_being_linked() && is_init_thread(current)) {
if (debug_logging_enabled) {
ResourceMark rm(current);
log_debug(class, init)("Thread \"%s\" recursively linking %s",
current->name(), external_name());
}
return;
}
// If this class wasn't linked already, set state to being_linked
if (!is_linked()) {
if (debug_logging_enabled) {
ResourceMark rm(current);
log_debug(class, init)("Thread \"%s\" linking %s",
current->name(), external_name());
}
set_init_state(being_linked);
set_init_thread(current);
} else {
if (debug_logging_enabled) {
ResourceMark rm(current);
log_debug(class, init)("Thread \"%s\" found %s already linked",
current->name(), external_name());
}
}
}
// Called to verify that a class can link during initialization, without
// throwing a VerifyError.
bool InstanceKlass::link_class_or_fail(TRAPS) {
@@ -896,8 +871,9 @@ bool InstanceKlass::link_class_impl(TRAPS) {
// verification & rewriting
{
LockLinkState init_lock(this, jt);
HandleMark hm(THREAD);
Handle h_init_lock(THREAD, init_lock());
ObjectLocker ol(h_init_lock, jt);
// rewritten will have been set if loader constraint error found
// on an earlier link attempt
// don't verify or rewrite if already rewritten
@@ -958,7 +934,21 @@ bool InstanceKlass::link_class_impl(TRAPS) {
// In case itable verification is ever added.
// itable().verify(tty, true);
#endif
set_initialization_state_and_notify(linked, THREAD);
if (UseVtableBasedCHA && Universe::is_fully_initialized()) {
DeoptimizationScope deopt_scope;
{
// Now mark all code that assumes the class is not linked.
// Set state under the Compile_lock also.
MutexLocker ml(THREAD, Compile_lock);
set_init_state(linked);
CodeCache::mark_dependents_on(&deopt_scope, this);
}
// Perform the deopt handshake outside Compile_lock.
deopt_scope.deoptimize_marked();
} else {
set_init_state(linked);
}
if (JvmtiExport::should_post_class_prepare() && (!AllowEnhancedClassRedefinition || old_version() == NULL /* JVMTI deadlock otherwise */)) {
JvmtiExport::post_class_prepare(THREAD, this);
}
@@ -1079,7 +1069,6 @@ void InstanceKlass::initialize_impl(TRAPS) {
DTRACE_CLASSINIT_PROBE(required, -1);
bool wait = false;
bool throw_error = false;
JavaThread* jt = THREAD;
@@ -1088,10 +1077,14 @@ void InstanceKlass::initialize_impl(TRAPS) {
// refer to the JVM book page 47 for description of steps
// Step 1
{
MonitorLocker ml(jt, _init_monitor);
Handle h_init_lock(THREAD, init_lock());
ObjectLocker ol(h_init_lock, jt);
// Step 2
while ((is_being_initialized() && !is_init_thread(jt))
// If we were to use wait() instead of waitInterruptibly() then
// we might end up throwing IE from link/symbol resolution sites
// that aren't expected to throw. This would wreak havoc. See 6320309.
while ((is_being_initialized() && !is_reentrant_initialization(jt))
|| (AllowEnhancedClassRedefinition && old_version() != NULL && InstanceKlass::cast(old_version())->is_being_initialized())) {
if (debug_logging_enabled) {
ResourceMark rm(jt);
@@ -1101,12 +1094,12 @@ void InstanceKlass::initialize_impl(TRAPS) {
wait = true;
jt->set_class_to_be_initialized(this);
ml.wait();
ol.wait_uninterruptibly(jt);
jt->set_class_to_be_initialized(nullptr);
}
// Step 3
if (is_being_initialized() && is_init_thread(jt)) {
if (is_being_initialized() && is_reentrant_initialization(jt)) {
if (debug_logging_enabled) {
ResourceMark rm(jt);
log_debug(class, init)("Thread \"%s\" recursively initializing %s",
@@ -1134,7 +1127,19 @@ void InstanceKlass::initialize_impl(TRAPS) {
log_debug(class, init)("Thread \"%s\" found %s is in error state",
jt->name(), external_name());
}
throw_error = true;
DTRACE_CLASSINIT_PROBE_WAIT(erroneous, -1, wait);
ResourceMark rm(THREAD);
Handle cause(THREAD, get_initialization_error(THREAD));
stringStream ss;
ss.print("Could not initialize class %s", external_name());
if (cause.is_null()) {
THROW_MSG(vmSymbols::java_lang_NoClassDefFoundError(), ss.as_string());
} else {
THROW_MSG_CAUSE(vmSymbols::java_lang_NoClassDefFoundError(),
ss.as_string(), cause);
}
} else {
// Step 6
@@ -1148,22 +1153,6 @@ void InstanceKlass::initialize_impl(TRAPS) {
}
}
// Throw error outside lock
if (throw_error) {
DTRACE_CLASSINIT_PROBE_WAIT(erroneous, -1, wait);
ResourceMark rm(THREAD);
Handle cause(THREAD, get_initialization_error(THREAD));
stringStream ss;
ss.print("Could not initialize class %s", external_name());
if (cause.is_null()) {
THROW_MSG(vmSymbols::java_lang_NoClassDefFoundError(), ss.as_string());
} else {
THROW_MSG_CAUSE(vmSymbols::java_lang_NoClassDefFoundError(),
ss.as_string(), cause);
}
}
// Step 7
// Next, if C is a class rather than an interface, initialize it's super class and super
// interfaces.
@@ -1221,7 +1210,7 @@ void InstanceKlass::initialize_impl(TRAPS) {
// Step 9
if (!HAS_PENDING_EXCEPTION) {
set_initialization_state_and_notify(fully_initialized, THREAD);
set_initialization_state_and_notify(fully_initialized, CHECK);
debug_only(vtable().verify(tty, true);)
}
else {
@@ -1254,43 +1243,26 @@ void InstanceKlass::initialize_impl(TRAPS) {
}
void InstanceKlass::set_initialization_state_and_notify(ClassState state, JavaThread* current) {
MonitorLocker ml(current, _init_monitor);
if (state == linked && UseVtableBasedCHA && Universe::is_fully_initialized()) {
DeoptimizationScope deopt_scope;
{
// Now mark all code that assumes the class is not linked.
// Set state under the Compile_lock also.
MutexLocker ml(current, Compile_lock);
set_init_thread(nullptr); // reset _init_thread before changing _init_state
set_init_state(state);
CodeCache::mark_dependents_on(&deopt_scope, this);
}
// Perform the deopt handshake outside Compile_lock.
deopt_scope.deoptimize_marked();
void InstanceKlass::set_initialization_state_and_notify(ClassState state, TRAPS) {
Handle h_init_lock(THREAD, init_lock());
if (h_init_lock() != nullptr) {
ObjectLocker ol(h_init_lock, THREAD);
set_init_thread(nullptr); // reset _init_thread before changing _init_state
set_init_state(state);
fence_and_clear_init_lock();
ol.notify_all(CHECK);
} else {
assert(h_init_lock() != nullptr, "The initialization state should never be set twice");
set_init_thread(nullptr); // reset _init_thread before changing _init_state
set_init_state(state);
}
ml.notify_all();
}
// Update hierarchy. This is done before the new klass has been added to the SystemDictionary. The Compile_lock
// is grabbed, to ensure that the compiler is not using the class hierarchy.
void InstanceKlass::add_to_hierarchy(JavaThread* current) {
void InstanceKlass::add_to_hierarchy_impl(JavaThread* current) {
assert(!SafepointSynchronize::is_at_safepoint(), "must NOT be at safepoint");
// In case we are not using CHA based vtables we need to make sure the loaded
// deopt is completed before anyone links this class.
// Linking is done with _init_monitor held, by loading and deopting with it
// held we make sure the deopt is completed before linking.
if (!UseVtableBasedCHA) {
init_monitor()->lock();
}
DeoptimizationScope deopt_scope;
{
MutexLocker ml(current, Compile_lock);
@@ -1312,12 +1284,26 @@ void InstanceKlass::add_to_hierarchy(JavaThread* current) {
}
// Perform the deopt handshake outside Compile_lock.
deopt_scope.deoptimize_marked();
}
if (!UseVtableBasedCHA) {
init_monitor()->unlock();
void InstanceKlass::add_to_hierarchy(JavaThread* current) {
if (UseVtableBasedCHA || !Universe::is_fully_initialized()) {
add_to_hierarchy_impl(current);
} else {
// In case we are not using CHA based vtables we need to make sure the loaded
// deopt is completed before anyone links this class.
// Linking is done with init_lock held, by loading and deopting with it
// held we make sure the deopt is completed before linking.
Handle h_init_lock(current, init_lock());
ObjectLocker ol(h_init_lock, current);
add_to_hierarchy_impl(current);
// This doesn't need a notify because the wait is only on the class initialization path.
}
}
InstanceKlass* InstanceKlass::implementor() const {
InstanceKlass* volatile* ik = adr_implementor();
if (ik == nullptr) {
@@ -2779,7 +2765,6 @@ void InstanceKlass::remove_unshareable_info() {
_nest_host = nullptr;
init_shared_package_entry();
_dep_context_last_cleaned = 0;
_init_monitor = nullptr;
remove_unshareable_flags();
}
@@ -2881,9 +2866,6 @@ void InstanceKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handl
if (DiagnoseSyncOnValueBasedClasses && has_value_based_class_annotation()) {
set_is_value_based();
}
// restore the monitor
_init_monitor = create_init_monitor("InstanceKlassInitMonitorRestored_lock");
}
// Check if a class or any of its supertypes has a version older than 50.
@@ -2979,9 +2961,6 @@ void InstanceKlass::release_C_heap_structures(bool release_sub_metadata) {
methods_do(method_release_C_heap_structures);
}
// Destroy the init_monitor
delete _init_monitor;
// Deallocate oop map cache
if (_oop_map_cache != nullptr) {
delete _oop_map_cache;
@@ -3647,7 +3626,7 @@ nmethod* InstanceKlass::lookup_osr_nmethod(const Method* m, int bci, int comp_le
#define BULLET " - "
static const char* state_names[] = {
"allocated", "loaded", "being_linked", "linked", "being_initialized", "fully_initialized", "initialization_error"
"allocated", "loaded", "linked", "being_initialized", "fully_initialized", "initialization_error"
};
static void print_vtable(intptr_t* start, int len, outputStream* st) {
@@ -4203,17 +4182,13 @@ void JNIid::verify(Klass* holder) {
}
void InstanceKlass::set_init_state(ClassState state) {
if (!is_redefining() && state > loaded) {
assert_lock_strong(_init_monitor);
}
#ifdef ASSERT
bool good_state = is_shared() ? (_init_state <= state)
: (_init_state < state);
bool link_failed = _init_state == being_linked && state == loaded;
assert(good_state || state == allocated || link_failed, "illegal state transition");
assert(good_state || state == allocated, "illegal state transition");
#endif
assert(_init_thread == nullptr, "should be cleared before state change");
Atomic::store(&_init_state, state);
_init_state = state;
}
#if INCLUDE_JVMTI

View File

@@ -150,7 +150,6 @@ class InstanceKlass: public Klass {
enum ClassState : u1 {
allocated, // allocated (but not yet linked)
loaded, // loaded and inserted in class hierarchy (but not linked yet)
being_linked, // currently running verifier and rewriter
linked, // successfully linked/verified (but not initialized yet)
being_initialized, // currently running class initializer
fully_initialized, // initialized (successful final state)
@@ -224,14 +223,20 @@ class InstanceKlass: public Klass {
volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change
// _is_marked_dependent can be set concurrently, thus cannot be part of the
// _misc_flags.
bool _is_marked_dependent; // used for marking during flushing and deoptimization
// Class states are defined as ClassState (see above).
// Place the _init_state here to utilize the unused 2-byte after
// _idnum_allocated_count.
volatile ClassState _init_state; // state of class
u1 _reference_type; // reference type
u1 _reference_type; // reference type
// State is set either at parse time or while executing, atomically to not disturb other state
InstanceKlassFlags _misc_flags;
Monitor* _init_monitor; // mutual exclusion to _init_state and _init_thread.
JavaThread* volatile _init_thread; // Pointer to current thread doing initialization (to handle recursive initialization)
OopMapCache* volatile _oop_map_cache; // OopMapCache for all methods in the klass (allocated lazily)
@@ -494,41 +499,23 @@ public:
TRAPS);
JavaThread* init_thread() { return Atomic::load(&_init_thread); }
// We can safely access the name as long as we hold the _init_monitor.
const char* init_thread_name() {
assert(_init_monitor->owned_by_self(), "Must hold _init_monitor here");
return init_thread()->name_raw();
}
public:
// initialization state
bool is_loaded() const { return init_state() >= loaded; }
bool is_linked() const { return init_state() >= linked; }
bool is_being_linked() const { return init_state() == being_linked; }
bool is_initialized() const { return init_state() == fully_initialized; }
bool is_not_initialized() const { return init_state() < being_initialized; }
bool is_being_initialized() const { return init_state() == being_initialized; }
bool is_in_error_state() const { return init_state() == initialization_error; }
bool is_init_thread(JavaThread *thread) { return thread == init_thread(); }
ClassState init_state() const { return Atomic::load(&_init_state); }
bool is_loaded() const { return _init_state >= loaded; }
bool is_linked() const { return _init_state >= linked; }
bool is_initialized() const { return _init_state == fully_initialized; }
bool is_not_initialized() const { return _init_state < being_initialized; }
bool is_being_initialized() const { return _init_state == being_initialized; }
bool is_in_error_state() const { return _init_state == initialization_error; }
bool is_reentrant_initialization(Thread *thread) { return thread == _init_thread; }
ClassState init_state() const { return _init_state; }
const char* init_state_name() const;
bool is_rewritten() const { return _misc_flags.rewritten(); }
class LockLinkState : public StackObj {
InstanceKlass* _ik;
JavaThread* _current;
public:
LockLinkState(InstanceKlass* ik, JavaThread* current) : _ik(ik), _current(current) {
ik->check_link_state_and_wait(current);
}
~LockLinkState() {
if (!_ik->is_linked()) {
// Reset to loaded if linking failed.
_ik->set_initialization_state_and_notify(loaded, _current);
}
}
};
// is this a sealed class
bool is_sealed() const;
@@ -846,7 +833,7 @@ public:
// initialization
void call_class_initializer(TRAPS);
void set_initialization_state_and_notify(ClassState state, JavaThread* current);
void set_initialization_state_and_notify(ClassState state, TRAPS);
// OopMapCache support
OopMapCache* oop_map_cache() { return _oop_map_cache; }
@@ -858,6 +845,10 @@ public:
void set_jni_ids(JNIid* ids) { _jni_ids = ids; }
JNIid* jni_id_for(int offset);
private:
void add_to_hierarchy_impl(JavaThread* current);
public:
// maintenance of deoptimization dependencies
inline DependencyContext dependencies();
void mark_dependent_nmethods(DeoptimizationScope* deopt_scope, KlassDepChange& changes);
@@ -1084,7 +1075,7 @@ public:
public:
u2 idnum_allocated_count() const { return _idnum_allocated_count; }
private:
private:
// initialization state
void set_init_state(ClassState state);
void set_rewritten() { _misc_flags.set_rewritten(true); }
@@ -1106,6 +1097,12 @@ public:
// Lock during initialization
public:
// Lock for (1) initialization; (2) access to the ConstantPool of this class.
// Must be one per class and it has to be a VM internal object so java code
// cannot lock it (like the mirror).
// It has to be an object not a Mutex because it's held through java calls.
oop init_lock() const;
// Returns the array class for the n'th dimension
virtual Klass* array_klass(int n, TRAPS);
virtual Klass* array_klass_or_null(int n);
@@ -1115,10 +1112,9 @@ public:
virtual Klass* array_klass_or_null();
static void clean_initialization_error_table();
Monitor* init_monitor() const { return _init_monitor; }
private:
void check_link_state_and_wait(JavaThread* current);
void fence_and_clear_init_lock();
bool link_class_impl (TRAPS);
bool verify_code (TRAPS);
void initialize_impl (TRAPS);

View File

@@ -1437,7 +1437,7 @@ methodHandle SharedRuntime::resolve_sub_helper(bool is_virtual, bool is_optimize
if (invoke_code == Bytecodes::_invokestatic) {
assert(callee_method->method_holder()->is_initialized() ||
callee_method->method_holder()->is_init_thread(current),
callee_method->method_holder()->is_reentrant_initialization(current),
"invalid class initialization state for invoke_static");
if (!VM_Version::supports_fast_class_init_checks() && callee_method->needs_clinit_barrier()) {
// In order to keep class initialization check, do not patch call

View File

@@ -731,6 +731,16 @@ int ObjectSynchronizer::wait(Handle obj, jlong millis, TRAPS) {
return ret_code;
}
void ObjectSynchronizer::waitUninterruptibly(Handle obj, jlong millis, TRAPS) {
if (millis < 0) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative");
}
ObjectSynchronizer::inflate(THREAD,
obj(),
inflate_cause_wait)->wait(millis, false, THREAD);
}
void ObjectSynchronizer::notify(Handle obj, TRAPS) {
JavaThread* current = THREAD;

View File

@@ -154,6 +154,11 @@ class ObjectSynchronizer : AllStatic {
static bool quick_notify(oopDesc* obj, JavaThread* current, bool All);
static bool quick_enter(oop obj, JavaThread* current, BasicLock* Lock);
// Special internal-use-only method for use by JVM infrastructure
// that needs to wait() on a java-level object but that can't risk
// throwing unexpected InterruptedExecutionExceptions.
static void waitUninterruptibly(Handle obj, jlong Millis, TRAPS);
// Inflate light weight monitor to heavy weight monitor
static ObjectMonitor* inflate(Thread* current, oop obj, const InflateCause cause);
// This version is only for internal use
@@ -249,6 +254,7 @@ class ObjectLocker : public StackObj {
// Monitor behavior
void wait(TRAPS) { ObjectSynchronizer::wait(_obj, 0, CHECK); } // wait forever
void wait_uninterruptibly(TRAPS) { ObjectSynchronizer::waitUninterruptibly(_obj, 0, CHECK); } // wait forever
void notify_all(TRAPS) { ObjectSynchronizer::notifyall(_obj, CHECK); }
};

View File

@@ -205,8 +205,9 @@ void javaVFrame::print_lock_info_on(outputStream* st, int frame_count) {
Klass* k = obj->klass();
st->print_cr("\t- %s <" INTPTR_FORMAT "> (a %s)", "parking to wait for ", p2i(obj), k->external_name());
}
else if (thread()->osthread()->get_state() == CONDVAR_WAIT) {
// We are waiting on the native class initialization monitor.
else if (thread()->osthread()->get_state() == OBJECT_WAIT) {
// We are waiting on an Object monitor but Object.wait() isn't the
// top-frame, so we should be waiting on a Class initialization monitor.
InstanceKlass* k = thread()->class_to_be_initialized();
if (k != nullptr) {
st->print_cr("\t- waiting on the Class initialization monitor for %s", k->external_name());

View File

@@ -239,6 +239,7 @@
nonstatic_field(InstanceKlass, _nonstatic_oop_map_size, int) \
volatile_nonstatic_field(InstanceKlass, _init_state, InstanceKlass::ClassState) \
volatile_nonstatic_field(InstanceKlass, _init_thread, JavaThread*) \
nonstatic_field(InstanceKlass, _is_marked_dependent, bool) \
nonstatic_field(InstanceKlass, _itable_len, int) \
nonstatic_field(InstanceKlass, _reference_type, u1) \
volatile_nonstatic_field(InstanceKlass, _oop_map_cache, OopMapCache*) \
@@ -2234,7 +2235,6 @@
\
declare_constant(InstanceKlass::allocated) \
declare_constant(InstanceKlass::loaded) \
declare_constant(InstanceKlass::being_linked) \
declare_constant(InstanceKlass::linked) \
declare_constant(InstanceKlass::being_initialized) \
declare_constant(InstanceKlass::fully_initialized) \

View File

@@ -1133,6 +1133,14 @@ u4 DumperSupport::get_static_fields_size(InstanceKlass* ik, u2& field_count) {
}
}
// Also provide a pointer to the init_lock if present, so there aren't unreferenced int[0]
// arrays.
oop init_lock = ik->init_lock();
if (init_lock != nullptr) {
field_count++;
size += sizeof(address);
}
// We write the value itself plus a name and a one byte type tag per field.
return size + field_count * (sizeof(address) + 1);
}
@@ -1170,6 +1178,14 @@ void DumperSupport::dump_static_fields(AbstractDumpWriter* writer, Klass* k) {
prev = prev->previous_versions();
}
}
// Add init lock to the end if the class is not yet initialized
oop init_lock = ik->init_lock();
if (init_lock != nullptr) {
writer->write_symbolID(vmSymbols::init_lock_name()); // name
writer->write_u1(sig2tag(vmSymbols::int_array_signature())); // type
writer->write_objectID(init_lock);
}
}
// dump the raw values of the instance fields of the given object

View File

@@ -26,17 +26,22 @@
package java.util.zip;
import java.io.Closeable;
import java.io.InputStream;
import java.io.IOException;
import java.io.EOFException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.io.UncheckedIOException;
import java.lang.ref.Cleaner.Cleanable;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.file.InvalidPathException;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.OpenOption;
import java.nio.file.StandardOpenOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
@@ -67,6 +72,7 @@ import jdk.internal.util.OperatingSystem;
import jdk.internal.perf.PerfCounter;
import jdk.internal.ref.CleanerFactory;
import jdk.internal.vm.annotation.Stable;
import sun.nio.ch.FileChannelImpl;
import sun.nio.cs.UTF_8;
import sun.nio.fs.DefaultFileSystemProvider;
import sun.security.action.GetPropertyAction;
@@ -105,6 +111,9 @@ public class ZipFile implements ZipConstants, Closeable {
// c) the "native" source of this zip file.
private final @Stable CleanableResource res;
private static final boolean USE_NIO_FOR_ZIP_FILE_ACCESS =
Boolean.parseBoolean(System.getProperty("java.util.zip.use.nio.for.zip.file.access", "false"));
private static final int STORED = ZipEntry.STORED;
private static final int DEFLATED = ZipEntry.DEFLATED;
@@ -1170,7 +1179,7 @@ public class ZipFile implements ZipConstants, Closeable {
private int refs = 1;
private RandomAccessFile zfile; // zfile of the underlying zip file
private FileAccessor zfile; // zfile of the underlying ZIP file
private byte[] cen; // CEN & ENDHDR
private long locpos; // position of first LOC header (usually 0)
private byte[] comment; // zip file comment
@@ -1181,6 +1190,88 @@ public class ZipFile implements ZipConstants, Closeable {
private int[] metaVersions; // list of unique versions found in META-INF/versions/
private final boolean startsWithLoc; // true, if zip file starts with LOCSIG (usually true)
private interface FileAccessor {
long length() throws IOException;
int read(byte[] dst, int off, int len) throws IOException;
void readFully(byte[] dst, int off, int len) throws IOException;
void seek(long pos) throws IOException;
void close() throws IOException;
}
static class RandomAccessFileAccessor implements FileAccessor {
private final RandomAccessFile file;
RandomAccessFileAccessor(RandomAccessFile file) {
this.file = file;
}
@Override
public long length() throws IOException {
return file.length();
}
@Override
public int read(byte[] dst, int off, int len) throws IOException {
return file.read(dst, off, len);
}
@Override
public void readFully(byte[] dst, int off, int len) throws IOException {
file.readFully(dst, off, len);
}
@Override
public void seek(long pos) throws IOException {
file.seek(pos);
}
@Override
public void close() throws IOException {
file.close();
}
}
static class ChannelFileAccessor implements FileAccessor {
private final FileChannel channel;
ChannelFileAccessor(FileChannel file) {
this.channel = file;
}
@Override
public long length() throws IOException {
return channel.size();
}
@Override
public int read(byte[] dst, int off, int len) throws IOException {
ByteBuffer buf = ByteBuffer.wrap(dst, off, len);
return channel.read(buf);
}
@Override
public void readFully(byte[] dst, int off, int len) throws IOException {
// copy-pasted from java.io.RandomAccessFile.readFully(byte[], int, int)
int n = 0;
do {
int count = this.read(dst, off + n, len - n);
if (count < 0)
throw new EOFException();
n += count;
} while (n < len);
}
@Override
public void seek(long pos) throws IOException {
channel.position(pos);
}
@Override
public void close() throws IOException {
channel.close();
}
}
// A Hashmap for all entries.
//
// A cen entry of Zip/JAR file. As we have one for every entry in every active Zip/JAR,
@@ -1480,16 +1571,32 @@ public class ZipFile implements ZipConstants, Closeable {
private Source(Key key, boolean toDelete, ZipCoder zc) throws IOException {
this.zc = zc;
this.key = key;
if (toDelete) {
if (OperatingSystem.isWindows()) {
this.zfile = SharedSecrets.getJavaIORandomAccessFileAccess()
.openAndDelete(key.file, "r");
if (USE_NIO_FOR_ZIP_FILE_ACCESS) {
Set<OpenOption> options;
if (toDelete) {
options = Set.of(StandardOpenOption.READ, StandardOpenOption.DELETE_ON_CLOSE);
} else {
this.zfile = new RandomAccessFile(key.file, "r");
key.file.delete();
options = Set.of(StandardOpenOption.READ);
}
FileChannel channel = FileSystems.getDefault().provider().newFileChannel(key.file.toPath(), options);
if (channel instanceof FileChannelImpl) {
((FileChannelImpl) channel).setUninterruptible();
}
this.zfile = new ChannelFileAccessor(channel);
} else {
this.zfile = new RandomAccessFile(key.file, "r");
RandomAccessFile file;
if (toDelete) {
if (OperatingSystem.isWindows()) {
file = SharedSecrets.getJavaIORandomAccessFileAccess()
.openAndDelete(key.file, "r");
} else {
file = new RandomAccessFile(key.file, "r");
key.file.delete();
}
} else {
file = new RandomAccessFile(key.file, "r");
}
this.zfile = new RandomAccessFileAccessor(file);
}
try {
initCEN(-1);

View File

@@ -57,7 +57,6 @@ public class InstanceKlass extends Klass {
// ClassState constants
private static int CLASS_STATE_ALLOCATED;
private static int CLASS_STATE_LOADED;
private static int CLASS_STATE_BEING_LINKED;
private static int CLASS_STATE_LINKED;
private static int CLASS_STATE_BEING_INITIALIZED;
private static int CLASS_STATE_FULLY_INITIALIZED;
@@ -98,7 +97,6 @@ public class InstanceKlass extends Klass {
// read ClassState constants
CLASS_STATE_ALLOCATED = db.lookupIntConstant("InstanceKlass::allocated").intValue();
CLASS_STATE_LOADED = db.lookupIntConstant("InstanceKlass::loaded").intValue();
CLASS_STATE_BEING_LINKED = db.lookupIntConstant("InstanceKlass::being_linked").intValue();
CLASS_STATE_LINKED = db.lookupIntConstant("InstanceKlass::linked").intValue();
CLASS_STATE_BEING_INITIALIZED = db.lookupIntConstant("InstanceKlass::being_initialized").intValue();
CLASS_STATE_FULLY_INITIALIZED = db.lookupIntConstant("InstanceKlass::fully_initialized").intValue();
@@ -152,7 +150,6 @@ public class InstanceKlass extends Klass {
public static class ClassState {
public static final ClassState ALLOCATED = new ClassState("allocated");
public static final ClassState LOADED = new ClassState("loaded");
public static final ClassState BEING_LINKED = new ClassState("beingLinked");
public static final ClassState LINKED = new ClassState("linked");
public static final ClassState BEING_INITIALIZED = new ClassState("beingInitialized");
public static final ClassState FULLY_INITIALIZED = new ClassState("fullyInitialized");
@@ -176,8 +173,6 @@ public class InstanceKlass extends Klass {
return ClassState.ALLOCATED;
} else if (state == CLASS_STATE_LOADED) {
return ClassState.LOADED;
} else if (state == CLASS_STATE_BEING_LINKED) {
return ClassState.BEING_LINKED;
} else if (state == CLASS_STATE_LINKED) {
return ClassState.LINKED;
} else if (state == CLASS_STATE_BEING_INITIALIZED) {

View File

@@ -183,6 +183,7 @@ serviceability/jvmti/vthread/GetSetLocalTest/GetSetLocalTest.java 8286836 generi
serviceability/jvmti/RedefineClasses/RedefineSharedClassJFR.java JBR-6245 generic-all
serviceability/jvmti/RedefineClasses/TestMultipleClasses.java initial_run windows-all
serviceability/jvmti/SetBreakpoint/TestManyBreakpoints.java initial_run generic-aarch64
serviceability/jvmti/stress/StackTrace/NotSuspended/GetStackTraceNotSuspendedStressTest.java JBR-7403 windows-aarch64
serviceability/dcmd/gc/RunFinalizationTest.java 8227120 linux-all,windows-x64,aix-ppc64

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 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
@@ -60,8 +60,7 @@ public class TestThreadDumpClassInitMonitor {
*/
final static String TEST_THREAD = "TestThread";
final static String TEST_THREAD_ENTRY = "\"" + TEST_THREAD;
// final static String IN_OBJECT_WAIT = "in Object.wait()";
final static String IN_CONVAR_WAIT = "waiting on condition";
final static String IN_OBJECT_WAIT = "in Object.wait()";
final static String THREAD_STATE = "java.lang.Thread.State: RUNNABLE";
final static String THREAD_INFO = "Thread:"; // the details are not important
final static String JAVATHREAD_STATE = "JavaThread state: _thread_blocked";
@@ -140,7 +139,7 @@ public class TestThreadDumpClassInitMonitor {
continue;
}
foundLines++;
if (!line.contains(IN_CONVAR_WAIT)) {
if (!line.contains(IN_OBJECT_WAIT)) {
throw new Error("Unexpected initial stack line: " + line);
}
continue;

View File

@@ -0,0 +1,156 @@
/*
* Copyright (c) 2024, 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 8333542
* @summary Missed breakpoint due to JVM not blocking other threads while
* delivering a ClassPrepareEvent.
*
* @run build TestScaffold VMConnection TargetListener TargetAdapter
* @run compile -g BreakpointOnClassPrepare.java
* @run driver BreakpointOnClassPrepare SUSPEND_NONE
* @run driver BreakpointOnClassPrepare SUSPEND_EVENT_THREAD
* @run driver BreakpointOnClassPrepare SUSPEND_ALL
*/
import com.sun.jdi.*;
import com.sun.jdi.event.*;
import com.sun.jdi.request.*;
import java.util.*;
// The debuggee spawns 50 threads that call LoadedClass.foo(). The debugger enables
// ClassPrepareEvent for LoadedClass, and sets a breakpoint on LoadedClass.foo() when
// the ClassPrepareEvent arrives. The debugger expects 50 breakpoints to be hit.
// This verifies that the thread that causes the generation of the ClassPrepareEvent
// has properly blocked all other threads from executing LoadedClass.foo() until the
// ClassPrepareEvent has been delivered.
class LoadedClass {
static void foo(int k) {
System.out.println("HIT = " + k); // set breakpoint here
}
}
class BreakpointOnClassPrepareTarg {
public static void main(String[] args) throws InterruptedException {
System.out.println("Start");
Thread threads[] = new Thread[BreakpointOnClassPrepare.NUM_BREAKPOINTS];
for (int i = 0; i < BreakpointOnClassPrepare.NUM_BREAKPOINTS; i++) {
int k = i;
Thread t = DebuggeeWrapper.newThread(() -> {
System.out.println("k = " + k);
LoadedClass.foo(k);
});
threads[i] = t;
t.setDaemon(true);
t.setName("MyThread-" + k);
t.start();
}
for (int i = 0; i < BreakpointOnClassPrepare.NUM_BREAKPOINTS; i++) {
try {
Thread t = threads[i];
t.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("Finish");
}
}
/********** test program **********/
public class BreakpointOnClassPrepare extends TestScaffold {
ClassType targetClass;
ThreadReference mainThread;
BreakpointOnClassPrepare(String args[]) {
super(args);
}
public static void main(String[] args) throws Exception {
new BreakpointOnClassPrepare(args).startTests();
}
/********** event handlers **********/
static final int NUM_BREAKPOINTS = 50;
int bkptCount;
BreakpointRequest bkptRequest;
public void breakpointReached(BreakpointEvent event) {
bkptCount++;
System.out.println("Got BreakpointEvent: " + bkptCount + " for thread " + event.thread());
}
public void vmDisconnected(VMDisconnectEvent event) {
println("Got VMDisconnectEvent");
}
/********** test core **********/
protected void runTests() throws Exception {
/* Determine which suspend policy to use. */
int policy;
if (args.length != 1) {
throw new RuntimeException("Invalid number of args: " + args.length);
}
String policyString = args[0];
if (policyString.equals("SUSPEND_NONE")) {
policy = EventRequest.SUSPEND_NONE;
} else if (policyString.equals("SUSPEND_ALL")) {
policy = EventRequest.SUSPEND_ALL;
} else if (policyString.equals("SUSPEND_EVENT_THREAD")) {
policy = EventRequest.SUSPEND_EVENT_THREAD;
} else {
throw new RuntimeException("Invalid suspend policy: " + policyString);
}
/* Stop when the target is loaded. */
BreakpointEvent bpe = startToMain("BreakpointOnClassPrepareTarg");
/* Stop when "LoadedClass" is loaded. */
EventRequestManager erm = vm().eventRequestManager();
ClassPrepareEvent cpe = resumeToPrepareOf("LoadedClass");
println("Got ClassPrepareEvent: " + cpe);
/* Set a breakpoint for each time LoadedClass.foo() is called. */
ClassType loadedClass = (ClassType)cpe.referenceType() ;
Location loc1 = findMethodLocation(loadedClass, "foo", "(I)V", 1);
bkptRequest = erm.createBreakpointRequest(loc1);
bkptRequest.setSuspendPolicy(policy);
bkptRequest.enable();
listenUntilVMDisconnect();
if (!testFailed && bkptCount == NUM_BREAKPOINTS) {
println("BreakpointOnClassPrepare: passed");
} else {
throw new Exception("BreakpointOnClassPrepare: failed. bkptCount == " + bkptCount);
}
}
}

View File

@@ -29,24 +29,24 @@
* @library /test/lib
*
* @summary Test: memory is properly limited using multiple buffers
* @run main/othervm -XX:MaxDirectMemorySize=10 LimitDirectMemory true 10 1
* @run main/othervm -XX:MaxDirectMemorySize=1k LimitDirectMemory true 1k 100
* @run main/othervm -XX:MaxDirectMemorySize=10m LimitDirectMemory true 10m 10m
* @run main/othervm -Djava.util.zip.use.nio.for.zip.file.access=false -XX:MaxDirectMemorySize=10 LimitDirectMemory true 10 1
* @run main/othervm -Djava.util.zip.use.nio.for.zip.file.access=false -XX:MaxDirectMemorySize=1k LimitDirectMemory true 1k 100
* @run main/othervm -Djava.util.zip.use.nio.for.zip.file.access=false -XX:MaxDirectMemorySize=10m LimitDirectMemory true 10m 10m
*
* @summary Test: We can increase the amount of available memory
* @run main/othervm -XX:MaxDirectMemorySize=65M LimitDirectMemory false 64M 65M
* @run main/othervm -Djava.util.zip.use.nio.for.zip.file.access=false -XX:MaxDirectMemorySize=65M LimitDirectMemory false 64M 65M
*
* @summary Test: Exactly the default amount of memory is available
* @run main/othervm LimitDirectMemory false 10 1
* @run main/othervm -Xmx64m LimitDirectMemory false 0 DEFAULT
* @run main/othervm -Xmx64m LimitDirectMemory true 0 DEFAULT+1
* @run main/othervm -Djava.util.zip.use.nio.for.zip.file.access=false -Xmx64m LimitDirectMemory false 0 DEFAULT
* @run main/othervm -Djava.util.zip.use.nio.for.zip.file.access=false -Xmx64m LimitDirectMemory true 0 DEFAULT+1
*
* @summary Test: We should be able to eliminate direct memory allocation entirely
* @run main/othervm -XX:MaxDirectMemorySize=0 LimitDirectMemory true 0 1
* @run main/othervm -Djava.util.zip.use.nio.for.zip.file.access=false -XX:MaxDirectMemorySize=0 LimitDirectMemory true 0 1
*
* @summary Test: Setting the system property should not work so we should be able
* to allocate the default amount
* @run main/othervm -Dsun.nio.MaxDirectMemorySize=1K -Xmx64m
* @run main/othervm -Djava.util.zip.use.nio.for.zip.file.access=false -Dsun.nio.MaxDirectMemorySize=1K -Xmx64m
* LimitDirectMemory false DEFAULT-1 DEFAULT/2
*/

View File

@@ -63,13 +63,10 @@ public class TestZipError {
// directory into in-memory data structures.
ZipFile zf = new ZipFile(fileName);
// Delete the file; of course this does not change the in-memory data
// structures that represent the central directory!
f.delete();
// Re-create zip file, with different entries than earlier. However,
// recall that we have in-memory information about the central
// directory of the file at its previous state.
// The actual file here is overwritten
zos = new ZipOutputStream(new FileOutputStream(f));
ze = new ZipEntry("uno");
zos.putNextEntry(ze);

View File

@@ -5,7 +5,9 @@ java/awt/Toolkit/AWTThreadingCMenuTest.java nobug macosx-all,linux-all,w
java/awt/Focus/TemporaryLostComponentDeadlock.java JBR-5734 windows-all
java/awt/Focus/WindowUpdateFocusabilityTest/WindowUpdateFocusabilityTest.java nobug macosx-all,linux-all,windows-all
java/awt/List/NofocusListDblClickTest/NofocusListDblClickTest.java nobug macosx-all,linux-all,windows-all
java/awt/Paint/PaintNativeOnUpdate.java JBR-5397,JBR-7415 macosx-all,windows-x64
java/awt/PopupMenu/PopupMenuLocation.java JBR-5397,JBR-7375 macosx-all,windows-x64
java/awt/Robot/CheckCommonColors/CheckCommonColors.java JBR-5397,JBR-6092 macosx-all,windows-x64
java/awt/Robot/RobotWheelTest/RobotWheelTest.java JBR-5397,JBR-7377 macosx-all,windows-x64
java/awt/Window/BackgroundIsNotUpdated/BackgroundIsNotUpdated.java JBR-5397,JBR-7378 macosx-all,windows-x64
@@ -16,7 +18,8 @@ javax/swing/JButton/8151303/PressedIconTest.java JBR-5210,JBR-5510,JBR-5397 wind
javax/swing/JComboBox/4743225/bug4743225.java JBR-5210,JBR-5397 windows-all,macosx-all
javax/swing/JComboBox/6559152/bug6559152.java JBR-5397,JBR-7382 macosx-all,windows-x64
javax/swing/JComboBox/8041909/ActionListenerExceptionTest.java JBR-5210 windows-all
javax/swing/JComboBox/EditableComboBoxPopupPos.java JBR-7383 windows-x64
javax/swing/JComboBox/bug4996503.java JBR-7412 windows-x64
javax/swing/JComboBox/EditableComboBoxPopupPos.java JBR-7383 windows-x64
javax/swing/JInternalFrame/Test6505027.java nobug macosx-all,linux-all,windows-all
javax/swing/JMenuBar/MenuBarRTLBug.java JBR-7385 windows-x64
javax/swing/JPopupMenu/4634626/bug4634626.java nobug macosx-all,linux-all,windows-all
@@ -53,7 +56,7 @@ java/awt/Toolkit/AWTEventListenerProxyTest/AWTEventListenerProxyTest.java JBR-69
java/awt/Toolkit/LockingKeyStateTest/LockingKeyStateTest.java JBR-5397 macosx-all
javax/swing/JFileChooser/4524490/bug4524490.java JBR-5397,JBR-5846 macosx-all,windows-all
javax/swing/JFileChooser/6520101/bug6520101.java JBR-5397 macosx-all
javax/swing/JFileChooser/6520101/bug6520101.java JBR-5397,JBR-7413 macosx-all,windows-x64
javax/swing/JFileChooser/8002077/bug8002077.java JBR-4880,JBR-5397 windows-all,macosx-all
javax/swing/JLabel/4138746/JLabelMnemonicsTest.java JBR-4949,JBR-5397 linux-all,windows-all,macosx-all
javax/swing/JLabel/6596966/bug6596966.java 8197552,JBR-5397 windows-all,macosx-all
@@ -100,8 +103,6 @@ java/awt/Mouse/EnterExitEvents/DragWindowTest.java 8253184,JBR-5397 macosx-all,w
java/awt/Mouse/ExtraMouseClick/ExtraMouseClick.java 8253184,JBR-5709 windows-all,linux-all
java/awt/Mouse/MouseComboBoxTest/MouseComboBoxTest.java 8253184,JBR-6752,JBR-5397 windows-all,linux-all,macosx-all
java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersInKeyEvent.java JBR-5397 macosx-all
java/awt/Paint/PaintNativeOnUpdate.java JBR-5397 macosx-all
java/awt/Robot/CheckCommonColors/CheckCommonColors.java JBR-5397 macosx-all
java/awt/Scrollbar/ScrollbarMouseWheelTest/ScrollbarMouseWheelTest.java JBR-5397 macosx-all
java/awt/Window/WindowOwnedByEmbeddedFrameTest/WindowOwnedByEmbeddedFrameTest.java JBR-5397 macosx-all
javax/accessibility/JSlider/AccessibleAction/JSliderAccessibleAction.java JBR-5397 macosx-all
@@ -149,6 +150,7 @@ java/awt/Modal/ModalFocusTransferTests/FocusTransferDialogsAppModalTest.java JBR
java/awt/Modal/ModalFocusTransferTests/FocusTransferDialogsDocModalTest.java 8164473,JBR-5505 linux-all,windows-all
java/awt/Modal/ModalFocusTransferTests/FocusTransferDialogsModelessTest.java 8196432,JBR-5505 linux-all,windows-all
java/awt/Modal/ModalFocusTransferTests/FocusTransferDialogsNonModalTest.java 8196432,JBR-5505 linux-all,windows-all
java/awt/MouseInfo/ContainerMousePositionTest.java JBR-7412 windows-x64
java/awt/MouseInfo/GetPointerInfoTest.java JBR-5505 windows-all
java/awt/MouseInfo/MultiscreenPointerInfo.java JBR-5505 windows-all
java/awt/Multiscreen/MouseEventTest/MouseEventTest.java JBR-4908,JBR-5505 linux-all,windows-all

View File

@@ -4,6 +4,7 @@ java/awt/Paint/PaintNativeOnUpdate.java JBR-7146 macosx-12.7.4,macosx-12.7.5,mac
java/awt/Robot/HiDPIScreenCapture/ScreenCaptureTest.java JBR-7146 macosx-12.7.4,macosx-12.7.5,macosx-12.7.6
java/awt/Window/BackgroundIsNotUpdated/BackgroundIsNotUpdated.java JBR-7146 macosx-12.7.4,macosx-12.7.5,macosx-12.7.6
java/awt/Window/FullWindowContentTest/FullWindowContentRenderTest.java JBR-7146 macosx-12.7.4,macosx-12.7.5,macosx-12.7.6
java/awt/Window/FullWindowContentTest/FullWindowContentTest.java JBR-7146 macosx-12.7.4,macosx-12.7.5,macosx-12.7.6
java/awt/Window/MultiWindowApp/ChildAlwaysOnTopTest.java JBR-7312 macosx-all
java/awt/Window/ShapedAndTranslucentWindows/TranslucentChoice.java JBR-7146 macosx-12.7.4,macosx-12.7.5,macosx-12.7.6
java/awt/Window/WindowTitleVisibleTest/WindowTitleVisibleTest.java JBR-7146 macosx-12.7.4,macosx-12.7.5,macosx-12.7.6

View File

@@ -116,6 +116,10 @@ java/awt/EventQueue/6980209/bug6980209.java 8198615,JBR-6699 macosx-all,linux-al
java/awt/Focus/6378278/InputVerifierTest.java JBR-6700 linux-all
java/awt/Focus/6382144/EndlessLoopTest.java JBR-6701 linux-all
java/awt/Focus/6981400/Test1.java 8029675,JBR-6702 windows-all,macosx-all,linux-all
java/awt/Focus/8013611/JDK8013611.java JBR-7338 linux-all
java/awt/Focus/8073453/SwingFocusTransitionTest.java JBR-7339 linux-all
java/awt/Focus/8282640/ScrollPaneFocusBugTest.java JBR-7340 linux-all
java/awt/Focus/ChoiceFocus/ChoiceFocus.java JBR-7341 linux-all
java/awt/KeyboardFocusmanager/TypeAhead/EnqueueWithDialogTest/EnqueueWithDialogTest.java JBR-5210,JBR-7077 windows-all,linux-all
java/awt/MenuItem/EnableTest.java NOBUG windows-all timeout
java/awt/Mouse/EnterExitEvents/DragWindowTest.java 8253184,JBR-5710 windows-all,linux-all

View File

@@ -71,6 +71,7 @@ javax/swing/text/StyledEditorKit/8016833/bug8016833.java initial_runs generic-al
javax/swing/text/Utilities/bug7045593.java initial_runs generic-all
javax/swing/tree/DefaultTreeCellEditor/bug4480602.java initial_runs generic-all
javax/swing/UIDefaults/6302464/bug6302464.java initial_runs generic-all
jb/java/awt/Focus/ComplexFocusSequence.java JBR-6728 linux-aarch64
jb/java/awt/Focus/PopupIncomingFocusTest.java initial_runs generic-all
jb/java/awt/Window/ZOrderOnModalDialogActivation.java initial_runs generic-all
jb/javax/swing/JLabel/JLabel/JLabel269.java initial_runs generic-all

View File

@@ -58,11 +58,13 @@ javax/swing/JComponent/7154030/bug7154030.java JBR-6134 windows-x64
javax/swing/JPopupMenu/6580930/bug6580930.java JBR-5071 linux-all
javax/swing/JSlider/6848475/bug6848475.java JBR-7329 windows-x64
javax/swing/JSplitPane/4885629/bug4885629.java JBR-7270 macosx-all
javax/swing/JWindow/ShapedAndTranslucentWindows/PerPixelTranslucentCanvas.java 8253184,JBR-7404 windows-all,macosx-all
javax/swing/JWindow/ShapedAndTranslucentWindows/ShapedPerPixelTranslucentGradient.java 8233582,JBR-6090,JBR-6360 linux-all,windows-all,macosx-all
javax/swing/plaf/basic/BasicGraphicsUtils/8132119/bug8132119.java JBR-5342 linux-all
jb/java/awt/event/MouseEvent/ReleaseAndClickModifiers.java JBR-6589 windows-all
sanity/client/SwingSet/src/GridBagLayoutDemoTest.java JBR-6285 linux-all
sanity/client/SwingSet/src/InternalFrameDemoTest.java 8253184,JBR-6685 windows-all,linux-all
sanity/client/SwingSet/src/ToolTipDemoTest.java 8293001,JBR-6293 linux-all,windows-all
sun/java2d/GdiRendering/ClipShapeRendering.java JBR-5204 linux-all,macosx-all,windows-all