/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "interpreter/bytecodeStream.hpp"
#include "interpreter/interpreter.hpp"
#include "jvmtifiles/jvmtiEnv.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.inline.hpp"
#include "oops/cpCacheOop.hpp"
#include "oops/instanceKlass.hpp"
#include "prims/jniCheck.hpp"
#include "prims/jvm_misc.hpp"
#include "prims/jvmtiAgentThread.hpp"
#include "prims/jvmtiClassFileReconstituter.hpp"
#include "prims/jvmtiCodeBlobEvents.hpp"
#include "prims/jvmtiExtensions.hpp"
#include "prims/jvmtiGetLoadedClasses.hpp"
#include "prims/jvmtiImpl.hpp"
#include "prims/jvmtiManageCapabilities.hpp"
#include "prims/jvmtiRawMonitor.hpp"
#include "prims/jvmtiRedefineClasses.hpp"
#include "prims/jvmtiTagMap.hpp"
#include "prims/jvmtiThreadState.inline.hpp"
#include "prims/jvmtiUtil.hpp"
#include "runtime/arguments.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/jfieldIDWorkaround.hpp"
#include "runtime/osThread.hpp"
#include "runtime/reflectionUtils.hpp"
#include "runtime/signature.hpp"
#include "runtime/vframe.hpp"
#include "runtime/vmThread.hpp"
#include "services/threadService.hpp"
#include "utilities/exceptions.hpp"
#include "utilities/preserveException.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "thread_linux.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "thread_solaris.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_windows
# include "thread_windows.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "thread_bsd.inline.hpp"
#endif
// FIXLATER: hook into JvmtiTrace
#define TraceJVMTICalls false
}
}
}
// VM operation class to copy jni function table at safepoint.
// More than one java threads or jvmti agents may be reading/
// modifying jni function tables. To reduce the risk of bad
// interaction b/w these threads it is copied at safepoint.
private:
public:
};
void doit() {
};
};
//
// Do not change the "prefix" marker below, everything above it is copied
// unchanged into the filled stub, everything below is controlled by the
// stub filler (only method bodies are carried forward, and then only for
// functionality still in the spec).
//
// end file prefix
//
// Memory Management functions
//
// mem_ptr - pre-checked for NULL
} /* end Allocate */
// mem - NULL is a valid value, must be checked
return deallocate(mem);
} /* end Deallocate */
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
// data - NULL is a valid value, must be checked
// leaving state unset same as data set to NULL
return JVMTI_ERROR_NONE;
}
// otherwise, create the state
return JVMTI_ERROR_THREAD_NOT_ALIVE;
}
}
return JVMTI_ERROR_NONE;
} /* end SetThreadLocalStorage */
// Threads_lock NOT held
// thread - NOT pre-checked
// data_ptr - pre-checked for NULL
} else {
// jvmti_GetThreadLocalStorage is "in native" and doesn't transition
// the thread to _thread_in_vm. However, when the TLS for a thread
// other than the current thread is required we need to transition
// from native so as to resolve the jthread.
if (thread_oop == NULL) {
return JVMTI_ERROR_INVALID_THREAD;
}
return JVMTI_ERROR_INVALID_THREAD;
}
if (java_thread == NULL) {
return JVMTI_ERROR_THREAD_NOT_ALIVE;
}
}
return JVMTI_ERROR_NONE;
} /* end GetThreadLocalStorage */
//
// Class functions
//
// class_count_ptr - pre-checked for NULL
// classes_ptr - pre-checked for NULL
} /* end GetLoadedClasses */
// initiating_loader - NULL is a valid value, must be checked
// class_count_ptr - pre-checked for NULL
// classes_ptr - pre-checked for NULL
JvmtiEnv::GetClassLoaderClasses(jobject initiating_loader, jint* class_count_ptr, jclass** classes_ptr) {
} /* end GetClassLoaderClasses */
// k_mirror - may be primitive, this must be checked
// is_modifiable_class_ptr - pre-checked for NULL
return JVMTI_ERROR_NONE;
} /* end IsModifiableClass */
// class_count - pre-checked to be greater than or equal to 0
// classes - pre-checked for NULL
//TODO: add locking
int index;
return JVMTI_ERROR_INVALID_CLASS;
}
return JVMTI_ERROR_INVALID_CLASS;
}
return JVMTI_ERROR_UNMODIFIABLE_CLASS;
}
if (status & (JVMTI_CLASS_STATUS_ERROR)) {
return JVMTI_ERROR_INVALID_CLASS;
}
if (status & (JVMTI_CLASS_STATUS_ARRAY)) {
return JVMTI_ERROR_UNMODIFIABLE_CLASS;
}
// Not cached, we need to reconstitute the class file from the
// VM representation. We don't attach the reconstituted class
// bytes to the instanceKlass here because they have not been
// validated and we're not at a safepoint.
return reconstituter.get_error();
}
} else {
// it is cached, get it from the cache
}
}
return (op.check_error());
} /* end RetransformClasses */
// class_count - pre-checked to be greater than or equal to 0
// class_definitions - pre-checked for NULL
//TODO: add locking
return (op.check_error());
} /* end RedefineClasses */
//
// Object functions
//
// size_ptr - pre-checked for NULL
}
}
return JVMTI_ERROR_NONE;
} /* end GetObjectSize */
//
// Method functions
//
// prefix - NULL is a valid value, must be checked
SetNativeMethodPrefixes(0, NULL) :
} /* end SetNativeMethodPrefix */
// prefix_count - pre-checked to be greater than or equal to 0
// prefixes - pre-checked for NULL
// Have to grab JVMTI thread state lock to be sure that some thread
// isn't accessing the prefixes at the same time we are setting them.
// No locks during VM bring-up.
if (Threads::number_of_threads() == 0) {
} else {
}
} /* end SetNativeMethodPrefixes */
//
// Event Management functions
//
// callbacks - NULL is a valid value, must be checked
// size_of_callbacks - pre-checked to be greater than or equal to 0
return JVMTI_ERROR_NONE;
} /* end SetEventCallbacks */
// event_thread - NULL is a valid value, must be checked
JvmtiEnv::SetEventNotificationMode(jvmtiEventMode mode, jvmtiEvent event_type, jthread event_thread, ...) {
if (event_thread != NULL) {
if (thread_oop == NULL) {
return JVMTI_ERROR_INVALID_THREAD;
}
return JVMTI_ERROR_INVALID_THREAD;
}
if (java_thread == NULL) {
return JVMTI_ERROR_THREAD_NOT_ALIVE;
}
}
// event_type must be valid
return JVMTI_ERROR_INVALID_EVENT_TYPE;
}
// global events cannot be controlled at thread level.
return JVMTI_ERROR_ILLEGAL_ARGUMENT;
}
// assure that needed capabilities are present
}
}
return JVMTI_ERROR_NONE;
} /* end SetEventNotificationMode */
//
// Capability functions
//
// capabilities_ptr - pre-checked for NULL
return JVMTI_ERROR_NONE;
} /* end GetPotentialCapabilities */
// capabilities_ptr - pre-checked for NULL
get_capabilities());
} /* end AddCapabilities */
// capabilities_ptr - pre-checked for NULL
JvmtiManageCapabilities::relinquish_capabilities(get_capabilities(), capabilities_ptr, get_capabilities());
return JVMTI_ERROR_NONE;
} /* end RelinquishCapabilities */
// capabilities_ptr - pre-checked for NULL
return JVMTI_ERROR_NONE;
} /* end GetCapabilities */
//
// Class Loader Search functions
//
// segment - pre-checked for NULL
if (phase == JVMTI_PHASE_ONLOAD) {
return JVMTI_ERROR_NONE;
} else if (use_version_1_0_semantics()) {
// This JvmtiEnv requested version 1.0 semantics and this function
// is only allowed in the ONLOAD phase in version 1.0 so we need to
// return an error here.
return JVMTI_ERROR_WRONG_PHASE;
} else if (phase == JVMTI_PHASE_LIVE) {
// The phase is checked by the wrapper that called this function,
// but this thread could be racing with the thread that is
// terminating the VM so we check one more time.
// create the zip entry
return JVMTI_ERROR_ILLEGAL_ARGUMENT;
}
// lock the loader
// add the jar file to the bootclasspath
if (TraceClassLoading) {
}
return JVMTI_ERROR_NONE;
} else {
return JVMTI_ERROR_WRONG_PHASE;
}
} /* end AddToBootstrapClassLoaderSearch */
// segment - pre-checked for NULL
if (phase == JVMTI_PHASE_ONLOAD) {
p->append_value(segment);
break;
}
}
return JVMTI_ERROR_NONE;
} else if (phase == JVMTI_PHASE_LIVE) {
// The phase is checked by the wrapper that called this function,
// but this thread could be racing with the thread that is
// terminating the VM so we check one more time.
// create the zip entry (which will open the zip file and hence
// check that the segment is indeed a zip file).
return JVMTI_ERROR_ILLEGAL_ARGUMENT;
}
delete zip_entry; // no longer needed
// lock the loader
// need the path as java.lang.String
if (HAS_PENDING_EXCEPTION) {
return JVMTI_ERROR_INTERNAL;
}
// Invoke the appendToClassPathForInstrumentation method - if the method
// is not found it means the loader doesn't support adding to the class path
// in the live phase.
{
path,
THREAD);
if (HAS_PENDING_EXCEPTION) {
} else {
return JVMTI_ERROR_INTERNAL;
}
}
}
return JVMTI_ERROR_NONE;
} else {
return JVMTI_ERROR_WRONG_PHASE;
}
} /* end AddToSystemClassLoaderSearch */
//
// General functions
//
// phase_ptr - pre-checked for NULL
return JVMTI_ERROR_NONE;
} /* end GetPhase */
dispose();
return JVMTI_ERROR_NONE;
} /* end DisposeEnvironment */
// data - NULL is a valid value, must be checked
return JVMTI_ERROR_NONE;
} /* end SetEnvironmentLocalStorage */
// data_ptr - pre-checked for NULL
*data_ptr = (void*)get_env_local_storage();
return JVMTI_ERROR_NONE;
} /* end GetEnvironmentLocalStorage */
// version_ptr - pre-checked for NULL
return JVMTI_ERROR_NONE;
} /* end GetVersionNumber */
// name_ptr - pre-checked for NULL
return JVMTI_ERROR_ILLEGAL_ARGUMENT;
}
return JVMTI_ERROR_ILLEGAL_ARGUMENT;
}
if (err == JVMTI_ERROR_NONE) {
}
return err;
} /* end GetErrorName */
switch (flag) {
case JVMTI_VERBOSE_OTHER:
// ignore
break;
case JVMTI_VERBOSE_CLASS:
TraceClassLoading = value != 0;
TraceClassUnloading = value != 0;
break;
case JVMTI_VERBOSE_GC:
break;
case JVMTI_VERBOSE_JNI:
PrintJNIResolving = value != 0;
break;
default:
return JVMTI_ERROR_ILLEGAL_ARGUMENT;
};
return JVMTI_ERROR_NONE;
} /* end SetVerboseFlag */
// format_ptr - pre-checked for NULL
return JVMTI_ERROR_NONE;
} /* end GetJLocationFormat */
//
// Thread functions
//
// Threads_lock NOT held
// thread - NOT pre-checked
// thread_state_ptr - pre-checked for NULL
} else {
}
return JVMTI_ERROR_INVALID_THREAD;
}
// get most state bits
// add more state bits
if (thr->is_being_ext_suspended()) {
}
if (jts == _thread_in_native) {
}
}
}
return JVMTI_ERROR_NONE;
} /* end GetThreadState */
// thread_ptr - pre-checked for NULL
return JVMTI_ERROR_NONE;
} /* end GetCurrentThread */
// threads_count_ptr - pre-checked for NULL
// threads_ptr - pre-checked for NULL
int nthreads = 0;
// enumerate threads (including agent threads)
if (nthreads == 0) {
*threads_ptr = NULL;
return JVMTI_ERROR_NONE;
}
for (int i=0; i < nthreads; i++) {
}
// have to make global handles outside of Threads_lock
*threads_ptr = jthreads;
return JVMTI_ERROR_NONE;
} /* end GetAllThreads */
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
// don't allow hidden thread suspend request.
if (java_thread->is_hidden_from_external_view()) {
return (JVMTI_ERROR_NONE);
}
{
if (java_thread->is_external_suspend()) {
// don't allow nested external suspend requests.
return (JVMTI_ERROR_THREAD_SUSPENDED);
}
return (JVMTI_ERROR_THREAD_NOT_ALIVE);
}
}
// the thread was in the process of exiting
return (JVMTI_ERROR_THREAD_NOT_ALIVE);
}
return JVMTI_ERROR_NONE;
} /* end SuspendThread */
// request_count - pre-checked to be greater than or equal to 0
// request_list - pre-checked for NULL
// results - pre-checked for NULL
for (int i = 0; i < request_count; i++) {
if (java_thread == NULL) {
continue;
}
// the thread has not yet run or has exited (not on threads list)
continue;
}
continue;
}
// don't allow hidden thread suspend request.
if (java_thread->is_hidden_from_external_view()) {
continue;
}
{
if (java_thread->is_external_suspend()) {
// don't allow nested external suspend requests.
continue;
}
continue;
}
}
// We need to try and suspend native threads here. Threads in
// other states will self-suspend on their next transition.
// The thread was in the process of exiting. Force another
// safepoint to make sure that this thread transitions.
continue;
}
} else {
}
}
if (needSafepoint > 0) {
}
// per-thread suspend results returned via results parameter
return JVMTI_ERROR_NONE;
} /* end SuspendThreadList */
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
// don't allow hidden thread resume request.
if (java_thread->is_hidden_from_external_view()) {
return JVMTI_ERROR_NONE;
}
if (!java_thread->is_being_ext_suspended()) {
return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
}
return JVMTI_ERROR_INTERNAL;
}
return JVMTI_ERROR_NONE;
} /* end ResumeThread */
// request_count - pre-checked to be greater than or equal to 0
// request_list - pre-checked for NULL
// results - pre-checked for NULL
for (int i = 0; i < request_count; i++) {
if (java_thread == NULL) {
continue;
}
// don't allow hidden thread resume request.
if (java_thread->is_hidden_from_external_view()) {
continue;
}
if (!java_thread->is_being_ext_suspended()) {
continue;
}
results[i] = JVMTI_ERROR_INTERNAL;
continue;
}
}
// per-thread resume results returned via results parameter
return JVMTI_ERROR_NONE;
} /* end ResumeThreadList */
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
return JVMTI_ERROR_NONE;
} /* end StopThread */
// Threads_lock NOT held
// thread - NOT pre-checked
return JVMTI_ERROR_INVALID_THREAD;
// Todo: this is a duplicate of JVM_Interrupt; share code in future
// Ensure that the C++ Thread and OSThread structures aren't freed before we operate
// We need to re-resolve the java_thread, since a GC might have happened during the
// acquire of the lock
return JVMTI_ERROR_NONE;
} /* end InterruptThread */
// Threads_lock NOT held
// thread - NOT pre-checked
// info_ptr - pre-checked for NULL
// if thread is NULL the current thread is used
} else {
}
return JVMTI_ERROR_INVALID_THREAD;
bool is_daemon;
}
{ const char *n;
} else {
}
return JVMTI_ERROR_OUT_OF_MEMORY;
}
return JVMTI_ERROR_NONE;
} /* end GetThreadInfo */
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
// owned_monitor_count_ptr - pre-checked for NULL
// owned_monitors_ptr - pre-checked for NULL
JvmtiEnv::GetOwnedMonitorInfo(JavaThread* java_thread, jint* owned_monitor_count_ptr, jobject** owned_monitors_ptr) {
// growable array of jvmti monitors info on the C-heap
} else {
// JVMTI get monitors info at safepoint. Do not require target thread to
// be suspended.
}
if (err == JVMTI_ERROR_NONE) {
(unsigned char**)owned_monitors_ptr)) == JVMTI_ERROR_NONE) {
// copy into the returned array
for (int i = 0; i < owned_monitor_count; i++) {
(*owned_monitors_ptr)[i] =
}
}
}
// clean up.
for (int i = 0; i < owned_monitor_count; i++) {
}
delete owned_monitors_list;
return err;
} /* end GetOwnedMonitorInfo */
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
// monitor_info_count_ptr - pre-checked for NULL
// monitor_info_ptr - pre-checked for NULL
JvmtiEnv::GetOwnedMonitorStackDepthInfo(JavaThread* java_thread, jint* monitor_info_count_ptr, jvmtiMonitorStackDepthInfo** monitor_info_ptr) {
// growable array of jvmti monitors info on the C-heap
} else {
// JVMTI get owned monitors info at safepoint. Do not require target thread to
// be suspended.
}
if (err == JVMTI_ERROR_NONE) {
(unsigned char**)monitor_info_ptr)) == JVMTI_ERROR_NONE) {
// copy to output array.
for (int i = 0; i < owned_monitor_count; i++) {
(*monitor_info_ptr)[i].monitor =
(*monitor_info_ptr)[i].stack_depth =
}
}
}
// clean up.
for (int i = 0; i < owned_monitor_count; i++) {
}
delete owned_monitors_list;
return err;
} /* end GetOwnedMonitorStackDepthInfo */
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
// monitor_ptr - pre-checked for NULL
} else {
// get contended monitor information at safepoint.
}
return err;
} /* end GetCurrentContendedMonitor */
// Threads_lock NOT held
// thread - NOT pre-checked
// proc - pre-checked for NULL
// arg - NULL is a valid value, must be checked
return JVMTI_ERROR_INVALID_THREAD;
}
return JVMTI_ERROR_INVALID_PRIORITY;
}
//Thread-self
{
// At this point it may be possible that no osthread was created for the
// JavaThread due to lack of memory.
if (new_thread) delete new_thread;
return JVMTI_ERROR_OUT_OF_MEMORY;
}
} // unlock Threads_lock
return JVMTI_ERROR_NONE;
} /* end RunAgentThread */
//
// Thread Group functions
//
// group_count_ptr - pre-checked for NULL
// groups_ptr - pre-checked for NULL
// Only one top level thread group now.
*group_count_ptr = 1;
// Allocate memory to store global-refs to the thread groups.
// Assume this area is freed by caller.
// Convert oop to Handle, then convert Handle to global-ref.
{
}
return JVMTI_ERROR_NONE;
} /* end GetTopThreadGroups */
// info_ptr - pre-checked for NULL
bool is_daemon;
}
} else {
}
return JVMTI_ERROR_NONE;
} /* end GetThreadGroupInfo */
// thread_count_ptr - pre-checked for NULL
// threads_ptr - pre-checked for NULL
// group_count_ptr - pre-checked for NULL
// groups_ptr - pre-checked for NULL
JvmtiEnv::GetThreadGroupChildren(jthreadGroup group, jint* thread_count_ptr, jthread** threads_ptr, jint* group_count_ptr, jthreadGroup** groups_ptr) {
int nthreads = 0;
int ngroups = 0;
int hidden_threads = 0;
if (nthreads > 0) {
for (int i=0, j=0; i<nthreads; i++) {
// Filter out hidden java threads.
continue;
}
}
}
if (ngroups > 0) {
for (int i=0; i<ngroups; i++) {
}
}
}
// have to make global handles outside of Threads_lock
return JVMTI_ERROR_OUT_OF_MEMORY;
}
return JVMTI_ERROR_OUT_OF_MEMORY;
}
return JVMTI_ERROR_NONE;
} /* end GetThreadGroupChildren */
//
// Stack Frame functions
//
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
// max_frame_count - pre-checked to be greater than or equal to 0
// frame_buffer - pre-checked for NULL
// count_ptr - pre-checked for NULL
JvmtiEnv::GetStackTrace(JavaThread* java_thread, jint start_depth, jint max_frame_count, jvmtiFrameInfo* frame_buffer, jint* count_ptr) {
} else {
// JVMTI get stack trace at safepoint. Do not require target thread to
// be suspended.
}
return err;
} /* end GetStackTrace */
// max_frame_count - pre-checked to be greater than or equal to 0
// stack_info_ptr - pre-checked for NULL
// thread_count_ptr - pre-checked for NULL
JvmtiEnv::GetAllStackTraces(jint max_frame_count, jvmtiStackInfo** stack_info_ptr, jint* thread_count_ptr) {
// JVMTI get stack traces at safepoint.
return err;
} /* end GetAllStackTraces */
// thread_count - pre-checked to be greater than or equal to 0
// thread_list - pre-checked for NULL
// max_frame_count - pre-checked to be greater than or equal to 0
// stack_info_ptr - pre-checked for NULL
JvmtiEnv::GetThreadListStackTraces(jint thread_count, const jthread* thread_list, jint max_frame_count, jvmtiStackInfo** stack_info_ptr) {
// JVMTI get stack traces at safepoint.
if (err == JVMTI_ERROR_NONE) {
}
return err;
} /* end GetThreadListStackTraces */
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
// count_ptr - pre-checked for NULL
// retrieve or create JvmtiThreadState.
return JVMTI_ERROR_THREAD_NOT_ALIVE;
}
} else {
// get java stack frame count at safepoint.
}
return err;
} /* end GetFrameCount */
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
// retrieve or create the state
return JVMTI_ERROR_THREAD_NOT_ALIVE;
}
// Check if java_thread is fully suspended
return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
}
// Check to see if a PopFrame was already in progress
// Probably possible for JVMTI clients to trigger this, but the
// JPDA backend shouldn't allow this to happen
return JVMTI_ERROR_INTERNAL;
}
{
// Was workaround bug
// 4812902: popFrame hangs if the method is waiting at a synchronize
// Catch this condition and return an error to avoid hanging.
// Now JVMTI spec allows an implementation to bail out with an opaque frame error.
return JVMTI_ERROR_OPAQUE_FRAME;
}
}
{
// Check if there are more than one Java frame in this thread, that the top two frames
// are Java (not native) frames, and that there is no intervening VM frame
int frame_count = 0;
// The 2-nd arg of constructor is needed to stop iterating at java entry frame.
if (++frame_count > 1) break;
}
if (frame_count < 2) {
// We haven't found two adjacent non-native Java frames on the top.
// There can be two situations here:
// 1. There are no more java frames
// 2. Two top java frames are separated by non-java native frames
return JVMTI_ERROR_NO_MORE_FRAMES;
} else {
// Intervening non-java native or VM frames separate java frames.
// Current implementation does not support this. See bug #5031735.
// In theory it is possible to pop frames in such cases.
return JVMTI_ERROR_OPAQUE_FRAME;
}
}
// If any of the top 2 frames is a compiled one, need to deoptimize it
for (int i = 0; i < 2; i++) {
if (!is_interpreted[i]) {
}
}
// Update the thread state to reflect that the top frame is popped
// so that cur_stack_depth is maintained properly and all frameIDs
// are invalidated.
// The current frame will be popped later when the suspended thread
// is resumed and right before returning from VM to Java.
// (see call_VM_base() in assembler_<cpu>.cpp).
// It's fine to update the thread state here because no JVMTI events
// shall be posted for this PopFrame.
// Set pending step flag for this popframe and it is cleared when next
// step event is posted.
}
return JVMTI_ERROR_NONE;
} /* end PopFrame */
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
// java_thread - unchecked
// depth - pre-checked as non-negative
// method_ptr - pre-checked for NULL
// location_ptr - pre-checked for NULL
JvmtiEnv::GetFrameLocation(JavaThread* java_thread, jint depth, jmethodID* method_ptr, jlocation* location_ptr) {
} else {
// JVMTI get java stack frame location at safepoint.
}
return err;
} /* end GetFrameLocation */
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
// java_thread - unchecked
// depth - pre-checked as non-negative
return JVMTI_ERROR_THREAD_NOT_ALIVE;
}
return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
}
if (TraceJVMTICalls) {
}
return JVMTI_ERROR_NO_MORE_FRAMES;
}
return JVMTI_ERROR_OPAQUE_FRAME;
}
return JVMTI_ERROR_NONE;
} /* end NotifyFramePop */
//
// Force Early Return functions
//
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
} /* end ForceEarlyReturnObject */
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
} /* end ForceEarlyReturnInt */
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
} /* end ForceEarlyReturnLong */
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
} /* end ForceEarlyReturnFloat */
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
} /* end ForceEarlyReturnDouble */
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
val.j = 0L;
} /* end ForceEarlyReturnVoid */
//
// Heap functions
//
// klass - NULL is a valid value, must be checked
// initial_object - NULL is a valid value, must be checked
// callbacks - pre-checked for NULL
// user_data - NULL is a valid value, must be checked
JvmtiEnv::FollowReferences(jint heap_filter, jclass klass, jobject initial_object, const jvmtiHeapCallbacks* callbacks, const void* user_data) {
// check klass if provided
return JVMTI_ERROR_INVALID_CLASS;
}
return JVMTI_ERROR_NONE;
}
return JVMTI_ERROR_INVALID_CLASS;
}
}
JvmtiTagMap::tag_map_for(this)->follow_references(heap_filter, kh, initial_object, callbacks, user_data);
return JVMTI_ERROR_NONE;
} /* end FollowReferences */
// klass - NULL is a valid value, must be checked
// callbacks - pre-checked for NULL
// user_data - NULL is a valid value, must be checked
JvmtiEnv::IterateThroughHeap(jint heap_filter, jclass klass, const jvmtiHeapCallbacks* callbacks, const void* user_data) {
// check klass if provided
return JVMTI_ERROR_INVALID_CLASS;
}
return JVMTI_ERROR_NONE;
}
return JVMTI_ERROR_INVALID_CLASS;
}
}
return JVMTI_ERROR_NONE;
} /* end IterateThroughHeap */
// tag_ptr - pre-checked for NULL
return JVMTI_ERROR_NONE;
} /* end GetTag */
return JVMTI_ERROR_NONE;
} /* end SetTag */
// tag_count - pre-checked to be greater than or equal to 0
// tags - pre-checked for NULL
// count_ptr - pre-checked for NULL
// object_result_ptr - NULL is a valid value, must be checked
// tag_result_ptr - NULL is a valid value, must be checked
JvmtiEnv::GetObjectsWithTags(jint tag_count, const jlong* tags, jint* count_ptr, jobject** object_result_ptr, jlong** tag_result_ptr) {
return JvmtiTagMap::tag_map_for(this)->get_objects_with_tags((jlong*)tags, tag_count, count_ptr, object_result_ptr, tag_result_ptr);
} /* end GetObjectsWithTags */
return JVMTI_ERROR_NONE;
} /* end ForceGarbageCollection */
//
// Heap (1.0) functions
//
// object_reference_callback - pre-checked for NULL
// user_data - NULL is a valid value, must be checked
JvmtiEnv::IterateOverObjectsReachableFromObject(jobject object, jvmtiObjectReferenceCallback object_reference_callback, const void* user_data) {
JvmtiTagMap::tag_map_for(this)->iterate_over_objects_reachable_from_object(object, object_reference_callback, user_data);
return JVMTI_ERROR_NONE;
} /* end IterateOverObjectsReachableFromObject */
// heap_root_callback - NULL is a valid value, must be checked
// stack_ref_callback - NULL is a valid value, must be checked
// object_ref_callback - NULL is a valid value, must be checked
// user_data - NULL is a valid value, must be checked
JvmtiEnv::IterateOverReachableObjects(jvmtiHeapRootCallback heap_root_callback, jvmtiStackReferenceCallback stack_ref_callback, jvmtiObjectReferenceCallback object_ref_callback, const void* user_data) {
JvmtiTagMap::tag_map_for(this)->iterate_over_reachable_objects(heap_root_callback, stack_ref_callback, object_ref_callback, user_data);
return JVMTI_ERROR_NONE;
} /* end IterateOverReachableObjects */
// heap_object_callback - pre-checked for NULL
// user_data - NULL is a valid value, must be checked
JvmtiEnv::IterateOverHeap(jvmtiHeapObjectFilter object_filter, jvmtiHeapObjectCallback heap_object_callback, const void* user_data) {
JvmtiTagMap::tag_map_for(this)->iterate_over_heap(object_filter, KlassHandle(), heap_object_callback, user_data);
return JVMTI_ERROR_NONE;
} /* end IterateOverHeap */
// k_mirror - may be primitive, this must be checked
// heap_object_callback - pre-checked for NULL
// user_data - NULL is a valid value, must be checked
JvmtiEnv::IterateOverInstancesOfClass(oop k_mirror, jvmtiHeapObjectFilter object_filter, jvmtiHeapObjectCallback heap_object_callback, const void* user_data) {
// DO PRIMITIVE CLASS PROCESSING
return JVMTI_ERROR_NONE;
}
return JVMTI_ERROR_INVALID_CLASS;
}
JvmtiTagMap::tag_map_for(this)->iterate_over_heap(object_filter, klass, heap_object_callback, user_data);
return JVMTI_ERROR_NONE;
} /* end IterateOverInstancesOfClass */
//
// Local Variable functions
//
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
// java_thread - unchecked
// depth - pre-checked as non-negative
// value_ptr - pre-checked for NULL
// rm object is created to clean up the javaVFrame created in
// doit_prologue(), but after doit() is finished with it.
if (err != JVMTI_ERROR_NONE) {
return err;
} else {
return JVMTI_ERROR_NONE;
}
} /* end GetLocalObject */
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
// java_thread - unchecked
// depth - pre-checked as non-negative
// value - pre-checked for NULL
// rm object is created to clean up the javaVFrame created in
// doit_prologue(), but after doit() is finished with it.
if (err != JVMTI_ERROR_NONE) {
return err;
} else {
return JVMTI_ERROR_NONE;
}
} /* end GetLocalInstance */
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
// java_thread - unchecked
// depth - pre-checked as non-negative
// value_ptr - pre-checked for NULL
// rm object is created to clean up the javaVFrame created in
// doit_prologue(), but after doit() is finished with it.
} /* end GetLocalInt */
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
// java_thread - unchecked
// depth - pre-checked as non-negative
// value_ptr - pre-checked for NULL
// rm object is created to clean up the javaVFrame created in
// doit_prologue(), but after doit() is finished with it.
} /* end GetLocalLong */
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
// java_thread - unchecked
// depth - pre-checked as non-negative
// value_ptr - pre-checked for NULL
// rm object is created to clean up the javaVFrame created in
// doit_prologue(), but after doit() is finished with it.
} /* end GetLocalFloat */
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
// java_thread - unchecked
// depth - pre-checked as non-negative
// value_ptr - pre-checked for NULL
// rm object is created to clean up the javaVFrame created in
// doit_prologue(), but after doit() is finished with it.
} /* end GetLocalDouble */
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
// java_thread - unchecked
// depth - pre-checked as non-negative
// rm object is created to clean up the javaVFrame created in
// doit_prologue(), but after doit() is finished with it.
} /* end SetLocalObject */
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
// java_thread - unchecked
// depth - pre-checked as non-negative
// rm object is created to clean up the javaVFrame created in
// doit_prologue(), but after doit() is finished with it.
} /* end SetLocalInt */
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
// java_thread - unchecked
// depth - pre-checked as non-negative
// rm object is created to clean up the javaVFrame created in
// doit_prologue(), but after doit() is finished with it.
} /* end SetLocalLong */
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
// java_thread - unchecked
// depth - pre-checked as non-negative
// rm object is created to clean up the javaVFrame created in
// doit_prologue(), but after doit() is finished with it.
} /* end SetLocalFloat */
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
// java_thread - unchecked
// depth - pre-checked as non-negative
// rm object is created to clean up the javaVFrame created in
// doit_prologue(), but after doit() is finished with it.
} /* end SetLocalDouble */
//
// Breakpoint functions
//
// method_oop - pre-checked for validity, but may be NULL meaning obsolete method
if (location < 0) { // simple invalid location check first
return JVMTI_ERROR_INVALID_LOCATION;
}
// verify that the breakpoint is not past the end of the method
return JVMTI_ERROR_INVALID_LOCATION;
}
return JVMTI_ERROR_DUPLICATE;
if (TraceJVMTICalls) {
}
return JVMTI_ERROR_NONE;
} /* end SetBreakpoint */
// method_oop - pre-checked for validity, but may be NULL meaning obsolete method
if (location < 0) { // simple invalid location check first
return JVMTI_ERROR_INVALID_LOCATION;
}
// verify that the breakpoint is not past the end of the method
return JVMTI_ERROR_INVALID_LOCATION;
}
return JVMTI_ERROR_NOT_FOUND;
if (TraceJVMTICalls) {
}
return JVMTI_ERROR_NONE;
} /* end ClearBreakpoint */
//
// Watched Field functions
//
// make sure we haven't set this watch before
fdesc_ptr->set_is_field_access_watched(true);
return JVMTI_ERROR_NONE;
} /* end SetFieldAccessWatch */
// make sure we have a watch to clear
fdesc_ptr->set_is_field_access_watched(false);
return JVMTI_ERROR_NONE;
} /* end ClearFieldAccessWatch */
// make sure we haven't set this watch before
return JVMTI_ERROR_NONE;
} /* end SetFieldModificationWatch */
// make sure we have a watch to clear
return JVMTI_ERROR_NONE;
} /* end ClearFieldModificationWatch */
//
// Class functions
//
// k_mirror - may be primitive, this must be checked
// signature_ptr - NULL is a valid value, must be checked
// generic_ptr - NULL is a valid value, must be checked
if (!isPrimitive) {
}
if (signature_ptr != NULL) {
if (isPrimitive) {
} else {
}
*signature_ptr = result;
}
if (generic_ptr != NULL) {
*generic_ptr = NULL;
char* gen_result;
(unsigned char **)&gen_result);
if (err != JVMTI_ERROR_NONE) {
return err;
}
}
}
}
}
return JVMTI_ERROR_NONE;
} /* end GetClassSignature */
// k_mirror - may be primitive, this must be checked
// status_ptr - pre-checked for NULL
} else {
}
*status_ptr = result;
return JVMTI_ERROR_NONE;
} /* end GetClassStatus */
// k_mirror - may be primitive, this must be checked
// source_name_ptr - pre-checked for NULL
return JVMTI_ERROR_ABSENT_INFORMATION;
}
return JVMTI_ERROR_ABSENT_INFORMATION;
}
{
}
return JVMTI_ERROR_NONE;
} /* end GetSourceFileName */
// k_mirror - may be primitive, this must be checked
// modifiers_ptr - pre-checked for NULL
assert((Klass::cast(k)->oop_is_instance() || Klass::cast(k)->oop_is_array()), "should be an instance or an array klass");
if (HAS_PENDING_EXCEPTION) {
return JVMTI_ERROR_INTERNAL;
};
// Reset the deleted ACC_SUPER bit ( deleted in compute_modifier_flags()).
result |= JVM_ACC_SUPER;
}
} else {
}
*modifiers_ptr = result;
return JVMTI_ERROR_NONE;
} /* end GetClassModifiers */
// k_mirror - may be primitive, this must be checked
// method_count_ptr - pre-checked for NULL
// methods_ptr - pre-checked for NULL
*method_count_ptr = 0;
return JVMTI_ERROR_NONE;
}
// Return CLASS_NOT_PREPARED error as per JVMTI spec.
if (!(Klass::cast(k)->jvmti_class_status() & (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY) )) {
return JVMTI_ERROR_CLASS_NOT_PREPARED;
}
*method_count_ptr = 0;
return JVMTI_ERROR_NONE;
}
// Allocate the result and fill it in
int index;
// Use the original method ordering indices stored in the class, so we can emit
// jmethodIDs in the order they appeared in the class file
}
} else {
// otherwise just copy in any order
}
}
// Fill in return value.
return JVMTI_ERROR_NONE;
} /* end GetClassMethods */
// k_mirror - may be primitive, this must be checked
// field_count_ptr - pre-checked for NULL
// fields_ptr - pre-checked for NULL
*field_count_ptr = 0;
return JVMTI_ERROR_NONE;
}
// Return CLASS_NOT_PREPARED error as per JVMTI spec.
if (!(Klass::cast(k)->jvmti_class_status() & (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY) )) {
return JVMTI_ERROR_CLASS_NOT_PREPARED;
}
*field_count_ptr = 0;
return JVMTI_ERROR_NONE;
}
int result_count = 0;
// First, count the fields.
// Allocate the result and fill it in
// The JVMTI spec requires fields in the order they occur in the class file,
// this is the reverse order of what FieldStream hands out.
}
// Fill in the results
return JVMTI_ERROR_NONE;
} /* end GetClassFields */
// k_mirror - may be primitive, this must be checked
// interface_count_ptr - pre-checked for NULL
// interfaces_ptr - pre-checked for NULL
JvmtiEnv::GetImplementedInterfaces(oop k_mirror, jint* interface_count_ptr, jclass** interfaces_ptr) {
{
*interface_count_ptr = 0;
return JVMTI_ERROR_NONE;
}
// Return CLASS_NOT_PREPARED error as per JVMTI spec.
if (!(Klass::cast(k)->jvmti_class_status() & (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY) ))
return JVMTI_ERROR_CLASS_NOT_PREPARED;
*interface_count_ptr = 0;
return JVMTI_ERROR_NONE;
}
}
}
return JVMTI_ERROR_NONE;
} /* end GetImplementedInterfaces */
// k_mirror - may be primitive, this must be checked
// minor_version_ptr - pre-checked for NULL
// major_version_ptr - pre-checked for NULL
return JVMTI_ERROR_ABSENT_INFORMATION;
}
if (status & (JVMTI_CLASS_STATUS_ERROR)) {
return JVMTI_ERROR_INVALID_CLASS;
}
if (status & (JVMTI_CLASS_STATUS_ARRAY)) {
return JVMTI_ERROR_ABSENT_INFORMATION;
}
return JVMTI_ERROR_NONE;
} /* end GetClassVersionNumbers */
// k_mirror - may be primitive, this must be checked
// constant_pool_count_ptr - pre-checked for NULL
// constant_pool_byte_count_ptr - pre-checked for NULL
// constant_pool_bytes_ptr - pre-checked for NULL
JvmtiEnv::GetConstantPool(oop k_mirror, jint* constant_pool_count_ptr, jint* constant_pool_byte_count_ptr, unsigned char** constant_pool_bytes_ptr) {
return JVMTI_ERROR_ABSENT_INFORMATION;
}
if (status & (JVMTI_CLASS_STATUS_ERROR)) {
return JVMTI_ERROR_INVALID_CLASS;
}
if (status & (JVMTI_CLASS_STATUS_ARRAY)) {
return JVMTI_ERROR_ABSENT_INFORMATION;
}
return reconstituter.get_error();
}
unsigned char *cpool_bytes;
return reconstituter.get_error();
}
if (res != JVMTI_ERROR_NONE) {
return res;
}
return reconstituter.get_error();
}
return JVMTI_ERROR_NONE;
} /* end GetConstantPool */
// k_mirror - may be primitive, this must be checked
// is_interface_ptr - pre-checked for NULL
{
bool result = false;
result = true;
}
}
}
return JVMTI_ERROR_NONE;
} /* end IsInterface */
// k_mirror - may be primitive, this must be checked
// is_array_class_ptr - pre-checked for NULL
{
bool result = false;
result = true;
}
}
}
return JVMTI_ERROR_NONE;
} /* end IsArrayClass */
// k_mirror - may be primitive, this must be checked
// classloader_ptr - pre-checked for NULL
{
return JVMTI_ERROR_NONE;
}
if (result_oop == NULL) {
return JVMTI_ERROR_NONE;
}
}
return JVMTI_ERROR_NONE;
} /* end GetClassLoader */
// k_mirror - may be primitive, this must be checked
// source_debug_extension_ptr - pre-checked for NULL
{
return JVMTI_ERROR_ABSENT_INFORMATION;
}
return JVMTI_ERROR_ABSENT_INFORMATION;
}
{
}
}
return JVMTI_ERROR_NONE;
} /* end GetSourceDebugExtension */
//
// Object functions
//
// hash_code_ptr - pre-checked for NULL
{
*hash_code_ptr = result;
}
return JVMTI_ERROR_NONE;
} /* end GetObjectHashCode */
// info_ptr - pre-checked for NULL
if (err == JVMTI_ERROR_THREAD_NOT_SUSPENDED) {
// Some of the critical threads were not suspended. go to a safepoint and try again
}
return err;
} /* end GetObjectMonitorUsage */
//
// Field functions
//
// name_ptr - NULL is a valid value, must be checked
// signature_ptr - NULL is a valid value, must be checked
// generic_ptr - NULL is a valid value, must be checked
JvmtiEnv::GetFieldName(fieldDescriptor* fdesc_ptr, char** name_ptr, char** signature_ptr, char** generic_ptr) {
// just don't return the name
} else {
return JVMTI_ERROR_OUT_OF_MEMORY;
}
if (signature_ptr== NULL) {
// just don't return the signature
} else {
if (*signature_ptr == NULL)
return JVMTI_ERROR_OUT_OF_MEMORY;
}
if (generic_ptr != NULL) {
*generic_ptr = NULL;
if (err != JVMTI_ERROR_NONE) {
return err;
}
}
}
}
return JVMTI_ERROR_NONE;
} /* end GetFieldName */
// declaring_class_ptr - pre-checked for NULL
return JVMTI_ERROR_NONE;
} /* end GetFieldDeclaringClass */
// modifiers_ptr - pre-checked for NULL
*modifiers_ptr = result;
return JVMTI_ERROR_NONE;
} /* end GetFieldModifiers */
// is_synthetic_ptr - pre-checked for NULL
return JVMTI_ERROR_NONE;
} /* end IsFieldSynthetic */
//
// Method functions
//
// method_oop - pre-checked for validity, but may be NULL meaning obsolete method
// name_ptr - NULL is a valid value, must be checked
// signature_ptr - NULL is a valid value, must be checked
// generic_ptr - NULL is a valid value, must be checked
JvmtiEnv::GetMethodName(methodOop method_oop, char** name_ptr, char** signature_ptr, char** generic_ptr) {
// just don't return the name
} else {
}
if (signature_ptr == NULL) {
// just don't return the signature
} else {
}
if (generic_ptr != NULL) {
*generic_ptr = NULL;
if (err != JVMTI_ERROR_NONE) {
return err;
}
}
}
}
return JVMTI_ERROR_NONE;
} /* end GetMethodName */
// method_oop - pre-checked for validity, but may be NULL meaning obsolete method
// declaring_class_ptr - pre-checked for NULL
return JVMTI_ERROR_NONE;
} /* end GetMethodDeclaringClass */
// method_oop - pre-checked for validity, but may be NULL meaning obsolete method
// modifiers_ptr - pre-checked for NULL
return JVMTI_ERROR_NONE;
} /* end GetMethodModifiers */
// method_oop - pre-checked for validity, but may be NULL meaning obsolete method
// max_ptr - pre-checked for NULL
// get max stack
return JVMTI_ERROR_NONE;
} /* end GetMaxLocals */
// method_oop - pre-checked for validity, but may be NULL meaning obsolete method
// size_ptr - pre-checked for NULL
// get size of arguments
return JVMTI_ERROR_NONE;
} /* end GetArgumentsSize */
// method_oop - pre-checked for validity, but may be NULL meaning obsolete method
// entry_count_ptr - pre-checked for NULL
// table_ptr - pre-checked for NULL
JvmtiEnv::GetLineNumberTable(methodOop method_oop, jint* entry_count_ptr, jvmtiLineNumberEntry** table_ptr) {
if (!method_oop->has_linenumber_table()) {
return (JVMTI_ERROR_ABSENT_INFORMATION);
}
// The line number table is compressed so we don't know how big it is until decompressed.
// Decompression is really fast so we just do it twice.
// Compute size of table
num_entries++;
}
// Fill jvmti table
if (num_entries > 0) {
int index = 0;
index++;
}
}
// Set up results
(*entry_count_ptr) = num_entries;
(*table_ptr) = jvmti_table;
return JVMTI_ERROR_NONE;
} /* end GetLineNumberTable */
// method_oop - pre-checked for validity, but may be NULL meaning obsolete method
// start_location_ptr - pre-checked for NULL
// end_location_ptr - pre-checked for NULL
JvmtiEnv::GetMethodLocation(methodOop method_oop, jlocation* start_location_ptr, jlocation* end_location_ptr) {
// get start and end location
if (method_oop->code_size() == 0) {
// there is no code so there is no start location
} else {
(*start_location_ptr) = (jlocation)(0);
}
return JVMTI_ERROR_NONE;
} /* end GetMethodLocation */
// method_oop - pre-checked for validity, but may be NULL meaning obsolete method
// entry_count_ptr - pre-checked for NULL
// table_ptr - pre-checked for NULL
JvmtiEnv::GetLocalVariableTable(methodOop method_oop, jint* entry_count_ptr, jvmtiLocalVariableEntry** table_ptr) {
// does the klass have any local variable information?
return (JVMTI_ERROR_ABSENT_INFORMATION);
}
// in the vm localvariable table representation, 6 consecutive elements in the table
// represent a 6-tuple of shorts
// [start_pc, length, name_index, descriptor_index, signature_index, index]
if (num_entries > 0) {
for (int i = 0; i < num_entries; i++) {
// get the 5 tuple information from the vm table
// get utf8 name and signature
{
if (generic_signature_index > 0) {
const char *utf8_gen_sign = (const char *)
}
}
// fill in the jvmti local variable table
}
}
// set results
(*entry_count_ptr) = num_entries;
(*table_ptr) = jvmti_table;
return JVMTI_ERROR_NONE;
} /* end GetLocalVariableTable */
// method_oop - pre-checked for validity, but may be NULL meaning obsolete method
// bytecode_count_ptr - pre-checked for NULL
// bytecodes_ptr - pre-checked for NULL
JvmtiEnv::GetBytecodes(methodOop method_oop, jint* bytecode_count_ptr, unsigned char** bytecodes_ptr) {
if (err != JVMTI_ERROR_NONE) {
return err;
}
(*bytecode_count_ptr) = size;
// get byte codes
return JVMTI_ERROR_NONE;
} /* end GetBytecodes */
// method_oop - pre-checked for validity, but may be NULL meaning obsolete method
// is_native_ptr - pre-checked for NULL
return JVMTI_ERROR_NONE;
} /* end IsMethodNative */
// method_oop - pre-checked for validity, but may be NULL meaning obsolete method
// is_synthetic_ptr - pre-checked for NULL
return JVMTI_ERROR_NONE;
} /* end IsMethodSynthetic */
// method_oop - pre-checked for validity, but may be NULL meaning obsolete method
// is_obsolete_ptr - pre-checked for NULL
if (use_version_1_0_semantics() &&
get_capabilities()->can_redefine_classes == 0) {
// This JvmtiEnv requested version 1.0 semantics and this function
// requires the can_redefine_classes capability in version 1.0 so
// we need to return an error here.
}
*is_obsolete_ptr = true;
} else {
*is_obsolete_ptr = false;
}
return JVMTI_ERROR_NONE;
} /* end IsMethodObsolete */
//
// Raw Monitor functions
//
// name - pre-checked for NULL
// monitor_ptr - pre-checked for NULL
return JVMTI_ERROR_NONE;
} /* end CreateRawMonitor */
// rmonitor - pre-checked for validity
if (Threads::number_of_threads() == 0) {
// Remove this monitor from pending raw monitors list
// if it has entered in onload or start phase.
} else {
// The caller owns this monitor which we are about to destroy.
// We exit the underlying synchronization object so that the
// "delete monitor" call below can work without an assertion
// failure on systems that don't like destroying synchronization
// objects that are locked.
int r;
return JVMTI_ERROR_INTERNAL;
}
}
}
// The caller is trying to destroy a monitor that is locked by
// someone else. While this is not forbidden by the JVMTI
// spec, it will cause an assertion failure on systems that don't
// like destroying synchronization objects that are locked.
// We indicate a problem with the error return (and leak the
// monitor's memory).
return JVMTI_ERROR_NOT_MONITOR_OWNER;
}
}
delete rmonitor;
return JVMTI_ERROR_NONE;
} /* end DestroyRawMonitor */
// rmonitor - pre-checked for validity
if (Threads::number_of_threads() == 0) {
// No JavaThreads exist so ObjectMonitor enter cannot be
// used, add this raw monitor to the pending list.
// The pending monitors will be actually entered when
// the VM is setup.
// See transition_pending_raw_monitors in create_vm()
// in thread.cpp.
} else {
int r;
if (thread->is_Java_thread()) {
#ifdef PROPER_TRANSITIONS
// Not really unknown but ThreadInVMfromNative does more than we want
{
}
#else
/* Transition to thread_blocked without entering vm state */
/* This is really evil. Normally you can't undo _thread_blocked */
/* transitions like this because it would cause us to miss a */
/* safepoint but since the thread was already in _thread_in_native */
/* the thread is not leaving a safepoint safe state and it will */
/* block when it tries to return from native. We can't safepoint */
/* block in here because we could deadlock the vmthread. Blech. */
// frame should already be walkable since we are in native
// restore state, still at a safepoint safe state
#endif /* PROPER_TRANSITIONS */
} else {
} else {
}
}
return JVMTI_ERROR_INTERNAL;
}
}
return JVMTI_ERROR_NONE;
} /* end RawMonitorEnter */
// rmonitor - pre-checked for validity
if (Threads::number_of_threads() == 0) {
// No JavaThreads exist so just remove this monitor from the pending list.
// Bool value from exit is false if rmonitor is not in the list.
}
} else {
int r;
if (thread->is_Java_thread()) {
#ifdef PROPER_TRANSITIONS
// Not really unknown but ThreadInVMfromNative does more than we want
#endif /* PROPER_TRANSITIONS */
} else {
} else {
}
}
if (r == ObjectMonitor::OM_ILLEGAL_MONITOR_STATE) {
} else {
}
}
}
return err;
} /* end RawMonitorExit */
// rmonitor - pre-checked for validity
int r;
if (thread->is_Java_thread()) {
#ifdef PROPER_TRANSITIONS
// Not really unknown but ThreadInVMfromNative does more than we want
{
}
#else
/* Transition to thread_blocked without entering vm state */
/* This is really evil. Normally you can't undo _thread_blocked */
/* transitions like this because it would cause us to miss a */
/* safepoint but since the thread was already in _thread_in_native */
/* the thread is not leaving a safepoint safe state and it will */
/* block when it tries to return from native. We can't safepoint */
/* block in here because we could deadlock the vmthread. Blech. */
// frame should already be walkable since we are in native
// restore state, still at a safepoint safe state
#endif /* PROPER_TRANSITIONS */
} else {
} else {
}
}
switch (r) {
case ObjectMonitor::OM_INTERRUPTED:
return JVMTI_ERROR_INTERRUPT;
return JVMTI_ERROR_NOT_MONITOR_OWNER;
}
return JVMTI_ERROR_INTERNAL;
}
return JVMTI_ERROR_NONE;
} /* end RawMonitorWait */
// rmonitor - pre-checked for validity
int r;
if (thread->is_Java_thread()) {
// Not really unknown but ThreadInVMfromNative does more than we want
} else {
} else {
}
}
if (r == ObjectMonitor::OM_ILLEGAL_MONITOR_STATE) {
return JVMTI_ERROR_NOT_MONITOR_OWNER;
}
return JVMTI_ERROR_INTERNAL;
}
return JVMTI_ERROR_NONE;
} /* end RawMonitorNotify */
// rmonitor - pre-checked for validity
int r;
if (thread->is_Java_thread()) {
} else {
} else {
}
}
if (r == ObjectMonitor::OM_ILLEGAL_MONITOR_STATE) {
return JVMTI_ERROR_NOT_MONITOR_OWNER;
}
return JVMTI_ERROR_INTERNAL;
}
return JVMTI_ERROR_NONE;
} /* end RawMonitorNotifyAll */
//
// JNI Function Interception functions
//
// function_table - pre-checked for NULL
// Copy jni function table at safepoint.
return JVMTI_ERROR_NONE;
} /* end SetJNIFunctionTable */
// function_table - pre-checked for NULL
if (*function_table == NULL)
return JVMTI_ERROR_OUT_OF_MEMORY;
return JVMTI_ERROR_NONE;
} /* end GetJNIFunctionTable */
//
// Event Management functions
//
// can only generate two event types
if (event_type != JVMTI_EVENT_COMPILED_METHOD_LOAD &&
return JVMTI_ERROR_ILLEGAL_ARGUMENT;
}
// for compiled_method_load events we must check that the environment
// has the can_generate_compiled_method_load_events capability.
if (event_type == JVMTI_EVENT_COMPILED_METHOD_LOAD) {
if (get_capabilities()->can_generate_compiled_method_load_events == 0) {
}
return JvmtiCodeBlobEvents::generate_compiled_method_load_events(this);
} else {
return JvmtiCodeBlobEvents::generate_dynamic_code_events(this);
}
} /* end GenerateEvents */
//
// Extension Mechanism functions
//
// extension_count_ptr - pre-checked for NULL
// extensions - pre-checked for NULL
JvmtiEnv::GetExtensionFunctions(jint* extension_count_ptr, jvmtiExtensionFunctionInfo** extensions) {
} /* end GetExtensionFunctions */
// extension_count_ptr - pre-checked for NULL
// extensions - pre-checked for NULL
} /* end GetExtensionEvents */
// callback - NULL is a valid value, must be checked
} /* end SetExtensionEventCallback */
//
// Timers functions
//
// info_ptr - pre-checked for NULL
return JVMTI_ERROR_NONE;
} /* end GetCurrentThreadCpuTimerInfo */
// nanos_ptr - pre-checked for NULL
return JVMTI_ERROR_NONE;
} /* end GetCurrentThreadCpuTime */
// info_ptr - pre-checked for NULL
return JVMTI_ERROR_NONE;
} /* end GetThreadCpuTimerInfo */
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
// nanos_ptr - pre-checked for NULL
return JVMTI_ERROR_NONE;
} /* end GetThreadCpuTime */
// info_ptr - pre-checked for NULL
return JVMTI_ERROR_NONE;
} /* end GetTimerInfo */
// nanos_ptr - pre-checked for NULL
return JVMTI_ERROR_NONE;
} /* end GetTime */
// processor_count_ptr - pre-checked for NULL
return JVMTI_ERROR_NONE;
} /* end GetAvailableProcessors */
//
// System Properties functions
//
// count_ptr - pre-checked for NULL
// property_ptr - pre-checked for NULL
if (err != JVMTI_ERROR_NONE) {
return err;
}
int i = 0 ;
for (SystemProperty* p = Arguments::system_properties(); p != NULL && i < *count_ptr; p = p->next(), i++) {
if (err == JVMTI_ERROR_NONE) {
} else {
// clean up previously allocated memory.
for (int j=0; j<i; j++) {
Deallocate((unsigned char*)*property_ptr+j);
}
Deallocate((unsigned char*)property_ptr);
break;
}
}
return err;
} /* end GetSystemProperties */
// property - pre-checked for NULL
// value_ptr - pre-checked for NULL
const char *value;
} else {
if (err == JVMTI_ERROR_NONE) {
}
}
return err;
} /* end GetSystemProperty */
// property - pre-checked for NULL
// value - NULL is a valid value, must be checked
}
}
}
return err;
} /* end SetSystemProperty */