Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/prims/jvmtiEnvThreadState.cpp
32285 views
/*1* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "classfile/systemDictionary.hpp"26#include "interpreter/interpreter.hpp"27#include "jvmtifiles/jvmtiEnv.hpp"28#include "memory/resourceArea.hpp"29#include "prims/jvmtiEnvThreadState.hpp"30#include "prims/jvmtiEventController.inline.hpp"31#include "prims/jvmtiImpl.hpp"32#include "runtime/handles.hpp"33#include "runtime/handles.inline.hpp"34#include "runtime/interfaceSupport.hpp"35#include "runtime/javaCalls.hpp"36#include "runtime/signature.hpp"37#include "runtime/vframe.hpp"38#include "runtime/vm_operations.hpp"394041///////////////////////////////////////////////////////////////42//43// class JvmtiFramePop44//4546#ifndef PRODUCT47void JvmtiFramePop::print() {48tty->print_cr("_frame_number=%d", _frame_number);49}50#endif515253///////////////////////////////////////////////////////////////54//55// class JvmtiFramePops - private methods56//5758void59JvmtiFramePops::set(JvmtiFramePop& fp) {60if (_pops->find(fp.frame_number()) < 0) {61_pops->append(fp.frame_number());62}63}646566void67JvmtiFramePops::clear(JvmtiFramePop& fp) {68assert(_pops->length() > 0, "No more frame pops");6970_pops->remove(fp.frame_number());71}727374int75JvmtiFramePops::clear_to(JvmtiFramePop& fp) {76int cleared = 0;77int index = 0;78while (index < _pops->length()) {79JvmtiFramePop pop = JvmtiFramePop(_pops->at(index));80if (pop.above_on_stack(fp)) {81_pops->remove_at(index);82++cleared;83} else {84++index;85}86}87return cleared;88}899091///////////////////////////////////////////////////////////////92//93// class JvmtiFramePops - public methods94//9596JvmtiFramePops::JvmtiFramePops() {97_pops = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<int> (2, true);98}99100JvmtiFramePops::~JvmtiFramePops() {101// return memory to c_heap.102delete _pops;103}104105106#ifndef PRODUCT107void JvmtiFramePops::print() {108ResourceMark rm;109110int n = _pops->length();111for (int i=0; i<n; i++) {112JvmtiFramePop fp = JvmtiFramePop(_pops->at(i));113tty->print("%d: ", i);114fp.print();115tty->cr();116}117}118#endif119120///////////////////////////////////////////////////////////////121//122// class JvmtiEnvThreadState123//124// Instances of JvmtiEnvThreadState hang off of each JvmtiThreadState,125// one per JvmtiEnv.126//127128JvmtiEnvThreadState::JvmtiEnvThreadState(JavaThread *thread, JvmtiEnvBase *env) :129_event_enable() {130_thread = thread;131_env = (JvmtiEnv*)env;132_next = NULL;133_frame_pops = NULL;134_current_bci = 0;135_current_method_id = NULL;136_breakpoint_posted = false;137_single_stepping_posted = false;138_agent_thread_local_storage_data = NULL;139}140141JvmtiEnvThreadState::~JvmtiEnvThreadState() {142delete _frame_pops;143_frame_pops = NULL;144}145146// Given that a new (potential) event has come in,147// maintain the current JVMTI location on a per-thread per-env basis148// and use it to filter out duplicate events:149// - instruction rewrites150// - breakpoint followed by single step151// - single step at a breakpoint152void JvmtiEnvThreadState::compare_and_set_current_location(Method* new_method,153address new_location, jvmtiEvent event) {154155int new_bci = new_location - new_method->code_base();156157// The method is identified and stored as a jmethodID which is safe in this158// case because the class cannot be unloaded while a method is executing.159jmethodID new_method_id = new_method->jmethod_id();160161// the last breakpoint or single step was at this same location162if (_current_bci == new_bci && _current_method_id == new_method_id) {163switch (event) {164case JVMTI_EVENT_BREAKPOINT:165// Repeat breakpoint is complicated. If we previously posted a breakpoint166// event at this location and if we also single stepped at this location167// then we skip the duplicate breakpoint.168_breakpoint_posted = _breakpoint_posted && _single_stepping_posted;169break;170case JVMTI_EVENT_SINGLE_STEP:171// Repeat single step is easy: just don't post it again.172// If step is pending for popframe then it may not be173// a repeat step. The new_bci and method_id is same as current_bci174// and current method_id after pop and step for recursive calls.175// This has been handled by clearing the location176_single_stepping_posted = true;177break;178default:179assert(false, "invalid event value passed");180break;181}182return;183}184185set_current_location(new_method_id, new_bci);186_breakpoint_posted = false;187_single_stepping_posted = false;188}189190191JvmtiFramePops* JvmtiEnvThreadState::get_frame_pops() {192#ifdef ASSERT193uint32_t debug_bits = 0;194#endif195assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),196"frame pop data only accessible from same thread or while suspended");197198if (_frame_pops == NULL) {199_frame_pops = new JvmtiFramePops();200assert(_frame_pops != NULL, "_frame_pops != NULL");201}202return _frame_pops;203}204205206bool JvmtiEnvThreadState::has_frame_pops() {207return _frame_pops == NULL? false : (_frame_pops->length() > 0);208}209210void JvmtiEnvThreadState::set_frame_pop(int frame_number) {211#ifdef ASSERT212uint32_t debug_bits = 0;213#endif214assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),215"frame pop data only accessible from same thread or while suspended");216JvmtiFramePop fpop(frame_number);217JvmtiEventController::set_frame_pop(this, fpop);218}219220221void JvmtiEnvThreadState::clear_frame_pop(int frame_number) {222#ifdef ASSERT223uint32_t debug_bits = 0;224#endif225assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),226"frame pop data only accessible from same thread or while suspended");227JvmtiFramePop fpop(frame_number);228JvmtiEventController::clear_frame_pop(this, fpop);229}230231232void JvmtiEnvThreadState::clear_to_frame_pop(int frame_number) {233#ifdef ASSERT234uint32_t debug_bits = 0;235#endif236assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),237"frame pop data only accessible from same thread or while suspended");238JvmtiFramePop fpop(frame_number);239JvmtiEventController::clear_to_frame_pop(this, fpop);240}241242243bool JvmtiEnvThreadState::is_frame_pop(int cur_frame_number) {244#ifdef ASSERT245uint32_t debug_bits = 0;246#endif247assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),248"frame pop data only accessible from same thread or while suspended");249if (!get_thread()->is_interp_only_mode() || _frame_pops == NULL) {250return false;251}252JvmtiFramePop fp(cur_frame_number);253return get_frame_pops()->contains(fp);254}255256257class VM_GetCurrentLocation : public VM_Operation {258private:259JavaThread *_thread;260jmethodID _method_id;261int _bci;262263public:264VM_GetCurrentLocation(JavaThread *thread) {265_thread = thread;266}267VMOp_Type type() const { return VMOp_GetCurrentLocation; }268void doit() {269ResourceMark rmark; // _thread != Thread::current()270RegisterMap rm(_thread, false);271// There can be a race condition between a VM_Operation reaching a safepoint272// and the target thread exiting from Java execution.273// We must recheck the last Java frame still exists.274if (!_thread->is_exiting() && _thread->has_last_Java_frame()) {275javaVFrame* vf = _thread->last_java_vframe(&rm);276assert(vf != NULL, "must have last java frame");277Method* method = vf->method();278_method_id = method->jmethod_id();279_bci = vf->bci();280} else {281// Clear current location as the target thread has no Java frames anymore.282_method_id = (jmethodID)NULL;283_bci = 0;284}285}286void get_current_location(jmethodID *method_id, int *bci) {287*method_id = _method_id;288*bci = _bci;289}290};291292void JvmtiEnvThreadState::reset_current_location(jvmtiEvent event_type, bool enabled) {293assert(event_type == JVMTI_EVENT_SINGLE_STEP || event_type == JVMTI_EVENT_BREAKPOINT,294"must be single-step or breakpoint event");295296// Current location is used to detect the following:297// 1) a breakpoint event followed by single-stepping to the same bci298// 2) single-step to a bytecode that will be transformed to a fast version299// We skip to avoid posting the duplicate single-stepping event.300301// If single-stepping is disabled, clear current location so that302// single-stepping to the same method and bcp at a later time will be303// detected if single-stepping is enabled at that time (see 4388912).304305// If single-stepping is enabled, set the current location to the306// current method and bcp. This covers the following type of case,307// e.g., the debugger stepi command:308// - bytecode single stepped309// - SINGLE_STEP event posted and SINGLE_STEP event disabled310// - SINGLE_STEP event reenabled311// - bytecode rewritten to fast version312313// If breakpoint event is disabled, clear current location only if314// single-stepping is not enabled. Otherwise, keep the thread location315// to detect any duplicate events.316317if (enabled) {318// If enabling breakpoint, no need to reset.319// Can't do anything if empty stack.320if (event_type == JVMTI_EVENT_SINGLE_STEP && _thread->has_last_Java_frame()) {321jmethodID method_id;322int bci;323// The java thread stack may not be walkable for a running thread324// so get current location at safepoint.325VM_GetCurrentLocation op(_thread);326VMThread::execute(&op);327op.get_current_location(&method_id, &bci);328set_current_location(method_id, bci);329}330} else if (event_type == JVMTI_EVENT_SINGLE_STEP || !is_enabled(JVMTI_EVENT_SINGLE_STEP)) {331// If this is to disable breakpoint, also check if single-step is not enabled332clear_current_location();333}334}335336337