This commit is contained in:
Jesper Wilhelmsson 2021-07-23 01:41:14 +00:00
commit 9935440ede
20 changed files with 226 additions and 91 deletions

View file

@ -296,6 +296,18 @@ void ZBarrierSetC2::clone_at_expansion(PhaseMacroExpand* phase, ArrayCopyNode* a
Node* dest_offset = ac->in(ArrayCopyNode::DestPos); Node* dest_offset = ac->in(ArrayCopyNode::DestPos);
Node* length = ac->in(ArrayCopyNode::Length); Node* length = ac->in(ArrayCopyNode::Length);
if (bt == T_OBJECT) {
// BarrierSetC2::clone sets the offsets via BarrierSetC2::arraycopy_payload_base_offset
// which 8-byte aligns them to allow for word size copies. Make sure the offsets point
// to the first element in the array when cloning object arrays. Otherwise, load
// barriers are applied to parts of the header.
assert(src_offset == dest_offset, "should be equal");
assert((src_offset->get_long() == arrayOopDesc::base_offset_in_bytes(T_OBJECT) && UseCompressedClassPointers) ||
(src_offset->get_long() == arrayOopDesc::length_offset_in_bytes() && !UseCompressedClassPointers),
"unexpected offset for object array clone");
src_offset = phase->longcon(arrayOopDesc::base_offset_in_bytes(T_OBJECT));
dest_offset = src_offset;
}
Node* payload_src = phase->basic_plus_adr(src, src_offset); Node* payload_src = phase->basic_plus_adr(src, src_offset);
Node* payload_dst = phase->basic_plus_adr(dest, dest_offset); Node* payload_dst = phase->basic_plus_adr(dest, dest_offset);

View file

@ -307,8 +307,8 @@ address PhaseMacroExpand::basictype2arraycopy(BasicType t,
bool disjoint_bases, bool disjoint_bases,
const char* &name, const char* &name,
bool dest_uninitialized) { bool dest_uninitialized) {
const TypeInt* src_offset_inttype = _igvn.find_int_type(src_offset);; const TypeInt* src_offset_inttype = _igvn.find_int_type(src_offset);
const TypeInt* dest_offset_inttype = _igvn.find_int_type(dest_offset);; const TypeInt* dest_offset_inttype = _igvn.find_int_type(dest_offset);
bool aligned = false; bool aligned = false;
bool disjoint = disjoint_bases; bool disjoint = disjoint_bases;

View file

@ -2122,7 +2122,32 @@ WB_ENTRY(void, WB_AsyncHandshakeWalkStack(JNIEnv* env, jobject wb, jobject threa
} }
WB_END WB_END
//Some convenience methods to deal with objects from java static volatile int _emulated_lock = 0;
WB_ENTRY(void, WB_LockAndBlock(JNIEnv* env, jobject wb, jboolean suspender))
JavaThread* self = JavaThread::current();
{
// Before trying to acquire the lock transition into a safepoint safe state.
// Otherwise if either suspender or suspendee blocks for a safepoint
// in ~ThreadBlockInVM the other one could loop forever trying to acquire
// the lock without allowing the safepoint to progress.
ThreadBlockInVM tbivm(self);
// We will deadlock here if we are 'suspender' and 'suspendee'
// suspended in ~ThreadBlockInVM. This verifies we only suspend
// at the right place.
while (Atomic::cmpxchg(&_emulated_lock, 0, 1) != 0) {}
assert(_emulated_lock == 1, "Must be locked");
// Sleep much longer in suspendee to force situation where
// 'suspender' is waiting above to acquire lock.
os::naked_short_sleep(suspender ? 1 : 10);
}
Atomic::store(&_emulated_lock, 0);
WB_END
// Some convenience methods to deal with objects from java
int WhiteBox::offset_for_field(const char* field_name, oop object, int WhiteBox::offset_for_field(const char* field_name, oop object,
Symbol* signature_symbol) { Symbol* signature_symbol) {
assert(field_name != NULL && strlen(field_name) > 0, "Field name not valid"); assert(field_name != NULL && strlen(field_name) > 0, "Field name not valid");
@ -2613,6 +2638,7 @@ static JNINativeMethod methods[] = {
{CC"handshakeReadMonitors", CC"(Ljava/lang/Thread;)Z", (void*)&WB_HandshakeReadMonitors }, {CC"handshakeReadMonitors", CC"(Ljava/lang/Thread;)Z", (void*)&WB_HandshakeReadMonitors },
{CC"handshakeWalkStack", CC"(Ljava/lang/Thread;Z)I", (void*)&WB_HandshakeWalkStack }, {CC"handshakeWalkStack", CC"(Ljava/lang/Thread;Z)I", (void*)&WB_HandshakeWalkStack },
{CC"asyncHandshakeWalkStack", CC"(Ljava/lang/Thread;)V", (void*)&WB_AsyncHandshakeWalkStack }, {CC"asyncHandshakeWalkStack", CC"(Ljava/lang/Thread;)V", (void*)&WB_AsyncHandshakeWalkStack },
{CC"lockAndBlock", CC"(Z)V", (void*)&WB_LockAndBlock},
{CC"checkThreadObjOfTerminatingThread", CC"(Ljava/lang/Thread;)V", (void*)&WB_CheckThreadObjOfTerminatingThread }, {CC"checkThreadObjOfTerminatingThread", CC"(Ljava/lang/Thread;)V", (void*)&WB_CheckThreadObjOfTerminatingThread },
{CC"verifyFrames", CC"(ZZ)V", (void*)&WB_VerifyFrames }, {CC"verifyFrames", CC"(ZZ)V", (void*)&WB_VerifyFrames },
{CC"addCompilerDirective", CC"(Ljava/lang/String;)I", {CC"addCompilerDirective", CC"(Ljava/lang/String;)I",

View file

@ -77,6 +77,7 @@ class HandshakeOperation : public CHeapObj<mtThread> {
int32_t pending_threads() { return Atomic::load(&_pending_threads); } int32_t pending_threads() { return Atomic::load(&_pending_threads); }
const char* name() { return _handshake_cl->name(); } const char* name() { return _handshake_cl->name(); }
bool is_async() { return _handshake_cl->is_async(); } bool is_async() { return _handshake_cl->is_async(); }
bool is_suspend() { return _handshake_cl->is_suspend(); }
}; };
class AsyncHandshakeOperation : public HandshakeOperation { class AsyncHandshakeOperation : public HandshakeOperation {
@ -376,6 +377,7 @@ void Handshake::execute(HandshakeClosure* hs_cl, JavaThread* target) {
// Check for pending handshakes to avoid possible deadlocks where our // Check for pending handshakes to avoid possible deadlocks where our
// target is trying to handshake us. // target is trying to handshake us.
if (SafepointMechanism::should_process(self)) { if (SafepointMechanism::should_process(self)) {
// Will not suspend here.
ThreadBlockInVM tbivm(self); ThreadBlockInVM tbivm(self);
} }
hsy.process(); hsy.process();
@ -425,11 +427,19 @@ bool HandshakeState::operation_pending(HandshakeOperation* op) {
return _queue.contains(mo); return _queue.contains(mo);
} }
HandshakeOperation* HandshakeState::get_op_for_self() { static bool no_suspend_filter(HandshakeOperation* op) {
return !op->is_suspend();
}
HandshakeOperation* HandshakeState::get_op_for_self(bool allow_suspend) {
assert(_handshakee == Thread::current(), "Must be called by self"); assert(_handshakee == Thread::current(), "Must be called by self");
assert(_lock.owned_by_self(), "Lock must be held"); assert(_lock.owned_by_self(), "Lock must be held");
if (allow_suspend) {
return _queue.peek(); return _queue.peek();
}; } else {
return _queue.peek(no_suspend_filter);
}
}
static bool non_self_queue_filter(HandshakeOperation* op) { static bool non_self_queue_filter(HandshakeOperation* op) {
return !op->is_async(); return !op->is_async();
@ -441,6 +451,11 @@ bool HandshakeState::have_non_self_executable_operation() {
return _queue.contains(non_self_queue_filter); return _queue.contains(non_self_queue_filter);
} }
bool HandshakeState::has_a_non_suspend_operation() {
MutexLocker ml(&_lock, Mutex::_no_safepoint_check_flag);
return _queue.contains(no_suspend_filter);
}
HandshakeOperation* HandshakeState::get_op() { HandshakeOperation* HandshakeState::get_op() {
assert(_handshakee != Thread::current(), "Must not be called by self"); assert(_handshakee != Thread::current(), "Must not be called by self");
assert(_lock.owned_by_self(), "Lock must be held"); assert(_lock.owned_by_self(), "Lock must be held");
@ -454,25 +469,22 @@ void HandshakeState::remove_op(HandshakeOperation* op) {
assert(ret == op, "Popped op must match requested op"); assert(ret == op, "Popped op must match requested op");
}; };
bool HandshakeState::process_by_self() { bool HandshakeState::process_by_self(bool allow_suspend) {
assert(Thread::current() == _handshakee, "should call from _handshakee"); assert(Thread::current() == _handshakee, "should call from _handshakee");
assert(!_handshakee->is_terminated(), "should not be a terminated thread"); assert(!_handshakee->is_terminated(), "should not be a terminated thread");
assert(_handshakee->thread_state() != _thread_blocked, "should not be in a blocked state"); assert(_handshakee->thread_state() != _thread_blocked, "should not be in a blocked state");
assert(_handshakee->thread_state() != _thread_in_native, "should not be in native"); assert(_handshakee->thread_state() != _thread_in_native, "should not be in native");
ThreadInVMForHandshake tivm(_handshakee); ThreadInVMForHandshake tivm(_handshakee);
{
// Handshakes cannot safely safepoint. // Handshakes cannot safely safepoint.
// The exception to this rule is the asynchronous suspension handshake. // The exception to this rule is the asynchronous suspension handshake.
// It by-passes the NSV by manually doing the transition. // It by-passes the NSV by manually doing the transition.
NoSafepointVerifier nsv; NoSafepointVerifier nsv;
return process_self_inner();
}
}
bool HandshakeState::process_self_inner() {
while (has_operation()) { while (has_operation()) {
MutexLocker ml(&_lock, Mutex::_no_safepoint_check_flag); MutexLocker ml(&_lock, Mutex::_no_safepoint_check_flag);
HandshakeOperation* op = get_op_for_self();
HandshakeOperation* op = get_op_for_self(allow_suspend);
if (op != NULL) { if (op != NULL) {
assert(op->_target == NULL || op->_target == Thread::current(), "Wrong thread"); assert(op->_target == NULL || op->_target == Thread::current(), "Wrong thread");
bool async = op->is_async(); bool async = op->is_async();
@ -621,6 +633,7 @@ class ThreadSelfSuspensionHandshake : public AsyncHandshakeClosure {
assert(current == Thread::current(), "Must be self executed."); assert(current == Thread::current(), "Must be self executed.");
current->handshake_state()->do_self_suspend(); current->handshake_state()->do_self_suspend();
} }
virtual bool is_suspend() { return true; }
}; };
bool HandshakeState::suspend_with_handshake() { bool HandshakeState::suspend_with_handshake() {
@ -667,8 +680,15 @@ public:
}; };
bool HandshakeState::suspend() { bool HandshakeState::suspend() {
JavaThread* self = JavaThread::current();
SuspendThreadHandshake st; SuspendThreadHandshake st;
Handshake::execute(&st, _handshakee); Handshake::execute(&st, _handshakee);
if (_handshakee == self) {
// If target is the current thread we need to call this to do the
// actual suspend since Handshake::execute() above only installed
// the asynchronous handshake.
SafepointMechanism::process_if_requested(self);
}
return st.did_suspend(); return st.did_suspend();
} }

View file

@ -49,6 +49,7 @@ class HandshakeClosure : public ThreadClosure, public CHeapObj<mtThread> {
virtual ~HandshakeClosure() {} virtual ~HandshakeClosure() {}
const char* name() const { return _name; } const char* name() const { return _name; }
virtual bool is_async() { return false; } virtual bool is_async() { return false; }
virtual bool is_suspend() { return false; }
virtual void do_thread(Thread* thread) = 0; virtual void do_thread(Thread* thread) = 0;
}; };
@ -92,15 +93,8 @@ class HandshakeState {
bool possibly_can_process_handshake(); bool possibly_can_process_handshake();
bool can_process_handshake(); bool can_process_handshake();
// Returns false if the JavaThread finished all its handshake operations.
// If the method returns true there is still potential work to be done,
// but we need to check for a safepoint before.
// (This is due to a suspension handshake which put the JavaThread in blocked
// state so a safepoint may be in-progress.)
bool process_self_inner();
bool have_non_self_executable_operation(); bool have_non_self_executable_operation();
HandshakeOperation* get_op_for_self(); HandshakeOperation* get_op_for_self(bool allow_suspend);
HandshakeOperation* get_op(); HandshakeOperation* get_op();
void remove_op(HandshakeOperation* op); void remove_op(HandshakeOperation* op);
@ -123,10 +117,14 @@ class HandshakeState {
bool has_operation() { bool has_operation() {
return !_queue.is_empty(); return !_queue.is_empty();
} }
bool has_a_non_suspend_operation();
bool operation_pending(HandshakeOperation* op); bool operation_pending(HandshakeOperation* op);
bool process_by_self(); // If the method returns true we need to check for a possible safepoint.
// This is due to a suspension handshake which put the JavaThread in blocked
// state so a safepoint may be in-progress.
bool process_by_self(bool allow_suspend);
enum ProcessResult { enum ProcessResult {
_no_operation = 0, _no_operation = 0,

View file

@ -243,8 +243,10 @@ template <typename PRE_PROC>
class ThreadBlockInVMPreprocess : public ThreadStateTransition { class ThreadBlockInVMPreprocess : public ThreadStateTransition {
private: private:
PRE_PROC& _pr; PRE_PROC& _pr;
bool _allow_suspend;
public: public:
ThreadBlockInVMPreprocess(JavaThread* thread, PRE_PROC& pr) : ThreadStateTransition(thread), _pr(pr) { ThreadBlockInVMPreprocess(JavaThread* thread, PRE_PROC& pr, bool allow_suspend = true)
: ThreadStateTransition(thread), _pr(pr), _allow_suspend(allow_suspend) {
assert(thread->thread_state() == _thread_in_vm, "coming from wrong thread state"); assert(thread->thread_state() == _thread_in_vm, "coming from wrong thread state");
thread->check_possible_safepoint(); thread->check_possible_safepoint();
// Once we are blocked vm expects stack to be walkable // Once we are blocked vm expects stack to be walkable
@ -257,9 +259,9 @@ class ThreadBlockInVMPreprocess : public ThreadStateTransition {
// Change to transition state and ensure it is seen by the VM thread. // Change to transition state and ensure it is seen by the VM thread.
_thread->set_thread_state_fence(_thread_blocked_trans); _thread->set_thread_state_fence(_thread_blocked_trans);
if (SafepointMechanism::should_process(_thread)) { if (SafepointMechanism::should_process(_thread, _allow_suspend)) {
_pr(_thread); _pr(_thread);
SafepointMechanism::process_if_requested(_thread); SafepointMechanism::process_if_requested(_thread, _allow_suspend);
} }
_thread->set_thread_state(_thread_in_vm); _thread->set_thread_state(_thread_in_vm);
@ -289,7 +291,7 @@ class ThreadBlockInVM {
ThreadBlockInVMPreprocess<InFlightMutexRelease> _tbivmpp; ThreadBlockInVMPreprocess<InFlightMutexRelease> _tbivmpp;
public: public:
ThreadBlockInVM(JavaThread* thread, Mutex** in_flight_mutex_addr = NULL) ThreadBlockInVM(JavaThread* thread, Mutex** in_flight_mutex_addr = NULL)
: _ifmr(in_flight_mutex_addr), _tbivmpp(thread, _ifmr) {} : _ifmr(in_flight_mutex_addr), _tbivmpp(thread, _ifmr, /* allow_suspend= */ false) {}
}; };
// Debug class instantiated in JRT_ENTRY macro. // Debug class instantiated in JRT_ENTRY macro.

View file

@ -76,29 +76,6 @@ void SafepointMechanism::default_initialize() {
} }
} }
void SafepointMechanism::process(JavaThread *thread) {
bool need_rechecking;
do {
if (global_poll()) {
// Any load in ::block() must not pass the global poll load.
// Otherwise we might load an old safepoint counter (for example).
OrderAccess::loadload();
SafepointSynchronize::block(thread);
}
// The call to on_safepoint fixes the thread's oops and the first few frames.
//
// The call has been carefully placed here to cater to a few situations:
// 1) After we exit from block after a global poll
// 2) After a thread races with the disarming of the global poll and transitions from native/blocked
// 3) Before the handshake code is run
StackWatermarkSet::on_safepoint(thread);
need_rechecking = thread->handshake_state()->has_operation() && thread->handshake_state()->process_by_self();
} while (need_rechecking);
}
uintptr_t SafepointMechanism::compute_poll_word(bool armed, uintptr_t stack_watermark) { uintptr_t SafepointMechanism::compute_poll_word(bool armed, uintptr_t stack_watermark) {
if (armed) { if (armed) {
log_debug(stackbarrier)("Computed armed for tid %d", Thread::current()->osthread()->thread_id()); log_debug(stackbarrier)("Computed armed for tid %d", Thread::current()->osthread()->thread_id());
@ -134,12 +111,31 @@ void SafepointMechanism::update_poll_values(JavaThread* thread) {
} }
} }
void SafepointMechanism::process_if_requested_slow(JavaThread *thread) { void SafepointMechanism::process(JavaThread *thread, bool allow_suspend) {
// Read global poll and has_handshake after local poll // Read global poll and has_handshake after local poll
OrderAccess::loadload(); OrderAccess::loadload();
// local poll already checked, if used. // local poll already checked, if used.
process(thread); bool need_rechecking;
do {
if (global_poll()) {
// Any load in ::block() must not pass the global poll load.
// Otherwise we might load an old safepoint counter (for example).
OrderAccess::loadload();
SafepointSynchronize::block(thread);
}
// The call to on_safepoint fixes the thread's oops and the first few frames.
//
// The call has been carefully placed here to cater to a few situations:
// 1) After we exit from block after a global poll
// 2) After a thread races with the disarming of the global poll and transitions from native/blocked
// 3) Before the handshake code is run
StackWatermarkSet::on_safepoint(thread);
need_rechecking = thread->handshake_state()->has_operation() && thread->handshake_state()->process_by_self(allow_suspend);
} while (need_rechecking);
update_poll_values(thread); update_poll_values(thread);
OrderAccess::cross_modify_fence(); OrderAccess::cross_modify_fence();
} }

View file

@ -50,8 +50,9 @@ class SafepointMechanism : public AllStatic {
static inline bool global_poll(); static inline bool global_poll();
static void process(JavaThread *thread); static void process(JavaThread *thread, bool allow_suspend);
static void process_if_requested_slow(JavaThread *thread);
static inline bool should_process_no_suspend(JavaThread* thread);
static void default_initialize(); static void default_initialize();
@ -60,7 +61,7 @@ class SafepointMechanism : public AllStatic {
static uintptr_t compute_poll_word(bool armed, uintptr_t stack_watermark); static uintptr_t compute_poll_word(bool armed, uintptr_t stack_watermark);
const static intptr_t _poll_bit = 1; const static intptr_t _poll_bit = 1;
public: public:
static inline bool local_poll_armed(JavaThread* thread); static inline bool local_poll_armed(JavaThread* thread);
static intptr_t poll_bit() { return _poll_bit; } static intptr_t poll_bit() { return _poll_bit; }
@ -79,10 +80,10 @@ public:
}; };
// Call this method to see if this thread should block for a safepoint or process handshake. // Call this method to see if this thread should block for a safepoint or process handshake.
static inline bool should_process(JavaThread* thread); static inline bool should_process(JavaThread* thread, bool allow_suspend = true);
// Processes a pending requested operation. // Processes a pending requested operation.
static inline void process_if_requested(JavaThread* thread); static inline void process_if_requested(JavaThread* thread, bool allow_suspend = true);
static inline void process_if_requested_with_exit_check(JavaThread* thread, bool check_asyncs); static inline void process_if_requested_with_exit_check(JavaThread* thread, bool check_asyncs);
// Compute what the poll values should be and install them. // Compute what the poll values should be and install them.
static void update_poll_values(JavaThread* thread); static void update_poll_values(JavaThread* thread);

View file

@ -28,6 +28,7 @@
#include "runtime/safepointMechanism.hpp" #include "runtime/safepointMechanism.hpp"
#include "runtime/atomic.hpp" #include "runtime/atomic.hpp"
#include "runtime/handshake.hpp"
#include "runtime/safepoint.hpp" #include "runtime/safepoint.hpp"
#include "runtime/thread.inline.hpp" #include "runtime/thread.inline.hpp"
@ -61,11 +62,29 @@ bool SafepointMechanism::global_poll() {
return (SafepointSynchronize::_state != SafepointSynchronize::_not_synchronized); return (SafepointSynchronize::_state != SafepointSynchronize::_not_synchronized);
} }
bool SafepointMechanism::should_process(JavaThread* thread) { bool SafepointMechanism::should_process_no_suspend(JavaThread* thread) {
return local_poll_armed(thread); if (global_poll() || thread->handshake_state()->has_a_non_suspend_operation()) {
return true;
} else {
// We ignore suspend requests if any and just check before returning if we need
// to fix the thread's oops and first few frames due to a possible safepoint.
StackWatermarkSet::on_safepoint(thread);
update_poll_values(thread);
OrderAccess::cross_modify_fence();
return false;
}
} }
void SafepointMechanism::process_if_requested(JavaThread* thread) { bool SafepointMechanism::should_process(JavaThread* thread, bool allow_suspend) {
if (!local_poll_armed(thread)) {
return false;
} else if (allow_suspend) {
return true;
}
return should_process_no_suspend(thread);
}
void SafepointMechanism::process_if_requested(JavaThread* thread, bool allow_suspend) {
// Macos/aarch64 should be in the right state for safepoint (e.g. // Macos/aarch64 should be in the right state for safepoint (e.g.
// deoptimization needs WXWrite). Crashes caused by the wrong state rarely // deoptimization needs WXWrite). Crashes caused by the wrong state rarely
@ -77,7 +96,7 @@ void SafepointMechanism::process_if_requested(JavaThread* thread) {
#endif #endif
if (local_poll_armed(thread)) { if (local_poll_armed(thread)) {
process_if_requested_slow(thread); process(thread, allow_suspend);
} }
} }

View file

@ -28,16 +28,16 @@ package java.lang.annotation;
/** /**
* Indicates the contexts in which an annotation interface is applicable. The * Indicates the contexts in which an annotation interface is applicable. The
* declaration contexts and type contexts in which an annotation interface may * declaration contexts and type contexts in which an annotation interface may
* be applicable are specified in JLS 9.6.4.1, and denoted in source code by * be applicable are specified in JLS {@jls 9.6.4.1}, and denoted in source code by
* enum constants of {@link ElementType java.lang.annotation.ElementType}. * enum constants of {@link ElementType java.lang.annotation.ElementType}.
* *
* <p>If an {@code @Target} meta-annotation is not present on an annotation * <p>If an {@code @Target} meta-annotation is not present on an annotation
* interface {@code T}, then an annotation of type {@code T} may be written as * interface {@code T}, then an annotation of type {@code T} may be written as
* a modifier for any declaration except a type parameter declaration. * a modifier for any declaration.
* *
* <p>If an {@code @Target} meta-annotation is present, the compiler will enforce * <p>If an {@code @Target} meta-annotation is present, the compiler will enforce
* the usage restrictions indicated by {@code ElementType} * the usage restrictions indicated by {@code ElementType}
* enum constants, in line with JLS 9.7.4. * enum constants, in line with JLS {@jls 9.7.4}.
* *
* <p>For example, this {@code @Target} meta-annotation indicates that the * <p>For example, this {@code @Target} meta-annotation indicates that the
* declared interface is itself a meta-annotation interface. It can only be * declared interface is itself a meta-annotation interface. It can only be

View file

@ -113,7 +113,7 @@ Jvm* AppLauncher::createJvmLauncher() const {
} }
SysInfo::setEnvVariable(libEnvVarName, SysInfo::getEnvVariable( SysInfo::setEnvVariable(libEnvVarName, SysInfo::getEnvVariable(
std::nothrow, libEnvVarName) + _T(";") + appDirPath); std::nothrow, libEnvVarName) + FileUtils::pathSeparator + appDirPath);
std::unique_ptr<Jvm> jvm(new Jvm()); std::unique_ptr<Jvm> jvm(new Jvm());

View file

@ -23,14 +23,15 @@
/* /*
* @test * @test
* @bug 8155643 * @bug 8155643 8268125 8270461
* @summary Test Object.clone() intrinsic if ReduceInitialCardMarks is disabled. * @summary Test Object.clone() intrinsic.
* *
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-ReduceInitialCardMarks * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-ReduceInitialCardMarks
* -XX:CompileCommand=compileonly,compiler.arraycopy.TestObjectArrayClone::testClone* * -XX:CompileCommand=compileonly,compiler.arraycopy.TestObjectArrayClone::testClone*
* compiler.arraycopy.TestObjectArrayClone * compiler.arraycopy.TestObjectArrayClone
* * @run main/othervm -XX:CompileCommand=compileonly,compiler.arraycopy.TestObjectArrayClone::testClone*
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions * compiler.arraycopy.TestObjectArrayClone
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedClassPointers -Xmx128m
* -XX:CompileCommand=compileonly,compiler.arraycopy.TestObjectArrayClone::testClone* * -XX:CompileCommand=compileonly,compiler.arraycopy.TestObjectArrayClone::testClone*
* compiler.arraycopy.TestObjectArrayClone * compiler.arraycopy.TestObjectArrayClone
*/ */

View file

@ -31,9 +31,9 @@ import sun.hotspot.WhiteBox;
* @summary Check if VM can kill thread which doesn't reach safepoint. * @summary Check if VM can kill thread which doesn't reach safepoint.
* @bug 8219584 8227528 * @bug 8219584 8227528
* @library /testlibrary /test/lib * @library /testlibrary /test/lib
* @build TestAbortVMOnSafepointTimeout * @build sun.hotspot.WhiteBox
* @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI TestAbortVMOnSafepointTimeout * @run driver TestAbortVMOnSafepointTimeout
*/ */
public class TestAbortVMOnSafepointTimeout { public class TestAbortVMOnSafepointTimeout {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -28,8 +28,7 @@
* @library /test/lib * @library /test/lib
* @modules java.base/jdk.internal.org.objectweb.asm * @modules java.base/jdk.internal.org.objectweb.asm
* java.base/jdk.internal.misc * java.base/jdk.internal.misc
* @compile LargeClassTest.java * @run driver LargeClassTest
* @run main LargeClassTest
*/ */
import java.io.File; import java.io.File;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -85,9 +85,4 @@ public class TestThreadDumpSMRInfo {
System.out.println("Test PASSED."); System.out.println("Test PASSED.");
} }
static void usage() {
System.err.println("Usage: java TestThreadDumpSMRInfo [-v]");
System.exit(1);
}
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -44,6 +44,7 @@ public class DuplAttributesTest {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(test); ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(test);
OutputAnalyzer output = new OutputAnalyzer(pb.start()); OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldContain("java.lang.ClassFormatError: Multiple " + result); output.shouldContain("java.lang.ClassFormatError: Multiple " + result);
output.shouldNotHaveExitValue(0);
} }
public static void main(String args[]) throws Throwable { public static void main(String args[]) throws Throwable {

View file

@ -57,6 +57,7 @@ public class HandshakeTimeoutTest {
"HandshakeTimeoutTest$Test"); "HandshakeTimeoutTest$Test");
OutputAnalyzer output = ProcessTools.executeProcess(pb); OutputAnalyzer output = ProcessTools.executeProcess(pb);
output.shouldNotHaveExitValue(0);
output.reportDiagnosticSummary(); output.reportDiagnosticSummary();
// In rare cases the target wakes up and performs the handshake at the same time as we timeout. // In rare cases the target wakes up and performs the handshake at the same time as we timeout.
// Therefore it's not certain the timeout will find any thread. // Therefore it's not certain the timeout will find any thread.

View file

@ -0,0 +1,58 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
/*
* @test SuspendBlocked
* @bug 8270085
* @library /test/lib
* @build SuspendBlocked
* @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI SuspendBlocked
*/
import jdk.test.lib.Asserts;
import sun.hotspot.WhiteBox;
public class SuspendBlocked {
public static void main(String... args) throws Exception {
Thread suspend_thread = new Thread(() -> run_loop());
suspend_thread.start();
WhiteBox wb = WhiteBox.getWhiteBox();
for (int i = 0; i < 100; i++) {
suspend_thread.suspend();
wb.lockAndBlock(/* suspender= */ true);
suspend_thread.resume();
Thread.sleep(1);
}
suspend_thread.join();
}
public static void run_loop() {
WhiteBox wb = WhiteBox.getWhiteBox();
for (int i = 0; i < 100; i++) {
wb.lockAndBlock(/* suspender= */ false);
}
}
}

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -30,6 +30,7 @@
*/ */
import java.util.List; import java.util.List;
import jdk.test.lib.Utils;
import jdk.test.lib.process.ProcessTools; import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.OutputAnalyzer;
@ -154,6 +155,7 @@ public class TestCheckedJniExceptionCheck {
// Check warnings appear where they should, with start/end statements in output... // Check warnings appear where they should, with start/end statements in output...
static void checkOuputForCorrectWarnings(OutputAnalyzer oa) throws RuntimeException { static void checkOuputForCorrectWarnings(OutputAnalyzer oa) throws RuntimeException {
oa.shouldHaveExitValue(0);
List<String> lines = oa.asLines(); List<String> lines = oa.asLines();
int expectedWarnings = 0; int expectedWarnings = 0;
int warningCount = 0; int warningCount = 0;
@ -175,12 +177,10 @@ public class TestCheckedJniExceptionCheck {
oa.reportDiagnosticSummary(); oa.reportDiagnosticSummary();
throw new RuntimeException("Unexpected warning at line " + lineNo); throw new RuntimeException("Unexpected warning at line " + lineNo);
} }
} } else if (line.startsWith(EXPECT_WARNING_START)) {
else if (line.startsWith(EXPECT_WARNING_START)) {
String countStr = line.substring(EXPECT_WARNING_START.length() + 1); String countStr = line.substring(EXPECT_WARNING_START.length() + 1);
expectedWarnings = Integer.parseInt(countStr); expectedWarnings = Integer.parseInt(countStr);
} } else if (line.startsWith(EXPECT_WARNING_END)) {
else if (line.startsWith(EXPECT_WARNING_END)) {
if (warningCount != expectedWarnings) { if (warningCount != expectedWarnings) {
oa.reportDiagnosticSummary(); oa.reportDiagnosticSummary();
throw new RuntimeException("Missing warning at line " + lineNo); throw new RuntimeException("Missing warning at line " + lineNo);
@ -189,6 +189,9 @@ public class TestCheckedJniExceptionCheck {
expectedWarnings = 0; expectedWarnings = 0;
} }
} }
if (!testStartLine) {
throw new RuntimeException("Missing test start line after " + lineNo + " lines");
}
/* /*
System.out.println("Output looks good..."); System.out.println("Output looks good...");
oa.reportDiagnosticSummary(); oa.reportDiagnosticSummary();
@ -203,6 +206,7 @@ public class TestCheckedJniExceptionCheck {
// launch and check output // launch and check output
checkOuputForCorrectWarnings(ProcessTools.executeTestJvm("-Xcheck:jni", checkOuputForCorrectWarnings(ProcessTools.executeTestJvm("-Xcheck:jni",
"-Djava.library.path=" + Utils.TEST_NATIVE_PATH,
"TestCheckedJniExceptionCheck")); "TestCheckedJniExceptionCheck"));
} }

View file

@ -608,6 +608,8 @@ public class WhiteBox {
public native boolean handshakeReadMonitors(Thread t); public native boolean handshakeReadMonitors(Thread t);
public native void asyncHandshakeWalkStack(Thread t); public native void asyncHandshakeWalkStack(Thread t);
public native void lockAndBlock(boolean suspender);
// Returns true on linux if library has the noexecstack flag set. // Returns true on linux if library has the noexecstack flag set.
public native boolean checkLibSpecifiesNoexecstack(String libfilename); public native boolean checkLibSpecifiesNoexecstack(String libfilename);