duke@435: /* trims@1907: * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * trims@1907: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA trims@1907: * or visit www.oracle.com if you need additional information or have any trims@1907: * questions. duke@435: * duke@435: */ duke@435: duke@435: # include "incls/_precompiled.incl" duke@435: # include "incls/_jvmtiThreadState.cpp.incl" duke@435: duke@435: // marker for when the stack depth has been reset and is now unknown. duke@435: // any negative number would work but small ones might obscure an duke@435: // underrun error. duke@435: static const int UNKNOWN_STACK_DEPTH = -99; duke@435: duke@435: /////////////////////////////////////////////////////////////// duke@435: // duke@435: // class JvmtiThreadState duke@435: // duke@435: // Instances of JvmtiThreadState hang off of each thread. duke@435: // Thread local storage for JVMTI. duke@435: // duke@435: duke@435: JvmtiThreadState *JvmtiThreadState::_head = NULL; duke@435: duke@435: JvmtiThreadState::JvmtiThreadState(JavaThread* thread) duke@435: : _thread_event_enable() { duke@435: assert(JvmtiThreadState_lock->is_locked(), "sanity check"); duke@435: _thread = thread; duke@435: _exception_detected = false; duke@435: _exception_caught = false; duke@435: _debuggable = true; duke@435: _hide_single_stepping = false; duke@435: _hide_level = 0; duke@435: _pending_step_for_popframe = false; duke@435: _class_being_redefined = NULL; duke@435: _class_load_kind = jvmti_class_load_kind_load; duke@435: _head_env_thread_state = NULL; duke@435: _dynamic_code_event_collector = NULL; duke@435: _vm_object_alloc_event_collector = NULL; duke@435: _the_class_for_redefinition_verification = NULL; duke@435: _scratch_class_for_redefinition_verification = NULL; duke@435: duke@435: // JVMTI ForceEarlyReturn support duke@435: _pending_step_for_earlyret = false; duke@435: _earlyret_state = earlyret_inactive; duke@435: _earlyret_tos = ilgl; duke@435: _earlyret_value.j = 0L; duke@435: _earlyret_oop = NULL; duke@435: duke@435: // add all the JvmtiEnvThreadState to the new JvmtiThreadState duke@435: { duke@435: JvmtiEnvIterator it; duke@435: for (JvmtiEnvBase* env = it.first(); env != NULL; env = it.next(env)) { duke@435: if (env->is_valid()) { duke@435: add_env(env); duke@435: } duke@435: } duke@435: } duke@435: duke@435: // link us into the list duke@435: { duke@435: // The thread state list manipulation code must not have safepoints. duke@435: // See periodic_clean_up(). duke@435: debug_only(No_Safepoint_Verifier nosafepoint;) duke@435: duke@435: _prev = NULL; duke@435: _next = _head; duke@435: if (_head != NULL) { duke@435: _head->_prev = this; duke@435: } duke@435: _head = this; duke@435: } duke@435: duke@435: // set this as the state for the thread duke@435: thread->set_jvmti_thread_state(this); duke@435: } duke@435: duke@435: duke@435: JvmtiThreadState::~JvmtiThreadState() { duke@435: assert(JvmtiThreadState_lock->is_locked(), "sanity check"); duke@435: duke@435: // clear this as the state for the thread duke@435: get_thread()->set_jvmti_thread_state(NULL); duke@435: duke@435: // zap our env thread states duke@435: { duke@435: JvmtiEnvBase::entering_dying_thread_env_iteration(); duke@435: JvmtiEnvThreadStateIterator it(this); duke@435: for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ) { duke@435: JvmtiEnvThreadState* zap = ets; duke@435: ets = it.next(ets); duke@435: delete zap; duke@435: } duke@435: JvmtiEnvBase::leaving_dying_thread_env_iteration(); duke@435: } duke@435: duke@435: // remove us from the list duke@435: { duke@435: // The thread state list manipulation code must not have safepoints. duke@435: // See periodic_clean_up(). duke@435: debug_only(No_Safepoint_Verifier nosafepoint;) duke@435: duke@435: if (_prev == NULL) { duke@435: assert(_head == this, "sanity check"); duke@435: _head = _next; duke@435: } else { duke@435: assert(_head != this, "sanity check"); duke@435: _prev->_next = _next; duke@435: } duke@435: if (_next != NULL) { duke@435: _next->_prev = _prev; duke@435: } duke@435: _next = NULL; duke@435: _prev = NULL; duke@435: } duke@435: } duke@435: duke@435: duke@435: void duke@435: JvmtiThreadState::periodic_clean_up() { duke@435: assert(SafepointSynchronize::is_at_safepoint(), "at safepoint"); duke@435: duke@435: // This iteration is initialized with "_head" instead of "JvmtiThreadState::first()" duke@435: // because the latter requires the JvmtiThreadState_lock. duke@435: // This iteration is safe at a safepoint as well, see the No_Safepoint_Verifier duke@435: // asserts at all list manipulation sites. duke@435: for (JvmtiThreadState *state = _head; state != NULL; state = state->next()) { duke@435: // For each environment thread state corresponding to an invalid environment duke@435: // unlink it from the list and deallocate it. duke@435: JvmtiEnvThreadStateIterator it(state); duke@435: JvmtiEnvThreadState* previous_ets = NULL; duke@435: JvmtiEnvThreadState* ets = it.first(); duke@435: while (ets != NULL) { duke@435: if (ets->get_env()->is_valid()) { duke@435: previous_ets = ets; duke@435: ets = it.next(ets); duke@435: } else { duke@435: // This one isn't valid, remove it from the list and deallocate it duke@435: JvmtiEnvThreadState* defunct_ets = ets; duke@435: ets = ets->next(); duke@435: if (previous_ets == NULL) { duke@435: assert(state->head_env_thread_state() == defunct_ets, "sanity check"); duke@435: state->set_head_env_thread_state(ets); duke@435: } else { duke@435: previous_ets->set_next(ets); duke@435: } duke@435: delete defunct_ets; duke@435: } duke@435: } duke@435: } duke@435: } duke@435: duke@435: void JvmtiThreadState::add_env(JvmtiEnvBase *env) { duke@435: assert(JvmtiThreadState_lock->is_locked(), "sanity check"); duke@435: duke@435: JvmtiEnvThreadState *new_ets = new JvmtiEnvThreadState(_thread, env); duke@435: // add this environment thread state to the end of the list (order is important) duke@435: { duke@435: // list deallocation (which occurs at a safepoint) cannot occur simultaneously duke@435: debug_only(No_Safepoint_Verifier nosafepoint;) duke@435: duke@435: JvmtiEnvThreadStateIterator it(this); duke@435: JvmtiEnvThreadState* previous_ets = NULL; duke@435: for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { duke@435: previous_ets = ets; duke@435: } duke@435: if (previous_ets == NULL) { duke@435: set_head_env_thread_state(new_ets); duke@435: } else { duke@435: previous_ets->set_next(new_ets); duke@435: } duke@435: } duke@435: } duke@435: duke@435: duke@435: duke@435: duke@435: void JvmtiThreadState::enter_interp_only_mode() { duke@435: assert(_thread->get_interp_only_mode() == 0, "entering interp only when mode not zero"); duke@435: _thread->increment_interp_only_mode(); duke@435: } duke@435: duke@435: duke@435: void JvmtiThreadState::leave_interp_only_mode() { duke@435: assert(_thread->get_interp_only_mode() == 1, "leaving interp only when mode not one"); duke@435: _thread->decrement_interp_only_mode(); duke@435: } duke@435: duke@435: duke@435: // Helper routine used in several places duke@435: int JvmtiThreadState::count_frames() { duke@435: #ifdef ASSERT duke@435: uint32_t debug_bits = 0; duke@435: #endif duke@435: assert(SafepointSynchronize::is_at_safepoint() || duke@435: JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits), duke@435: "at safepoint or must be suspended"); duke@435: duke@435: if (!get_thread()->has_last_Java_frame()) return 0; // no Java frames duke@435: duke@435: ResourceMark rm; duke@435: RegisterMap reg_map(get_thread()); duke@435: javaVFrame *jvf = get_thread()->last_java_vframe(®_map); duke@435: int n = 0; duke@435: // tty->print_cr("CSD: counting frames on %s ...", duke@435: // JvmtiTrace::safe_get_thread_name(get_thread())); duke@435: while (jvf != NULL) { duke@435: methodOop method = jvf->method(); duke@435: // tty->print_cr("CSD: frame - method %s.%s - loc %d", duke@435: // method->klass_name()->as_C_string(), duke@435: // method->name()->as_C_string(), duke@435: // jvf->bci() ); duke@435: jvf = jvf->java_sender(); duke@435: n++; duke@435: } duke@435: // tty->print_cr("CSD: frame count: %d", n); duke@435: return n; duke@435: } duke@435: duke@435: duke@435: void JvmtiThreadState::invalidate_cur_stack_depth() { duke@435: Thread *cur = Thread::current(); duke@435: uint32_t debug_bits = 0; duke@435: duke@435: // The caller can be the VMThread at a safepoint, the current thread duke@435: // or the target thread must be suspended. duke@435: guarantee((cur->is_VM_thread() && SafepointSynchronize::is_at_safepoint()) || duke@435: (JavaThread *)cur == get_thread() || duke@435: JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits), duke@435: "sanity check"); duke@435: duke@435: _cur_stack_depth = UNKNOWN_STACK_DEPTH; duke@435: } duke@435: duke@435: void JvmtiThreadState::incr_cur_stack_depth() { duke@435: guarantee(JavaThread::current() == get_thread(), "must be current thread"); duke@435: duke@435: if (!is_interp_only_mode()) { duke@435: _cur_stack_depth = UNKNOWN_STACK_DEPTH; duke@435: } duke@435: if (_cur_stack_depth != UNKNOWN_STACK_DEPTH) { duke@435: ++_cur_stack_depth; duke@435: } duke@435: } duke@435: duke@435: void JvmtiThreadState::decr_cur_stack_depth() { duke@435: guarantee(JavaThread::current() == get_thread(), "must be current thread"); duke@435: duke@435: if (!is_interp_only_mode()) { duke@435: _cur_stack_depth = UNKNOWN_STACK_DEPTH; duke@435: } duke@435: if (_cur_stack_depth != UNKNOWN_STACK_DEPTH) { duke@435: --_cur_stack_depth; duke@435: assert(_cur_stack_depth >= 0, "incr/decr_cur_stack_depth mismatch"); duke@435: } duke@435: } duke@435: duke@435: int JvmtiThreadState::cur_stack_depth() { duke@435: uint32_t debug_bits = 0; duke@435: guarantee(JavaThread::current() == get_thread() || duke@435: JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits), duke@435: "must be current thread or suspended"); duke@435: duke@435: if (!is_interp_only_mode() || _cur_stack_depth == UNKNOWN_STACK_DEPTH) { duke@435: _cur_stack_depth = count_frames(); duke@435: } else { duke@435: // heavy weight assert duke@435: assert(_cur_stack_depth == count_frames(), duke@435: "cur_stack_depth out of sync"); duke@435: } duke@435: return _cur_stack_depth; duke@435: } duke@435: duke@435: bool JvmtiThreadState::may_be_walked() { duke@435: return (get_thread()->is_being_ext_suspended() || (JavaThread::current() == get_thread())); duke@435: } duke@435: duke@435: duke@435: void JvmtiThreadState::process_pending_step_for_popframe() { duke@435: // We are single stepping as the last part of the PopFrame() dance duke@435: // so we have some house keeping to do. duke@435: duke@435: JavaThread *thr = get_thread(); duke@435: if (thr->popframe_condition() != JavaThread::popframe_inactive) { duke@435: // If the popframe_condition field is not popframe_inactive, then duke@435: // we missed all of the popframe_field cleanup points: duke@435: // duke@435: // - unpack_frames() was not called (nothing to deopt) duke@435: // - remove_activation_preserving_args_entry() was not called duke@435: // (did not get suspended in a call_vm() family call and did duke@435: // not complete a call_vm() family call on the way here) duke@435: thr->clear_popframe_condition(); duke@435: } duke@435: duke@435: // clearing the flag indicates we are done with the PopFrame() dance duke@435: clr_pending_step_for_popframe(); duke@435: duke@435: // If step is pending for popframe then it may not be duke@435: // a repeat step. The new_bci and method_id is same as current_bci duke@435: // and current method_id after pop and step for recursive calls. duke@435: // Force the step by clearing the last location. duke@435: JvmtiEnvThreadStateIterator it(this); duke@435: for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { duke@435: ets->clear_current_location(); duke@435: } duke@435: } duke@435: duke@435: duke@435: // Class: JvmtiThreadState duke@435: // Function: update_for_pop_top_frame duke@435: // Description: duke@435: // This function removes any frame pop notification request for duke@435: // the top frame and invalidates both the current stack depth and duke@435: // all cached frameIDs. duke@435: // duke@435: // Called by: PopFrame duke@435: // duke@435: void JvmtiThreadState::update_for_pop_top_frame() { duke@435: if (is_interp_only_mode()) { duke@435: // remove any frame pop notification request for the top frame duke@435: // in any environment duke@435: int popframe_number = cur_stack_depth(); duke@435: { duke@435: JvmtiEnvThreadStateIterator it(this); duke@435: for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { duke@435: if (ets->is_frame_pop(popframe_number)) { duke@435: ets->clear_frame_pop(popframe_number); duke@435: } duke@435: } duke@435: } duke@435: // force stack depth to be recalculated duke@435: invalidate_cur_stack_depth(); duke@435: } else { duke@435: assert(!is_enabled(JVMTI_EVENT_FRAME_POP), "Must have no framepops set"); duke@435: } duke@435: } duke@435: duke@435: duke@435: void JvmtiThreadState::process_pending_step_for_earlyret() { duke@435: // We are single stepping as the last part of the ForceEarlyReturn duke@435: // dance so we have some house keeping to do. duke@435: duke@435: if (is_earlyret_pending()) { duke@435: // If the earlyret_state field is not earlyret_inactive, then duke@435: // we missed all of the earlyret_field cleanup points: duke@435: // duke@435: // - remove_activation() was not called duke@435: // (did not get suspended in a call_vm() family call and did duke@435: // not complete a call_vm() family call on the way here) duke@435: // duke@435: // One legitimate way for us to miss all the cleanup points is duke@435: // if we got here right after handling a compiled return. If that duke@435: // is the case, then we consider our return from compiled code to duke@435: // complete the ForceEarlyReturn request and we clear the condition. duke@435: clr_earlyret_pending(); duke@435: set_earlyret_oop(NULL); duke@435: clr_earlyret_value(); duke@435: } duke@435: duke@435: // clearing the flag indicates we are done with duke@435: // the ForceEarlyReturn() dance duke@435: clr_pending_step_for_earlyret(); duke@435: duke@435: // If step is pending for earlyret then it may not be a repeat step. duke@435: // The new_bci and method_id is same as current_bci and current duke@435: // method_id after earlyret and step for recursive calls. duke@435: // Force the step by clearing the last location. duke@435: JvmtiEnvThreadStateIterator it(this); duke@435: for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { duke@435: ets->clear_current_location(); duke@435: } duke@435: } duke@435: duke@435: void JvmtiThreadState::oops_do(OopClosure* f) { duke@435: f->do_oop((oop*) &_earlyret_oop); duke@435: }