1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/prims/jvmtiEnv.cpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,3436 @@ 1.4 +/* 1.5 + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "precompiled.hpp" 1.29 +#include "classfile/systemDictionary.hpp" 1.30 +#include "classfile/vmSymbols.hpp" 1.31 +#include "interpreter/bytecodeStream.hpp" 1.32 +#include "interpreter/interpreter.hpp" 1.33 +#include "jvmtifiles/jvmtiEnv.hpp" 1.34 +#include "memory/resourceArea.hpp" 1.35 +#include "memory/universe.inline.hpp" 1.36 +#include "oops/instanceKlass.hpp" 1.37 +#include "prims/jniCheck.hpp" 1.38 +#include "prims/jvm_misc.hpp" 1.39 +#include "prims/jvmtiAgentThread.hpp" 1.40 +#include "prims/jvmtiClassFileReconstituter.hpp" 1.41 +#include "prims/jvmtiCodeBlobEvents.hpp" 1.42 +#include "prims/jvmtiExtensions.hpp" 1.43 +#include "prims/jvmtiGetLoadedClasses.hpp" 1.44 +#include "prims/jvmtiImpl.hpp" 1.45 +#include "prims/jvmtiManageCapabilities.hpp" 1.46 +#include "prims/jvmtiRawMonitor.hpp" 1.47 +#include "prims/jvmtiRedefineClasses.hpp" 1.48 +#include "prims/jvmtiTagMap.hpp" 1.49 +#include "prims/jvmtiThreadState.inline.hpp" 1.50 +#include "prims/jvmtiUtil.hpp" 1.51 +#include "runtime/arguments.hpp" 1.52 +#include "runtime/deoptimization.hpp" 1.53 +#include "runtime/interfaceSupport.hpp" 1.54 +#include "runtime/javaCalls.hpp" 1.55 +#include "runtime/jfieldIDWorkaround.hpp" 1.56 +#include "runtime/osThread.hpp" 1.57 +#include "runtime/reflectionUtils.hpp" 1.58 +#include "runtime/signature.hpp" 1.59 +#include "runtime/thread.inline.hpp" 1.60 +#include "runtime/vframe.hpp" 1.61 +#include "runtime/vmThread.hpp" 1.62 +#include "services/threadService.hpp" 1.63 +#include "utilities/exceptions.hpp" 1.64 +#include "utilities/preserveException.hpp" 1.65 + 1.66 + 1.67 +#define FIXLATER 0 // REMOVE this when completed. 1.68 + 1.69 + // FIXLATER: hook into JvmtiTrace 1.70 +#define TraceJVMTICalls false 1.71 + 1.72 +JvmtiEnv::JvmtiEnv(jint version) : JvmtiEnvBase(version) { 1.73 +} 1.74 + 1.75 +JvmtiEnv::~JvmtiEnv() { 1.76 +} 1.77 + 1.78 +JvmtiEnv* 1.79 +JvmtiEnv::create_a_jvmti(jint version) { 1.80 + return new JvmtiEnv(version); 1.81 +} 1.82 + 1.83 +// VM operation class to copy jni function table at safepoint. 1.84 +// More than one java threads or jvmti agents may be reading/ 1.85 +// modifying jni function tables. To reduce the risk of bad 1.86 +// interaction b/w these threads it is copied at safepoint. 1.87 +class VM_JNIFunctionTableCopier : public VM_Operation { 1.88 + private: 1.89 + const struct JNINativeInterface_ *_function_table; 1.90 + public: 1.91 + VM_JNIFunctionTableCopier(const struct JNINativeInterface_ *func_tbl) { 1.92 + _function_table = func_tbl; 1.93 + }; 1.94 + 1.95 + VMOp_Type type() const { return VMOp_JNIFunctionTableCopier; } 1.96 + void doit() { 1.97 + copy_jni_function_table(_function_table); 1.98 + }; 1.99 +}; 1.100 + 1.101 +// 1.102 +// Do not change the "prefix" marker below, everything above it is copied 1.103 +// unchanged into the filled stub, everything below is controlled by the 1.104 +// stub filler (only method bodies are carried forward, and then only for 1.105 +// functionality still in the spec). 1.106 +// 1.107 +// end file prefix 1.108 + 1.109 + // 1.110 + // Memory Management functions 1.111 + // 1.112 + 1.113 +// mem_ptr - pre-checked for NULL 1.114 +jvmtiError 1.115 +JvmtiEnv::Allocate(jlong size, unsigned char** mem_ptr) { 1.116 + return allocate(size, mem_ptr); 1.117 +} /* end Allocate */ 1.118 + 1.119 + 1.120 +// mem - NULL is a valid value, must be checked 1.121 +jvmtiError 1.122 +JvmtiEnv::Deallocate(unsigned char* mem) { 1.123 + return deallocate(mem); 1.124 +} /* end Deallocate */ 1.125 + 1.126 +// Threads_lock NOT held, java_thread not protected by lock 1.127 +// java_thread - pre-checked 1.128 +// data - NULL is a valid value, must be checked 1.129 +jvmtiError 1.130 +JvmtiEnv::SetThreadLocalStorage(JavaThread* java_thread, const void* data) { 1.131 + JvmtiThreadState* state = java_thread->jvmti_thread_state(); 1.132 + if (state == NULL) { 1.133 + if (data == NULL) { 1.134 + // leaving state unset same as data set to NULL 1.135 + return JVMTI_ERROR_NONE; 1.136 + } 1.137 + // otherwise, create the state 1.138 + state = JvmtiThreadState::state_for(java_thread); 1.139 + if (state == NULL) { 1.140 + return JVMTI_ERROR_THREAD_NOT_ALIVE; 1.141 + } 1.142 + } 1.143 + state->env_thread_state(this)->set_agent_thread_local_storage_data((void*)data); 1.144 + return JVMTI_ERROR_NONE; 1.145 +} /* end SetThreadLocalStorage */ 1.146 + 1.147 + 1.148 +// Threads_lock NOT held 1.149 +// thread - NOT pre-checked 1.150 +// data_ptr - pre-checked for NULL 1.151 +jvmtiError 1.152 +JvmtiEnv::GetThreadLocalStorage(jthread thread, void** data_ptr) { 1.153 + JavaThread* current_thread = JavaThread::current(); 1.154 + if (thread == NULL) { 1.155 + JvmtiThreadState* state = current_thread->jvmti_thread_state(); 1.156 + *data_ptr = (state == NULL) ? NULL : 1.157 + state->env_thread_state(this)->get_agent_thread_local_storage_data(); 1.158 + } else { 1.159 + 1.160 + // jvmti_GetThreadLocalStorage is "in native" and doesn't transition 1.161 + // the thread to _thread_in_vm. However, when the TLS for a thread 1.162 + // other than the current thread is required we need to transition 1.163 + // from native so as to resolve the jthread. 1.164 + 1.165 + ThreadInVMfromNative __tiv(current_thread); 1.166 + VM_ENTRY_BASE(jvmtiError, JvmtiEnv::GetThreadLocalStorage , current_thread) 1.167 + debug_only(VMNativeEntryWrapper __vew;) 1.168 + 1.169 + oop thread_oop = JNIHandles::resolve_external_guard(thread); 1.170 + if (thread_oop == NULL) { 1.171 + return JVMTI_ERROR_INVALID_THREAD; 1.172 + } 1.173 + if (!thread_oop->is_a(SystemDictionary::Thread_klass())) { 1.174 + return JVMTI_ERROR_INVALID_THREAD; 1.175 + } 1.176 + JavaThread* java_thread = java_lang_Thread::thread(thread_oop); 1.177 + if (java_thread == NULL) { 1.178 + return JVMTI_ERROR_THREAD_NOT_ALIVE; 1.179 + } 1.180 + JvmtiThreadState* state = java_thread->jvmti_thread_state(); 1.181 + *data_ptr = (state == NULL) ? NULL : 1.182 + state->env_thread_state(this)->get_agent_thread_local_storage_data(); 1.183 + } 1.184 + return JVMTI_ERROR_NONE; 1.185 +} /* end GetThreadLocalStorage */ 1.186 + 1.187 + // 1.188 + // Class functions 1.189 + // 1.190 + 1.191 +// class_count_ptr - pre-checked for NULL 1.192 +// classes_ptr - pre-checked for NULL 1.193 +jvmtiError 1.194 +JvmtiEnv::GetLoadedClasses(jint* class_count_ptr, jclass** classes_ptr) { 1.195 + return JvmtiGetLoadedClasses::getLoadedClasses(this, class_count_ptr, classes_ptr); 1.196 +} /* end GetLoadedClasses */ 1.197 + 1.198 + 1.199 +// initiating_loader - NULL is a valid value, must be checked 1.200 +// class_count_ptr - pre-checked for NULL 1.201 +// classes_ptr - pre-checked for NULL 1.202 +jvmtiError 1.203 +JvmtiEnv::GetClassLoaderClasses(jobject initiating_loader, jint* class_count_ptr, jclass** classes_ptr) { 1.204 + return JvmtiGetLoadedClasses::getClassLoaderClasses(this, initiating_loader, 1.205 + class_count_ptr, classes_ptr); 1.206 +} /* end GetClassLoaderClasses */ 1.207 + 1.208 +// k_mirror - may be primitive, this must be checked 1.209 +// is_modifiable_class_ptr - pre-checked for NULL 1.210 +jvmtiError 1.211 +JvmtiEnv::IsModifiableClass(oop k_mirror, jboolean* is_modifiable_class_ptr) { 1.212 + *is_modifiable_class_ptr = VM_RedefineClasses::is_modifiable_class(k_mirror)? 1.213 + JNI_TRUE : JNI_FALSE; 1.214 + return JVMTI_ERROR_NONE; 1.215 +} /* end IsModifiableClass */ 1.216 + 1.217 +// class_count - pre-checked to be greater than or equal to 0 1.218 +// classes - pre-checked for NULL 1.219 +jvmtiError 1.220 +JvmtiEnv::RetransformClasses(jint class_count, const jclass* classes) { 1.221 +//TODO: add locking 1.222 + 1.223 + int index; 1.224 + JavaThread* current_thread = JavaThread::current(); 1.225 + ResourceMark rm(current_thread); 1.226 + 1.227 + jvmtiClassDefinition* class_definitions = 1.228 + NEW_RESOURCE_ARRAY(jvmtiClassDefinition, class_count); 1.229 + NULL_CHECK(class_definitions, JVMTI_ERROR_OUT_OF_MEMORY); 1.230 + 1.231 + for (index = 0; index < class_count; index++) { 1.232 + HandleMark hm(current_thread); 1.233 + 1.234 + jclass jcls = classes[index]; 1.235 + oop k_mirror = JNIHandles::resolve_external_guard(jcls); 1.236 + if (k_mirror == NULL) { 1.237 + return JVMTI_ERROR_INVALID_CLASS; 1.238 + } 1.239 + if (!k_mirror->is_a(SystemDictionary::Class_klass())) { 1.240 + return JVMTI_ERROR_INVALID_CLASS; 1.241 + } 1.242 + 1.243 + if (java_lang_Class::is_primitive(k_mirror)) { 1.244 + return JVMTI_ERROR_UNMODIFIABLE_CLASS; 1.245 + } 1.246 + 1.247 + Klass* k_oop = java_lang_Class::as_Klass(k_mirror); 1.248 + KlassHandle klass(current_thread, k_oop); 1.249 + 1.250 + jint status = klass->jvmti_class_status(); 1.251 + if (status & (JVMTI_CLASS_STATUS_ERROR)) { 1.252 + return JVMTI_ERROR_INVALID_CLASS; 1.253 + } 1.254 + if (status & (JVMTI_CLASS_STATUS_ARRAY)) { 1.255 + return JVMTI_ERROR_UNMODIFIABLE_CLASS; 1.256 + } 1.257 + 1.258 + instanceKlassHandle ikh(current_thread, k_oop); 1.259 + if (ikh->get_cached_class_file_bytes() == NULL) { 1.260 + // Not cached, we need to reconstitute the class file from the 1.261 + // VM representation. We don't attach the reconstituted class 1.262 + // bytes to the InstanceKlass here because they have not been 1.263 + // validated and we're not at a safepoint. 1.264 + constantPoolHandle constants(current_thread, ikh->constants()); 1.265 + MonitorLockerEx ml(constants->lock()); // lock constant pool while we query it 1.266 + 1.267 + JvmtiClassFileReconstituter reconstituter(ikh); 1.268 + if (reconstituter.get_error() != JVMTI_ERROR_NONE) { 1.269 + return reconstituter.get_error(); 1.270 + } 1.271 + 1.272 + class_definitions[index].class_byte_count = (jint)reconstituter.class_file_size(); 1.273 + class_definitions[index].class_bytes = (unsigned char*) 1.274 + reconstituter.class_file_bytes(); 1.275 + } else { 1.276 + // it is cached, get it from the cache 1.277 + class_definitions[index].class_byte_count = ikh->get_cached_class_file_len(); 1.278 + class_definitions[index].class_bytes = ikh->get_cached_class_file_bytes(); 1.279 + } 1.280 + class_definitions[index].klass = jcls; 1.281 + } 1.282 + VM_RedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_retransform); 1.283 + VMThread::execute(&op); 1.284 + return (op.check_error()); 1.285 +} /* end RetransformClasses */ 1.286 + 1.287 + 1.288 +// class_count - pre-checked to be greater than or equal to 0 1.289 +// class_definitions - pre-checked for NULL 1.290 +jvmtiError 1.291 +JvmtiEnv::RedefineClasses(jint class_count, const jvmtiClassDefinition* class_definitions) { 1.292 +//TODO: add locking 1.293 + VM_RedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_redefine); 1.294 + VMThread::execute(&op); 1.295 + return (op.check_error()); 1.296 +} /* end RedefineClasses */ 1.297 + 1.298 + 1.299 + // 1.300 + // Object functions 1.301 + // 1.302 + 1.303 +// size_ptr - pre-checked for NULL 1.304 +jvmtiError 1.305 +JvmtiEnv::GetObjectSize(jobject object, jlong* size_ptr) { 1.306 + oop mirror = JNIHandles::resolve_external_guard(object); 1.307 + NULL_CHECK(mirror, JVMTI_ERROR_INVALID_OBJECT); 1.308 + 1.309 + if (mirror->klass() == SystemDictionary::Class_klass() && 1.310 + !java_lang_Class::is_primitive(mirror)) { 1.311 + Klass* k = java_lang_Class::as_Klass(mirror); 1.312 + assert(k != NULL, "class for non-primitive mirror must exist"); 1.313 + *size_ptr = (jlong)k->size() * wordSize; 1.314 + } else { 1.315 + *size_ptr = (jlong)mirror->size() * wordSize; 1.316 + } 1.317 + return JVMTI_ERROR_NONE; 1.318 +} /* end GetObjectSize */ 1.319 + 1.320 + // 1.321 + // Method functions 1.322 + // 1.323 + 1.324 +// prefix - NULL is a valid value, must be checked 1.325 +jvmtiError 1.326 +JvmtiEnv::SetNativeMethodPrefix(const char* prefix) { 1.327 + return prefix == NULL? 1.328 + SetNativeMethodPrefixes(0, NULL) : 1.329 + SetNativeMethodPrefixes(1, (char**)&prefix); 1.330 +} /* end SetNativeMethodPrefix */ 1.331 + 1.332 + 1.333 +// prefix_count - pre-checked to be greater than or equal to 0 1.334 +// prefixes - pre-checked for NULL 1.335 +jvmtiError 1.336 +JvmtiEnv::SetNativeMethodPrefixes(jint prefix_count, char** prefixes) { 1.337 + // Have to grab JVMTI thread state lock to be sure that some thread 1.338 + // isn't accessing the prefixes at the same time we are setting them. 1.339 + // No locks during VM bring-up. 1.340 + if (Threads::number_of_threads() == 0) { 1.341 + return set_native_method_prefixes(prefix_count, prefixes); 1.342 + } else { 1.343 + MutexLocker mu(JvmtiThreadState_lock); 1.344 + return set_native_method_prefixes(prefix_count, prefixes); 1.345 + } 1.346 +} /* end SetNativeMethodPrefixes */ 1.347 + 1.348 + // 1.349 + // Event Management functions 1.350 + // 1.351 + 1.352 +// callbacks - NULL is a valid value, must be checked 1.353 +// size_of_callbacks - pre-checked to be greater than or equal to 0 1.354 +jvmtiError 1.355 +JvmtiEnv::SetEventCallbacks(const jvmtiEventCallbacks* callbacks, jint size_of_callbacks) { 1.356 + JvmtiEventController::set_event_callbacks(this, callbacks, size_of_callbacks); 1.357 + return JVMTI_ERROR_NONE; 1.358 +} /* end SetEventCallbacks */ 1.359 + 1.360 + 1.361 +// event_thread - NULL is a valid value, must be checked 1.362 +jvmtiError 1.363 +JvmtiEnv::SetEventNotificationMode(jvmtiEventMode mode, jvmtiEvent event_type, jthread event_thread, ...) { 1.364 + JavaThread* java_thread = NULL; 1.365 + if (event_thread != NULL) { 1.366 + oop thread_oop = JNIHandles::resolve_external_guard(event_thread); 1.367 + if (thread_oop == NULL) { 1.368 + return JVMTI_ERROR_INVALID_THREAD; 1.369 + } 1.370 + if (!thread_oop->is_a(SystemDictionary::Thread_klass())) { 1.371 + return JVMTI_ERROR_INVALID_THREAD; 1.372 + } 1.373 + java_thread = java_lang_Thread::thread(thread_oop); 1.374 + if (java_thread == NULL) { 1.375 + return JVMTI_ERROR_THREAD_NOT_ALIVE; 1.376 + } 1.377 + } 1.378 + 1.379 + // event_type must be valid 1.380 + if (!JvmtiEventController::is_valid_event_type(event_type)) { 1.381 + return JVMTI_ERROR_INVALID_EVENT_TYPE; 1.382 + } 1.383 + 1.384 + // global events cannot be controlled at thread level. 1.385 + if (java_thread != NULL && JvmtiEventController::is_global_event(event_type)) { 1.386 + return JVMTI_ERROR_ILLEGAL_ARGUMENT; 1.387 + } 1.388 + 1.389 + bool enabled = (mode == JVMTI_ENABLE); 1.390 + 1.391 + // assure that needed capabilities are present 1.392 + if (enabled && !JvmtiUtil::has_event_capability(event_type, get_capabilities())) { 1.393 + return JVMTI_ERROR_MUST_POSSESS_CAPABILITY; 1.394 + } 1.395 + 1.396 + if (event_type == JVMTI_EVENT_CLASS_FILE_LOAD_HOOK && enabled) { 1.397 + record_class_file_load_hook_enabled(); 1.398 + } 1.399 + JvmtiEventController::set_user_enabled(this, java_thread, event_type, enabled); 1.400 + 1.401 + return JVMTI_ERROR_NONE; 1.402 +} /* end SetEventNotificationMode */ 1.403 + 1.404 + // 1.405 + // Capability functions 1.406 + // 1.407 + 1.408 +// capabilities_ptr - pre-checked for NULL 1.409 +jvmtiError 1.410 +JvmtiEnv::GetPotentialCapabilities(jvmtiCapabilities* capabilities_ptr) { 1.411 + JvmtiManageCapabilities::get_potential_capabilities(get_capabilities(), 1.412 + get_prohibited_capabilities(), 1.413 + capabilities_ptr); 1.414 + return JVMTI_ERROR_NONE; 1.415 +} /* end GetPotentialCapabilities */ 1.416 + 1.417 + 1.418 +// capabilities_ptr - pre-checked for NULL 1.419 +jvmtiError 1.420 +JvmtiEnv::AddCapabilities(const jvmtiCapabilities* capabilities_ptr) { 1.421 + return JvmtiManageCapabilities::add_capabilities(get_capabilities(), 1.422 + get_prohibited_capabilities(), 1.423 + capabilities_ptr, 1.424 + get_capabilities()); 1.425 +} /* end AddCapabilities */ 1.426 + 1.427 + 1.428 +// capabilities_ptr - pre-checked for NULL 1.429 +jvmtiError 1.430 +JvmtiEnv::RelinquishCapabilities(const jvmtiCapabilities* capabilities_ptr) { 1.431 + JvmtiManageCapabilities::relinquish_capabilities(get_capabilities(), capabilities_ptr, get_capabilities()); 1.432 + return JVMTI_ERROR_NONE; 1.433 +} /* end RelinquishCapabilities */ 1.434 + 1.435 + 1.436 +// capabilities_ptr - pre-checked for NULL 1.437 +jvmtiError 1.438 +JvmtiEnv::GetCapabilities(jvmtiCapabilities* capabilities_ptr) { 1.439 + JvmtiManageCapabilities::copy_capabilities(get_capabilities(), capabilities_ptr); 1.440 + return JVMTI_ERROR_NONE; 1.441 +} /* end GetCapabilities */ 1.442 + 1.443 + // 1.444 + // Class Loader Search functions 1.445 + // 1.446 + 1.447 +// segment - pre-checked for NULL 1.448 +jvmtiError 1.449 +JvmtiEnv::AddToBootstrapClassLoaderSearch(const char* segment) { 1.450 + jvmtiPhase phase = get_phase(); 1.451 + if (phase == JVMTI_PHASE_ONLOAD) { 1.452 + Arguments::append_sysclasspath(segment); 1.453 + return JVMTI_ERROR_NONE; 1.454 + } else if (use_version_1_0_semantics()) { 1.455 + // This JvmtiEnv requested version 1.0 semantics and this function 1.456 + // is only allowed in the ONLOAD phase in version 1.0 so we need to 1.457 + // return an error here. 1.458 + return JVMTI_ERROR_WRONG_PHASE; 1.459 + } else if (phase == JVMTI_PHASE_LIVE) { 1.460 + // The phase is checked by the wrapper that called this function, 1.461 + // but this thread could be racing with the thread that is 1.462 + // terminating the VM so we check one more time. 1.463 + 1.464 + // create the zip entry 1.465 + ClassPathZipEntry* zip_entry = ClassLoader::create_class_path_zip_entry(segment); 1.466 + if (zip_entry == NULL) { 1.467 + return JVMTI_ERROR_ILLEGAL_ARGUMENT; 1.468 + } 1.469 + 1.470 + // lock the loader 1.471 + Thread* thread = Thread::current(); 1.472 + HandleMark hm; 1.473 + Handle loader_lock = Handle(thread, SystemDictionary::system_loader_lock()); 1.474 + 1.475 + ObjectLocker ol(loader_lock, thread); 1.476 + 1.477 + // add the jar file to the bootclasspath 1.478 + if (TraceClassLoading) { 1.479 + tty->print_cr("[Opened %s]", zip_entry->name()); 1.480 + } 1.481 + ClassLoader::add_to_list(zip_entry); 1.482 + return JVMTI_ERROR_NONE; 1.483 + } else { 1.484 + return JVMTI_ERROR_WRONG_PHASE; 1.485 + } 1.486 + 1.487 +} /* end AddToBootstrapClassLoaderSearch */ 1.488 + 1.489 + 1.490 +// segment - pre-checked for NULL 1.491 +jvmtiError 1.492 +JvmtiEnv::AddToSystemClassLoaderSearch(const char* segment) { 1.493 + jvmtiPhase phase = get_phase(); 1.494 + 1.495 + if (phase == JVMTI_PHASE_ONLOAD) { 1.496 + for (SystemProperty* p = Arguments::system_properties(); p != NULL; p = p->next()) { 1.497 + if (strcmp("java.class.path", p->key()) == 0) { 1.498 + p->append_value(segment); 1.499 + break; 1.500 + } 1.501 + } 1.502 + return JVMTI_ERROR_NONE; 1.503 + } else if (phase == JVMTI_PHASE_LIVE) { 1.504 + // The phase is checked by the wrapper that called this function, 1.505 + // but this thread could be racing with the thread that is 1.506 + // terminating the VM so we check one more time. 1.507 + HandleMark hm; 1.508 + 1.509 + // create the zip entry (which will open the zip file and hence 1.510 + // check that the segment is indeed a zip file). 1.511 + ClassPathZipEntry* zip_entry = ClassLoader::create_class_path_zip_entry(segment); 1.512 + if (zip_entry == NULL) { 1.513 + return JVMTI_ERROR_ILLEGAL_ARGUMENT; 1.514 + } 1.515 + delete zip_entry; // no longer needed 1.516 + 1.517 + // lock the loader 1.518 + Thread* THREAD = Thread::current(); 1.519 + Handle loader = Handle(THREAD, SystemDictionary::java_system_loader()); 1.520 + 1.521 + ObjectLocker ol(loader, THREAD); 1.522 + 1.523 + // need the path as java.lang.String 1.524 + Handle path = java_lang_String::create_from_platform_dependent_str(segment, THREAD); 1.525 + if (HAS_PENDING_EXCEPTION) { 1.526 + CLEAR_PENDING_EXCEPTION; 1.527 + return JVMTI_ERROR_INTERNAL; 1.528 + } 1.529 + 1.530 + instanceKlassHandle loader_ik(THREAD, loader->klass()); 1.531 + 1.532 + // Invoke the appendToClassPathForInstrumentation method - if the method 1.533 + // is not found it means the loader doesn't support adding to the class path 1.534 + // in the live phase. 1.535 + { 1.536 + JavaValue res(T_VOID); 1.537 + JavaCalls::call_special(&res, 1.538 + loader, 1.539 + loader_ik, 1.540 + vmSymbols::appendToClassPathForInstrumentation_name(), 1.541 + vmSymbols::appendToClassPathForInstrumentation_signature(), 1.542 + path, 1.543 + THREAD); 1.544 + if (HAS_PENDING_EXCEPTION) { 1.545 + Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); 1.546 + CLEAR_PENDING_EXCEPTION; 1.547 + 1.548 + if (ex_name == vmSymbols::java_lang_NoSuchMethodError()) { 1.549 + return JVMTI_ERROR_CLASS_LOADER_UNSUPPORTED; 1.550 + } else { 1.551 + return JVMTI_ERROR_INTERNAL; 1.552 + } 1.553 + } 1.554 + } 1.555 + 1.556 + return JVMTI_ERROR_NONE; 1.557 + } else { 1.558 + return JVMTI_ERROR_WRONG_PHASE; 1.559 + } 1.560 +} /* end AddToSystemClassLoaderSearch */ 1.561 + 1.562 + // 1.563 + // General functions 1.564 + // 1.565 + 1.566 +// phase_ptr - pre-checked for NULL 1.567 +jvmtiError 1.568 +JvmtiEnv::GetPhase(jvmtiPhase* phase_ptr) { 1.569 + *phase_ptr = get_phase(); 1.570 + return JVMTI_ERROR_NONE; 1.571 +} /* end GetPhase */ 1.572 + 1.573 + 1.574 +jvmtiError 1.575 +JvmtiEnv::DisposeEnvironment() { 1.576 + dispose(); 1.577 + return JVMTI_ERROR_NONE; 1.578 +} /* end DisposeEnvironment */ 1.579 + 1.580 + 1.581 +// data - NULL is a valid value, must be checked 1.582 +jvmtiError 1.583 +JvmtiEnv::SetEnvironmentLocalStorage(const void* data) { 1.584 + set_env_local_storage(data); 1.585 + return JVMTI_ERROR_NONE; 1.586 +} /* end SetEnvironmentLocalStorage */ 1.587 + 1.588 + 1.589 +// data_ptr - pre-checked for NULL 1.590 +jvmtiError 1.591 +JvmtiEnv::GetEnvironmentLocalStorage(void** data_ptr) { 1.592 + *data_ptr = (void*)get_env_local_storage(); 1.593 + return JVMTI_ERROR_NONE; 1.594 +} /* end GetEnvironmentLocalStorage */ 1.595 + 1.596 +// version_ptr - pre-checked for NULL 1.597 +jvmtiError 1.598 +JvmtiEnv::GetVersionNumber(jint* version_ptr) { 1.599 + *version_ptr = JVMTI_VERSION; 1.600 + return JVMTI_ERROR_NONE; 1.601 +} /* end GetVersionNumber */ 1.602 + 1.603 + 1.604 +// name_ptr - pre-checked for NULL 1.605 +jvmtiError 1.606 +JvmtiEnv::GetErrorName(jvmtiError error, char** name_ptr) { 1.607 + if (error < JVMTI_ERROR_NONE || error > JVMTI_ERROR_MAX) { 1.608 + return JVMTI_ERROR_ILLEGAL_ARGUMENT; 1.609 + } 1.610 + const char *name = JvmtiUtil::error_name(error); 1.611 + if (name == NULL) { 1.612 + return JVMTI_ERROR_ILLEGAL_ARGUMENT; 1.613 + } 1.614 + size_t len = strlen(name) + 1; 1.615 + jvmtiError err = allocate(len, (unsigned char**)name_ptr); 1.616 + if (err == JVMTI_ERROR_NONE) { 1.617 + memcpy(*name_ptr, name, len); 1.618 + } 1.619 + return err; 1.620 +} /* end GetErrorName */ 1.621 + 1.622 + 1.623 +jvmtiError 1.624 +JvmtiEnv::SetVerboseFlag(jvmtiVerboseFlag flag, jboolean value) { 1.625 + switch (flag) { 1.626 + case JVMTI_VERBOSE_OTHER: 1.627 + // ignore 1.628 + break; 1.629 + case JVMTI_VERBOSE_CLASS: 1.630 + TraceClassLoading = value != 0; 1.631 + TraceClassUnloading = value != 0; 1.632 + break; 1.633 + case JVMTI_VERBOSE_GC: 1.634 + PrintGC = value != 0; 1.635 + break; 1.636 + case JVMTI_VERBOSE_JNI: 1.637 + PrintJNIResolving = value != 0; 1.638 + break; 1.639 + default: 1.640 + return JVMTI_ERROR_ILLEGAL_ARGUMENT; 1.641 + }; 1.642 + return JVMTI_ERROR_NONE; 1.643 +} /* end SetVerboseFlag */ 1.644 + 1.645 + 1.646 +// format_ptr - pre-checked for NULL 1.647 +jvmtiError 1.648 +JvmtiEnv::GetJLocationFormat(jvmtiJlocationFormat* format_ptr) { 1.649 + *format_ptr = JVMTI_JLOCATION_JVMBCI; 1.650 + return JVMTI_ERROR_NONE; 1.651 +} /* end GetJLocationFormat */ 1.652 + 1.653 + // 1.654 + // Thread functions 1.655 + // 1.656 + 1.657 +// Threads_lock NOT held 1.658 +// thread - NOT pre-checked 1.659 +// thread_state_ptr - pre-checked for NULL 1.660 +jvmtiError 1.661 +JvmtiEnv::GetThreadState(jthread thread, jint* thread_state_ptr) { 1.662 + jint state; 1.663 + oop thread_oop; 1.664 + JavaThread* thr; 1.665 + 1.666 + if (thread == NULL) { 1.667 + thread_oop = JavaThread::current()->threadObj(); 1.668 + } else { 1.669 + thread_oop = JNIHandles::resolve_external_guard(thread); 1.670 + } 1.671 + 1.672 + if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::Thread_klass())) { 1.673 + return JVMTI_ERROR_INVALID_THREAD; 1.674 + } 1.675 + 1.676 + // get most state bits 1.677 + state = (jint)java_lang_Thread::get_thread_status(thread_oop); 1.678 + 1.679 + // add more state bits 1.680 + thr = java_lang_Thread::thread(thread_oop); 1.681 + if (thr != NULL) { 1.682 + JavaThreadState jts = thr->thread_state(); 1.683 + 1.684 + if (thr->is_being_ext_suspended()) { 1.685 + state |= JVMTI_THREAD_STATE_SUSPENDED; 1.686 + } 1.687 + if (jts == _thread_in_native) { 1.688 + state |= JVMTI_THREAD_STATE_IN_NATIVE; 1.689 + } 1.690 + OSThread* osThread = thr->osthread(); 1.691 + if (osThread != NULL && osThread->interrupted()) { 1.692 + state |= JVMTI_THREAD_STATE_INTERRUPTED; 1.693 + } 1.694 + } 1.695 + 1.696 + *thread_state_ptr = state; 1.697 + return JVMTI_ERROR_NONE; 1.698 +} /* end GetThreadState */ 1.699 + 1.700 + 1.701 +// thread_ptr - pre-checked for NULL 1.702 +jvmtiError 1.703 +JvmtiEnv::GetCurrentThread(jthread* thread_ptr) { 1.704 + JavaThread* current_thread = JavaThread::current(); 1.705 + *thread_ptr = (jthread)JNIHandles::make_local(current_thread, current_thread->threadObj()); 1.706 + return JVMTI_ERROR_NONE; 1.707 +} /* end GetCurrentThread */ 1.708 + 1.709 + 1.710 +// threads_count_ptr - pre-checked for NULL 1.711 +// threads_ptr - pre-checked for NULL 1.712 +jvmtiError 1.713 +JvmtiEnv::GetAllThreads(jint* threads_count_ptr, jthread** threads_ptr) { 1.714 + int nthreads = 0; 1.715 + Handle *thread_objs = NULL; 1.716 + ResourceMark rm; 1.717 + HandleMark hm; 1.718 + 1.719 + // enumerate threads (including agent threads) 1.720 + ThreadsListEnumerator tle(Thread::current(), true); 1.721 + nthreads = tle.num_threads(); 1.722 + *threads_count_ptr = nthreads; 1.723 + 1.724 + if (nthreads == 0) { 1.725 + *threads_ptr = NULL; 1.726 + return JVMTI_ERROR_NONE; 1.727 + } 1.728 + 1.729 + thread_objs = NEW_RESOURCE_ARRAY(Handle, nthreads); 1.730 + NULL_CHECK(thread_objs, JVMTI_ERROR_OUT_OF_MEMORY); 1.731 + 1.732 + for (int i=0; i < nthreads; i++) { 1.733 + thread_objs[i] = Handle(tle.get_threadObj(i)); 1.734 + } 1.735 + 1.736 + // have to make global handles outside of Threads_lock 1.737 + jthread *jthreads = new_jthreadArray(nthreads, thread_objs); 1.738 + NULL_CHECK(jthreads, JVMTI_ERROR_OUT_OF_MEMORY); 1.739 + 1.740 + *threads_ptr = jthreads; 1.741 + return JVMTI_ERROR_NONE; 1.742 +} /* end GetAllThreads */ 1.743 + 1.744 + 1.745 +// Threads_lock NOT held, java_thread not protected by lock 1.746 +// java_thread - pre-checked 1.747 +jvmtiError 1.748 +JvmtiEnv::SuspendThread(JavaThread* java_thread) { 1.749 + // don't allow hidden thread suspend request. 1.750 + if (java_thread->is_hidden_from_external_view()) { 1.751 + return (JVMTI_ERROR_NONE); 1.752 + } 1.753 + 1.754 + { 1.755 + MutexLockerEx ml(java_thread->SR_lock(), Mutex::_no_safepoint_check_flag); 1.756 + if (java_thread->is_external_suspend()) { 1.757 + // don't allow nested external suspend requests. 1.758 + return (JVMTI_ERROR_THREAD_SUSPENDED); 1.759 + } 1.760 + if (java_thread->is_exiting()) { // thread is in the process of exiting 1.761 + return (JVMTI_ERROR_THREAD_NOT_ALIVE); 1.762 + } 1.763 + java_thread->set_external_suspend(); 1.764 + } 1.765 + 1.766 + if (!JvmtiSuspendControl::suspend(java_thread)) { 1.767 + // the thread was in the process of exiting 1.768 + return (JVMTI_ERROR_THREAD_NOT_ALIVE); 1.769 + } 1.770 + return JVMTI_ERROR_NONE; 1.771 +} /* end SuspendThread */ 1.772 + 1.773 + 1.774 +// request_count - pre-checked to be greater than or equal to 0 1.775 +// request_list - pre-checked for NULL 1.776 +// results - pre-checked for NULL 1.777 +jvmtiError 1.778 +JvmtiEnv::SuspendThreadList(jint request_count, const jthread* request_list, jvmtiError* results) { 1.779 + int needSafepoint = 0; // > 0 if we need a safepoint 1.780 + for (int i = 0; i < request_count; i++) { 1.781 + JavaThread *java_thread = get_JavaThread(request_list[i]); 1.782 + if (java_thread == NULL) { 1.783 + results[i] = JVMTI_ERROR_INVALID_THREAD; 1.784 + continue; 1.785 + } 1.786 + // the thread has not yet run or has exited (not on threads list) 1.787 + if (java_thread->threadObj() == NULL) { 1.788 + results[i] = JVMTI_ERROR_THREAD_NOT_ALIVE; 1.789 + continue; 1.790 + } 1.791 + if (java_lang_Thread::thread(java_thread->threadObj()) == NULL) { 1.792 + results[i] = JVMTI_ERROR_THREAD_NOT_ALIVE; 1.793 + continue; 1.794 + } 1.795 + // don't allow hidden thread suspend request. 1.796 + if (java_thread->is_hidden_from_external_view()) { 1.797 + results[i] = JVMTI_ERROR_NONE; // indicate successful suspend 1.798 + continue; 1.799 + } 1.800 + 1.801 + { 1.802 + MutexLockerEx ml(java_thread->SR_lock(), Mutex::_no_safepoint_check_flag); 1.803 + if (java_thread->is_external_suspend()) { 1.804 + // don't allow nested external suspend requests. 1.805 + results[i] = JVMTI_ERROR_THREAD_SUSPENDED; 1.806 + continue; 1.807 + } 1.808 + if (java_thread->is_exiting()) { // thread is in the process of exiting 1.809 + results[i] = JVMTI_ERROR_THREAD_NOT_ALIVE; 1.810 + continue; 1.811 + } 1.812 + java_thread->set_external_suspend(); 1.813 + } 1.814 + if (java_thread->thread_state() == _thread_in_native) { 1.815 + // We need to try and suspend native threads here. Threads in 1.816 + // other states will self-suspend on their next transition. 1.817 + if (!JvmtiSuspendControl::suspend(java_thread)) { 1.818 + // The thread was in the process of exiting. Force another 1.819 + // safepoint to make sure that this thread transitions. 1.820 + needSafepoint++; 1.821 + results[i] = JVMTI_ERROR_THREAD_NOT_ALIVE; 1.822 + continue; 1.823 + } 1.824 + } else { 1.825 + needSafepoint++; 1.826 + } 1.827 + results[i] = JVMTI_ERROR_NONE; // indicate successful suspend 1.828 + } 1.829 + if (needSafepoint > 0) { 1.830 + VM_ForceSafepoint vfs; 1.831 + VMThread::execute(&vfs); 1.832 + } 1.833 + // per-thread suspend results returned via results parameter 1.834 + return JVMTI_ERROR_NONE; 1.835 +} /* end SuspendThreadList */ 1.836 + 1.837 + 1.838 +// Threads_lock NOT held, java_thread not protected by lock 1.839 +// java_thread - pre-checked 1.840 +jvmtiError 1.841 +JvmtiEnv::ResumeThread(JavaThread* java_thread) { 1.842 + // don't allow hidden thread resume request. 1.843 + if (java_thread->is_hidden_from_external_view()) { 1.844 + return JVMTI_ERROR_NONE; 1.845 + } 1.846 + 1.847 + if (!java_thread->is_being_ext_suspended()) { 1.848 + return JVMTI_ERROR_THREAD_NOT_SUSPENDED; 1.849 + } 1.850 + 1.851 + if (!JvmtiSuspendControl::resume(java_thread)) { 1.852 + return JVMTI_ERROR_INTERNAL; 1.853 + } 1.854 + return JVMTI_ERROR_NONE; 1.855 +} /* end ResumeThread */ 1.856 + 1.857 + 1.858 +// request_count - pre-checked to be greater than or equal to 0 1.859 +// request_list - pre-checked for NULL 1.860 +// results - pre-checked for NULL 1.861 +jvmtiError 1.862 +JvmtiEnv::ResumeThreadList(jint request_count, const jthread* request_list, jvmtiError* results) { 1.863 + for (int i = 0; i < request_count; i++) { 1.864 + JavaThread *java_thread = get_JavaThread(request_list[i]); 1.865 + if (java_thread == NULL) { 1.866 + results[i] = JVMTI_ERROR_INVALID_THREAD; 1.867 + continue; 1.868 + } 1.869 + // don't allow hidden thread resume request. 1.870 + if (java_thread->is_hidden_from_external_view()) { 1.871 + results[i] = JVMTI_ERROR_NONE; // indicate successful resume 1.872 + continue; 1.873 + } 1.874 + if (!java_thread->is_being_ext_suspended()) { 1.875 + results[i] = JVMTI_ERROR_THREAD_NOT_SUSPENDED; 1.876 + continue; 1.877 + } 1.878 + 1.879 + if (!JvmtiSuspendControl::resume(java_thread)) { 1.880 + results[i] = JVMTI_ERROR_INTERNAL; 1.881 + continue; 1.882 + } 1.883 + 1.884 + results[i] = JVMTI_ERROR_NONE; // indicate successful suspend 1.885 + } 1.886 + // per-thread resume results returned via results parameter 1.887 + return JVMTI_ERROR_NONE; 1.888 +} /* end ResumeThreadList */ 1.889 + 1.890 + 1.891 +// Threads_lock NOT held, java_thread not protected by lock 1.892 +// java_thread - pre-checked 1.893 +jvmtiError 1.894 +JvmtiEnv::StopThread(JavaThread* java_thread, jobject exception) { 1.895 + oop e = JNIHandles::resolve_external_guard(exception); 1.896 + NULL_CHECK(e, JVMTI_ERROR_NULL_POINTER); 1.897 + 1.898 + JavaThread::send_async_exception(java_thread->threadObj(), e); 1.899 + 1.900 + return JVMTI_ERROR_NONE; 1.901 + 1.902 +} /* end StopThread */ 1.903 + 1.904 + 1.905 +// Threads_lock NOT held 1.906 +// thread - NOT pre-checked 1.907 +jvmtiError 1.908 +JvmtiEnv::InterruptThread(jthread thread) { 1.909 + oop thread_oop = JNIHandles::resolve_external_guard(thread); 1.910 + if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::Thread_klass())) 1.911 + return JVMTI_ERROR_INVALID_THREAD; 1.912 + 1.913 + JavaThread* current_thread = JavaThread::current(); 1.914 + 1.915 + // Todo: this is a duplicate of JVM_Interrupt; share code in future 1.916 + // Ensure that the C++ Thread and OSThread structures aren't freed before we operate 1.917 + MutexLockerEx ml(current_thread->threadObj() == thread_oop ? NULL : Threads_lock); 1.918 + // We need to re-resolve the java_thread, since a GC might have happened during the 1.919 + // acquire of the lock 1.920 + 1.921 + JavaThread* java_thread = java_lang_Thread::thread(JNIHandles::resolve_external_guard(thread)); 1.922 + NULL_CHECK(java_thread, JVMTI_ERROR_THREAD_NOT_ALIVE); 1.923 + 1.924 + Thread::interrupt(java_thread); 1.925 + 1.926 + return JVMTI_ERROR_NONE; 1.927 +} /* end InterruptThread */ 1.928 + 1.929 + 1.930 +// Threads_lock NOT held 1.931 +// thread - NOT pre-checked 1.932 +// info_ptr - pre-checked for NULL 1.933 +jvmtiError 1.934 +JvmtiEnv::GetThreadInfo(jthread thread, jvmtiThreadInfo* info_ptr) { 1.935 + ResourceMark rm; 1.936 + HandleMark hm; 1.937 + 1.938 + JavaThread* current_thread = JavaThread::current(); 1.939 + 1.940 + // if thread is NULL the current thread is used 1.941 + oop thread_oop; 1.942 + if (thread == NULL) { 1.943 + thread_oop = current_thread->threadObj(); 1.944 + } else { 1.945 + thread_oop = JNIHandles::resolve_external_guard(thread); 1.946 + } 1.947 + if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::Thread_klass())) 1.948 + return JVMTI_ERROR_INVALID_THREAD; 1.949 + 1.950 + Handle thread_obj(current_thread, thread_oop); 1.951 + typeArrayHandle name; 1.952 + ThreadPriority priority; 1.953 + Handle thread_group; 1.954 + Handle context_class_loader; 1.955 + bool is_daemon; 1.956 + 1.957 + { MutexLocker mu(Threads_lock); 1.958 + 1.959 + name = typeArrayHandle(current_thread, java_lang_Thread::name(thread_obj())); 1.960 + priority = java_lang_Thread::priority(thread_obj()); 1.961 + thread_group = Handle(current_thread, java_lang_Thread::threadGroup(thread_obj())); 1.962 + is_daemon = java_lang_Thread::is_daemon(thread_obj()); 1.963 + 1.964 + oop loader = java_lang_Thread::context_class_loader(thread_obj()); 1.965 + context_class_loader = Handle(current_thread, loader); 1.966 + } 1.967 + { const char *n; 1.968 + 1.969 + if (name() != NULL) { 1.970 + n = UNICODE::as_utf8((jchar*) name->base(T_CHAR), name->length()); 1.971 + } else { 1.972 + n = UNICODE::as_utf8(NULL, 0); 1.973 + } 1.974 + 1.975 + info_ptr->name = (char *) jvmtiMalloc(strlen(n)+1); 1.976 + if (info_ptr->name == NULL) 1.977 + return JVMTI_ERROR_OUT_OF_MEMORY; 1.978 + 1.979 + strcpy(info_ptr->name, n); 1.980 + } 1.981 + info_ptr->is_daemon = is_daemon; 1.982 + info_ptr->priority = priority; 1.983 + 1.984 + info_ptr->context_class_loader = (context_class_loader.is_null()) ? NULL : 1.985 + jni_reference(context_class_loader); 1.986 + info_ptr->thread_group = jni_reference(thread_group); 1.987 + 1.988 + return JVMTI_ERROR_NONE; 1.989 +} /* end GetThreadInfo */ 1.990 + 1.991 + 1.992 +// Threads_lock NOT held, java_thread not protected by lock 1.993 +// java_thread - pre-checked 1.994 +// owned_monitor_count_ptr - pre-checked for NULL 1.995 +// owned_monitors_ptr - pre-checked for NULL 1.996 +jvmtiError 1.997 +JvmtiEnv::GetOwnedMonitorInfo(JavaThread* java_thread, jint* owned_monitor_count_ptr, jobject** owned_monitors_ptr) { 1.998 + jvmtiError err = JVMTI_ERROR_NONE; 1.999 + JavaThread* calling_thread = JavaThread::current(); 1.1000 + 1.1001 + // growable array of jvmti monitors info on the C-heap 1.1002 + GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list = 1.1003 + new (ResourceObj::C_HEAP, mtInternal) GrowableArray<jvmtiMonitorStackDepthInfo*>(1, true); 1.1004 + 1.1005 + uint32_t debug_bits = 0; 1.1006 + if (is_thread_fully_suspended(java_thread, true, &debug_bits)) { 1.1007 + err = get_owned_monitors(calling_thread, java_thread, owned_monitors_list); 1.1008 + } else { 1.1009 + // JVMTI get monitors info at safepoint. Do not require target thread to 1.1010 + // be suspended. 1.1011 + VM_GetOwnedMonitorInfo op(this, calling_thread, java_thread, owned_monitors_list); 1.1012 + VMThread::execute(&op); 1.1013 + err = op.result(); 1.1014 + } 1.1015 + jint owned_monitor_count = owned_monitors_list->length(); 1.1016 + if (err == JVMTI_ERROR_NONE) { 1.1017 + if ((err = allocate(owned_monitor_count * sizeof(jobject *), 1.1018 + (unsigned char**)owned_monitors_ptr)) == JVMTI_ERROR_NONE) { 1.1019 + // copy into the returned array 1.1020 + for (int i = 0; i < owned_monitor_count; i++) { 1.1021 + (*owned_monitors_ptr)[i] = 1.1022 + ((jvmtiMonitorStackDepthInfo*)owned_monitors_list->at(i))->monitor; 1.1023 + } 1.1024 + *owned_monitor_count_ptr = owned_monitor_count; 1.1025 + } 1.1026 + } 1.1027 + // clean up. 1.1028 + for (int i = 0; i < owned_monitor_count; i++) { 1.1029 + deallocate((unsigned char*)owned_monitors_list->at(i)); 1.1030 + } 1.1031 + delete owned_monitors_list; 1.1032 + 1.1033 + return err; 1.1034 +} /* end GetOwnedMonitorInfo */ 1.1035 + 1.1036 + 1.1037 +// Threads_lock NOT held, java_thread not protected by lock 1.1038 +// java_thread - pre-checked 1.1039 +// monitor_info_count_ptr - pre-checked for NULL 1.1040 +// monitor_info_ptr - pre-checked for NULL 1.1041 +jvmtiError 1.1042 +JvmtiEnv::GetOwnedMonitorStackDepthInfo(JavaThread* java_thread, jint* monitor_info_count_ptr, jvmtiMonitorStackDepthInfo** monitor_info_ptr) { 1.1043 + jvmtiError err = JVMTI_ERROR_NONE; 1.1044 + JavaThread* calling_thread = JavaThread::current(); 1.1045 + 1.1046 + // growable array of jvmti monitors info on the C-heap 1.1047 + GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list = 1.1048 + new (ResourceObj::C_HEAP, mtInternal) GrowableArray<jvmtiMonitorStackDepthInfo*>(1, true); 1.1049 + 1.1050 + uint32_t debug_bits = 0; 1.1051 + if (is_thread_fully_suspended(java_thread, true, &debug_bits)) { 1.1052 + err = get_owned_monitors(calling_thread, java_thread, owned_monitors_list); 1.1053 + } else { 1.1054 + // JVMTI get owned monitors info at safepoint. Do not require target thread to 1.1055 + // be suspended. 1.1056 + VM_GetOwnedMonitorInfo op(this, calling_thread, java_thread, owned_monitors_list); 1.1057 + VMThread::execute(&op); 1.1058 + err = op.result(); 1.1059 + } 1.1060 + 1.1061 + jint owned_monitor_count = owned_monitors_list->length(); 1.1062 + if (err == JVMTI_ERROR_NONE) { 1.1063 + if ((err = allocate(owned_monitor_count * sizeof(jvmtiMonitorStackDepthInfo), 1.1064 + (unsigned char**)monitor_info_ptr)) == JVMTI_ERROR_NONE) { 1.1065 + // copy to output array. 1.1066 + for (int i = 0; i < owned_monitor_count; i++) { 1.1067 + (*monitor_info_ptr)[i].monitor = 1.1068 + ((jvmtiMonitorStackDepthInfo*)owned_monitors_list->at(i))->monitor; 1.1069 + (*monitor_info_ptr)[i].stack_depth = 1.1070 + ((jvmtiMonitorStackDepthInfo*)owned_monitors_list->at(i))->stack_depth; 1.1071 + } 1.1072 + } 1.1073 + *monitor_info_count_ptr = owned_monitor_count; 1.1074 + } 1.1075 + 1.1076 + // clean up. 1.1077 + for (int i = 0; i < owned_monitor_count; i++) { 1.1078 + deallocate((unsigned char*)owned_monitors_list->at(i)); 1.1079 + } 1.1080 + delete owned_monitors_list; 1.1081 + 1.1082 + return err; 1.1083 +} /* end GetOwnedMonitorStackDepthInfo */ 1.1084 + 1.1085 + 1.1086 +// Threads_lock NOT held, java_thread not protected by lock 1.1087 +// java_thread - pre-checked 1.1088 +// monitor_ptr - pre-checked for NULL 1.1089 +jvmtiError 1.1090 +JvmtiEnv::GetCurrentContendedMonitor(JavaThread* java_thread, jobject* monitor_ptr) { 1.1091 + jvmtiError err = JVMTI_ERROR_NONE; 1.1092 + uint32_t debug_bits = 0; 1.1093 + JavaThread* calling_thread = JavaThread::current(); 1.1094 + if (is_thread_fully_suspended(java_thread, true, &debug_bits)) { 1.1095 + err = get_current_contended_monitor(calling_thread, java_thread, monitor_ptr); 1.1096 + } else { 1.1097 + // get contended monitor information at safepoint. 1.1098 + VM_GetCurrentContendedMonitor op(this, calling_thread, java_thread, monitor_ptr); 1.1099 + VMThread::execute(&op); 1.1100 + err = op.result(); 1.1101 + } 1.1102 + return err; 1.1103 +} /* end GetCurrentContendedMonitor */ 1.1104 + 1.1105 + 1.1106 +// Threads_lock NOT held 1.1107 +// thread - NOT pre-checked 1.1108 +// proc - pre-checked for NULL 1.1109 +// arg - NULL is a valid value, must be checked 1.1110 +jvmtiError 1.1111 +JvmtiEnv::RunAgentThread(jthread thread, jvmtiStartFunction proc, const void* arg, jint priority) { 1.1112 + oop thread_oop = JNIHandles::resolve_external_guard(thread); 1.1113 + if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::Thread_klass())) { 1.1114 + return JVMTI_ERROR_INVALID_THREAD; 1.1115 + } 1.1116 + if (priority < JVMTI_THREAD_MIN_PRIORITY || priority > JVMTI_THREAD_MAX_PRIORITY) { 1.1117 + return JVMTI_ERROR_INVALID_PRIORITY; 1.1118 + } 1.1119 + 1.1120 + //Thread-self 1.1121 + JavaThread* current_thread = JavaThread::current(); 1.1122 + 1.1123 + Handle thread_hndl(current_thread, thread_oop); 1.1124 + { 1.1125 + MutexLocker mu(Threads_lock); // grab Threads_lock 1.1126 + 1.1127 + JvmtiAgentThread *new_thread = new JvmtiAgentThread(this, proc, arg); 1.1128 + 1.1129 + // At this point it may be possible that no osthread was created for the 1.1130 + // JavaThread due to lack of memory. 1.1131 + if (new_thread == NULL || new_thread->osthread() == NULL) { 1.1132 + if (new_thread) delete new_thread; 1.1133 + return JVMTI_ERROR_OUT_OF_MEMORY; 1.1134 + } 1.1135 + 1.1136 + java_lang_Thread::set_thread(thread_hndl(), new_thread); 1.1137 + java_lang_Thread::set_priority(thread_hndl(), (ThreadPriority)priority); 1.1138 + java_lang_Thread::set_daemon(thread_hndl()); 1.1139 + 1.1140 + new_thread->set_threadObj(thread_hndl()); 1.1141 + Threads::add(new_thread); 1.1142 + Thread::start(new_thread); 1.1143 + } // unlock Threads_lock 1.1144 + 1.1145 + return JVMTI_ERROR_NONE; 1.1146 +} /* end RunAgentThread */ 1.1147 + 1.1148 + // 1.1149 + // Thread Group functions 1.1150 + // 1.1151 + 1.1152 +// group_count_ptr - pre-checked for NULL 1.1153 +// groups_ptr - pre-checked for NULL 1.1154 +jvmtiError 1.1155 +JvmtiEnv::GetTopThreadGroups(jint* group_count_ptr, jthreadGroup** groups_ptr) { 1.1156 + JavaThread* current_thread = JavaThread::current(); 1.1157 + 1.1158 + // Only one top level thread group now. 1.1159 + *group_count_ptr = 1; 1.1160 + 1.1161 + // Allocate memory to store global-refs to the thread groups. 1.1162 + // Assume this area is freed by caller. 1.1163 + *groups_ptr = (jthreadGroup *) jvmtiMalloc((sizeof(jthreadGroup)) * (*group_count_ptr)); 1.1164 + 1.1165 + NULL_CHECK(*groups_ptr, JVMTI_ERROR_OUT_OF_MEMORY); 1.1166 + 1.1167 + // Convert oop to Handle, then convert Handle to global-ref. 1.1168 + { 1.1169 + HandleMark hm(current_thread); 1.1170 + Handle system_thread_group(current_thread, Universe::system_thread_group()); 1.1171 + *groups_ptr[0] = jni_reference(system_thread_group); 1.1172 + } 1.1173 + 1.1174 + return JVMTI_ERROR_NONE; 1.1175 +} /* end GetTopThreadGroups */ 1.1176 + 1.1177 + 1.1178 +// info_ptr - pre-checked for NULL 1.1179 +jvmtiError 1.1180 +JvmtiEnv::GetThreadGroupInfo(jthreadGroup group, jvmtiThreadGroupInfo* info_ptr) { 1.1181 + ResourceMark rm; 1.1182 + HandleMark hm; 1.1183 + 1.1184 + JavaThread* current_thread = JavaThread::current(); 1.1185 + 1.1186 + Handle group_obj (current_thread, JNIHandles::resolve_external_guard(group)); 1.1187 + NULL_CHECK(group_obj(), JVMTI_ERROR_INVALID_THREAD_GROUP); 1.1188 + 1.1189 + typeArrayHandle name; 1.1190 + Handle parent_group; 1.1191 + bool is_daemon; 1.1192 + ThreadPriority max_priority; 1.1193 + 1.1194 + { MutexLocker mu(Threads_lock); 1.1195 + 1.1196 + name = typeArrayHandle(current_thread, 1.1197 + java_lang_ThreadGroup::name(group_obj())); 1.1198 + parent_group = Handle(current_thread, java_lang_ThreadGroup::parent(group_obj())); 1.1199 + is_daemon = java_lang_ThreadGroup::is_daemon(group_obj()); 1.1200 + max_priority = java_lang_ThreadGroup::maxPriority(group_obj()); 1.1201 + } 1.1202 + 1.1203 + info_ptr->is_daemon = is_daemon; 1.1204 + info_ptr->max_priority = max_priority; 1.1205 + info_ptr->parent = jni_reference(parent_group); 1.1206 + 1.1207 + if (name() != NULL) { 1.1208 + const char* n = UNICODE::as_utf8((jchar*) name->base(T_CHAR), name->length()); 1.1209 + info_ptr->name = (char *)jvmtiMalloc(strlen(n)+1); 1.1210 + NULL_CHECK(info_ptr->name, JVMTI_ERROR_OUT_OF_MEMORY); 1.1211 + strcpy(info_ptr->name, n); 1.1212 + } else { 1.1213 + info_ptr->name = NULL; 1.1214 + } 1.1215 + 1.1216 + return JVMTI_ERROR_NONE; 1.1217 +} /* end GetThreadGroupInfo */ 1.1218 + 1.1219 + 1.1220 +// thread_count_ptr - pre-checked for NULL 1.1221 +// threads_ptr - pre-checked for NULL 1.1222 +// group_count_ptr - pre-checked for NULL 1.1223 +// groups_ptr - pre-checked for NULL 1.1224 +jvmtiError 1.1225 +JvmtiEnv::GetThreadGroupChildren(jthreadGroup group, jint* thread_count_ptr, jthread** threads_ptr, jint* group_count_ptr, jthreadGroup** groups_ptr) { 1.1226 + JavaThread* current_thread = JavaThread::current(); 1.1227 + oop group_obj = (oop) JNIHandles::resolve_external_guard(group); 1.1228 + NULL_CHECK(group_obj, JVMTI_ERROR_INVALID_THREAD_GROUP); 1.1229 + 1.1230 + Handle *thread_objs = NULL; 1.1231 + Handle *group_objs = NULL; 1.1232 + int nthreads = 0; 1.1233 + int ngroups = 0; 1.1234 + int hidden_threads = 0; 1.1235 + 1.1236 + ResourceMark rm; 1.1237 + HandleMark hm; 1.1238 + 1.1239 + Handle group_hdl(current_thread, group_obj); 1.1240 + 1.1241 + { MutexLocker mu(Threads_lock); 1.1242 + 1.1243 + nthreads = java_lang_ThreadGroup::nthreads(group_hdl()); 1.1244 + ngroups = java_lang_ThreadGroup::ngroups(group_hdl()); 1.1245 + 1.1246 + if (nthreads > 0) { 1.1247 + objArrayOop threads = java_lang_ThreadGroup::threads(group_hdl()); 1.1248 + assert(nthreads <= threads->length(), "too many threads"); 1.1249 + thread_objs = NEW_RESOURCE_ARRAY(Handle,nthreads); 1.1250 + for (int i=0, j=0; i<nthreads; i++) { 1.1251 + oop thread_obj = threads->obj_at(i); 1.1252 + assert(thread_obj != NULL, "thread_obj is NULL"); 1.1253 + JavaThread *javathread = java_lang_Thread::thread(thread_obj); 1.1254 + // Filter out hidden java threads. 1.1255 + if (javathread != NULL && javathread->is_hidden_from_external_view()) { 1.1256 + hidden_threads++; 1.1257 + continue; 1.1258 + } 1.1259 + thread_objs[j++] = Handle(current_thread, thread_obj); 1.1260 + } 1.1261 + nthreads -= hidden_threads; 1.1262 + } 1.1263 + if (ngroups > 0) { 1.1264 + objArrayOop groups = java_lang_ThreadGroup::groups(group_hdl()); 1.1265 + assert(ngroups <= groups->length(), "too many threads"); 1.1266 + group_objs = NEW_RESOURCE_ARRAY(Handle,ngroups); 1.1267 + for (int i=0; i<ngroups; i++) { 1.1268 + oop group_obj = groups->obj_at(i); 1.1269 + assert(group_obj != NULL, "group_obj != NULL"); 1.1270 + group_objs[i] = Handle(current_thread, group_obj); 1.1271 + } 1.1272 + } 1.1273 + } 1.1274 + 1.1275 + // have to make global handles outside of Threads_lock 1.1276 + *group_count_ptr = ngroups; 1.1277 + *thread_count_ptr = nthreads; 1.1278 + *threads_ptr = new_jthreadArray(nthreads, thread_objs); 1.1279 + *groups_ptr = new_jthreadGroupArray(ngroups, group_objs); 1.1280 + if ((nthreads > 0) && (*threads_ptr == NULL)) { 1.1281 + return JVMTI_ERROR_OUT_OF_MEMORY; 1.1282 + } 1.1283 + if ((ngroups > 0) && (*groups_ptr == NULL)) { 1.1284 + return JVMTI_ERROR_OUT_OF_MEMORY; 1.1285 + } 1.1286 + 1.1287 + return JVMTI_ERROR_NONE; 1.1288 +} /* end GetThreadGroupChildren */ 1.1289 + 1.1290 + 1.1291 + // 1.1292 + // Stack Frame functions 1.1293 + // 1.1294 + 1.1295 +// Threads_lock NOT held, java_thread not protected by lock 1.1296 +// java_thread - pre-checked 1.1297 +// max_frame_count - pre-checked to be greater than or equal to 0 1.1298 +// frame_buffer - pre-checked for NULL 1.1299 +// count_ptr - pre-checked for NULL 1.1300 +jvmtiError 1.1301 +JvmtiEnv::GetStackTrace(JavaThread* java_thread, jint start_depth, jint max_frame_count, jvmtiFrameInfo* frame_buffer, jint* count_ptr) { 1.1302 + jvmtiError err = JVMTI_ERROR_NONE; 1.1303 + uint32_t debug_bits = 0; 1.1304 + if (is_thread_fully_suspended(java_thread, true, &debug_bits)) { 1.1305 + err = get_stack_trace(java_thread, start_depth, max_frame_count, frame_buffer, count_ptr); 1.1306 + } else { 1.1307 + // JVMTI get stack trace at safepoint. Do not require target thread to 1.1308 + // be suspended. 1.1309 + VM_GetStackTrace op(this, java_thread, start_depth, max_frame_count, frame_buffer, count_ptr); 1.1310 + VMThread::execute(&op); 1.1311 + err = op.result(); 1.1312 + } 1.1313 + 1.1314 + return err; 1.1315 +} /* end GetStackTrace */ 1.1316 + 1.1317 + 1.1318 +// max_frame_count - pre-checked to be greater than or equal to 0 1.1319 +// stack_info_ptr - pre-checked for NULL 1.1320 +// thread_count_ptr - pre-checked for NULL 1.1321 +jvmtiError 1.1322 +JvmtiEnv::GetAllStackTraces(jint max_frame_count, jvmtiStackInfo** stack_info_ptr, jint* thread_count_ptr) { 1.1323 + jvmtiError err = JVMTI_ERROR_NONE; 1.1324 + JavaThread* calling_thread = JavaThread::current(); 1.1325 + 1.1326 + // JVMTI get stack traces at safepoint. 1.1327 + VM_GetAllStackTraces op(this, calling_thread, max_frame_count); 1.1328 + VMThread::execute(&op); 1.1329 + *thread_count_ptr = op.final_thread_count(); 1.1330 + *stack_info_ptr = op.stack_info(); 1.1331 + err = op.result(); 1.1332 + return err; 1.1333 +} /* end GetAllStackTraces */ 1.1334 + 1.1335 + 1.1336 +// thread_count - pre-checked to be greater than or equal to 0 1.1337 +// thread_list - pre-checked for NULL 1.1338 +// max_frame_count - pre-checked to be greater than or equal to 0 1.1339 +// stack_info_ptr - pre-checked for NULL 1.1340 +jvmtiError 1.1341 +JvmtiEnv::GetThreadListStackTraces(jint thread_count, const jthread* thread_list, jint max_frame_count, jvmtiStackInfo** stack_info_ptr) { 1.1342 + jvmtiError err = JVMTI_ERROR_NONE; 1.1343 + // JVMTI get stack traces at safepoint. 1.1344 + VM_GetThreadListStackTraces op(this, thread_count, thread_list, max_frame_count); 1.1345 + VMThread::execute(&op); 1.1346 + err = op.result(); 1.1347 + if (err == JVMTI_ERROR_NONE) { 1.1348 + *stack_info_ptr = op.stack_info(); 1.1349 + } 1.1350 + return err; 1.1351 +} /* end GetThreadListStackTraces */ 1.1352 + 1.1353 + 1.1354 +// Threads_lock NOT held, java_thread not protected by lock 1.1355 +// java_thread - pre-checked 1.1356 +// count_ptr - pre-checked for NULL 1.1357 +jvmtiError 1.1358 +JvmtiEnv::GetFrameCount(JavaThread* java_thread, jint* count_ptr) { 1.1359 + jvmtiError err = JVMTI_ERROR_NONE; 1.1360 + 1.1361 + // retrieve or create JvmtiThreadState. 1.1362 + JvmtiThreadState* state = JvmtiThreadState::state_for(java_thread); 1.1363 + if (state == NULL) { 1.1364 + return JVMTI_ERROR_THREAD_NOT_ALIVE; 1.1365 + } 1.1366 + uint32_t debug_bits = 0; 1.1367 + if (is_thread_fully_suspended(java_thread, true, &debug_bits)) { 1.1368 + err = get_frame_count(state, count_ptr); 1.1369 + } else { 1.1370 + // get java stack frame count at safepoint. 1.1371 + VM_GetFrameCount op(this, state, count_ptr); 1.1372 + VMThread::execute(&op); 1.1373 + err = op.result(); 1.1374 + } 1.1375 + return err; 1.1376 +} /* end GetFrameCount */ 1.1377 + 1.1378 + 1.1379 +// Threads_lock NOT held, java_thread not protected by lock 1.1380 +// java_thread - pre-checked 1.1381 +jvmtiError 1.1382 +JvmtiEnv::PopFrame(JavaThread* java_thread) { 1.1383 + JavaThread* current_thread = JavaThread::current(); 1.1384 + HandleMark hm(current_thread); 1.1385 + uint32_t debug_bits = 0; 1.1386 + 1.1387 + // retrieve or create the state 1.1388 + JvmtiThreadState* state = JvmtiThreadState::state_for(java_thread); 1.1389 + if (state == NULL) { 1.1390 + return JVMTI_ERROR_THREAD_NOT_ALIVE; 1.1391 + } 1.1392 + 1.1393 + // Check if java_thread is fully suspended 1.1394 + if (!is_thread_fully_suspended(java_thread, true /* wait for suspend completion */, &debug_bits)) { 1.1395 + return JVMTI_ERROR_THREAD_NOT_SUSPENDED; 1.1396 + } 1.1397 + // Check to see if a PopFrame was already in progress 1.1398 + if (java_thread->popframe_condition() != JavaThread::popframe_inactive) { 1.1399 + // Probably possible for JVMTI clients to trigger this, but the 1.1400 + // JPDA backend shouldn't allow this to happen 1.1401 + return JVMTI_ERROR_INTERNAL; 1.1402 + } 1.1403 + 1.1404 + { 1.1405 + // Was workaround bug 1.1406 + // 4812902: popFrame hangs if the method is waiting at a synchronize 1.1407 + // Catch this condition and return an error to avoid hanging. 1.1408 + // Now JVMTI spec allows an implementation to bail out with an opaque frame error. 1.1409 + OSThread* osThread = java_thread->osthread(); 1.1410 + if (osThread->get_state() == MONITOR_WAIT) { 1.1411 + return JVMTI_ERROR_OPAQUE_FRAME; 1.1412 + } 1.1413 + } 1.1414 + 1.1415 + { 1.1416 + ResourceMark rm(current_thread); 1.1417 + // Check if there are more than one Java frame in this thread, that the top two frames 1.1418 + // are Java (not native) frames, and that there is no intervening VM frame 1.1419 + int frame_count = 0; 1.1420 + bool is_interpreted[2]; 1.1421 + intptr_t *frame_sp[2]; 1.1422 + // The 2-nd arg of constructor is needed to stop iterating at java entry frame. 1.1423 + for (vframeStream vfs(java_thread, true); !vfs.at_end(); vfs.next()) { 1.1424 + methodHandle mh(current_thread, vfs.method()); 1.1425 + if (mh->is_native()) return(JVMTI_ERROR_OPAQUE_FRAME); 1.1426 + is_interpreted[frame_count] = vfs.is_interpreted_frame(); 1.1427 + frame_sp[frame_count] = vfs.frame_id(); 1.1428 + if (++frame_count > 1) break; 1.1429 + } 1.1430 + if (frame_count < 2) { 1.1431 + // We haven't found two adjacent non-native Java frames on the top. 1.1432 + // There can be two situations here: 1.1433 + // 1. There are no more java frames 1.1434 + // 2. Two top java frames are separated by non-java native frames 1.1435 + if(vframeFor(java_thread, 1) == NULL) { 1.1436 + return JVMTI_ERROR_NO_MORE_FRAMES; 1.1437 + } else { 1.1438 + // Intervening non-java native or VM frames separate java frames. 1.1439 + // Current implementation does not support this. See bug #5031735. 1.1440 + // In theory it is possible to pop frames in such cases. 1.1441 + return JVMTI_ERROR_OPAQUE_FRAME; 1.1442 + } 1.1443 + } 1.1444 + 1.1445 + // If any of the top 2 frames is a compiled one, need to deoptimize it 1.1446 + for (int i = 0; i < 2; i++) { 1.1447 + if (!is_interpreted[i]) { 1.1448 + Deoptimization::deoptimize_frame(java_thread, frame_sp[i]); 1.1449 + } 1.1450 + } 1.1451 + 1.1452 + // Update the thread state to reflect that the top frame is popped 1.1453 + // so that cur_stack_depth is maintained properly and all frameIDs 1.1454 + // are invalidated. 1.1455 + // The current frame will be popped later when the suspended thread 1.1456 + // is resumed and right before returning from VM to Java. 1.1457 + // (see call_VM_base() in assembler_<cpu>.cpp). 1.1458 + 1.1459 + // It's fine to update the thread state here because no JVMTI events 1.1460 + // shall be posted for this PopFrame. 1.1461 + 1.1462 + state->update_for_pop_top_frame(); 1.1463 + java_thread->set_popframe_condition(JavaThread::popframe_pending_bit); 1.1464 + // Set pending step flag for this popframe and it is cleared when next 1.1465 + // step event is posted. 1.1466 + state->set_pending_step_for_popframe(); 1.1467 + } 1.1468 + 1.1469 + return JVMTI_ERROR_NONE; 1.1470 +} /* end PopFrame */ 1.1471 + 1.1472 + 1.1473 +// Threads_lock NOT held, java_thread not protected by lock 1.1474 +// java_thread - pre-checked 1.1475 +// java_thread - unchecked 1.1476 +// depth - pre-checked as non-negative 1.1477 +// method_ptr - pre-checked for NULL 1.1478 +// location_ptr - pre-checked for NULL 1.1479 +jvmtiError 1.1480 +JvmtiEnv::GetFrameLocation(JavaThread* java_thread, jint depth, jmethodID* method_ptr, jlocation* location_ptr) { 1.1481 + jvmtiError err = JVMTI_ERROR_NONE; 1.1482 + uint32_t debug_bits = 0; 1.1483 + 1.1484 + if (is_thread_fully_suspended(java_thread, true, &debug_bits)) { 1.1485 + err = get_frame_location(java_thread, depth, method_ptr, location_ptr); 1.1486 + } else { 1.1487 + // JVMTI get java stack frame location at safepoint. 1.1488 + VM_GetFrameLocation op(this, java_thread, depth, method_ptr, location_ptr); 1.1489 + VMThread::execute(&op); 1.1490 + err = op.result(); 1.1491 + } 1.1492 + return err; 1.1493 +} /* end GetFrameLocation */ 1.1494 + 1.1495 + 1.1496 +// Threads_lock NOT held, java_thread not protected by lock 1.1497 +// java_thread - pre-checked 1.1498 +// java_thread - unchecked 1.1499 +// depth - pre-checked as non-negative 1.1500 +jvmtiError 1.1501 +JvmtiEnv::NotifyFramePop(JavaThread* java_thread, jint depth) { 1.1502 + ResourceMark rm; 1.1503 + uint32_t debug_bits = 0; 1.1504 + 1.1505 + JvmtiThreadState *state = JvmtiThreadState::state_for(java_thread); 1.1506 + if (state == NULL) { 1.1507 + return JVMTI_ERROR_THREAD_NOT_ALIVE; 1.1508 + } 1.1509 + 1.1510 + if (!JvmtiEnv::is_thread_fully_suspended(java_thread, true, &debug_bits)) { 1.1511 + return JVMTI_ERROR_THREAD_NOT_SUSPENDED; 1.1512 + } 1.1513 + 1.1514 + if (TraceJVMTICalls) { 1.1515 + JvmtiSuspendControl::print(); 1.1516 + } 1.1517 + 1.1518 + vframe *vf = vframeFor(java_thread, depth); 1.1519 + if (vf == NULL) { 1.1520 + return JVMTI_ERROR_NO_MORE_FRAMES; 1.1521 + } 1.1522 + 1.1523 + if (!vf->is_java_frame() || ((javaVFrame*) vf)->method()->is_native()) { 1.1524 + return JVMTI_ERROR_OPAQUE_FRAME; 1.1525 + } 1.1526 + 1.1527 + assert(vf->frame_pointer() != NULL, "frame pointer mustn't be NULL"); 1.1528 + 1.1529 + int frame_number = state->count_frames() - depth; 1.1530 + state->env_thread_state(this)->set_frame_pop(frame_number); 1.1531 + 1.1532 + return JVMTI_ERROR_NONE; 1.1533 +} /* end NotifyFramePop */ 1.1534 + 1.1535 + 1.1536 + // 1.1537 + // Force Early Return functions 1.1538 + // 1.1539 + 1.1540 +// Threads_lock NOT held, java_thread not protected by lock 1.1541 +// java_thread - pre-checked 1.1542 +jvmtiError 1.1543 +JvmtiEnv::ForceEarlyReturnObject(JavaThread* java_thread, jobject value) { 1.1544 + jvalue val; 1.1545 + val.l = value; 1.1546 + return force_early_return(java_thread, val, atos); 1.1547 +} /* end ForceEarlyReturnObject */ 1.1548 + 1.1549 + 1.1550 +// Threads_lock NOT held, java_thread not protected by lock 1.1551 +// java_thread - pre-checked 1.1552 +jvmtiError 1.1553 +JvmtiEnv::ForceEarlyReturnInt(JavaThread* java_thread, jint value) { 1.1554 + jvalue val; 1.1555 + val.i = value; 1.1556 + return force_early_return(java_thread, val, itos); 1.1557 +} /* end ForceEarlyReturnInt */ 1.1558 + 1.1559 + 1.1560 +// Threads_lock NOT held, java_thread not protected by lock 1.1561 +// java_thread - pre-checked 1.1562 +jvmtiError 1.1563 +JvmtiEnv::ForceEarlyReturnLong(JavaThread* java_thread, jlong value) { 1.1564 + jvalue val; 1.1565 + val.j = value; 1.1566 + return force_early_return(java_thread, val, ltos); 1.1567 +} /* end ForceEarlyReturnLong */ 1.1568 + 1.1569 + 1.1570 +// Threads_lock NOT held, java_thread not protected by lock 1.1571 +// java_thread - pre-checked 1.1572 +jvmtiError 1.1573 +JvmtiEnv::ForceEarlyReturnFloat(JavaThread* java_thread, jfloat value) { 1.1574 + jvalue val; 1.1575 + val.f = value; 1.1576 + return force_early_return(java_thread, val, ftos); 1.1577 +} /* end ForceEarlyReturnFloat */ 1.1578 + 1.1579 + 1.1580 +// Threads_lock NOT held, java_thread not protected by lock 1.1581 +// java_thread - pre-checked 1.1582 +jvmtiError 1.1583 +JvmtiEnv::ForceEarlyReturnDouble(JavaThread* java_thread, jdouble value) { 1.1584 + jvalue val; 1.1585 + val.d = value; 1.1586 + return force_early_return(java_thread, val, dtos); 1.1587 +} /* end ForceEarlyReturnDouble */ 1.1588 + 1.1589 + 1.1590 +// Threads_lock NOT held, java_thread not protected by lock 1.1591 +// java_thread - pre-checked 1.1592 +jvmtiError 1.1593 +JvmtiEnv::ForceEarlyReturnVoid(JavaThread* java_thread) { 1.1594 + jvalue val; 1.1595 + val.j = 0L; 1.1596 + return force_early_return(java_thread, val, vtos); 1.1597 +} /* end ForceEarlyReturnVoid */ 1.1598 + 1.1599 + 1.1600 + // 1.1601 + // Heap functions 1.1602 + // 1.1603 + 1.1604 +// klass - NULL is a valid value, must be checked 1.1605 +// initial_object - NULL is a valid value, must be checked 1.1606 +// callbacks - pre-checked for NULL 1.1607 +// user_data - NULL is a valid value, must be checked 1.1608 +jvmtiError 1.1609 +JvmtiEnv::FollowReferences(jint heap_filter, jclass klass, jobject initial_object, const jvmtiHeapCallbacks* callbacks, const void* user_data) { 1.1610 + // check klass if provided 1.1611 + Klass* k_oop = NULL; 1.1612 + if (klass != NULL) { 1.1613 + oop k_mirror = JNIHandles::resolve_external_guard(klass); 1.1614 + if (k_mirror == NULL) { 1.1615 + return JVMTI_ERROR_INVALID_CLASS; 1.1616 + } 1.1617 + if (java_lang_Class::is_primitive(k_mirror)) { 1.1618 + return JVMTI_ERROR_NONE; 1.1619 + } 1.1620 + k_oop = java_lang_Class::as_Klass(k_mirror); 1.1621 + if (k_oop == NULL) { 1.1622 + return JVMTI_ERROR_INVALID_CLASS; 1.1623 + } 1.1624 + } 1.1625 + 1.1626 + Thread *thread = Thread::current(); 1.1627 + HandleMark hm(thread); 1.1628 + KlassHandle kh (thread, k_oop); 1.1629 + 1.1630 + TraceTime t("FollowReferences", TraceJVMTIObjectTagging); 1.1631 + JvmtiTagMap::tag_map_for(this)->follow_references(heap_filter, kh, initial_object, callbacks, user_data); 1.1632 + return JVMTI_ERROR_NONE; 1.1633 +} /* end FollowReferences */ 1.1634 + 1.1635 + 1.1636 +// klass - NULL is a valid value, must be checked 1.1637 +// callbacks - pre-checked for NULL 1.1638 +// user_data - NULL is a valid value, must be checked 1.1639 +jvmtiError 1.1640 +JvmtiEnv::IterateThroughHeap(jint heap_filter, jclass klass, const jvmtiHeapCallbacks* callbacks, const void* user_data) { 1.1641 + // check klass if provided 1.1642 + Klass* k_oop = NULL; 1.1643 + if (klass != NULL) { 1.1644 + oop k_mirror = JNIHandles::resolve_external_guard(klass); 1.1645 + if (k_mirror == NULL) { 1.1646 + return JVMTI_ERROR_INVALID_CLASS; 1.1647 + } 1.1648 + if (java_lang_Class::is_primitive(k_mirror)) { 1.1649 + return JVMTI_ERROR_NONE; 1.1650 + } 1.1651 + k_oop = java_lang_Class::as_Klass(k_mirror); 1.1652 + if (k_oop == NULL) { 1.1653 + return JVMTI_ERROR_INVALID_CLASS; 1.1654 + } 1.1655 + } 1.1656 + 1.1657 + Thread *thread = Thread::current(); 1.1658 + HandleMark hm(thread); 1.1659 + KlassHandle kh (thread, k_oop); 1.1660 + 1.1661 + TraceTime t("IterateThroughHeap", TraceJVMTIObjectTagging); 1.1662 + JvmtiTagMap::tag_map_for(this)->iterate_through_heap(heap_filter, kh, callbacks, user_data); 1.1663 + return JVMTI_ERROR_NONE; 1.1664 +} /* end IterateThroughHeap */ 1.1665 + 1.1666 + 1.1667 +// tag_ptr - pre-checked for NULL 1.1668 +jvmtiError 1.1669 +JvmtiEnv::GetTag(jobject object, jlong* tag_ptr) { 1.1670 + oop o = JNIHandles::resolve_external_guard(object); 1.1671 + NULL_CHECK(o, JVMTI_ERROR_INVALID_OBJECT); 1.1672 + *tag_ptr = JvmtiTagMap::tag_map_for(this)->get_tag(object); 1.1673 + return JVMTI_ERROR_NONE; 1.1674 +} /* end GetTag */ 1.1675 + 1.1676 + 1.1677 +jvmtiError 1.1678 +JvmtiEnv::SetTag(jobject object, jlong tag) { 1.1679 + oop o = JNIHandles::resolve_external_guard(object); 1.1680 + NULL_CHECK(o, JVMTI_ERROR_INVALID_OBJECT); 1.1681 + JvmtiTagMap::tag_map_for(this)->set_tag(object, tag); 1.1682 + return JVMTI_ERROR_NONE; 1.1683 +} /* end SetTag */ 1.1684 + 1.1685 + 1.1686 +// tag_count - pre-checked to be greater than or equal to 0 1.1687 +// tags - pre-checked for NULL 1.1688 +// count_ptr - pre-checked for NULL 1.1689 +// object_result_ptr - NULL is a valid value, must be checked 1.1690 +// tag_result_ptr - NULL is a valid value, must be checked 1.1691 +jvmtiError 1.1692 +JvmtiEnv::GetObjectsWithTags(jint tag_count, const jlong* tags, jint* count_ptr, jobject** object_result_ptr, jlong** tag_result_ptr) { 1.1693 + TraceTime t("GetObjectsWithTags", TraceJVMTIObjectTagging); 1.1694 + return JvmtiTagMap::tag_map_for(this)->get_objects_with_tags((jlong*)tags, tag_count, count_ptr, object_result_ptr, tag_result_ptr); 1.1695 +} /* end GetObjectsWithTags */ 1.1696 + 1.1697 + 1.1698 +jvmtiError 1.1699 +JvmtiEnv::ForceGarbageCollection() { 1.1700 + Universe::heap()->collect(GCCause::_jvmti_force_gc); 1.1701 + return JVMTI_ERROR_NONE; 1.1702 +} /* end ForceGarbageCollection */ 1.1703 + 1.1704 + 1.1705 + // 1.1706 + // Heap (1.0) functions 1.1707 + // 1.1708 + 1.1709 +// object_reference_callback - pre-checked for NULL 1.1710 +// user_data - NULL is a valid value, must be checked 1.1711 +jvmtiError 1.1712 +JvmtiEnv::IterateOverObjectsReachableFromObject(jobject object, jvmtiObjectReferenceCallback object_reference_callback, const void* user_data) { 1.1713 + oop o = JNIHandles::resolve_external_guard(object); 1.1714 + NULL_CHECK(o, JVMTI_ERROR_INVALID_OBJECT); 1.1715 + JvmtiTagMap::tag_map_for(this)->iterate_over_objects_reachable_from_object(object, object_reference_callback, user_data); 1.1716 + return JVMTI_ERROR_NONE; 1.1717 +} /* end IterateOverObjectsReachableFromObject */ 1.1718 + 1.1719 + 1.1720 +// heap_root_callback - NULL is a valid value, must be checked 1.1721 +// stack_ref_callback - NULL is a valid value, must be checked 1.1722 +// object_ref_callback - NULL is a valid value, must be checked 1.1723 +// user_data - NULL is a valid value, must be checked 1.1724 +jvmtiError 1.1725 +JvmtiEnv::IterateOverReachableObjects(jvmtiHeapRootCallback heap_root_callback, jvmtiStackReferenceCallback stack_ref_callback, jvmtiObjectReferenceCallback object_ref_callback, const void* user_data) { 1.1726 + TraceTime t("IterateOverReachableObjects", TraceJVMTIObjectTagging); 1.1727 + JvmtiTagMap::tag_map_for(this)->iterate_over_reachable_objects(heap_root_callback, stack_ref_callback, object_ref_callback, user_data); 1.1728 + return JVMTI_ERROR_NONE; 1.1729 +} /* end IterateOverReachableObjects */ 1.1730 + 1.1731 + 1.1732 +// heap_object_callback - pre-checked for NULL 1.1733 +// user_data - NULL is a valid value, must be checked 1.1734 +jvmtiError 1.1735 +JvmtiEnv::IterateOverHeap(jvmtiHeapObjectFilter object_filter, jvmtiHeapObjectCallback heap_object_callback, const void* user_data) { 1.1736 + TraceTime t("IterateOverHeap", TraceJVMTIObjectTagging); 1.1737 + Thread *thread = Thread::current(); 1.1738 + HandleMark hm(thread); 1.1739 + JvmtiTagMap::tag_map_for(this)->iterate_over_heap(object_filter, KlassHandle(), heap_object_callback, user_data); 1.1740 + return JVMTI_ERROR_NONE; 1.1741 +} /* end IterateOverHeap */ 1.1742 + 1.1743 + 1.1744 +// k_mirror - may be primitive, this must be checked 1.1745 +// heap_object_callback - pre-checked for NULL 1.1746 +// user_data - NULL is a valid value, must be checked 1.1747 +jvmtiError 1.1748 +JvmtiEnv::IterateOverInstancesOfClass(oop k_mirror, jvmtiHeapObjectFilter object_filter, jvmtiHeapObjectCallback heap_object_callback, const void* user_data) { 1.1749 + if (java_lang_Class::is_primitive(k_mirror)) { 1.1750 + // DO PRIMITIVE CLASS PROCESSING 1.1751 + return JVMTI_ERROR_NONE; 1.1752 + } 1.1753 + Klass* k_oop = java_lang_Class::as_Klass(k_mirror); 1.1754 + if (k_oop == NULL) { 1.1755 + return JVMTI_ERROR_INVALID_CLASS; 1.1756 + } 1.1757 + Thread *thread = Thread::current(); 1.1758 + HandleMark hm(thread); 1.1759 + KlassHandle klass (thread, k_oop); 1.1760 + TraceTime t("IterateOverInstancesOfClass", TraceJVMTIObjectTagging); 1.1761 + JvmtiTagMap::tag_map_for(this)->iterate_over_heap(object_filter, klass, heap_object_callback, user_data); 1.1762 + return JVMTI_ERROR_NONE; 1.1763 +} /* end IterateOverInstancesOfClass */ 1.1764 + 1.1765 + 1.1766 + // 1.1767 + // Local Variable functions 1.1768 + // 1.1769 + 1.1770 +// Threads_lock NOT held, java_thread not protected by lock 1.1771 +// java_thread - pre-checked 1.1772 +// java_thread - unchecked 1.1773 +// depth - pre-checked as non-negative 1.1774 +// value_ptr - pre-checked for NULL 1.1775 +jvmtiError 1.1776 +JvmtiEnv::GetLocalObject(JavaThread* java_thread, jint depth, jint slot, jobject* value_ptr) { 1.1777 + JavaThread* current_thread = JavaThread::current(); 1.1778 + // rm object is created to clean up the javaVFrame created in 1.1779 + // doit_prologue(), but after doit() is finished with it. 1.1780 + ResourceMark rm(current_thread); 1.1781 + 1.1782 + VM_GetOrSetLocal op(java_thread, current_thread, depth, slot); 1.1783 + VMThread::execute(&op); 1.1784 + jvmtiError err = op.result(); 1.1785 + if (err != JVMTI_ERROR_NONE) { 1.1786 + return err; 1.1787 + } else { 1.1788 + *value_ptr = op.value().l; 1.1789 + return JVMTI_ERROR_NONE; 1.1790 + } 1.1791 +} /* end GetLocalObject */ 1.1792 + 1.1793 +// Threads_lock NOT held, java_thread not protected by lock 1.1794 +// java_thread - pre-checked 1.1795 +// java_thread - unchecked 1.1796 +// depth - pre-checked as non-negative 1.1797 +// value - pre-checked for NULL 1.1798 +jvmtiError 1.1799 +JvmtiEnv::GetLocalInstance(JavaThread* java_thread, jint depth, jobject* value_ptr){ 1.1800 + JavaThread* current_thread = JavaThread::current(); 1.1801 + // rm object is created to clean up the javaVFrame created in 1.1802 + // doit_prologue(), but after doit() is finished with it. 1.1803 + ResourceMark rm(current_thread); 1.1804 + 1.1805 + VM_GetReceiver op(java_thread, current_thread, depth); 1.1806 + VMThread::execute(&op); 1.1807 + jvmtiError err = op.result(); 1.1808 + if (err != JVMTI_ERROR_NONE) { 1.1809 + return err; 1.1810 + } else { 1.1811 + *value_ptr = op.value().l; 1.1812 + return JVMTI_ERROR_NONE; 1.1813 + } 1.1814 +} /* end GetLocalInstance */ 1.1815 + 1.1816 + 1.1817 +// Threads_lock NOT held, java_thread not protected by lock 1.1818 +// java_thread - pre-checked 1.1819 +// java_thread - unchecked 1.1820 +// depth - pre-checked as non-negative 1.1821 +// value_ptr - pre-checked for NULL 1.1822 +jvmtiError 1.1823 +JvmtiEnv::GetLocalInt(JavaThread* java_thread, jint depth, jint slot, jint* value_ptr) { 1.1824 + // rm object is created to clean up the javaVFrame created in 1.1825 + // doit_prologue(), but after doit() is finished with it. 1.1826 + ResourceMark rm; 1.1827 + 1.1828 + VM_GetOrSetLocal op(java_thread, depth, slot, T_INT); 1.1829 + VMThread::execute(&op); 1.1830 + *value_ptr = op.value().i; 1.1831 + return op.result(); 1.1832 +} /* end GetLocalInt */ 1.1833 + 1.1834 + 1.1835 +// Threads_lock NOT held, java_thread not protected by lock 1.1836 +// java_thread - pre-checked 1.1837 +// java_thread - unchecked 1.1838 +// depth - pre-checked as non-negative 1.1839 +// value_ptr - pre-checked for NULL 1.1840 +jvmtiError 1.1841 +JvmtiEnv::GetLocalLong(JavaThread* java_thread, jint depth, jint slot, jlong* value_ptr) { 1.1842 + // rm object is created to clean up the javaVFrame created in 1.1843 + // doit_prologue(), but after doit() is finished with it. 1.1844 + ResourceMark rm; 1.1845 + 1.1846 + VM_GetOrSetLocal op(java_thread, depth, slot, T_LONG); 1.1847 + VMThread::execute(&op); 1.1848 + *value_ptr = op.value().j; 1.1849 + return op.result(); 1.1850 +} /* end GetLocalLong */ 1.1851 + 1.1852 + 1.1853 +// Threads_lock NOT held, java_thread not protected by lock 1.1854 +// java_thread - pre-checked 1.1855 +// java_thread - unchecked 1.1856 +// depth - pre-checked as non-negative 1.1857 +// value_ptr - pre-checked for NULL 1.1858 +jvmtiError 1.1859 +JvmtiEnv::GetLocalFloat(JavaThread* java_thread, jint depth, jint slot, jfloat* value_ptr) { 1.1860 + // rm object is created to clean up the javaVFrame created in 1.1861 + // doit_prologue(), but after doit() is finished with it. 1.1862 + ResourceMark rm; 1.1863 + 1.1864 + VM_GetOrSetLocal op(java_thread, depth, slot, T_FLOAT); 1.1865 + VMThread::execute(&op); 1.1866 + *value_ptr = op.value().f; 1.1867 + return op.result(); 1.1868 +} /* end GetLocalFloat */ 1.1869 + 1.1870 + 1.1871 +// Threads_lock NOT held, java_thread not protected by lock 1.1872 +// java_thread - pre-checked 1.1873 +// java_thread - unchecked 1.1874 +// depth - pre-checked as non-negative 1.1875 +// value_ptr - pre-checked for NULL 1.1876 +jvmtiError 1.1877 +JvmtiEnv::GetLocalDouble(JavaThread* java_thread, jint depth, jint slot, jdouble* value_ptr) { 1.1878 + // rm object is created to clean up the javaVFrame created in 1.1879 + // doit_prologue(), but after doit() is finished with it. 1.1880 + ResourceMark rm; 1.1881 + 1.1882 + VM_GetOrSetLocal op(java_thread, depth, slot, T_DOUBLE); 1.1883 + VMThread::execute(&op); 1.1884 + *value_ptr = op.value().d; 1.1885 + return op.result(); 1.1886 +} /* end GetLocalDouble */ 1.1887 + 1.1888 + 1.1889 +// Threads_lock NOT held, java_thread not protected by lock 1.1890 +// java_thread - pre-checked 1.1891 +// java_thread - unchecked 1.1892 +// depth - pre-checked as non-negative 1.1893 +jvmtiError 1.1894 +JvmtiEnv::SetLocalObject(JavaThread* java_thread, jint depth, jint slot, jobject value) { 1.1895 + // rm object is created to clean up the javaVFrame created in 1.1896 + // doit_prologue(), but after doit() is finished with it. 1.1897 + ResourceMark rm; 1.1898 + jvalue val; 1.1899 + val.l = value; 1.1900 + VM_GetOrSetLocal op(java_thread, depth, slot, T_OBJECT, val); 1.1901 + VMThread::execute(&op); 1.1902 + return op.result(); 1.1903 +} /* end SetLocalObject */ 1.1904 + 1.1905 + 1.1906 +// Threads_lock NOT held, java_thread not protected by lock 1.1907 +// java_thread - pre-checked 1.1908 +// java_thread - unchecked 1.1909 +// depth - pre-checked as non-negative 1.1910 +jvmtiError 1.1911 +JvmtiEnv::SetLocalInt(JavaThread* java_thread, jint depth, jint slot, jint value) { 1.1912 + // rm object is created to clean up the javaVFrame created in 1.1913 + // doit_prologue(), but after doit() is finished with it. 1.1914 + ResourceMark rm; 1.1915 + jvalue val; 1.1916 + val.i = value; 1.1917 + VM_GetOrSetLocal op(java_thread, depth, slot, T_INT, val); 1.1918 + VMThread::execute(&op); 1.1919 + return op.result(); 1.1920 +} /* end SetLocalInt */ 1.1921 + 1.1922 + 1.1923 +// Threads_lock NOT held, java_thread not protected by lock 1.1924 +// java_thread - pre-checked 1.1925 +// java_thread - unchecked 1.1926 +// depth - pre-checked as non-negative 1.1927 +jvmtiError 1.1928 +JvmtiEnv::SetLocalLong(JavaThread* java_thread, jint depth, jint slot, jlong value) { 1.1929 + // rm object is created to clean up the javaVFrame created in 1.1930 + // doit_prologue(), but after doit() is finished with it. 1.1931 + ResourceMark rm; 1.1932 + jvalue val; 1.1933 + val.j = value; 1.1934 + VM_GetOrSetLocal op(java_thread, depth, slot, T_LONG, val); 1.1935 + VMThread::execute(&op); 1.1936 + return op.result(); 1.1937 +} /* end SetLocalLong */ 1.1938 + 1.1939 + 1.1940 +// Threads_lock NOT held, java_thread not protected by lock 1.1941 +// java_thread - pre-checked 1.1942 +// java_thread - unchecked 1.1943 +// depth - pre-checked as non-negative 1.1944 +jvmtiError 1.1945 +JvmtiEnv::SetLocalFloat(JavaThread* java_thread, jint depth, jint slot, jfloat value) { 1.1946 + // rm object is created to clean up the javaVFrame created in 1.1947 + // doit_prologue(), but after doit() is finished with it. 1.1948 + ResourceMark rm; 1.1949 + jvalue val; 1.1950 + val.f = value; 1.1951 + VM_GetOrSetLocal op(java_thread, depth, slot, T_FLOAT, val); 1.1952 + VMThread::execute(&op); 1.1953 + return op.result(); 1.1954 +} /* end SetLocalFloat */ 1.1955 + 1.1956 + 1.1957 +// Threads_lock NOT held, java_thread not protected by lock 1.1958 +// java_thread - pre-checked 1.1959 +// java_thread - unchecked 1.1960 +// depth - pre-checked as non-negative 1.1961 +jvmtiError 1.1962 +JvmtiEnv::SetLocalDouble(JavaThread* java_thread, jint depth, jint slot, jdouble value) { 1.1963 + // rm object is created to clean up the javaVFrame created in 1.1964 + // doit_prologue(), but after doit() is finished with it. 1.1965 + ResourceMark rm; 1.1966 + jvalue val; 1.1967 + val.d = value; 1.1968 + VM_GetOrSetLocal op(java_thread, depth, slot, T_DOUBLE, val); 1.1969 + VMThread::execute(&op); 1.1970 + return op.result(); 1.1971 +} /* end SetLocalDouble */ 1.1972 + 1.1973 + 1.1974 + // 1.1975 + // Breakpoint functions 1.1976 + // 1.1977 + 1.1978 +// method_oop - pre-checked for validity, but may be NULL meaning obsolete method 1.1979 +jvmtiError 1.1980 +JvmtiEnv::SetBreakpoint(Method* method_oop, jlocation location) { 1.1981 + NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID); 1.1982 + if (location < 0) { // simple invalid location check first 1.1983 + return JVMTI_ERROR_INVALID_LOCATION; 1.1984 + } 1.1985 + // verify that the breakpoint is not past the end of the method 1.1986 + if (location >= (jlocation) method_oop->code_size()) { 1.1987 + return JVMTI_ERROR_INVALID_LOCATION; 1.1988 + } 1.1989 + 1.1990 + ResourceMark rm; 1.1991 + JvmtiBreakpoint bp(method_oop, location); 1.1992 + JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints(); 1.1993 + if (jvmti_breakpoints.set(bp) == JVMTI_ERROR_DUPLICATE) 1.1994 + return JVMTI_ERROR_DUPLICATE; 1.1995 + 1.1996 + if (TraceJVMTICalls) { 1.1997 + jvmti_breakpoints.print(); 1.1998 + } 1.1999 + 1.2000 + return JVMTI_ERROR_NONE; 1.2001 +} /* end SetBreakpoint */ 1.2002 + 1.2003 + 1.2004 +// method_oop - pre-checked for validity, but may be NULL meaning obsolete method 1.2005 +jvmtiError 1.2006 +JvmtiEnv::ClearBreakpoint(Method* method_oop, jlocation location) { 1.2007 + NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID); 1.2008 + 1.2009 + if (location < 0) { // simple invalid location check first 1.2010 + return JVMTI_ERROR_INVALID_LOCATION; 1.2011 + } 1.2012 + 1.2013 + // verify that the breakpoint is not past the end of the method 1.2014 + if (location >= (jlocation) method_oop->code_size()) { 1.2015 + return JVMTI_ERROR_INVALID_LOCATION; 1.2016 + } 1.2017 + 1.2018 + JvmtiBreakpoint bp(method_oop, location); 1.2019 + 1.2020 + JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints(); 1.2021 + if (jvmti_breakpoints.clear(bp) == JVMTI_ERROR_NOT_FOUND) 1.2022 + return JVMTI_ERROR_NOT_FOUND; 1.2023 + 1.2024 + if (TraceJVMTICalls) { 1.2025 + jvmti_breakpoints.print(); 1.2026 + } 1.2027 + 1.2028 + return JVMTI_ERROR_NONE; 1.2029 +} /* end ClearBreakpoint */ 1.2030 + 1.2031 + 1.2032 + // 1.2033 + // Watched Field functions 1.2034 + // 1.2035 + 1.2036 +jvmtiError 1.2037 +JvmtiEnv::SetFieldAccessWatch(fieldDescriptor* fdesc_ptr) { 1.2038 + // make sure we haven't set this watch before 1.2039 + if (fdesc_ptr->is_field_access_watched()) return JVMTI_ERROR_DUPLICATE; 1.2040 + fdesc_ptr->set_is_field_access_watched(true); 1.2041 + 1.2042 + JvmtiEventController::change_field_watch(JVMTI_EVENT_FIELD_ACCESS, true); 1.2043 + 1.2044 + return JVMTI_ERROR_NONE; 1.2045 +} /* end SetFieldAccessWatch */ 1.2046 + 1.2047 + 1.2048 +jvmtiError 1.2049 +JvmtiEnv::ClearFieldAccessWatch(fieldDescriptor* fdesc_ptr) { 1.2050 + // make sure we have a watch to clear 1.2051 + if (!fdesc_ptr->is_field_access_watched()) return JVMTI_ERROR_NOT_FOUND; 1.2052 + fdesc_ptr->set_is_field_access_watched(false); 1.2053 + 1.2054 + JvmtiEventController::change_field_watch(JVMTI_EVENT_FIELD_ACCESS, false); 1.2055 + 1.2056 + return JVMTI_ERROR_NONE; 1.2057 +} /* end ClearFieldAccessWatch */ 1.2058 + 1.2059 + 1.2060 +jvmtiError 1.2061 +JvmtiEnv::SetFieldModificationWatch(fieldDescriptor* fdesc_ptr) { 1.2062 + // make sure we haven't set this watch before 1.2063 + if (fdesc_ptr->is_field_modification_watched()) return JVMTI_ERROR_DUPLICATE; 1.2064 + fdesc_ptr->set_is_field_modification_watched(true); 1.2065 + 1.2066 + JvmtiEventController::change_field_watch(JVMTI_EVENT_FIELD_MODIFICATION, true); 1.2067 + 1.2068 + return JVMTI_ERROR_NONE; 1.2069 +} /* end SetFieldModificationWatch */ 1.2070 + 1.2071 + 1.2072 +jvmtiError 1.2073 +JvmtiEnv::ClearFieldModificationWatch(fieldDescriptor* fdesc_ptr) { 1.2074 + // make sure we have a watch to clear 1.2075 + if (!fdesc_ptr->is_field_modification_watched()) return JVMTI_ERROR_NOT_FOUND; 1.2076 + fdesc_ptr->set_is_field_modification_watched(false); 1.2077 + 1.2078 + JvmtiEventController::change_field_watch(JVMTI_EVENT_FIELD_MODIFICATION, false); 1.2079 + 1.2080 + return JVMTI_ERROR_NONE; 1.2081 +} /* end ClearFieldModificationWatch */ 1.2082 + 1.2083 + // 1.2084 + // Class functions 1.2085 + // 1.2086 + 1.2087 + 1.2088 +// k_mirror - may be primitive, this must be checked 1.2089 +// signature_ptr - NULL is a valid value, must be checked 1.2090 +// generic_ptr - NULL is a valid value, must be checked 1.2091 +jvmtiError 1.2092 +JvmtiEnv::GetClassSignature(oop k_mirror, char** signature_ptr, char** generic_ptr) { 1.2093 + ResourceMark rm; 1.2094 + bool isPrimitive = java_lang_Class::is_primitive(k_mirror); 1.2095 + Klass* k = NULL; 1.2096 + if (!isPrimitive) { 1.2097 + k = java_lang_Class::as_Klass(k_mirror); 1.2098 + NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS); 1.2099 + } 1.2100 + if (signature_ptr != NULL) { 1.2101 + char* result = NULL; 1.2102 + if (isPrimitive) { 1.2103 + char tchar = type2char(java_lang_Class::primitive_type(k_mirror)); 1.2104 + result = (char*) jvmtiMalloc(2); 1.2105 + result[0] = tchar; 1.2106 + result[1] = '\0'; 1.2107 + } else { 1.2108 + const char* class_sig = k->signature_name(); 1.2109 + result = (char *) jvmtiMalloc(strlen(class_sig)+1); 1.2110 + strcpy(result, class_sig); 1.2111 + } 1.2112 + *signature_ptr = result; 1.2113 + } 1.2114 + if (generic_ptr != NULL) { 1.2115 + *generic_ptr = NULL; 1.2116 + if (!isPrimitive && k->oop_is_instance()) { 1.2117 + Symbol* soo = InstanceKlass::cast(k)->generic_signature(); 1.2118 + if (soo != NULL) { 1.2119 + const char *gen_sig = soo->as_C_string(); 1.2120 + if (gen_sig != NULL) { 1.2121 + char* gen_result; 1.2122 + jvmtiError err = allocate(strlen(gen_sig) + 1, 1.2123 + (unsigned char **)&gen_result); 1.2124 + if (err != JVMTI_ERROR_NONE) { 1.2125 + return err; 1.2126 + } 1.2127 + strcpy(gen_result, gen_sig); 1.2128 + *generic_ptr = gen_result; 1.2129 + } 1.2130 + } 1.2131 + } 1.2132 + } 1.2133 + return JVMTI_ERROR_NONE; 1.2134 +} /* end GetClassSignature */ 1.2135 + 1.2136 + 1.2137 +// k_mirror - may be primitive, this must be checked 1.2138 +// status_ptr - pre-checked for NULL 1.2139 +jvmtiError 1.2140 +JvmtiEnv::GetClassStatus(oop k_mirror, jint* status_ptr) { 1.2141 + jint result = 0; 1.2142 + if (java_lang_Class::is_primitive(k_mirror)) { 1.2143 + result |= JVMTI_CLASS_STATUS_PRIMITIVE; 1.2144 + } else { 1.2145 + Klass* k = java_lang_Class::as_Klass(k_mirror); 1.2146 + NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS); 1.2147 + result = k->jvmti_class_status(); 1.2148 + } 1.2149 + *status_ptr = result; 1.2150 + 1.2151 + return JVMTI_ERROR_NONE; 1.2152 +} /* end GetClassStatus */ 1.2153 + 1.2154 + 1.2155 +// k_mirror - may be primitive, this must be checked 1.2156 +// source_name_ptr - pre-checked for NULL 1.2157 +jvmtiError 1.2158 +JvmtiEnv::GetSourceFileName(oop k_mirror, char** source_name_ptr) { 1.2159 + if (java_lang_Class::is_primitive(k_mirror)) { 1.2160 + return JVMTI_ERROR_ABSENT_INFORMATION; 1.2161 + } 1.2162 + Klass* k_klass = java_lang_Class::as_Klass(k_mirror); 1.2163 + NULL_CHECK(k_klass, JVMTI_ERROR_INVALID_CLASS); 1.2164 + 1.2165 + if (!k_klass->oop_is_instance()) { 1.2166 + return JVMTI_ERROR_ABSENT_INFORMATION; 1.2167 + } 1.2168 + 1.2169 + Symbol* sfnOop = InstanceKlass::cast(k_klass)->source_file_name(); 1.2170 + NULL_CHECK(sfnOop, JVMTI_ERROR_ABSENT_INFORMATION); 1.2171 + { 1.2172 + JavaThread* current_thread = JavaThread::current(); 1.2173 + ResourceMark rm(current_thread); 1.2174 + const char* sfncp = (const char*) sfnOop->as_C_string(); 1.2175 + *source_name_ptr = (char *) jvmtiMalloc(strlen(sfncp)+1); 1.2176 + strcpy(*source_name_ptr, sfncp); 1.2177 + } 1.2178 + 1.2179 + return JVMTI_ERROR_NONE; 1.2180 +} /* end GetSourceFileName */ 1.2181 + 1.2182 + 1.2183 +// k_mirror - may be primitive, this must be checked 1.2184 +// modifiers_ptr - pre-checked for NULL 1.2185 +jvmtiError 1.2186 +JvmtiEnv::GetClassModifiers(oop k_mirror, jint* modifiers_ptr) { 1.2187 + JavaThread* current_thread = JavaThread::current(); 1.2188 + jint result = 0; 1.2189 + if (!java_lang_Class::is_primitive(k_mirror)) { 1.2190 + Klass* k = java_lang_Class::as_Klass(k_mirror); 1.2191 + NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS); 1.2192 + result = k->compute_modifier_flags(current_thread); 1.2193 + JavaThread* THREAD = current_thread; // pass to macros 1.2194 + if (HAS_PENDING_EXCEPTION) { 1.2195 + CLEAR_PENDING_EXCEPTION; 1.2196 + return JVMTI_ERROR_INTERNAL; 1.2197 + }; 1.2198 + 1.2199 + // Reset the deleted ACC_SUPER bit ( deleted in compute_modifier_flags()). 1.2200 + if(k->is_super()) { 1.2201 + result |= JVM_ACC_SUPER; 1.2202 + } 1.2203 + } else { 1.2204 + result = (JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC); 1.2205 + } 1.2206 + *modifiers_ptr = result; 1.2207 + 1.2208 + return JVMTI_ERROR_NONE; 1.2209 +} /* end GetClassModifiers */ 1.2210 + 1.2211 + 1.2212 +// k_mirror - may be primitive, this must be checked 1.2213 +// method_count_ptr - pre-checked for NULL 1.2214 +// methods_ptr - pre-checked for NULL 1.2215 +jvmtiError 1.2216 +JvmtiEnv::GetClassMethods(oop k_mirror, jint* method_count_ptr, jmethodID** methods_ptr) { 1.2217 + JavaThread* current_thread = JavaThread::current(); 1.2218 + HandleMark hm(current_thread); 1.2219 + 1.2220 + if (java_lang_Class::is_primitive(k_mirror)) { 1.2221 + *method_count_ptr = 0; 1.2222 + *methods_ptr = (jmethodID*) jvmtiMalloc(0 * sizeof(jmethodID)); 1.2223 + return JVMTI_ERROR_NONE; 1.2224 + } 1.2225 + Klass* k = java_lang_Class::as_Klass(k_mirror); 1.2226 + NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS); 1.2227 + 1.2228 + // Return CLASS_NOT_PREPARED error as per JVMTI spec. 1.2229 + if (!(k->jvmti_class_status() & (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY) )) { 1.2230 + return JVMTI_ERROR_CLASS_NOT_PREPARED; 1.2231 + } 1.2232 + 1.2233 + if (!k->oop_is_instance()) { 1.2234 + *method_count_ptr = 0; 1.2235 + *methods_ptr = (jmethodID*) jvmtiMalloc(0 * sizeof(jmethodID)); 1.2236 + return JVMTI_ERROR_NONE; 1.2237 + } 1.2238 + instanceKlassHandle instanceK_h(current_thread, k); 1.2239 + // Allocate the result and fill it in 1.2240 + int result_length = instanceK_h->methods()->length(); 1.2241 + jmethodID* result_list = (jmethodID*)jvmtiMalloc(result_length * sizeof(jmethodID)); 1.2242 + int index; 1.2243 + if (JvmtiExport::can_maintain_original_method_order()) { 1.2244 + // Use the original method ordering indices stored in the class, so we can emit 1.2245 + // jmethodIDs in the order they appeared in the class file 1.2246 + for (index = 0; index < result_length; index++) { 1.2247 + Method* m = instanceK_h->methods()->at(index); 1.2248 + int original_index = instanceK_h->method_ordering()->at(index); 1.2249 + assert(original_index >= 0 && original_index < result_length, "invalid original method index"); 1.2250 + jmethodID id = m->jmethod_id(); 1.2251 + result_list[original_index] = id; 1.2252 + } 1.2253 + } else { 1.2254 + // otherwise just copy in any order 1.2255 + for (index = 0; index < result_length; index++) { 1.2256 + Method* m = instanceK_h->methods()->at(index); 1.2257 + jmethodID id = m->jmethod_id(); 1.2258 + result_list[index] = id; 1.2259 + } 1.2260 + } 1.2261 + // Fill in return value. 1.2262 + *method_count_ptr = result_length; 1.2263 + *methods_ptr = result_list; 1.2264 + 1.2265 + return JVMTI_ERROR_NONE; 1.2266 +} /* end GetClassMethods */ 1.2267 + 1.2268 + 1.2269 +// k_mirror - may be primitive, this must be checked 1.2270 +// field_count_ptr - pre-checked for NULL 1.2271 +// fields_ptr - pre-checked for NULL 1.2272 +jvmtiError 1.2273 +JvmtiEnv::GetClassFields(oop k_mirror, jint* field_count_ptr, jfieldID** fields_ptr) { 1.2274 + if (java_lang_Class::is_primitive(k_mirror)) { 1.2275 + *field_count_ptr = 0; 1.2276 + *fields_ptr = (jfieldID*) jvmtiMalloc(0 * sizeof(jfieldID)); 1.2277 + return JVMTI_ERROR_NONE; 1.2278 + } 1.2279 + JavaThread* current_thread = JavaThread::current(); 1.2280 + HandleMark hm(current_thread); 1.2281 + Klass* k = java_lang_Class::as_Klass(k_mirror); 1.2282 + NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS); 1.2283 + 1.2284 + // Return CLASS_NOT_PREPARED error as per JVMTI spec. 1.2285 + if (!(k->jvmti_class_status() & (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY) )) { 1.2286 + return JVMTI_ERROR_CLASS_NOT_PREPARED; 1.2287 + } 1.2288 + 1.2289 + if (!k->oop_is_instance()) { 1.2290 + *field_count_ptr = 0; 1.2291 + *fields_ptr = (jfieldID*) jvmtiMalloc(0 * sizeof(jfieldID)); 1.2292 + return JVMTI_ERROR_NONE; 1.2293 + } 1.2294 + 1.2295 + 1.2296 + instanceKlassHandle instanceK_h(current_thread, k); 1.2297 + 1.2298 + int result_count = 0; 1.2299 + // First, count the fields. 1.2300 + FilteredFieldStream flds(instanceK_h, true, true); 1.2301 + result_count = flds.field_count(); 1.2302 + 1.2303 + // Allocate the result and fill it in 1.2304 + jfieldID* result_list = (jfieldID*) jvmtiMalloc(result_count * sizeof(jfieldID)); 1.2305 + // The JVMTI spec requires fields in the order they occur in the class file, 1.2306 + // this is the reverse order of what FieldStream hands out. 1.2307 + int id_index = (result_count - 1); 1.2308 + 1.2309 + for (FilteredFieldStream src_st(instanceK_h, true, true); !src_st.eos(); src_st.next()) { 1.2310 + result_list[id_index--] = jfieldIDWorkaround::to_jfieldID( 1.2311 + instanceK_h, src_st.offset(), 1.2312 + src_st.access_flags().is_static()); 1.2313 + } 1.2314 + assert(id_index == -1, "just checking"); 1.2315 + // Fill in the results 1.2316 + *field_count_ptr = result_count; 1.2317 + *fields_ptr = result_list; 1.2318 + 1.2319 + return JVMTI_ERROR_NONE; 1.2320 +} /* end GetClassFields */ 1.2321 + 1.2322 + 1.2323 +// k_mirror - may be primitive, this must be checked 1.2324 +// interface_count_ptr - pre-checked for NULL 1.2325 +// interfaces_ptr - pre-checked for NULL 1.2326 +jvmtiError 1.2327 +JvmtiEnv::GetImplementedInterfaces(oop k_mirror, jint* interface_count_ptr, jclass** interfaces_ptr) { 1.2328 + { 1.2329 + if (java_lang_Class::is_primitive(k_mirror)) { 1.2330 + *interface_count_ptr = 0; 1.2331 + *interfaces_ptr = (jclass*) jvmtiMalloc(0 * sizeof(jclass)); 1.2332 + return JVMTI_ERROR_NONE; 1.2333 + } 1.2334 + JavaThread* current_thread = JavaThread::current(); 1.2335 + HandleMark hm(current_thread); 1.2336 + Klass* k = java_lang_Class::as_Klass(k_mirror); 1.2337 + NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS); 1.2338 + 1.2339 + // Return CLASS_NOT_PREPARED error as per JVMTI spec. 1.2340 + if (!(k->jvmti_class_status() & (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY) )) 1.2341 + return JVMTI_ERROR_CLASS_NOT_PREPARED; 1.2342 + 1.2343 + if (!k->oop_is_instance()) { 1.2344 + *interface_count_ptr = 0; 1.2345 + *interfaces_ptr = (jclass*) jvmtiMalloc(0 * sizeof(jclass)); 1.2346 + return JVMTI_ERROR_NONE; 1.2347 + } 1.2348 + 1.2349 + Array<Klass*>* interface_list = InstanceKlass::cast(k)->local_interfaces(); 1.2350 + const int result_length = (interface_list == NULL ? 0 : interface_list->length()); 1.2351 + jclass* result_list = (jclass*) jvmtiMalloc(result_length * sizeof(jclass)); 1.2352 + for (int i_index = 0; i_index < result_length; i_index += 1) { 1.2353 + Klass* klass_at = interface_list->at(i_index); 1.2354 + assert(klass_at->is_klass(), "interfaces must be Klass*s"); 1.2355 + assert(klass_at->is_interface(), "interfaces must be interfaces"); 1.2356 + oop mirror_at = klass_at->java_mirror(); 1.2357 + Handle handle_at = Handle(current_thread, mirror_at); 1.2358 + result_list[i_index] = (jclass) jni_reference(handle_at); 1.2359 + } 1.2360 + *interface_count_ptr = result_length; 1.2361 + *interfaces_ptr = result_list; 1.2362 + } 1.2363 + 1.2364 + return JVMTI_ERROR_NONE; 1.2365 +} /* end GetImplementedInterfaces */ 1.2366 + 1.2367 + 1.2368 +// k_mirror - may be primitive, this must be checked 1.2369 +// minor_version_ptr - pre-checked for NULL 1.2370 +// major_version_ptr - pre-checked for NULL 1.2371 +jvmtiError 1.2372 +JvmtiEnv::GetClassVersionNumbers(oop k_mirror, jint* minor_version_ptr, jint* major_version_ptr) { 1.2373 + if (java_lang_Class::is_primitive(k_mirror)) { 1.2374 + return JVMTI_ERROR_ABSENT_INFORMATION; 1.2375 + } 1.2376 + Klass* k_oop = java_lang_Class::as_Klass(k_mirror); 1.2377 + Thread *thread = Thread::current(); 1.2378 + HandleMark hm(thread); 1.2379 + KlassHandle klass(thread, k_oop); 1.2380 + 1.2381 + jint status = klass->jvmti_class_status(); 1.2382 + if (status & (JVMTI_CLASS_STATUS_ERROR)) { 1.2383 + return JVMTI_ERROR_INVALID_CLASS; 1.2384 + } 1.2385 + if (status & (JVMTI_CLASS_STATUS_ARRAY)) { 1.2386 + return JVMTI_ERROR_ABSENT_INFORMATION; 1.2387 + } 1.2388 + 1.2389 + instanceKlassHandle ik(thread, k_oop); 1.2390 + *minor_version_ptr = ik->minor_version(); 1.2391 + *major_version_ptr = ik->major_version(); 1.2392 + 1.2393 + return JVMTI_ERROR_NONE; 1.2394 +} /* end GetClassVersionNumbers */ 1.2395 + 1.2396 + 1.2397 +// k_mirror - may be primitive, this must be checked 1.2398 +// constant_pool_count_ptr - pre-checked for NULL 1.2399 +// constant_pool_byte_count_ptr - pre-checked for NULL 1.2400 +// constant_pool_bytes_ptr - pre-checked for NULL 1.2401 +jvmtiError 1.2402 +JvmtiEnv::GetConstantPool(oop k_mirror, jint* constant_pool_count_ptr, jint* constant_pool_byte_count_ptr, unsigned char** constant_pool_bytes_ptr) { 1.2403 + if (java_lang_Class::is_primitive(k_mirror)) { 1.2404 + return JVMTI_ERROR_ABSENT_INFORMATION; 1.2405 + } 1.2406 + 1.2407 + Klass* k_oop = java_lang_Class::as_Klass(k_mirror); 1.2408 + Thread *thread = Thread::current(); 1.2409 + HandleMark hm(thread); 1.2410 + ResourceMark rm(thread); 1.2411 + KlassHandle klass(thread, k_oop); 1.2412 + 1.2413 + jint status = klass->jvmti_class_status(); 1.2414 + if (status & (JVMTI_CLASS_STATUS_ERROR)) { 1.2415 + return JVMTI_ERROR_INVALID_CLASS; 1.2416 + } 1.2417 + if (status & (JVMTI_CLASS_STATUS_ARRAY)) { 1.2418 + return JVMTI_ERROR_ABSENT_INFORMATION; 1.2419 + } 1.2420 + 1.2421 + instanceKlassHandle ikh(thread, k_oop); 1.2422 + constantPoolHandle constants(thread, ikh->constants()); 1.2423 + MonitorLockerEx ml(constants->lock()); // lock constant pool while we query it 1.2424 + 1.2425 + JvmtiConstantPoolReconstituter reconstituter(ikh); 1.2426 + if (reconstituter.get_error() != JVMTI_ERROR_NONE) { 1.2427 + return reconstituter.get_error(); 1.2428 + } 1.2429 + 1.2430 + unsigned char *cpool_bytes; 1.2431 + int cpool_size = reconstituter.cpool_size(); 1.2432 + if (reconstituter.get_error() != JVMTI_ERROR_NONE) { 1.2433 + return reconstituter.get_error(); 1.2434 + } 1.2435 + jvmtiError res = allocate(cpool_size, &cpool_bytes); 1.2436 + if (res != JVMTI_ERROR_NONE) { 1.2437 + return res; 1.2438 + } 1.2439 + reconstituter.copy_cpool_bytes(cpool_bytes); 1.2440 + if (reconstituter.get_error() != JVMTI_ERROR_NONE) { 1.2441 + return reconstituter.get_error(); 1.2442 + } 1.2443 + 1.2444 + *constant_pool_count_ptr = constants->length(); 1.2445 + *constant_pool_byte_count_ptr = cpool_size; 1.2446 + *constant_pool_bytes_ptr = cpool_bytes; 1.2447 + 1.2448 + return JVMTI_ERROR_NONE; 1.2449 +} /* end GetConstantPool */ 1.2450 + 1.2451 + 1.2452 +// k_mirror - may be primitive, this must be checked 1.2453 +// is_interface_ptr - pre-checked for NULL 1.2454 +jvmtiError 1.2455 +JvmtiEnv::IsInterface(oop k_mirror, jboolean* is_interface_ptr) { 1.2456 + { 1.2457 + bool result = false; 1.2458 + if (!java_lang_Class::is_primitive(k_mirror)) { 1.2459 + Klass* k = java_lang_Class::as_Klass(k_mirror); 1.2460 + if (k != NULL && k->is_interface()) { 1.2461 + result = true; 1.2462 + } 1.2463 + } 1.2464 + *is_interface_ptr = result; 1.2465 + } 1.2466 + 1.2467 + return JVMTI_ERROR_NONE; 1.2468 +} /* end IsInterface */ 1.2469 + 1.2470 + 1.2471 +// k_mirror - may be primitive, this must be checked 1.2472 +// is_array_class_ptr - pre-checked for NULL 1.2473 +jvmtiError 1.2474 +JvmtiEnv::IsArrayClass(oop k_mirror, jboolean* is_array_class_ptr) { 1.2475 + { 1.2476 + bool result = false; 1.2477 + if (!java_lang_Class::is_primitive(k_mirror)) { 1.2478 + Klass* k = java_lang_Class::as_Klass(k_mirror); 1.2479 + if (k != NULL && k->oop_is_array()) { 1.2480 + result = true; 1.2481 + } 1.2482 + } 1.2483 + *is_array_class_ptr = result; 1.2484 + } 1.2485 + 1.2486 + return JVMTI_ERROR_NONE; 1.2487 +} /* end IsArrayClass */ 1.2488 + 1.2489 + 1.2490 +// k_mirror - may be primitive, this must be checked 1.2491 +// classloader_ptr - pre-checked for NULL 1.2492 +jvmtiError 1.2493 +JvmtiEnv::GetClassLoader(oop k_mirror, jobject* classloader_ptr) { 1.2494 + { 1.2495 + if (java_lang_Class::is_primitive(k_mirror)) { 1.2496 + *classloader_ptr = (jclass) jni_reference(Handle()); 1.2497 + return JVMTI_ERROR_NONE; 1.2498 + } 1.2499 + JavaThread* current_thread = JavaThread::current(); 1.2500 + HandleMark hm(current_thread); 1.2501 + Klass* k = java_lang_Class::as_Klass(k_mirror); 1.2502 + NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS); 1.2503 + 1.2504 + oop result_oop = k->class_loader(); 1.2505 + if (result_oop == NULL) { 1.2506 + *classloader_ptr = (jclass) jni_reference(Handle()); 1.2507 + return JVMTI_ERROR_NONE; 1.2508 + } 1.2509 + Handle result_handle = Handle(current_thread, result_oop); 1.2510 + jclass result_jnihandle = (jclass) jni_reference(result_handle); 1.2511 + *classloader_ptr = result_jnihandle; 1.2512 + } 1.2513 + return JVMTI_ERROR_NONE; 1.2514 +} /* end GetClassLoader */ 1.2515 + 1.2516 + 1.2517 +// k_mirror - may be primitive, this must be checked 1.2518 +// source_debug_extension_ptr - pre-checked for NULL 1.2519 +jvmtiError 1.2520 +JvmtiEnv::GetSourceDebugExtension(oop k_mirror, char** source_debug_extension_ptr) { 1.2521 + { 1.2522 + if (java_lang_Class::is_primitive(k_mirror)) { 1.2523 + return JVMTI_ERROR_ABSENT_INFORMATION; 1.2524 + } 1.2525 + Klass* k = java_lang_Class::as_Klass(k_mirror); 1.2526 + NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS); 1.2527 + if (!k->oop_is_instance()) { 1.2528 + return JVMTI_ERROR_ABSENT_INFORMATION; 1.2529 + } 1.2530 + char* sde = InstanceKlass::cast(k)->source_debug_extension(); 1.2531 + NULL_CHECK(sde, JVMTI_ERROR_ABSENT_INFORMATION); 1.2532 + 1.2533 + { 1.2534 + *source_debug_extension_ptr = (char *) jvmtiMalloc(strlen(sde)+1); 1.2535 + strcpy(*source_debug_extension_ptr, sde); 1.2536 + } 1.2537 + } 1.2538 + 1.2539 + return JVMTI_ERROR_NONE; 1.2540 +} /* end GetSourceDebugExtension */ 1.2541 + 1.2542 + // 1.2543 + // Object functions 1.2544 + // 1.2545 + 1.2546 +// hash_code_ptr - pre-checked for NULL 1.2547 +jvmtiError 1.2548 +JvmtiEnv::GetObjectHashCode(jobject object, jint* hash_code_ptr) { 1.2549 + oop mirror = JNIHandles::resolve_external_guard(object); 1.2550 + NULL_CHECK(mirror, JVMTI_ERROR_INVALID_OBJECT); 1.2551 + NULL_CHECK(hash_code_ptr, JVMTI_ERROR_NULL_POINTER); 1.2552 + 1.2553 + { 1.2554 + jint result = (jint) mirror->identity_hash(); 1.2555 + *hash_code_ptr = result; 1.2556 + } 1.2557 + return JVMTI_ERROR_NONE; 1.2558 +} /* end GetObjectHashCode */ 1.2559 + 1.2560 + 1.2561 +// info_ptr - pre-checked for NULL 1.2562 +jvmtiError 1.2563 +JvmtiEnv::GetObjectMonitorUsage(jobject object, jvmtiMonitorUsage* info_ptr) { 1.2564 + JavaThread* calling_thread = JavaThread::current(); 1.2565 + jvmtiError err = get_object_monitor_usage(calling_thread, object, info_ptr); 1.2566 + if (err == JVMTI_ERROR_THREAD_NOT_SUSPENDED) { 1.2567 + // Some of the critical threads were not suspended. go to a safepoint and try again 1.2568 + VM_GetObjectMonitorUsage op(this, calling_thread, object, info_ptr); 1.2569 + VMThread::execute(&op); 1.2570 + err = op.result(); 1.2571 + } 1.2572 + return err; 1.2573 +} /* end GetObjectMonitorUsage */ 1.2574 + 1.2575 + 1.2576 + // 1.2577 + // Field functions 1.2578 + // 1.2579 + 1.2580 +// name_ptr - NULL is a valid value, must be checked 1.2581 +// signature_ptr - NULL is a valid value, must be checked 1.2582 +// generic_ptr - NULL is a valid value, must be checked 1.2583 +jvmtiError 1.2584 +JvmtiEnv::GetFieldName(fieldDescriptor* fdesc_ptr, char** name_ptr, char** signature_ptr, char** generic_ptr) { 1.2585 + JavaThread* current_thread = JavaThread::current(); 1.2586 + ResourceMark rm(current_thread); 1.2587 + if (name_ptr == NULL) { 1.2588 + // just don't return the name 1.2589 + } else { 1.2590 + const char* fieldName = fdesc_ptr->name()->as_C_string(); 1.2591 + *name_ptr = (char*) jvmtiMalloc(strlen(fieldName) + 1); 1.2592 + if (*name_ptr == NULL) 1.2593 + return JVMTI_ERROR_OUT_OF_MEMORY; 1.2594 + strcpy(*name_ptr, fieldName); 1.2595 + } 1.2596 + if (signature_ptr== NULL) { 1.2597 + // just don't return the signature 1.2598 + } else { 1.2599 + const char* fieldSignature = fdesc_ptr->signature()->as_C_string(); 1.2600 + *signature_ptr = (char*) jvmtiMalloc(strlen(fieldSignature) + 1); 1.2601 + if (*signature_ptr == NULL) 1.2602 + return JVMTI_ERROR_OUT_OF_MEMORY; 1.2603 + strcpy(*signature_ptr, fieldSignature); 1.2604 + } 1.2605 + if (generic_ptr != NULL) { 1.2606 + *generic_ptr = NULL; 1.2607 + Symbol* soop = fdesc_ptr->generic_signature(); 1.2608 + if (soop != NULL) { 1.2609 + const char* gen_sig = soop->as_C_string(); 1.2610 + if (gen_sig != NULL) { 1.2611 + jvmtiError err = allocate(strlen(gen_sig) + 1, (unsigned char **)generic_ptr); 1.2612 + if (err != JVMTI_ERROR_NONE) { 1.2613 + return err; 1.2614 + } 1.2615 + strcpy(*generic_ptr, gen_sig); 1.2616 + } 1.2617 + } 1.2618 + } 1.2619 + return JVMTI_ERROR_NONE; 1.2620 +} /* end GetFieldName */ 1.2621 + 1.2622 + 1.2623 +// declaring_class_ptr - pre-checked for NULL 1.2624 +jvmtiError 1.2625 +JvmtiEnv::GetFieldDeclaringClass(fieldDescriptor* fdesc_ptr, jclass* declaring_class_ptr) { 1.2626 + 1.2627 + *declaring_class_ptr = get_jni_class_non_null(fdesc_ptr->field_holder()); 1.2628 + return JVMTI_ERROR_NONE; 1.2629 +} /* end GetFieldDeclaringClass */ 1.2630 + 1.2631 + 1.2632 +// modifiers_ptr - pre-checked for NULL 1.2633 +jvmtiError 1.2634 +JvmtiEnv::GetFieldModifiers(fieldDescriptor* fdesc_ptr, jint* modifiers_ptr) { 1.2635 + 1.2636 + AccessFlags resultFlags = fdesc_ptr->access_flags(); 1.2637 + jint result = resultFlags.as_int(); 1.2638 + *modifiers_ptr = result; 1.2639 + 1.2640 + return JVMTI_ERROR_NONE; 1.2641 +} /* end GetFieldModifiers */ 1.2642 + 1.2643 + 1.2644 +// is_synthetic_ptr - pre-checked for NULL 1.2645 +jvmtiError 1.2646 +JvmtiEnv::IsFieldSynthetic(fieldDescriptor* fdesc_ptr, jboolean* is_synthetic_ptr) { 1.2647 + *is_synthetic_ptr = fdesc_ptr->is_synthetic(); 1.2648 + return JVMTI_ERROR_NONE; 1.2649 +} /* end IsFieldSynthetic */ 1.2650 + 1.2651 + 1.2652 + // 1.2653 + // Method functions 1.2654 + // 1.2655 + 1.2656 +// method_oop - pre-checked for validity, but may be NULL meaning obsolete method 1.2657 +// name_ptr - NULL is a valid value, must be checked 1.2658 +// signature_ptr - NULL is a valid value, must be checked 1.2659 +// generic_ptr - NULL is a valid value, must be checked 1.2660 +jvmtiError 1.2661 +JvmtiEnv::GetMethodName(Method* method_oop, char** name_ptr, char** signature_ptr, char** generic_ptr) { 1.2662 + NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID); 1.2663 + JavaThread* current_thread = JavaThread::current(); 1.2664 + 1.2665 + ResourceMark rm(current_thread); // get the utf8 name and signature 1.2666 + if (name_ptr == NULL) { 1.2667 + // just don't return the name 1.2668 + } else { 1.2669 + const char* utf8_name = (const char *) method_oop->name()->as_utf8(); 1.2670 + *name_ptr = (char *) jvmtiMalloc(strlen(utf8_name)+1); 1.2671 + strcpy(*name_ptr, utf8_name); 1.2672 + } 1.2673 + if (signature_ptr == NULL) { 1.2674 + // just don't return the signature 1.2675 + } else { 1.2676 + const char* utf8_signature = (const char *) method_oop->signature()->as_utf8(); 1.2677 + *signature_ptr = (char *) jvmtiMalloc(strlen(utf8_signature) + 1); 1.2678 + strcpy(*signature_ptr, utf8_signature); 1.2679 + } 1.2680 + 1.2681 + if (generic_ptr != NULL) { 1.2682 + *generic_ptr = NULL; 1.2683 + Symbol* soop = method_oop->generic_signature(); 1.2684 + if (soop != NULL) { 1.2685 + const char* gen_sig = soop->as_C_string(); 1.2686 + if (gen_sig != NULL) { 1.2687 + jvmtiError err = allocate(strlen(gen_sig) + 1, (unsigned char **)generic_ptr); 1.2688 + if (err != JVMTI_ERROR_NONE) { 1.2689 + return err; 1.2690 + } 1.2691 + strcpy(*generic_ptr, gen_sig); 1.2692 + } 1.2693 + } 1.2694 + } 1.2695 + return JVMTI_ERROR_NONE; 1.2696 +} /* end GetMethodName */ 1.2697 + 1.2698 + 1.2699 +// method_oop - pre-checked for validity, but may be NULL meaning obsolete method 1.2700 +// declaring_class_ptr - pre-checked for NULL 1.2701 +jvmtiError 1.2702 +JvmtiEnv::GetMethodDeclaringClass(Method* method_oop, jclass* declaring_class_ptr) { 1.2703 + NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID); 1.2704 + (*declaring_class_ptr) = get_jni_class_non_null(method_oop->method_holder()); 1.2705 + return JVMTI_ERROR_NONE; 1.2706 +} /* end GetMethodDeclaringClass */ 1.2707 + 1.2708 + 1.2709 +// method_oop - pre-checked for validity, but may be NULL meaning obsolete method 1.2710 +// modifiers_ptr - pre-checked for NULL 1.2711 +jvmtiError 1.2712 +JvmtiEnv::GetMethodModifiers(Method* method_oop, jint* modifiers_ptr) { 1.2713 + NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID); 1.2714 + (*modifiers_ptr) = method_oop->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; 1.2715 + return JVMTI_ERROR_NONE; 1.2716 +} /* end GetMethodModifiers */ 1.2717 + 1.2718 + 1.2719 +// method_oop - pre-checked for validity, but may be NULL meaning obsolete method 1.2720 +// max_ptr - pre-checked for NULL 1.2721 +jvmtiError 1.2722 +JvmtiEnv::GetMaxLocals(Method* method_oop, jint* max_ptr) { 1.2723 + NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID); 1.2724 + // get max stack 1.2725 + (*max_ptr) = method_oop->max_locals(); 1.2726 + return JVMTI_ERROR_NONE; 1.2727 +} /* end GetMaxLocals */ 1.2728 + 1.2729 + 1.2730 +// method_oop - pre-checked for validity, but may be NULL meaning obsolete method 1.2731 +// size_ptr - pre-checked for NULL 1.2732 +jvmtiError 1.2733 +JvmtiEnv::GetArgumentsSize(Method* method_oop, jint* size_ptr) { 1.2734 + NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID); 1.2735 + // get size of arguments 1.2736 + 1.2737 + (*size_ptr) = method_oop->size_of_parameters(); 1.2738 + return JVMTI_ERROR_NONE; 1.2739 +} /* end GetArgumentsSize */ 1.2740 + 1.2741 + 1.2742 +// method_oop - pre-checked for validity, but may be NULL meaning obsolete method 1.2743 +// entry_count_ptr - pre-checked for NULL 1.2744 +// table_ptr - pre-checked for NULL 1.2745 +jvmtiError 1.2746 +JvmtiEnv::GetLineNumberTable(Method* method_oop, jint* entry_count_ptr, jvmtiLineNumberEntry** table_ptr) { 1.2747 + NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID); 1.2748 + if (!method_oop->has_linenumber_table()) { 1.2749 + return (JVMTI_ERROR_ABSENT_INFORMATION); 1.2750 + } 1.2751 + 1.2752 + // The line number table is compressed so we don't know how big it is until decompressed. 1.2753 + // Decompression is really fast so we just do it twice. 1.2754 + 1.2755 + // Compute size of table 1.2756 + jint num_entries = 0; 1.2757 + CompressedLineNumberReadStream stream(method_oop->compressed_linenumber_table()); 1.2758 + while (stream.read_pair()) { 1.2759 + num_entries++; 1.2760 + } 1.2761 + jvmtiLineNumberEntry *jvmti_table = 1.2762 + (jvmtiLineNumberEntry *)jvmtiMalloc(num_entries * (sizeof(jvmtiLineNumberEntry))); 1.2763 + 1.2764 + // Fill jvmti table 1.2765 + if (num_entries > 0) { 1.2766 + int index = 0; 1.2767 + CompressedLineNumberReadStream stream(method_oop->compressed_linenumber_table()); 1.2768 + while (stream.read_pair()) { 1.2769 + jvmti_table[index].start_location = (jlocation) stream.bci(); 1.2770 + jvmti_table[index].line_number = (jint) stream.line(); 1.2771 + index++; 1.2772 + } 1.2773 + assert(index == num_entries, "sanity check"); 1.2774 + } 1.2775 + 1.2776 + // Set up results 1.2777 + (*entry_count_ptr) = num_entries; 1.2778 + (*table_ptr) = jvmti_table; 1.2779 + 1.2780 + return JVMTI_ERROR_NONE; 1.2781 +} /* end GetLineNumberTable */ 1.2782 + 1.2783 + 1.2784 +// method_oop - pre-checked for validity, but may be NULL meaning obsolete method 1.2785 +// start_location_ptr - pre-checked for NULL 1.2786 +// end_location_ptr - pre-checked for NULL 1.2787 +jvmtiError 1.2788 +JvmtiEnv::GetMethodLocation(Method* method_oop, jlocation* start_location_ptr, jlocation* end_location_ptr) { 1.2789 + 1.2790 + NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID); 1.2791 + // get start and end location 1.2792 + (*end_location_ptr) = (jlocation) (method_oop->code_size() - 1); 1.2793 + if (method_oop->code_size() == 0) { 1.2794 + // there is no code so there is no start location 1.2795 + (*start_location_ptr) = (jlocation)(-1); 1.2796 + } else { 1.2797 + (*start_location_ptr) = (jlocation)(0); 1.2798 + } 1.2799 + 1.2800 + return JVMTI_ERROR_NONE; 1.2801 +} /* end GetMethodLocation */ 1.2802 + 1.2803 + 1.2804 +// method_oop - pre-checked for validity, but may be NULL meaning obsolete method 1.2805 +// entry_count_ptr - pre-checked for NULL 1.2806 +// table_ptr - pre-checked for NULL 1.2807 +jvmtiError 1.2808 +JvmtiEnv::GetLocalVariableTable(Method* method_oop, jint* entry_count_ptr, jvmtiLocalVariableEntry** table_ptr) { 1.2809 + 1.2810 + NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID); 1.2811 + JavaThread* current_thread = JavaThread::current(); 1.2812 + 1.2813 + // does the klass have any local variable information? 1.2814 + InstanceKlass* ik = method_oop->method_holder(); 1.2815 + if (!ik->access_flags().has_localvariable_table()) { 1.2816 + return (JVMTI_ERROR_ABSENT_INFORMATION); 1.2817 + } 1.2818 + 1.2819 + ConstantPool* constants = method_oop->constants(); 1.2820 + NULL_CHECK(constants, JVMTI_ERROR_ABSENT_INFORMATION); 1.2821 + 1.2822 + // in the vm localvariable table representation, 6 consecutive elements in the table 1.2823 + // represent a 6-tuple of shorts 1.2824 + // [start_pc, length, name_index, descriptor_index, signature_index, index] 1.2825 + jint num_entries = method_oop->localvariable_table_length(); 1.2826 + jvmtiLocalVariableEntry *jvmti_table = (jvmtiLocalVariableEntry *) 1.2827 + jvmtiMalloc(num_entries * (sizeof(jvmtiLocalVariableEntry))); 1.2828 + 1.2829 + if (num_entries > 0) { 1.2830 + LocalVariableTableElement* table = method_oop->localvariable_table_start(); 1.2831 + for (int i = 0; i < num_entries; i++) { 1.2832 + // get the 5 tuple information from the vm table 1.2833 + jlocation start_location = (jlocation) table[i].start_bci; 1.2834 + jint length = (jint) table[i].length; 1.2835 + int name_index = (int) table[i].name_cp_index; 1.2836 + int signature_index = (int) table[i].descriptor_cp_index; 1.2837 + int generic_signature_index = (int) table[i].signature_cp_index; 1.2838 + jint slot = (jint) table[i].slot; 1.2839 + 1.2840 + // get utf8 name and signature 1.2841 + char *name_buf = NULL; 1.2842 + char *sig_buf = NULL; 1.2843 + char *gen_sig_buf = NULL; 1.2844 + { 1.2845 + ResourceMark rm(current_thread); 1.2846 + 1.2847 + const char *utf8_name = (const char *) constants->symbol_at(name_index)->as_utf8(); 1.2848 + name_buf = (char *) jvmtiMalloc(strlen(utf8_name)+1); 1.2849 + strcpy(name_buf, utf8_name); 1.2850 + 1.2851 + const char *utf8_signature = (const char *) constants->symbol_at(signature_index)->as_utf8(); 1.2852 + sig_buf = (char *) jvmtiMalloc(strlen(utf8_signature)+1); 1.2853 + strcpy(sig_buf, utf8_signature); 1.2854 + 1.2855 + if (generic_signature_index > 0) { 1.2856 + const char *utf8_gen_sign = (const char *) 1.2857 + constants->symbol_at(generic_signature_index)->as_utf8(); 1.2858 + gen_sig_buf = (char *) jvmtiMalloc(strlen(utf8_gen_sign)+1); 1.2859 + strcpy(gen_sig_buf, utf8_gen_sign); 1.2860 + } 1.2861 + } 1.2862 + 1.2863 + // fill in the jvmti local variable table 1.2864 + jvmti_table[i].start_location = start_location; 1.2865 + jvmti_table[i].length = length; 1.2866 + jvmti_table[i].name = name_buf; 1.2867 + jvmti_table[i].signature = sig_buf; 1.2868 + jvmti_table[i].generic_signature = gen_sig_buf; 1.2869 + jvmti_table[i].slot = slot; 1.2870 + } 1.2871 + } 1.2872 + 1.2873 + // set results 1.2874 + (*entry_count_ptr) = num_entries; 1.2875 + (*table_ptr) = jvmti_table; 1.2876 + 1.2877 + return JVMTI_ERROR_NONE; 1.2878 +} /* end GetLocalVariableTable */ 1.2879 + 1.2880 + 1.2881 +// method_oop - pre-checked for validity, but may be NULL meaning obsolete method 1.2882 +// bytecode_count_ptr - pre-checked for NULL 1.2883 +// bytecodes_ptr - pre-checked for NULL 1.2884 +jvmtiError 1.2885 +JvmtiEnv::GetBytecodes(Method* method_oop, jint* bytecode_count_ptr, unsigned char** bytecodes_ptr) { 1.2886 + NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID); 1.2887 + 1.2888 + HandleMark hm; 1.2889 + methodHandle method(method_oop); 1.2890 + jint size = (jint)method->code_size(); 1.2891 + jvmtiError err = allocate(size, bytecodes_ptr); 1.2892 + if (err != JVMTI_ERROR_NONE) { 1.2893 + return err; 1.2894 + } 1.2895 + 1.2896 + (*bytecode_count_ptr) = size; 1.2897 + // get byte codes 1.2898 + JvmtiClassFileReconstituter::copy_bytecodes(method, *bytecodes_ptr); 1.2899 + 1.2900 + return JVMTI_ERROR_NONE; 1.2901 +} /* end GetBytecodes */ 1.2902 + 1.2903 + 1.2904 +// method_oop - pre-checked for validity, but may be NULL meaning obsolete method 1.2905 +// is_native_ptr - pre-checked for NULL 1.2906 +jvmtiError 1.2907 +JvmtiEnv::IsMethodNative(Method* method_oop, jboolean* is_native_ptr) { 1.2908 + NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID); 1.2909 + (*is_native_ptr) = method_oop->is_native(); 1.2910 + return JVMTI_ERROR_NONE; 1.2911 +} /* end IsMethodNative */ 1.2912 + 1.2913 + 1.2914 +// method_oop - pre-checked for validity, but may be NULL meaning obsolete method 1.2915 +// is_synthetic_ptr - pre-checked for NULL 1.2916 +jvmtiError 1.2917 +JvmtiEnv::IsMethodSynthetic(Method* method_oop, jboolean* is_synthetic_ptr) { 1.2918 + NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID); 1.2919 + (*is_synthetic_ptr) = method_oop->is_synthetic(); 1.2920 + return JVMTI_ERROR_NONE; 1.2921 +} /* end IsMethodSynthetic */ 1.2922 + 1.2923 + 1.2924 +// method_oop - pre-checked for validity, but may be NULL meaning obsolete method 1.2925 +// is_obsolete_ptr - pre-checked for NULL 1.2926 +jvmtiError 1.2927 +JvmtiEnv::IsMethodObsolete(Method* method_oop, jboolean* is_obsolete_ptr) { 1.2928 + if (use_version_1_0_semantics() && 1.2929 + get_capabilities()->can_redefine_classes == 0) { 1.2930 + // This JvmtiEnv requested version 1.0 semantics and this function 1.2931 + // requires the can_redefine_classes capability in version 1.0 so 1.2932 + // we need to return an error here. 1.2933 + return JVMTI_ERROR_MUST_POSSESS_CAPABILITY; 1.2934 + } 1.2935 + 1.2936 + if (method_oop == NULL || method_oop->is_obsolete()) { 1.2937 + *is_obsolete_ptr = true; 1.2938 + } else { 1.2939 + *is_obsolete_ptr = false; 1.2940 + } 1.2941 + return JVMTI_ERROR_NONE; 1.2942 +} /* end IsMethodObsolete */ 1.2943 + 1.2944 + // 1.2945 + // Raw Monitor functions 1.2946 + // 1.2947 + 1.2948 +// name - pre-checked for NULL 1.2949 +// monitor_ptr - pre-checked for NULL 1.2950 +jvmtiError 1.2951 +JvmtiEnv::CreateRawMonitor(const char* name, jrawMonitorID* monitor_ptr) { 1.2952 + JvmtiRawMonitor* rmonitor = new JvmtiRawMonitor(name); 1.2953 + NULL_CHECK(rmonitor, JVMTI_ERROR_OUT_OF_MEMORY); 1.2954 + 1.2955 + *monitor_ptr = (jrawMonitorID)rmonitor; 1.2956 + 1.2957 + return JVMTI_ERROR_NONE; 1.2958 +} /* end CreateRawMonitor */ 1.2959 + 1.2960 + 1.2961 +// rmonitor - pre-checked for validity 1.2962 +jvmtiError 1.2963 +JvmtiEnv::DestroyRawMonitor(JvmtiRawMonitor * rmonitor) { 1.2964 + if (Threads::number_of_threads() == 0) { 1.2965 + // Remove this monitor from pending raw monitors list 1.2966 + // if it has entered in onload or start phase. 1.2967 + JvmtiPendingMonitors::destroy(rmonitor); 1.2968 + } else { 1.2969 + Thread* thread = Thread::current(); 1.2970 + if (rmonitor->is_entered(thread)) { 1.2971 + // The caller owns this monitor which we are about to destroy. 1.2972 + // We exit the underlying synchronization object so that the 1.2973 + // "delete monitor" call below can work without an assertion 1.2974 + // failure on systems that don't like destroying synchronization 1.2975 + // objects that are locked. 1.2976 + int r; 1.2977 + intptr_t recursion = rmonitor->recursions(); 1.2978 + for (intptr_t i=0; i <= recursion; i++) { 1.2979 + r = rmonitor->raw_exit(thread); 1.2980 + assert(r == ObjectMonitor::OM_OK, "raw_exit should have worked"); 1.2981 + if (r != ObjectMonitor::OM_OK) { // robustness 1.2982 + return JVMTI_ERROR_INTERNAL; 1.2983 + } 1.2984 + } 1.2985 + } 1.2986 + if (rmonitor->owner() != NULL) { 1.2987 + // The caller is trying to destroy a monitor that is locked by 1.2988 + // someone else. While this is not forbidden by the JVMTI 1.2989 + // spec, it will cause an assertion failure on systems that don't 1.2990 + // like destroying synchronization objects that are locked. 1.2991 + // We indicate a problem with the error return (and leak the 1.2992 + // monitor's memory). 1.2993 + return JVMTI_ERROR_NOT_MONITOR_OWNER; 1.2994 + } 1.2995 + } 1.2996 + 1.2997 + delete rmonitor; 1.2998 + 1.2999 + return JVMTI_ERROR_NONE; 1.3000 +} /* end DestroyRawMonitor */ 1.3001 + 1.3002 + 1.3003 +// rmonitor - pre-checked for validity 1.3004 +jvmtiError 1.3005 +JvmtiEnv::RawMonitorEnter(JvmtiRawMonitor * rmonitor) { 1.3006 + if (Threads::number_of_threads() == 0) { 1.3007 + // No JavaThreads exist so ObjectMonitor enter cannot be 1.3008 + // used, add this raw monitor to the pending list. 1.3009 + // The pending monitors will be actually entered when 1.3010 + // the VM is setup. 1.3011 + // See transition_pending_raw_monitors in create_vm() 1.3012 + // in thread.cpp. 1.3013 + JvmtiPendingMonitors::enter(rmonitor); 1.3014 + } else { 1.3015 + int r; 1.3016 + Thread* thread = Thread::current(); 1.3017 + 1.3018 + if (thread->is_Java_thread()) { 1.3019 + JavaThread* current_thread = (JavaThread*)thread; 1.3020 + 1.3021 +#ifdef PROPER_TRANSITIONS 1.3022 + // Not really unknown but ThreadInVMfromNative does more than we want 1.3023 + ThreadInVMfromUnknown __tiv; 1.3024 + { 1.3025 + ThreadBlockInVM __tbivm(current_thread); 1.3026 + r = rmonitor->raw_enter(current_thread); 1.3027 + } 1.3028 +#else 1.3029 + /* Transition to thread_blocked without entering vm state */ 1.3030 + /* This is really evil. Normally you can't undo _thread_blocked */ 1.3031 + /* transitions like this because it would cause us to miss a */ 1.3032 + /* safepoint but since the thread was already in _thread_in_native */ 1.3033 + /* the thread is not leaving a safepoint safe state and it will */ 1.3034 + /* block when it tries to return from native. We can't safepoint */ 1.3035 + /* block in here because we could deadlock the vmthread. Blech. */ 1.3036 + 1.3037 + JavaThreadState state = current_thread->thread_state(); 1.3038 + assert(state == _thread_in_native, "Must be _thread_in_native"); 1.3039 + // frame should already be walkable since we are in native 1.3040 + assert(!current_thread->has_last_Java_frame() || 1.3041 + current_thread->frame_anchor()->walkable(), "Must be walkable"); 1.3042 + current_thread->set_thread_state(_thread_blocked); 1.3043 + 1.3044 + r = rmonitor->raw_enter(current_thread); 1.3045 + // restore state, still at a safepoint safe state 1.3046 + current_thread->set_thread_state(state); 1.3047 + 1.3048 +#endif /* PROPER_TRANSITIONS */ 1.3049 + assert(r == ObjectMonitor::OM_OK, "raw_enter should have worked"); 1.3050 + } else { 1.3051 + if (thread->is_VM_thread() || thread->is_ConcurrentGC_thread()) { 1.3052 + r = rmonitor->raw_enter(thread); 1.3053 + } else { 1.3054 + ShouldNotReachHere(); 1.3055 + } 1.3056 + } 1.3057 + 1.3058 + if (r != ObjectMonitor::OM_OK) { // robustness 1.3059 + return JVMTI_ERROR_INTERNAL; 1.3060 + } 1.3061 + } 1.3062 + return JVMTI_ERROR_NONE; 1.3063 +} /* end RawMonitorEnter */ 1.3064 + 1.3065 + 1.3066 +// rmonitor - pre-checked for validity 1.3067 +jvmtiError 1.3068 +JvmtiEnv::RawMonitorExit(JvmtiRawMonitor * rmonitor) { 1.3069 + jvmtiError err = JVMTI_ERROR_NONE; 1.3070 + 1.3071 + if (Threads::number_of_threads() == 0) { 1.3072 + // No JavaThreads exist so just remove this monitor from the pending list. 1.3073 + // Bool value from exit is false if rmonitor is not in the list. 1.3074 + if (!JvmtiPendingMonitors::exit(rmonitor)) { 1.3075 + err = JVMTI_ERROR_NOT_MONITOR_OWNER; 1.3076 + } 1.3077 + } else { 1.3078 + int r; 1.3079 + Thread* thread = Thread::current(); 1.3080 + 1.3081 + if (thread->is_Java_thread()) { 1.3082 + JavaThread* current_thread = (JavaThread*)thread; 1.3083 +#ifdef PROPER_TRANSITIONS 1.3084 + // Not really unknown but ThreadInVMfromNative does more than we want 1.3085 + ThreadInVMfromUnknown __tiv; 1.3086 +#endif /* PROPER_TRANSITIONS */ 1.3087 + r = rmonitor->raw_exit(current_thread); 1.3088 + } else { 1.3089 + if (thread->is_VM_thread() || thread->is_ConcurrentGC_thread()) { 1.3090 + r = rmonitor->raw_exit(thread); 1.3091 + } else { 1.3092 + ShouldNotReachHere(); 1.3093 + } 1.3094 + } 1.3095 + 1.3096 + if (r == ObjectMonitor::OM_ILLEGAL_MONITOR_STATE) { 1.3097 + err = JVMTI_ERROR_NOT_MONITOR_OWNER; 1.3098 + } else { 1.3099 + assert(r == ObjectMonitor::OM_OK, "raw_exit should have worked"); 1.3100 + if (r != ObjectMonitor::OM_OK) { // robustness 1.3101 + err = JVMTI_ERROR_INTERNAL; 1.3102 + } 1.3103 + } 1.3104 + } 1.3105 + return err; 1.3106 +} /* end RawMonitorExit */ 1.3107 + 1.3108 + 1.3109 +// rmonitor - pre-checked for validity 1.3110 +jvmtiError 1.3111 +JvmtiEnv::RawMonitorWait(JvmtiRawMonitor * rmonitor, jlong millis) { 1.3112 + int r; 1.3113 + Thread* thread = Thread::current(); 1.3114 + 1.3115 + if (thread->is_Java_thread()) { 1.3116 + JavaThread* current_thread = (JavaThread*)thread; 1.3117 +#ifdef PROPER_TRANSITIONS 1.3118 + // Not really unknown but ThreadInVMfromNative does more than we want 1.3119 + ThreadInVMfromUnknown __tiv; 1.3120 + { 1.3121 + ThreadBlockInVM __tbivm(current_thread); 1.3122 + r = rmonitor->raw_wait(millis, true, current_thread); 1.3123 + } 1.3124 +#else 1.3125 + /* Transition to thread_blocked without entering vm state */ 1.3126 + /* This is really evil. Normally you can't undo _thread_blocked */ 1.3127 + /* transitions like this because it would cause us to miss a */ 1.3128 + /* safepoint but since the thread was already in _thread_in_native */ 1.3129 + /* the thread is not leaving a safepoint safe state and it will */ 1.3130 + /* block when it tries to return from native. We can't safepoint */ 1.3131 + /* block in here because we could deadlock the vmthread. Blech. */ 1.3132 + 1.3133 + JavaThreadState state = current_thread->thread_state(); 1.3134 + assert(state == _thread_in_native, "Must be _thread_in_native"); 1.3135 + // frame should already be walkable since we are in native 1.3136 + assert(!current_thread->has_last_Java_frame() || 1.3137 + current_thread->frame_anchor()->walkable(), "Must be walkable"); 1.3138 + current_thread->set_thread_state(_thread_blocked); 1.3139 + 1.3140 + r = rmonitor->raw_wait(millis, true, current_thread); 1.3141 + // restore state, still at a safepoint safe state 1.3142 + current_thread->set_thread_state(state); 1.3143 + 1.3144 +#endif /* PROPER_TRANSITIONS */ 1.3145 + } else { 1.3146 + if (thread->is_VM_thread() || thread->is_ConcurrentGC_thread()) { 1.3147 + r = rmonitor->raw_wait(millis, true, thread); 1.3148 + } else { 1.3149 + ShouldNotReachHere(); 1.3150 + } 1.3151 + } 1.3152 + 1.3153 + switch (r) { 1.3154 + case ObjectMonitor::OM_INTERRUPTED: 1.3155 + return JVMTI_ERROR_INTERRUPT; 1.3156 + case ObjectMonitor::OM_ILLEGAL_MONITOR_STATE: 1.3157 + return JVMTI_ERROR_NOT_MONITOR_OWNER; 1.3158 + } 1.3159 + assert(r == ObjectMonitor::OM_OK, "raw_wait should have worked"); 1.3160 + if (r != ObjectMonitor::OM_OK) { // robustness 1.3161 + return JVMTI_ERROR_INTERNAL; 1.3162 + } 1.3163 + 1.3164 + return JVMTI_ERROR_NONE; 1.3165 +} /* end RawMonitorWait */ 1.3166 + 1.3167 + 1.3168 +// rmonitor - pre-checked for validity 1.3169 +jvmtiError 1.3170 +JvmtiEnv::RawMonitorNotify(JvmtiRawMonitor * rmonitor) { 1.3171 + int r; 1.3172 + Thread* thread = Thread::current(); 1.3173 + 1.3174 + if (thread->is_Java_thread()) { 1.3175 + JavaThread* current_thread = (JavaThread*)thread; 1.3176 + // Not really unknown but ThreadInVMfromNative does more than we want 1.3177 + ThreadInVMfromUnknown __tiv; 1.3178 + r = rmonitor->raw_notify(current_thread); 1.3179 + } else { 1.3180 + if (thread->is_VM_thread() || thread->is_ConcurrentGC_thread()) { 1.3181 + r = rmonitor->raw_notify(thread); 1.3182 + } else { 1.3183 + ShouldNotReachHere(); 1.3184 + } 1.3185 + } 1.3186 + 1.3187 + if (r == ObjectMonitor::OM_ILLEGAL_MONITOR_STATE) { 1.3188 + return JVMTI_ERROR_NOT_MONITOR_OWNER; 1.3189 + } 1.3190 + assert(r == ObjectMonitor::OM_OK, "raw_notify should have worked"); 1.3191 + if (r != ObjectMonitor::OM_OK) { // robustness 1.3192 + return JVMTI_ERROR_INTERNAL; 1.3193 + } 1.3194 + 1.3195 + return JVMTI_ERROR_NONE; 1.3196 +} /* end RawMonitorNotify */ 1.3197 + 1.3198 + 1.3199 +// rmonitor - pre-checked for validity 1.3200 +jvmtiError 1.3201 +JvmtiEnv::RawMonitorNotifyAll(JvmtiRawMonitor * rmonitor) { 1.3202 + int r; 1.3203 + Thread* thread = Thread::current(); 1.3204 + 1.3205 + if (thread->is_Java_thread()) { 1.3206 + JavaThread* current_thread = (JavaThread*)thread; 1.3207 + ThreadInVMfromUnknown __tiv; 1.3208 + r = rmonitor->raw_notifyAll(current_thread); 1.3209 + } else { 1.3210 + if (thread->is_VM_thread() || thread->is_ConcurrentGC_thread()) { 1.3211 + r = rmonitor->raw_notifyAll(thread); 1.3212 + } else { 1.3213 + ShouldNotReachHere(); 1.3214 + } 1.3215 + } 1.3216 + 1.3217 + if (r == ObjectMonitor::OM_ILLEGAL_MONITOR_STATE) { 1.3218 + return JVMTI_ERROR_NOT_MONITOR_OWNER; 1.3219 + } 1.3220 + assert(r == ObjectMonitor::OM_OK, "raw_notifyAll should have worked"); 1.3221 + if (r != ObjectMonitor::OM_OK) { // robustness 1.3222 + return JVMTI_ERROR_INTERNAL; 1.3223 + } 1.3224 + 1.3225 + return JVMTI_ERROR_NONE; 1.3226 +} /* end RawMonitorNotifyAll */ 1.3227 + 1.3228 + 1.3229 + // 1.3230 + // JNI Function Interception functions 1.3231 + // 1.3232 + 1.3233 + 1.3234 +// function_table - pre-checked for NULL 1.3235 +jvmtiError 1.3236 +JvmtiEnv::SetJNIFunctionTable(const jniNativeInterface* function_table) { 1.3237 + // Copy jni function table at safepoint. 1.3238 + VM_JNIFunctionTableCopier copier(function_table); 1.3239 + VMThread::execute(&copier); 1.3240 + 1.3241 + return JVMTI_ERROR_NONE; 1.3242 +} /* end SetJNIFunctionTable */ 1.3243 + 1.3244 + 1.3245 +// function_table - pre-checked for NULL 1.3246 +jvmtiError 1.3247 +JvmtiEnv::GetJNIFunctionTable(jniNativeInterface** function_table) { 1.3248 + *function_table=(jniNativeInterface*)jvmtiMalloc(sizeof(jniNativeInterface)); 1.3249 + if (*function_table == NULL) 1.3250 + return JVMTI_ERROR_OUT_OF_MEMORY; 1.3251 + memcpy(*function_table,(JavaThread::current())->get_jni_functions(),sizeof(jniNativeInterface)); 1.3252 + return JVMTI_ERROR_NONE; 1.3253 +} /* end GetJNIFunctionTable */ 1.3254 + 1.3255 + 1.3256 + // 1.3257 + // Event Management functions 1.3258 + // 1.3259 + 1.3260 +jvmtiError 1.3261 +JvmtiEnv::GenerateEvents(jvmtiEvent event_type) { 1.3262 + // can only generate two event types 1.3263 + if (event_type != JVMTI_EVENT_COMPILED_METHOD_LOAD && 1.3264 + event_type != JVMTI_EVENT_DYNAMIC_CODE_GENERATED) { 1.3265 + return JVMTI_ERROR_ILLEGAL_ARGUMENT; 1.3266 + } 1.3267 + 1.3268 + // for compiled_method_load events we must check that the environment 1.3269 + // has the can_generate_compiled_method_load_events capability. 1.3270 + if (event_type == JVMTI_EVENT_COMPILED_METHOD_LOAD) { 1.3271 + if (get_capabilities()->can_generate_compiled_method_load_events == 0) { 1.3272 + return JVMTI_ERROR_MUST_POSSESS_CAPABILITY; 1.3273 + } 1.3274 + return JvmtiCodeBlobEvents::generate_compiled_method_load_events(this); 1.3275 + } else { 1.3276 + return JvmtiCodeBlobEvents::generate_dynamic_code_events(this); 1.3277 + } 1.3278 + 1.3279 +} /* end GenerateEvents */ 1.3280 + 1.3281 + 1.3282 + // 1.3283 + // Extension Mechanism functions 1.3284 + // 1.3285 + 1.3286 +// extension_count_ptr - pre-checked for NULL 1.3287 +// extensions - pre-checked for NULL 1.3288 +jvmtiError 1.3289 +JvmtiEnv::GetExtensionFunctions(jint* extension_count_ptr, jvmtiExtensionFunctionInfo** extensions) { 1.3290 + return JvmtiExtensions::get_functions(this, extension_count_ptr, extensions); 1.3291 +} /* end GetExtensionFunctions */ 1.3292 + 1.3293 + 1.3294 +// extension_count_ptr - pre-checked for NULL 1.3295 +// extensions - pre-checked for NULL 1.3296 +jvmtiError 1.3297 +JvmtiEnv::GetExtensionEvents(jint* extension_count_ptr, jvmtiExtensionEventInfo** extensions) { 1.3298 + return JvmtiExtensions::get_events(this, extension_count_ptr, extensions); 1.3299 +} /* end GetExtensionEvents */ 1.3300 + 1.3301 + 1.3302 +// callback - NULL is a valid value, must be checked 1.3303 +jvmtiError 1.3304 +JvmtiEnv::SetExtensionEventCallback(jint extension_event_index, jvmtiExtensionEvent callback) { 1.3305 + return JvmtiExtensions::set_event_callback(this, extension_event_index, callback); 1.3306 +} /* end SetExtensionEventCallback */ 1.3307 + 1.3308 + // 1.3309 + // Timers functions 1.3310 + // 1.3311 + 1.3312 +// info_ptr - pre-checked for NULL 1.3313 +jvmtiError 1.3314 +JvmtiEnv::GetCurrentThreadCpuTimerInfo(jvmtiTimerInfo* info_ptr) { 1.3315 + os::current_thread_cpu_time_info(info_ptr); 1.3316 + return JVMTI_ERROR_NONE; 1.3317 +} /* end GetCurrentThreadCpuTimerInfo */ 1.3318 + 1.3319 + 1.3320 +// nanos_ptr - pre-checked for NULL 1.3321 +jvmtiError 1.3322 +JvmtiEnv::GetCurrentThreadCpuTime(jlong* nanos_ptr) { 1.3323 + *nanos_ptr = os::current_thread_cpu_time(); 1.3324 + return JVMTI_ERROR_NONE; 1.3325 +} /* end GetCurrentThreadCpuTime */ 1.3326 + 1.3327 + 1.3328 +// info_ptr - pre-checked for NULL 1.3329 +jvmtiError 1.3330 +JvmtiEnv::GetThreadCpuTimerInfo(jvmtiTimerInfo* info_ptr) { 1.3331 + os::thread_cpu_time_info(info_ptr); 1.3332 + return JVMTI_ERROR_NONE; 1.3333 +} /* end GetThreadCpuTimerInfo */ 1.3334 + 1.3335 + 1.3336 +// Threads_lock NOT held, java_thread not protected by lock 1.3337 +// java_thread - pre-checked 1.3338 +// nanos_ptr - pre-checked for NULL 1.3339 +jvmtiError 1.3340 +JvmtiEnv::GetThreadCpuTime(JavaThread* java_thread, jlong* nanos_ptr) { 1.3341 + *nanos_ptr = os::thread_cpu_time(java_thread); 1.3342 + return JVMTI_ERROR_NONE; 1.3343 +} /* end GetThreadCpuTime */ 1.3344 + 1.3345 + 1.3346 +// info_ptr - pre-checked for NULL 1.3347 +jvmtiError 1.3348 +JvmtiEnv::GetTimerInfo(jvmtiTimerInfo* info_ptr) { 1.3349 + os::javaTimeNanos_info(info_ptr); 1.3350 + return JVMTI_ERROR_NONE; 1.3351 +} /* end GetTimerInfo */ 1.3352 + 1.3353 + 1.3354 +// nanos_ptr - pre-checked for NULL 1.3355 +jvmtiError 1.3356 +JvmtiEnv::GetTime(jlong* nanos_ptr) { 1.3357 + *nanos_ptr = os::javaTimeNanos(); 1.3358 + return JVMTI_ERROR_NONE; 1.3359 +} /* end GetTime */ 1.3360 + 1.3361 + 1.3362 +// processor_count_ptr - pre-checked for NULL 1.3363 +jvmtiError 1.3364 +JvmtiEnv::GetAvailableProcessors(jint* processor_count_ptr) { 1.3365 + *processor_count_ptr = os::active_processor_count(); 1.3366 + return JVMTI_ERROR_NONE; 1.3367 +} /* end GetAvailableProcessors */ 1.3368 + 1.3369 + // 1.3370 + // System Properties functions 1.3371 + // 1.3372 + 1.3373 +// count_ptr - pre-checked for NULL 1.3374 +// property_ptr - pre-checked for NULL 1.3375 +jvmtiError 1.3376 +JvmtiEnv::GetSystemProperties(jint* count_ptr, char*** property_ptr) { 1.3377 + jvmtiError err = JVMTI_ERROR_NONE; 1.3378 + 1.3379 + *count_ptr = Arguments::PropertyList_count(Arguments::system_properties()); 1.3380 + 1.3381 + err = allocate(*count_ptr * sizeof(char *), (unsigned char **)property_ptr); 1.3382 + if (err != JVMTI_ERROR_NONE) { 1.3383 + return err; 1.3384 + } 1.3385 + int i = 0 ; 1.3386 + for (SystemProperty* p = Arguments::system_properties(); p != NULL && i < *count_ptr; p = p->next(), i++) { 1.3387 + const char *key = p->key(); 1.3388 + char **tmp_value = *property_ptr+i; 1.3389 + err = allocate((strlen(key)+1) * sizeof(char), (unsigned char**)tmp_value); 1.3390 + if (err == JVMTI_ERROR_NONE) { 1.3391 + strcpy(*tmp_value, key); 1.3392 + } else { 1.3393 + // clean up previously allocated memory. 1.3394 + for (int j=0; j<i; j++) { 1.3395 + Deallocate((unsigned char*)*property_ptr+j); 1.3396 + } 1.3397 + Deallocate((unsigned char*)property_ptr); 1.3398 + break; 1.3399 + } 1.3400 + } 1.3401 + return err; 1.3402 +} /* end GetSystemProperties */ 1.3403 + 1.3404 + 1.3405 +// property - pre-checked for NULL 1.3406 +// value_ptr - pre-checked for NULL 1.3407 +jvmtiError 1.3408 +JvmtiEnv::GetSystemProperty(const char* property, char** value_ptr) { 1.3409 + jvmtiError err = JVMTI_ERROR_NONE; 1.3410 + const char *value; 1.3411 + 1.3412 + value = Arguments::PropertyList_get_value(Arguments::system_properties(), property); 1.3413 + if (value == NULL) { 1.3414 + err = JVMTI_ERROR_NOT_AVAILABLE; 1.3415 + } else { 1.3416 + err = allocate((strlen(value)+1) * sizeof(char), (unsigned char **)value_ptr); 1.3417 + if (err == JVMTI_ERROR_NONE) { 1.3418 + strcpy(*value_ptr, value); 1.3419 + } 1.3420 + } 1.3421 + return err; 1.3422 +} /* end GetSystemProperty */ 1.3423 + 1.3424 + 1.3425 +// property - pre-checked for NULL 1.3426 +// value - NULL is a valid value, must be checked 1.3427 +jvmtiError 1.3428 +JvmtiEnv::SetSystemProperty(const char* property, const char* value_ptr) { 1.3429 + jvmtiError err =JVMTI_ERROR_NOT_AVAILABLE; 1.3430 + 1.3431 + for (SystemProperty* p = Arguments::system_properties(); p != NULL; p = p->next()) { 1.3432 + if (strcmp(property, p->key()) == 0) { 1.3433 + if (p->set_value((char *)value_ptr)) { 1.3434 + err = JVMTI_ERROR_NONE; 1.3435 + } 1.3436 + } 1.3437 + } 1.3438 + return err; 1.3439 +} /* end SetSystemProperty */