Path: blob/master/src/hotspot/share/prims/jvmtiEnv.cpp
41144 views
/*1* Copyright (c) 2003, 2021, 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/javaClasses.inline.hpp"27#include "classfile/stringTable.hpp"28#include "classfile/modules.hpp"29#include "classfile/systemDictionary.hpp"30#include "classfile/vmClasses.hpp"31#include "classfile/vmSymbols.hpp"32#include "gc/shared/collectedHeap.hpp"33#include "interpreter/bytecodeStream.hpp"34#include "interpreter/interpreter.hpp"35#include "jfr/jfrEvents.hpp"36#include "jvmtifiles/jvmtiEnv.hpp"37#include "logging/log.hpp"38#include "logging/logConfiguration.hpp"39#include "memory/resourceArea.hpp"40#include "memory/universe.hpp"41#include "oops/instanceKlass.hpp"42#include "oops/klass.inline.hpp"43#include "oops/objArrayOop.inline.hpp"44#include "oops/oop.inline.hpp"45#include "prims/jniCheck.hpp"46#include "prims/jvm_misc.hpp"47#include "prims/jvmtiAgentThread.hpp"48#include "prims/jvmtiClassFileReconstituter.hpp"49#include "prims/jvmtiCodeBlobEvents.hpp"50#include "prims/jvmtiExtensions.hpp"51#include "prims/jvmtiGetLoadedClasses.hpp"52#include "prims/jvmtiImpl.hpp"53#include "prims/jvmtiManageCapabilities.hpp"54#include "prims/jvmtiRawMonitor.hpp"55#include "prims/jvmtiRedefineClasses.hpp"56#include "prims/jvmtiTagMap.hpp"57#include "prims/jvmtiThreadState.inline.hpp"58#include "prims/jvmtiUtil.hpp"59#include "runtime/arguments.hpp"60#include "runtime/deoptimization.hpp"61#include "runtime/fieldDescriptor.inline.hpp"62#include "runtime/handles.inline.hpp"63#include "runtime/interfaceSupport.inline.hpp"64#include "runtime/javaCalls.hpp"65#include "runtime/jfieldIDWorkaround.hpp"66#include "runtime/jniHandles.inline.hpp"67#include "runtime/objectMonitor.inline.hpp"68#include "runtime/osThread.hpp"69#include "runtime/reflectionUtils.hpp"70#include "runtime/signature.hpp"71#include "runtime/thread.inline.hpp"72#include "runtime/threadHeapSampler.hpp"73#include "runtime/threadSMR.hpp"74#include "runtime/timerTrace.hpp"75#include "runtime/vframe.inline.hpp"76#include "runtime/vmThread.hpp"77#include "services/threadService.hpp"78#include "utilities/exceptions.hpp"79#include "utilities/preserveException.hpp"80#include "utilities/utf8.hpp"818283#define FIXLATER 0 // REMOVE this when completed.8485// FIXLATER: hook into JvmtiTrace86#define TraceJVMTICalls false8788JvmtiEnv::JvmtiEnv(jint version) : JvmtiEnvBase(version) {89}9091JvmtiEnv::~JvmtiEnv() {92}9394JvmtiEnv*95JvmtiEnv::create_a_jvmti(jint version) {96return new JvmtiEnv(version);97}9899// VM operation class to copy jni function table at safepoint.100// More than one java threads or jvmti agents may be reading/101// modifying jni function tables. To reduce the risk of bad102// interaction b/w these threads it is copied at safepoint.103class VM_JNIFunctionTableCopier : public VM_Operation {104private:105const struct JNINativeInterface_ *_function_table;106public:107VM_JNIFunctionTableCopier(const struct JNINativeInterface_ *func_tbl) {108_function_table = func_tbl;109};110111VMOp_Type type() const { return VMOp_JNIFunctionTableCopier; }112void doit() {113copy_jni_function_table(_function_table);114};115};116117//118// Do not change the "prefix" marker below, everything above it is copied119// unchanged into the filled stub, everything below is controlled by the120// stub filler (only method bodies are carried forward, and then only for121// functionality still in the spec).122//123// end file prefix124125//126// Memory Management functions127//128129// mem_ptr - pre-checked for NULL130jvmtiError131JvmtiEnv::Allocate(jlong size, unsigned char** mem_ptr) {132return allocate(size, mem_ptr);133} /* end Allocate */134135136// mem - NULL is a valid value, must be checked137jvmtiError138JvmtiEnv::Deallocate(unsigned char* mem) {139return deallocate(mem);140} /* end Deallocate */141142// java_thread - protected by ThreadsListHandle and pre-checked143// data - NULL is a valid value, must be checked144jvmtiError145JvmtiEnv::SetThreadLocalStorage(JavaThread* java_thread, const void* data) {146JvmtiThreadState* state = java_thread->jvmti_thread_state();147if (state == NULL) {148if (data == NULL) {149// leaving state unset same as data set to NULL150return JVMTI_ERROR_NONE;151}152// otherwise, create the state153state = JvmtiThreadState::state_for(java_thread);154if (state == NULL) {155return JVMTI_ERROR_THREAD_NOT_ALIVE;156}157}158state->env_thread_state(this)->set_agent_thread_local_storage_data((void*)data);159return JVMTI_ERROR_NONE;160} /* end SetThreadLocalStorage */161162163// thread - NOT protected by ThreadsListHandle and NOT pre-checked164// data_ptr - pre-checked for NULL165jvmtiError166JvmtiEnv::GetThreadLocalStorage(jthread thread, void** data_ptr) {167JavaThread* current_thread = JavaThread::current();168if (thread == NULL) {169JvmtiThreadState* state = current_thread->jvmti_thread_state();170*data_ptr = (state == NULL) ? NULL :171state->env_thread_state(this)->get_agent_thread_local_storage_data();172} else {173// jvmti_GetThreadLocalStorage is "in native" and doesn't transition174// the thread to _thread_in_vm. However, when the TLS for a thread175// other than the current thread is required we need to transition176// from native so as to resolve the jthread.177178MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, current_thread));179ThreadInVMfromNative __tiv(current_thread);180VM_ENTRY_BASE(jvmtiError, JvmtiEnv::GetThreadLocalStorage , current_thread)181debug_only(VMNativeEntryWrapper __vew;)182183JavaThread* java_thread = NULL;184ThreadsListHandle tlh(current_thread);185jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), thread, &java_thread, NULL);186if (err != JVMTI_ERROR_NONE) {187return err;188}189190JvmtiThreadState* state = java_thread->jvmti_thread_state();191*data_ptr = (state == NULL) ? NULL :192state->env_thread_state(this)->get_agent_thread_local_storage_data();193}194return JVMTI_ERROR_NONE;195} /* end GetThreadLocalStorage */196197//198// Module functions199//200201// module_count_ptr - pre-checked for NULL202// modules_ptr - pre-checked for NULL203jvmtiError204JvmtiEnv::GetAllModules(jint* module_count_ptr, jobject** modules_ptr) {205JvmtiModuleClosure jmc;206207return jmc.get_all_modules(this, module_count_ptr, modules_ptr);208} /* end GetAllModules */209210211// class_loader - NULL is a valid value, must be pre-checked212// package_name - pre-checked for NULL213// module_ptr - pre-checked for NULL214jvmtiError215JvmtiEnv::GetNamedModule(jobject class_loader, const char* package_name, jobject* module_ptr) {216JavaThread* THREAD = JavaThread::current(); // For exception macros.217ResourceMark rm(THREAD);218Handle h_loader (THREAD, JNIHandles::resolve(class_loader));219// Check that loader is a subclass of java.lang.ClassLoader.220if (h_loader.not_null() && !java_lang_ClassLoader::is_subclass(h_loader->klass())) {221return JVMTI_ERROR_ILLEGAL_ARGUMENT;222}223oop module = Modules::get_named_module(h_loader, package_name);224*module_ptr = module != NULL ? JNIHandles::make_local(THREAD, module) : NULL;225return JVMTI_ERROR_NONE;226} /* end GetNamedModule */227228229// module - pre-checked for NULL230// to_module - pre-checked for NULL231jvmtiError232JvmtiEnv::AddModuleReads(jobject module, jobject to_module) {233JavaThread* THREAD = JavaThread::current(); // For exception macros.234235// check module236Handle h_module(THREAD, JNIHandles::resolve(module));237if (!java_lang_Module::is_instance(h_module())) {238return JVMTI_ERROR_INVALID_MODULE;239}240// check to_module241Handle h_to_module(THREAD, JNIHandles::resolve(to_module));242if (!java_lang_Module::is_instance(h_to_module())) {243return JVMTI_ERROR_INVALID_MODULE;244}245return JvmtiExport::add_module_reads(h_module, h_to_module, THREAD);246} /* end AddModuleReads */247248249// module - pre-checked for NULL250// pkg_name - pre-checked for NULL251// to_module - pre-checked for NULL252jvmtiError253JvmtiEnv::AddModuleExports(jobject module, const char* pkg_name, jobject to_module) {254JavaThread* THREAD = JavaThread::current(); // For exception macros.255Handle h_pkg = java_lang_String::create_from_str(pkg_name, THREAD);256257// check module258Handle h_module(THREAD, JNIHandles::resolve(module));259if (!java_lang_Module::is_instance(h_module())) {260return JVMTI_ERROR_INVALID_MODULE;261}262// check to_module263Handle h_to_module(THREAD, JNIHandles::resolve(to_module));264if (!java_lang_Module::is_instance(h_to_module())) {265return JVMTI_ERROR_INVALID_MODULE;266}267return JvmtiExport::add_module_exports(h_module, h_pkg, h_to_module, THREAD);268} /* end AddModuleExports */269270271// module - pre-checked for NULL272// pkg_name - pre-checked for NULL273// to_module - pre-checked for NULL274jvmtiError275JvmtiEnv::AddModuleOpens(jobject module, const char* pkg_name, jobject to_module) {276JavaThread* THREAD = JavaThread::current(); // For exception macros.277Handle h_pkg = java_lang_String::create_from_str(pkg_name, THREAD);278279// check module280Handle h_module(THREAD, JNIHandles::resolve(module));281if (!java_lang_Module::is_instance(h_module())) {282return JVMTI_ERROR_INVALID_MODULE;283}284// check to_module285Handle h_to_module(THREAD, JNIHandles::resolve(to_module));286if (!java_lang_Module::is_instance(h_to_module())) {287return JVMTI_ERROR_INVALID_MODULE;288}289return JvmtiExport::add_module_opens(h_module, h_pkg, h_to_module, THREAD);290} /* end AddModuleOpens */291292293// module - pre-checked for NULL294// service - pre-checked for NULL295jvmtiError296JvmtiEnv::AddModuleUses(jobject module, jclass service) {297JavaThread* THREAD = JavaThread::current(); // For exception macros.298299// check module300Handle h_module(THREAD, JNIHandles::resolve(module));301if (!java_lang_Module::is_instance(h_module())) {302return JVMTI_ERROR_INVALID_MODULE;303}304// check service305Handle h_service(THREAD, JNIHandles::resolve_external_guard(service));306if (!java_lang_Class::is_instance(h_service()) ||307java_lang_Class::is_primitive(h_service())) {308return JVMTI_ERROR_INVALID_CLASS;309}310return JvmtiExport::add_module_uses(h_module, h_service, THREAD);311} /* end AddModuleUses */312313314// module - pre-checked for NULL315// service - pre-checked for NULL316// impl_class - pre-checked for NULL317jvmtiError318JvmtiEnv::AddModuleProvides(jobject module, jclass service, jclass impl_class) {319JavaThread* THREAD = JavaThread::current(); // For exception macros.320321// check module322Handle h_module(THREAD, JNIHandles::resolve(module));323if (!java_lang_Module::is_instance(h_module())) {324return JVMTI_ERROR_INVALID_MODULE;325}326// check service327Handle h_service(THREAD, JNIHandles::resolve_external_guard(service));328if (!java_lang_Class::is_instance(h_service()) ||329java_lang_Class::is_primitive(h_service())) {330return JVMTI_ERROR_INVALID_CLASS;331}332// check impl_class333Handle h_impl_class(THREAD, JNIHandles::resolve_external_guard(impl_class));334if (!java_lang_Class::is_instance(h_impl_class()) ||335java_lang_Class::is_primitive(h_impl_class())) {336return JVMTI_ERROR_INVALID_CLASS;337}338return JvmtiExport::add_module_provides(h_module, h_service, h_impl_class, THREAD);339} /* end AddModuleProvides */340341// module - pre-checked for NULL342// is_modifiable_class_ptr - pre-checked for NULL343jvmtiError344JvmtiEnv::IsModifiableModule(jobject module, jboolean* is_modifiable_module_ptr) {345JavaThread* current = JavaThread::current();346347// check module348Handle h_module(current, JNIHandles::resolve(module));349if (!java_lang_Module::is_instance(h_module())) {350return JVMTI_ERROR_INVALID_MODULE;351}352353*is_modifiable_module_ptr = JNI_TRUE;354return JVMTI_ERROR_NONE;355} /* end IsModifiableModule */356357358//359// Class functions360//361362// class_count_ptr - pre-checked for NULL363// classes_ptr - pre-checked for NULL364jvmtiError365JvmtiEnv::GetLoadedClasses(jint* class_count_ptr, jclass** classes_ptr) {366return JvmtiGetLoadedClasses::getLoadedClasses(this, class_count_ptr, classes_ptr);367} /* end GetLoadedClasses */368369370// initiating_loader - NULL is a valid value, must be checked371// class_count_ptr - pre-checked for NULL372// classes_ptr - pre-checked for NULL373jvmtiError374JvmtiEnv::GetClassLoaderClasses(jobject initiating_loader, jint* class_count_ptr, jclass** classes_ptr) {375return JvmtiGetLoadedClasses::getClassLoaderClasses(this, initiating_loader,376class_count_ptr, classes_ptr);377} /* end GetClassLoaderClasses */378379// k_mirror - may be primitive, this must be checked380// is_modifiable_class_ptr - pre-checked for NULL381jvmtiError382JvmtiEnv::IsModifiableClass(oop k_mirror, jboolean* is_modifiable_class_ptr) {383*is_modifiable_class_ptr = VM_RedefineClasses::is_modifiable_class(k_mirror)?384JNI_TRUE : JNI_FALSE;385return JVMTI_ERROR_NONE;386} /* end IsModifiableClass */387388// class_count - pre-checked to be greater than or equal to 0389// classes - pre-checked for NULL390jvmtiError391JvmtiEnv::RetransformClasses(jint class_count, const jclass* classes) {392//TODO: add locking393394int index;395JavaThread* current_thread = JavaThread::current();396ResourceMark rm(current_thread);397398jvmtiClassDefinition* class_definitions =399NEW_RESOURCE_ARRAY(jvmtiClassDefinition, class_count);400NULL_CHECK(class_definitions, JVMTI_ERROR_OUT_OF_MEMORY);401402for (index = 0; index < class_count; index++) {403HandleMark hm(current_thread);404405jclass jcls = classes[index];406oop k_mirror = JNIHandles::resolve_external_guard(jcls);407if (k_mirror == NULL) {408return JVMTI_ERROR_INVALID_CLASS;409}410if (!k_mirror->is_a(vmClasses::Class_klass())) {411return JVMTI_ERROR_INVALID_CLASS;412}413414if (!VM_RedefineClasses::is_modifiable_class(k_mirror)) {415return JVMTI_ERROR_UNMODIFIABLE_CLASS;416}417418Klass* klass = java_lang_Class::as_Klass(k_mirror);419420jint status = klass->jvmti_class_status();421if (status & (JVMTI_CLASS_STATUS_ERROR)) {422return JVMTI_ERROR_INVALID_CLASS;423}424425InstanceKlass* ik = InstanceKlass::cast(klass);426if (ik->get_cached_class_file_bytes() == NULL) {427// Not cached, we need to reconstitute the class file from the428// VM representation. We don't attach the reconstituted class429// bytes to the InstanceKlass here because they have not been430// validated and we're not at a safepoint.431JvmtiClassFileReconstituter reconstituter(ik);432if (reconstituter.get_error() != JVMTI_ERROR_NONE) {433return reconstituter.get_error();434}435436class_definitions[index].class_byte_count = (jint)reconstituter.class_file_size();437class_definitions[index].class_bytes = (unsigned char*)438reconstituter.class_file_bytes();439} else {440// it is cached, get it from the cache441class_definitions[index].class_byte_count = ik->get_cached_class_file_len();442class_definitions[index].class_bytes = ik->get_cached_class_file_bytes();443}444class_definitions[index].klass = jcls;445}446EventRetransformClasses event;447VM_RedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_retransform);448VMThread::execute(&op);449jvmtiError error = op.check_error();450if (error == JVMTI_ERROR_NONE) {451event.set_classCount(class_count);452event.set_redefinitionId(op.id());453event.commit();454}455return error;456} /* end RetransformClasses */457458459// class_count - pre-checked to be greater than or equal to 0460// class_definitions - pre-checked for NULL461jvmtiError462JvmtiEnv::RedefineClasses(jint class_count, const jvmtiClassDefinition* class_definitions) {463//TODO: add locking464EventRedefineClasses event;465VM_RedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_redefine);466VMThread::execute(&op);467jvmtiError error = op.check_error();468if (error == JVMTI_ERROR_NONE) {469event.set_classCount(class_count);470event.set_redefinitionId(op.id());471event.commit();472}473return error;474} /* end RedefineClasses */475476477//478// Object functions479//480481// size_ptr - pre-checked for NULL482jvmtiError483JvmtiEnv::GetObjectSize(jobject object, jlong* size_ptr) {484oop mirror = JNIHandles::resolve_external_guard(object);485NULL_CHECK(mirror, JVMTI_ERROR_INVALID_OBJECT);486*size_ptr = (jlong)mirror->size() * wordSize;487return JVMTI_ERROR_NONE;488} /* end GetObjectSize */489490//491// Method functions492//493494// prefix - NULL is a valid value, must be checked495jvmtiError496JvmtiEnv::SetNativeMethodPrefix(const char* prefix) {497return prefix == NULL?498SetNativeMethodPrefixes(0, NULL) :499SetNativeMethodPrefixes(1, (char**)&prefix);500} /* end SetNativeMethodPrefix */501502503// prefix_count - pre-checked to be greater than or equal to 0504// prefixes - pre-checked for NULL505jvmtiError506JvmtiEnv::SetNativeMethodPrefixes(jint prefix_count, char** prefixes) {507// Have to grab JVMTI thread state lock to be sure that some thread508// isn't accessing the prefixes at the same time we are setting them.509// No locks during VM bring-up.510if (Threads::number_of_threads() == 0) {511return set_native_method_prefixes(prefix_count, prefixes);512} else {513MutexLocker mu(JvmtiThreadState_lock);514return set_native_method_prefixes(prefix_count, prefixes);515}516} /* end SetNativeMethodPrefixes */517518//519// Event Management functions520//521522// callbacks - NULL is a valid value, must be checked523// size_of_callbacks - pre-checked to be greater than or equal to 0524jvmtiError525JvmtiEnv::SetEventCallbacks(const jvmtiEventCallbacks* callbacks, jint size_of_callbacks) {526JvmtiEventController::set_event_callbacks(this, callbacks, size_of_callbacks);527return JVMTI_ERROR_NONE;528} /* end SetEventCallbacks */529530531// event_thread - NULL is a valid value, must be checked532jvmtiError533JvmtiEnv::SetEventNotificationMode(jvmtiEventMode mode, jvmtiEvent event_type, jthread event_thread, ...) {534if (event_thread == NULL) {535// Can be called at Agent_OnLoad() time with event_thread == NULL536// when Thread::current() does not work yet so we cannot create a537// ThreadsListHandle that is common to both thread-specific and538// global code paths.539540// event_type must be valid541if (!JvmtiEventController::is_valid_event_type(event_type)) {542return JVMTI_ERROR_INVALID_EVENT_TYPE;543}544545bool enabled = (mode == JVMTI_ENABLE);546547// assure that needed capabilities are present548if (enabled && !JvmtiUtil::has_event_capability(event_type, get_capabilities())) {549return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;550}551552if (event_type == JVMTI_EVENT_CLASS_FILE_LOAD_HOOK && enabled) {553record_class_file_load_hook_enabled();554}555556JvmtiEventController::set_user_enabled(this, (JavaThread*) NULL, event_type, enabled);557} else {558// We have a specified event_thread.559JavaThread* java_thread = NULL;560ThreadsListHandle tlh;561jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), event_thread, &java_thread, NULL);562if (err != JVMTI_ERROR_NONE) {563return err;564}565566// event_type must be valid567if (!JvmtiEventController::is_valid_event_type(event_type)) {568return JVMTI_ERROR_INVALID_EVENT_TYPE;569}570571// global events cannot be controlled at thread level.572if (JvmtiEventController::is_global_event(event_type)) {573return JVMTI_ERROR_ILLEGAL_ARGUMENT;574}575576bool enabled = (mode == JVMTI_ENABLE);577578// assure that needed capabilities are present579if (enabled && !JvmtiUtil::has_event_capability(event_type, get_capabilities())) {580return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;581}582583if (event_type == JVMTI_EVENT_CLASS_FILE_LOAD_HOOK && enabled) {584record_class_file_load_hook_enabled();585}586JvmtiEventController::set_user_enabled(this, java_thread, event_type, enabled);587}588589return JVMTI_ERROR_NONE;590} /* end SetEventNotificationMode */591592//593// Capability functions594//595596// capabilities_ptr - pre-checked for NULL597jvmtiError598JvmtiEnv::GetPotentialCapabilities(jvmtiCapabilities* capabilities_ptr) {599JvmtiManageCapabilities::get_potential_capabilities(get_capabilities(),600get_prohibited_capabilities(),601capabilities_ptr);602return JVMTI_ERROR_NONE;603} /* end GetPotentialCapabilities */604605606// capabilities_ptr - pre-checked for NULL607jvmtiError608JvmtiEnv::AddCapabilities(const jvmtiCapabilities* capabilities_ptr) {609return JvmtiManageCapabilities::add_capabilities(get_capabilities(),610get_prohibited_capabilities(),611capabilities_ptr,612get_capabilities());613} /* end AddCapabilities */614615616// capabilities_ptr - pre-checked for NULL617jvmtiError618JvmtiEnv::RelinquishCapabilities(const jvmtiCapabilities* capabilities_ptr) {619JvmtiManageCapabilities::relinquish_capabilities(get_capabilities(), capabilities_ptr, get_capabilities());620return JVMTI_ERROR_NONE;621} /* end RelinquishCapabilities */622623624// capabilities_ptr - pre-checked for NULL625jvmtiError626JvmtiEnv::GetCapabilities(jvmtiCapabilities* capabilities_ptr) {627JvmtiManageCapabilities::copy_capabilities(get_capabilities(), capabilities_ptr);628return JVMTI_ERROR_NONE;629} /* end GetCapabilities */630631//632// Class Loader Search functions633//634635// segment - pre-checked for NULL636jvmtiError637JvmtiEnv::AddToBootstrapClassLoaderSearch(const char* segment) {638jvmtiPhase phase = get_phase();639if (phase == JVMTI_PHASE_ONLOAD) {640Arguments::append_sysclasspath(segment);641return JVMTI_ERROR_NONE;642} else if (use_version_1_0_semantics()) {643// This JvmtiEnv requested version 1.0 semantics and this function644// is only allowed in the ONLOAD phase in version 1.0 so we need to645// return an error here.646return JVMTI_ERROR_WRONG_PHASE;647} else if (phase == JVMTI_PHASE_LIVE) {648// The phase is checked by the wrapper that called this function,649// but this thread could be racing with the thread that is650// terminating the VM so we check one more time.651652// create the zip entry653ClassPathZipEntry* zip_entry = ClassLoader::create_class_path_zip_entry(segment, true);654if (zip_entry == NULL) {655return JVMTI_ERROR_ILLEGAL_ARGUMENT;656}657658// add the jar file to the bootclasspath659log_info(class, load)("opened: %s", zip_entry->name());660#if INCLUDE_CDS661ClassLoaderExt::append_boot_classpath(zip_entry);662#else663ClassLoader::add_to_boot_append_entries(zip_entry);664#endif665return JVMTI_ERROR_NONE;666} else {667return JVMTI_ERROR_WRONG_PHASE;668}669670} /* end AddToBootstrapClassLoaderSearch */671672673// segment - pre-checked for NULL674jvmtiError675JvmtiEnv::AddToSystemClassLoaderSearch(const char* segment) {676jvmtiPhase phase = get_phase();677678if (phase == JVMTI_PHASE_ONLOAD) {679for (SystemProperty* p = Arguments::system_properties(); p != NULL; p = p->next()) {680if (strcmp("java.class.path", p->key()) == 0) {681p->append_value(segment);682break;683}684}685return JVMTI_ERROR_NONE;686} else if (phase == JVMTI_PHASE_LIVE) {687// The phase is checked by the wrapper that called this function,688// but this thread could be racing with the thread that is689// terminating the VM so we check one more time.690JavaThread* THREAD = JavaThread::current(); // For exception macros.691HandleMark hm(THREAD);692693// create the zip entry (which will open the zip file and hence694// check that the segment is indeed a zip file).695ClassPathZipEntry* zip_entry = ClassLoader::create_class_path_zip_entry(segment, false);696if (zip_entry == NULL) {697return JVMTI_ERROR_ILLEGAL_ARGUMENT;698}699delete zip_entry; // no longer needed700701// lock the loader702Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());703ObjectLocker ol(loader, THREAD);704705// need the path as java.lang.String706Handle path = java_lang_String::create_from_platform_dependent_str(segment, THREAD);707if (HAS_PENDING_EXCEPTION) {708CLEAR_PENDING_EXCEPTION;709return JVMTI_ERROR_INTERNAL;710}711712// Invoke the appendToClassPathForInstrumentation method - if the method713// is not found it means the loader doesn't support adding to the class path714// in the live phase.715{716JavaValue res(T_VOID);717JavaCalls::call_special(&res,718loader,719loader->klass(),720vmSymbols::appendToClassPathForInstrumentation_name(),721vmSymbols::appendToClassPathForInstrumentation_signature(),722path,723THREAD);724if (HAS_PENDING_EXCEPTION) {725Symbol* ex_name = PENDING_EXCEPTION->klass()->name();726CLEAR_PENDING_EXCEPTION;727728if (ex_name == vmSymbols::java_lang_NoSuchMethodError()) {729return JVMTI_ERROR_CLASS_LOADER_UNSUPPORTED;730} else {731return JVMTI_ERROR_INTERNAL;732}733}734}735736return JVMTI_ERROR_NONE;737} else {738return JVMTI_ERROR_WRONG_PHASE;739}740} /* end AddToSystemClassLoaderSearch */741742//743// General functions744//745746// phase_ptr - pre-checked for NULL747jvmtiError748JvmtiEnv::GetPhase(jvmtiPhase* phase_ptr) {749*phase_ptr = phase();750return JVMTI_ERROR_NONE;751} /* end GetPhase */752753754jvmtiError755JvmtiEnv::DisposeEnvironment() {756dispose();757return JVMTI_ERROR_NONE;758} /* end DisposeEnvironment */759760761// data - NULL is a valid value, must be checked762jvmtiError763JvmtiEnv::SetEnvironmentLocalStorage(const void* data) {764set_env_local_storage(data);765return JVMTI_ERROR_NONE;766} /* end SetEnvironmentLocalStorage */767768769// data_ptr - pre-checked for NULL770jvmtiError771JvmtiEnv::GetEnvironmentLocalStorage(void** data_ptr) {772*data_ptr = (void*)get_env_local_storage();773return JVMTI_ERROR_NONE;774} /* end GetEnvironmentLocalStorage */775776// version_ptr - pre-checked for NULL777jvmtiError778JvmtiEnv::GetVersionNumber(jint* version_ptr) {779*version_ptr = JVMTI_VERSION;780return JVMTI_ERROR_NONE;781} /* end GetVersionNumber */782783784// name_ptr - pre-checked for NULL785jvmtiError786JvmtiEnv::GetErrorName(jvmtiError error, char** name_ptr) {787if (error < JVMTI_ERROR_NONE || error > JVMTI_ERROR_MAX) {788return JVMTI_ERROR_ILLEGAL_ARGUMENT;789}790const char *name = JvmtiUtil::error_name(error);791if (name == NULL) {792return JVMTI_ERROR_ILLEGAL_ARGUMENT;793}794size_t len = strlen(name) + 1;795jvmtiError err = allocate(len, (unsigned char**)name_ptr);796if (err == JVMTI_ERROR_NONE) {797memcpy(*name_ptr, name, len);798}799return err;800} /* end GetErrorName */801802803jvmtiError804JvmtiEnv::SetVerboseFlag(jvmtiVerboseFlag flag, jboolean value) {805LogLevelType level = value == 0 ? LogLevel::Off : LogLevel::Info;806switch (flag) {807case JVMTI_VERBOSE_OTHER:808// ignore809break;810case JVMTI_VERBOSE_CLASS:811LogConfiguration::configure_stdout(level, false, LOG_TAGS(class, unload));812LogConfiguration::configure_stdout(level, false, LOG_TAGS(class, load));813break;814case JVMTI_VERBOSE_GC:815LogConfiguration::configure_stdout(level, true, LOG_TAGS(gc));816break;817case JVMTI_VERBOSE_JNI:818level = value == 0 ? LogLevel::Off : LogLevel::Debug;819LogConfiguration::configure_stdout(level, true, LOG_TAGS(jni, resolve));820break;821default:822return JVMTI_ERROR_ILLEGAL_ARGUMENT;823};824return JVMTI_ERROR_NONE;825} /* end SetVerboseFlag */826827828// format_ptr - pre-checked for NULL829jvmtiError830JvmtiEnv::GetJLocationFormat(jvmtiJlocationFormat* format_ptr) {831*format_ptr = JVMTI_JLOCATION_JVMBCI;832return JVMTI_ERROR_NONE;833} /* end GetJLocationFormat */834835//836// Thread functions837//838839// thread - NOT protected by ThreadsListHandle and NOT pre-checked840// thread_state_ptr - pre-checked for NULL841jvmtiError842JvmtiEnv::GetThreadState(jthread thread, jint* thread_state_ptr) {843JavaThread* current_thread = JavaThread::current();844JavaThread* java_thread = NULL;845oop thread_oop = NULL;846ThreadsListHandle tlh(current_thread);847848if (thread == NULL) {849java_thread = current_thread;850thread_oop = java_thread->threadObj();851852if (thread_oop == NULL || !thread_oop->is_a(vmClasses::Thread_klass())) {853return JVMTI_ERROR_INVALID_THREAD;854}855} else {856jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), thread, &java_thread, &thread_oop);857if (err != JVMTI_ERROR_NONE) {858// We got an error code so we don't have a JavaThread *, but859// only return an error from here if we didn't get a valid860// thread_oop.861if (thread_oop == NULL) {862return err;863}864// We have a valid thread_oop so we can return some thread state.865}866}867868// get most state bits869jint state = (jint)java_lang_Thread::get_thread_status(thread_oop);870871if (java_thread != NULL) {872// We have a JavaThread* so add more state bits.873JavaThreadState jts = java_thread->thread_state();874875if (java_thread->is_suspended()) {876state |= JVMTI_THREAD_STATE_SUSPENDED;877}878if (jts == _thread_in_native) {879state |= JVMTI_THREAD_STATE_IN_NATIVE;880}881if (java_thread->is_interrupted(false)) {882state |= JVMTI_THREAD_STATE_INTERRUPTED;883}884}885886*thread_state_ptr = state;887return JVMTI_ERROR_NONE;888} /* end GetThreadState */889890891// thread_ptr - pre-checked for NULL892jvmtiError893JvmtiEnv::GetCurrentThread(jthread* thread_ptr) {894JavaThread* current_thread = JavaThread::current();895*thread_ptr = (jthread)JNIHandles::make_local(current_thread, current_thread->threadObj());896return JVMTI_ERROR_NONE;897} /* end GetCurrentThread */898899900// threads_count_ptr - pre-checked for NULL901// threads_ptr - pre-checked for NULL902jvmtiError903JvmtiEnv::GetAllThreads(jint* threads_count_ptr, jthread** threads_ptr) {904int nthreads = 0;905Handle *thread_objs = NULL;906Thread* current_thread = Thread::current();907ResourceMark rm(current_thread);908HandleMark hm(current_thread);909910// enumerate threads (including agent threads)911ThreadsListEnumerator tle(current_thread, true);912nthreads = tle.num_threads();913*threads_count_ptr = nthreads;914915if (nthreads == 0) {916*threads_ptr = NULL;917return JVMTI_ERROR_NONE;918}919920thread_objs = NEW_RESOURCE_ARRAY(Handle, nthreads);921NULL_CHECK(thread_objs, JVMTI_ERROR_OUT_OF_MEMORY);922923for (int i = 0; i < nthreads; i++) {924thread_objs[i] = Handle(tle.get_threadObj(i));925}926927jthread *jthreads = new_jthreadArray(nthreads, thread_objs);928NULL_CHECK(jthreads, JVMTI_ERROR_OUT_OF_MEMORY);929930*threads_ptr = jthreads;931return JVMTI_ERROR_NONE;932} /* end GetAllThreads */933934935// java_thread - protected by ThreadsListHandle and pre-checked936jvmtiError937JvmtiEnv::SuspendThread(JavaThread* java_thread) {938// don't allow hidden thread suspend request.939if (java_thread->is_hidden_from_external_view()) {940return JVMTI_ERROR_NONE;941}942if (java_thread->is_suspended()) {943return JVMTI_ERROR_THREAD_SUSPENDED;944}945if (!JvmtiSuspendControl::suspend(java_thread)) {946// Either the thread is already suspended or947// it was in the process of exiting.948if (java_thread->is_exiting()) {949return JVMTI_ERROR_THREAD_NOT_ALIVE;950}951return JVMTI_ERROR_THREAD_SUSPENDED;952}953return JVMTI_ERROR_NONE;954} /* end SuspendThread */955956957// request_count - pre-checked to be greater than or equal to 0958// request_list - pre-checked for NULL959// results - pre-checked for NULL960jvmtiError961JvmtiEnv::SuspendThreadList(jint request_count, const jthread* request_list, jvmtiError* results) {962int self_index = -1;963int needSafepoint = 0; // > 0 if we need a safepoint964JavaThread* current = JavaThread::current();965ThreadsListHandle tlh(current);966for (int i = 0; i < request_count; i++) {967JavaThread *java_thread = NULL;968jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), request_list[i], &java_thread, NULL);969if (err != JVMTI_ERROR_NONE) {970results[i] = err;971continue;972}973// don't allow hidden thread suspend request.974if (java_thread->is_hidden_from_external_view()) {975results[i] = JVMTI_ERROR_NONE; // indicate successful suspend976continue;977}978if (java_thread->is_suspended()) {979results[i] = JVMTI_ERROR_THREAD_SUSPENDED;980continue;981}982if (java_thread == current) {983self_index = i;984continue;985}986if (!JvmtiSuspendControl::suspend(java_thread)) {987// Either the thread is already suspended or988// it was in the process of exiting.989if (java_thread->is_exiting()) {990results[i] = JVMTI_ERROR_THREAD_NOT_ALIVE;991continue;992}993results[i] = JVMTI_ERROR_THREAD_SUSPENDED;994continue;995}996results[i] = JVMTI_ERROR_NONE; // indicate successful suspend997}998if (self_index >= 0) {999if (!JvmtiSuspendControl::suspend(current)) {1000// Either the thread is already suspended or1001// it was in the process of exiting.1002if (current->is_exiting()) {1003results[self_index] = JVMTI_ERROR_THREAD_NOT_ALIVE;1004} else {1005results[self_index] = JVMTI_ERROR_THREAD_SUSPENDED;1006}1007} else {1008results[self_index] = JVMTI_ERROR_NONE; // indicate successful suspend1009}1010}1011// per-thread suspend results returned via results parameter1012return JVMTI_ERROR_NONE;1013} /* end SuspendThreadList */101410151016// java_thread - protected by ThreadsListHandle and pre-checked1017jvmtiError1018JvmtiEnv::ResumeThread(JavaThread* java_thread) {1019// don't allow hidden thread resume request.1020if (java_thread->is_hidden_from_external_view()) {1021return JVMTI_ERROR_NONE;1022}1023if (!java_thread->is_suspended()) {1024return JVMTI_ERROR_THREAD_NOT_SUSPENDED;1025}1026if (!JvmtiSuspendControl::resume(java_thread)) {1027return JVMTI_ERROR_INTERNAL;1028}1029return JVMTI_ERROR_NONE;1030} /* end ResumeThread */103110321033// request_count - pre-checked to be greater than or equal to 01034// request_list - pre-checked for NULL1035// results - pre-checked for NULL1036jvmtiError1037JvmtiEnv::ResumeThreadList(jint request_count, const jthread* request_list, jvmtiError* results) {1038ThreadsListHandle tlh;1039for (int i = 0; i < request_count; i++) {1040JavaThread* java_thread = NULL;1041jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), request_list[i], &java_thread, NULL);1042if (err != JVMTI_ERROR_NONE) {1043results[i] = err;1044continue;1045}1046// don't allow hidden thread resume request.1047if (java_thread->is_hidden_from_external_view()) {1048results[i] = JVMTI_ERROR_NONE; // indicate successful resume1049continue;1050}1051if (!java_thread->is_suspended()) {1052results[i] = JVMTI_ERROR_THREAD_NOT_SUSPENDED;1053continue;1054}10551056if (!JvmtiSuspendControl::resume(java_thread)) {1057results[i] = JVMTI_ERROR_INTERNAL;1058continue;1059}10601061results[i] = JVMTI_ERROR_NONE; // indicate successful resume1062}1063// per-thread resume results returned via results parameter1064return JVMTI_ERROR_NONE;1065} /* end ResumeThreadList */106610671068// java_thread - protected by ThreadsListHandle and pre-checked1069jvmtiError1070JvmtiEnv::StopThread(JavaThread* java_thread, jobject exception) {1071oop e = JNIHandles::resolve_external_guard(exception);1072NULL_CHECK(e, JVMTI_ERROR_NULL_POINTER);10731074JavaThread::send_async_exception(java_thread->threadObj(), e);10751076return JVMTI_ERROR_NONE;10771078} /* end StopThread */107910801081// thread - NOT protected by ThreadsListHandle and NOT pre-checked1082jvmtiError1083JvmtiEnv::InterruptThread(jthread thread) {1084JavaThread* current_thread = JavaThread::current();1085JavaThread* java_thread = NULL;1086ThreadsListHandle tlh(current_thread);1087jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), thread, &java_thread, NULL);1088if (err != JVMTI_ERROR_NONE) {1089return err;1090}1091// Really this should be a Java call to Thread.interrupt to ensure the same1092// semantics, however historically this has not been done for some reason.1093// So we continue with that (which means we don't interact with any Java-level1094// Interruptible object) but we must set the Java-level interrupted state.1095java_lang_Thread::set_interrupted(JNIHandles::resolve(thread), true);1096java_thread->interrupt();10971098return JVMTI_ERROR_NONE;1099} /* end InterruptThread */110011011102// thread - NOT protected by ThreadsListHandle and NOT pre-checked1103// info_ptr - pre-checked for NULL1104jvmtiError1105JvmtiEnv::GetThreadInfo(jthread thread, jvmtiThreadInfo* info_ptr) {1106JavaThread* current_thread = JavaThread::current();1107ResourceMark rm(current_thread);1108HandleMark hm(current_thread);11091110ThreadsListHandle tlh(current_thread);11111112// if thread is NULL the current thread is used1113oop thread_oop = NULL;1114if (thread == NULL) {1115thread_oop = current_thread->threadObj();1116if (thread_oop == NULL || !thread_oop->is_a(vmClasses::Thread_klass())) {1117return JVMTI_ERROR_INVALID_THREAD;1118}1119} else {1120JavaThread* java_thread = NULL;1121jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), thread, &java_thread, &thread_oop);1122if (err != JVMTI_ERROR_NONE) {1123// We got an error code so we don't have a JavaThread *, but1124// only return an error from here if we didn't get a valid1125// thread_oop.1126if (thread_oop == NULL) {1127return err;1128}1129// We have a valid thread_oop so we can return some thread info.1130}1131}11321133Handle thread_obj(current_thread, thread_oop);1134Handle name;1135ThreadPriority priority;1136Handle thread_group;1137Handle context_class_loader;1138bool is_daemon;11391140name = Handle(current_thread, java_lang_Thread::name(thread_obj()));1141priority = java_lang_Thread::priority(thread_obj());1142thread_group = Handle(current_thread, java_lang_Thread::threadGroup(thread_obj()));1143is_daemon = java_lang_Thread::is_daemon(thread_obj());11441145oop loader = java_lang_Thread::context_class_loader(thread_obj());1146context_class_loader = Handle(current_thread, loader);11471148{ const char *n;11491150if (name() != NULL) {1151n = java_lang_String::as_utf8_string(name());1152} else {1153int utf8_length = 0;1154n = UNICODE::as_utf8((jchar*) NULL, utf8_length);1155}11561157info_ptr->name = (char *) jvmtiMalloc(strlen(n)+1);1158if (info_ptr->name == NULL)1159return JVMTI_ERROR_OUT_OF_MEMORY;11601161strcpy(info_ptr->name, n);1162}1163info_ptr->is_daemon = is_daemon;1164info_ptr->priority = priority;11651166info_ptr->context_class_loader = (context_class_loader.is_null()) ? NULL :1167jni_reference(context_class_loader);1168info_ptr->thread_group = jni_reference(thread_group);11691170return JVMTI_ERROR_NONE;1171} /* end GetThreadInfo */117211731174// java_thread - protected by ThreadsListHandle and pre-checked1175// owned_monitor_count_ptr - pre-checked for NULL1176// owned_monitors_ptr - pre-checked for NULL1177jvmtiError1178JvmtiEnv::GetOwnedMonitorInfo(JavaThread* java_thread, jint* owned_monitor_count_ptr, jobject** owned_monitors_ptr) {1179jvmtiError err = JVMTI_ERROR_NONE;1180JavaThread* calling_thread = JavaThread::current();11811182EscapeBarrier eb(true, calling_thread, java_thread);1183if (!eb.deoptimize_objects(MaxJavaStackTraceDepth)) {1184return JVMTI_ERROR_OUT_OF_MEMORY;1185}11861187// growable array of jvmti monitors info on the C-heap1188GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list =1189new (ResourceObj::C_HEAP, mtServiceability) GrowableArray<jvmtiMonitorStackDepthInfo*>(1, mtServiceability);11901191// It is only safe to perform the direct operation on the current1192// thread. All other usage needs to use a direct handshake for safety.1193if (java_thread == calling_thread) {1194err = get_owned_monitors(calling_thread, java_thread, owned_monitors_list);1195} else {1196// get owned monitors info with handshake1197GetOwnedMonitorInfoClosure op(calling_thread, this, owned_monitors_list);1198Handshake::execute(&op, java_thread);1199err = op.result();1200}1201jint owned_monitor_count = owned_monitors_list->length();1202if (err == JVMTI_ERROR_NONE) {1203if ((err = allocate(owned_monitor_count * sizeof(jobject *),1204(unsigned char**)owned_monitors_ptr)) == JVMTI_ERROR_NONE) {1205// copy into the returned array1206for (int i = 0; i < owned_monitor_count; i++) {1207(*owned_monitors_ptr)[i] =1208((jvmtiMonitorStackDepthInfo*)owned_monitors_list->at(i))->monitor;1209}1210*owned_monitor_count_ptr = owned_monitor_count;1211}1212}1213// clean up.1214for (int i = 0; i < owned_monitor_count; i++) {1215deallocate((unsigned char*)owned_monitors_list->at(i));1216}1217delete owned_monitors_list;12181219return err;1220} /* end GetOwnedMonitorInfo */122112221223// java_thread - protected by ThreadsListHandle and pre-checked1224// monitor_info_count_ptr - pre-checked for NULL1225// monitor_info_ptr - pre-checked for NULL1226jvmtiError1227JvmtiEnv::GetOwnedMonitorStackDepthInfo(JavaThread* java_thread, jint* monitor_info_count_ptr, jvmtiMonitorStackDepthInfo** monitor_info_ptr) {1228jvmtiError err = JVMTI_ERROR_NONE;1229JavaThread* calling_thread = JavaThread::current();12301231EscapeBarrier eb(true, calling_thread, java_thread);1232if (!eb.deoptimize_objects(MaxJavaStackTraceDepth)) {1233return JVMTI_ERROR_OUT_OF_MEMORY;1234}12351236// growable array of jvmti monitors info on the C-heap1237GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list =1238new (ResourceObj::C_HEAP, mtServiceability) GrowableArray<jvmtiMonitorStackDepthInfo*>(1, mtServiceability);12391240// It is only safe to perform the direct operation on the current1241// thread. All other usage needs to use a direct handshake for safety.1242if (java_thread == calling_thread) {1243err = get_owned_monitors(calling_thread, java_thread, owned_monitors_list);1244} else {1245// get owned monitors info with handshake1246GetOwnedMonitorInfoClosure op(calling_thread, this, owned_monitors_list);1247Handshake::execute(&op, java_thread);1248err = op.result();1249}12501251jint owned_monitor_count = owned_monitors_list->length();1252if (err == JVMTI_ERROR_NONE) {1253if ((err = allocate(owned_monitor_count * sizeof(jvmtiMonitorStackDepthInfo),1254(unsigned char**)monitor_info_ptr)) == JVMTI_ERROR_NONE) {1255// copy to output array.1256for (int i = 0; i < owned_monitor_count; i++) {1257(*monitor_info_ptr)[i].monitor =1258((jvmtiMonitorStackDepthInfo*)owned_monitors_list->at(i))->monitor;1259(*monitor_info_ptr)[i].stack_depth =1260((jvmtiMonitorStackDepthInfo*)owned_monitors_list->at(i))->stack_depth;1261}1262}1263*monitor_info_count_ptr = owned_monitor_count;1264}12651266// clean up.1267for (int i = 0; i < owned_monitor_count; i++) {1268deallocate((unsigned char*)owned_monitors_list->at(i));1269}1270delete owned_monitors_list;12711272return err;1273} /* end GetOwnedMonitorStackDepthInfo */127412751276// java_thread - protected by ThreadsListHandle and pre-checked1277// monitor_ptr - pre-checked for NULL1278jvmtiError1279JvmtiEnv::GetCurrentContendedMonitor(JavaThread* java_thread, jobject* monitor_ptr) {1280jvmtiError err = JVMTI_ERROR_NONE;1281JavaThread* calling_thread = JavaThread::current();12821283// It is only safe to perform the direct operation on the current1284// thread. All other usage needs to use a direct handshake for safety.1285if (java_thread == calling_thread) {1286err = get_current_contended_monitor(calling_thread, java_thread, monitor_ptr);1287} else {1288// get contended monitor information with handshake1289GetCurrentContendedMonitorClosure op(calling_thread, this, monitor_ptr);1290Handshake::execute(&op, java_thread);1291err = op.result();1292}1293return err;1294} /* end GetCurrentContendedMonitor */129512961297// thread - NOT protected by ThreadsListHandle and NOT pre-checked1298// proc - pre-checked for NULL1299// arg - NULL is a valid value, must be checked1300jvmtiError1301JvmtiEnv::RunAgentThread(jthread thread, jvmtiStartFunction proc, const void* arg, jint priority) {1302JavaThread* current_thread = JavaThread::current();13031304JavaThread* java_thread = NULL;1305oop thread_oop = NULL;1306ThreadsListHandle tlh(current_thread);1307jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), thread, &java_thread, &thread_oop);1308if (err != JVMTI_ERROR_NONE) {1309// We got an error code so we don't have a JavaThread *, but1310// only return an error from here if we didn't get a valid1311// thread_oop.1312if (thread_oop == NULL) {1313return err;1314}1315// We have a valid thread_oop.1316}13171318if (java_thread != NULL) {1319// 'thread' refers to an existing JavaThread.1320return JVMTI_ERROR_INVALID_THREAD;1321}13221323if (priority < JVMTI_THREAD_MIN_PRIORITY || priority > JVMTI_THREAD_MAX_PRIORITY) {1324return JVMTI_ERROR_INVALID_PRIORITY;1325}13261327Handle thread_hndl(current_thread, thread_oop);1328{1329MutexLocker mu(current_thread, Threads_lock); // grab Threads_lock13301331JvmtiAgentThread *new_thread = new JvmtiAgentThread(this, proc, arg);13321333// At this point it may be possible that no osthread was created for the1334// JavaThread due to lack of memory.1335if (new_thread == NULL || new_thread->osthread() == NULL) {1336if (new_thread != NULL) {1337new_thread->smr_delete();1338}1339return JVMTI_ERROR_OUT_OF_MEMORY;1340}13411342java_lang_Thread::set_thread(thread_hndl(), new_thread);1343java_lang_Thread::set_priority(thread_hndl(), (ThreadPriority)priority);1344java_lang_Thread::set_daemon(thread_hndl());13451346new_thread->set_threadObj(thread_hndl());1347Threads::add(new_thread);1348Thread::start(new_thread);1349} // unlock Threads_lock13501351return JVMTI_ERROR_NONE;1352} /* end RunAgentThread */13531354//1355// Thread Group functions1356//13571358// group_count_ptr - pre-checked for NULL1359// groups_ptr - pre-checked for NULL1360jvmtiError1361JvmtiEnv::GetTopThreadGroups(jint* group_count_ptr, jthreadGroup** groups_ptr) {1362JavaThread* current_thread = JavaThread::current();13631364// Only one top level thread group now.1365*group_count_ptr = 1;13661367// Allocate memory to store global-refs to the thread groups.1368// Assume this area is freed by caller.1369*groups_ptr = (jthreadGroup *) jvmtiMalloc((sizeof(jthreadGroup)) * (*group_count_ptr));13701371NULL_CHECK(*groups_ptr, JVMTI_ERROR_OUT_OF_MEMORY);13721373// Convert oop to Handle, then convert Handle to global-ref.1374{1375HandleMark hm(current_thread);1376Handle system_thread_group(current_thread, Universe::system_thread_group());1377*groups_ptr[0] = jni_reference(system_thread_group);1378}13791380return JVMTI_ERROR_NONE;1381} /* end GetTopThreadGroups */138213831384// info_ptr - pre-checked for NULL1385jvmtiError1386JvmtiEnv::GetThreadGroupInfo(jthreadGroup group, jvmtiThreadGroupInfo* info_ptr) {1387Thread* current_thread = Thread::current();1388ResourceMark rm(current_thread);1389HandleMark hm(current_thread);13901391Handle group_obj (current_thread, JNIHandles::resolve_external_guard(group));1392NULL_CHECK(group_obj(), JVMTI_ERROR_INVALID_THREAD_GROUP);13931394const char* name;1395Handle parent_group;1396bool is_daemon;1397ThreadPriority max_priority;13981399name = java_lang_ThreadGroup::name(group_obj());1400parent_group = Handle(current_thread, java_lang_ThreadGroup::parent(group_obj()));1401is_daemon = java_lang_ThreadGroup::is_daemon(group_obj());1402max_priority = java_lang_ThreadGroup::maxPriority(group_obj());14031404info_ptr->is_daemon = is_daemon;1405info_ptr->max_priority = max_priority;1406info_ptr->parent = jni_reference(parent_group);14071408if (name != NULL) {1409info_ptr->name = (char*)jvmtiMalloc(strlen(name)+1);1410NULL_CHECK(info_ptr->name, JVMTI_ERROR_OUT_OF_MEMORY);1411strcpy(info_ptr->name, name);1412} else {1413info_ptr->name = NULL;1414}14151416return JVMTI_ERROR_NONE;1417} /* end GetThreadGroupInfo */141814191420// thread_count_ptr - pre-checked for NULL1421// threads_ptr - pre-checked for NULL1422// group_count_ptr - pre-checked for NULL1423// groups_ptr - pre-checked for NULL1424jvmtiError1425JvmtiEnv::GetThreadGroupChildren(jthreadGroup group, jint* thread_count_ptr, jthread** threads_ptr, jint* group_count_ptr, jthreadGroup** groups_ptr) {1426JavaThread* current_thread = JavaThread::current();1427oop group_obj = JNIHandles::resolve_external_guard(group);1428NULL_CHECK(group_obj, JVMTI_ERROR_INVALID_THREAD_GROUP);14291430Handle *thread_objs = NULL;1431Handle *group_objs = NULL;1432int nthreads = 0;1433int ngroups = 0;1434int hidden_threads = 0;14351436ResourceMark rm(current_thread);1437HandleMark hm(current_thread);14381439Handle group_hdl(current_thread, group_obj);14401441{ // Cannot allow thread or group counts to change.1442ObjectLocker ol(group_hdl, current_thread);14431444nthreads = java_lang_ThreadGroup::nthreads(group_hdl());1445ngroups = java_lang_ThreadGroup::ngroups(group_hdl());14461447if (nthreads > 0) {1448ThreadsListHandle tlh(current_thread);1449objArrayOop threads = java_lang_ThreadGroup::threads(group_hdl());1450assert(nthreads <= threads->length(), "too many threads");1451thread_objs = NEW_RESOURCE_ARRAY(Handle,nthreads);1452for (int i = 0, j = 0; i < nthreads; i++) {1453oop thread_obj = threads->obj_at(i);1454assert(thread_obj != NULL, "thread_obj is NULL");1455JavaThread *java_thread = NULL;1456jvmtiError err = JvmtiExport::cv_oop_to_JavaThread(tlh.list(), thread_obj, &java_thread);1457if (err == JVMTI_ERROR_NONE) {1458// Have a valid JavaThread*.1459if (java_thread->is_hidden_from_external_view()) {1460// Filter out hidden java threads.1461hidden_threads++;1462continue;1463}1464} else {1465// We couldn't convert thread_obj into a JavaThread*.1466if (err == JVMTI_ERROR_INVALID_THREAD) {1467// The thread_obj does not refer to a java.lang.Thread object1468// so skip it.1469hidden_threads++;1470continue;1471}1472// We have a valid thread_obj, but no JavaThread*; the caller1473// can still have limited use for the thread_obj.1474}1475thread_objs[j++] = Handle(current_thread, thread_obj);1476}1477nthreads -= hidden_threads;1478} // ThreadsListHandle is destroyed here.14791480if (ngroups > 0) {1481objArrayOop groups = java_lang_ThreadGroup::groups(group_hdl());1482assert(ngroups <= groups->length(), "too many groups");1483group_objs = NEW_RESOURCE_ARRAY(Handle,ngroups);1484for (int i = 0; i < ngroups; i++) {1485oop group_obj = groups->obj_at(i);1486assert(group_obj != NULL, "group_obj != NULL");1487group_objs[i] = Handle(current_thread, group_obj);1488}1489}1490} // ThreadGroup unlocked here14911492*group_count_ptr = ngroups;1493*thread_count_ptr = nthreads;1494*threads_ptr = new_jthreadArray(nthreads, thread_objs);1495*groups_ptr = new_jthreadGroupArray(ngroups, group_objs);1496if ((nthreads > 0) && (*threads_ptr == NULL)) {1497return JVMTI_ERROR_OUT_OF_MEMORY;1498}1499if ((ngroups > 0) && (*groups_ptr == NULL)) {1500return JVMTI_ERROR_OUT_OF_MEMORY;1501}15021503return JVMTI_ERROR_NONE;1504} /* end GetThreadGroupChildren */150515061507//1508// Stack Frame functions1509//15101511// java_thread - protected by ThreadsListHandle and pre-checked1512// max_frame_count - pre-checked to be greater than or equal to 01513// frame_buffer - pre-checked for NULL1514// count_ptr - pre-checked for NULL1515jvmtiError1516JvmtiEnv::GetStackTrace(JavaThread* java_thread, jint start_depth, jint max_frame_count, jvmtiFrameInfo* frame_buffer, jint* count_ptr) {1517jvmtiError err = JVMTI_ERROR_NONE;15181519// It is only safe to perform the direct operation on the current1520// thread. All other usage needs to use a direct handshake for safety.1521if (java_thread == JavaThread::current()) {1522err = get_stack_trace(java_thread, start_depth, max_frame_count, frame_buffer, count_ptr);1523} else {1524// Get stack trace with handshake.1525GetStackTraceClosure op(this, start_depth, max_frame_count, frame_buffer, count_ptr);1526Handshake::execute(&op, java_thread);1527err = op.result();1528}15291530return err;1531} /* end GetStackTrace */153215331534// max_frame_count - pre-checked to be greater than or equal to 01535// stack_info_ptr - pre-checked for NULL1536// thread_count_ptr - pre-checked for NULL1537jvmtiError1538JvmtiEnv::GetAllStackTraces(jint max_frame_count, jvmtiStackInfo** stack_info_ptr, jint* thread_count_ptr) {1539jvmtiError err = JVMTI_ERROR_NONE;1540JavaThread* calling_thread = JavaThread::current();15411542// JVMTI get stack traces at safepoint.1543VM_GetAllStackTraces op(this, calling_thread, max_frame_count);1544VMThread::execute(&op);1545*thread_count_ptr = op.final_thread_count();1546*stack_info_ptr = op.stack_info();1547err = op.result();1548return err;1549} /* end GetAllStackTraces */155015511552// thread_count - pre-checked to be greater than or equal to 01553// thread_list - pre-checked for NULL1554// max_frame_count - pre-checked to be greater than or equal to 01555// stack_info_ptr - pre-checked for NULL1556jvmtiError1557JvmtiEnv::GetThreadListStackTraces(jint thread_count, const jthread* thread_list, jint max_frame_count, jvmtiStackInfo** stack_info_ptr) {1558jvmtiError err = JVMTI_ERROR_NONE;15591560if (thread_count == 1) {1561// Use direct handshake if we need to get only one stack trace.1562JavaThread *current_thread = JavaThread::current();1563ThreadsListHandle tlh(current_thread);1564JavaThread *java_thread;1565err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), *thread_list, &java_thread, NULL);1566if (err != JVMTI_ERROR_NONE) {1567return err;1568}15691570GetSingleStackTraceClosure op(this, current_thread, *thread_list, max_frame_count);1571Handshake::execute(&op, java_thread);1572err = op.result();1573if (err == JVMTI_ERROR_NONE) {1574*stack_info_ptr = op.stack_info();1575}1576} else {1577// JVMTI get stack traces at safepoint.1578VM_GetThreadListStackTraces op(this, thread_count, thread_list, max_frame_count);1579VMThread::execute(&op);1580err = op.result();1581if (err == JVMTI_ERROR_NONE) {1582*stack_info_ptr = op.stack_info();1583}1584}1585return err;1586} /* end GetThreadListStackTraces */158715881589// java_thread - protected by ThreadsListHandle and pre-checked1590// count_ptr - pre-checked for NULL1591jvmtiError1592JvmtiEnv::GetFrameCount(JavaThread* java_thread, jint* count_ptr) {1593jvmtiError err = JVMTI_ERROR_NONE;15941595// retrieve or create JvmtiThreadState.1596JvmtiThreadState* state = JvmtiThreadState::state_for(java_thread);1597if (state == NULL) {1598return JVMTI_ERROR_THREAD_NOT_ALIVE;1599}16001601// It is only safe to perform the direct operation on the current1602// thread. All other usage needs to use a direct handshake for safety.1603if (java_thread == JavaThread::current()) {1604err = get_frame_count(state, count_ptr);1605} else {1606// get java stack frame count with handshake.1607GetFrameCountClosure op(this, state, count_ptr);1608Handshake::execute(&op, java_thread);1609err = op.result();1610}1611return err;1612} /* end GetFrameCount */161316141615// java_thread - protected by ThreadsListHandle and pre-checked1616jvmtiError1617JvmtiEnv::PopFrame(JavaThread* java_thread) {1618// retrieve or create the state1619JvmtiThreadState* state = JvmtiThreadState::state_for(java_thread);1620if (state == NULL) {1621return JVMTI_ERROR_THREAD_NOT_ALIVE;1622}16231624// Eagerly reallocate scalar replaced objects.1625JavaThread* current_thread = JavaThread::current();1626EscapeBarrier eb(true, current_thread, java_thread);1627if (!eb.deoptimize_objects(1)) {1628// Reallocation of scalar replaced objects failed -> return with error1629return JVMTI_ERROR_OUT_OF_MEMORY;1630}16311632MutexLocker mu(JvmtiThreadState_lock);1633UpdateForPopTopFrameClosure op(state);1634if (java_thread == current_thread) {1635op.doit(java_thread, true /* self */);1636} else {1637Handshake::execute(&op, java_thread);1638}1639return op.result();1640} /* end PopFrame */164116421643// java_thread - protected by ThreadsListHandle and pre-checked1644// depth - pre-checked as non-negative1645// method_ptr - pre-checked for NULL1646// location_ptr - pre-checked for NULL1647jvmtiError1648JvmtiEnv::GetFrameLocation(JavaThread* java_thread, jint depth, jmethodID* method_ptr, jlocation* location_ptr) {1649jvmtiError err = JVMTI_ERROR_NONE;16501651// It is only safe to perform the direct operation on the current1652// thread. All other usage needs to use a direct handshake for safety.1653if (java_thread == JavaThread::current()) {1654err = get_frame_location(java_thread, depth, method_ptr, location_ptr);1655} else {1656// JVMTI get java stack frame location via direct handshake.1657GetFrameLocationClosure op(this, depth, method_ptr, location_ptr);1658Handshake::execute(&op, java_thread);1659err = op.result();1660}1661return err;1662} /* end GetFrameLocation */166316641665// java_thread - protected by ThreadsListHandle and pre-checked1666// depth - pre-checked as non-negative1667jvmtiError1668JvmtiEnv::NotifyFramePop(JavaThread* java_thread, jint depth) {1669JvmtiThreadState *state = JvmtiThreadState::state_for(java_thread);1670if (state == NULL) {1671return JVMTI_ERROR_THREAD_NOT_ALIVE;1672}16731674SetFramePopClosure op(this, state, depth);1675MutexLocker mu(JvmtiThreadState_lock);1676if (java_thread == JavaThread::current()) {1677op.doit(java_thread, true /* self */);1678} else {1679Handshake::execute(&op, java_thread);1680}1681return op.result();1682} /* end NotifyFramePop */168316841685//1686// Force Early Return functions1687//16881689// java_thread - protected by ThreadsListHandle and pre-checked1690jvmtiError1691JvmtiEnv::ForceEarlyReturnObject(JavaThread* java_thread, jobject value) {1692jvalue val;1693val.l = value;1694return force_early_return(java_thread, val, atos);1695} /* end ForceEarlyReturnObject */169616971698// java_thread - protected by ThreadsListHandle and pre-checked1699jvmtiError1700JvmtiEnv::ForceEarlyReturnInt(JavaThread* java_thread, jint value) {1701jvalue val;1702val.i = value;1703return force_early_return(java_thread, val, itos);1704} /* end ForceEarlyReturnInt */170517061707// java_thread - protected by ThreadsListHandle and pre-checked1708jvmtiError1709JvmtiEnv::ForceEarlyReturnLong(JavaThread* java_thread, jlong value) {1710jvalue val;1711val.j = value;1712return force_early_return(java_thread, val, ltos);1713} /* end ForceEarlyReturnLong */171417151716// java_thread - protected by ThreadsListHandle and pre-checked1717jvmtiError1718JvmtiEnv::ForceEarlyReturnFloat(JavaThread* java_thread, jfloat value) {1719jvalue val;1720val.f = value;1721return force_early_return(java_thread, val, ftos);1722} /* end ForceEarlyReturnFloat */172317241725// java_thread - protected by ThreadsListHandle and pre-checked1726jvmtiError1727JvmtiEnv::ForceEarlyReturnDouble(JavaThread* java_thread, jdouble value) {1728jvalue val;1729val.d = value;1730return force_early_return(java_thread, val, dtos);1731} /* end ForceEarlyReturnDouble */173217331734// java_thread - protected by ThreadsListHandle and pre-checked1735jvmtiError1736JvmtiEnv::ForceEarlyReturnVoid(JavaThread* java_thread) {1737jvalue val;1738val.j = 0L;1739return force_early_return(java_thread, val, vtos);1740} /* end ForceEarlyReturnVoid */174117421743//1744// Heap functions1745//17461747// klass - NULL is a valid value, must be checked1748// initial_object - NULL is a valid value, must be checked1749// callbacks - pre-checked for NULL1750// user_data - NULL is a valid value, must be checked1751jvmtiError1752JvmtiEnv::FollowReferences(jint heap_filter, jclass klass, jobject initial_object, const jvmtiHeapCallbacks* callbacks, const void* user_data) {1753// check klass if provided1754Klass* k = NULL;1755if (klass != NULL) {1756oop k_mirror = JNIHandles::resolve_external_guard(klass);1757if (k_mirror == NULL) {1758return JVMTI_ERROR_INVALID_CLASS;1759}1760if (java_lang_Class::is_primitive(k_mirror)) {1761return JVMTI_ERROR_NONE;1762}1763k = java_lang_Class::as_Klass(k_mirror);1764if (klass == NULL) {1765return JVMTI_ERROR_INVALID_CLASS;1766}1767}17681769if (initial_object != NULL) {1770oop init_obj = JNIHandles::resolve_external_guard(initial_object);1771if (init_obj == NULL) {1772return JVMTI_ERROR_INVALID_OBJECT;1773}1774}17751776Thread *thread = Thread::current();1777HandleMark hm(thread);17781779TraceTime t("FollowReferences", TRACETIME_LOG(Debug, jvmti, objecttagging));1780JvmtiTagMap::tag_map_for(this)->follow_references(heap_filter, k, initial_object, callbacks, user_data);1781return JVMTI_ERROR_NONE;1782} /* end FollowReferences */178317841785// klass - NULL is a valid value, must be checked1786// callbacks - pre-checked for NULL1787// user_data - NULL is a valid value, must be checked1788jvmtiError1789JvmtiEnv::IterateThroughHeap(jint heap_filter, jclass klass, const jvmtiHeapCallbacks* callbacks, const void* user_data) {1790// check klass if provided1791Klass* k = NULL;1792if (klass != NULL) {1793oop k_mirror = JNIHandles::resolve_external_guard(klass);1794if (k_mirror == NULL) {1795return JVMTI_ERROR_INVALID_CLASS;1796}1797if (java_lang_Class::is_primitive(k_mirror)) {1798return JVMTI_ERROR_NONE;1799}1800k = java_lang_Class::as_Klass(k_mirror);1801if (k == NULL) {1802return JVMTI_ERROR_INVALID_CLASS;1803}1804}18051806TraceTime t("IterateThroughHeap", TRACETIME_LOG(Debug, jvmti, objecttagging));1807JvmtiTagMap::tag_map_for(this)->iterate_through_heap(heap_filter, k, callbacks, user_data);1808return JVMTI_ERROR_NONE;1809} /* end IterateThroughHeap */181018111812// tag_ptr - pre-checked for NULL1813jvmtiError1814JvmtiEnv::GetTag(jobject object, jlong* tag_ptr) {1815oop o = JNIHandles::resolve_external_guard(object);1816NULL_CHECK(o, JVMTI_ERROR_INVALID_OBJECT);1817*tag_ptr = JvmtiTagMap::tag_map_for(this)->get_tag(object);1818return JVMTI_ERROR_NONE;1819} /* end GetTag */182018211822jvmtiError1823JvmtiEnv::SetTag(jobject object, jlong tag) {1824oop o = JNIHandles::resolve_external_guard(object);1825NULL_CHECK(o, JVMTI_ERROR_INVALID_OBJECT);1826JvmtiTagMap::tag_map_for(this)->set_tag(object, tag);1827return JVMTI_ERROR_NONE;1828} /* end SetTag */182918301831// tag_count - pre-checked to be greater than or equal to 01832// tags - pre-checked for NULL1833// count_ptr - pre-checked for NULL1834// object_result_ptr - NULL is a valid value, must be checked1835// tag_result_ptr - NULL is a valid value, must be checked1836jvmtiError1837JvmtiEnv::GetObjectsWithTags(jint tag_count, const jlong* tags, jint* count_ptr, jobject** object_result_ptr, jlong** tag_result_ptr) {1838TraceTime t("GetObjectsWithTags", TRACETIME_LOG(Debug, jvmti, objecttagging));1839return JvmtiTagMap::tag_map_for(this)->get_objects_with_tags((jlong*)tags, tag_count, count_ptr, object_result_ptr, tag_result_ptr);1840} /* end GetObjectsWithTags */184118421843jvmtiError1844JvmtiEnv::ForceGarbageCollection() {1845Universe::heap()->collect(GCCause::_jvmti_force_gc);1846return JVMTI_ERROR_NONE;1847} /* end ForceGarbageCollection */184818491850//1851// Heap (1.0) functions1852//18531854// object_reference_callback - pre-checked for NULL1855// user_data - NULL is a valid value, must be checked1856jvmtiError1857JvmtiEnv::IterateOverObjectsReachableFromObject(jobject object, jvmtiObjectReferenceCallback object_reference_callback, const void* user_data) {1858oop o = JNIHandles::resolve_external_guard(object);1859NULL_CHECK(o, JVMTI_ERROR_INVALID_OBJECT);1860JvmtiTagMap::tag_map_for(this)->iterate_over_objects_reachable_from_object(object, object_reference_callback, user_data);1861return JVMTI_ERROR_NONE;1862} /* end IterateOverObjectsReachableFromObject */186318641865// heap_root_callback - NULL is a valid value, must be checked1866// stack_ref_callback - NULL is a valid value, must be checked1867// object_ref_callback - NULL is a valid value, must be checked1868// user_data - NULL is a valid value, must be checked1869jvmtiError1870JvmtiEnv::IterateOverReachableObjects(jvmtiHeapRootCallback heap_root_callback, jvmtiStackReferenceCallback stack_ref_callback, jvmtiObjectReferenceCallback object_ref_callback, const void* user_data) {1871TraceTime t("IterateOverReachableObjects", TRACETIME_LOG(Debug, jvmti, objecttagging));1872JvmtiTagMap::tag_map_for(this)->iterate_over_reachable_objects(heap_root_callback, stack_ref_callback, object_ref_callback, user_data);1873return JVMTI_ERROR_NONE;1874} /* end IterateOverReachableObjects */187518761877// heap_object_callback - pre-checked for NULL1878// user_data - NULL is a valid value, must be checked1879jvmtiError1880JvmtiEnv::IterateOverHeap(jvmtiHeapObjectFilter object_filter, jvmtiHeapObjectCallback heap_object_callback, const void* user_data) {1881TraceTime t("IterateOverHeap", TRACETIME_LOG(Debug, jvmti, objecttagging));1882Thread *thread = Thread::current();1883HandleMark hm(thread);1884JvmtiTagMap::tag_map_for(this)->iterate_over_heap(object_filter, NULL, heap_object_callback, user_data);1885return JVMTI_ERROR_NONE;1886} /* end IterateOverHeap */188718881889// k_mirror - may be primitive, this must be checked1890// heap_object_callback - pre-checked for NULL1891// user_data - NULL is a valid value, must be checked1892jvmtiError1893JvmtiEnv::IterateOverInstancesOfClass(oop k_mirror, jvmtiHeapObjectFilter object_filter, jvmtiHeapObjectCallback heap_object_callback, const void* user_data) {1894if (java_lang_Class::is_primitive(k_mirror)) {1895// DO PRIMITIVE CLASS PROCESSING1896return JVMTI_ERROR_NONE;1897}1898Klass* klass = java_lang_Class::as_Klass(k_mirror);1899if (klass == NULL) {1900return JVMTI_ERROR_INVALID_CLASS;1901}1902TraceTime t("IterateOverInstancesOfClass", TRACETIME_LOG(Debug, jvmti, objecttagging));1903JvmtiTagMap::tag_map_for(this)->iterate_over_heap(object_filter, klass, heap_object_callback, user_data);1904return JVMTI_ERROR_NONE;1905} /* end IterateOverInstancesOfClass */190619071908//1909// Local Variable functions1910//19111912// java_thread - protected by ThreadsListHandle and pre-checked1913// depth - pre-checked as non-negative1914// value_ptr - pre-checked for NULL1915jvmtiError1916JvmtiEnv::GetLocalObject(JavaThread* java_thread, jint depth, jint slot, jobject* value_ptr) {1917JavaThread* current_thread = JavaThread::current();1918// rm object is created to clean up the javaVFrame created in1919// doit_prologue(), but after doit() is finished with it.1920ResourceMark rm(current_thread);19211922VM_GetOrSetLocal op(java_thread, current_thread, depth, slot);1923VMThread::execute(&op);1924jvmtiError err = op.result();1925if (err != JVMTI_ERROR_NONE) {1926return err;1927} else {1928*value_ptr = op.value().l;1929return JVMTI_ERROR_NONE;1930}1931} /* end GetLocalObject */19321933// java_thread - protected by ThreadsListHandle and pre-checked1934// depth - pre-checked as non-negative1935// value - pre-checked for NULL1936jvmtiError1937JvmtiEnv::GetLocalInstance(JavaThread* java_thread, jint depth, jobject* value_ptr){1938JavaThread* current_thread = JavaThread::current();1939// rm object is created to clean up the javaVFrame created in1940// doit_prologue(), but after doit() is finished with it.1941ResourceMark rm(current_thread);19421943VM_GetReceiver op(java_thread, current_thread, depth);1944VMThread::execute(&op);1945jvmtiError err = op.result();1946if (err != JVMTI_ERROR_NONE) {1947return err;1948} else {1949*value_ptr = op.value().l;1950return JVMTI_ERROR_NONE;1951}1952} /* end GetLocalInstance */195319541955// java_thread - protected by ThreadsListHandle and pre-checked1956// depth - pre-checked as non-negative1957// value_ptr - pre-checked for NULL1958jvmtiError1959JvmtiEnv::GetLocalInt(JavaThread* java_thread, jint depth, jint slot, jint* value_ptr) {1960// rm object is created to clean up the javaVFrame created in1961// doit_prologue(), but after doit() is finished with it.1962ResourceMark rm;19631964VM_GetOrSetLocal op(java_thread, depth, slot, T_INT);1965VMThread::execute(&op);1966*value_ptr = op.value().i;1967return op.result();1968} /* end GetLocalInt */196919701971// java_thread - protected by ThreadsListHandle and pre-checked1972// depth - pre-checked as non-negative1973// value_ptr - pre-checked for NULL1974jvmtiError1975JvmtiEnv::GetLocalLong(JavaThread* java_thread, jint depth, jint slot, jlong* value_ptr) {1976// rm object is created to clean up the javaVFrame created in1977// doit_prologue(), but after doit() is finished with it.1978ResourceMark rm;19791980VM_GetOrSetLocal op(java_thread, depth, slot, T_LONG);1981VMThread::execute(&op);1982*value_ptr = op.value().j;1983return op.result();1984} /* end GetLocalLong */198519861987// java_thread - protected by ThreadsListHandle and pre-checked1988// depth - pre-checked as non-negative1989// value_ptr - pre-checked for NULL1990jvmtiError1991JvmtiEnv::GetLocalFloat(JavaThread* java_thread, jint depth, jint slot, jfloat* value_ptr) {1992// rm object is created to clean up the javaVFrame created in1993// doit_prologue(), but after doit() is finished with it.1994ResourceMark rm;19951996VM_GetOrSetLocal op(java_thread, depth, slot, T_FLOAT);1997VMThread::execute(&op);1998*value_ptr = op.value().f;1999return op.result();2000} /* end GetLocalFloat */200120022003// java_thread - protected by ThreadsListHandle and pre-checked2004// depth - pre-checked as non-negative2005// value_ptr - pre-checked for NULL2006jvmtiError2007JvmtiEnv::GetLocalDouble(JavaThread* java_thread, jint depth, jint slot, jdouble* value_ptr) {2008// rm object is created to clean up the javaVFrame created in2009// doit_prologue(), but after doit() is finished with it.2010ResourceMark rm;20112012VM_GetOrSetLocal op(java_thread, depth, slot, T_DOUBLE);2013VMThread::execute(&op);2014*value_ptr = op.value().d;2015return op.result();2016} /* end GetLocalDouble */201720182019// java_thread - protected by ThreadsListHandle and pre-checked2020// depth - pre-checked as non-negative2021jvmtiError2022JvmtiEnv::SetLocalObject(JavaThread* java_thread, jint depth, jint slot, jobject value) {2023// rm object is created to clean up the javaVFrame created in2024// doit_prologue(), but after doit() is finished with it.2025ResourceMark rm;2026jvalue val;2027val.l = value;2028VM_GetOrSetLocal op(java_thread, depth, slot, T_OBJECT, val);2029VMThread::execute(&op);2030return op.result();2031} /* end SetLocalObject */203220332034// java_thread - protected by ThreadsListHandle and pre-checked2035// depth - pre-checked as non-negative2036jvmtiError2037JvmtiEnv::SetLocalInt(JavaThread* java_thread, jint depth, jint slot, jint value) {2038// rm object is created to clean up the javaVFrame created in2039// doit_prologue(), but after doit() is finished with it.2040ResourceMark rm;2041jvalue val;2042val.i = value;2043VM_GetOrSetLocal op(java_thread, depth, slot, T_INT, val);2044VMThread::execute(&op);2045return op.result();2046} /* end SetLocalInt */204720482049// java_thread - protected by ThreadsListHandle and pre-checked2050// depth - pre-checked as non-negative2051jvmtiError2052JvmtiEnv::SetLocalLong(JavaThread* java_thread, jint depth, jint slot, jlong value) {2053// rm object is created to clean up the javaVFrame created in2054// doit_prologue(), but after doit() is finished with it.2055ResourceMark rm;2056jvalue val;2057val.j = value;2058VM_GetOrSetLocal op(java_thread, depth, slot, T_LONG, val);2059VMThread::execute(&op);2060return op.result();2061} /* end SetLocalLong */206220632064// java_thread - protected by ThreadsListHandle and pre-checked2065// depth - pre-checked as non-negative2066jvmtiError2067JvmtiEnv::SetLocalFloat(JavaThread* java_thread, jint depth, jint slot, jfloat value) {2068// rm object is created to clean up the javaVFrame created in2069// doit_prologue(), but after doit() is finished with it.2070ResourceMark rm;2071jvalue val;2072val.f = value;2073VM_GetOrSetLocal op(java_thread, depth, slot, T_FLOAT, val);2074VMThread::execute(&op);2075return op.result();2076} /* end SetLocalFloat */207720782079// java_thread - protected by ThreadsListHandle and pre-checked2080// depth - pre-checked as non-negative2081jvmtiError2082JvmtiEnv::SetLocalDouble(JavaThread* java_thread, jint depth, jint slot, jdouble value) {2083// rm object is created to clean up the javaVFrame created in2084// doit_prologue(), but after doit() is finished with it.2085ResourceMark rm;2086jvalue val;2087val.d = value;2088VM_GetOrSetLocal op(java_thread, depth, slot, T_DOUBLE, val);2089VMThread::execute(&op);2090return op.result();2091} /* end SetLocalDouble */209220932094//2095// Breakpoint functions2096//20972098// method - pre-checked for validity, but may be NULL meaning obsolete method2099jvmtiError2100JvmtiEnv::SetBreakpoint(Method* method, jlocation location) {2101NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);2102if (location < 0) { // simple invalid location check first2103return JVMTI_ERROR_INVALID_LOCATION;2104}2105// verify that the breakpoint is not past the end of the method2106if (location >= (jlocation) method->code_size()) {2107return JVMTI_ERROR_INVALID_LOCATION;2108}21092110ResourceMark rm;2111JvmtiBreakpoint bp(method, location);2112JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints();2113if (jvmti_breakpoints.set(bp) == JVMTI_ERROR_DUPLICATE)2114return JVMTI_ERROR_DUPLICATE;21152116if (TraceJVMTICalls) {2117jvmti_breakpoints.print();2118}21192120return JVMTI_ERROR_NONE;2121} /* end SetBreakpoint */212221232124// method - pre-checked for validity, but may be NULL meaning obsolete method2125jvmtiError2126JvmtiEnv::ClearBreakpoint(Method* method, jlocation location) {2127NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);21282129if (location < 0) { // simple invalid location check first2130return JVMTI_ERROR_INVALID_LOCATION;2131}21322133// verify that the breakpoint is not past the end of the method2134if (location >= (jlocation) method->code_size()) {2135return JVMTI_ERROR_INVALID_LOCATION;2136}21372138JvmtiBreakpoint bp(method, location);21392140JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints();2141if (jvmti_breakpoints.clear(bp) == JVMTI_ERROR_NOT_FOUND)2142return JVMTI_ERROR_NOT_FOUND;21432144if (TraceJVMTICalls) {2145jvmti_breakpoints.print();2146}21472148return JVMTI_ERROR_NONE;2149} /* end ClearBreakpoint */215021512152//2153// Watched Field functions2154//21552156jvmtiError2157JvmtiEnv::SetFieldAccessWatch(fieldDescriptor* fdesc_ptr) {2158// make sure we haven't set this watch before2159if (fdesc_ptr->is_field_access_watched()) return JVMTI_ERROR_DUPLICATE;2160fdesc_ptr->set_is_field_access_watched(true);21612162JvmtiEventController::change_field_watch(JVMTI_EVENT_FIELD_ACCESS, true);21632164return JVMTI_ERROR_NONE;2165} /* end SetFieldAccessWatch */216621672168jvmtiError2169JvmtiEnv::ClearFieldAccessWatch(fieldDescriptor* fdesc_ptr) {2170// make sure we have a watch to clear2171if (!fdesc_ptr->is_field_access_watched()) return JVMTI_ERROR_NOT_FOUND;2172fdesc_ptr->set_is_field_access_watched(false);21732174JvmtiEventController::change_field_watch(JVMTI_EVENT_FIELD_ACCESS, false);21752176return JVMTI_ERROR_NONE;2177} /* end ClearFieldAccessWatch */217821792180jvmtiError2181JvmtiEnv::SetFieldModificationWatch(fieldDescriptor* fdesc_ptr) {2182// make sure we haven't set this watch before2183if (fdesc_ptr->is_field_modification_watched()) return JVMTI_ERROR_DUPLICATE;2184fdesc_ptr->set_is_field_modification_watched(true);21852186JvmtiEventController::change_field_watch(JVMTI_EVENT_FIELD_MODIFICATION, true);21872188return JVMTI_ERROR_NONE;2189} /* end SetFieldModificationWatch */219021912192jvmtiError2193JvmtiEnv::ClearFieldModificationWatch(fieldDescriptor* fdesc_ptr) {2194// make sure we have a watch to clear2195if (!fdesc_ptr->is_field_modification_watched()) return JVMTI_ERROR_NOT_FOUND;2196fdesc_ptr->set_is_field_modification_watched(false);21972198JvmtiEventController::change_field_watch(JVMTI_EVENT_FIELD_MODIFICATION, false);21992200return JVMTI_ERROR_NONE;2201} /* end ClearFieldModificationWatch */22022203//2204// Class functions2205//220622072208// k_mirror - may be primitive, this must be checked2209// signature_ptr - NULL is a valid value, must be checked2210// generic_ptr - NULL is a valid value, must be checked2211jvmtiError2212JvmtiEnv::GetClassSignature(oop k_mirror, char** signature_ptr, char** generic_ptr) {2213ResourceMark rm;2214bool isPrimitive = java_lang_Class::is_primitive(k_mirror);2215Klass* k = NULL;2216if (!isPrimitive) {2217k = java_lang_Class::as_Klass(k_mirror);2218NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);2219}2220if (signature_ptr != NULL) {2221char* result = NULL;2222if (isPrimitive) {2223char tchar = type2char(java_lang_Class::primitive_type(k_mirror));2224result = (char*) jvmtiMalloc(2);2225result[0] = tchar;2226result[1] = '\0';2227} else {2228const char* class_sig = k->signature_name();2229result = (char *) jvmtiMalloc(strlen(class_sig)+1);2230strcpy(result, class_sig);2231}2232*signature_ptr = result;2233}2234if (generic_ptr != NULL) {2235*generic_ptr = NULL;2236if (!isPrimitive && k->is_instance_klass()) {2237Symbol* soo = InstanceKlass::cast(k)->generic_signature();2238if (soo != NULL) {2239const char *gen_sig = soo->as_C_string();2240if (gen_sig != NULL) {2241char* gen_result;2242jvmtiError err = allocate(strlen(gen_sig) + 1,2243(unsigned char **)&gen_result);2244if (err != JVMTI_ERROR_NONE) {2245return err;2246}2247strcpy(gen_result, gen_sig);2248*generic_ptr = gen_result;2249}2250}2251}2252}2253return JVMTI_ERROR_NONE;2254} /* end GetClassSignature */225522562257// k_mirror - may be primitive, this must be checked2258// status_ptr - pre-checked for NULL2259jvmtiError2260JvmtiEnv::GetClassStatus(oop k_mirror, jint* status_ptr) {2261jint result = 0;2262if (java_lang_Class::is_primitive(k_mirror)) {2263result |= JVMTI_CLASS_STATUS_PRIMITIVE;2264} else {2265Klass* k = java_lang_Class::as_Klass(k_mirror);2266NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);2267result = k->jvmti_class_status();2268}2269*status_ptr = result;22702271return JVMTI_ERROR_NONE;2272} /* end GetClassStatus */227322742275// k_mirror - may be primitive, this must be checked2276// source_name_ptr - pre-checked for NULL2277jvmtiError2278JvmtiEnv::GetSourceFileName(oop k_mirror, char** source_name_ptr) {2279if (java_lang_Class::is_primitive(k_mirror)) {2280return JVMTI_ERROR_ABSENT_INFORMATION;2281}2282Klass* k_klass = java_lang_Class::as_Klass(k_mirror);2283NULL_CHECK(k_klass, JVMTI_ERROR_INVALID_CLASS);22842285if (!k_klass->is_instance_klass()) {2286return JVMTI_ERROR_ABSENT_INFORMATION;2287}22882289Symbol* sfnOop = InstanceKlass::cast(k_klass)->source_file_name();2290NULL_CHECK(sfnOop, JVMTI_ERROR_ABSENT_INFORMATION);2291{2292JavaThread* current_thread = JavaThread::current();2293ResourceMark rm(current_thread);2294const char* sfncp = (const char*) sfnOop->as_C_string();2295*source_name_ptr = (char *) jvmtiMalloc(strlen(sfncp)+1);2296strcpy(*source_name_ptr, sfncp);2297}22982299return JVMTI_ERROR_NONE;2300} /* end GetSourceFileName */230123022303// k_mirror - may be primitive, this must be checked2304// modifiers_ptr - pre-checked for NULL2305jvmtiError2306JvmtiEnv::GetClassModifiers(oop k_mirror, jint* modifiers_ptr) {2307JavaThread* current_thread = JavaThread::current();2308jint result = 0;2309if (!java_lang_Class::is_primitive(k_mirror)) {2310Klass* k = java_lang_Class::as_Klass(k_mirror);2311NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);2312result = k->compute_modifier_flags();23132314// Reset the deleted ACC_SUPER bit (deleted in compute_modifier_flags()).2315if (k->is_super()) {2316result |= JVM_ACC_SUPER;2317}2318} else {2319result = (JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC);2320}2321*modifiers_ptr = result;23222323return JVMTI_ERROR_NONE;2324} /* end GetClassModifiers */232523262327// k_mirror - may be primitive, this must be checked2328// method_count_ptr - pre-checked for NULL2329// methods_ptr - pre-checked for NULL2330jvmtiError2331JvmtiEnv::GetClassMethods(oop k_mirror, jint* method_count_ptr, jmethodID** methods_ptr) {2332JavaThread* current_thread = JavaThread::current();2333HandleMark hm(current_thread);23342335if (java_lang_Class::is_primitive(k_mirror)) {2336*method_count_ptr = 0;2337*methods_ptr = (jmethodID*) jvmtiMalloc(0 * sizeof(jmethodID));2338return JVMTI_ERROR_NONE;2339}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;2346}23472348if (!k->is_instance_klass()) {2349*method_count_ptr = 0;2350*methods_ptr = (jmethodID*) jvmtiMalloc(0 * sizeof(jmethodID));2351return JVMTI_ERROR_NONE;2352}2353InstanceKlass* ik = InstanceKlass::cast(k);2354// Allocate the result and fill it in2355int result_length = ik->methods()->length();2356jmethodID* result_list = (jmethodID*)jvmtiMalloc(result_length * sizeof(jmethodID));2357int index;2358bool jmethodids_found = true;2359int skipped = 0; // skip overpass methods23602361for (index = 0; index < result_length; index++) {2362Method* m = ik->methods()->at(index);2363// Depending on can_maintain_original_method_order capability use the original2364// method ordering indices stored in the class, so we can emit jmethodIDs in2365// the order they appeared in the class file or just copy in current order.2366int result_index = JvmtiExport::can_maintain_original_method_order() ? ik->method_ordering()->at(index) : index;2367assert(result_index >= 0 && result_index < result_length, "invalid original method index");2368if (m->is_overpass()) {2369result_list[result_index] = NULL;2370skipped++;2371continue;2372}2373jmethodID id;2374if (jmethodids_found) {2375id = m->find_jmethod_id_or_null();2376if (id == NULL) {2377// If we find an uninitialized value, make sure there is2378// enough space for all the uninitialized values we might2379// find.2380ik->ensure_space_for_methodids(index);2381jmethodids_found = false;2382id = m->jmethod_id();2383}2384} else {2385id = m->jmethod_id();2386}2387result_list[result_index] = id;2388}23892390// Fill in return value.2391if (skipped > 0) {2392// copy results skipping NULL methodIDs2393*methods_ptr = (jmethodID*)jvmtiMalloc((result_length - skipped) * sizeof(jmethodID));2394*method_count_ptr = result_length - skipped;2395for (index = 0, skipped = 0; index < result_length; index++) {2396if (result_list[index] == NULL) {2397skipped++;2398} else {2399(*methods_ptr)[index - skipped] = result_list[index];2400}2401}2402deallocate((unsigned char *)result_list);2403} else {2404*method_count_ptr = result_length;2405*methods_ptr = result_list;2406}24072408return JVMTI_ERROR_NONE;2409} /* end GetClassMethods */241024112412// k_mirror - may be primitive, this must be checked2413// field_count_ptr - pre-checked for NULL2414// fields_ptr - pre-checked for NULL2415jvmtiError2416JvmtiEnv::GetClassFields(oop k_mirror, jint* field_count_ptr, jfieldID** fields_ptr) {2417if (java_lang_Class::is_primitive(k_mirror)) {2418*field_count_ptr = 0;2419*fields_ptr = (jfieldID*) jvmtiMalloc(0 * sizeof(jfieldID));2420return JVMTI_ERROR_NONE;2421}2422JavaThread* current_thread = JavaThread::current();2423HandleMark hm(current_thread);2424Klass* k = java_lang_Class::as_Klass(k_mirror);2425NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);24262427// Return CLASS_NOT_PREPARED error as per JVMTI spec.2428if (!(k->jvmti_class_status() & (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY) )) {2429return JVMTI_ERROR_CLASS_NOT_PREPARED;2430}24312432if (!k->is_instance_klass()) {2433*field_count_ptr = 0;2434*fields_ptr = (jfieldID*) jvmtiMalloc(0 * sizeof(jfieldID));2435return JVMTI_ERROR_NONE;2436}243724382439InstanceKlass* ik = InstanceKlass::cast(k);24402441int result_count = 0;2442// First, count the fields.2443FilteredFieldStream flds(ik, true, true);2444result_count = flds.field_count();24452446// Allocate the result and fill it in2447jfieldID* result_list = (jfieldID*) jvmtiMalloc(result_count * sizeof(jfieldID));2448// The JVMTI spec requires fields in the order they occur in the class file,2449// this is the reverse order of what FieldStream hands out.2450int id_index = (result_count - 1);24512452for (FilteredFieldStream src_st(ik, true, true); !src_st.eos(); src_st.next()) {2453result_list[id_index--] = jfieldIDWorkaround::to_jfieldID(2454ik, src_st.offset(),2455src_st.access_flags().is_static());2456}2457assert(id_index == -1, "just checking");2458// Fill in the results2459*field_count_ptr = result_count;2460*fields_ptr = result_list;24612462return JVMTI_ERROR_NONE;2463} /* end GetClassFields */246424652466// k_mirror - may be primitive, this must be checked2467// interface_count_ptr - pre-checked for NULL2468// interfaces_ptr - pre-checked for NULL2469jvmtiError2470JvmtiEnv::GetImplementedInterfaces(oop k_mirror, jint* interface_count_ptr, jclass** interfaces_ptr) {2471{2472if (java_lang_Class::is_primitive(k_mirror)) {2473*interface_count_ptr = 0;2474*interfaces_ptr = (jclass*) jvmtiMalloc(0 * sizeof(jclass));2475return JVMTI_ERROR_NONE;2476}2477JavaThread* current_thread = JavaThread::current();2478HandleMark hm(current_thread);2479Klass* k = java_lang_Class::as_Klass(k_mirror);2480NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);24812482// Return CLASS_NOT_PREPARED error as per JVMTI spec.2483if (!(k->jvmti_class_status() & (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY) ))2484return JVMTI_ERROR_CLASS_NOT_PREPARED;24852486if (!k->is_instance_klass()) {2487*interface_count_ptr = 0;2488*interfaces_ptr = (jclass*) jvmtiMalloc(0 * sizeof(jclass));2489return JVMTI_ERROR_NONE;2490}24912492Array<InstanceKlass*>* interface_list = InstanceKlass::cast(k)->local_interfaces();2493const int result_length = (interface_list == NULL ? 0 : interface_list->length());2494jclass* result_list = (jclass*) jvmtiMalloc(result_length * sizeof(jclass));2495for (int i_index = 0; i_index < result_length; i_index += 1) {2496InstanceKlass* klass_at = interface_list->at(i_index);2497assert(klass_at->is_klass(), "interfaces must be Klass*s");2498assert(klass_at->is_interface(), "interfaces must be interfaces");2499oop mirror_at = klass_at->java_mirror();2500Handle handle_at = Handle(current_thread, mirror_at);2501result_list[i_index] = (jclass) jni_reference(handle_at);2502}2503*interface_count_ptr = result_length;2504*interfaces_ptr = result_list;2505}25062507return JVMTI_ERROR_NONE;2508} /* end GetImplementedInterfaces */250925102511// k_mirror - may be primitive, this must be checked2512// minor_version_ptr - pre-checked for NULL2513// major_version_ptr - pre-checked for NULL2514jvmtiError2515JvmtiEnv::GetClassVersionNumbers(oop k_mirror, jint* minor_version_ptr, jint* major_version_ptr) {2516if (java_lang_Class::is_primitive(k_mirror)) {2517return JVMTI_ERROR_ABSENT_INFORMATION;2518}2519Klass* klass = java_lang_Class::as_Klass(k_mirror);25202521jint status = klass->jvmti_class_status();2522if (status & (JVMTI_CLASS_STATUS_ERROR)) {2523return JVMTI_ERROR_INVALID_CLASS;2524}2525if (status & (JVMTI_CLASS_STATUS_ARRAY)) {2526return JVMTI_ERROR_ABSENT_INFORMATION;2527}25282529InstanceKlass* ik = InstanceKlass::cast(klass);2530*minor_version_ptr = ik->minor_version();2531*major_version_ptr = ik->major_version();25322533return JVMTI_ERROR_NONE;2534} /* end GetClassVersionNumbers */253525362537// k_mirror - may be primitive, this must be checked2538// constant_pool_count_ptr - pre-checked for NULL2539// constant_pool_byte_count_ptr - pre-checked for NULL2540// constant_pool_bytes_ptr - pre-checked for NULL2541jvmtiError2542JvmtiEnv::GetConstantPool(oop k_mirror, jint* constant_pool_count_ptr, jint* constant_pool_byte_count_ptr, unsigned char** constant_pool_bytes_ptr) {2543if (java_lang_Class::is_primitive(k_mirror)) {2544return JVMTI_ERROR_ABSENT_INFORMATION;2545}25462547Klass* klass = java_lang_Class::as_Klass(k_mirror);2548Thread *thread = Thread::current();2549ResourceMark rm(thread);25502551jint status = klass->jvmti_class_status();2552if (status & (JVMTI_CLASS_STATUS_ERROR)) {2553return JVMTI_ERROR_INVALID_CLASS;2554}2555if (status & (JVMTI_CLASS_STATUS_ARRAY)) {2556return JVMTI_ERROR_ABSENT_INFORMATION;2557}25582559InstanceKlass* ik = InstanceKlass::cast(klass);2560JvmtiConstantPoolReconstituter reconstituter(ik);2561if (reconstituter.get_error() != JVMTI_ERROR_NONE) {2562return reconstituter.get_error();2563}25642565unsigned char *cpool_bytes;2566int cpool_size = reconstituter.cpool_size();2567if (reconstituter.get_error() != JVMTI_ERROR_NONE) {2568return reconstituter.get_error();2569}2570jvmtiError res = allocate(cpool_size, &cpool_bytes);2571if (res != JVMTI_ERROR_NONE) {2572return res;2573}2574reconstituter.copy_cpool_bytes(cpool_bytes);2575if (reconstituter.get_error() != JVMTI_ERROR_NONE) {2576return reconstituter.get_error();2577}25782579constantPoolHandle constants(thread, ik->constants());2580*constant_pool_count_ptr = constants->length();2581*constant_pool_byte_count_ptr = cpool_size;2582*constant_pool_bytes_ptr = cpool_bytes;25832584return JVMTI_ERROR_NONE;2585} /* end GetConstantPool */258625872588// k_mirror - may be primitive, this must be checked2589// is_interface_ptr - pre-checked for NULL2590jvmtiError2591JvmtiEnv::IsInterface(oop k_mirror, jboolean* is_interface_ptr) {2592{2593bool result = false;2594if (!java_lang_Class::is_primitive(k_mirror)) {2595Klass* k = java_lang_Class::as_Klass(k_mirror);2596if (k != NULL && k->is_interface()) {2597result = true;2598}2599}2600*is_interface_ptr = result;2601}26022603return JVMTI_ERROR_NONE;2604} /* end IsInterface */260526062607// k_mirror - may be primitive, this must be checked2608// is_array_class_ptr - pre-checked for NULL2609jvmtiError2610JvmtiEnv::IsArrayClass(oop k_mirror, jboolean* is_array_class_ptr) {2611{2612bool result = false;2613if (!java_lang_Class::is_primitive(k_mirror)) {2614Klass* k = java_lang_Class::as_Klass(k_mirror);2615if (k != NULL && k->is_array_klass()) {2616result = true;2617}2618}2619*is_array_class_ptr = result;2620}26212622return JVMTI_ERROR_NONE;2623} /* end IsArrayClass */262426252626// k_mirror - may be primitive, this must be checked2627// classloader_ptr - pre-checked for NULL2628jvmtiError2629JvmtiEnv::GetClassLoader(oop k_mirror, jobject* classloader_ptr) {2630{2631if (java_lang_Class::is_primitive(k_mirror)) {2632*classloader_ptr = (jclass) jni_reference(Handle());2633return JVMTI_ERROR_NONE;2634}2635JavaThread* current_thread = JavaThread::current();2636HandleMark hm(current_thread);2637Klass* k = java_lang_Class::as_Klass(k_mirror);2638NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);26392640oop result_oop = k->class_loader();2641if (result_oop == NULL) {2642*classloader_ptr = (jclass) jni_reference(Handle());2643return JVMTI_ERROR_NONE;2644}2645Handle result_handle = Handle(current_thread, result_oop);2646jclass result_jnihandle = (jclass) jni_reference(result_handle);2647*classloader_ptr = result_jnihandle;2648}2649return JVMTI_ERROR_NONE;2650} /* end GetClassLoader */265126522653// k_mirror - may be primitive, this must be checked2654// source_debug_extension_ptr - pre-checked for NULL2655jvmtiError2656JvmtiEnv::GetSourceDebugExtension(oop k_mirror, char** source_debug_extension_ptr) {2657{2658if (java_lang_Class::is_primitive(k_mirror)) {2659return JVMTI_ERROR_ABSENT_INFORMATION;2660}2661Klass* k = java_lang_Class::as_Klass(k_mirror);2662NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);2663if (!k->is_instance_klass()) {2664return JVMTI_ERROR_ABSENT_INFORMATION;2665}2666const char* sde = InstanceKlass::cast(k)->source_debug_extension();2667NULL_CHECK(sde, JVMTI_ERROR_ABSENT_INFORMATION);26682669{2670*source_debug_extension_ptr = (char *) jvmtiMalloc(strlen(sde)+1);2671strcpy(*source_debug_extension_ptr, sde);2672}2673}26742675return JVMTI_ERROR_NONE;2676} /* end GetSourceDebugExtension */26772678//2679// Object functions2680//26812682// hash_code_ptr - pre-checked for NULL2683jvmtiError2684JvmtiEnv::GetObjectHashCode(jobject object, jint* hash_code_ptr) {2685oop mirror = JNIHandles::resolve_external_guard(object);2686NULL_CHECK(mirror, JVMTI_ERROR_INVALID_OBJECT);2687NULL_CHECK(hash_code_ptr, JVMTI_ERROR_NULL_POINTER);26882689{2690jint result = (jint) mirror->identity_hash();2691*hash_code_ptr = result;2692}2693return JVMTI_ERROR_NONE;2694} /* end GetObjectHashCode */269526962697// info_ptr - pre-checked for NULL2698jvmtiError2699JvmtiEnv::GetObjectMonitorUsage(jobject object, jvmtiMonitorUsage* info_ptr) {2700// This needs to be performed at a safepoint to gather stable data2701// because monitor owner / waiters might not be suspended.2702VM_GetObjectMonitorUsage op(this, JavaThread::current(), object, info_ptr);2703VMThread::execute(&op);2704return op.result();2705} /* end GetObjectMonitorUsage */270627072708//2709// Field functions2710//27112712// name_ptr - NULL is a valid value, must be checked2713// signature_ptr - NULL is a valid value, must be checked2714// generic_ptr - NULL is a valid value, must be checked2715jvmtiError2716JvmtiEnv::GetFieldName(fieldDescriptor* fdesc_ptr, char** name_ptr, char** signature_ptr, char** generic_ptr) {2717JavaThread* current_thread = JavaThread::current();2718ResourceMark rm(current_thread);2719if (name_ptr == NULL) {2720// just don't return the name2721} else {2722const char* fieldName = fdesc_ptr->name()->as_C_string();2723*name_ptr = (char*) jvmtiMalloc(strlen(fieldName) + 1);2724if (*name_ptr == NULL)2725return JVMTI_ERROR_OUT_OF_MEMORY;2726strcpy(*name_ptr, fieldName);2727}2728if (signature_ptr== NULL) {2729// just don't return the signature2730} else {2731const char* fieldSignature = fdesc_ptr->signature()->as_C_string();2732*signature_ptr = (char*) jvmtiMalloc(strlen(fieldSignature) + 1);2733if (*signature_ptr == NULL)2734return JVMTI_ERROR_OUT_OF_MEMORY;2735strcpy(*signature_ptr, fieldSignature);2736}2737if (generic_ptr != NULL) {2738*generic_ptr = NULL;2739Symbol* soop = fdesc_ptr->generic_signature();2740if (soop != NULL) {2741const char* gen_sig = soop->as_C_string();2742if (gen_sig != NULL) {2743jvmtiError err = allocate(strlen(gen_sig) + 1, (unsigned char **)generic_ptr);2744if (err != JVMTI_ERROR_NONE) {2745return err;2746}2747strcpy(*generic_ptr, gen_sig);2748}2749}2750}2751return JVMTI_ERROR_NONE;2752} /* end GetFieldName */275327542755// declaring_class_ptr - pre-checked for NULL2756jvmtiError2757JvmtiEnv::GetFieldDeclaringClass(fieldDescriptor* fdesc_ptr, jclass* declaring_class_ptr) {27582759*declaring_class_ptr = get_jni_class_non_null(fdesc_ptr->field_holder());2760return JVMTI_ERROR_NONE;2761} /* end GetFieldDeclaringClass */276227632764// modifiers_ptr - pre-checked for NULL2765jvmtiError2766JvmtiEnv::GetFieldModifiers(fieldDescriptor* fdesc_ptr, jint* modifiers_ptr) {27672768AccessFlags resultFlags = fdesc_ptr->access_flags();2769jint result = resultFlags.as_int();2770*modifiers_ptr = result;27712772return JVMTI_ERROR_NONE;2773} /* end GetFieldModifiers */277427752776// is_synthetic_ptr - pre-checked for NULL2777jvmtiError2778JvmtiEnv::IsFieldSynthetic(fieldDescriptor* fdesc_ptr, jboolean* is_synthetic_ptr) {2779*is_synthetic_ptr = fdesc_ptr->is_synthetic();2780return JVMTI_ERROR_NONE;2781} /* end IsFieldSynthetic */278227832784//2785// Method functions2786//27872788// method - pre-checked for validity, but may be NULL meaning obsolete method2789// name_ptr - NULL is a valid value, must be checked2790// signature_ptr - NULL is a valid value, must be checked2791// generic_ptr - NULL is a valid value, must be checked2792jvmtiError2793JvmtiEnv::GetMethodName(Method* method, char** name_ptr, char** signature_ptr, char** generic_ptr) {2794NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);2795JavaThread* current_thread = JavaThread::current();27962797ResourceMark rm(current_thread); // get the utf8 name and signature2798if (name_ptr == NULL) {2799// just don't return the name2800} else {2801const char* utf8_name = (const char *) method->name()->as_utf8();2802*name_ptr = (char *) jvmtiMalloc(strlen(utf8_name)+1);2803strcpy(*name_ptr, utf8_name);2804}2805if (signature_ptr == NULL) {2806// just don't return the signature2807} else {2808const char* utf8_signature = (const char *) method->signature()->as_utf8();2809*signature_ptr = (char *) jvmtiMalloc(strlen(utf8_signature) + 1);2810strcpy(*signature_ptr, utf8_signature);2811}28122813if (generic_ptr != NULL) {2814*generic_ptr = NULL;2815Symbol* soop = method->generic_signature();2816if (soop != NULL) {2817const char* gen_sig = soop->as_C_string();2818if (gen_sig != NULL) {2819jvmtiError err = allocate(strlen(gen_sig) + 1, (unsigned char **)generic_ptr);2820if (err != JVMTI_ERROR_NONE) {2821return err;2822}2823strcpy(*generic_ptr, gen_sig);2824}2825}2826}2827return JVMTI_ERROR_NONE;2828} /* end GetMethodName */282928302831// method - pre-checked for validity, but may be NULL meaning obsolete method2832// declaring_class_ptr - pre-checked for NULL2833jvmtiError2834JvmtiEnv::GetMethodDeclaringClass(Method* method, jclass* declaring_class_ptr) {2835NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);2836(*declaring_class_ptr) = get_jni_class_non_null(method->method_holder());2837return JVMTI_ERROR_NONE;2838} /* end GetMethodDeclaringClass */283928402841// method - pre-checked for validity, but may be NULL meaning obsolete method2842// modifiers_ptr - pre-checked for NULL2843jvmtiError2844JvmtiEnv::GetMethodModifiers(Method* method, jint* modifiers_ptr) {2845NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);2846(*modifiers_ptr) = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS;2847return JVMTI_ERROR_NONE;2848} /* end GetMethodModifiers */284928502851// method - pre-checked for validity, but may be NULL meaning obsolete method2852// max_ptr - pre-checked for NULL2853jvmtiError2854JvmtiEnv::GetMaxLocals(Method* method, jint* max_ptr) {2855NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);2856// get max stack2857(*max_ptr) = method->max_locals();2858return JVMTI_ERROR_NONE;2859} /* end GetMaxLocals */286028612862// method - pre-checked for validity, but may be NULL meaning obsolete method2863// size_ptr - pre-checked for NULL2864jvmtiError2865JvmtiEnv::GetArgumentsSize(Method* method, jint* size_ptr) {2866NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);2867// get size of arguments28682869(*size_ptr) = method->size_of_parameters();2870return JVMTI_ERROR_NONE;2871} /* end GetArgumentsSize */287228732874// method - pre-checked for validity, but may be NULL meaning obsolete method2875// entry_count_ptr - pre-checked for NULL2876// table_ptr - pre-checked for NULL2877jvmtiError2878JvmtiEnv::GetLineNumberTable(Method* method, jint* entry_count_ptr, jvmtiLineNumberEntry** table_ptr) {2879NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);2880if (!method->has_linenumber_table()) {2881return (JVMTI_ERROR_ABSENT_INFORMATION);2882}28832884// The line number table is compressed so we don't know how big it is until decompressed.2885// Decompression is really fast so we just do it twice.28862887// Compute size of table2888jint num_entries = 0;2889CompressedLineNumberReadStream stream(method->compressed_linenumber_table());2890while (stream.read_pair()) {2891num_entries++;2892}2893jvmtiLineNumberEntry *jvmti_table =2894(jvmtiLineNumberEntry *)jvmtiMalloc(num_entries * (sizeof(jvmtiLineNumberEntry)));28952896// Fill jvmti table2897if (num_entries > 0) {2898int index = 0;2899CompressedLineNumberReadStream stream(method->compressed_linenumber_table());2900while (stream.read_pair()) {2901jvmti_table[index].start_location = (jlocation) stream.bci();2902jvmti_table[index].line_number = (jint) stream.line();2903index++;2904}2905assert(index == num_entries, "sanity check");2906}29072908// Set up results2909(*entry_count_ptr) = num_entries;2910(*table_ptr) = jvmti_table;29112912return JVMTI_ERROR_NONE;2913} /* end GetLineNumberTable */291429152916// method - pre-checked for validity, but may be NULL meaning obsolete method2917// start_location_ptr - pre-checked for NULL2918// end_location_ptr - pre-checked for NULL2919jvmtiError2920JvmtiEnv::GetMethodLocation(Method* method, jlocation* start_location_ptr, jlocation* end_location_ptr) {29212922NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);2923// get start and end location2924(*end_location_ptr) = (jlocation) (method->code_size() - 1);2925if (method->code_size() == 0) {2926// there is no code so there is no start location2927(*start_location_ptr) = (jlocation)(-1);2928} else {2929(*start_location_ptr) = (jlocation)(0);2930}29312932return JVMTI_ERROR_NONE;2933} /* end GetMethodLocation */293429352936// method - pre-checked for validity, but may be NULL meaning obsolete method2937// entry_count_ptr - pre-checked for NULL2938// table_ptr - pre-checked for NULL2939jvmtiError2940JvmtiEnv::GetLocalVariableTable(Method* method, jint* entry_count_ptr, jvmtiLocalVariableEntry** table_ptr) {29412942NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);2943JavaThread* current_thread = JavaThread::current();29442945// does the klass have any local variable information?2946InstanceKlass* ik = method->method_holder();2947if (!ik->access_flags().has_localvariable_table()) {2948return (JVMTI_ERROR_ABSENT_INFORMATION);2949}29502951ConstantPool* constants = method->constants();2952NULL_CHECK(constants, JVMTI_ERROR_ABSENT_INFORMATION);29532954// in the vm localvariable table representation, 6 consecutive elements in the table2955// represent a 6-tuple of shorts2956// [start_pc, length, name_index, descriptor_index, signature_index, index]2957jint num_entries = method->localvariable_table_length();2958jvmtiLocalVariableEntry *jvmti_table = (jvmtiLocalVariableEntry *)2959jvmtiMalloc(num_entries * (sizeof(jvmtiLocalVariableEntry)));29602961if (num_entries > 0) {2962LocalVariableTableElement* table = method->localvariable_table_start();2963for (int i = 0; i < num_entries; i++) {2964// get the 5 tuple information from the vm table2965jlocation start_location = (jlocation) table[i].start_bci;2966jint length = (jint) table[i].length;2967int name_index = (int) table[i].name_cp_index;2968int signature_index = (int) table[i].descriptor_cp_index;2969int generic_signature_index = (int) table[i].signature_cp_index;2970jint slot = (jint) table[i].slot;29712972// get utf8 name and signature2973char *name_buf = NULL;2974char *sig_buf = NULL;2975char *gen_sig_buf = NULL;2976{2977ResourceMark rm(current_thread);29782979const char *utf8_name = (const char *) constants->symbol_at(name_index)->as_utf8();2980name_buf = (char *) jvmtiMalloc(strlen(utf8_name)+1);2981strcpy(name_buf, utf8_name);29822983const char *utf8_signature = (const char *) constants->symbol_at(signature_index)->as_utf8();2984sig_buf = (char *) jvmtiMalloc(strlen(utf8_signature)+1);2985strcpy(sig_buf, utf8_signature);29862987if (generic_signature_index > 0) {2988const char *utf8_gen_sign = (const char *)2989constants->symbol_at(generic_signature_index)->as_utf8();2990gen_sig_buf = (char *) jvmtiMalloc(strlen(utf8_gen_sign)+1);2991strcpy(gen_sig_buf, utf8_gen_sign);2992}2993}29942995// fill in the jvmti local variable table2996jvmti_table[i].start_location = start_location;2997jvmti_table[i].length = length;2998jvmti_table[i].name = name_buf;2999jvmti_table[i].signature = sig_buf;3000jvmti_table[i].generic_signature = gen_sig_buf;3001jvmti_table[i].slot = slot;3002}3003}30043005// set results3006(*entry_count_ptr) = num_entries;3007(*table_ptr) = jvmti_table;30083009return JVMTI_ERROR_NONE;3010} /* end GetLocalVariableTable */301130123013// method - pre-checked for validity, but may be NULL meaning obsolete method3014// bytecode_count_ptr - pre-checked for NULL3015// bytecodes_ptr - pre-checked for NULL3016jvmtiError3017JvmtiEnv::GetBytecodes(Method* method, jint* bytecode_count_ptr, unsigned char** bytecodes_ptr) {3018NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);30193020methodHandle mh(Thread::current(), method);3021jint size = (jint)mh->code_size();3022jvmtiError err = allocate(size, bytecodes_ptr);3023if (err != JVMTI_ERROR_NONE) {3024return err;3025}30263027(*bytecode_count_ptr) = size;3028// get byte codes3029JvmtiClassFileReconstituter::copy_bytecodes(mh, *bytecodes_ptr);30303031return JVMTI_ERROR_NONE;3032} /* end GetBytecodes */303330343035// method - pre-checked for validity, but may be NULL meaning obsolete method3036// is_native_ptr - pre-checked for NULL3037jvmtiError3038JvmtiEnv::IsMethodNative(Method* method, jboolean* is_native_ptr) {3039NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);3040(*is_native_ptr) = method->is_native();3041return JVMTI_ERROR_NONE;3042} /* end IsMethodNative */304330443045// method - pre-checked for validity, but may be NULL meaning obsolete method3046// is_synthetic_ptr - pre-checked for NULL3047jvmtiError3048JvmtiEnv::IsMethodSynthetic(Method* method, jboolean* is_synthetic_ptr) {3049NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);3050(*is_synthetic_ptr) = method->is_synthetic();3051return JVMTI_ERROR_NONE;3052} /* end IsMethodSynthetic */305330543055// method - pre-checked for validity, but may be NULL meaning obsolete method3056// is_obsolete_ptr - pre-checked for NULL3057jvmtiError3058JvmtiEnv::IsMethodObsolete(Method* method, jboolean* is_obsolete_ptr) {3059if (use_version_1_0_semantics() &&3060get_capabilities()->can_redefine_classes == 0) {3061// This JvmtiEnv requested version 1.0 semantics and this function3062// requires the can_redefine_classes capability in version 1.0 so3063// we need to return an error here.3064return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;3065}30663067if (method == NULL || method->is_obsolete()) {3068*is_obsolete_ptr = true;3069} else {3070*is_obsolete_ptr = false;3071}3072return JVMTI_ERROR_NONE;3073} /* end IsMethodObsolete */30743075//3076// Raw Monitor functions3077//30783079// name - pre-checked for NULL3080// monitor_ptr - pre-checked for NULL3081jvmtiError3082JvmtiEnv::CreateRawMonitor(const char* name, jrawMonitorID* monitor_ptr) {3083JvmtiRawMonitor* rmonitor = new JvmtiRawMonitor(name);3084NULL_CHECK(rmonitor, JVMTI_ERROR_OUT_OF_MEMORY);30853086*monitor_ptr = (jrawMonitorID)rmonitor;30873088return JVMTI_ERROR_NONE;3089} /* end CreateRawMonitor */309030913092// rmonitor - pre-checked for validity3093jvmtiError3094JvmtiEnv::DestroyRawMonitor(JvmtiRawMonitor * rmonitor) {3095if (Threads::number_of_threads() == 0) {3096// Remove this monitor from pending raw monitors list3097// if it has entered in onload or start phase.3098JvmtiPendingMonitors::destroy(rmonitor);3099} else {3100Thread* thread = Thread::current();3101if (rmonitor->owner() == thread) {3102// The caller owns this monitor which we are about to destroy.3103// We exit the underlying synchronization object so that the3104// "delete monitor" call below can work without an assertion3105// failure on systems that don't like destroying synchronization3106// objects that are locked.3107int r;3108int recursion = rmonitor->recursions();3109for (int i = 0; i <= recursion; i++) {3110r = rmonitor->raw_exit(thread);3111assert(r == JvmtiRawMonitor::M_OK, "raw_exit should have worked");3112if (r != JvmtiRawMonitor::M_OK) { // robustness3113return JVMTI_ERROR_INTERNAL;3114}3115}3116}3117if (rmonitor->owner() != NULL) {3118// The caller is trying to destroy a monitor that is locked by3119// someone else. While this is not forbidden by the JVMTI3120// spec, it will cause an assertion failure on systems that don't3121// like destroying synchronization objects that are locked.3122// We indicate a problem with the error return (and leak the3123// monitor's memory).3124return JVMTI_ERROR_NOT_MONITOR_OWNER;3125}3126}31273128delete rmonitor;31293130return JVMTI_ERROR_NONE;3131} /* end DestroyRawMonitor */313231333134// rmonitor - pre-checked for validity3135jvmtiError3136JvmtiEnv::RawMonitorEnter(JvmtiRawMonitor * rmonitor) {3137if (Threads::number_of_threads() == 0) {3138// No JavaThreads exist so JvmtiRawMonitor enter cannot be3139// used, add this raw monitor to the pending list.3140// The pending monitors will be actually entered when3141// the VM is setup.3142// See transition_pending_raw_monitors in create_vm()3143// in thread.cpp.3144JvmtiPendingMonitors::enter(rmonitor);3145} else {3146rmonitor->raw_enter(Thread::current());3147}3148return JVMTI_ERROR_NONE;3149} /* end RawMonitorEnter */315031513152// rmonitor - pre-checked for validity3153jvmtiError3154JvmtiEnv::RawMonitorExit(JvmtiRawMonitor * rmonitor) {3155jvmtiError err = JVMTI_ERROR_NONE;31563157if (Threads::number_of_threads() == 0) {3158// No JavaThreads exist so just remove this monitor from the pending list.3159// Bool value from exit is false if rmonitor is not in the list.3160if (!JvmtiPendingMonitors::exit(rmonitor)) {3161err = JVMTI_ERROR_NOT_MONITOR_OWNER;3162}3163} else {3164Thread* thread = Thread::current();3165int r = rmonitor->raw_exit(thread);3166if (r == JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE) {3167err = JVMTI_ERROR_NOT_MONITOR_OWNER;3168}3169}3170return err;3171} /* end RawMonitorExit */317231733174// rmonitor - pre-checked for validity3175jvmtiError3176JvmtiEnv::RawMonitorWait(JvmtiRawMonitor * rmonitor, jlong millis) {3177Thread* thread = Thread::current();3178int r = rmonitor->raw_wait(millis, thread);31793180switch (r) {3181case JvmtiRawMonitor::M_INTERRUPTED:3182return JVMTI_ERROR_INTERRUPT;3183case JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE:3184return JVMTI_ERROR_NOT_MONITOR_OWNER;3185default:3186return JVMTI_ERROR_NONE;3187}3188} /* end RawMonitorWait */318931903191// rmonitor - pre-checked for validity3192jvmtiError3193JvmtiEnv::RawMonitorNotify(JvmtiRawMonitor * rmonitor) {3194Thread* thread = Thread::current();3195int r = rmonitor->raw_notify(thread);31963197if (r == JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE) {3198return JVMTI_ERROR_NOT_MONITOR_OWNER;3199}3200return JVMTI_ERROR_NONE;3201} /* end RawMonitorNotify */320232033204// rmonitor - pre-checked for validity3205jvmtiError3206JvmtiEnv::RawMonitorNotifyAll(JvmtiRawMonitor * rmonitor) {3207Thread* thread = Thread::current();3208int r = rmonitor->raw_notifyAll(thread);32093210if (r == JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE) {3211return JVMTI_ERROR_NOT_MONITOR_OWNER;3212}3213return JVMTI_ERROR_NONE;3214} /* end RawMonitorNotifyAll */321532163217//3218// JNI Function Interception functions3219//322032213222// function_table - pre-checked for NULL3223jvmtiError3224JvmtiEnv::SetJNIFunctionTable(const jniNativeInterface* function_table) {3225// Copy jni function table at safepoint.3226VM_JNIFunctionTableCopier copier(function_table);3227VMThread::execute(&copier);32283229return JVMTI_ERROR_NONE;3230} /* end SetJNIFunctionTable */323132323233// function_table - pre-checked for NULL3234jvmtiError3235JvmtiEnv::GetJNIFunctionTable(jniNativeInterface** function_table) {3236*function_table=(jniNativeInterface*)jvmtiMalloc(sizeof(jniNativeInterface));3237if (*function_table == NULL)3238return JVMTI_ERROR_OUT_OF_MEMORY;3239memcpy(*function_table,(JavaThread::current())->get_jni_functions(),sizeof(jniNativeInterface));3240return JVMTI_ERROR_NONE;3241} /* end GetJNIFunctionTable */324232433244//3245// Event Management functions3246//32473248jvmtiError3249JvmtiEnv::GenerateEvents(jvmtiEvent event_type) {3250// can only generate two event types3251if (event_type != JVMTI_EVENT_COMPILED_METHOD_LOAD &&3252event_type != JVMTI_EVENT_DYNAMIC_CODE_GENERATED) {3253return JVMTI_ERROR_ILLEGAL_ARGUMENT;3254}32553256// for compiled_method_load events we must check that the environment3257// has the can_generate_compiled_method_load_events capability.3258if (event_type == JVMTI_EVENT_COMPILED_METHOD_LOAD) {3259if (get_capabilities()->can_generate_compiled_method_load_events == 0) {3260return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;3261}3262return JvmtiCodeBlobEvents::generate_compiled_method_load_events(this);3263} else {3264return JvmtiCodeBlobEvents::generate_dynamic_code_events(this);3265}32663267} /* end GenerateEvents */326832693270//3271// Extension Mechanism functions3272//32733274// extension_count_ptr - pre-checked for NULL3275// extensions - pre-checked for NULL3276jvmtiError3277JvmtiEnv::GetExtensionFunctions(jint* extension_count_ptr, jvmtiExtensionFunctionInfo** extensions) {3278return JvmtiExtensions::get_functions(this, extension_count_ptr, extensions);3279} /* end GetExtensionFunctions */328032813282// extension_count_ptr - pre-checked for NULL3283// extensions - pre-checked for NULL3284jvmtiError3285JvmtiEnv::GetExtensionEvents(jint* extension_count_ptr, jvmtiExtensionEventInfo** extensions) {3286return JvmtiExtensions::get_events(this, extension_count_ptr, extensions);3287} /* end GetExtensionEvents */328832893290// callback - NULL is a valid value, must be checked3291jvmtiError3292JvmtiEnv::SetExtensionEventCallback(jint extension_event_index, jvmtiExtensionEvent callback) {3293return JvmtiExtensions::set_event_callback(this, extension_event_index, callback);3294} /* end SetExtensionEventCallback */32953296//3297// Timers functions3298//32993300// info_ptr - pre-checked for NULL3301jvmtiError3302JvmtiEnv::GetCurrentThreadCpuTimerInfo(jvmtiTimerInfo* info_ptr) {3303os::current_thread_cpu_time_info(info_ptr);3304return JVMTI_ERROR_NONE;3305} /* end GetCurrentThreadCpuTimerInfo */330633073308// nanos_ptr - pre-checked for NULL3309jvmtiError3310JvmtiEnv::GetCurrentThreadCpuTime(jlong* nanos_ptr) {3311*nanos_ptr = os::current_thread_cpu_time();3312return JVMTI_ERROR_NONE;3313} /* end GetCurrentThreadCpuTime */331433153316// info_ptr - pre-checked for NULL3317jvmtiError3318JvmtiEnv::GetThreadCpuTimerInfo(jvmtiTimerInfo* info_ptr) {3319os::thread_cpu_time_info(info_ptr);3320return JVMTI_ERROR_NONE;3321} /* end GetThreadCpuTimerInfo */332233233324// java_thread - protected by ThreadsListHandle and pre-checked3325// nanos_ptr - pre-checked for NULL3326jvmtiError3327JvmtiEnv::GetThreadCpuTime(JavaThread* java_thread, jlong* nanos_ptr) {3328*nanos_ptr = os::thread_cpu_time(java_thread);3329return JVMTI_ERROR_NONE;3330} /* end GetThreadCpuTime */333133323333// info_ptr - pre-checked for NULL3334jvmtiError3335JvmtiEnv::GetTimerInfo(jvmtiTimerInfo* info_ptr) {3336os::javaTimeNanos_info(info_ptr);3337return JVMTI_ERROR_NONE;3338} /* end GetTimerInfo */333933403341// nanos_ptr - pre-checked for NULL3342jvmtiError3343JvmtiEnv::GetTime(jlong* nanos_ptr) {3344*nanos_ptr = os::javaTimeNanos();3345return JVMTI_ERROR_NONE;3346} /* end GetTime */334733483349// processor_count_ptr - pre-checked for NULL3350jvmtiError3351JvmtiEnv::GetAvailableProcessors(jint* processor_count_ptr) {3352*processor_count_ptr = os::active_processor_count();3353return JVMTI_ERROR_NONE;3354} /* end GetAvailableProcessors */33553356jvmtiError3357JvmtiEnv::SetHeapSamplingInterval(jint sampling_interval) {3358if (sampling_interval < 0) {3359return JVMTI_ERROR_ILLEGAL_ARGUMENT;3360}3361ThreadHeapSampler::set_sampling_interval(sampling_interval);3362return JVMTI_ERROR_NONE;3363} /* end SetHeapSamplingInterval */33643365//3366// System Properties functions3367//33683369// count_ptr - pre-checked for NULL3370// property_ptr - pre-checked for NULL3371jvmtiError3372JvmtiEnv::GetSystemProperties(jint* count_ptr, char*** property_ptr) {3373jvmtiError err = JVMTI_ERROR_NONE;33743375// Get the number of readable properties.3376*count_ptr = Arguments::PropertyList_readable_count(Arguments::system_properties());33773378// Allocate memory to hold the exact number of readable properties.3379err = allocate(*count_ptr * sizeof(char *), (unsigned char **)property_ptr);3380if (err != JVMTI_ERROR_NONE) {3381return err;3382}3383int readable_count = 0;3384// Loop through the system properties until all the readable properties are found.3385for (SystemProperty* p = Arguments::system_properties(); p != NULL && readable_count < *count_ptr; p = p->next()) {3386if (p->is_readable()) {3387const char *key = p->key();3388char **tmp_value = *property_ptr+readable_count;3389readable_count++;3390err = allocate((strlen(key)+1) * sizeof(char), (unsigned char**)tmp_value);3391if (err == JVMTI_ERROR_NONE) {3392strcpy(*tmp_value, key);3393} else {3394// clean up previously allocated memory.3395for (int j = 0; j < readable_count; j++) {3396Deallocate((unsigned char*)*property_ptr+j);3397}3398Deallocate((unsigned char*)property_ptr);3399break;3400}3401}3402}3403assert(err != JVMTI_ERROR_NONE || readable_count == *count_ptr, "Bad readable property count");3404return err;3405} /* end GetSystemProperties */340634073408// property - pre-checked for NULL3409// value_ptr - pre-checked for NULL3410jvmtiError3411JvmtiEnv::GetSystemProperty(const char* property, char** value_ptr) {3412jvmtiError err = JVMTI_ERROR_NONE;3413const char *value;34143415// Return JVMTI_ERROR_NOT_AVAILABLE if property is not readable or doesn't exist.3416value = Arguments::PropertyList_get_readable_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_writeable_value(value_ptr)) {3438err = JVMTI_ERROR_NONE;3439}3440}3441}3442return err;3443} /* end SetSystemProperty */344434453446