mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-22 20:14:43 +02:00
Merge
This commit is contained in:
commit
a0bb00ac27
18 changed files with 621 additions and 66 deletions
|
@ -3619,13 +3619,14 @@ bool os::is_interrupted(Thread* thread, bool clear_interrupted) {
|
|||
"possibility of dangling Thread pointer");
|
||||
|
||||
OSThread* osthread = thread->osthread();
|
||||
bool interrupted = osthread->interrupted();
|
||||
// There is no synchronization between the setting of the interrupt
|
||||
// and it being cleared here. It is critical - see 6535709 - that
|
||||
// we only clear the interrupt state, and reset the interrupt event,
|
||||
// if we are going to report that we were indeed interrupted - else
|
||||
// an interrupt can be "lost", leading to spurious wakeups or lost wakeups
|
||||
// depending on the timing
|
||||
// depending on the timing. By checking thread interrupt event to see
|
||||
// if the thread gets real interrupt thus prevent spurious wakeup.
|
||||
bool interrupted = osthread->interrupted() && (WaitForSingleObject(osthread->interrupt_event(), 0) == WAIT_OBJECT_0);
|
||||
if (interrupted && clear_interrupted) {
|
||||
osthread->set_interrupted(false);
|
||||
ResetEvent(osthread->interrupt_event());
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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
|
||||
|
@ -273,8 +273,8 @@ class DebugInfoReadStream : public CompressedReadStream {
|
|||
}
|
||||
Method* read_method() {
|
||||
Method* o = (Method*)(code()->metadata_at(read_int()));
|
||||
assert(o == NULL ||
|
||||
o->is_metaspace_object(), "meta data only");
|
||||
// is_metadata() is a faster check than is_metaspace_object()
|
||||
assert(o == NULL || o->is_metadata(), "meta data only");
|
||||
return o;
|
||||
}
|
||||
ScopeValue* read_object_value();
|
||||
|
|
|
@ -1295,6 +1295,7 @@ void ConstantPool::copy_entry_to(constantPoolHandle from_cp, int from_i,
|
|||
} break;
|
||||
|
||||
case JVM_CONSTANT_UnresolvedClass:
|
||||
case JVM_CONSTANT_UnresolvedClassInError:
|
||||
{
|
||||
// Can be resolved after checking tag, so check the slot first.
|
||||
CPSlot entry = from_cp->slot_at(from_i);
|
||||
|
|
|
@ -42,6 +42,7 @@ class Metadata : public MetaspaceObj {
|
|||
// Rehashing support for tables containing pointers to this
|
||||
unsigned int new_hash(juint seed) { ShouldNotReachHere(); return 0; }
|
||||
|
||||
virtual bool is_metadata() const volatile { return true; }
|
||||
virtual bool is_klass() const volatile { return false; }
|
||||
virtual bool is_method() const volatile { return false; }
|
||||
virtual bool is_methodData() const volatile { return false; }
|
||||
|
|
|
@ -3180,7 +3180,8 @@ bool LibraryCallKit::inline_native_currentThread() {
|
|||
// private native boolean java.lang.Thread.isInterrupted(boolean ClearInterrupted);
|
||||
bool LibraryCallKit::inline_native_isInterrupted() {
|
||||
// Add a fast path to t.isInterrupted(clear_int):
|
||||
// (t == Thread.current() && (!TLS._osthread._interrupted || !clear_int))
|
||||
// (t == Thread.current() &&
|
||||
// (!TLS._osthread._interrupted || WINDOWS_ONLY(false) NOT_WINDOWS(!clear_int)))
|
||||
// ? TLS._osthread._interrupted : /*slow path:*/ t.isInterrupted(clear_int)
|
||||
// So, in the common case that the interrupt bit is false,
|
||||
// we avoid making a call into the VM. Even if the interrupt bit
|
||||
|
@ -3237,6 +3238,7 @@ bool LibraryCallKit::inline_native_isInterrupted() {
|
|||
// drop through to next case
|
||||
set_control( _gvn.transform(new (C) IfTrueNode(iff_bit)));
|
||||
|
||||
#ifndef TARGET_OS_FAMILY_windows
|
||||
// (c) Or, if interrupt bit is set and clear_int is false, use 2nd fast path.
|
||||
Node* clr_arg = argument(1);
|
||||
Node* cmp_arg = _gvn.transform(new (C) CmpINode(clr_arg, intcon(0)));
|
||||
|
@ -3250,6 +3252,10 @@ bool LibraryCallKit::inline_native_isInterrupted() {
|
|||
|
||||
// drop through to next case
|
||||
set_control( _gvn.transform(new (C) IfTrueNode(iff_arg)));
|
||||
#else
|
||||
// To return true on Windows you must read the _interrupted field
|
||||
// and check the the event state i.e. take the slow path.
|
||||
#endif // TARGET_OS_FAMILY_windows
|
||||
|
||||
// (d) Otherwise, go to the slow path.
|
||||
slow_region->add_req(control());
|
||||
|
|
|
@ -4360,7 +4360,7 @@ JVM_END
|
|||
|
||||
JVM_ENTRY(void, JVM_GetVersionInfo(JNIEnv* env, jvm_version_info* info, size_t info_size))
|
||||
{
|
||||
memset(info, 0, sizeof(info_size));
|
||||
memset(info, 0, info_size);
|
||||
|
||||
info->jvm_version = Abstract_VM_Version::jvm_version();
|
||||
info->update_version = 0; /* 0 in HotSpot Express VM */
|
||||
|
|
|
@ -1464,7 +1464,19 @@ JvmtiEnv::PopFrame(JavaThread* java_thread) {
|
|||
// It's fine to update the thread state here because no JVMTI events
|
||||
// shall be posted for this PopFrame.
|
||||
|
||||
state->update_for_pop_top_frame();
|
||||
// It is only safe to perform the direct operation on the current
|
||||
// thread. All other usage needs to use a vm-safepoint-op for safety.
|
||||
if (java_thread == JavaThread::current()) {
|
||||
state->update_for_pop_top_frame();
|
||||
} else {
|
||||
VM_UpdateForPopTopFrame op(state);
|
||||
VMThread::execute(&op);
|
||||
jvmtiError err = op.result();
|
||||
if (err != JVMTI_ERROR_NONE) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
java_thread->set_popframe_condition(JavaThread::popframe_pending_bit);
|
||||
// Set pending step flag for this popframe and it is cleared when next
|
||||
// step event is posted.
|
||||
|
@ -1505,6 +1517,7 @@ JvmtiEnv::GetFrameLocation(JavaThread* java_thread, jint depth, jmethodID* metho
|
|||
// depth - pre-checked as non-negative
|
||||
jvmtiError
|
||||
JvmtiEnv::NotifyFramePop(JavaThread* java_thread, jint depth) {
|
||||
jvmtiError err = JVMTI_ERROR_NONE;
|
||||
ResourceMark rm;
|
||||
uint32_t debug_bits = 0;
|
||||
|
||||
|
@ -1532,10 +1545,17 @@ JvmtiEnv::NotifyFramePop(JavaThread* java_thread, jint depth) {
|
|||
|
||||
assert(vf->frame_pointer() != NULL, "frame pointer mustn't be NULL");
|
||||
|
||||
int frame_number = state->count_frames() - depth;
|
||||
state->env_thread_state(this)->set_frame_pop(frame_number);
|
||||
|
||||
return JVMTI_ERROR_NONE;
|
||||
// It is only safe to perform the direct operation on the current
|
||||
// thread. All other usage needs to use a vm-safepoint-op for safety.
|
||||
if (java_thread == JavaThread::current()) {
|
||||
int frame_number = state->count_frames() - depth;
|
||||
state->env_thread_state(this)->set_frame_pop(frame_number);
|
||||
} else {
|
||||
VM_SetFramePop op(this, state, depth);
|
||||
VMThread::execute(&op);
|
||||
err = op.result();
|
||||
}
|
||||
return err;
|
||||
} /* end NotifyFramePop */
|
||||
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "prims/jvmtiEnvThreadState.hpp"
|
||||
#include "prims/jvmtiEventController.hpp"
|
||||
#include "prims/jvmtiThreadState.hpp"
|
||||
#include "prims/jvmtiThreadState.inline.hpp"
|
||||
#include "runtime/fieldDescriptor.hpp"
|
||||
#include "runtime/frame.hpp"
|
||||
#include "runtime/handles.inline.hpp"
|
||||
|
@ -334,6 +335,60 @@ class JvmtiEnvIterator : public StackObj {
|
|||
JvmtiEnv* next(JvmtiEnvBase* env) { return env->next_environment(); }
|
||||
};
|
||||
|
||||
// VM operation to update for pop top frame.
|
||||
class VM_UpdateForPopTopFrame : public VM_Operation {
|
||||
private:
|
||||
JvmtiThreadState* _state;
|
||||
jvmtiError _result;
|
||||
|
||||
public:
|
||||
VM_UpdateForPopTopFrame(JvmtiThreadState* state) {
|
||||
_state = state;
|
||||
_result = JVMTI_ERROR_NONE;
|
||||
}
|
||||
VMOp_Type type() const { return VMOp_UpdateForPopTopFrame; }
|
||||
jvmtiError result() { return _result; }
|
||||
void doit() {
|
||||
JavaThread* jt = _state->get_thread();
|
||||
if (Threads::includes(jt) && !jt->is_exiting() && jt->threadObj() != NULL) {
|
||||
_state->update_for_pop_top_frame();
|
||||
} else {
|
||||
_result = JVMTI_ERROR_THREAD_NOT_ALIVE;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// VM operation to set frame pop.
|
||||
class VM_SetFramePop : public VM_Operation {
|
||||
private:
|
||||
JvmtiEnv *_env;
|
||||
JvmtiThreadState* _state;
|
||||
jint _depth;
|
||||
jvmtiError _result;
|
||||
|
||||
public:
|
||||
VM_SetFramePop(JvmtiEnv *env, JvmtiThreadState* state, jint depth) {
|
||||
_env = env;
|
||||
_state = state;
|
||||
_depth = depth;
|
||||
_result = JVMTI_ERROR_NONE;
|
||||
}
|
||||
// Nested operation must be allowed for the VM_EnterInterpOnlyMode that is
|
||||
// called from the JvmtiEventControllerPrivate::recompute_thread_enabled.
|
||||
bool allow_nested_vm_operations() const { return true; }
|
||||
VMOp_Type type() const { return VMOp_SetFramePop; }
|
||||
jvmtiError result() { return _result; }
|
||||
void doit() {
|
||||
JavaThread* jt = _state->get_thread();
|
||||
if (Threads::includes(jt) && !jt->is_exiting() && jt->threadObj() != NULL) {
|
||||
int frame_number = _state->count_frames() - _depth;
|
||||
_state->env_thread_state((JvmtiEnvBase*)_env)->set_frame_pop(frame_number);
|
||||
} else {
|
||||
_result = JVMTI_ERROR_THREAD_NOT_ALIVE;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// VM operation to get monitor information with stack depth.
|
||||
class VM_GetOwnedMonitorInfo : public VM_Operation {
|
||||
|
|
|
@ -190,12 +190,8 @@ void JvmtiEnvThreadState::compare_and_set_current_location(Method* new_method,
|
|||
|
||||
|
||||
JvmtiFramePops* JvmtiEnvThreadState::get_frame_pops() {
|
||||
#ifdef ASSERT
|
||||
uint32_t debug_bits = 0;
|
||||
#endif
|
||||
assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
|
||||
"frame pop data only accessible from same thread or while suspended");
|
||||
|
||||
assert(get_thread() == Thread::current() || SafepointSynchronize::is_at_safepoint(),
|
||||
"frame pop data only accessible from same thread or at safepoint");
|
||||
if (_frame_pops == NULL) {
|
||||
_frame_pops = new JvmtiFramePops();
|
||||
assert(_frame_pops != NULL, "_frame_pops != NULL");
|
||||
|
@ -209,44 +205,32 @@ bool JvmtiEnvThreadState::has_frame_pops() {
|
|||
}
|
||||
|
||||
void JvmtiEnvThreadState::set_frame_pop(int frame_number) {
|
||||
#ifdef ASSERT
|
||||
uint32_t debug_bits = 0;
|
||||
#endif
|
||||
assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
|
||||
"frame pop data only accessible from same thread or while suspended");
|
||||
assert(get_thread() == Thread::current() || SafepointSynchronize::is_at_safepoint(),
|
||||
"frame pop data only accessible from same thread or at safepoint");
|
||||
JvmtiFramePop fpop(frame_number);
|
||||
JvmtiEventController::set_frame_pop(this, fpop);
|
||||
}
|
||||
|
||||
|
||||
void JvmtiEnvThreadState::clear_frame_pop(int frame_number) {
|
||||
#ifdef ASSERT
|
||||
uint32_t debug_bits = 0;
|
||||
#endif
|
||||
assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
|
||||
"frame pop data only accessible from same thread or while suspended");
|
||||
assert(get_thread() == Thread::current() || SafepointSynchronize::is_at_safepoint(),
|
||||
"frame pop data only accessible from same thread or at safepoint");
|
||||
JvmtiFramePop fpop(frame_number);
|
||||
JvmtiEventController::clear_frame_pop(this, fpop);
|
||||
}
|
||||
|
||||
|
||||
void JvmtiEnvThreadState::clear_to_frame_pop(int frame_number) {
|
||||
#ifdef ASSERT
|
||||
uint32_t debug_bits = 0;
|
||||
#endif
|
||||
assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
|
||||
"frame pop data only accessible from same thread or while suspended");
|
||||
assert(get_thread() == Thread::current() || SafepointSynchronize::is_at_safepoint(),
|
||||
"frame pop data only accessible from same thread or at safepoint");
|
||||
JvmtiFramePop fpop(frame_number);
|
||||
JvmtiEventController::clear_to_frame_pop(this, fpop);
|
||||
}
|
||||
|
||||
|
||||
bool JvmtiEnvThreadState::is_frame_pop(int cur_frame_number) {
|
||||
#ifdef ASSERT
|
||||
uint32_t debug_bits = 0;
|
||||
#endif
|
||||
assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
|
||||
"frame pop data only accessible from same thread or while suspended");
|
||||
assert(get_thread() == Thread::current() || SafepointSynchronize::is_at_safepoint(),
|
||||
"frame pop data only accessible from same thread or at safepoint");
|
||||
if (!get_thread()->is_interp_only_mode() || _frame_pops == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2014, 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
|
||||
|
@ -989,21 +989,21 @@ JvmtiEventController::set_extension_event_callback(JvmtiEnvBase *env,
|
|||
|
||||
void
|
||||
JvmtiEventController::set_frame_pop(JvmtiEnvThreadState *ets, JvmtiFramePop fpop) {
|
||||
MutexLocker mu(JvmtiThreadState_lock);
|
||||
MutexLockerEx mu(SafepointSynchronize::is_at_safepoint() ? NULL : JvmtiThreadState_lock);
|
||||
JvmtiEventControllerPrivate::set_frame_pop(ets, fpop);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JvmtiEventController::clear_frame_pop(JvmtiEnvThreadState *ets, JvmtiFramePop fpop) {
|
||||
MutexLocker mu(JvmtiThreadState_lock);
|
||||
MutexLockerEx mu(SafepointSynchronize::is_at_safepoint() ? NULL : JvmtiThreadState_lock);
|
||||
JvmtiEventControllerPrivate::clear_frame_pop(ets, fpop);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JvmtiEventController::clear_to_frame_pop(JvmtiEnvThreadState *ets, JvmtiFramePop fpop) {
|
||||
MutexLocker mu(JvmtiThreadState_lock);
|
||||
MutexLockerEx mu(SafepointSynchronize::is_at_safepoint() ? NULL : JvmtiThreadState_lock);
|
||||
JvmtiEventControllerPrivate::clear_to_frame_pop(ets, fpop);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2014, 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
|
||||
|
@ -63,6 +63,7 @@ JvmtiThreadState::JvmtiThreadState(JavaThread* thread)
|
|||
_vm_object_alloc_event_collector = NULL;
|
||||
_the_class_for_redefinition_verification = NULL;
|
||||
_scratch_class_for_redefinition_verification = NULL;
|
||||
_cur_stack_depth = UNKNOWN_STACK_DEPTH;
|
||||
|
||||
// JVMTI ForceEarlyReturn support
|
||||
_pending_step_for_earlyret = false;
|
||||
|
@ -213,12 +214,9 @@ void JvmtiThreadState::leave_interp_only_mode() {
|
|||
|
||||
// Helper routine used in several places
|
||||
int JvmtiThreadState::count_frames() {
|
||||
#ifdef ASSERT
|
||||
uint32_t debug_bits = 0;
|
||||
#endif
|
||||
assert(SafepointSynchronize::is_at_safepoint() ||
|
||||
JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
|
||||
"at safepoint or must be suspended");
|
||||
guarantee(SafepointSynchronize::is_at_safepoint() ||
|
||||
(JavaThread *)Thread::current() == get_thread(),
|
||||
"must be current thread or at safepoint");
|
||||
|
||||
if (!get_thread()->has_last_Java_frame()) return 0; // no Java frames
|
||||
|
||||
|
@ -243,15 +241,9 @@ int JvmtiThreadState::count_frames() {
|
|||
|
||||
|
||||
void JvmtiThreadState::invalidate_cur_stack_depth() {
|
||||
Thread *cur = Thread::current();
|
||||
uint32_t debug_bits = 0;
|
||||
|
||||
// The caller can be the VMThread at a safepoint, the current thread
|
||||
// or the target thread must be suspended.
|
||||
guarantee((cur->is_VM_thread() && SafepointSynchronize::is_at_safepoint()) ||
|
||||
(JavaThread *)cur == get_thread() ||
|
||||
JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
|
||||
"sanity check");
|
||||
guarantee(SafepointSynchronize::is_at_safepoint() ||
|
||||
(JavaThread *)Thread::current() == get_thread(),
|
||||
"must be current thread or at safepoint");
|
||||
|
||||
_cur_stack_depth = UNKNOWN_STACK_DEPTH;
|
||||
}
|
||||
|
@ -280,10 +272,9 @@ void JvmtiThreadState::decr_cur_stack_depth() {
|
|||
}
|
||||
|
||||
int JvmtiThreadState::cur_stack_depth() {
|
||||
uint32_t debug_bits = 0;
|
||||
guarantee(JavaThread::current() == get_thread() ||
|
||||
JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
|
||||
"must be current thread or suspended");
|
||||
guarantee(SafepointSynchronize::is_at_safepoint() ||
|
||||
(JavaThread *)Thread::current() == get_thread(),
|
||||
"must be current thread or at safepoint");
|
||||
|
||||
if (!is_interp_only_mode() || _cur_stack_depth == UNKNOWN_STACK_DEPTH) {
|
||||
_cur_stack_depth = count_frames();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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
|
||||
|
@ -74,6 +74,8 @@
|
|||
template(PopulateDumpSharedSpace) \
|
||||
template(JNIFunctionTableCopier) \
|
||||
template(RedefineClasses) \
|
||||
template(UpdateForPopTopFrame) \
|
||||
template(SetFramePop) \
|
||||
template(GetOwnedMonitorInfo) \
|
||||
template(GetObjectMonitorUsage) \
|
||||
template(GetCurrentContendedMonitor) \
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue