Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/prims/jvmtiImpl.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 "interpreter/oopMapCache.hpp"28#include "jvmtifiles/jvmtiEnv.hpp"29#include "memory/resourceArea.hpp"30#include "oops/instanceKlass.hpp"31#include "prims/jvmtiAgentThread.hpp"32#include "prims/jvmtiEventController.inline.hpp"33#include "prims/jvmtiImpl.hpp"34#include "prims/jvmtiRedefineClasses.hpp"35#include "runtime/atomic.hpp"36#include "runtime/deoptimization.hpp"37#include "runtime/handles.hpp"38#include "runtime/handles.inline.hpp"39#include "runtime/interfaceSupport.hpp"40#include "runtime/javaCalls.hpp"41#include "runtime/os.hpp"42#include "runtime/serviceThread.hpp"43#include "runtime/signature.hpp"44#include "runtime/thread.inline.hpp"45#include "runtime/vframe.hpp"46#include "runtime/vframe_hp.hpp"47#include "runtime/vm_operations.hpp"48#include "utilities/exceptions.hpp"4950//51// class JvmtiAgentThread52//53// JavaThread used to wrap a thread started by an agent54// using the JVMTI method RunAgentThread.55//5657JvmtiAgentThread::JvmtiAgentThread(JvmtiEnv* env, jvmtiStartFunction start_fn, const void *start_arg)58: JavaThread(start_function_wrapper) {59_env = env;60_start_fn = start_fn;61_start_arg = start_arg;62}6364void65JvmtiAgentThread::start_function_wrapper(JavaThread *thread, TRAPS) {66// It is expected that any Agent threads will be created as67// Java Threads. If this is the case, notification of the creation68// of the thread is given in JavaThread::thread_main().69assert(thread->is_Java_thread(), "debugger thread should be a Java Thread");70assert(thread == JavaThread::current(), "sanity check");7172JvmtiAgentThread *dthread = (JvmtiAgentThread *)thread;73dthread->call_start_function();74}7576void77JvmtiAgentThread::call_start_function() {78ThreadToNativeFromVM transition(this);79_start_fn(_env->jvmti_external(), jni_environment(), (void*)_start_arg);80}818283//84// class GrowableCache - private methods85//8687void GrowableCache::recache() {88int len = _elements->length();8990FREE_C_HEAP_ARRAY(address, _cache, mtInternal);91_cache = NEW_C_HEAP_ARRAY(address,len+1, mtInternal);9293for (int i=0; i<len; i++) {94_cache[i] = _elements->at(i)->getCacheValue();95//96// The cache entry has gone bad. Without a valid frame pointer97// value, the entry is useless so we simply delete it in product98// mode. The call to remove() will rebuild the cache again99// without the bad entry.100//101if (_cache[i] == NULL) {102assert(false, "cannot recache NULL elements");103remove(i);104return;105}106}107_cache[len] = NULL;108109_listener_fun(_this_obj,_cache);110}111112bool GrowableCache::equals(void* v, GrowableElement *e2) {113GrowableElement *e1 = (GrowableElement *) v;114assert(e1 != NULL, "e1 != NULL");115assert(e2 != NULL, "e2 != NULL");116117return e1->equals(e2);118}119120//121// class GrowableCache - public methods122//123124GrowableCache::GrowableCache() {125_this_obj = NULL;126_listener_fun = NULL;127_elements = NULL;128_cache = NULL;129}130131GrowableCache::~GrowableCache() {132clear();133delete _elements;134FREE_C_HEAP_ARRAY(address, _cache, mtInternal);135}136137void GrowableCache::initialize(void *this_obj, void listener_fun(void *, address*) ) {138_this_obj = this_obj;139_listener_fun = listener_fun;140_elements = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<GrowableElement*>(5,true);141recache();142}143144// number of elements in the collection145int GrowableCache::length() {146return _elements->length();147}148149// get the value of the index element in the collection150GrowableElement* GrowableCache::at(int index) {151GrowableElement *e = (GrowableElement *) _elements->at(index);152assert(e != NULL, "e != NULL");153return e;154}155156int GrowableCache::find(GrowableElement* e) {157return _elements->find(e, GrowableCache::equals);158}159160// append a copy of the element to the end of the collection161void GrowableCache::append(GrowableElement* e) {162GrowableElement *new_e = e->clone();163_elements->append(new_e);164recache();165}166167// insert a copy of the element using lessthan()168void GrowableCache::insert(GrowableElement* e) {169GrowableElement *new_e = e->clone();170_elements->append(new_e);171172int n = length()-2;173for (int i=n; i>=0; i--) {174GrowableElement *e1 = _elements->at(i);175GrowableElement *e2 = _elements->at(i+1);176if (e2->lessThan(e1)) {177_elements->at_put(i+1, e1);178_elements->at_put(i, e2);179}180}181182recache();183}184185// remove the element at index186void GrowableCache::remove (int index) {187GrowableElement *e = _elements->at(index);188assert(e != NULL, "e != NULL");189_elements->remove(e);190delete e;191recache();192}193194// clear out all elements, release all heap space and195// let our listener know that things have changed.196void GrowableCache::clear() {197int len = _elements->length();198for (int i=0; i<len; i++) {199delete _elements->at(i);200}201_elements->clear();202recache();203}204205void GrowableCache::oops_do(OopClosure* f) {206int len = _elements->length();207for (int i=0; i<len; i++) {208GrowableElement *e = _elements->at(i);209e->oops_do(f);210}211}212213void GrowableCache::metadata_do(void f(Metadata*)) {214int len = _elements->length();215for (int i=0; i<len; i++) {216GrowableElement *e = _elements->at(i);217e->metadata_do(f);218}219}220221void GrowableCache::gc_epilogue() {222int len = _elements->length();223for (int i=0; i<len; i++) {224_cache[i] = _elements->at(i)->getCacheValue();225}226}227228//229// class JvmtiBreakpoint230//231232JvmtiBreakpoint::JvmtiBreakpoint() {233_method = NULL;234_bci = 0;235_class_holder = NULL;236}237238JvmtiBreakpoint::JvmtiBreakpoint(Method* m_method, jlocation location) {239_method = m_method;240_class_holder = _method->method_holder()->klass_holder();241#ifdef CHECK_UNHANDLED_OOPS242// _class_holder can't be wrapped in a Handle, because JvmtiBreakpoints are243// sometimes allocated on the heap.244//245// The code handling JvmtiBreakpoints allocated on the stack can't be246// interrupted by a GC until _class_holder is reachable by the GC via the247// oops_do method.248Thread::current()->allow_unhandled_oop(&_class_holder);249#endif // CHECK_UNHANDLED_OOPS250assert(_method != NULL, "_method != NULL");251_bci = (int) location;252assert(_bci >= 0, "_bci >= 0");253}254255void JvmtiBreakpoint::copy(JvmtiBreakpoint& bp) {256_method = bp._method;257_bci = bp._bci;258_class_holder = bp._class_holder;259}260261bool JvmtiBreakpoint::lessThan(JvmtiBreakpoint& bp) {262Unimplemented();263return false;264}265266bool JvmtiBreakpoint::equals(JvmtiBreakpoint& bp) {267return _method == bp._method268&& _bci == bp._bci;269}270271bool JvmtiBreakpoint::is_valid() {272// class loader can be NULL273return _method != NULL &&274_bci >= 0;275}276277address JvmtiBreakpoint::getBcp() {278return _method->bcp_from(_bci);279}280281void JvmtiBreakpoint::each_method_version_do(method_action meth_act) {282((Method*)_method->*meth_act)(_bci);283284// add/remove breakpoint to/from versions of the method that are EMCP.285Thread *thread = Thread::current();286instanceKlassHandle ikh = instanceKlassHandle(thread, _method->method_holder());287Symbol* m_name = _method->name();288Symbol* m_signature = _method->signature();289290// search previous versions if they exist291for (InstanceKlass* pv_node = ikh->previous_versions();292pv_node != NULL;293pv_node = pv_node->previous_versions()) {294Array<Method*>* methods = pv_node->methods();295296for (int i = methods->length() - 1; i >= 0; i--) {297Method* method = methods->at(i);298// Only set breakpoints in running EMCP methods.299if (method->is_running_emcp() &&300method->name() == m_name &&301method->signature() == m_signature) {302RC_TRACE(0x00000800, ("%sing breakpoint in %s(%s)",303meth_act == &Method::set_breakpoint ? "sett" : "clear",304method->name()->as_C_string(),305method->signature()->as_C_string()));306307(method->*meth_act)(_bci);308break;309}310}311}312}313314void JvmtiBreakpoint::set() {315each_method_version_do(&Method::set_breakpoint);316}317318void JvmtiBreakpoint::clear() {319each_method_version_do(&Method::clear_breakpoint);320}321322void JvmtiBreakpoint::print() {323#ifndef PRODUCT324const char *class_name = (_method == NULL) ? "NULL" : _method->klass_name()->as_C_string();325const char *method_name = (_method == NULL) ? "NULL" : _method->name()->as_C_string();326327tty->print("Breakpoint(%s,%s,%d,%p)",class_name, method_name, _bci, getBcp());328#endif329}330331332//333// class VM_ChangeBreakpoints334//335// Modify the Breakpoints data structure at a safepoint336//337338void VM_ChangeBreakpoints::doit() {339switch (_operation) {340case SET_BREAKPOINT:341_breakpoints->set_at_safepoint(*_bp);342break;343case CLEAR_BREAKPOINT:344_breakpoints->clear_at_safepoint(*_bp);345break;346default:347assert(false, "Unknown operation");348}349}350351void VM_ChangeBreakpoints::oops_do(OopClosure* f) {352// The JvmtiBreakpoints in _breakpoints will be visited via353// JvmtiExport::oops_do.354if (_bp != NULL) {355_bp->oops_do(f);356}357}358359void VM_ChangeBreakpoints::metadata_do(void f(Metadata*)) {360// Walk metadata in breakpoints to keep from being deallocated with RedefineClasses361if (_bp != NULL) {362_bp->metadata_do(f);363}364}365366//367// class JvmtiBreakpoints368//369// a JVMTI internal collection of JvmtiBreakpoint370//371372JvmtiBreakpoints::JvmtiBreakpoints(void listener_fun(void *,address *)) {373_bps.initialize(this,listener_fun);374}375376JvmtiBreakpoints:: ~JvmtiBreakpoints() {}377378void JvmtiBreakpoints::oops_do(OopClosure* f) {379_bps.oops_do(f);380}381382void JvmtiBreakpoints::metadata_do(void f(Metadata*)) {383_bps.metadata_do(f);384}385386void JvmtiBreakpoints::gc_epilogue() {387_bps.gc_epilogue();388}389390void JvmtiBreakpoints::print() {391#ifndef PRODUCT392ResourceMark rm;393394int n = _bps.length();395for (int i=0; i<n; i++) {396JvmtiBreakpoint& bp = _bps.at(i);397tty->print("%d: ", i);398bp.print();399tty->cr();400}401#endif402}403404405void JvmtiBreakpoints::set_at_safepoint(JvmtiBreakpoint& bp) {406assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");407408int i = _bps.find(bp);409if (i == -1) {410_bps.append(bp);411bp.set();412}413}414415void JvmtiBreakpoints::clear_at_safepoint(JvmtiBreakpoint& bp) {416assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");417418int i = _bps.find(bp);419if (i != -1) {420_bps.remove(i);421bp.clear();422}423}424425int JvmtiBreakpoints::length() { return _bps.length(); }426427int JvmtiBreakpoints::set(JvmtiBreakpoint& bp) {428if ( _bps.find(bp) != -1) {429return JVMTI_ERROR_DUPLICATE;430}431VM_ChangeBreakpoints set_breakpoint(VM_ChangeBreakpoints::SET_BREAKPOINT, &bp);432VMThread::execute(&set_breakpoint);433return JVMTI_ERROR_NONE;434}435436int JvmtiBreakpoints::clear(JvmtiBreakpoint& bp) {437if ( _bps.find(bp) == -1) {438return JVMTI_ERROR_NOT_FOUND;439}440441VM_ChangeBreakpoints clear_breakpoint(VM_ChangeBreakpoints::CLEAR_BREAKPOINT, &bp);442VMThread::execute(&clear_breakpoint);443return JVMTI_ERROR_NONE;444}445446void JvmtiBreakpoints::clearall_in_class_at_safepoint(Klass* klass) {447bool changed = true;448// We are going to run thru the list of bkpts449// and delete some. This deletion probably alters450// the list in some implementation defined way such451// that when we delete entry i, the next entry might452// no longer be at i+1. To be safe, each time we delete453// an entry, we'll just start again from the beginning.454// We'll stop when we make a pass thru the whole list without455// deleting anything.456while (changed) {457int len = _bps.length();458changed = false;459for (int i = 0; i < len; i++) {460JvmtiBreakpoint& bp = _bps.at(i);461if (bp.method()->method_holder() == klass) {462bp.clear();463_bps.remove(i);464// This changed 'i' so we have to start over.465changed = true;466break;467}468}469}470}471472//473// class JvmtiCurrentBreakpoints474//475476JvmtiBreakpoints *JvmtiCurrentBreakpoints::_jvmti_breakpoints = NULL;477address * JvmtiCurrentBreakpoints::_breakpoint_list = NULL;478479480JvmtiBreakpoints& JvmtiCurrentBreakpoints::get_jvmti_breakpoints() {481if (_jvmti_breakpoints != NULL) return (*_jvmti_breakpoints);482_jvmti_breakpoints = new JvmtiBreakpoints(listener_fun);483assert(_jvmti_breakpoints != NULL, "_jvmti_breakpoints != NULL");484return (*_jvmti_breakpoints);485}486487void JvmtiCurrentBreakpoints::listener_fun(void *this_obj, address *cache) {488JvmtiBreakpoints *this_jvmti = (JvmtiBreakpoints *) this_obj;489assert(this_jvmti != NULL, "this_jvmti != NULL");490491debug_only(int n = this_jvmti->length(););492assert(cache[n] == NULL, "cache must be NULL terminated");493494set_breakpoint_list(cache);495}496497498void JvmtiCurrentBreakpoints::oops_do(OopClosure* f) {499if (_jvmti_breakpoints != NULL) {500_jvmti_breakpoints->oops_do(f);501}502}503504void JvmtiCurrentBreakpoints::metadata_do(void f(Metadata*)) {505if (_jvmti_breakpoints != NULL) {506_jvmti_breakpoints->metadata_do(f);507}508}509510void JvmtiCurrentBreakpoints::gc_epilogue() {511if (_jvmti_breakpoints != NULL) {512_jvmti_breakpoints->gc_epilogue();513}514}515516///////////////////////////////////////////////////////////////517//518// class VM_GetOrSetLocal519//520521// Constructor for non-object getter522VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, jint depth, int index, BasicType type)523: _thread(thread)524, _calling_thread(NULL)525, _depth(depth)526, _index(index)527, _type(type)528, _set(false)529, _jvf(NULL)530, _result(JVMTI_ERROR_NONE)531{532}533534// Constructor for object or non-object setter535VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, jint depth, int index, BasicType type, jvalue value)536: _thread(thread)537, _calling_thread(NULL)538, _depth(depth)539, _index(index)540, _type(type)541, _value(value)542, _set(true)543, _jvf(NULL)544, _result(JVMTI_ERROR_NONE)545{546}547548// Constructor for object getter549VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, JavaThread* calling_thread, jint depth, int index)550: _thread(thread)551, _calling_thread(calling_thread)552, _depth(depth)553, _index(index)554, _type(T_OBJECT)555, _set(false)556, _jvf(NULL)557, _result(JVMTI_ERROR_NONE)558{559}560561vframe *VM_GetOrSetLocal::get_vframe() {562if (!_thread->has_last_Java_frame()) {563return NULL;564}565RegisterMap reg_map(_thread);566vframe *vf = _thread->last_java_vframe(®_map);567int d = 0;568while ((vf != NULL) && (d < _depth)) {569vf = vf->java_sender();570d++;571}572return vf;573}574575javaVFrame *VM_GetOrSetLocal::get_java_vframe() {576vframe* vf = get_vframe();577if (vf == NULL) {578_result = JVMTI_ERROR_NO_MORE_FRAMES;579return NULL;580}581javaVFrame *jvf = (javaVFrame*)vf;582583if (!vf->is_java_frame()) {584_result = JVMTI_ERROR_OPAQUE_FRAME;585return NULL;586}587return jvf;588}589590// Check that the klass is assignable to a type with the given signature.591// Another solution could be to use the function Klass::is_subtype_of(type).592// But the type class can be forced to load/initialize eagerly in such a case.593// This may cause unexpected consequences like CFLH or class-init JVMTI events.594// It is better to avoid such a behavior.595bool VM_GetOrSetLocal::is_assignable(const char* ty_sign, Klass* klass, Thread* thread) {596assert(ty_sign != NULL, "type signature must not be NULL");597assert(thread != NULL, "thread must not be NULL");598assert(klass != NULL, "klass must not be NULL");599600int len = (int) strlen(ty_sign);601if (ty_sign[0] == 'L' && ty_sign[len-1] == ';') { // Need pure class/interface name602ty_sign++;603len -= 2;604}605TempNewSymbol ty_sym = SymbolTable::new_symbol(ty_sign, len, thread);606if (klass->name() == ty_sym) {607return true;608}609// Compare primary supers610int super_depth = klass->super_depth();611int idx;612for (idx = 0; idx < super_depth; idx++) {613if (klass->primary_super_of_depth(idx)->name() == ty_sym) {614return true;615}616}617// Compare secondary supers618Array<Klass*>* sec_supers = klass->secondary_supers();619for (idx = 0; idx < sec_supers->length(); idx++) {620if (((Klass*) sec_supers->at(idx))->name() == ty_sym) {621return true;622}623}624return false;625}626627// Checks error conditions:628// JVMTI_ERROR_INVALID_SLOT629// JVMTI_ERROR_TYPE_MISMATCH630// Returns: 'true' - everything is Ok, 'false' - error code631632bool VM_GetOrSetLocal::check_slot_type(javaVFrame* jvf) {633Method* method_oop = jvf->method();634if (!method_oop->has_localvariable_table()) {635// Just to check index boundaries636jint extra_slot = (_type == T_LONG || _type == T_DOUBLE) ? 1 : 0;637if (_index < 0 || _index + extra_slot >= method_oop->max_locals()) {638_result = JVMTI_ERROR_INVALID_SLOT;639return false;640}641return true;642}643644jint num_entries = method_oop->localvariable_table_length();645if (num_entries == 0) {646_result = JVMTI_ERROR_INVALID_SLOT;647return false; // There are no slots648}649int signature_idx = -1;650int vf_bci = jvf->bci();651LocalVariableTableElement* table = method_oop->localvariable_table_start();652for (int i = 0; i < num_entries; i++) {653int start_bci = table[i].start_bci;654int end_bci = start_bci + table[i].length;655656// Here we assume that locations of LVT entries657// with the same slot number cannot be overlapped658if (_index == (jint) table[i].slot && start_bci <= vf_bci && vf_bci <= end_bci) {659signature_idx = (int) table[i].descriptor_cp_index;660break;661}662}663if (signature_idx == -1) {664_result = JVMTI_ERROR_INVALID_SLOT;665return false; // Incorrect slot index666}667Symbol* sign_sym = method_oop->constants()->symbol_at(signature_idx);668const char* signature = (const char *) sign_sym->as_utf8();669BasicType slot_type = char2type(signature[0]);670671switch (slot_type) {672case T_BYTE:673case T_SHORT:674case T_CHAR:675case T_BOOLEAN:676slot_type = T_INT;677break;678case T_ARRAY:679slot_type = T_OBJECT;680break;681};682if (_type != slot_type) {683_result = JVMTI_ERROR_TYPE_MISMATCH;684return false;685}686687jobject jobj = _value.l;688if (_set && slot_type == T_OBJECT && jobj != NULL) { // NULL reference is allowed689// Check that the jobject class matches the return type signature.690JavaThread* cur_thread = JavaThread::current();691HandleMark hm(cur_thread);692693Handle obj = Handle(cur_thread, JNIHandles::resolve_external_guard(jobj));694NULL_CHECK(obj, (_result = JVMTI_ERROR_INVALID_OBJECT, false));695KlassHandle ob_kh = KlassHandle(cur_thread, obj->klass());696NULL_CHECK(ob_kh, (_result = JVMTI_ERROR_INVALID_OBJECT, false));697698if (!is_assignable(signature, ob_kh(), cur_thread)) {699_result = JVMTI_ERROR_TYPE_MISMATCH;700return false;701}702}703return true;704}705706static bool can_be_deoptimized(vframe* vf) {707return (vf->is_compiled_frame() && vf->fr().can_be_deoptimized());708}709710bool VM_GetOrSetLocal::doit_prologue() {711_jvf = get_java_vframe();712NULL_CHECK(_jvf, false);713714if (_jvf->method()->is_native()) {715if (getting_receiver() && !_jvf->method()->is_static()) {716return true;717} else {718_result = JVMTI_ERROR_OPAQUE_FRAME;719return false;720}721}722723if (!check_slot_type(_jvf)) {724return false;725}726return true;727}728729void VM_GetOrSetLocal::doit() {730InterpreterOopMap oop_mask;731_jvf->method()->mask_for(_jvf->bci(), &oop_mask);732if (oop_mask.is_dead(_index)) {733// The local can be invalid and uninitialized in the scope of current bci734_result = JVMTI_ERROR_INVALID_SLOT;735return;736}737if (_set) {738// Force deoptimization of frame if compiled because it's739// possible the compiler emitted some locals as constant values,740// meaning they are not mutable.741if (can_be_deoptimized(_jvf)) {742743// Schedule deoptimization so that eventually the local744// update will be written to an interpreter frame.745Deoptimization::deoptimize_frame(_jvf->thread(), _jvf->fr().id());746747// Now store a new value for the local which will be applied748// once deoptimization occurs. Note however that while this749// write is deferred until deoptimization actually happens750// can vframe created after this point will have its locals751// reflecting this update so as far as anyone can see the752// write has already taken place.753754// If we are updating an oop then get the oop from the handle755// since the handle will be long gone by the time the deopt756// happens. The oop stored in the deferred local will be757// gc'd on its own.758if (_type == T_OBJECT) {759_value.l = (jobject) (JNIHandles::resolve_external_guard(_value.l));760}761// Re-read the vframe so we can see that it is deoptimized762// [ Only need because of assert in update_local() ]763_jvf = get_java_vframe();764((compiledVFrame*)_jvf)->update_local(_type, _index, _value);765return;766}767StackValueCollection *locals = _jvf->locals();768HandleMark hm;769770switch (_type) {771case T_INT: locals->set_int_at (_index, _value.i); break;772case T_LONG: locals->set_long_at (_index, _value.j); break;773case T_FLOAT: locals->set_float_at (_index, _value.f); break;774case T_DOUBLE: locals->set_double_at(_index, _value.d); break;775case T_OBJECT: {776Handle ob_h(JNIHandles::resolve_external_guard(_value.l));777locals->set_obj_at (_index, ob_h);778break;779}780default: ShouldNotReachHere();781}782_jvf->set_locals(locals);783} else {784if (_jvf->method()->is_native() && _jvf->is_compiled_frame()) {785assert(getting_receiver(), "Can only get here when getting receiver");786oop receiver = _jvf->fr().get_native_receiver();787_value.l = JNIHandles::make_local(_calling_thread, receiver);788} else {789StackValueCollection *locals = _jvf->locals();790791if (locals->at(_index)->type() == T_CONFLICT) {792memset(&_value, 0, sizeof(_value));793_value.l = NULL;794return;795}796797switch (_type) {798case T_INT: _value.i = locals->int_at (_index); break;799case T_LONG: _value.j = locals->long_at (_index); break;800case T_FLOAT: _value.f = locals->float_at (_index); break;801case T_DOUBLE: _value.d = locals->double_at(_index); break;802case T_OBJECT: {803// Wrap the oop to be returned in a local JNI handle since804// oops_do() no longer applies after doit() is finished.805oop obj = locals->obj_at(_index)();806_value.l = JNIHandles::make_local(_calling_thread, obj);807break;808}809default: ShouldNotReachHere();810}811}812}813}814815816bool VM_GetOrSetLocal::allow_nested_vm_operations() const {817return true; // May need to deoptimize818}819820821VM_GetReceiver::VM_GetReceiver(822JavaThread* thread, JavaThread* caller_thread, jint depth)823: VM_GetOrSetLocal(thread, caller_thread, depth, 0) {}824825/////////////////////////////////////////////////////////////////////////////////////////826827//828// class JvmtiSuspendControl - see comments in jvmtiImpl.hpp829//830831bool JvmtiSuspendControl::suspend(JavaThread *java_thread) {832// external suspend should have caught suspending a thread twice833834// Immediate suspension required for JPDA back-end so JVMTI agent threads do835// not deadlock due to later suspension on transitions while holding836// raw monitors. Passing true causes the immediate suspension.837// java_suspend() will catch threads in the process of exiting838// and will ignore them.839java_thread->java_suspend();840841// It would be nice to have the following assertion in all the time,842// but it is possible for a racing resume request to have resumed843// this thread right after we suspended it. Temporarily enable this844// assertion if you are chasing a different kind of bug.845//846// assert(java_lang_Thread::thread(java_thread->threadObj()) == NULL ||847// java_thread->is_being_ext_suspended(), "thread is not suspended");848849if (java_lang_Thread::thread(java_thread->threadObj()) == NULL) {850// check again because we can get delayed in java_suspend():851// the thread is in process of exiting.852return false;853}854855return true;856}857858bool JvmtiSuspendControl::resume(JavaThread *java_thread) {859// external suspend should have caught resuming a thread twice860assert(java_thread->is_being_ext_suspended(), "thread should be suspended");861862// resume thread863{864// must always grab Threads_lock, see JVM_SuspendThread865MutexLocker ml(Threads_lock);866java_thread->java_resume();867}868869return true;870}871872873void JvmtiSuspendControl::print() {874#ifndef PRODUCT875MutexLocker mu(Threads_lock);876ResourceMark rm;877878tty->print("Suspended Threads: [");879for (JavaThread *thread = Threads::first(); thread != NULL; thread = thread->next()) {880#ifdef JVMTI_TRACE881const char *name = JvmtiTrace::safe_get_thread_name(thread);882#else883const char *name = "";884#endif /*JVMTI_TRACE */885tty->print("%s(%c ", name, thread->is_being_ext_suspended() ? 'S' : '_');886if (!thread->has_last_Java_frame()) {887tty->print("no stack");888}889tty->print(") ");890}891tty->print_cr("]");892#endif893}894895JvmtiDeferredEvent JvmtiDeferredEvent::compiled_method_load_event(896nmethod* nm) {897JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_COMPILED_METHOD_LOAD);898event._event_data.compiled_method_load = nm;899// Keep the nmethod alive until the ServiceThread can process900// this deferred event.901nmethodLocker::lock_nmethod(nm);902return event;903}904905JvmtiDeferredEvent JvmtiDeferredEvent::compiled_method_unload_event(906nmethod* nm, jmethodID id, const void* code) {907JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_COMPILED_METHOD_UNLOAD);908event._event_data.compiled_method_unload.nm = nm;909event._event_data.compiled_method_unload.method_id = id;910event._event_data.compiled_method_unload.code_begin = code;911// Keep the nmethod alive until the ServiceThread can process912// this deferred event. This will keep the memory for the913// generated code from being reused too early. We pass914// zombie_ok == true here so that our nmethod that was just915// made into a zombie can be locked.916nmethodLocker::lock_nmethod(nm, true /* zombie_ok */);917return event;918}919920JvmtiDeferredEvent JvmtiDeferredEvent::dynamic_code_generated_event(921const char* name, const void* code_begin, const void* code_end) {922JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_DYNAMIC_CODE_GENERATED);923// Need to make a copy of the name since we don't know how long924// the event poster will keep it around after we enqueue the925// deferred event and return. strdup() failure is handled in926// the post() routine below.927event._event_data.dynamic_code_generated.name = os::strdup(name);928event._event_data.dynamic_code_generated.code_begin = code_begin;929event._event_data.dynamic_code_generated.code_end = code_end;930return event;931}932933void JvmtiDeferredEvent::post() {934assert(ServiceThread::is_service_thread(Thread::current()),935"Service thread must post enqueued events");936switch(_type) {937case TYPE_COMPILED_METHOD_LOAD: {938nmethod* nm = _event_data.compiled_method_load;939JvmtiExport::post_compiled_method_load(nm);940// done with the deferred event so unlock the nmethod941nmethodLocker::unlock_nmethod(nm);942break;943}944case TYPE_COMPILED_METHOD_UNLOAD: {945nmethod* nm = _event_data.compiled_method_unload.nm;946JvmtiExport::post_compiled_method_unload(947_event_data.compiled_method_unload.method_id,948_event_data.compiled_method_unload.code_begin);949// done with the deferred event so unlock the nmethod950nmethodLocker::unlock_nmethod(nm);951break;952}953case TYPE_DYNAMIC_CODE_GENERATED: {954JvmtiExport::post_dynamic_code_generated_internal(955// if strdup failed give the event a default name956(_event_data.dynamic_code_generated.name == NULL)957? "unknown_code" : _event_data.dynamic_code_generated.name,958_event_data.dynamic_code_generated.code_begin,959_event_data.dynamic_code_generated.code_end);960if (_event_data.dynamic_code_generated.name != NULL) {961// release our copy962os::free((void *)_event_data.dynamic_code_generated.name);963}964break;965}966default:967ShouldNotReachHere();968}969}970971JvmtiDeferredEventQueue::QueueNode* JvmtiDeferredEventQueue::_queue_tail = NULL;972JvmtiDeferredEventQueue::QueueNode* JvmtiDeferredEventQueue::_queue_head = NULL;973974volatile JvmtiDeferredEventQueue::QueueNode*975JvmtiDeferredEventQueue::_pending_list = NULL;976977bool JvmtiDeferredEventQueue::has_events() {978assert(Service_lock->owned_by_self(), "Must own Service_lock");979return _queue_head != NULL || _pending_list != NULL;980}981982void JvmtiDeferredEventQueue::enqueue(const JvmtiDeferredEvent& event) {983assert(Service_lock->owned_by_self(), "Must own Service_lock");984985process_pending_events();986987// Events get added to the end of the queue (and are pulled off the front).988QueueNode* node = new QueueNode(event);989if (_queue_tail == NULL) {990_queue_tail = _queue_head = node;991} else {992assert(_queue_tail->next() == NULL, "Must be the last element in the list");993_queue_tail->set_next(node);994_queue_tail = node;995}996997Service_lock->notify_all();998assert((_queue_head == NULL) == (_queue_tail == NULL),999"Inconsistent queue markers");1000}10011002JvmtiDeferredEvent JvmtiDeferredEventQueue::dequeue() {1003assert(Service_lock->owned_by_self(), "Must own Service_lock");10041005process_pending_events();10061007assert(_queue_head != NULL, "Nothing to dequeue");10081009if (_queue_head == NULL) {1010// Just in case this happens in product; it shouldn't but let's not crash1011return JvmtiDeferredEvent();1012}10131014QueueNode* node = _queue_head;1015_queue_head = _queue_head->next();1016if (_queue_head == NULL) {1017_queue_tail = NULL;1018}10191020assert((_queue_head == NULL) == (_queue_tail == NULL),1021"Inconsistent queue markers");10221023JvmtiDeferredEvent event = node->event();1024delete node;1025return event;1026}10271028void JvmtiDeferredEventQueue::add_pending_event(1029const JvmtiDeferredEvent& event) {10301031QueueNode* node = new QueueNode(event);10321033bool success = false;1034QueueNode* prev_value = (QueueNode*)_pending_list;1035do {1036node->set_next(prev_value);1037prev_value = (QueueNode*)Atomic::cmpxchg_ptr(1038(void*)node, (volatile void*)&_pending_list, (void*)node->next());1039} while (prev_value != node->next());1040}10411042// This method transfers any events that were added by someone NOT holding1043// the lock into the mainline queue.1044void JvmtiDeferredEventQueue::process_pending_events() {1045assert(Service_lock->owned_by_self(), "Must own Service_lock");10461047if (_pending_list != NULL) {1048QueueNode* head =1049(QueueNode*)Atomic::xchg_ptr(NULL, (volatile void*)&_pending_list);10501051assert((_queue_head == NULL) == (_queue_tail == NULL),1052"Inconsistent queue markers");10531054if (head != NULL) {1055// Since we've treated the pending list as a stack (with newer1056// events at the beginning), we need to join the bottom of the stack1057// with the 'tail' of the queue in order to get the events in the1058// right order. We do this by reversing the pending list and appending1059// it to the queue.10601061QueueNode* new_tail = head;1062QueueNode* new_head = NULL;10631064// This reverses the list1065QueueNode* prev = new_tail;1066QueueNode* node = new_tail->next();1067new_tail->set_next(NULL);1068while (node != NULL) {1069QueueNode* next = node->next();1070node->set_next(prev);1071prev = node;1072node = next;1073}1074new_head = prev;10751076// Now append the new list to the queue1077if (_queue_tail != NULL) {1078_queue_tail->set_next(new_head);1079} else { // _queue_head == NULL1080_queue_head = new_head;1081}1082_queue_tail = new_tail;1083}1084}1085}108610871088