diff options
author | trims <none@none> | 2009-03-12 18:16:36 -0700 |
---|---|---|
committer | trims <none@none> | 2009-03-12 18:16:36 -0700 |
commit | be223741e196a9674309e0ad6f7a6ee80d4a708c (patch) | |
tree | 7d1460f138a00c594cb7dd4097b6971a2c686eb4 /src/share/vm/prims | |
parent | 2ccc9bd9f66f568de9d973a2bb916c40058c63fa (diff) | |
parent | 31afc3d8e2d634535d9a254cc30e88724e99cb07 (diff) | |
download | jdk8u_hotspot-be223741e196a9674309e0ad6f7a6ee80d4a708c.tar.gz |
Merge
Diffstat (limited to 'src/share/vm/prims')
-rw-r--r-- | src/share/vm/prims/jvmtiEnv.cpp | 21 | ||||
-rw-r--r-- | src/share/vm/prims/jvmtiEnvBase.cpp | 38 | ||||
-rw-r--r-- | src/share/vm/prims/jvmtiEnvBase.hpp | 2 | ||||
-rw-r--r-- | src/share/vm/prims/jvmtiEventController.cpp | 6 | ||||
-rw-r--r-- | src/share/vm/prims/jvmtiExport.cpp | 6 | ||||
-rw-r--r-- | src/share/vm/prims/jvmtiImpl.cpp | 29 | ||||
-rw-r--r-- | src/share/vm/prims/jvmtiImpl.hpp | 2 | ||||
-rw-r--r-- | src/share/vm/prims/jvmtiRedefineClasses.cpp | 31 | ||||
-rw-r--r-- | src/share/vm/prims/jvmtiRedefineClassesTrace.hpp | 4 | ||||
-rw-r--r-- | src/share/vm/prims/jvmtiThreadState.hpp | 7 |
10 files changed, 121 insertions, 25 deletions
diff --git a/src/share/vm/prims/jvmtiEnv.cpp b/src/share/vm/prims/jvmtiEnv.cpp index a19c48972..95977f009 100644 --- a/src/share/vm/prims/jvmtiEnv.cpp +++ b/src/share/vm/prims/jvmtiEnv.cpp @@ -99,6 +99,9 @@ JvmtiEnv::SetThreadLocalStorage(JavaThread* java_thread, const void* data) { } // otherwise, create the state state = JvmtiThreadState::state_for(java_thread); + if (state == NULL) { + return JVMTI_ERROR_THREAD_NOT_ALIVE; + } } state->env_thread_state(this)->set_agent_thread_local_storage_data((void*)data); return JVMTI_ERROR_NONE; @@ -1308,6 +1311,9 @@ JvmtiEnv::GetFrameCount(JavaThread* java_thread, jint* count_ptr) { // retrieve or create JvmtiThreadState. JvmtiThreadState* state = JvmtiThreadState::state_for(java_thread); + if (state == NULL) { + return JVMTI_ERROR_THREAD_NOT_ALIVE; + } uint32_t debug_bits = 0; if (is_thread_fully_suspended(java_thread, true, &debug_bits)) { err = get_frame_count(state, count_ptr); @@ -1329,6 +1335,12 @@ JvmtiEnv::PopFrame(JavaThread* java_thread) { HandleMark hm(current_thread); uint32_t debug_bits = 0; + // retrieve or create the state + JvmtiThreadState* state = JvmtiThreadState::state_for(java_thread); + if (state == NULL) { + return JVMTI_ERROR_THREAD_NOT_ALIVE; + } + // Check if java_thread is fully suspended if (!is_thread_fully_suspended(java_thread, true /* wait for suspend completion */, &debug_bits)) { return JVMTI_ERROR_THREAD_NOT_SUSPENDED; @@ -1399,9 +1411,6 @@ JvmtiEnv::PopFrame(JavaThread* java_thread) { // It's fine to update the thread state here because no JVMTI events // shall be posted for this PopFrame. - // retreive or create the state - JvmtiThreadState* state = JvmtiThreadState::state_for(java_thread); - state->update_for_pop_top_frame(); java_thread->set_popframe_condition(JavaThread::popframe_pending_bit); // Set pending step flag for this popframe and it is cleared when next @@ -1445,6 +1454,11 @@ JvmtiEnv::NotifyFramePop(JavaThread* java_thread, jint depth) { ResourceMark rm; uint32_t debug_bits = 0; + JvmtiThreadState *state = JvmtiThreadState::state_for(java_thread); + if (state == NULL) { + return JVMTI_ERROR_THREAD_NOT_ALIVE; + } + if (!JvmtiEnv::is_thread_fully_suspended(java_thread, true, &debug_bits)) { return JVMTI_ERROR_THREAD_NOT_SUSPENDED; } @@ -1464,7 +1478,6 @@ JvmtiEnv::NotifyFramePop(JavaThread* java_thread, jint depth) { assert(vf->frame_pointer() != NULL, "frame pointer mustn't be NULL"); - JvmtiThreadState *state = JvmtiThreadState::state_for(java_thread); int frame_number = state->count_frames() - depth; state->env_thread_state(this)->set_frame_pop(frame_number); diff --git a/src/share/vm/prims/jvmtiEnvBase.cpp b/src/share/vm/prims/jvmtiEnvBase.cpp index 3152e91c3..c0c98f01e 100644 --- a/src/share/vm/prims/jvmtiEnvBase.cpp +++ b/src/share/vm/prims/jvmtiEnvBase.cpp @@ -94,6 +94,35 @@ JvmtiEnvBase::initialize() { } +bool +JvmtiEnvBase::is_valid() { + jint value = 0; + + // This object might not be a JvmtiEnvBase so we can't assume + // the _magic field is properly aligned. Get the value in a safe + // way and then check against JVMTI_MAGIC. + + switch (sizeof(_magic)) { + case 2: + value = Bytes::get_native_u2((address)&_magic); + break; + + case 4: + value = Bytes::get_native_u4((address)&_magic); + break; + + case 8: + value = Bytes::get_native_u8((address)&_magic); + break; + + default: + guarantee(false, "_magic field is an unexpected size"); + } + + return value == JVMTI_MAGIC; +} + + JvmtiEnvBase::JvmtiEnvBase() : _env_event_enable() { _env_local_storage = NULL; _tag_map = NULL; @@ -1322,6 +1351,12 @@ JvmtiEnvBase::force_early_return(JavaThread* java_thread, jvalue value, TosState HandleMark hm(current_thread); uint32_t debug_bits = 0; + // retrieve or create the state + JvmtiThreadState* state = JvmtiThreadState::state_for(java_thread); + if (state == NULL) { + return JVMTI_ERROR_THREAD_NOT_ALIVE; + } + // Check if java_thread is fully suspended if (!is_thread_fully_suspended(java_thread, true /* wait for suspend completion */, @@ -1329,9 +1364,6 @@ JvmtiEnvBase::force_early_return(JavaThread* java_thread, jvalue value, TosState return JVMTI_ERROR_THREAD_NOT_SUSPENDED; } - // retreive or create the state - JvmtiThreadState* state = JvmtiThreadState::state_for(java_thread); - // Check to see if a ForceEarlyReturn was already in progress if (state->is_earlyret_pending()) { // Probably possible for JVMTI clients to trigger this, but the diff --git a/src/share/vm/prims/jvmtiEnvBase.hpp b/src/share/vm/prims/jvmtiEnvBase.hpp index 477725ffe..e6dd31e58 100644 --- a/src/share/vm/prims/jvmtiEnvBase.hpp +++ b/src/share/vm/prims/jvmtiEnvBase.hpp @@ -120,7 +120,7 @@ class JvmtiEnvBase : public CHeapObj { public: - bool is_valid() { return _magic == JVMTI_MAGIC; } + bool is_valid(); bool is_retransformable() { return _is_retransformable; } diff --git a/src/share/vm/prims/jvmtiEventController.cpp b/src/share/vm/prims/jvmtiEventController.cpp index ebadd45e2..4e07d6f84 100644 --- a/src/share/vm/prims/jvmtiEventController.cpp +++ b/src/share/vm/prims/jvmtiEventController.cpp @@ -478,6 +478,11 @@ JvmtiEventControllerPrivate::recompute_env_thread_enabled(JvmtiEnvThreadState* e // set external state accordingly. Only thread-filtered events are included. jlong JvmtiEventControllerPrivate::recompute_thread_enabled(JvmtiThreadState *state) { + if (state == NULL) { + // associated JavaThread is exiting + return (jlong)0; + } + jlong was_any_env_enabled = state->thread_event_enable()->_event_enabled.get_bits(); jlong any_env_enabled = 0; @@ -553,6 +558,7 @@ JvmtiEventControllerPrivate::recompute_enabled() { { MutexLocker mu(Threads_lock); //hold the Threads_lock for the iteration for (JavaThread *tp = Threads::first(); tp != NULL; tp = tp->next()) { + // state_for_while_locked() makes tp->is_exiting() check JvmtiThreadState::state_for_while_locked(tp); // create the thread state if missing } }// release Threads_lock diff --git a/src/share/vm/prims/jvmtiExport.cpp b/src/share/vm/prims/jvmtiExport.cpp index a3894b3d6..50ecb4b95 100644 --- a/src/share/vm/prims/jvmtiExport.cpp +++ b/src/share/vm/prims/jvmtiExport.cpp @@ -1872,6 +1872,9 @@ void JvmtiExport::post_dynamic_code_generated_while_holding_locks(const char* na { // register the stub with the current dynamic code event collector JvmtiThreadState* state = JvmtiThreadState::state_for(JavaThread::current()); + // state can only be NULL if the current thread is exiting which + // should not happen since we're trying to post an event + guarantee(state != NULL, "attempt to register stub via an exiting thread"); JvmtiDynamicCodeEventCollector* collector = state->get_dynamic_code_event_collector(); guarantee(collector != NULL, "attempt to register stub without event collector"); collector->register_stub(name, code_begin, code_end); @@ -2253,6 +2256,9 @@ void JvmtiExport::cms_ref_processing_epilogue() { void JvmtiEventCollector::setup_jvmti_thread_state() { // set this event collector to be the current one. JvmtiThreadState* state = JvmtiThreadState::state_for(JavaThread::current()); + // state can only be NULL if the current thread is exiting which + // should not happen since we're trying to configure for event collection + guarantee(state != NULL, "exiting thread called setup_jvmti_thread_state"); if (is_vm_object_alloc_event()) { _prev = state->get_vm_object_alloc_event_collector(); state->set_vm_object_alloc_event_collector((JvmtiVMObjectAllocEventCollector *)this); diff --git a/src/share/vm/prims/jvmtiImpl.cpp b/src/share/vm/prims/jvmtiImpl.cpp index f9a512c42..5a174b35b 100644 --- a/src/share/vm/prims/jvmtiImpl.cpp +++ b/src/share/vm/prims/jvmtiImpl.cpp @@ -238,6 +238,35 @@ JvmtiRawMonitor::~JvmtiRawMonitor() { } +bool +JvmtiRawMonitor::is_valid() { + int value = 0; + + // This object might not be a JvmtiRawMonitor so we can't assume + // the _magic field is properly aligned. Get the value in a safe + // way and then check against JVMTI_RM_MAGIC. + + switch (sizeof(_magic)) { + case 2: + value = Bytes::get_native_u2((address)&_magic); + break; + + case 4: + value = Bytes::get_native_u4((address)&_magic); + break; + + case 8: + value = Bytes::get_native_u8((address)&_magic); + break; + + default: + guarantee(false, "_magic field is an unexpected size"); + } + + return value == JVMTI_RM_MAGIC; +} + + // // class JvmtiBreakpoint // diff --git a/src/share/vm/prims/jvmtiImpl.hpp b/src/share/vm/prims/jvmtiImpl.hpp index d1b8414e6..2605546c6 100644 --- a/src/share/vm/prims/jvmtiImpl.hpp +++ b/src/share/vm/prims/jvmtiImpl.hpp @@ -349,7 +349,7 @@ public: ~JvmtiRawMonitor(); int magic() { return _magic; } const char *get_name() { return _name; } - bool is_valid() { return _magic == JVMTI_RM_MAGIC; } + bool is_valid(); }; // Onload pending raw monitors diff --git a/src/share/vm/prims/jvmtiRedefineClasses.cpp b/src/share/vm/prims/jvmtiRedefineClasses.cpp index ad832c35d..ba9b1d877 100644 --- a/src/share/vm/prims/jvmtiRedefineClasses.cpp +++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp @@ -831,6 +831,9 @@ jvmtiError VM_RedefineClasses::load_new_class_versions(TRAPS) { ResourceMark rm(THREAD); JvmtiThreadState *state = JvmtiThreadState::state_for(JavaThread::current()); + // state can only be NULL if the current thread is exiting which + // should not happen since we're trying to do a RedefineClasses + guarantee(state != NULL, "exiting thread calling load_new_class_versions"); for (int i = 0; i < _class_count; i++) { oop mirror = JNIHandles::resolve_non_null(_class_defs[i].klass); // classes for primitives cannot be redefined @@ -1349,39 +1352,39 @@ bool VM_RedefineClasses::rewrite_cp_refs(instanceKlassHandle scratch_class, // rewrite constant pool references in the methods: if (!rewrite_cp_refs_in_methods(scratch_class, THREAD)) { - // propogate failure back to caller + // propagate failure back to caller return false; } // rewrite constant pool references in the class_annotations: if (!rewrite_cp_refs_in_class_annotations(scratch_class, THREAD)) { - // propogate failure back to caller + // propagate failure back to caller return false; } // rewrite constant pool references in the fields_annotations: if (!rewrite_cp_refs_in_fields_annotations(scratch_class, THREAD)) { - // propogate failure back to caller + // propagate failure back to caller return false; } // rewrite constant pool references in the methods_annotations: if (!rewrite_cp_refs_in_methods_annotations(scratch_class, THREAD)) { - // propogate failure back to caller + // propagate failure back to caller return false; } // rewrite constant pool references in the methods_parameter_annotations: if (!rewrite_cp_refs_in_methods_parameter_annotations(scratch_class, THREAD)) { - // propogate failure back to caller + // propagate failure back to caller return false; } // rewrite constant pool references in the methods_default_annotations: if (!rewrite_cp_refs_in_methods_default_annotations(scratch_class, THREAD)) { - // propogate failure back to caller + // propagate failure back to caller return false; } @@ -1600,7 +1603,7 @@ bool VM_RedefineClasses::rewrite_cp_refs_in_annotations_typeArray( byte_i_ref, THREAD)) { RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("bad annotation_struct at %d", calc_num_annotations)); - // propogate failure back to caller + // propagate failure back to caller return false; } } @@ -1666,7 +1669,7 @@ bool VM_RedefineClasses::rewrite_cp_refs_in_annotation_struct( byte_i_ref, THREAD)) { RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("bad element_value at %d", calc_num_element_value_pairs)); - // propogate failure back to caller + // propagate failure back to caller return false; } } // end for each component @@ -1815,7 +1818,7 @@ bool VM_RedefineClasses::rewrite_cp_refs_in_element_value( // field. This is a nested annotation. if (!rewrite_cp_refs_in_annotation_struct(annotations_typeArray, byte_i_ref, THREAD)) { - // propogate failure back to caller + // propagate failure back to caller return false; } break; @@ -1842,7 +1845,7 @@ bool VM_RedefineClasses::rewrite_cp_refs_in_element_value( annotations_typeArray, byte_i_ref, THREAD)) { RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("bad nested element_value at %d", calc_num_values)); - // propogate failure back to caller + // propagate failure back to caller return false; } } @@ -1886,7 +1889,7 @@ bool VM_RedefineClasses::rewrite_cp_refs_in_fields_annotations( THREAD)) { RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("bad field_annotations at %d", i)); - // propogate failure back to caller + // propagate failure back to caller return false; } } @@ -1923,7 +1926,7 @@ bool VM_RedefineClasses::rewrite_cp_refs_in_methods_annotations( THREAD)) { RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("bad method_annotations at %d", i)); - // propogate failure back to caller + // propagate failure back to caller return false; } } @@ -1991,7 +1994,7 @@ bool VM_RedefineClasses::rewrite_cp_refs_in_methods_parameter_annotations( method_parameter_annotations, byte_i, THREAD)) { RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("bad method_parameter_annotations at %d", calc_num_parameters)); - // propogate failure back to caller + // propagate failure back to caller return false; } } @@ -2041,7 +2044,7 @@ bool VM_RedefineClasses::rewrite_cp_refs_in_methods_default_annotations( method_default_annotations, byte_i, THREAD)) { RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("bad default element_value at %d", i)); - // propogate failure back to caller + // propagate failure back to caller return false; } } diff --git a/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp b/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp index 83192cf16..6762e572b 100644 --- a/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp +++ b/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp @@ -49,8 +49,8 @@ // 0x00000400 | 1024 - previous class weak reference mgmt during // add previous ops (GC) // 0x00000800 | 2048 - previous class breakpoint mgmt -// 0x00001000 | 4096 - unused -// 0x00002000 | 8192 - unused +// 0x00001000 | 4096 - detect calls to obsolete methods +// 0x00002000 | 8192 - fail a guarantee() in addition to detection // 0x00004000 | 16384 - unused // 0x00008000 | 32768 - old/new method matching/add/delete // 0x00010000 | 65536 - impl details: CP size info diff --git a/src/share/vm/prims/jvmtiThreadState.hpp b/src/share/vm/prims/jvmtiThreadState.hpp index 703d87339..d77d2a8a4 100644 --- a/src/share/vm/prims/jvmtiThreadState.hpp +++ b/src/share/vm/prims/jvmtiThreadState.hpp @@ -314,17 +314,24 @@ class JvmtiThreadState : public CHeapObj { void update_for_pop_top_frame(); // already holding JvmtiThreadState_lock - retrieve or create JvmtiThreadState + // Can return NULL if JavaThread is exiting. inline static JvmtiThreadState *state_for_while_locked(JavaThread *thread) { assert(JvmtiThreadState_lock->is_locked(), "sanity check"); JvmtiThreadState *state = thread->jvmti_thread_state(); if (state == NULL) { + if (thread->is_exiting()) { + // don't add a JvmtiThreadState to a thread that is exiting + return NULL; + } + state = new JvmtiThreadState(thread); } return state; } // retrieve or create JvmtiThreadState + // Can return NULL if JavaThread is exiting. inline static JvmtiThreadState *state_for(JavaThread *thread) { JvmtiThreadState *state = thread->jvmti_thread_state(); if (state == NULL) { |