Path: blob/jdk8u272-b10-aarch32-20201026/hotspot/src/share/vm/prims/jvmtiEnv.cpp
48729 views
/*1* Copyright (c) 2003, 2019, 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/classLoaderExt.hpp"26#include "classfile/systemDictionary.hpp"27#include "classfile/vmSymbols.hpp"28#include "interpreter/bytecodeStream.hpp"29#include "interpreter/interpreter.hpp"30#include "jvmtifiles/jvmtiEnv.hpp"31#include "memory/resourceArea.hpp"32#include "memory/universe.inline.hpp"33#include "oops/instanceKlass.hpp"34#include "prims/jniCheck.hpp"35#include "prims/jvm_misc.hpp"36#include "prims/jvmtiAgentThread.hpp"37#include "prims/jvmtiClassFileReconstituter.hpp"38#include "prims/jvmtiCodeBlobEvents.hpp"39#include "prims/jvmtiExtensions.hpp"40#include "prims/jvmtiGetLoadedClasses.hpp"41#include "prims/jvmtiImpl.hpp"42#include "prims/jvmtiManageCapabilities.hpp"43#include "prims/jvmtiRawMonitor.hpp"44#include "prims/jvmtiRedefineClasses.hpp"45#include "prims/jvmtiTagMap.hpp"46#include "prims/jvmtiThreadState.inline.hpp"47#include "prims/jvmtiUtil.hpp"48#include "runtime/arguments.hpp"49#include "runtime/deoptimization.hpp"50#include "runtime/interfaceSupport.hpp"51#include "runtime/javaCalls.hpp"52#include "runtime/jfieldIDWorkaround.hpp"53#include "runtime/osThread.hpp"54#include "runtime/reflectionUtils.hpp"55#include "runtime/signature.hpp"56#include "runtime/thread.inline.hpp"57#include "runtime/vframe.hpp"58#include "runtime/vmThread.hpp"59#include "services/threadService.hpp"60#include "utilities/exceptions.hpp"61#include "utilities/preserveException.hpp"626364#define FIXLATER 0 // REMOVE this when completed.6566// FIXLATER: hook into JvmtiTrace67#define TraceJVMTICalls false6869JvmtiEnv::JvmtiEnv(jint version) : JvmtiEnvBase(version) {70}7172JvmtiEnv::~JvmtiEnv() {73}7475JvmtiEnv*76JvmtiEnv::create_a_jvmti(jint version) {77return new JvmtiEnv(version);78}7980// VM operation class to copy jni function table at safepoint.81// More than one java threads or jvmti agents may be reading/82// modifying jni function tables. To reduce the risk of bad83// interaction b/w these threads it is copied at safepoint.84class VM_JNIFunctionTableCopier : public VM_Operation {85private:86const struct JNINativeInterface_ *_function_table;87public:88VM_JNIFunctionTableCopier(const struct JNINativeInterface_ *func_tbl) {89_function_table = func_tbl;90};9192VMOp_Type type() const { return VMOp_JNIFunctionTableCopier; }93void doit() {94copy_jni_function_table(_function_table);95};96};9798//99// Do not change the "prefix" marker below, everything above it is copied100// unchanged into the filled stub, everything below is controlled by the101// stub filler (only method bodies are carried forward, and then only for102// functionality still in the spec).103//104// end file prefix105106//107// Memory Management functions108//109110// mem_ptr - pre-checked for NULL111jvmtiError112JvmtiEnv::Allocate(jlong size, unsigned char** mem_ptr) {113return allocate(size, mem_ptr);114} /* end Allocate */115116117// mem - NULL is a valid value, must be checked118jvmtiError119JvmtiEnv::Deallocate(unsigned char* mem) {120return deallocate(mem);121} /* end Deallocate */122123// Threads_lock NOT held, java_thread not protected by lock124// java_thread - pre-checked125// data - NULL is a valid value, must be checked126jvmtiError127JvmtiEnv::SetThreadLocalStorage(JavaThread* java_thread, const void* data) {128JvmtiThreadState* state = java_thread->jvmti_thread_state();129if (state == NULL) {130if (data == NULL) {131// leaving state unset same as data set to NULL132return JVMTI_ERROR_NONE;133}134// otherwise, create the state135state = JvmtiThreadState::state_for(java_thread);136if (state == NULL) {137return JVMTI_ERROR_THREAD_NOT_ALIVE;138}139}140state->env_thread_state(this)->set_agent_thread_local_storage_data((void*)data);141return JVMTI_ERROR_NONE;142} /* end SetThreadLocalStorage */143144145// Threads_lock NOT held146// thread - NOT pre-checked147// data_ptr - pre-checked for NULL148jvmtiError149JvmtiEnv::GetThreadLocalStorage(jthread thread, void** data_ptr) {150JavaThread* current_thread = JavaThread::current();151if (thread == NULL) {152JvmtiThreadState* state = current_thread->jvmti_thread_state();153*data_ptr = (state == NULL) ? NULL :154state->env_thread_state(this)->get_agent_thread_local_storage_data();155} else {156157// jvmti_GetThreadLocalStorage is "in native" and doesn't transition158// the thread to _thread_in_vm. However, when the TLS for a thread159// other than the current thread is required we need to transition160// from native so as to resolve the jthread.161162ThreadInVMfromNative __tiv(current_thread);163VM_ENTRY_BASE(jvmtiError, JvmtiEnv::GetThreadLocalStorage , current_thread)164debug_only(VMNativeEntryWrapper __vew;)165166oop thread_oop = JNIHandles::resolve_external_guard(thread);167if (thread_oop == NULL) {168return JVMTI_ERROR_INVALID_THREAD;169}170if (!thread_oop->is_a(SystemDictionary::Thread_klass())) {171return JVMTI_ERROR_INVALID_THREAD;172}173JavaThread* java_thread = java_lang_Thread::thread(thread_oop);174if (java_thread == NULL) {175return JVMTI_ERROR_THREAD_NOT_ALIVE;176}177JvmtiThreadState* state = java_thread->jvmti_thread_state();178*data_ptr = (state == NULL) ? NULL :179state->env_thread_state(this)->get_agent_thread_local_storage_data();180}181return JVMTI_ERROR_NONE;182} /* end GetThreadLocalStorage */183184//185// Class functions186//187188// class_count_ptr - pre-checked for NULL189// classes_ptr - pre-checked for NULL190jvmtiError191JvmtiEnv::GetLoadedClasses(jint* class_count_ptr, jclass** classes_ptr) {192return JvmtiGetLoadedClasses::getLoadedClasses(this, class_count_ptr, classes_ptr);193} /* end GetLoadedClasses */194195196// initiating_loader - NULL is a valid value, must be checked197// class_count_ptr - pre-checked for NULL198// classes_ptr - pre-checked for NULL199jvmtiError200JvmtiEnv::GetClassLoaderClasses(jobject initiating_loader, jint* class_count_ptr, jclass** classes_ptr) {201return JvmtiGetLoadedClasses::getClassLoaderClasses(this, initiating_loader,202class_count_ptr, classes_ptr);203} /* end GetClassLoaderClasses */204205// k_mirror - may be primitive, this must be checked206// is_modifiable_class_ptr - pre-checked for NULL207jvmtiError208JvmtiEnv::IsModifiableClass(oop k_mirror, jboolean* is_modifiable_class_ptr) {209*is_modifiable_class_ptr = VM_RedefineClasses::is_modifiable_class(k_mirror)?210JNI_TRUE : JNI_FALSE;211return JVMTI_ERROR_NONE;212} /* end IsModifiableClass */213214// class_count - pre-checked to be greater than or equal to 0215// classes - pre-checked for NULL216jvmtiError217JvmtiEnv::RetransformClasses(jint class_count, const jclass* classes) {218//TODO: add locking219220int index;221JavaThread* current_thread = JavaThread::current();222ResourceMark rm(current_thread);223224jvmtiClassDefinition* class_definitions =225NEW_RESOURCE_ARRAY(jvmtiClassDefinition, class_count);226NULL_CHECK(class_definitions, JVMTI_ERROR_OUT_OF_MEMORY);227228for (index = 0; index < class_count; index++) {229HandleMark hm(current_thread);230231jclass jcls = classes[index];232oop k_mirror = JNIHandles::resolve_external_guard(jcls);233if (k_mirror == NULL) {234return JVMTI_ERROR_INVALID_CLASS;235}236if (!k_mirror->is_a(SystemDictionary::Class_klass())) {237return JVMTI_ERROR_INVALID_CLASS;238}239240if (java_lang_Class::is_primitive(k_mirror)) {241return JVMTI_ERROR_UNMODIFIABLE_CLASS;242}243244Klass* k_oop = java_lang_Class::as_Klass(k_mirror);245KlassHandle klass(current_thread, k_oop);246247jint status = klass->jvmti_class_status();248if (status & (JVMTI_CLASS_STATUS_ERROR)) {249return JVMTI_ERROR_INVALID_CLASS;250}251if (status & (JVMTI_CLASS_STATUS_ARRAY)) {252return JVMTI_ERROR_UNMODIFIABLE_CLASS;253}254255instanceKlassHandle ikh(current_thread, k_oop);256if (ikh->get_cached_class_file_bytes() == NULL) {257// Not cached, we need to reconstitute the class file from the258// VM representation. We don't attach the reconstituted class259// bytes to the InstanceKlass here because they have not been260// validated and we're not at a safepoint.261constantPoolHandle constants(current_thread, ikh->constants());262MonitorLockerEx ml(constants->lock()); // lock constant pool while we query it263264JvmtiClassFileReconstituter reconstituter(ikh);265if (reconstituter.get_error() != JVMTI_ERROR_NONE) {266return reconstituter.get_error();267}268269class_definitions[index].class_byte_count = (jint)reconstituter.class_file_size();270class_definitions[index].class_bytes = (unsigned char*)271reconstituter.class_file_bytes();272} else {273// it is cached, get it from the cache274class_definitions[index].class_byte_count = ikh->get_cached_class_file_len();275class_definitions[index].class_bytes = ikh->get_cached_class_file_bytes();276}277class_definitions[index].klass = jcls;278}279VM_RedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_retransform);280VMThread::execute(&op);281return (op.check_error());282} /* end RetransformClasses */283284285// class_count - pre-checked to be greater than or equal to 0286// class_definitions - pre-checked for NULL287jvmtiError288JvmtiEnv::RedefineClasses(jint class_count, const jvmtiClassDefinition* class_definitions) {289//TODO: add locking290VM_RedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_redefine);291VMThread::execute(&op);292return (op.check_error());293} /* end RedefineClasses */294295296//297// Object functions298//299300// size_ptr - pre-checked for NULL301jvmtiError302JvmtiEnv::GetObjectSize(jobject object, jlong* size_ptr) {303oop mirror = JNIHandles::resolve_external_guard(object);304NULL_CHECK(mirror, JVMTI_ERROR_INVALID_OBJECT);305306if (mirror->klass() == SystemDictionary::Class_klass() &&307!java_lang_Class::is_primitive(mirror)) {308Klass* k = java_lang_Class::as_Klass(mirror);309assert(k != NULL, "class for non-primitive mirror must exist");310*size_ptr = (jlong)k->size() * wordSize;311} else {312*size_ptr = (jlong)mirror->size() * wordSize;313}314return JVMTI_ERROR_NONE;315} /* end GetObjectSize */316317//318// Method functions319//320321// prefix - NULL is a valid value, must be checked322jvmtiError323JvmtiEnv::SetNativeMethodPrefix(const char* prefix) {324return prefix == NULL?325SetNativeMethodPrefixes(0, NULL) :326SetNativeMethodPrefixes(1, (char**)&prefix);327} /* end SetNativeMethodPrefix */328329330// prefix_count - pre-checked to be greater than or equal to 0331// prefixes - pre-checked for NULL332jvmtiError333JvmtiEnv::SetNativeMethodPrefixes(jint prefix_count, char** prefixes) {334// Have to grab JVMTI thread state lock to be sure that some thread335// isn't accessing the prefixes at the same time we are setting them.336// No locks during VM bring-up.337if (Threads::number_of_threads() == 0) {338return set_native_method_prefixes(prefix_count, prefixes);339} else {340MutexLocker mu(JvmtiThreadState_lock);341return set_native_method_prefixes(prefix_count, prefixes);342}343} /* end SetNativeMethodPrefixes */344345//346// Event Management functions347//348349// callbacks - NULL is a valid value, must be checked350// size_of_callbacks - pre-checked to be greater than or equal to 0351jvmtiError352JvmtiEnv::SetEventCallbacks(const jvmtiEventCallbacks* callbacks, jint size_of_callbacks) {353JvmtiEventController::set_event_callbacks(this, callbacks, size_of_callbacks);354return JVMTI_ERROR_NONE;355} /* end SetEventCallbacks */356357358// event_thread - NULL is a valid value, must be checked359jvmtiError360JvmtiEnv::SetEventNotificationMode(jvmtiEventMode mode, jvmtiEvent event_type, jthread event_thread, ...) {361JavaThread* java_thread = NULL;362if (event_thread != NULL) {363oop thread_oop = JNIHandles::resolve_external_guard(event_thread);364if (thread_oop == NULL) {365return JVMTI_ERROR_INVALID_THREAD;366}367if (!thread_oop->is_a(SystemDictionary::Thread_klass())) {368return JVMTI_ERROR_INVALID_THREAD;369}370java_thread = java_lang_Thread::thread(thread_oop);371if (java_thread == NULL) {372return JVMTI_ERROR_THREAD_NOT_ALIVE;373}374}375376// event_type must be valid377if (!JvmtiEventController::is_valid_event_type(event_type)) {378return JVMTI_ERROR_INVALID_EVENT_TYPE;379}380381// global events cannot be controlled at thread level.382if (java_thread != NULL && JvmtiEventController::is_global_event(event_type)) {383return JVMTI_ERROR_ILLEGAL_ARGUMENT;384}385386bool enabled = (mode == JVMTI_ENABLE);387388// assure that needed capabilities are present389if (enabled && !JvmtiUtil::has_event_capability(event_type, get_capabilities())) {390return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;391}392393if (event_type == JVMTI_EVENT_CLASS_FILE_LOAD_HOOK && enabled) {394record_class_file_load_hook_enabled();395}396JvmtiEventController::set_user_enabled(this, java_thread, event_type, enabled);397398return JVMTI_ERROR_NONE;399} /* end SetEventNotificationMode */400401//402// Capability functions403//404405// capabilities_ptr - pre-checked for NULL406jvmtiError407JvmtiEnv::GetPotentialCapabilities(jvmtiCapabilities* capabilities_ptr) {408JvmtiManageCapabilities::get_potential_capabilities(get_capabilities(),409get_prohibited_capabilities(),410capabilities_ptr);411return JVMTI_ERROR_NONE;412} /* end GetPotentialCapabilities */413414415// capabilities_ptr - pre-checked for NULL416jvmtiError417JvmtiEnv::AddCapabilities(const jvmtiCapabilities* capabilities_ptr) {418return JvmtiManageCapabilities::add_capabilities(get_capabilities(),419get_prohibited_capabilities(),420capabilities_ptr,421get_capabilities());422} /* end AddCapabilities */423424425// capabilities_ptr - pre-checked for NULL426jvmtiError427JvmtiEnv::RelinquishCapabilities(const jvmtiCapabilities* capabilities_ptr) {428JvmtiManageCapabilities::relinquish_capabilities(get_capabilities(), capabilities_ptr, get_capabilities());429return JVMTI_ERROR_NONE;430} /* end RelinquishCapabilities */431432433// capabilities_ptr - pre-checked for NULL434jvmtiError435JvmtiEnv::GetCapabilities(jvmtiCapabilities* capabilities_ptr) {436JvmtiManageCapabilities::copy_capabilities(get_capabilities(), capabilities_ptr);437return JVMTI_ERROR_NONE;438} /* end GetCapabilities */439440//441// Class Loader Search functions442//443444// segment - pre-checked for NULL445jvmtiError446JvmtiEnv::AddToBootstrapClassLoaderSearch(const char* segment) {447jvmtiPhase phase = get_phase();448if (phase == JVMTI_PHASE_ONLOAD) {449Arguments::append_sysclasspath(segment);450return JVMTI_ERROR_NONE;451} else if (use_version_1_0_semantics()) {452// This JvmtiEnv requested version 1.0 semantics and this function453// is only allowed in the ONLOAD phase in version 1.0 so we need to454// return an error here.455return JVMTI_ERROR_WRONG_PHASE;456} else if (phase == JVMTI_PHASE_LIVE) {457// The phase is checked by the wrapper that called this function,458// but this thread could be racing with the thread that is459// terminating the VM so we check one more time.460461// create the zip entry462ClassPathZipEntry* zip_entry = ClassLoader::create_class_path_zip_entry(segment);463if (zip_entry == NULL) {464return JVMTI_ERROR_ILLEGAL_ARGUMENT;465}466467// lock the loader468Thread* thread = Thread::current();469HandleMark hm;470Handle loader_lock = Handle(thread, SystemDictionary::system_loader_lock());471472ObjectLocker ol(loader_lock, thread);473474// add the jar file to the bootclasspath475if (TraceClassLoading) {476tty->print_cr("[Opened %s]", zip_entry->name());477}478ClassLoaderExt::append_boot_classpath(zip_entry);479return JVMTI_ERROR_NONE;480} else {481return JVMTI_ERROR_WRONG_PHASE;482}483484} /* end AddToBootstrapClassLoaderSearch */485486487// segment - pre-checked for NULL488jvmtiError489JvmtiEnv::AddToSystemClassLoaderSearch(const char* segment) {490jvmtiPhase phase = get_phase();491492if (phase == JVMTI_PHASE_ONLOAD) {493for (SystemProperty* p = Arguments::system_properties(); p != NULL; p = p->next()) {494if (strcmp("java.class.path", p->key()) == 0) {495p->append_value(segment);496break;497}498}499return JVMTI_ERROR_NONE;500} else if (phase == JVMTI_PHASE_LIVE) {501// The phase is checked by the wrapper that called this function,502// but this thread could be racing with the thread that is503// terminating the VM so we check one more time.504HandleMark hm;505506// create the zip entry (which will open the zip file and hence507// check that the segment is indeed a zip file).508ClassPathZipEntry* zip_entry = ClassLoader::create_class_path_zip_entry(segment);509if (zip_entry == NULL) {510return JVMTI_ERROR_ILLEGAL_ARGUMENT;511}512delete zip_entry; // no longer needed513514// lock the loader515Thread* THREAD = Thread::current();516Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());517518ObjectLocker ol(loader, THREAD);519520// need the path as java.lang.String521Handle path = java_lang_String::create_from_platform_dependent_str(segment, THREAD);522if (HAS_PENDING_EXCEPTION) {523CLEAR_PENDING_EXCEPTION;524return JVMTI_ERROR_INTERNAL;525}526527instanceKlassHandle loader_ik(THREAD, loader->klass());528529// Invoke the appendToClassPathForInstrumentation method - if the method530// is not found it means the loader doesn't support adding to the class path531// in the live phase.532{533JavaValue res(T_VOID);534JavaCalls::call_special(&res,535loader,536loader_ik,537vmSymbols::appendToClassPathForInstrumentation_name(),538vmSymbols::appendToClassPathForInstrumentation_signature(),539path,540THREAD);541if (HAS_PENDING_EXCEPTION) {542Symbol* ex_name = PENDING_EXCEPTION->klass()->name();543CLEAR_PENDING_EXCEPTION;544545if (ex_name == vmSymbols::java_lang_NoSuchMethodError()) {546return JVMTI_ERROR_CLASS_LOADER_UNSUPPORTED;547} else {548return JVMTI_ERROR_INTERNAL;549}550}551}552553return JVMTI_ERROR_NONE;554} else {555return JVMTI_ERROR_WRONG_PHASE;556}557} /* end AddToSystemClassLoaderSearch */558559//560// General functions561//562563// phase_ptr - pre-checked for NULL564jvmtiError565JvmtiEnv::GetPhase(jvmtiPhase* phase_ptr) {566*phase_ptr = get_phase();567return JVMTI_ERROR_NONE;568} /* end GetPhase */569570571jvmtiError572JvmtiEnv::DisposeEnvironment() {573dispose();574return JVMTI_ERROR_NONE;575} /* end DisposeEnvironment */576577578// data - NULL is a valid value, must be checked579jvmtiError580JvmtiEnv::SetEnvironmentLocalStorage(const void* data) {581set_env_local_storage(data);582return JVMTI_ERROR_NONE;583} /* end SetEnvironmentLocalStorage */584585586// data_ptr - pre-checked for NULL587jvmtiError588JvmtiEnv::GetEnvironmentLocalStorage(void** data_ptr) {589*data_ptr = (void*)get_env_local_storage();590return JVMTI_ERROR_NONE;591} /* end GetEnvironmentLocalStorage */592593// version_ptr - pre-checked for NULL594jvmtiError595JvmtiEnv::GetVersionNumber(jint* version_ptr) {596*version_ptr = JVMTI_VERSION;597return JVMTI_ERROR_NONE;598} /* end GetVersionNumber */599600601// name_ptr - pre-checked for NULL602jvmtiError603JvmtiEnv::GetErrorName(jvmtiError error, char** name_ptr) {604if (error < JVMTI_ERROR_NONE || error > JVMTI_ERROR_MAX) {605return JVMTI_ERROR_ILLEGAL_ARGUMENT;606}607const char *name = JvmtiUtil::error_name(error);608if (name == NULL) {609return JVMTI_ERROR_ILLEGAL_ARGUMENT;610}611size_t len = strlen(name) + 1;612jvmtiError err = allocate(len, (unsigned char**)name_ptr);613if (err == JVMTI_ERROR_NONE) {614memcpy(*name_ptr, name, len);615}616return err;617} /* end GetErrorName */618619620jvmtiError621JvmtiEnv::SetVerboseFlag(jvmtiVerboseFlag flag, jboolean value) {622switch (flag) {623case JVMTI_VERBOSE_OTHER:624// ignore625break;626case JVMTI_VERBOSE_CLASS:627TraceClassLoading = value != 0;628TraceClassUnloading = value != 0;629break;630case JVMTI_VERBOSE_GC:631PrintGC = value != 0;632break;633case JVMTI_VERBOSE_JNI:634PrintJNIResolving = value != 0;635break;636default:637return JVMTI_ERROR_ILLEGAL_ARGUMENT;638};639return JVMTI_ERROR_NONE;640} /* end SetVerboseFlag */641642643// format_ptr - pre-checked for NULL644jvmtiError645JvmtiEnv::GetJLocationFormat(jvmtiJlocationFormat* format_ptr) {646*format_ptr = JVMTI_JLOCATION_JVMBCI;647return JVMTI_ERROR_NONE;648} /* end GetJLocationFormat */649650//651// Thread functions652//653654// Threads_lock NOT held655// thread - NOT pre-checked656// thread_state_ptr - pre-checked for NULL657jvmtiError658JvmtiEnv::GetThreadState(jthread thread, jint* thread_state_ptr) {659jint state;660oop thread_oop;661JavaThread* thr;662663if (thread == NULL) {664thread_oop = JavaThread::current()->threadObj();665} else {666thread_oop = JNIHandles::resolve_external_guard(thread);667}668669if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::Thread_klass())) {670return JVMTI_ERROR_INVALID_THREAD;671}672673// get most state bits674state = (jint)java_lang_Thread::get_thread_status(thread_oop);675676// add more state bits677thr = java_lang_Thread::thread(thread_oop);678if (thr != NULL) {679JavaThreadState jts = thr->thread_state();680681if (thr->is_being_ext_suspended()) {682state |= JVMTI_THREAD_STATE_SUSPENDED;683}684if (jts == _thread_in_native) {685state |= JVMTI_THREAD_STATE_IN_NATIVE;686}687OSThread* osThread = thr->osthread();688if (osThread != NULL && osThread->interrupted()) {689state |= JVMTI_THREAD_STATE_INTERRUPTED;690}691}692693*thread_state_ptr = state;694return JVMTI_ERROR_NONE;695} /* end GetThreadState */696697698// thread_ptr - pre-checked for NULL699jvmtiError700JvmtiEnv::GetCurrentThread(jthread* thread_ptr) {701JavaThread* current_thread = JavaThread::current();702*thread_ptr = (jthread)JNIHandles::make_local(current_thread, current_thread->threadObj());703return JVMTI_ERROR_NONE;704} /* end GetCurrentThread */705706707// threads_count_ptr - pre-checked for NULL708// threads_ptr - pre-checked for NULL709jvmtiError710JvmtiEnv::GetAllThreads(jint* threads_count_ptr, jthread** threads_ptr) {711int nthreads = 0;712Handle *thread_objs = NULL;713ResourceMark rm;714HandleMark hm;715716// enumerate threads (including agent threads)717ThreadsListEnumerator tle(Thread::current(), true);718nthreads = tle.num_threads();719*threads_count_ptr = nthreads;720721if (nthreads == 0) {722*threads_ptr = NULL;723return JVMTI_ERROR_NONE;724}725726thread_objs = NEW_RESOURCE_ARRAY(Handle, nthreads);727NULL_CHECK(thread_objs, JVMTI_ERROR_OUT_OF_MEMORY);728729for (int i = 0; i < nthreads; i++) {730thread_objs[i] = Handle(tle.get_threadObj(i));731}732733// have to make global handles outside of Threads_lock734jthread *jthreads = new_jthreadArray(nthreads, thread_objs);735NULL_CHECK(jthreads, JVMTI_ERROR_OUT_OF_MEMORY);736737*threads_ptr = jthreads;738return JVMTI_ERROR_NONE;739} /* end GetAllThreads */740741742// Threads_lock NOT held, java_thread not protected by lock743// java_thread - pre-checked744jvmtiError745JvmtiEnv::SuspendThread(JavaThread* java_thread) {746// don't allow hidden thread suspend request.747if (java_thread->is_hidden_from_external_view()) {748return (JVMTI_ERROR_NONE);749}750751{752MutexLockerEx ml(java_thread->SR_lock(), Mutex::_no_safepoint_check_flag);753if (java_thread->is_external_suspend()) {754// don't allow nested external suspend requests.755return (JVMTI_ERROR_THREAD_SUSPENDED);756}757if (java_thread->is_exiting()) { // thread is in the process of exiting758return (JVMTI_ERROR_THREAD_NOT_ALIVE);759}760java_thread->set_external_suspend();761}762763if (!JvmtiSuspendControl::suspend(java_thread)) {764// the thread was in the process of exiting765return (JVMTI_ERROR_THREAD_NOT_ALIVE);766}767return JVMTI_ERROR_NONE;768} /* end SuspendThread */769770771// request_count - pre-checked to be greater than or equal to 0772// request_list - pre-checked for NULL773// results - pre-checked for NULL774jvmtiError775JvmtiEnv::SuspendThreadList(jint request_count, const jthread* request_list, jvmtiError* results) {776int needSafepoint = 0; // > 0 if we need a safepoint777for (int i = 0; i < request_count; i++) {778JavaThread *java_thread = get_JavaThread(request_list[i]);779if (java_thread == NULL) {780results[i] = JVMTI_ERROR_INVALID_THREAD;781continue;782}783// the thread has not yet run or has exited (not on threads list)784if (java_thread->threadObj() == NULL) {785results[i] = JVMTI_ERROR_THREAD_NOT_ALIVE;786continue;787}788if (java_lang_Thread::thread(java_thread->threadObj()) == NULL) {789results[i] = JVMTI_ERROR_THREAD_NOT_ALIVE;790continue;791}792// don't allow hidden thread suspend request.793if (java_thread->is_hidden_from_external_view()) {794results[i] = JVMTI_ERROR_NONE; // indicate successful suspend795continue;796}797798{799MutexLockerEx ml(java_thread->SR_lock(), Mutex::_no_safepoint_check_flag);800if (java_thread->is_external_suspend()) {801// don't allow nested external suspend requests.802results[i] = JVMTI_ERROR_THREAD_SUSPENDED;803continue;804}805if (java_thread->is_exiting()) { // thread is in the process of exiting806results[i] = JVMTI_ERROR_THREAD_NOT_ALIVE;807continue;808}809java_thread->set_external_suspend();810}811if (java_thread->thread_state() == _thread_in_native) {812// We need to try and suspend native threads here. Threads in813// other states will self-suspend on their next transition.814if (!JvmtiSuspendControl::suspend(java_thread)) {815// The thread was in the process of exiting. Force another816// safepoint to make sure that this thread transitions.817needSafepoint++;818results[i] = JVMTI_ERROR_THREAD_NOT_ALIVE;819continue;820}821} else {822needSafepoint++;823}824results[i] = JVMTI_ERROR_NONE; // indicate successful suspend825}826if (needSafepoint > 0) {827VM_ForceSafepoint vfs;828VMThread::execute(&vfs);829}830// per-thread suspend results returned via results parameter831return JVMTI_ERROR_NONE;832} /* end SuspendThreadList */833834835// Threads_lock NOT held, java_thread not protected by lock836// java_thread - pre-checked837jvmtiError838JvmtiEnv::ResumeThread(JavaThread* java_thread) {839// don't allow hidden thread resume request.840if (java_thread->is_hidden_from_external_view()) {841return JVMTI_ERROR_NONE;842}843844if (!java_thread->is_being_ext_suspended()) {845return JVMTI_ERROR_THREAD_NOT_SUSPENDED;846}847848if (!JvmtiSuspendControl::resume(java_thread)) {849return JVMTI_ERROR_INTERNAL;850}851return JVMTI_ERROR_NONE;852} /* end ResumeThread */853854855// request_count - pre-checked to be greater than or equal to 0856// request_list - pre-checked for NULL857// results - pre-checked for NULL858jvmtiError859JvmtiEnv::ResumeThreadList(jint request_count, const jthread* request_list, jvmtiError* results) {860for (int i = 0; i < request_count; i++) {861JavaThread *java_thread = get_JavaThread(request_list[i]);862if (java_thread == NULL) {863results[i] = JVMTI_ERROR_INVALID_THREAD;864continue;865}866// don't allow hidden thread resume request.867if (java_thread->is_hidden_from_external_view()) {868results[i] = JVMTI_ERROR_NONE; // indicate successful resume869continue;870}871if (!java_thread->is_being_ext_suspended()) {872results[i] = JVMTI_ERROR_THREAD_NOT_SUSPENDED;873continue;874}875876if (!JvmtiSuspendControl::resume(java_thread)) {877results[i] = JVMTI_ERROR_INTERNAL;878continue;879}880881results[i] = JVMTI_ERROR_NONE; // indicate successful suspend882}883// per-thread resume results returned via results parameter884return JVMTI_ERROR_NONE;885} /* end ResumeThreadList */886887888// Threads_lock NOT held, java_thread not protected by lock889// java_thread - pre-checked890jvmtiError891JvmtiEnv::StopThread(JavaThread* java_thread, jobject exception) {892oop e = JNIHandles::resolve_external_guard(exception);893NULL_CHECK(e, JVMTI_ERROR_NULL_POINTER);894895JavaThread::send_async_exception(java_thread->threadObj(), e);896897return JVMTI_ERROR_NONE;898899} /* end StopThread */900901902// Threads_lock NOT held903// thread - NOT pre-checked904jvmtiError905JvmtiEnv::InterruptThread(jthread thread) {906oop thread_oop = JNIHandles::resolve_external_guard(thread);907if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::Thread_klass()))908return JVMTI_ERROR_INVALID_THREAD;909910JavaThread* current_thread = JavaThread::current();911912// Todo: this is a duplicate of JVM_Interrupt; share code in future913// Ensure that the C++ Thread and OSThread structures aren't freed before we operate914MutexLockerEx ml(current_thread->threadObj() == thread_oop ? NULL : Threads_lock);915// We need to re-resolve the java_thread, since a GC might have happened during the916// acquire of the lock917918JavaThread* java_thread = java_lang_Thread::thread(JNIHandles::resolve_external_guard(thread));919NULL_CHECK(java_thread, JVMTI_ERROR_THREAD_NOT_ALIVE);920921Thread::interrupt(java_thread);922923return JVMTI_ERROR_NONE;924} /* end InterruptThread */925926927// Threads_lock NOT held928// thread - NOT pre-checked929// info_ptr - pre-checked for NULL930jvmtiError931JvmtiEnv::GetThreadInfo(jthread thread, jvmtiThreadInfo* info_ptr) {932ResourceMark rm;933HandleMark hm;934935JavaThread* current_thread = JavaThread::current();936937// if thread is NULL the current thread is used938oop thread_oop;939if (thread == NULL) {940thread_oop = current_thread->threadObj();941} else {942thread_oop = JNIHandles::resolve_external_guard(thread);943}944if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::Thread_klass()))945return JVMTI_ERROR_INVALID_THREAD;946947Handle thread_obj(current_thread, thread_oop);948Handle name;949ThreadPriority priority;950Handle thread_group;951Handle context_class_loader;952bool is_daemon;953954name = Handle(current_thread, java_lang_Thread::name(thread_obj()));955priority = java_lang_Thread::priority(thread_obj());956thread_group = Handle(current_thread, java_lang_Thread::threadGroup(thread_obj()));957is_daemon = java_lang_Thread::is_daemon(thread_obj());958959oop loader = java_lang_Thread::context_class_loader(thread_obj());960context_class_loader = Handle(current_thread, loader);961962{ const char *n;963964if (name() != NULL) {965n = java_lang_String::as_utf8_string(name());966} else {967n = UNICODE::as_utf8(NULL, 0);968}969970info_ptr->name = (char *) jvmtiMalloc(strlen(n)+1);971if (info_ptr->name == NULL)972return JVMTI_ERROR_OUT_OF_MEMORY;973974strcpy(info_ptr->name, n);975}976info_ptr->is_daemon = is_daemon;977info_ptr->priority = priority;978979info_ptr->context_class_loader = (context_class_loader.is_null()) ? NULL :980jni_reference(context_class_loader);981info_ptr->thread_group = jni_reference(thread_group);982983return JVMTI_ERROR_NONE;984} /* end GetThreadInfo */985986987// Threads_lock NOT held, java_thread not protected by lock988// java_thread - pre-checked989// owned_monitor_count_ptr - pre-checked for NULL990// owned_monitors_ptr - pre-checked for NULL991jvmtiError992JvmtiEnv::GetOwnedMonitorInfo(JavaThread* java_thread, jint* owned_monitor_count_ptr, jobject** owned_monitors_ptr) {993jvmtiError err = JVMTI_ERROR_NONE;994JavaThread* calling_thread = JavaThread::current();995996// growable array of jvmti monitors info on the C-heap997GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list =998new (ResourceObj::C_HEAP, mtInternal) GrowableArray<jvmtiMonitorStackDepthInfo*>(1, true);9991000// It is only safe to perform the direct operation on the current1001// thread. All other usage needs to use a vm-safepoint-op for safety.1002if (java_thread == calling_thread) {1003err = get_owned_monitors(calling_thread, java_thread, owned_monitors_list);1004} else {1005// JVMTI get monitors info at safepoint. Do not require target thread to1006// be suspended.1007VM_GetOwnedMonitorInfo op(this, calling_thread, java_thread, owned_monitors_list);1008VMThread::execute(&op);1009err = op.result();1010}1011jint owned_monitor_count = owned_monitors_list->length();1012if (err == JVMTI_ERROR_NONE) {1013if ((err = allocate(owned_monitor_count * sizeof(jobject *),1014(unsigned char**)owned_monitors_ptr)) == JVMTI_ERROR_NONE) {1015// copy into the returned array1016for (int i = 0; i < owned_monitor_count; i++) {1017(*owned_monitors_ptr)[i] =1018((jvmtiMonitorStackDepthInfo*)owned_monitors_list->at(i))->monitor;1019}1020*owned_monitor_count_ptr = owned_monitor_count;1021}1022}1023// clean up.1024for (int i = 0; i < owned_monitor_count; i++) {1025deallocate((unsigned char*)owned_monitors_list->at(i));1026}1027delete owned_monitors_list;10281029return err;1030} /* end GetOwnedMonitorInfo */103110321033// Threads_lock NOT held, java_thread not protected by lock1034// java_thread - pre-checked1035// monitor_info_count_ptr - pre-checked for NULL1036// monitor_info_ptr - pre-checked for NULL1037jvmtiError1038JvmtiEnv::GetOwnedMonitorStackDepthInfo(JavaThread* java_thread, jint* monitor_info_count_ptr, jvmtiMonitorStackDepthInfo** monitor_info_ptr) {1039jvmtiError err = JVMTI_ERROR_NONE;1040JavaThread* calling_thread = JavaThread::current();10411042// growable array of jvmti monitors info on the C-heap1043GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list =1044new (ResourceObj::C_HEAP, mtInternal) GrowableArray<jvmtiMonitorStackDepthInfo*>(1, true);10451046// It is only safe to perform the direct operation on the current1047// thread. All other usage needs to use a vm-safepoint-op for safety.1048if (java_thread == calling_thread) {1049err = get_owned_monitors(calling_thread, java_thread, owned_monitors_list);1050} else {1051// JVMTI get owned monitors info at safepoint. Do not require target thread to1052// be suspended.1053VM_GetOwnedMonitorInfo op(this, calling_thread, java_thread, owned_monitors_list);1054VMThread::execute(&op);1055err = op.result();1056}10571058jint owned_monitor_count = owned_monitors_list->length();1059if (err == JVMTI_ERROR_NONE) {1060if ((err = allocate(owned_monitor_count * sizeof(jvmtiMonitorStackDepthInfo),1061(unsigned char**)monitor_info_ptr)) == JVMTI_ERROR_NONE) {1062// copy to output array.1063for (int i = 0; i < owned_monitor_count; i++) {1064(*monitor_info_ptr)[i].monitor =1065((jvmtiMonitorStackDepthInfo*)owned_monitors_list->at(i))->monitor;1066(*monitor_info_ptr)[i].stack_depth =1067((jvmtiMonitorStackDepthInfo*)owned_monitors_list->at(i))->stack_depth;1068}1069}1070*monitor_info_count_ptr = owned_monitor_count;1071}10721073// clean up.1074for (int i = 0; i < owned_monitor_count; i++) {1075deallocate((unsigned char*)owned_monitors_list->at(i));1076}1077delete owned_monitors_list;10781079return err;1080} /* end GetOwnedMonitorStackDepthInfo */108110821083// Threads_lock NOT held, java_thread not protected by lock1084// java_thread - pre-checked1085// monitor_ptr - pre-checked for NULL1086jvmtiError1087JvmtiEnv::GetCurrentContendedMonitor(JavaThread* java_thread, jobject* monitor_ptr) {1088jvmtiError err = JVMTI_ERROR_NONE;1089JavaThread* calling_thread = JavaThread::current();10901091// It is only safe to perform the direct operation on the current1092// thread. All other usage needs to use a vm-safepoint-op for safety.1093if (java_thread == calling_thread) {1094err = get_current_contended_monitor(calling_thread, java_thread, monitor_ptr);1095} else {1096// get contended monitor information at safepoint.1097VM_GetCurrentContendedMonitor op(this, calling_thread, java_thread, monitor_ptr);1098VMThread::execute(&op);1099err = op.result();1100}1101return err;1102} /* end GetCurrentContendedMonitor */110311041105// Threads_lock NOT held1106// thread - NOT pre-checked1107// proc - pre-checked for NULL1108// arg - NULL is a valid value, must be checked1109jvmtiError1110JvmtiEnv::RunAgentThread(jthread thread, jvmtiStartFunction proc, const void* arg, jint priority) {1111oop thread_oop = JNIHandles::resolve_external_guard(thread);1112if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::Thread_klass())) {1113return JVMTI_ERROR_INVALID_THREAD;1114}1115if (priority < JVMTI_THREAD_MIN_PRIORITY || priority > JVMTI_THREAD_MAX_PRIORITY) {1116return JVMTI_ERROR_INVALID_PRIORITY;1117}11181119//Thread-self1120JavaThread* current_thread = JavaThread::current();11211122Handle thread_hndl(current_thread, thread_oop);1123{1124MutexLocker mu(Threads_lock); // grab Threads_lock11251126JvmtiAgentThread *new_thread = new JvmtiAgentThread(this, proc, arg);11271128// At this point it may be possible that no osthread was created for the1129// JavaThread due to lack of memory.1130if (new_thread == NULL || new_thread->osthread() == NULL) {1131if (new_thread) delete new_thread;1132return JVMTI_ERROR_OUT_OF_MEMORY;1133}11341135java_lang_Thread::set_thread(thread_hndl(), new_thread);1136java_lang_Thread::set_priority(thread_hndl(), (ThreadPriority)priority);1137java_lang_Thread::set_daemon(thread_hndl());11381139new_thread->set_threadObj(thread_hndl());1140Threads::add(new_thread);1141Thread::start(new_thread);1142} // unlock Threads_lock11431144return JVMTI_ERROR_NONE;1145} /* end RunAgentThread */11461147//1148// Thread Group functions1149//11501151// group_count_ptr - pre-checked for NULL1152// groups_ptr - pre-checked for NULL1153jvmtiError1154JvmtiEnv::GetTopThreadGroups(jint* group_count_ptr, jthreadGroup** groups_ptr) {1155JavaThread* current_thread = JavaThread::current();11561157// Only one top level thread group now.1158*group_count_ptr = 1;11591160// Allocate memory to store global-refs to the thread groups.1161// Assume this area is freed by caller.1162*groups_ptr = (jthreadGroup *) jvmtiMalloc((sizeof(jthreadGroup)) * (*group_count_ptr));11631164NULL_CHECK(*groups_ptr, JVMTI_ERROR_OUT_OF_MEMORY);11651166// Convert oop to Handle, then convert Handle to global-ref.1167{1168HandleMark hm(current_thread);1169Handle system_thread_group(current_thread, Universe::system_thread_group());1170*groups_ptr[0] = jni_reference(system_thread_group);1171}11721173return JVMTI_ERROR_NONE;1174} /* end GetTopThreadGroups */117511761177// info_ptr - pre-checked for NULL1178jvmtiError1179JvmtiEnv::GetThreadGroupInfo(jthreadGroup group, jvmtiThreadGroupInfo* info_ptr) {1180ResourceMark rm;1181HandleMark hm;11821183JavaThread* current_thread = JavaThread::current();11841185Handle group_obj (current_thread, JNIHandles::resolve_external_guard(group));1186NULL_CHECK(group_obj(), JVMTI_ERROR_INVALID_THREAD_GROUP);11871188typeArrayHandle name;1189Handle parent_group;1190bool is_daemon;1191ThreadPriority max_priority;11921193name = typeArrayHandle(current_thread,1194java_lang_ThreadGroup::name(group_obj()));1195parent_group = Handle(current_thread, java_lang_ThreadGroup::parent(group_obj()));1196is_daemon = java_lang_ThreadGroup::is_daemon(group_obj());1197max_priority = java_lang_ThreadGroup::maxPriority(group_obj());11981199info_ptr->is_daemon = is_daemon;1200info_ptr->max_priority = max_priority;1201info_ptr->parent = jni_reference(parent_group);12021203if (name() != NULL) {1204const char* n = UNICODE::as_utf8((jchar*) name->base(T_CHAR), name->length());1205info_ptr->name = (char *)jvmtiMalloc(strlen(n)+1);1206NULL_CHECK(info_ptr->name, JVMTI_ERROR_OUT_OF_MEMORY);1207strcpy(info_ptr->name, n);1208} else {1209info_ptr->name = NULL;1210}12111212return JVMTI_ERROR_NONE;1213} /* end GetThreadGroupInfo */121412151216// thread_count_ptr - pre-checked for NULL1217// threads_ptr - pre-checked for NULL1218// group_count_ptr - pre-checked for NULL1219// groups_ptr - pre-checked for NULL1220jvmtiError1221JvmtiEnv::GetThreadGroupChildren(jthreadGroup group, jint* thread_count_ptr, jthread** threads_ptr, jint* group_count_ptr, jthreadGroup** groups_ptr) {1222JavaThread* current_thread = JavaThread::current();1223oop group_obj = (oop) JNIHandles::resolve_external_guard(group);1224NULL_CHECK(group_obj, JVMTI_ERROR_INVALID_THREAD_GROUP);12251226Handle *thread_objs = NULL;1227Handle *group_objs = NULL;1228int nthreads = 0;1229int ngroups = 0;1230int hidden_threads = 0;12311232ResourceMark rm;1233HandleMark hm;12341235Handle group_hdl(current_thread, group_obj);12361237{1238ObjectLocker ol(group_hdl, current_thread);1239nthreads = java_lang_ThreadGroup::nthreads(group_hdl());1240ngroups = java_lang_ThreadGroup::ngroups(group_hdl());12411242if (nthreads > 0) {1243objArrayOop threads = java_lang_ThreadGroup::threads(group_hdl());1244assert(nthreads <= threads->length(), "too many threads");1245thread_objs = NEW_RESOURCE_ARRAY(Handle,nthreads);1246for (int i = 0, j = 0; i < nthreads; i++) {1247oop thread_obj = threads->obj_at(i);1248assert(thread_obj != NULL, "thread_obj is NULL");1249JavaThread *javathread = java_lang_Thread::thread(thread_obj);1250// Filter out hidden java threads.1251if (javathread != NULL && javathread->is_hidden_from_external_view()) {1252hidden_threads++;1253continue;1254}1255thread_objs[j++] = Handle(current_thread, thread_obj);1256}1257nthreads -= hidden_threads;1258}1259if (ngroups > 0) {1260objArrayOop groups = java_lang_ThreadGroup::groups(group_hdl());1261assert(ngroups <= groups->length(), "too many threads");1262group_objs = NEW_RESOURCE_ARRAY(Handle,ngroups);1263for (int i = 0; i < ngroups; i++) {1264oop group_obj = groups->obj_at(i);1265assert(group_obj != NULL, "group_obj != NULL");1266group_objs[i] = Handle(current_thread, group_obj);1267}1268}1269} // ThreadGroup unlocked here12701271*group_count_ptr = ngroups;1272*thread_count_ptr = nthreads;1273*threads_ptr = new_jthreadArray(nthreads, thread_objs);1274*groups_ptr = new_jthreadGroupArray(ngroups, group_objs);1275if ((nthreads > 0) && (*threads_ptr == NULL)) {1276return JVMTI_ERROR_OUT_OF_MEMORY;1277}1278if ((ngroups > 0) && (*groups_ptr == NULL)) {1279return JVMTI_ERROR_OUT_OF_MEMORY;1280}12811282return JVMTI_ERROR_NONE;1283} /* end GetThreadGroupChildren */128412851286//1287// Stack Frame functions1288//12891290// Threads_lock NOT held, java_thread not protected by lock1291// java_thread - pre-checked1292// max_frame_count - pre-checked to be greater than or equal to 01293// frame_buffer - pre-checked for NULL1294// count_ptr - pre-checked for NULL1295jvmtiError1296JvmtiEnv::GetStackTrace(JavaThread* java_thread, jint start_depth, jint max_frame_count, jvmtiFrameInfo* frame_buffer, jint* count_ptr) {1297jvmtiError err = JVMTI_ERROR_NONE;12981299// It is only safe to perform the direct operation on the current1300// thread. All other usage needs to use a vm-safepoint-op for safety.1301if (java_thread == JavaThread::current()) {1302err = get_stack_trace(java_thread, start_depth, max_frame_count, frame_buffer, count_ptr);1303} else {1304// JVMTI get stack trace at safepoint. Do not require target thread to1305// be suspended.1306VM_GetStackTrace op(this, java_thread, start_depth, max_frame_count, frame_buffer, count_ptr);1307VMThread::execute(&op);1308err = op.result();1309}13101311return err;1312} /* end GetStackTrace */131313141315// max_frame_count - pre-checked to be greater than or equal to 01316// stack_info_ptr - pre-checked for NULL1317// thread_count_ptr - pre-checked for NULL1318jvmtiError1319JvmtiEnv::GetAllStackTraces(jint max_frame_count, jvmtiStackInfo** stack_info_ptr, jint* thread_count_ptr) {1320jvmtiError err = JVMTI_ERROR_NONE;1321JavaThread* calling_thread = JavaThread::current();13221323// JVMTI get stack traces at safepoint.1324VM_GetAllStackTraces op(this, calling_thread, max_frame_count);1325VMThread::execute(&op);1326*thread_count_ptr = op.final_thread_count();1327*stack_info_ptr = op.stack_info();1328err = op.result();1329return err;1330} /* end GetAllStackTraces */133113321333// thread_count - pre-checked to be greater than or equal to 01334// thread_list - pre-checked for NULL1335// max_frame_count - pre-checked to be greater than or equal to 01336// stack_info_ptr - pre-checked for NULL1337jvmtiError1338JvmtiEnv::GetThreadListStackTraces(jint thread_count, const jthread* thread_list, jint max_frame_count, jvmtiStackInfo** stack_info_ptr) {1339jvmtiError err = JVMTI_ERROR_NONE;1340// JVMTI get stack traces at safepoint.1341VM_GetThreadListStackTraces op(this, thread_count, thread_list, max_frame_count);1342VMThread::execute(&op);1343err = op.result();1344if (err == JVMTI_ERROR_NONE) {1345*stack_info_ptr = op.stack_info();1346}1347return err;1348} /* end GetThreadListStackTraces */134913501351// Threads_lock NOT held, java_thread not protected by lock1352// java_thread - pre-checked1353// count_ptr - pre-checked for NULL1354jvmtiError1355JvmtiEnv::GetFrameCount(JavaThread* java_thread, jint* count_ptr) {1356jvmtiError err = JVMTI_ERROR_NONE;13571358// retrieve or create JvmtiThreadState.1359JvmtiThreadState* state = JvmtiThreadState::state_for(java_thread);1360if (state == NULL) {1361return JVMTI_ERROR_THREAD_NOT_ALIVE;1362}1363uint32_t debug_bits = 0;1364if (is_thread_fully_suspended(java_thread, true, &debug_bits)) {1365err = get_frame_count(state, count_ptr);1366} else {1367// get java stack frame count at safepoint.1368VM_GetFrameCount op(this, state, count_ptr);1369VMThread::execute(&op);1370err = op.result();1371}1372return err;1373} /* end GetFrameCount */137413751376// Threads_lock NOT held, java_thread not protected by lock1377// java_thread - pre-checked1378jvmtiError1379JvmtiEnv::PopFrame(JavaThread* java_thread) {1380JavaThread* current_thread = JavaThread::current();1381HandleMark hm(current_thread);1382uint32_t debug_bits = 0;13831384// retrieve or create the state1385JvmtiThreadState* state = JvmtiThreadState::state_for(java_thread);1386if (state == NULL) {1387return JVMTI_ERROR_THREAD_NOT_ALIVE;1388}13891390// Check if java_thread is fully suspended1391if (!is_thread_fully_suspended(java_thread, true /* wait for suspend completion */, &debug_bits)) {1392return JVMTI_ERROR_THREAD_NOT_SUSPENDED;1393}1394// Check to see if a PopFrame was already in progress1395if (java_thread->popframe_condition() != JavaThread::popframe_inactive) {1396// Probably possible for JVMTI clients to trigger this, but the1397// JPDA backend shouldn't allow this to happen1398return JVMTI_ERROR_INTERNAL;1399}14001401{1402// Was workaround bug1403// 4812902: popFrame hangs if the method is waiting at a synchronize1404// Catch this condition and return an error to avoid hanging.1405// Now JVMTI spec allows an implementation to bail out with an opaque frame error.1406OSThread* osThread = java_thread->osthread();1407if (osThread->get_state() == MONITOR_WAIT) {1408return JVMTI_ERROR_OPAQUE_FRAME;1409}1410}14111412{1413ResourceMark rm(current_thread);1414// Check if there are more than one Java frame in this thread, that the top two frames1415// are Java (not native) frames, and that there is no intervening VM frame1416int frame_count = 0;1417bool is_interpreted[2];1418intptr_t *frame_sp[2];1419// The 2-nd arg of constructor is needed to stop iterating at java entry frame.1420for (vframeStream vfs(java_thread, true); !vfs.at_end(); vfs.next()) {1421methodHandle mh(current_thread, vfs.method());1422if (mh->is_native()) return(JVMTI_ERROR_OPAQUE_FRAME);1423is_interpreted[frame_count] = vfs.is_interpreted_frame();1424frame_sp[frame_count] = vfs.frame_id();1425if (++frame_count > 1) break;1426}1427if (frame_count < 2) {1428// We haven't found two adjacent non-native Java frames on the top.1429// There can be two situations here:1430// 1. There are no more java frames1431// 2. Two top java frames are separated by non-java native frames1432if(vframeFor(java_thread, 1) == NULL) {1433return JVMTI_ERROR_NO_MORE_FRAMES;1434} else {1435// Intervening non-java native or VM frames separate java frames.1436// Current implementation does not support this. See bug #5031735.1437// In theory it is possible to pop frames in such cases.1438return JVMTI_ERROR_OPAQUE_FRAME;1439}1440}14411442// If any of the top 2 frames is a compiled one, need to deoptimize it1443for (int i = 0; i < 2; i++) {1444if (!is_interpreted[i]) {1445Deoptimization::deoptimize_frame(java_thread, frame_sp[i]);1446}1447}14481449// Update the thread state to reflect that the top frame is popped1450// so that cur_stack_depth is maintained properly and all frameIDs1451// are invalidated.1452// The current frame will be popped later when the suspended thread1453// is resumed and right before returning from VM to Java.1454// (see call_VM_base() in assembler_<cpu>.cpp).14551456// It's fine to update the thread state here because no JVMTI events1457// shall be posted for this PopFrame.14581459state->update_for_pop_top_frame();1460java_thread->set_popframe_condition(JavaThread::popframe_pending_bit);1461// Set pending step flag for this popframe and it is cleared when next1462// step event is posted.1463state->set_pending_step_for_popframe();1464}14651466return JVMTI_ERROR_NONE;1467} /* end PopFrame */146814691470// Threads_lock NOT held, java_thread not protected by lock1471// java_thread - pre-checked1472// java_thread - unchecked1473// depth - pre-checked as non-negative1474// method_ptr - pre-checked for NULL1475// location_ptr - pre-checked for NULL1476jvmtiError1477JvmtiEnv::GetFrameLocation(JavaThread* java_thread, jint depth, jmethodID* method_ptr, jlocation* location_ptr) {1478jvmtiError err = JVMTI_ERROR_NONE;1479uint32_t debug_bits = 0;14801481if (is_thread_fully_suspended(java_thread, true, &debug_bits)) {1482err = get_frame_location(java_thread, depth, method_ptr, location_ptr);1483} else {1484// JVMTI get java stack frame location at safepoint.1485VM_GetFrameLocation op(this, java_thread, depth, method_ptr, location_ptr);1486VMThread::execute(&op);1487err = op.result();1488}1489return err;1490} /* end GetFrameLocation */149114921493// Threads_lock NOT held, java_thread not protected by lock1494// java_thread - pre-checked1495// java_thread - unchecked1496// depth - pre-checked as non-negative1497jvmtiError1498JvmtiEnv::NotifyFramePop(JavaThread* java_thread, jint depth) {1499ResourceMark rm;1500uint32_t debug_bits = 0;15011502JvmtiThreadState *state = JvmtiThreadState::state_for(java_thread);1503if (state == NULL) {1504return JVMTI_ERROR_THREAD_NOT_ALIVE;1505}15061507if (!JvmtiEnv::is_thread_fully_suspended(java_thread, true, &debug_bits)) {1508return JVMTI_ERROR_THREAD_NOT_SUSPENDED;1509}15101511if (TraceJVMTICalls) {1512JvmtiSuspendControl::print();1513}15141515vframe *vf = vframeFor(java_thread, depth);1516if (vf == NULL) {1517return JVMTI_ERROR_NO_MORE_FRAMES;1518}15191520if (!vf->is_java_frame() || ((javaVFrame*) vf)->method()->is_native()) {1521return JVMTI_ERROR_OPAQUE_FRAME;1522}15231524assert(vf->frame_pointer() != NULL, "frame pointer mustn't be NULL");15251526int frame_number = state->count_frames() - depth;1527state->env_thread_state(this)->set_frame_pop(frame_number);15281529return JVMTI_ERROR_NONE;1530} /* end NotifyFramePop */153115321533//1534// Force Early Return functions1535//15361537// Threads_lock NOT held, java_thread not protected by lock1538// java_thread - pre-checked1539jvmtiError1540JvmtiEnv::ForceEarlyReturnObject(JavaThread* java_thread, jobject value) {1541jvalue val;1542val.l = value;1543return force_early_return(java_thread, val, atos);1544} /* end ForceEarlyReturnObject */154515461547// Threads_lock NOT held, java_thread not protected by lock1548// java_thread - pre-checked1549jvmtiError1550JvmtiEnv::ForceEarlyReturnInt(JavaThread* java_thread, jint value) {1551jvalue val;1552val.i = value;1553return force_early_return(java_thread, val, itos);1554} /* end ForceEarlyReturnInt */155515561557// Threads_lock NOT held, java_thread not protected by lock1558// java_thread - pre-checked1559jvmtiError1560JvmtiEnv::ForceEarlyReturnLong(JavaThread* java_thread, jlong value) {1561jvalue val;1562val.j = value;1563return force_early_return(java_thread, val, ltos);1564} /* end ForceEarlyReturnLong */156515661567// Threads_lock NOT held, java_thread not protected by lock1568// java_thread - pre-checked1569jvmtiError1570JvmtiEnv::ForceEarlyReturnFloat(JavaThread* java_thread, jfloat value) {1571jvalue val;1572val.f = value;1573return force_early_return(java_thread, val, ftos);1574} /* end ForceEarlyReturnFloat */157515761577// Threads_lock NOT held, java_thread not protected by lock1578// java_thread - pre-checked1579jvmtiError1580JvmtiEnv::ForceEarlyReturnDouble(JavaThread* java_thread, jdouble value) {1581jvalue val;1582val.d = value;1583return force_early_return(java_thread, val, dtos);1584} /* end ForceEarlyReturnDouble */158515861587// Threads_lock NOT held, java_thread not protected by lock1588// java_thread - pre-checked1589jvmtiError1590JvmtiEnv::ForceEarlyReturnVoid(JavaThread* java_thread) {1591jvalue val;1592val.j = 0L;1593return force_early_return(java_thread, val, vtos);1594} /* end ForceEarlyReturnVoid */159515961597//1598// Heap functions1599//16001601// klass - NULL is a valid value, must be checked1602// initial_object - NULL is a valid value, must be checked1603// callbacks - pre-checked for NULL1604// user_data - NULL is a valid value, must be checked1605jvmtiError1606JvmtiEnv::FollowReferences(jint heap_filter, jclass klass, jobject initial_object, const jvmtiHeapCallbacks* callbacks, const void* user_data) {1607// check klass if provided1608Klass* k_oop = NULL;1609if (klass != NULL) {1610oop k_mirror = JNIHandles::resolve_external_guard(klass);1611if (k_mirror == NULL) {1612return JVMTI_ERROR_INVALID_CLASS;1613}1614if (java_lang_Class::is_primitive(k_mirror)) {1615return JVMTI_ERROR_NONE;1616}1617k_oop = java_lang_Class::as_Klass(k_mirror);1618if (k_oop == NULL) {1619return JVMTI_ERROR_INVALID_CLASS;1620}1621}16221623if (initial_object != NULL) {1624oop init_obj = JNIHandles::resolve_external_guard(initial_object);1625if (init_obj == NULL) {1626return JVMTI_ERROR_INVALID_OBJECT;1627}1628}16291630Thread *thread = Thread::current();1631HandleMark hm(thread);1632KlassHandle kh (thread, k_oop);16331634TraceTime t("FollowReferences", TraceJVMTIObjectTagging);1635JvmtiTagMap::tag_map_for(this)->follow_references(heap_filter, kh, initial_object, callbacks, user_data);1636return JVMTI_ERROR_NONE;1637} /* end FollowReferences */163816391640// klass - NULL is a valid value, must be checked1641// callbacks - pre-checked for NULL1642// user_data - NULL is a valid value, must be checked1643jvmtiError1644JvmtiEnv::IterateThroughHeap(jint heap_filter, jclass klass, const jvmtiHeapCallbacks* callbacks, const void* user_data) {1645// check klass if provided1646Klass* k_oop = NULL;1647if (klass != NULL) {1648oop k_mirror = JNIHandles::resolve_external_guard(klass);1649if (k_mirror == NULL) {1650return JVMTI_ERROR_INVALID_CLASS;1651}1652if (java_lang_Class::is_primitive(k_mirror)) {1653return JVMTI_ERROR_NONE;1654}1655k_oop = java_lang_Class::as_Klass(k_mirror);1656if (k_oop == NULL) {1657return JVMTI_ERROR_INVALID_CLASS;1658}1659}16601661Thread *thread = Thread::current();1662HandleMark hm(thread);1663KlassHandle kh (thread, k_oop);16641665TraceTime t("IterateThroughHeap", TraceJVMTIObjectTagging);1666JvmtiTagMap::tag_map_for(this)->iterate_through_heap(heap_filter, kh, callbacks, user_data);1667return JVMTI_ERROR_NONE;1668} /* end IterateThroughHeap */166916701671// tag_ptr - pre-checked for NULL1672jvmtiError1673JvmtiEnv::GetTag(jobject object, jlong* tag_ptr) {1674oop o = JNIHandles::resolve_external_guard(object);1675NULL_CHECK(o, JVMTI_ERROR_INVALID_OBJECT);1676*tag_ptr = JvmtiTagMap::tag_map_for(this)->get_tag(object);1677return JVMTI_ERROR_NONE;1678} /* end GetTag */167916801681jvmtiError1682JvmtiEnv::SetTag(jobject object, jlong tag) {1683oop o = JNIHandles::resolve_external_guard(object);1684NULL_CHECK(o, JVMTI_ERROR_INVALID_OBJECT);1685JvmtiTagMap::tag_map_for(this)->set_tag(object, tag);1686return JVMTI_ERROR_NONE;1687} /* end SetTag */168816891690// tag_count - pre-checked to be greater than or equal to 01691// tags - pre-checked for NULL1692// count_ptr - pre-checked for NULL1693// object_result_ptr - NULL is a valid value, must be checked1694// tag_result_ptr - NULL is a valid value, must be checked1695jvmtiError1696JvmtiEnv::GetObjectsWithTags(jint tag_count, const jlong* tags, jint* count_ptr, jobject** object_result_ptr, jlong** tag_result_ptr) {1697TraceTime t("GetObjectsWithTags", TraceJVMTIObjectTagging);1698return JvmtiTagMap::tag_map_for(this)->get_objects_with_tags((jlong*)tags, tag_count, count_ptr, object_result_ptr, tag_result_ptr);1699} /* end GetObjectsWithTags */170017011702jvmtiError1703JvmtiEnv::ForceGarbageCollection() {1704Universe::heap()->collect(GCCause::_jvmti_force_gc);1705return JVMTI_ERROR_NONE;1706} /* end ForceGarbageCollection */170717081709//1710// Heap (1.0) functions1711//17121713// object_reference_callback - pre-checked for NULL1714// user_data - NULL is a valid value, must be checked1715jvmtiError1716JvmtiEnv::IterateOverObjectsReachableFromObject(jobject object, jvmtiObjectReferenceCallback object_reference_callback, const void* user_data) {1717oop o = JNIHandles::resolve_external_guard(object);1718NULL_CHECK(o, JVMTI_ERROR_INVALID_OBJECT);1719JvmtiTagMap::tag_map_for(this)->iterate_over_objects_reachable_from_object(object, object_reference_callback, user_data);1720return JVMTI_ERROR_NONE;1721} /* end IterateOverObjectsReachableFromObject */172217231724// heap_root_callback - NULL is a valid value, must be checked1725// stack_ref_callback - NULL is a valid value, must be checked1726// object_ref_callback - NULL is a valid value, must be checked1727// user_data - NULL is a valid value, must be checked1728jvmtiError1729JvmtiEnv::IterateOverReachableObjects(jvmtiHeapRootCallback heap_root_callback, jvmtiStackReferenceCallback stack_ref_callback, jvmtiObjectReferenceCallback object_ref_callback, const void* user_data) {1730TraceTime t("IterateOverReachableObjects", TraceJVMTIObjectTagging);1731JvmtiTagMap::tag_map_for(this)->iterate_over_reachable_objects(heap_root_callback, stack_ref_callback, object_ref_callback, user_data);1732return JVMTI_ERROR_NONE;1733} /* end IterateOverReachableObjects */173417351736// heap_object_callback - pre-checked for NULL1737// user_data - NULL is a valid value, must be checked1738jvmtiError1739JvmtiEnv::IterateOverHeap(jvmtiHeapObjectFilter object_filter, jvmtiHeapObjectCallback heap_object_callback, const void* user_data) {1740TraceTime t("IterateOverHeap", TraceJVMTIObjectTagging);1741Thread *thread = Thread::current();1742HandleMark hm(thread);1743JvmtiTagMap::tag_map_for(this)->iterate_over_heap(object_filter, KlassHandle(), heap_object_callback, user_data);1744return JVMTI_ERROR_NONE;1745} /* end IterateOverHeap */174617471748// k_mirror - may be primitive, this must be checked1749// heap_object_callback - pre-checked for NULL1750// user_data - NULL is a valid value, must be checked1751jvmtiError1752JvmtiEnv::IterateOverInstancesOfClass(oop k_mirror, jvmtiHeapObjectFilter object_filter, jvmtiHeapObjectCallback heap_object_callback, const void* user_data) {1753if (java_lang_Class::is_primitive(k_mirror)) {1754// DO PRIMITIVE CLASS PROCESSING1755return JVMTI_ERROR_NONE;1756}1757Klass* k_oop = java_lang_Class::as_Klass(k_mirror);1758if (k_oop == NULL) {1759return JVMTI_ERROR_INVALID_CLASS;1760}1761Thread *thread = Thread::current();1762HandleMark hm(thread);1763KlassHandle klass (thread, k_oop);1764TraceTime t("IterateOverInstancesOfClass", TraceJVMTIObjectTagging);1765JvmtiTagMap::tag_map_for(this)->iterate_over_heap(object_filter, klass, heap_object_callback, user_data);1766return JVMTI_ERROR_NONE;1767} /* end IterateOverInstancesOfClass */176817691770//1771// Local Variable functions1772//17731774// Threads_lock NOT held, java_thread not protected by lock1775// java_thread - pre-checked1776// java_thread - unchecked1777// depth - pre-checked as non-negative1778// value_ptr - pre-checked for NULL1779jvmtiError1780JvmtiEnv::GetLocalObject(JavaThread* java_thread, jint depth, jint slot, jobject* value_ptr) {1781JavaThread* current_thread = JavaThread::current();1782// rm object is created to clean up the javaVFrame created in1783// doit_prologue(), but after doit() is finished with it.1784ResourceMark rm(current_thread);17851786VM_GetOrSetLocal op(java_thread, current_thread, depth, slot);1787VMThread::execute(&op);1788jvmtiError err = op.result();1789if (err != JVMTI_ERROR_NONE) {1790return err;1791} else {1792*value_ptr = op.value().l;1793return JVMTI_ERROR_NONE;1794}1795} /* end GetLocalObject */17961797// Threads_lock NOT held, java_thread not protected by lock1798// java_thread - pre-checked1799// java_thread - unchecked1800// depth - pre-checked as non-negative1801// value - pre-checked for NULL1802jvmtiError1803JvmtiEnv::GetLocalInstance(JavaThread* java_thread, jint depth, jobject* value_ptr){1804JavaThread* current_thread = JavaThread::current();1805// rm object is created to clean up the javaVFrame created in1806// doit_prologue(), but after doit() is finished with it.1807ResourceMark rm(current_thread);18081809VM_GetReceiver op(java_thread, current_thread, depth);1810VMThread::execute(&op);1811jvmtiError err = op.result();1812if (err != JVMTI_ERROR_NONE) {1813return err;1814} else {1815*value_ptr = op.value().l;1816return JVMTI_ERROR_NONE;1817}1818} /* end GetLocalInstance */181918201821// Threads_lock NOT held, java_thread not protected by lock1822// java_thread - pre-checked1823// java_thread - unchecked1824// depth - pre-checked as non-negative1825// value_ptr - pre-checked for NULL1826jvmtiError1827JvmtiEnv::GetLocalInt(JavaThread* java_thread, jint depth, jint slot, jint* value_ptr) {1828// rm object is created to clean up the javaVFrame created in1829// doit_prologue(), but after doit() is finished with it.1830ResourceMark rm;18311832VM_GetOrSetLocal op(java_thread, depth, slot, T_INT);1833VMThread::execute(&op);1834*value_ptr = op.value().i;1835return op.result();1836} /* end GetLocalInt */183718381839// Threads_lock NOT held, java_thread not protected by lock1840// java_thread - pre-checked1841// java_thread - unchecked1842// depth - pre-checked as non-negative1843// value_ptr - pre-checked for NULL1844jvmtiError1845JvmtiEnv::GetLocalLong(JavaThread* java_thread, jint depth, jint slot, jlong* value_ptr) {1846// rm object is created to clean up the javaVFrame created in1847// doit_prologue(), but after doit() is finished with it.1848ResourceMark rm;18491850VM_GetOrSetLocal op(java_thread, depth, slot, T_LONG);1851VMThread::execute(&op);1852*value_ptr = op.value().j;1853return op.result();1854} /* end GetLocalLong */185518561857// Threads_lock NOT held, java_thread not protected by lock1858// java_thread - pre-checked1859// java_thread - unchecked1860// depth - pre-checked as non-negative1861// value_ptr - pre-checked for NULL1862jvmtiError1863JvmtiEnv::GetLocalFloat(JavaThread* java_thread, jint depth, jint slot, jfloat* value_ptr) {1864// rm object is created to clean up the javaVFrame created in1865// doit_prologue(), but after doit() is finished with it.1866ResourceMark rm;18671868VM_GetOrSetLocal op(java_thread, depth, slot, T_FLOAT);1869VMThread::execute(&op);1870*value_ptr = op.value().f;1871return op.result();1872} /* end GetLocalFloat */187318741875// Threads_lock NOT held, java_thread not protected by lock1876// java_thread - pre-checked1877// java_thread - unchecked1878// depth - pre-checked as non-negative1879// value_ptr - pre-checked for NULL1880jvmtiError1881JvmtiEnv::GetLocalDouble(JavaThread* java_thread, jint depth, jint slot, jdouble* value_ptr) {1882// rm object is created to clean up the javaVFrame created in1883// doit_prologue(), but after doit() is finished with it.1884ResourceMark rm;18851886VM_GetOrSetLocal op(java_thread, depth, slot, T_DOUBLE);1887VMThread::execute(&op);1888*value_ptr = op.value().d;1889return op.result();1890} /* end GetLocalDouble */189118921893// Threads_lock NOT held, java_thread not protected by lock1894// java_thread - pre-checked1895// java_thread - unchecked1896// depth - pre-checked as non-negative1897jvmtiError1898JvmtiEnv::SetLocalObject(JavaThread* java_thread, jint depth, jint slot, jobject value) {1899// rm object is created to clean up the javaVFrame created in1900// doit_prologue(), but after doit() is finished with it.1901ResourceMark rm;1902jvalue val;1903val.l = value;1904VM_GetOrSetLocal op(java_thread, depth, slot, T_OBJECT, val);1905VMThread::execute(&op);1906return op.result();1907} /* end SetLocalObject */190819091910// Threads_lock NOT held, java_thread not protected by lock1911// java_thread - pre-checked1912// java_thread - unchecked1913// depth - pre-checked as non-negative1914jvmtiError1915JvmtiEnv::SetLocalInt(JavaThread* java_thread, jint depth, jint slot, jint value) {1916// rm object is created to clean up the javaVFrame created in1917// doit_prologue(), but after doit() is finished with it.1918ResourceMark rm;1919jvalue val;1920val.i = value;1921VM_GetOrSetLocal op(java_thread, depth, slot, T_INT, val);1922VMThread::execute(&op);1923return op.result();1924} /* end SetLocalInt */192519261927// Threads_lock NOT held, java_thread not protected by lock1928// java_thread - pre-checked1929// java_thread - unchecked1930// depth - pre-checked as non-negative1931jvmtiError1932JvmtiEnv::SetLocalLong(JavaThread* java_thread, jint depth, jint slot, jlong value) {1933// rm object is created to clean up the javaVFrame created in1934// doit_prologue(), but after doit() is finished with it.1935ResourceMark rm;1936jvalue val;1937val.j = value;1938VM_GetOrSetLocal op(java_thread, depth, slot, T_LONG, val);1939VMThread::execute(&op);1940return op.result();1941} /* end SetLocalLong */194219431944// Threads_lock NOT held, java_thread not protected by lock1945// java_thread - pre-checked1946// java_thread - unchecked1947// depth - pre-checked as non-negative1948jvmtiError1949JvmtiEnv::SetLocalFloat(JavaThread* java_thread, jint depth, jint slot, jfloat value) {1950// rm object is created to clean up the javaVFrame created in1951// doit_prologue(), but after doit() is finished with it.1952ResourceMark rm;1953jvalue val;1954val.f = value;1955VM_GetOrSetLocal op(java_thread, depth, slot, T_FLOAT, val);1956VMThread::execute(&op);1957return op.result();1958} /* end SetLocalFloat */195919601961// Threads_lock NOT held, java_thread not protected by lock1962// java_thread - pre-checked1963// java_thread - unchecked1964// depth - pre-checked as non-negative1965jvmtiError1966JvmtiEnv::SetLocalDouble(JavaThread* java_thread, jint depth, jint slot, jdouble value) {1967// rm object is created to clean up the javaVFrame created in1968// doit_prologue(), but after doit() is finished with it.1969ResourceMark rm;1970jvalue val;1971val.d = value;1972VM_GetOrSetLocal op(java_thread, depth, slot, T_DOUBLE, val);1973VMThread::execute(&op);1974return op.result();1975} /* end SetLocalDouble */197619771978//1979// Breakpoint functions1980//19811982// method_oop - pre-checked for validity, but may be NULL meaning obsolete method1983jvmtiError1984JvmtiEnv::SetBreakpoint(Method* method_oop, jlocation location) {1985NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID);1986if (location < 0) { // simple invalid location check first1987return JVMTI_ERROR_INVALID_LOCATION;1988}1989// verify that the breakpoint is not past the end of the method1990if (location >= (jlocation) method_oop->code_size()) {1991return JVMTI_ERROR_INVALID_LOCATION;1992}19931994ResourceMark rm;1995JvmtiBreakpoint bp(method_oop, location);1996JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints();1997if (jvmti_breakpoints.set(bp) == JVMTI_ERROR_DUPLICATE)1998return JVMTI_ERROR_DUPLICATE;19992000if (TraceJVMTICalls) {2001jvmti_breakpoints.print();2002}20032004return JVMTI_ERROR_NONE;2005} /* end SetBreakpoint */200620072008// method_oop - pre-checked for validity, but may be NULL meaning obsolete method2009jvmtiError2010JvmtiEnv::ClearBreakpoint(Method* method_oop, jlocation location) {2011NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID);20122013if (location < 0) { // simple invalid location check first2014return JVMTI_ERROR_INVALID_LOCATION;2015}20162017// verify that the breakpoint is not past the end of the method2018if (location >= (jlocation) method_oop->code_size()) {2019return JVMTI_ERROR_INVALID_LOCATION;2020}20212022JvmtiBreakpoint bp(method_oop, location);20232024JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints();2025if (jvmti_breakpoints.clear(bp) == JVMTI_ERROR_NOT_FOUND)2026return JVMTI_ERROR_NOT_FOUND;20272028if (TraceJVMTICalls) {2029jvmti_breakpoints.print();2030}20312032return JVMTI_ERROR_NONE;2033} /* end ClearBreakpoint */203420352036//2037// Watched Field functions2038//20392040jvmtiError2041JvmtiEnv::SetFieldAccessWatch(fieldDescriptor* fdesc_ptr) {2042// make sure we haven't set this watch before2043if (fdesc_ptr->is_field_access_watched()) return JVMTI_ERROR_DUPLICATE;2044fdesc_ptr->set_is_field_access_watched(true);20452046JvmtiEventController::change_field_watch(JVMTI_EVENT_FIELD_ACCESS, true);20472048return JVMTI_ERROR_NONE;2049} /* end SetFieldAccessWatch */205020512052jvmtiError2053JvmtiEnv::ClearFieldAccessWatch(fieldDescriptor* fdesc_ptr) {2054// make sure we have a watch to clear2055if (!fdesc_ptr->is_field_access_watched()) return JVMTI_ERROR_NOT_FOUND;2056fdesc_ptr->set_is_field_access_watched(false);20572058JvmtiEventController::change_field_watch(JVMTI_EVENT_FIELD_ACCESS, false);20592060return JVMTI_ERROR_NONE;2061} /* end ClearFieldAccessWatch */206220632064jvmtiError2065JvmtiEnv::SetFieldModificationWatch(fieldDescriptor* fdesc_ptr) {2066// make sure we haven't set this watch before2067if (fdesc_ptr->is_field_modification_watched()) return JVMTI_ERROR_DUPLICATE;2068fdesc_ptr->set_is_field_modification_watched(true);20692070JvmtiEventController::change_field_watch(JVMTI_EVENT_FIELD_MODIFICATION, true);20712072return JVMTI_ERROR_NONE;2073} /* end SetFieldModificationWatch */207420752076jvmtiError2077JvmtiEnv::ClearFieldModificationWatch(fieldDescriptor* fdesc_ptr) {2078// make sure we have a watch to clear2079if (!fdesc_ptr->is_field_modification_watched()) return JVMTI_ERROR_NOT_FOUND;2080fdesc_ptr->set_is_field_modification_watched(false);20812082JvmtiEventController::change_field_watch(JVMTI_EVENT_FIELD_MODIFICATION, false);20832084return JVMTI_ERROR_NONE;2085} /* end ClearFieldModificationWatch */20862087//2088// Class functions2089//209020912092// k_mirror - may be primitive, this must be checked2093// signature_ptr - NULL is a valid value, must be checked2094// generic_ptr - NULL is a valid value, must be checked2095jvmtiError2096JvmtiEnv::GetClassSignature(oop k_mirror, char** signature_ptr, char** generic_ptr) {2097ResourceMark rm;2098bool isPrimitive = java_lang_Class::is_primitive(k_mirror);2099Klass* k = NULL;2100if (!isPrimitive) {2101k = java_lang_Class::as_Klass(k_mirror);2102NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);2103}2104if (signature_ptr != NULL) {2105char* result = NULL;2106if (isPrimitive) {2107char tchar = type2char(java_lang_Class::primitive_type(k_mirror));2108result = (char*) jvmtiMalloc(2);2109result[0] = tchar;2110result[1] = '\0';2111} else {2112const char* class_sig = k->signature_name();2113result = (char *) jvmtiMalloc(strlen(class_sig)+1);2114strcpy(result, class_sig);2115}2116*signature_ptr = result;2117}2118if (generic_ptr != NULL) {2119*generic_ptr = NULL;2120if (!isPrimitive && k->oop_is_instance()) {2121Symbol* soo = InstanceKlass::cast(k)->generic_signature();2122if (soo != NULL) {2123const char *gen_sig = soo->as_C_string();2124if (gen_sig != NULL) {2125char* gen_result;2126jvmtiError err = allocate(strlen(gen_sig) + 1,2127(unsigned char **)&gen_result);2128if (err != JVMTI_ERROR_NONE) {2129return err;2130}2131strcpy(gen_result, gen_sig);2132*generic_ptr = gen_result;2133}2134}2135}2136}2137return JVMTI_ERROR_NONE;2138} /* end GetClassSignature */213921402141// k_mirror - may be primitive, this must be checked2142// status_ptr - pre-checked for NULL2143jvmtiError2144JvmtiEnv::GetClassStatus(oop k_mirror, jint* status_ptr) {2145jint result = 0;2146if (java_lang_Class::is_primitive(k_mirror)) {2147result |= JVMTI_CLASS_STATUS_PRIMITIVE;2148} else {2149Klass* k = java_lang_Class::as_Klass(k_mirror);2150NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);2151result = k->jvmti_class_status();2152}2153*status_ptr = result;21542155return JVMTI_ERROR_NONE;2156} /* end GetClassStatus */215721582159// k_mirror - may be primitive, this must be checked2160// source_name_ptr - pre-checked for NULL2161jvmtiError2162JvmtiEnv::GetSourceFileName(oop k_mirror, char** source_name_ptr) {2163if (java_lang_Class::is_primitive(k_mirror)) {2164return JVMTI_ERROR_ABSENT_INFORMATION;2165}2166Klass* k_klass = java_lang_Class::as_Klass(k_mirror);2167NULL_CHECK(k_klass, JVMTI_ERROR_INVALID_CLASS);21682169if (!k_klass->oop_is_instance()) {2170return JVMTI_ERROR_ABSENT_INFORMATION;2171}21722173Symbol* sfnOop = InstanceKlass::cast(k_klass)->source_file_name();2174NULL_CHECK(sfnOop, JVMTI_ERROR_ABSENT_INFORMATION);2175{2176JavaThread* current_thread = JavaThread::current();2177ResourceMark rm(current_thread);2178const char* sfncp = (const char*) sfnOop->as_C_string();2179*source_name_ptr = (char *) jvmtiMalloc(strlen(sfncp)+1);2180strcpy(*source_name_ptr, sfncp);2181}21822183return JVMTI_ERROR_NONE;2184} /* end GetSourceFileName */218521862187// k_mirror - may be primitive, this must be checked2188// modifiers_ptr - pre-checked for NULL2189jvmtiError2190JvmtiEnv::GetClassModifiers(oop k_mirror, jint* modifiers_ptr) {2191JavaThread* current_thread = JavaThread::current();2192jint result = 0;2193if (!java_lang_Class::is_primitive(k_mirror)) {2194Klass* k = java_lang_Class::as_Klass(k_mirror);2195NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);2196result = k->compute_modifier_flags(current_thread);2197JavaThread* THREAD = current_thread; // pass to macros2198if (HAS_PENDING_EXCEPTION) {2199CLEAR_PENDING_EXCEPTION;2200return JVMTI_ERROR_INTERNAL;2201};22022203// Reset the deleted ACC_SUPER bit ( deleted in compute_modifier_flags()).2204if(k->is_super()) {2205result |= JVM_ACC_SUPER;2206}2207} else {2208result = (JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC);2209}2210*modifiers_ptr = result;22112212return JVMTI_ERROR_NONE;2213} /* end GetClassModifiers */221422152216// k_mirror - may be primitive, this must be checked2217// method_count_ptr - pre-checked for NULL2218// methods_ptr - pre-checked for NULL2219jvmtiError2220JvmtiEnv::GetClassMethods(oop k_mirror, jint* method_count_ptr, jmethodID** methods_ptr) {2221JavaThread* current_thread = JavaThread::current();2222HandleMark hm(current_thread);22232224if (java_lang_Class::is_primitive(k_mirror)) {2225*method_count_ptr = 0;2226*methods_ptr = (jmethodID*) jvmtiMalloc(0 * sizeof(jmethodID));2227return JVMTI_ERROR_NONE;2228}2229Klass* k = java_lang_Class::as_Klass(k_mirror);2230NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);22312232// Return CLASS_NOT_PREPARED error as per JVMTI spec.2233if (!(k->jvmti_class_status() & (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY) )) {2234return JVMTI_ERROR_CLASS_NOT_PREPARED;2235}22362237if (!k->oop_is_instance()) {2238*method_count_ptr = 0;2239*methods_ptr = (jmethodID*) jvmtiMalloc(0 * sizeof(jmethodID));2240return JVMTI_ERROR_NONE;2241}2242instanceKlassHandle instanceK_h(current_thread, k);2243// Allocate the result and fill it in2244int result_length = instanceK_h->methods()->length();2245jmethodID* result_list = (jmethodID*)jvmtiMalloc(result_length * sizeof(jmethodID));2246int index;2247if (JvmtiExport::can_maintain_original_method_order()) {2248// Use the original method ordering indices stored in the class, so we can emit2249// jmethodIDs in the order they appeared in the class file2250for (index = 0; index < result_length; index++) {2251Method* m = instanceK_h->methods()->at(index);2252int original_index = instanceK_h->method_ordering()->at(index);2253assert(original_index >= 0 && original_index < result_length, "invalid original method index");2254jmethodID id = m->jmethod_id();2255result_list[original_index] = id;2256}2257} else {2258// otherwise just copy in any order2259for (index = 0; index < result_length; index++) {2260Method* m = instanceK_h->methods()->at(index);2261jmethodID id = m->jmethod_id();2262result_list[index] = id;2263}2264}2265// Fill in return value.2266*method_count_ptr = result_length;2267*methods_ptr = result_list;22682269return JVMTI_ERROR_NONE;2270} /* end GetClassMethods */227122722273// k_mirror - may be primitive, this must be checked2274// field_count_ptr - pre-checked for NULL2275// fields_ptr - pre-checked for NULL2276jvmtiError2277JvmtiEnv::GetClassFields(oop k_mirror, jint* field_count_ptr, jfieldID** fields_ptr) {2278if (java_lang_Class::is_primitive(k_mirror)) {2279*field_count_ptr = 0;2280*fields_ptr = (jfieldID*) jvmtiMalloc(0 * sizeof(jfieldID));2281return JVMTI_ERROR_NONE;2282}2283JavaThread* current_thread = JavaThread::current();2284HandleMark hm(current_thread);2285Klass* k = java_lang_Class::as_Klass(k_mirror);2286NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);22872288// Return CLASS_NOT_PREPARED error as per JVMTI spec.2289if (!(k->jvmti_class_status() & (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY) )) {2290return JVMTI_ERROR_CLASS_NOT_PREPARED;2291}22922293if (!k->oop_is_instance()) {2294*field_count_ptr = 0;2295*fields_ptr = (jfieldID*) jvmtiMalloc(0 * sizeof(jfieldID));2296return JVMTI_ERROR_NONE;2297}229822992300instanceKlassHandle instanceK_h(current_thread, k);23012302int result_count = 0;2303// First, count the fields.2304FilteredFieldStream flds(instanceK_h, true, true);2305result_count = flds.field_count();23062307// Allocate the result and fill it in2308jfieldID* result_list = (jfieldID*) jvmtiMalloc(result_count * sizeof(jfieldID));2309// The JVMTI spec requires fields in the order they occur in the class file,2310// this is the reverse order of what FieldStream hands out.2311int id_index = (result_count - 1);23122313for (FilteredFieldStream src_st(instanceK_h, true, true); !src_st.eos(); src_st.next()) {2314result_list[id_index--] = jfieldIDWorkaround::to_jfieldID(2315instanceK_h, src_st.offset(),2316src_st.access_flags().is_static());2317}2318assert(id_index == -1, "just checking");2319// Fill in the results2320*field_count_ptr = result_count;2321*fields_ptr = result_list;23222323return JVMTI_ERROR_NONE;2324} /* end GetClassFields */232523262327// k_mirror - may be primitive, this must be checked2328// interface_count_ptr - pre-checked for NULL2329// interfaces_ptr - pre-checked for NULL2330jvmtiError2331JvmtiEnv::GetImplementedInterfaces(oop k_mirror, jint* interface_count_ptr, jclass** interfaces_ptr) {2332{2333if (java_lang_Class::is_primitive(k_mirror)) {2334*interface_count_ptr = 0;2335*interfaces_ptr = (jclass*) jvmtiMalloc(0 * sizeof(jclass));2336return JVMTI_ERROR_NONE;2337}2338JavaThread* current_thread = JavaThread::current();2339HandleMark hm(current_thread);2340Klass* k = java_lang_Class::as_Klass(k_mirror);2341NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);23422343// Return CLASS_NOT_PREPARED error as per JVMTI spec.2344if (!(k->jvmti_class_status() & (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY) ))2345return JVMTI_ERROR_CLASS_NOT_PREPARED;23462347if (!k->oop_is_instance()) {2348*interface_count_ptr = 0;2349*interfaces_ptr = (jclass*) jvmtiMalloc(0 * sizeof(jclass));2350return JVMTI_ERROR_NONE;2351}23522353Array<Klass*>* interface_list = InstanceKlass::cast(k)->local_interfaces();2354const int result_length = (interface_list == NULL ? 0 : interface_list->length());2355jclass* result_list = (jclass*) jvmtiMalloc(result_length * sizeof(jclass));2356for (int i_index = 0; i_index < result_length; i_index += 1) {2357Klass* klass_at = interface_list->at(i_index);2358assert(klass_at->is_klass(), "interfaces must be Klass*s");2359assert(klass_at->is_interface(), "interfaces must be interfaces");2360oop mirror_at = klass_at->java_mirror();2361Handle handle_at = Handle(current_thread, mirror_at);2362result_list[i_index] = (jclass) jni_reference(handle_at);2363}2364*interface_count_ptr = result_length;2365*interfaces_ptr = result_list;2366}23672368return JVMTI_ERROR_NONE;2369} /* end GetImplementedInterfaces */237023712372// k_mirror - may be primitive, this must be checked2373// minor_version_ptr - pre-checked for NULL2374// major_version_ptr - pre-checked for NULL2375jvmtiError2376JvmtiEnv::GetClassVersionNumbers(oop k_mirror, jint* minor_version_ptr, jint* major_version_ptr) {2377if (java_lang_Class::is_primitive(k_mirror)) {2378return JVMTI_ERROR_ABSENT_INFORMATION;2379}2380Klass* k_oop = java_lang_Class::as_Klass(k_mirror);2381Thread *thread = Thread::current();2382HandleMark hm(thread);2383KlassHandle klass(thread, k_oop);23842385jint status = klass->jvmti_class_status();2386if (status & (JVMTI_CLASS_STATUS_ERROR)) {2387return JVMTI_ERROR_INVALID_CLASS;2388}2389if (status & (JVMTI_CLASS_STATUS_ARRAY)) {2390return JVMTI_ERROR_ABSENT_INFORMATION;2391}23922393instanceKlassHandle ik(thread, k_oop);2394*minor_version_ptr = ik->minor_version();2395*major_version_ptr = ik->major_version();23962397return JVMTI_ERROR_NONE;2398} /* end GetClassVersionNumbers */239924002401// k_mirror - may be primitive, this must be checked2402// constant_pool_count_ptr - pre-checked for NULL2403// constant_pool_byte_count_ptr - pre-checked for NULL2404// constant_pool_bytes_ptr - pre-checked for NULL2405jvmtiError2406JvmtiEnv::GetConstantPool(oop k_mirror, jint* constant_pool_count_ptr, jint* constant_pool_byte_count_ptr, unsigned char** constant_pool_bytes_ptr) {2407if (java_lang_Class::is_primitive(k_mirror)) {2408return JVMTI_ERROR_ABSENT_INFORMATION;2409}24102411Klass* k_oop = java_lang_Class::as_Klass(k_mirror);2412Thread *thread = Thread::current();2413HandleMark hm(thread);2414ResourceMark rm(thread);2415KlassHandle klass(thread, k_oop);24162417jint status = klass->jvmti_class_status();2418if (status & (JVMTI_CLASS_STATUS_ERROR)) {2419return JVMTI_ERROR_INVALID_CLASS;2420}2421if (status & (JVMTI_CLASS_STATUS_ARRAY)) {2422return JVMTI_ERROR_ABSENT_INFORMATION;2423}24242425instanceKlassHandle ikh(thread, k_oop);2426constantPoolHandle constants(thread, ikh->constants());2427MonitorLockerEx ml(constants->lock()); // lock constant pool while we query it24282429JvmtiConstantPoolReconstituter reconstituter(ikh);2430if (reconstituter.get_error() != JVMTI_ERROR_NONE) {2431return reconstituter.get_error();2432}24332434unsigned char *cpool_bytes;2435int cpool_size = reconstituter.cpool_size();2436if (reconstituter.get_error() != JVMTI_ERROR_NONE) {2437return reconstituter.get_error();2438}2439jvmtiError res = allocate(cpool_size, &cpool_bytes);2440if (res != JVMTI_ERROR_NONE) {2441return res;2442}2443reconstituter.copy_cpool_bytes(cpool_bytes);2444if (reconstituter.get_error() != JVMTI_ERROR_NONE) {2445return reconstituter.get_error();2446}24472448*constant_pool_count_ptr = constants->length();2449*constant_pool_byte_count_ptr = cpool_size;2450*constant_pool_bytes_ptr = cpool_bytes;24512452return JVMTI_ERROR_NONE;2453} /* end GetConstantPool */245424552456// k_mirror - may be primitive, this must be checked2457// is_interface_ptr - pre-checked for NULL2458jvmtiError2459JvmtiEnv::IsInterface(oop k_mirror, jboolean* is_interface_ptr) {2460{2461bool result = false;2462if (!java_lang_Class::is_primitive(k_mirror)) {2463Klass* k = java_lang_Class::as_Klass(k_mirror);2464if (k != NULL && k->is_interface()) {2465result = true;2466}2467}2468*is_interface_ptr = result;2469}24702471return JVMTI_ERROR_NONE;2472} /* end IsInterface */247324742475// k_mirror - may be primitive, this must be checked2476// is_array_class_ptr - pre-checked for NULL2477jvmtiError2478JvmtiEnv::IsArrayClass(oop k_mirror, jboolean* is_array_class_ptr) {2479{2480bool result = false;2481if (!java_lang_Class::is_primitive(k_mirror)) {2482Klass* k = java_lang_Class::as_Klass(k_mirror);2483if (k != NULL && k->oop_is_array()) {2484result = true;2485}2486}2487*is_array_class_ptr = result;2488}24892490return JVMTI_ERROR_NONE;2491} /* end IsArrayClass */249224932494// k_mirror - may be primitive, this must be checked2495// classloader_ptr - pre-checked for NULL2496jvmtiError2497JvmtiEnv::GetClassLoader(oop k_mirror, jobject* classloader_ptr) {2498{2499if (java_lang_Class::is_primitive(k_mirror)) {2500*classloader_ptr = (jclass) jni_reference(Handle());2501return JVMTI_ERROR_NONE;2502}2503JavaThread* current_thread = JavaThread::current();2504HandleMark hm(current_thread);2505Klass* k = java_lang_Class::as_Klass(k_mirror);2506NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);25072508oop result_oop = k->class_loader();2509if (result_oop == NULL) {2510*classloader_ptr = (jclass) jni_reference(Handle());2511return JVMTI_ERROR_NONE;2512}2513Handle result_handle = Handle(current_thread, result_oop);2514jclass result_jnihandle = (jclass) jni_reference(result_handle);2515*classloader_ptr = result_jnihandle;2516}2517return JVMTI_ERROR_NONE;2518} /* end GetClassLoader */251925202521// k_mirror - may be primitive, this must be checked2522// source_debug_extension_ptr - pre-checked for NULL2523jvmtiError2524JvmtiEnv::GetSourceDebugExtension(oop k_mirror, char** source_debug_extension_ptr) {2525{2526if (java_lang_Class::is_primitive(k_mirror)) {2527return JVMTI_ERROR_ABSENT_INFORMATION;2528}2529Klass* k = java_lang_Class::as_Klass(k_mirror);2530NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);2531if (!k->oop_is_instance()) {2532return JVMTI_ERROR_ABSENT_INFORMATION;2533}2534char* sde = InstanceKlass::cast(k)->source_debug_extension();2535NULL_CHECK(sde, JVMTI_ERROR_ABSENT_INFORMATION);25362537{2538*source_debug_extension_ptr = (char *) jvmtiMalloc(strlen(sde)+1);2539strcpy(*source_debug_extension_ptr, sde);2540}2541}25422543return JVMTI_ERROR_NONE;2544} /* end GetSourceDebugExtension */25452546//2547// Object functions2548//25492550// hash_code_ptr - pre-checked for NULL2551jvmtiError2552JvmtiEnv::GetObjectHashCode(jobject object, jint* hash_code_ptr) {2553oop mirror = JNIHandles::resolve_external_guard(object);2554NULL_CHECK(mirror, JVMTI_ERROR_INVALID_OBJECT);2555NULL_CHECK(hash_code_ptr, JVMTI_ERROR_NULL_POINTER);25562557{2558jint result = (jint) mirror->identity_hash();2559*hash_code_ptr = result;2560}2561return JVMTI_ERROR_NONE;2562} /* end GetObjectHashCode */256325642565// info_ptr - pre-checked for NULL2566jvmtiError2567JvmtiEnv::GetObjectMonitorUsage(jobject object, jvmtiMonitorUsage* info_ptr) {2568JavaThread* calling_thread = JavaThread::current();2569jvmtiError err = get_object_monitor_usage(calling_thread, object, info_ptr);2570if (err == JVMTI_ERROR_THREAD_NOT_SUSPENDED) {2571// Some of the critical threads were not suspended. go to a safepoint and try again2572VM_GetObjectMonitorUsage op(this, calling_thread, object, info_ptr);2573VMThread::execute(&op);2574err = op.result();2575}2576return err;2577} /* end GetObjectMonitorUsage */257825792580//2581// Field functions2582//25832584// name_ptr - NULL is a valid value, must be checked2585// signature_ptr - NULL is a valid value, must be checked2586// generic_ptr - NULL is a valid value, must be checked2587jvmtiError2588JvmtiEnv::GetFieldName(fieldDescriptor* fdesc_ptr, char** name_ptr, char** signature_ptr, char** generic_ptr) {2589JavaThread* current_thread = JavaThread::current();2590ResourceMark rm(current_thread);2591if (name_ptr == NULL) {2592// just don't return the name2593} else {2594const char* fieldName = fdesc_ptr->name()->as_C_string();2595*name_ptr = (char*) jvmtiMalloc(strlen(fieldName) + 1);2596if (*name_ptr == NULL)2597return JVMTI_ERROR_OUT_OF_MEMORY;2598strcpy(*name_ptr, fieldName);2599}2600if (signature_ptr== NULL) {2601// just don't return the signature2602} else {2603const char* fieldSignature = fdesc_ptr->signature()->as_C_string();2604*signature_ptr = (char*) jvmtiMalloc(strlen(fieldSignature) + 1);2605if (*signature_ptr == NULL)2606return JVMTI_ERROR_OUT_OF_MEMORY;2607strcpy(*signature_ptr, fieldSignature);2608}2609if (generic_ptr != NULL) {2610*generic_ptr = NULL;2611Symbol* soop = fdesc_ptr->generic_signature();2612if (soop != NULL) {2613const char* gen_sig = soop->as_C_string();2614if (gen_sig != NULL) {2615jvmtiError err = allocate(strlen(gen_sig) + 1, (unsigned char **)generic_ptr);2616if (err != JVMTI_ERROR_NONE) {2617return err;2618}2619strcpy(*generic_ptr, gen_sig);2620}2621}2622}2623return JVMTI_ERROR_NONE;2624} /* end GetFieldName */262526262627// declaring_class_ptr - pre-checked for NULL2628jvmtiError2629JvmtiEnv::GetFieldDeclaringClass(fieldDescriptor* fdesc_ptr, jclass* declaring_class_ptr) {26302631*declaring_class_ptr = get_jni_class_non_null(fdesc_ptr->field_holder());2632return JVMTI_ERROR_NONE;2633} /* end GetFieldDeclaringClass */263426352636// modifiers_ptr - pre-checked for NULL2637jvmtiError2638JvmtiEnv::GetFieldModifiers(fieldDescriptor* fdesc_ptr, jint* modifiers_ptr) {26392640AccessFlags resultFlags = fdesc_ptr->access_flags();2641jint result = resultFlags.as_int();2642*modifiers_ptr = result;26432644return JVMTI_ERROR_NONE;2645} /* end GetFieldModifiers */264626472648// is_synthetic_ptr - pre-checked for NULL2649jvmtiError2650JvmtiEnv::IsFieldSynthetic(fieldDescriptor* fdesc_ptr, jboolean* is_synthetic_ptr) {2651*is_synthetic_ptr = fdesc_ptr->is_synthetic();2652return JVMTI_ERROR_NONE;2653} /* end IsFieldSynthetic */265426552656//2657// Method functions2658//26592660// method_oop - pre-checked for validity, but may be NULL meaning obsolete method2661// name_ptr - NULL is a valid value, must be checked2662// signature_ptr - NULL is a valid value, must be checked2663// generic_ptr - NULL is a valid value, must be checked2664jvmtiError2665JvmtiEnv::GetMethodName(Method* method_oop, char** name_ptr, char** signature_ptr, char** generic_ptr) {2666NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID);2667JavaThread* current_thread = JavaThread::current();26682669ResourceMark rm(current_thread); // get the utf8 name and signature2670if (name_ptr == NULL) {2671// just don't return the name2672} else {2673const char* utf8_name = (const char *) method_oop->name()->as_utf8();2674*name_ptr = (char *) jvmtiMalloc(strlen(utf8_name)+1);2675strcpy(*name_ptr, utf8_name);2676}2677if (signature_ptr == NULL) {2678// just don't return the signature2679} else {2680const char* utf8_signature = (const char *) method_oop->signature()->as_utf8();2681*signature_ptr = (char *) jvmtiMalloc(strlen(utf8_signature) + 1);2682strcpy(*signature_ptr, utf8_signature);2683}26842685if (generic_ptr != NULL) {2686*generic_ptr = NULL;2687Symbol* soop = method_oop->generic_signature();2688if (soop != NULL) {2689const char* gen_sig = soop->as_C_string();2690if (gen_sig != NULL) {2691jvmtiError err = allocate(strlen(gen_sig) + 1, (unsigned char **)generic_ptr);2692if (err != JVMTI_ERROR_NONE) {2693return err;2694}2695strcpy(*generic_ptr, gen_sig);2696}2697}2698}2699return JVMTI_ERROR_NONE;2700} /* end GetMethodName */270127022703// method_oop - pre-checked for validity, but may be NULL meaning obsolete method2704// declaring_class_ptr - pre-checked for NULL2705jvmtiError2706JvmtiEnv::GetMethodDeclaringClass(Method* method_oop, jclass* declaring_class_ptr) {2707NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID);2708(*declaring_class_ptr) = get_jni_class_non_null(method_oop->method_holder());2709return JVMTI_ERROR_NONE;2710} /* end GetMethodDeclaringClass */271127122713// method_oop - pre-checked for validity, but may be NULL meaning obsolete method2714// modifiers_ptr - pre-checked for NULL2715jvmtiError2716JvmtiEnv::GetMethodModifiers(Method* method_oop, jint* modifiers_ptr) {2717NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID);2718(*modifiers_ptr) = method_oop->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS;2719return JVMTI_ERROR_NONE;2720} /* end GetMethodModifiers */272127222723// method_oop - pre-checked for validity, but may be NULL meaning obsolete method2724// max_ptr - pre-checked for NULL2725jvmtiError2726JvmtiEnv::GetMaxLocals(Method* method_oop, jint* max_ptr) {2727NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID);2728// get max stack2729(*max_ptr) = method_oop->max_locals();2730return JVMTI_ERROR_NONE;2731} /* end GetMaxLocals */273227332734// method_oop - pre-checked for validity, but may be NULL meaning obsolete method2735// size_ptr - pre-checked for NULL2736jvmtiError2737JvmtiEnv::GetArgumentsSize(Method* method_oop, jint* size_ptr) {2738NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID);2739// get size of arguments27402741(*size_ptr) = method_oop->size_of_parameters();2742return JVMTI_ERROR_NONE;2743} /* end GetArgumentsSize */274427452746// method_oop - pre-checked for validity, but may be NULL meaning obsolete method2747// entry_count_ptr - pre-checked for NULL2748// table_ptr - pre-checked for NULL2749jvmtiError2750JvmtiEnv::GetLineNumberTable(Method* method_oop, jint* entry_count_ptr, jvmtiLineNumberEntry** table_ptr) {2751NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID);2752if (!method_oop->has_linenumber_table()) {2753return (JVMTI_ERROR_ABSENT_INFORMATION);2754}27552756// The line number table is compressed so we don't know how big it is until decompressed.2757// Decompression is really fast so we just do it twice.27582759// Compute size of table2760jint num_entries = 0;2761CompressedLineNumberReadStream stream(method_oop->compressed_linenumber_table());2762while (stream.read_pair()) {2763num_entries++;2764}2765jvmtiLineNumberEntry *jvmti_table =2766(jvmtiLineNumberEntry *)jvmtiMalloc(num_entries * (sizeof(jvmtiLineNumberEntry)));27672768// Fill jvmti table2769if (num_entries > 0) {2770int index = 0;2771CompressedLineNumberReadStream stream(method_oop->compressed_linenumber_table());2772while (stream.read_pair()) {2773jvmti_table[index].start_location = (jlocation) stream.bci();2774jvmti_table[index].line_number = (jint) stream.line();2775index++;2776}2777assert(index == num_entries, "sanity check");2778}27792780// Set up results2781(*entry_count_ptr) = num_entries;2782(*table_ptr) = jvmti_table;27832784return JVMTI_ERROR_NONE;2785} /* end GetLineNumberTable */278627872788// method_oop - pre-checked for validity, but may be NULL meaning obsolete method2789// start_location_ptr - pre-checked for NULL2790// end_location_ptr - pre-checked for NULL2791jvmtiError2792JvmtiEnv::GetMethodLocation(Method* method_oop, jlocation* start_location_ptr, jlocation* end_location_ptr) {27932794NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID);2795// get start and end location2796(*end_location_ptr) = (jlocation) (method_oop->code_size() - 1);2797if (method_oop->code_size() == 0) {2798// there is no code so there is no start location2799(*start_location_ptr) = (jlocation)(-1);2800} else {2801(*start_location_ptr) = (jlocation)(0);2802}28032804return JVMTI_ERROR_NONE;2805} /* end GetMethodLocation */280628072808// method_oop - pre-checked for validity, but may be NULL meaning obsolete method2809// entry_count_ptr - pre-checked for NULL2810// table_ptr - pre-checked for NULL2811jvmtiError2812JvmtiEnv::GetLocalVariableTable(Method* method_oop, jint* entry_count_ptr, jvmtiLocalVariableEntry** table_ptr) {28132814NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID);2815JavaThread* current_thread = JavaThread::current();28162817// does the klass have any local variable information?2818InstanceKlass* ik = method_oop->method_holder();2819if (!ik->access_flags().has_localvariable_table()) {2820return (JVMTI_ERROR_ABSENT_INFORMATION);2821}28222823ConstantPool* constants = method_oop->constants();2824NULL_CHECK(constants, JVMTI_ERROR_ABSENT_INFORMATION);28252826// in the vm localvariable table representation, 6 consecutive elements in the table2827// represent a 6-tuple of shorts2828// [start_pc, length, name_index, descriptor_index, signature_index, index]2829jint num_entries = method_oop->localvariable_table_length();2830jvmtiLocalVariableEntry *jvmti_table = (jvmtiLocalVariableEntry *)2831jvmtiMalloc(num_entries * (sizeof(jvmtiLocalVariableEntry)));28322833if (num_entries > 0) {2834LocalVariableTableElement* table = method_oop->localvariable_table_start();2835for (int i = 0; i < num_entries; i++) {2836// get the 5 tuple information from the vm table2837jlocation start_location = (jlocation) table[i].start_bci;2838jint length = (jint) table[i].length;2839int name_index = (int) table[i].name_cp_index;2840int signature_index = (int) table[i].descriptor_cp_index;2841int generic_signature_index = (int) table[i].signature_cp_index;2842jint slot = (jint) table[i].slot;28432844// get utf8 name and signature2845char *name_buf = NULL;2846char *sig_buf = NULL;2847char *gen_sig_buf = NULL;2848{2849ResourceMark rm(current_thread);28502851const char *utf8_name = (const char *) constants->symbol_at(name_index)->as_utf8();2852name_buf = (char *) jvmtiMalloc(strlen(utf8_name)+1);2853strcpy(name_buf, utf8_name);28542855const char *utf8_signature = (const char *) constants->symbol_at(signature_index)->as_utf8();2856sig_buf = (char *) jvmtiMalloc(strlen(utf8_signature)+1);2857strcpy(sig_buf, utf8_signature);28582859if (generic_signature_index > 0) {2860const char *utf8_gen_sign = (const char *)2861constants->symbol_at(generic_signature_index)->as_utf8();2862gen_sig_buf = (char *) jvmtiMalloc(strlen(utf8_gen_sign)+1);2863strcpy(gen_sig_buf, utf8_gen_sign);2864}2865}28662867// fill in the jvmti local variable table2868jvmti_table[i].start_location = start_location;2869jvmti_table[i].length = length;2870jvmti_table[i].name = name_buf;2871jvmti_table[i].signature = sig_buf;2872jvmti_table[i].generic_signature = gen_sig_buf;2873jvmti_table[i].slot = slot;2874}2875}28762877// set results2878(*entry_count_ptr) = num_entries;2879(*table_ptr) = jvmti_table;28802881return JVMTI_ERROR_NONE;2882} /* end GetLocalVariableTable */288328842885// method_oop - pre-checked for validity, but may be NULL meaning obsolete method2886// bytecode_count_ptr - pre-checked for NULL2887// bytecodes_ptr - pre-checked for NULL2888jvmtiError2889JvmtiEnv::GetBytecodes(Method* method_oop, jint* bytecode_count_ptr, unsigned char** bytecodes_ptr) {2890NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID);28912892HandleMark hm;2893methodHandle method(method_oop);2894jint size = (jint)method->code_size();2895jvmtiError err = allocate(size, bytecodes_ptr);2896if (err != JVMTI_ERROR_NONE) {2897return err;2898}28992900(*bytecode_count_ptr) = size;2901// get byte codes2902JvmtiClassFileReconstituter::copy_bytecodes(method, *bytecodes_ptr);29032904return JVMTI_ERROR_NONE;2905} /* end GetBytecodes */290629072908// method_oop - pre-checked for validity, but may be NULL meaning obsolete method2909// is_native_ptr - pre-checked for NULL2910jvmtiError2911JvmtiEnv::IsMethodNative(Method* method_oop, jboolean* is_native_ptr) {2912NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID);2913(*is_native_ptr) = method_oop->is_native();2914return JVMTI_ERROR_NONE;2915} /* end IsMethodNative */291629172918// method_oop - pre-checked for validity, but may be NULL meaning obsolete method2919// is_synthetic_ptr - pre-checked for NULL2920jvmtiError2921JvmtiEnv::IsMethodSynthetic(Method* method_oop, jboolean* is_synthetic_ptr) {2922NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID);2923(*is_synthetic_ptr) = method_oop->is_synthetic();2924return JVMTI_ERROR_NONE;2925} /* end IsMethodSynthetic */292629272928// method_oop - pre-checked for validity, but may be NULL meaning obsolete method2929// is_obsolete_ptr - pre-checked for NULL2930jvmtiError2931JvmtiEnv::IsMethodObsolete(Method* method_oop, jboolean* is_obsolete_ptr) {2932if (use_version_1_0_semantics() &&2933get_capabilities()->can_redefine_classes == 0) {2934// This JvmtiEnv requested version 1.0 semantics and this function2935// requires the can_redefine_classes capability in version 1.0 so2936// we need to return an error here.2937return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;2938}29392940if (method_oop == NULL || method_oop->is_obsolete()) {2941*is_obsolete_ptr = true;2942} else {2943*is_obsolete_ptr = false;2944}2945return JVMTI_ERROR_NONE;2946} /* end IsMethodObsolete */29472948//2949// Raw Monitor functions2950//29512952// name - pre-checked for NULL2953// monitor_ptr - pre-checked for NULL2954jvmtiError2955JvmtiEnv::CreateRawMonitor(const char* name, jrawMonitorID* monitor_ptr) {2956JvmtiRawMonitor* rmonitor = new JvmtiRawMonitor(name);2957NULL_CHECK(rmonitor, JVMTI_ERROR_OUT_OF_MEMORY);29582959*monitor_ptr = (jrawMonitorID)rmonitor;29602961return JVMTI_ERROR_NONE;2962} /* end CreateRawMonitor */296329642965// rmonitor - pre-checked for validity2966jvmtiError2967JvmtiEnv::DestroyRawMonitor(JvmtiRawMonitor * rmonitor) {2968if (Threads::number_of_threads() == 0) {2969// Remove this monitor from pending raw monitors list2970// if it has entered in onload or start phase.2971JvmtiPendingMonitors::destroy(rmonitor);2972} else {2973Thread* thread = Thread::current();2974if (rmonitor->is_entered(thread)) {2975// The caller owns this monitor which we are about to destroy.2976// We exit the underlying synchronization object so that the2977// "delete monitor" call below can work without an assertion2978// failure on systems that don't like destroying synchronization2979// objects that are locked.2980int r;2981intptr_t recursion = rmonitor->recursions();2982for (intptr_t i = 0; i <= recursion; i++) {2983r = rmonitor->raw_exit(thread);2984assert(r == ObjectMonitor::OM_OK, "raw_exit should have worked");2985if (r != ObjectMonitor::OM_OK) { // robustness2986return JVMTI_ERROR_INTERNAL;2987}2988}2989}2990if (rmonitor->owner() != NULL) {2991// The caller is trying to destroy a monitor that is locked by2992// someone else. While this is not forbidden by the JVMTI2993// spec, it will cause an assertion failure on systems that don't2994// like destroying synchronization objects that are locked.2995// We indicate a problem with the error return (and leak the2996// monitor's memory).2997return JVMTI_ERROR_NOT_MONITOR_OWNER;2998}2999}30003001delete rmonitor;30023003return JVMTI_ERROR_NONE;3004} /* end DestroyRawMonitor */300530063007// rmonitor - pre-checked for validity3008jvmtiError3009JvmtiEnv::RawMonitorEnter(JvmtiRawMonitor * rmonitor) {3010if (Threads::number_of_threads() == 0) {3011// No JavaThreads exist so ObjectMonitor enter cannot be3012// used, add this raw monitor to the pending list.3013// The pending monitors will be actually entered when3014// the VM is setup.3015// See transition_pending_raw_monitors in create_vm()3016// in thread.cpp.3017JvmtiPendingMonitors::enter(rmonitor);3018} else {3019int r = 0;3020Thread* thread = Thread::current();30213022if (thread->is_Java_thread()) {3023JavaThread* current_thread = (JavaThread*)thread;30243025#ifdef PROPER_TRANSITIONS3026// Not really unknown but ThreadInVMfromNative does more than we want3027ThreadInVMfromUnknown __tiv;3028{3029ThreadBlockInVM __tbivm(current_thread);3030r = rmonitor->raw_enter(current_thread);3031}3032#else3033/* Transition to thread_blocked without entering vm state */3034/* This is really evil. Normally you can't undo _thread_blocked */3035/* transitions like this because it would cause us to miss a */3036/* safepoint but since the thread was already in _thread_in_native */3037/* the thread is not leaving a safepoint safe state and it will */3038/* block when it tries to return from native. We can't safepoint */3039/* block in here because we could deadlock the vmthread. Blech. */30403041JavaThreadState state = current_thread->thread_state();3042assert(state == _thread_in_native, "Must be _thread_in_native");3043// frame should already be walkable since we are in native3044assert(!current_thread->has_last_Java_frame() ||3045current_thread->frame_anchor()->walkable(), "Must be walkable");3046current_thread->set_thread_state(_thread_blocked);30473048r = rmonitor->raw_enter(current_thread);3049// restore state, still at a safepoint safe state3050current_thread->set_thread_state(state);30513052#endif /* PROPER_TRANSITIONS */3053assert(r == ObjectMonitor::OM_OK, "raw_enter should have worked");3054} else {3055if (thread->is_VM_thread() || thread->is_ConcurrentGC_thread()) {3056r = rmonitor->raw_enter(thread);3057} else {3058ShouldNotReachHere();3059}3060}30613062if (r != ObjectMonitor::OM_OK) { // robustness3063return JVMTI_ERROR_INTERNAL;3064}3065}3066return JVMTI_ERROR_NONE;3067} /* end RawMonitorEnter */306830693070// rmonitor - pre-checked for validity3071jvmtiError3072JvmtiEnv::RawMonitorExit(JvmtiRawMonitor * rmonitor) {3073jvmtiError err = JVMTI_ERROR_NONE;30743075if (Threads::number_of_threads() == 0) {3076// No JavaThreads exist so just remove this monitor from the pending list.3077// Bool value from exit is false if rmonitor is not in the list.3078if (!JvmtiPendingMonitors::exit(rmonitor)) {3079err = JVMTI_ERROR_NOT_MONITOR_OWNER;3080}3081} else {3082int r = 0;3083Thread* thread = Thread::current();30843085if (thread->is_Java_thread()) {3086JavaThread* current_thread = (JavaThread*)thread;3087#ifdef PROPER_TRANSITIONS3088// Not really unknown but ThreadInVMfromNative does more than we want3089ThreadInVMfromUnknown __tiv;3090#endif /* PROPER_TRANSITIONS */3091r = rmonitor->raw_exit(current_thread);3092} else {3093if (thread->is_VM_thread() || thread->is_ConcurrentGC_thread()) {3094r = rmonitor->raw_exit(thread);3095} else {3096ShouldNotReachHere();3097}3098}30993100if (r == ObjectMonitor::OM_ILLEGAL_MONITOR_STATE) {3101err = JVMTI_ERROR_NOT_MONITOR_OWNER;3102} else {3103assert(r == ObjectMonitor::OM_OK, "raw_exit should have worked");3104if (r != ObjectMonitor::OM_OK) { // robustness3105err = JVMTI_ERROR_INTERNAL;3106}3107}3108}3109return err;3110} /* end RawMonitorExit */311131123113// rmonitor - pre-checked for validity3114jvmtiError3115JvmtiEnv::RawMonitorWait(JvmtiRawMonitor * rmonitor, jlong millis) {3116int r = 0;3117Thread* thread = Thread::current();31183119if (thread->is_Java_thread()) {3120JavaThread* current_thread = (JavaThread*)thread;3121#ifdef PROPER_TRANSITIONS3122// Not really unknown but ThreadInVMfromNative does more than we want3123ThreadInVMfromUnknown __tiv;3124{3125ThreadBlockInVM __tbivm(current_thread);3126r = rmonitor->raw_wait(millis, true, current_thread);3127}3128#else3129/* Transition to thread_blocked without entering vm state */3130/* This is really evil. Normally you can't undo _thread_blocked */3131/* transitions like this because it would cause us to miss a */3132/* safepoint but since the thread was already in _thread_in_native */3133/* the thread is not leaving a safepoint safe state and it will */3134/* block when it tries to return from native. We can't safepoint */3135/* block in here because we could deadlock the vmthread. Blech. */31363137JavaThreadState state = current_thread->thread_state();3138assert(state == _thread_in_native, "Must be _thread_in_native");3139// frame should already be walkable since we are in native3140assert(!current_thread->has_last_Java_frame() ||3141current_thread->frame_anchor()->walkable(), "Must be walkable");3142current_thread->set_thread_state(_thread_blocked);31433144r = rmonitor->raw_wait(millis, true, current_thread);3145// restore state, still at a safepoint safe state3146current_thread->set_thread_state(state);31473148#endif /* PROPER_TRANSITIONS */3149} else {3150if (thread->is_VM_thread() || thread->is_ConcurrentGC_thread()) {3151r = rmonitor->raw_wait(millis, true, thread);3152} else {3153ShouldNotReachHere();3154}3155}31563157switch (r) {3158case ObjectMonitor::OM_INTERRUPTED:3159return JVMTI_ERROR_INTERRUPT;3160case ObjectMonitor::OM_ILLEGAL_MONITOR_STATE:3161return JVMTI_ERROR_NOT_MONITOR_OWNER;3162}3163assert(r == ObjectMonitor::OM_OK, "raw_wait should have worked");3164if (r != ObjectMonitor::OM_OK) { // robustness3165return JVMTI_ERROR_INTERNAL;3166}31673168return JVMTI_ERROR_NONE;3169} /* end RawMonitorWait */317031713172// rmonitor - pre-checked for validity3173jvmtiError3174JvmtiEnv::RawMonitorNotify(JvmtiRawMonitor * rmonitor) {3175int r = 0;3176Thread* thread = Thread::current();31773178if (thread->is_Java_thread()) {3179JavaThread* current_thread = (JavaThread*)thread;3180// Not really unknown but ThreadInVMfromNative does more than we want3181ThreadInVMfromUnknown __tiv;3182r = rmonitor->raw_notify(current_thread);3183} else {3184if (thread->is_VM_thread() || thread->is_ConcurrentGC_thread()) {3185r = rmonitor->raw_notify(thread);3186} else {3187ShouldNotReachHere();3188}3189}31903191if (r == ObjectMonitor::OM_ILLEGAL_MONITOR_STATE) {3192return JVMTI_ERROR_NOT_MONITOR_OWNER;3193}3194assert(r == ObjectMonitor::OM_OK, "raw_notify should have worked");3195if (r != ObjectMonitor::OM_OK) { // robustness3196return JVMTI_ERROR_INTERNAL;3197}31983199return JVMTI_ERROR_NONE;3200} /* end RawMonitorNotify */320132023203// rmonitor - pre-checked for validity3204jvmtiError3205JvmtiEnv::RawMonitorNotifyAll(JvmtiRawMonitor * rmonitor) {3206int r = 0;3207Thread* thread = Thread::current();32083209if (thread->is_Java_thread()) {3210JavaThread* current_thread = (JavaThread*)thread;3211ThreadInVMfromUnknown __tiv;3212r = rmonitor->raw_notifyAll(current_thread);3213} else {3214if (thread->is_VM_thread() || thread->is_ConcurrentGC_thread()) {3215r = rmonitor->raw_notifyAll(thread);3216} else {3217ShouldNotReachHere();3218}3219}32203221if (r == ObjectMonitor::OM_ILLEGAL_MONITOR_STATE) {3222return JVMTI_ERROR_NOT_MONITOR_OWNER;3223}3224assert(r == ObjectMonitor::OM_OK, "raw_notifyAll should have worked");3225if (r != ObjectMonitor::OM_OK) { // robustness3226return JVMTI_ERROR_INTERNAL;3227}32283229return JVMTI_ERROR_NONE;3230} /* end RawMonitorNotifyAll */323132323233//3234// JNI Function Interception functions3235//323632373238// function_table - pre-checked for NULL3239jvmtiError3240JvmtiEnv::SetJNIFunctionTable(const jniNativeInterface* function_table) {3241// Copy jni function table at safepoint.3242VM_JNIFunctionTableCopier copier(function_table);3243VMThread::execute(&copier);32443245return JVMTI_ERROR_NONE;3246} /* end SetJNIFunctionTable */324732483249// function_table - pre-checked for NULL3250jvmtiError3251JvmtiEnv::GetJNIFunctionTable(jniNativeInterface** function_table) {3252*function_table=(jniNativeInterface*)jvmtiMalloc(sizeof(jniNativeInterface));3253if (*function_table == NULL)3254return JVMTI_ERROR_OUT_OF_MEMORY;3255memcpy(*function_table,(JavaThread::current())->get_jni_functions(),sizeof(jniNativeInterface));3256return JVMTI_ERROR_NONE;3257} /* end GetJNIFunctionTable */325832593260//3261// Event Management functions3262//32633264jvmtiError3265JvmtiEnv::GenerateEvents(jvmtiEvent event_type) {3266// can only generate two event types3267if (event_type != JVMTI_EVENT_COMPILED_METHOD_LOAD &&3268event_type != JVMTI_EVENT_DYNAMIC_CODE_GENERATED) {3269return JVMTI_ERROR_ILLEGAL_ARGUMENT;3270}32713272// for compiled_method_load events we must check that the environment3273// has the can_generate_compiled_method_load_events capability.3274if (event_type == JVMTI_EVENT_COMPILED_METHOD_LOAD) {3275if (get_capabilities()->can_generate_compiled_method_load_events == 0) {3276return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;3277}3278return JvmtiCodeBlobEvents::generate_compiled_method_load_events(this);3279} else {3280return JvmtiCodeBlobEvents::generate_dynamic_code_events(this);3281}32823283} /* end GenerateEvents */328432853286//3287// Extension Mechanism functions3288//32893290// extension_count_ptr - pre-checked for NULL3291// extensions - pre-checked for NULL3292jvmtiError3293JvmtiEnv::GetExtensionFunctions(jint* extension_count_ptr, jvmtiExtensionFunctionInfo** extensions) {3294return JvmtiExtensions::get_functions(this, extension_count_ptr, extensions);3295} /* end GetExtensionFunctions */329632973298// extension_count_ptr - pre-checked for NULL3299// extensions - pre-checked for NULL3300jvmtiError3301JvmtiEnv::GetExtensionEvents(jint* extension_count_ptr, jvmtiExtensionEventInfo** extensions) {3302return JvmtiExtensions::get_events(this, extension_count_ptr, extensions);3303} /* end GetExtensionEvents */330433053306// callback - NULL is a valid value, must be checked3307jvmtiError3308JvmtiEnv::SetExtensionEventCallback(jint extension_event_index, jvmtiExtensionEvent callback) {3309return JvmtiExtensions::set_event_callback(this, extension_event_index, callback);3310} /* end SetExtensionEventCallback */33113312//3313// Timers functions3314//33153316// info_ptr - pre-checked for NULL3317jvmtiError3318JvmtiEnv::GetCurrentThreadCpuTimerInfo(jvmtiTimerInfo* info_ptr) {3319os::current_thread_cpu_time_info(info_ptr);3320return JVMTI_ERROR_NONE;3321} /* end GetCurrentThreadCpuTimerInfo */332233233324// nanos_ptr - pre-checked for NULL3325jvmtiError3326JvmtiEnv::GetCurrentThreadCpuTime(jlong* nanos_ptr) {3327*nanos_ptr = os::current_thread_cpu_time();3328return JVMTI_ERROR_NONE;3329} /* end GetCurrentThreadCpuTime */333033313332// info_ptr - pre-checked for NULL3333jvmtiError3334JvmtiEnv::GetThreadCpuTimerInfo(jvmtiTimerInfo* info_ptr) {3335os::thread_cpu_time_info(info_ptr);3336return JVMTI_ERROR_NONE;3337} /* end GetThreadCpuTimerInfo */333833393340// Threads_lock NOT held, java_thread not protected by lock3341// java_thread - pre-checked3342// nanos_ptr - pre-checked for NULL3343jvmtiError3344JvmtiEnv::GetThreadCpuTime(JavaThread* java_thread, jlong* nanos_ptr) {3345*nanos_ptr = os::thread_cpu_time(java_thread);3346return JVMTI_ERROR_NONE;3347} /* end GetThreadCpuTime */334833493350// info_ptr - pre-checked for NULL3351jvmtiError3352JvmtiEnv::GetTimerInfo(jvmtiTimerInfo* info_ptr) {3353os::javaTimeNanos_info(info_ptr);3354return JVMTI_ERROR_NONE;3355} /* end GetTimerInfo */335633573358// nanos_ptr - pre-checked for NULL3359jvmtiError3360JvmtiEnv::GetTime(jlong* nanos_ptr) {3361*nanos_ptr = os::javaTimeNanos();3362return JVMTI_ERROR_NONE;3363} /* end GetTime */336433653366// processor_count_ptr - pre-checked for NULL3367jvmtiError3368JvmtiEnv::GetAvailableProcessors(jint* processor_count_ptr) {3369*processor_count_ptr = os::active_processor_count();3370return JVMTI_ERROR_NONE;3371} /* end GetAvailableProcessors */33723373//3374// System Properties functions3375//33763377// count_ptr - pre-checked for NULL3378// property_ptr - pre-checked for NULL3379jvmtiError3380JvmtiEnv::GetSystemProperties(jint* count_ptr, char*** property_ptr) {3381jvmtiError err = JVMTI_ERROR_NONE;33823383*count_ptr = Arguments::PropertyList_count(Arguments::system_properties());33843385err = allocate(*count_ptr * sizeof(char *), (unsigned char **)property_ptr);3386if (err != JVMTI_ERROR_NONE) {3387return err;3388}3389int i = 0 ;3390for (SystemProperty* p = Arguments::system_properties(); p != NULL && i < *count_ptr; p = p->next(), i++) {3391const char *key = p->key();3392char **tmp_value = *property_ptr+i;3393err = allocate((strlen(key)+1) * sizeof(char), (unsigned char**)tmp_value);3394if (err == JVMTI_ERROR_NONE) {3395strcpy(*tmp_value, key);3396} else {3397// clean up previously allocated memory.3398for (int j = 0; j < i; j++) {3399Deallocate((unsigned char*)*property_ptr+j);3400}3401Deallocate((unsigned char*)property_ptr);3402break;3403}3404}3405return err;3406} /* end GetSystemProperties */340734083409// property - pre-checked for NULL3410// value_ptr - pre-checked for NULL3411jvmtiError3412JvmtiEnv::GetSystemProperty(const char* property, char** value_ptr) {3413jvmtiError err = JVMTI_ERROR_NONE;3414const char *value;34153416value = Arguments::PropertyList_get_value(Arguments::system_properties(), property);3417if (value == NULL) {3418err = JVMTI_ERROR_NOT_AVAILABLE;3419} else {3420err = allocate((strlen(value)+1) * sizeof(char), (unsigned char **)value_ptr);3421if (err == JVMTI_ERROR_NONE) {3422strcpy(*value_ptr, value);3423}3424}3425return err;3426} /* end GetSystemProperty */342734283429// property - pre-checked for NULL3430// value - NULL is a valid value, must be checked3431jvmtiError3432JvmtiEnv::SetSystemProperty(const char* property, const char* value_ptr) {3433jvmtiError err =JVMTI_ERROR_NOT_AVAILABLE;34343435for (SystemProperty* p = Arguments::system_properties(); p != NULL; p = p->next()) {3436if (strcmp(property, p->key()) == 0) {3437if (p->set_value((char *)value_ptr)) {3438err = JVMTI_ERROR_NONE;3439}3440}3441}3442return err;3443} /* end SetSystemProperty */344434453446