diff options
author | Andrew Haley <aph@redhat.com> | 2016-09-30 16:24:48 +0000 |
---|---|---|
committer | Andrew Haley <aph@gcc.gnu.org> | 2016-09-30 16:24:48 +0000 |
commit | 07b78716af6a9d7c9fd1e94d9baf94a52c873947 (patch) | |
tree | 3f22b3241c513ad168c8353805614ae1249410f4 /libjava/jvmti.cc | |
parent | eae993948bae8b788c53772bcb9217c063716f93 (diff) | |
download | gcc-07b78716af6a9d7c9fd1e94d9baf94a52c873947.zip gcc-07b78716af6a9d7c9fd1e94d9baf94a52c873947.tar.gz gcc-07b78716af6a9d7c9fd1e94d9baf94a52c873947.tar.bz2 |
Makefile.def: Remove libjava.
2016-09-30 Andrew Haley <aph@redhat.com>
* Makefile.def: Remove libjava.
* Makefile.tpl: Likewise.
* Makefile.in: Regenerate.
* configure.ac: Likewise.
* configure: Likewise.
* gcc/java: Remove.
* libjava: Likewise.
From-SVN: r240662
Diffstat (limited to 'libjava/jvmti.cc')
-rw-r--r-- | libjava/jvmti.cc | 2626 |
1 files changed, 0 insertions, 2626 deletions
diff --git a/libjava/jvmti.cc b/libjava/jvmti.cc deleted file mode 100644 index 7c7923b..0000000 --- a/libjava/jvmti.cc +++ /dev/null @@ -1,2626 +0,0 @@ -// jvmti.cc - JVMTI implementation - -/* Copyright (C) 2006, 2007, 2010 Free Software Foundation - - This file is part of libgcj. - -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ - -#include <config.h> -#include <platform.h> - -#include <jvm.h> -#include <java-threads.h> -#include <java-gc.h> -#include <java-interp.h> -#include <jvmti.h> -#include "jvmti-int.h" - -#include <gcj/method.h> - -#include <gnu/classpath/SystemProperties.h> -#include <gnu/gcj/runtime/BootClassLoader.h> -#include <gnu/gcj/jvmti/Breakpoint.h> -#include <gnu/gcj/jvmti/BreakpointManager.h> - -#include <java/lang/Class.h> -#include <java/lang/ClassLoader.h> -#include <java/lang/OutOfMemoryError.h> -#include <java/lang/Thread.h> -#include <java/lang/ThreadGroup.h> -#include <java/lang/Thread$State.h> -#include <java/lang/Throwable.h> -#include <java/lang/VMClassLoader.h> -#include <java/lang/reflect/Field.h> -#include <java/lang/reflect/Modifier.h> -#include <java/util/Collection.h> -#include <java/util/HashMap.h> -#include <java/util/concurrent/locks/Lock.h> -#include <java/util/concurrent/locks/ReentrantReadWriteLock.h> -#include <java/net/URL.h> - -static void check_enabled_events (void); -static void check_enabled_event (jvmtiEvent); - -namespace JVMTI -{ - // Is JVMTI enabled? (i.e., any jvmtiEnv created?) - bool enabled; - - // Event notifications - bool VMInit = false; - bool VMDeath = false; - bool ThreadStart = false; - bool ThreadEnd = false; - bool ClassFileLoadHook = false; - bool ClassLoad = false; - bool ClassPrepare = false; - bool VMStart = false; - bool Exception = false; - bool ExceptionCatch = false; - bool SingleStep = false; - bool FramePop = false; - bool Breakpoint = false; - bool FieldAccess = false; - bool FieldModification = false; - bool MethodEntry = false; - bool MethodExit = false; - bool NativeMethodBind = false; - bool CompiledMethodLoad = false; - bool CompiledMethodUnload = false; - bool DynamicCodeGenerated = false; - bool DataDumpRequest = false; - bool reserved72 = false; - bool MonitorWait = false; - bool MonitorWaited = false; - bool MonitorContendedEnter = false; - bool MonitorContendedEntered = false; - bool reserved77 = false; - bool reserved78 = false; - bool reserved79 = false; - bool reserved80 = false; - bool GarbageCollectionStart = false; - bool GarbageCollectionFinish = false; - bool ObjectFree = false; - bool VMObjectAlloc = false; -}; - -extern struct JNINativeInterface _Jv_JNIFunctions; - -struct _Jv_rawMonitorID -{ - _Jv_Mutex_t mutex; - _Jv_ConditionVariable_t condition; -}; - -/* A simple linked list of all JVMTI environments. Since - events must be delivered to environments in the order - in which the environments were created, new environments - are added to the end of the list. */ -struct jvmti_env_list -{ - jvmtiEnv *env; - struct jvmti_env_list *next; -}; -static struct jvmti_env_list *_jvmtiEnvironments = NULL; -static java::util::concurrent::locks:: -ReentrantReadWriteLock *_envListLock = NULL; -#define FOREACH_ENVIRONMENT(Ele) \ - for (Ele = _jvmtiEnvironments; Ele != NULL; Ele = Ele->next) - -// Some commonly-used checks - -#define THREAD_DEFAULT_TO_CURRENT(Ajthread) \ - do \ - { \ - if (Ajthread == NULL) \ - Ajthread = java::lang::Thread::currentThread (); \ - } \ - while (0) - -#define THREAD_CHECK_VALID(Athread) \ - do \ - { \ - if (!java::lang::Thread::class$.isAssignableFrom (&(Athread->class$))) \ - return JVMTI_ERROR_INVALID_THREAD; \ - } \ - while (0) - -#define THREAD_CHECK_IS_ALIVE(Athread) \ - do \ - { \ - if (!Athread->isAlive ()) \ - return JVMTI_ERROR_THREAD_NOT_ALIVE; \ - } \ - while (0) - -// FIXME: if current phase is not set in Phases, -// return JVMTI_ERROR_WRONG_PHASE -#define REQUIRE_PHASE(Env, Phases) - -#define NULL_CHECK(Ptr) \ - do \ - { \ - if (Ptr == NULL) \ - return JVMTI_ERROR_NULL_POINTER; \ - } \ - while (0) - -#define ILLEGAL_ARGUMENT(Cond) \ - do \ - { \ - if ((Cond)) \ - return JVMTI_ERROR_ILLEGAL_ARGUMENT; \ - } \ - while (0) - -#define CHECK_FOR_NATIVE_METHOD(AjmethodID) \ - do \ - { \ - jboolean is_native; \ - jvmtiError jerr = env->IsMethodNative (AjmethodID, &is_native); \ - if (jerr != JVMTI_ERROR_NONE) \ - return jerr; \ - if (is_native) \ - return JVMTI_ERROR_NATIVE_METHOD; \ - } \ - while (0) - -static jvmtiError JNICALL -_Jv_JVMTI_SuspendThread (MAYBE_UNUSED jvmtiEnv *env, jthread thread) -{ - using namespace java::lang; - - THREAD_DEFAULT_TO_CURRENT (thread); - THREAD_CHECK_VALID (thread); - THREAD_CHECK_IS_ALIVE (thread); - - _Jv_Thread_t *data = _Jv_ThreadGetData (thread); - _Jv_SuspendThread (data); - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_ResumeThread (MAYBE_UNUSED jvmtiEnv *env, jthread thread) -{ - using namespace java::lang; - - THREAD_DEFAULT_TO_CURRENT (thread); - THREAD_CHECK_VALID (thread); - THREAD_CHECK_IS_ALIVE (thread); - - _Jv_Thread_t *data = _Jv_ThreadGetData (thread); - _Jv_ResumeThread (data); - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_InterruptThread (MAYBE_UNUSED jvmtiEnv *env, jthread thread) -{ - using namespace java::lang; - - REQUIRE_PHASE (env, JVMTI_PHASE_LIVE); - // FIXME: capability handling? 'can_signal_thread' - if (thread == NULL) - return JVMTI_ERROR_INVALID_THREAD; - - THREAD_CHECK_VALID (thread); - THREAD_CHECK_IS_ALIVE (thread); - thread->interrupt(); - return JVMTI_ERROR_NONE; -} - -// This method performs the common tasks to get and set variables of all types. -// It is called by the _Jv_JVMTI_Get/SetLocalInt/Object/.... methods. -static jvmtiError -getLocalFrame (jvmtiEnv *env, jthread thread, jint depth, jint slot, char type, - _Jv_InterpFrame **iframe) -{ - using namespace java::lang; - - REQUIRE_PHASE (env, JVMTI_PHASE_LIVE); - - ILLEGAL_ARGUMENT (depth < 0); - - THREAD_DEFAULT_TO_CURRENT (thread); - THREAD_CHECK_VALID (thread); - THREAD_CHECK_IS_ALIVE (thread); - - _Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (thread->frame); - - for (int i = 0; i < depth; i++) - { - frame = frame->next; - - if (frame == NULL) - return JVMTI_ERROR_NO_MORE_FRAMES; - } - - if (frame->frame_type == frame_native) - return JVMTI_ERROR_OPAQUE_FRAME; - - jint max_locals; - jvmtiError jerr = env->GetMaxLocals (reinterpret_cast<jmethodID> - (frame->self->get_method ()), - &max_locals); - if (jerr != JVMTI_ERROR_NONE) - return jerr; - - _Jv_InterpFrame *tmp_iframe = reinterpret_cast<_Jv_InterpFrame *> (frame); - - // The second slot taken up by a long type is marked as type 'x' meaning it - // is not valid for access since it holds only the 4 low bytes of the value. - if (tmp_iframe->locals_type[slot] == 'x') - return JVMTI_ERROR_INVALID_SLOT; - - if (tmp_iframe->locals_type[slot] != type) - return JVMTI_ERROR_TYPE_MISMATCH; - - // Check for invalid slots, if the type is a long type, we must check that - // the next slot is valid as well. - if (slot < 0 || slot >= max_locals - || ((type == 'l' || type == 'd') && slot + 1 >= max_locals)) - return JVMTI_ERROR_INVALID_SLOT; - - *iframe = tmp_iframe; - - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_GetLocalObject (jvmtiEnv *env, jthread thread, jint depth, jint slot, - jobject *value) -{ - NULL_CHECK (value); - - _Jv_InterpFrame *frame; - jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'o', &frame); - - if (jerr != JVMTI_ERROR_NONE) - return jerr; - - *value = frame->locals[slot].o; - - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_SetLocalObject (jvmtiEnv *env, jthread thread, jint depth, jint slot, - jobject value) -{ - _Jv_InterpFrame *frame; - jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'o', &frame); - - if (jerr != JVMTI_ERROR_NONE) - return jerr; - - frame->locals[slot].o = value; - - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_GetLocalInt (jvmtiEnv *env, jthread thread, jint depth, jint slot, - jint *value) -{ - NULL_CHECK (value); - - _Jv_InterpFrame *frame; - jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'i', &frame); - - if (jerr != JVMTI_ERROR_NONE) - return jerr; - - *value = frame->locals[slot].i; - - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_SetLocalInt (jvmtiEnv *env, jthread thread, jint depth, jint slot, - jint value) -{ - _Jv_InterpFrame *frame; - jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'i', &frame); - - if (jerr != JVMTI_ERROR_NONE) - return jerr; - - frame->locals[slot].i = value; - - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_GetLocalLong (jvmtiEnv *env, jthread thread, jint depth, jint slot, - jlong *value) -{ - NULL_CHECK (value); - - _Jv_InterpFrame *frame; - jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'l', &frame); - - if (jerr != JVMTI_ERROR_NONE) - return jerr; - -#if SIZEOF_VOID_P==8 - *value = frame->locals[slot].l; -#else - _Jv_word2 val; - val.ia[0] = frame->locals[slot].ia[0]; - val.ia[1] = frame->locals[slot + 1].ia[0]; - *value = val.l; -#endif - - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_SetLocalLong (jvmtiEnv *env, jthread thread, jint depth, jint slot, - jlong value) -{ - _Jv_InterpFrame *frame; - jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'l', &frame); - - if (jerr != JVMTI_ERROR_NONE) - return jerr; - -#if SIZEOF_VOID_P==8 - frame->locals[slot].l = value; -#else - _Jv_word2 val; - val.l = value; - frame->locals[slot].ia[0] = val.ia[0]; - frame->locals[slot + 1].ia[0] = val.ia[1]; -#endif - - return JVMTI_ERROR_NONE; -} - - -static jvmtiError JNICALL -_Jv_JVMTI_GetLocalFloat (jvmtiEnv *env, jthread thread, jint depth, jint slot, - jfloat *value) -{ - NULL_CHECK (value); - - _Jv_InterpFrame *frame; - jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'f', &frame); - - if (jerr != JVMTI_ERROR_NONE) - return jerr; - - *value = frame->locals[slot].f; - - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_SetLocalFloat (jvmtiEnv *env, jthread thread, jint depth, jint slot, - jfloat value) -{ - _Jv_InterpFrame *frame; - jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'f', &frame); - - if (jerr != JVMTI_ERROR_NONE) - return jerr; - - frame->locals[slot].f = value; - - return JVMTI_ERROR_NONE; -} - - -static jvmtiError JNICALL -_Jv_JVMTI_GetLocalDouble (jvmtiEnv *env, jthread thread, jint depth, jint slot, - jdouble *value) -{ - NULL_CHECK (value); - - _Jv_InterpFrame *frame; - jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'd', &frame); - - if (jerr != JVMTI_ERROR_NONE) - return jerr; - -#if SIZEOF_VOID_P==8 - *value = frame->locals[slot].d; -#else - _Jv_word2 val; - val.ia[0] = frame->locals[slot].ia[0]; - val.ia[1] = frame->locals[slot + 1].ia[0]; - *value = val.d; -#endif - - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_SetLocalDouble (jvmtiEnv *env, jthread thread, jint depth, jint slot, - jdouble value) -{ - _Jv_InterpFrame *frame; - jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'd', &frame); - - if (jerr != JVMTI_ERROR_NONE) - return jerr; - -#if SIZEOF_VOID_P==8 - frame->locals[slot].d = value; -#else - _Jv_word2 val; - val.d = value; - frame->locals[slot].ia[0] = val.ia[0]; - frame->locals[slot + 1].ia[0] = val.ia[1]; -#endif - - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_GetAllThreads(MAYBE_UNUSED jvmtiEnv *env, jint *thread_cnt, - jthread **threads) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_LIVE); - NULL_CHECK (thread_cnt); - NULL_CHECK (threads); - - using namespace java::lang; - - ThreadGroup *root_grp = ThreadGroup::root; - jint estimate = root_grp->activeCount (); - - JArray<Thread *> *thr_arr; - - // Allocate some extra space since threads can be created between calls - try - { - thr_arr = reinterpret_cast<JArray<Thread *> *> (JvNewObjectArray - ((estimate * 2), - &Thread::class$, NULL)); - } - catch (java::lang::OutOfMemoryError *err) - { - return JVMTI_ERROR_OUT_OF_MEMORY; - } - - *thread_cnt = root_grp->enumerate (thr_arr); - - jvmtiError jerr = env->Allocate ((jlong) ((*thread_cnt) * sizeof (jthread)), - (unsigned char **) threads); - - if (jerr != JVMTI_ERROR_NONE) - return jerr; - - // Transfer the threads to the result array - jthread *tmp_arr = reinterpret_cast<jthread *> (elements (thr_arr)); - - memcpy ((*threads), tmp_arr, (*thread_cnt)); - - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_GetFrameCount (MAYBE_UNUSED jvmtiEnv *env, jthread thread, - jint *frame_count) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_LIVE); - - NULL_CHECK (frame_count); - - using namespace java::lang; - - THREAD_DEFAULT_TO_CURRENT (thread); - THREAD_CHECK_VALID (thread); - THREAD_CHECK_IS_ALIVE (thread); - - _Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (thread->frame); - (*frame_count) = frame->depth (); - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_GetThreadState (MAYBE_UNUSED jvmtiEnv *env, jthread thread, - jint *thread_state_ptr) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_LIVE); - - THREAD_DEFAULT_TO_CURRENT (thread); - THREAD_CHECK_VALID (thread); - NULL_CHECK (thread_state_ptr); - - jint state = 0; - if (thread->isAlive ()) - { - state |= JVMTI_THREAD_STATE_ALIVE; - - _Jv_Thread_t *data = _Jv_ThreadGetData (thread); - if (_Jv_IsThreadSuspended (data)) - state |= JVMTI_THREAD_STATE_SUSPENDED; - - if (thread->isInterrupted ()) - state |= JVMTI_THREAD_STATE_INTERRUPTED; - - _Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (thread->frame); - if (frame != NULL && frame->frame_type == frame_native) - state |= JVMTI_THREAD_STATE_IN_NATIVE; - - using namespace java::lang; - Thread$State *ts = thread->getState (); - if (ts == Thread$State::RUNNABLE) - state |= JVMTI_THREAD_STATE_RUNNABLE; - else if (ts == Thread$State::BLOCKED) - state |= JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER; - else if (ts == Thread$State::TIMED_WAITING - || ts == Thread$State::WAITING) - { - state |= JVMTI_THREAD_STATE_WAITING; - state |= ((ts == Thread$State::WAITING) - ? JVMTI_THREAD_STATE_WAITING_INDEFINITELY - : JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT); - - /* FIXME: We don't have a way to tell - the caller why the thread is suspended, - i.e., JVMTI_THREAD_STATE_SLEEPING, - JVMTI_THREAD_STATE_PARKED, and - JVMTI_THREAD_STATE_IN_OBJECT_WAIT - are never set. */ - } - } - else - { - using namespace java::lang; - Thread$State *ts = thread->getState (); - if (ts == Thread$State::TERMINATED) - state |= JVMTI_THREAD_STATE_TERMINATED; - } - - *thread_state_ptr = state; - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_CreateRawMonitor (MAYBE_UNUSED jvmtiEnv *env, const char *name, - jrawMonitorID *result) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE); - NULL_CHECK (name); - NULL_CHECK (result); - *result = (jrawMonitorID) _Jv_MallocUnchecked (sizeof (_Jv_rawMonitorID)); - if (*result == NULL) - return JVMTI_ERROR_OUT_OF_MEMORY; - _Jv_MutexInit (&(*result)->mutex); - _Jv_CondInit (&(*result)->condition); - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_DestroyRawMonitor (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE); - // Note we have no better way of knowing whether this object is - // really a raw monitor. - if (monitor == NULL) - return JVMTI_ERROR_INVALID_MONITOR; - // FIXME: perform checks on monitor, release it if this thread owns - // it. -#ifdef _Jv_HaveMutexDestroy - _Jv_MutexDestroy (&monitor->mutex); -#endif - _Jv_Free (monitor); - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_RawMonitorEnter (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor) -{ - if (monitor == NULL) - return JVMTI_ERROR_INVALID_MONITOR; - _Jv_MutexLock (&monitor->mutex); - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_RawMonitorExit (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor) -{ - if (monitor == NULL) - return JVMTI_ERROR_INVALID_MONITOR; - if (_Jv_MutexUnlock (&monitor->mutex)) - return JVMTI_ERROR_NOT_MONITOR_OWNER; - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_RawMonitorWait (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor, - jlong millis) -{ - if (monitor == NULL) - return JVMTI_ERROR_INVALID_MONITOR; - int r = _Jv_CondWait (&monitor->condition, &monitor->mutex, millis, 0); - if (r == _JV_NOT_OWNER) - return JVMTI_ERROR_NOT_MONITOR_OWNER; - if (r == _JV_INTERRUPTED) - return JVMTI_ERROR_INTERRUPT; - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_RawMonitorNotify (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor) -{ - if (monitor == NULL) - return JVMTI_ERROR_INVALID_MONITOR; - if (_Jv_CondNotify (&monitor->condition, &monitor->mutex) == _JV_NOT_OWNER) - return JVMTI_ERROR_NOT_MONITOR_OWNER; - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_RawMonitorNotifyAll (MAYBE_UNUSED jvmtiEnv *env, - jrawMonitorID monitor) -{ - if (monitor == NULL) - return JVMTI_ERROR_INVALID_MONITOR; - if (_Jv_CondNotifyAll (&monitor->condition, &monitor->mutex) - == _JV_NOT_OWNER) - return JVMTI_ERROR_NOT_MONITOR_OWNER; - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_SetBreakpoint (jvmtiEnv *env, jmethodID method, jlocation location) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_LIVE); - - using namespace gnu::gcj::jvmti; - Breakpoint *bp - = BreakpointManager::getBreakpoint (reinterpret_cast<jlong> (method), - location); - if (bp == NULL) - { - jclass klass; - jvmtiError err = env->GetMethodDeclaringClass (method, &klass); - if (err != JVMTI_ERROR_NONE) - return err; - - if (!_Jv_IsInterpretedClass (klass)) - return JVMTI_ERROR_INVALID_CLASS; - - _Jv_MethodBase *base = _Jv_FindInterpreterMethod (klass, method); - if (base == NULL) - return JVMTI_ERROR_INVALID_METHODID; - - jint flags; - err = env->GetMethodModifiers (method, &flags); - if (err != JVMTI_ERROR_NONE) - return err; - - if (flags & java::lang::reflect::Modifier::NATIVE) - return JVMTI_ERROR_NATIVE_METHOD; - - _Jv_InterpMethod *imeth = reinterpret_cast<_Jv_InterpMethod *> (base); - if (imeth->get_insn (location) == NULL) - return JVMTI_ERROR_INVALID_LOCATION; - - // Now the breakpoint can be safely installed - bp = BreakpointManager::newBreakpoint (reinterpret_cast<jlong> (method), - location); - } - else - { - // Duplicate breakpoints are not permitted by JVMTI - return JVMTI_ERROR_DUPLICATE; - } - - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_ClearBreakpoint (MAYBE_UNUSED jvmtiEnv *env, jmethodID method, - jlocation location) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_LIVE); - - using namespace gnu::gcj::jvmti; - - Breakpoint *bp - = BreakpointManager::getBreakpoint (reinterpret_cast<jlong> (method), - location); - if (bp == NULL) - return JVMTI_ERROR_NOT_FOUND; - - BreakpointManager::deleteBreakpoint (reinterpret_cast<jlong> (method), location); - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_Allocate (MAYBE_UNUSED jvmtiEnv *env, jlong size, - unsigned char **result) -{ - ILLEGAL_ARGUMENT (size < 0); - NULL_CHECK (result); - if (size == 0) - *result = NULL; - else - { - *result = (unsigned char *) _Jv_MallocUnchecked (size); - if (*result == NULL) - return JVMTI_ERROR_OUT_OF_MEMORY; - } - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_Deallocate (MAYBE_UNUSED jvmtiEnv *env, unsigned char *mem) -{ - if (mem != NULL) - _Jv_Free (mem); - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_GetClassStatus (MAYBE_UNUSED jvmtiEnv *env, jclass klass, - jint *status_ptr) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE); - NULL_CHECK (status_ptr); - if (klass == NULL) - return JVMTI_ERROR_INVALID_CLASS; - - if (klass->isArray ()) - *status_ptr = JVMTI_CLASS_STATUS_ARRAY; - else if (klass->isPrimitive ()) - *status_ptr = JVMTI_CLASS_STATUS_PRIMITIVE; - else - { - jbyte state = _Jv_GetClassState (klass); - *status_ptr = 0; - if (state >= JV_STATE_LINKED) - (*status_ptr) |= JVMTI_CLASS_STATUS_VERIFIED; - if (state >= JV_STATE_PREPARED) - (*status_ptr) |= JVMTI_CLASS_STATUS_PREPARED; - if (state == JV_STATE_ERROR || state == JV_STATE_PHANTOM) - (*status_ptr) |= JVMTI_CLASS_STATUS_ERROR; - else if (state == JV_STATE_DONE) - (*status_ptr) |= JVMTI_CLASS_STATUS_INITIALIZED; - } - - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_GetClassModifiers (MAYBE_UNUSED jvmtiEnv *env, jclass klass, - jint *mods) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE); - // Don't bother checking KLASS' type. - if (klass == NULL) - return JVMTI_ERROR_INVALID_CLASS; - NULL_CHECK (mods); - *mods = klass->getModifiers(); - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_GetClassMethods (MAYBE_UNUSED jvmtiEnv *env, jclass klass, - jint *count_ptr, jmethodID **methods_ptr) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE); - // FIXME: capability can_maintain_original_method_order - // Don't bother checking KLASS' type. - if (klass == NULL) - return JVMTI_ERROR_INVALID_CLASS; - NULL_CHECK (count_ptr); - NULL_CHECK (methods_ptr); - *count_ptr = JvNumMethods(klass); - - *methods_ptr - = (jmethodID *) _Jv_MallocUnchecked (*count_ptr * sizeof (jmethodID)); - if (*methods_ptr == NULL) - return JVMTI_ERROR_OUT_OF_MEMORY; - - jmethodID start = JvGetFirstMethod (klass); - for (jint i = 0; i < *count_ptr; ++i) - // FIXME: correct? - (*methods_ptr)[i] = start + i; - - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_IsInterface (MAYBE_UNUSED jvmtiEnv *env, jclass klass, - jboolean *result) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE); - if (klass == NULL) - return JVMTI_ERROR_INVALID_CLASS; - NULL_CHECK (result); - *result = klass->isInterface(); - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_IsArrayClass (MAYBE_UNUSED jvmtiEnv *env, jclass klass, - jboolean *result) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE); - if (klass == NULL) - return JVMTI_ERROR_INVALID_CLASS; - NULL_CHECK (result); - *result = klass->isArray(); - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_GetClassLoader (MAYBE_UNUSED jvmtiEnv *env, jclass klass, - jobject *result) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE); - if (klass == NULL) - return JVMTI_ERROR_INVALID_CLASS; - NULL_CHECK (result); - *result = klass->getClassLoaderInternal(); - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_GetObjectHashCode (MAYBE_UNUSED jvmtiEnv *env, jobject obj, - jint *result) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE); - if (obj == NULL) - return JVMTI_ERROR_INVALID_OBJECT; - NULL_CHECK (result); - *result = _Jv_HashCode (obj); - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_GetFieldModifiers (MAYBE_UNUSED jvmtiEnv *env, jclass klass, - jfieldID field, jint *result) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE); - if (klass == NULL) - return JVMTI_ERROR_INVALID_CLASS; - if (field == NULL) - return JVMTI_ERROR_INVALID_FIELDID; - NULL_CHECK (result); - *result = field->getModifiers(); - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_IsFieldSynthetic (MAYBE_UNUSED jvmtiEnv *env, jclass klass, - jfieldID field, jboolean *result) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE); - if (klass == NULL) - return JVMTI_ERROR_INVALID_CLASS; - if (field == NULL) - return JVMTI_ERROR_INVALID_FIELDID; - NULL_CHECK (result); - - // FIXME: capability can_get_synthetic_attribute - *result = ((field->getModifiers() & java::lang::reflect::Modifier::SYNTHETIC) - != 0); - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_GetMethodName (MAYBE_UNUSED jvmtiEnv *env, jmethodID method, - char **name_ptr, char **signature_ptr, - char **generic_ptr) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE); - - if (method == NULL) - return JVMTI_ERROR_INVALID_METHODID; - - if (name_ptr != NULL) - { - int len = static_cast<int> (method->name->len ()); - *name_ptr = (char *) _Jv_MallocUnchecked (len + 1); - if (*name_ptr == NULL) - return JVMTI_ERROR_OUT_OF_MEMORY; - strncpy (*name_ptr, method->name->chars (), len); - (*name_ptr)[len] = '\0'; - } - - if (signature_ptr != NULL) - { - int len = static_cast<int> (method->signature->len ()); - *signature_ptr = (char *) _Jv_MallocUnchecked (len + 1); - if (*signature_ptr == NULL) - { - if (name_ptr != NULL) - _Jv_Free (*name_ptr); - return JVMTI_ERROR_OUT_OF_MEMORY; - } - strncpy (*signature_ptr, method->signature->chars (), len); - (*signature_ptr)[len] = '\0'; - } - - if (generic_ptr != NULL) - { - *generic_ptr = NULL; - } - - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_GetMethodModifiers (MAYBE_UNUSED jvmtiEnv *env, jmethodID method, - jint *result) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE); - if (method == NULL) - return JVMTI_ERROR_INVALID_METHODID; - NULL_CHECK (result); - - // FIXME: mask off some internal bits... - *result = method->accflags; - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_GetLineNumberTable (jvmtiEnv *env, jmethodID method, - jint *entry_count_ptr, - jvmtiLineNumberEntry **table_ptr) -{ - NULL_CHECK (entry_count_ptr); - NULL_CHECK (table_ptr); - - jclass klass; - jvmtiError jerr = env->GetMethodDeclaringClass (method, &klass); - if (jerr != JVMTI_ERROR_NONE) - return jerr; - - _Jv_MethodBase *base = _Jv_FindInterpreterMethod (klass, method); - if (base == NULL) - return JVMTI_ERROR_INVALID_METHODID; - - if (java::lang::reflect::Modifier::isNative (method->accflags) - || !_Jv_IsInterpretedClass (klass)) - return JVMTI_ERROR_NATIVE_METHOD; - - _Jv_InterpMethod *imeth = reinterpret_cast<_Jv_InterpMethod *> (base); - jlong start, end; - jintArray lines = NULL; - jlongArray indices = NULL; - imeth->get_line_table (start, end, lines, indices); - if (lines == NULL) - return JVMTI_ERROR_ABSENT_INFORMATION; - - jvmtiLineNumberEntry *table; - jsize len = lines->length * sizeof (jvmtiLineNumberEntry); - table = (jvmtiLineNumberEntry *) _Jv_MallocUnchecked (len); - if (table == NULL) - return JVMTI_ERROR_OUT_OF_MEMORY; - - jint *line = elements (lines); - jlong *index = elements (indices); - for (int i = 0; i < lines->length; ++i) - { - table[i].start_location = index[i]; - table[i].line_number = line[i]; - } - - *table_ptr = table; - *entry_count_ptr = lines->length; - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_GetLocalVariableTable (MAYBE_UNUSED jvmtiEnv *env, jmethodID method, - jint *num_locals, - jvmtiLocalVariableEntry **locals) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_LIVE); - NULL_CHECK (num_locals); - NULL_CHECK (locals); - - CHECK_FOR_NATIVE_METHOD(method); - - jclass klass; - jvmtiError jerr = env->GetMethodDeclaringClass (method, &klass); - if (jerr != JVMTI_ERROR_NONE) - return jerr; - - _Jv_InterpMethod *imeth = reinterpret_cast<_Jv_InterpMethod *> - (_Jv_FindInterpreterMethod (klass, method)); - - if (imeth == NULL) - return JVMTI_ERROR_INVALID_METHODID; - - jerr = env->GetMaxLocals (method, num_locals); - if (jerr != JVMTI_ERROR_NONE) - return jerr; - - jerr = env->Allocate (static_cast<jlong> - ((*num_locals) * sizeof (jvmtiLocalVariableEntry)), - reinterpret_cast<unsigned char **> (locals)); - - if (jerr != JVMTI_ERROR_NONE) - return jerr; - - //the slot in the methods local_var_table to get - int table_slot = 0; - char *name; - char *sig; - char *generic_sig; - - while (table_slot < *num_locals - && imeth->get_local_var_table (&name, &sig, &generic_sig, - &((((*locals)[table_slot].start_location))), - &((*locals)[table_slot].length), - &((*locals)[table_slot].slot), - table_slot) - >= 0) - { - char **str_ptr = &(*locals)[table_slot].name; - jerr = env->Allocate (static_cast<jlong> (strlen (name) + 1), - reinterpret_cast<unsigned char **> (str_ptr)); - if (jerr != JVMTI_ERROR_NONE) - return jerr; - strcpy ((*locals)[table_slot].name, name); - - str_ptr = &(*locals)[table_slot].signature; - jerr = env->Allocate (static_cast<jlong> (strlen (sig) + 1), - reinterpret_cast<unsigned char **> (str_ptr)); - if (jerr != JVMTI_ERROR_NONE) - return jerr; - strcpy ((*locals)[table_slot].signature, sig); - - str_ptr = &(*locals)[table_slot].generic_signature; - jerr = env->Allocate (static_cast<jlong> (strlen (generic_sig) + 1), - reinterpret_cast<unsigned char **> (str_ptr)); - if (jerr != JVMTI_ERROR_NONE) - return jerr; - strcpy ((*locals)[table_slot].generic_signature, generic_sig); - - table_slot++; - } - - if (table_slot == 0) - return JVMTI_ERROR_ABSENT_INFORMATION; - - // If there are double or long variables in the table, the the table will be - // smaller than the max number of slots, so correct for this here. - if ((table_slot) < *num_locals) - *num_locals = table_slot; - - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_IsMethodNative (MAYBE_UNUSED jvmtiEnv *env, jmethodID method, - jboolean *result) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE); - if (method == NULL) - return JVMTI_ERROR_INVALID_METHODID; - NULL_CHECK (result); - - *result = ((method->accflags & java::lang::reflect::Modifier::NATIVE) != 0); - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_IsMethodSynthetic (MAYBE_UNUSED jvmtiEnv *env, jmethodID method, - jboolean *result) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE); - if (method == NULL) - return JVMTI_ERROR_INVALID_METHODID; - NULL_CHECK (result); - - // FIXME capability can_get_synthetic_attribute - - *result = ((method->accflags & java::lang::reflect::Modifier::SYNTHETIC) - != 0); - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_GetMaxLocals (jvmtiEnv *env, jmethodID method, jint *max_locals) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE); - NULL_CHECK (max_locals); - - CHECK_FOR_NATIVE_METHOD (method); - - jclass klass; - jvmtiError jerr = env->GetMethodDeclaringClass (method, &klass); - if (jerr != JVMTI_ERROR_NONE) - return jerr; - - _Jv_InterpMethod *imeth = reinterpret_cast<_Jv_InterpMethod *> - (_Jv_FindInterpreterMethod (klass, method)); - - if (imeth == NULL) - return JVMTI_ERROR_INVALID_METHODID; - - *max_locals = imeth->get_max_locals (); - - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_GetArgumentsSize (jvmtiEnv *env, jmethodID method, jint *size) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE); - NULL_CHECK (size); - - CHECK_FOR_NATIVE_METHOD (method); - - jvmtiError jerr; - char *sig; - jint num_slots = 0; - - jerr = env->GetMethodName (method, NULL, &sig, NULL); - if (jerr != JVMTI_ERROR_NONE) - return jerr; - - // If the method is non-static add a slot for the "this" pointer. - if ((method->accflags & java::lang::reflect::Modifier::STATIC) == 0) - num_slots++; - - for (int i = 0; sig[i] != ')'; i++) - { - if (sig[i] == 'Z' || sig[i] == 'B' || sig[i] == 'C' || sig[i] == 'S' - || sig[i] == 'I' || sig[i] == 'F') - num_slots++; - else if (sig[i] == 'J' || sig[i] == 'D') - { - // If this is an array of wide types it uses a single slot - if (i > 0 && sig[i - 1] == '[') - num_slots++; - else - num_slots += 2; - } - else if (sig[i] == 'L') - { - num_slots++; - while (sig[i] != ';') - i++; - } - } - - *size = num_slots; - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_GetMethodDeclaringClass (MAYBE_UNUSED jvmtiEnv *env, - jmethodID method, - jclass *declaring_class_ptr) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_LIVE); - NULL_CHECK (declaring_class_ptr); - - jclass klass = _Jv_GetMethodDeclaringClass (method); - if (klass != NULL) - { - *declaring_class_ptr = klass; - return JVMTI_ERROR_NONE; - } - - return JVMTI_ERROR_INVALID_METHODID; -} - -static jvmtiError JNICALL -_Jv_JVMTI_GetClassLoaderClasses (MAYBE_UNUSED jvmtiEnv *env, - jobject init_loader, - jint *count_ptr, - jclass **result_ptr) -{ - using namespace java::lang; - using namespace java::util; - - REQUIRE_PHASE (env, JVMTI_PHASE_LIVE); - NULL_CHECK (count_ptr); - NULL_CHECK (result_ptr); - - ClassLoader *loader = (ClassLoader *) init_loader; - if (loader == NULL) - loader = VMClassLoader::bootLoader; - - Collection *values = loader->loadedClasses->values(); - jobjectArray array = values->toArray(); - *count_ptr = array->length; - jobject *elts = elements (array); - jclass *result - = (jclass *) _Jv_MallocUnchecked (*count_ptr * sizeof (jclass)); - if (result == NULL) - return JVMTI_ERROR_OUT_OF_MEMORY; - - // FIXME: JNI references... - memcpy (result, elts, *count_ptr * sizeof (jclass)); - - *result_ptr = result; - - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_GetStackTrace (MAYBE_UNUSED jvmtiEnv *env, jthread thread, - jint start_depth, jint max_frames, - jvmtiFrameInfo *frames, jint *frame_count) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_LIVE); - - ILLEGAL_ARGUMENT (max_frames < 0); - - NULL_CHECK (frames); - NULL_CHECK (frame_count); - - using namespace java::lang; - - THREAD_DEFAULT_TO_CURRENT (thread); - THREAD_CHECK_VALID (thread); - THREAD_CHECK_IS_ALIVE (thread); - - jvmtiError jerr = env->GetFrameCount (thread, frame_count); - if (jerr != JVMTI_ERROR_NONE) - return jerr; - - // start_depth can be either a positive number, indicating the depth of the - // stack at which to begin the trace, or a negative number indicating the - // number of frames at the bottom of the stack to exclude. These checks - // ensure that it is a valid value in either case - - ILLEGAL_ARGUMENT (start_depth >= (*frame_count)); - ILLEGAL_ARGUMENT (start_depth < (-(*frame_count))); - - _Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (thread->frame); - - // If start_depth is negative use this to determine at what depth to start - // the trace by adding it to the length of the call stack. This allows the - // use of the same frame "discarding" mechanism as for a positive start_depth - if (start_depth < 0) - start_depth = *frame_count + start_depth; - - // If start_depth > 0 "remove" start_depth frames from the beginning - // of the stack before beginning the trace by moving along the frame list. - while (start_depth > 0) - { - frame = frame->next; - start_depth--; - (*frame_count)--; - } - - // Now check to see if the array supplied by the agent is large enough to - // hold frame_count frames, after adjustment for start_depth. - if ((*frame_count) > max_frames) - (*frame_count) = max_frames; - - for (int i = 0; i < (*frame_count); i++) - { - frames[i].method = frame->self->get_method (); - - // Set the location in the frame, native frames have location = -1 - if (frame->frame_type == frame_interpreter) - { - _Jv_InterpMethod *imeth - = static_cast<_Jv_InterpMethod *> (frame->self); - _Jv_InterpFrame *interp_frame - = static_cast<_Jv_InterpFrame *> (frame); - frames[i].location = imeth->insn_index (interp_frame->get_pc ()); - } - else - frames[i].location = -1; - - frame = frame->next; - } - - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_ForceGarbageCollection (MAYBE_UNUSED jvmtiEnv *env) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_LIVE); - _Jv_RunGC(); - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_SetJNIFunctionTable (MAYBE_UNUSED jvmtiEnv *env, - const jniNativeInterface *function_table) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE); - NULL_CHECK (function_table); - memcpy (&_Jv_JNIFunctions, function_table, sizeof (jniNativeInterface)); - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_GetJNIFunctionTable (MAYBE_UNUSED jvmtiEnv *env, - jniNativeInterface **function_table) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE); - NULL_CHECK (function_table); - *function_table - = (jniNativeInterface *) _Jv_MallocUnchecked (sizeof (jniNativeInterface)); - if (*function_table == NULL) - return JVMTI_ERROR_OUT_OF_MEMORY; - memcpy (*function_table, &_Jv_JNIFunctions, sizeof (jniNativeInterface)); - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_DisposeEnvironment (jvmtiEnv *env) -{ - NULL_CHECK (env); - - if (_jvmtiEnvironments == NULL) - return JVMTI_ERROR_INVALID_ENVIRONMENT; - else - { - _envListLock->writeLock ()->lock (); - if (_jvmtiEnvironments->env == env) - { - struct jvmti_env_list *next = _jvmtiEnvironments->next; - _Jv_Free (_jvmtiEnvironments); - _jvmtiEnvironments = next; - } - else - { - struct jvmti_env_list *e = _jvmtiEnvironments; - while (e->next != NULL && e->next->env != env) - e = e->next; - if (e->next == NULL) - { - _envListLock->writeLock ()->unlock (); - return JVMTI_ERROR_INVALID_ENVIRONMENT; - } - - struct jvmti_env_list *next = e->next->next; - _Jv_Free (e->next); - e->next = next; - } - _envListLock->writeLock ()->unlock (); - } - - _Jv_Free (env); - - check_enabled_events (); - - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_GetSystemProperty (MAYBE_UNUSED jvmtiEnv *env, const char *property, - char **result) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE); - NULL_CHECK (property); - NULL_CHECK (result); - - jstring name = JvNewStringUTF(property); - jstring result_str = gnu::classpath::SystemProperties::getProperty(name); - - if (result_str == NULL) - return JVMTI_ERROR_NOT_AVAILABLE; - - int len = JvGetStringUTFLength (result_str); - *result = (char *) _Jv_MallocUnchecked (len + 1); - if (*result == NULL) - return JVMTI_ERROR_OUT_OF_MEMORY; - JvGetStringUTFRegion (result_str, 0, result_str->length(), *result); - (*result)[len] = '\0'; - - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_SetSystemProperty (MAYBE_UNUSED jvmtiEnv *env, const char *property, - const char *value) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD); - - NULL_CHECK (property); - if (value == NULL) - { - // FIXME: When would a property not be writeable? - return JVMTI_ERROR_NONE; - } - - jstring prop_str = JvNewStringUTF(property); - jstring value_str = JvNewStringUTF(value); - gnu::classpath::SystemProperties::setProperty(prop_str, value_str); - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_GetTime (MAYBE_UNUSED jvmtiEnv *env, jlong *nanos_ptr) -{ - NULL_CHECK (nanos_ptr); - *nanos_ptr = _Jv_platform_nanotime(); - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_GetAvailableProcessors (MAYBE_UNUSED jvmtiEnv *env, - jint *nprocessors_ptr) -{ - NULL_CHECK (nprocessors_ptr); -#ifdef _SC_NPROCESSORS_ONLN - *nprocessors_ptr = sysconf(_SC_NPROCESSORS_ONLN); -#else - *nprocessors_ptr = 1; -#endif - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_AddToBootstrapClassLoaderSearch (MAYBE_UNUSED jvmtiEnv *env, - const char *segment) -{ - using namespace java::lang; - using namespace java::net; - using namespace gnu::gcj::runtime; - - REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD); - NULL_CHECK (segment); - - jstring str_segment = JvNewStringUTF(segment); - URL *url; - try - { - url = new URL(JvNewStringUTF("file"), NULL, str_segment); - } - catch (jthrowable ignore) - { - return JVMTI_ERROR_ILLEGAL_ARGUMENT; - } - - BootClassLoader *loader = VMClassLoader::bootLoader; - // Don't call this too early. - // assert (loader != NULL); - loader->addURL(url); - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_SetVerboseFlag (MAYBE_UNUSED jvmtiEnv *env, jvmtiVerboseFlag flag, - jboolean value) -{ - switch (flag) - { - case JVMTI_VERBOSE_OTHER: - case JVMTI_VERBOSE_GC: - case JVMTI_VERBOSE_JNI: - // Ignore. - break; - case JVMTI_VERBOSE_CLASS: - gcj::verbose_class_flag = value; - break; - default: - return JVMTI_ERROR_ILLEGAL_ARGUMENT; - } - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_GetObjectSize (MAYBE_UNUSED jvmtiEnv *env, jobject object, - jlong *result) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE); - if (object == NULL) - return JVMTI_ERROR_INVALID_OBJECT; - NULL_CHECK (result); - - jclass klass = object->getClass(); - if (klass->isArray()) - { - jclass comp = klass->getComponentType(); - jint base - = (jint) (_Jv_uintptr_t) _Jv_GetArrayElementFromElementType(NULL, - klass->getComponentType()); - // FIXME: correct for primitive types? - jint compSize = comp->size(); - __JArray *array = (__JArray *) object; - *result = base + array->length * compSize; - } - else - { - // Note that if OBJECT is a String then it may (if - // str->data==str) take more space. Do we care? - *result = klass->size(); - } - return JVMTI_ERROR_NONE; -} - -/* An event is enabled only if it has both an event handler - and it is enabled in the environment. */ -static void -check_enabled_event (jvmtiEvent type) -{ - bool *enabled; - int offset; - -#define GET_OFFSET(Event) \ - do \ - { \ - enabled = &JVMTI::Event; \ - offset = offsetof (jvmtiEventCallbacks, Event); \ - } \ - while (0) - - switch (type) - { - case JVMTI_EVENT_VM_INIT: - GET_OFFSET (VMInit); - break; - - case JVMTI_EVENT_VM_DEATH: - GET_OFFSET (VMDeath); - break; - - case JVMTI_EVENT_THREAD_START: - GET_OFFSET (ThreadStart); - break; - - case JVMTI_EVENT_THREAD_END: - GET_OFFSET (ThreadEnd); - break; - - case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK: - GET_OFFSET (ClassFileLoadHook); - break; - - case JVMTI_EVENT_CLASS_LOAD: - GET_OFFSET (ClassLoad); - break; - - case JVMTI_EVENT_CLASS_PREPARE: - GET_OFFSET (ClassPrepare); - break; - - case JVMTI_EVENT_VM_START: - GET_OFFSET (VMStart); - break; - - case JVMTI_EVENT_EXCEPTION: - GET_OFFSET (Exception); - break; - - case JVMTI_EVENT_EXCEPTION_CATCH: - GET_OFFSET (ExceptionCatch); - break; - - case JVMTI_EVENT_SINGLE_STEP: - GET_OFFSET (SingleStep); - break; - - case JVMTI_EVENT_FRAME_POP: - GET_OFFSET (FramePop); - break; - - case JVMTI_EVENT_BREAKPOINT: - GET_OFFSET (Breakpoint); - break; - - case JVMTI_EVENT_FIELD_ACCESS: - GET_OFFSET (FieldAccess); - break; - - case JVMTI_EVENT_FIELD_MODIFICATION: - GET_OFFSET (FieldModification); - break; - - case JVMTI_EVENT_METHOD_ENTRY: - GET_OFFSET (MethodEntry); - break; - - case JVMTI_EVENT_METHOD_EXIT: - GET_OFFSET (MethodExit); - break; - - case JVMTI_EVENT_NATIVE_METHOD_BIND: - GET_OFFSET (NativeMethodBind); - break; - - case JVMTI_EVENT_COMPILED_METHOD_LOAD: - GET_OFFSET (CompiledMethodLoad); - break; - - case JVMTI_EVENT_COMPILED_METHOD_UNLOAD: - GET_OFFSET (CompiledMethodUnload); - break; - - case JVMTI_EVENT_DYNAMIC_CODE_GENERATED: - GET_OFFSET (DynamicCodeGenerated); - break; - - case JVMTI_EVENT_DATA_DUMP_REQUEST: - GET_OFFSET (DataDumpRequest); - break; - - case JVMTI_EVENT_MONITOR_WAIT: - GET_OFFSET (MonitorWait); - break; - - case JVMTI_EVENT_MONITOR_WAITED: - GET_OFFSET (MonitorWaited); - break; - - case JVMTI_EVENT_MONITOR_CONTENDED_ENTER: - GET_OFFSET (MonitorContendedEnter); - break; - - case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED: - GET_OFFSET (MonitorContendedEntered); - break; - - case JVMTI_EVENT_GARBAGE_COLLECTION_START: - GET_OFFSET (GarbageCollectionStart); - break; - - case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH: - GET_OFFSET (GarbageCollectionFinish); - break; - - case JVMTI_EVENT_OBJECT_FREE: - GET_OFFSET (ObjectFree); - break; - - case JVMTI_EVENT_VM_OBJECT_ALLOC: - GET_OFFSET (VMObjectAlloc); - break; - - default: - fprintf (stderr, - "libgcj: check_enabled_event for unknown JVMTI event (%d)\n", - (int) type); - return; - } -#undef GET_OFFSET - - int index = EVENT_INDEX (type); // safe since caller checks this - - if (_jvmtiEnvironments != NULL) - { - _envListLock->readLock ()->lock (); - struct jvmti_env_list *e; - FOREACH_ENVIRONMENT (e) - { - char *addr - = reinterpret_cast<char *> (&e->env->callbacks) + offset; - void **callback = reinterpret_cast<void **> (addr); - if (e->env->enabled[index] && *callback != NULL) - { - *enabled = true; - _envListLock->readLock ()->unlock (); - return; - } - } - - _envListLock->readLock ()->unlock (); - } - - *enabled = false; -} - -static void -check_enabled_events () -{ - check_enabled_event (JVMTI_EVENT_VM_INIT); - check_enabled_event (JVMTI_EVENT_VM_DEATH); - check_enabled_event (JVMTI_EVENT_THREAD_START); - check_enabled_event (JVMTI_EVENT_THREAD_END); - check_enabled_event (JVMTI_EVENT_CLASS_FILE_LOAD_HOOK); - check_enabled_event (JVMTI_EVENT_CLASS_LOAD); - check_enabled_event (JVMTI_EVENT_CLASS_PREPARE); - check_enabled_event (JVMTI_EVENT_VM_START); - check_enabled_event (JVMTI_EVENT_EXCEPTION); - check_enabled_event (JVMTI_EVENT_EXCEPTION_CATCH); - check_enabled_event (JVMTI_EVENT_SINGLE_STEP); - check_enabled_event (JVMTI_EVENT_FRAME_POP); - check_enabled_event (JVMTI_EVENT_BREAKPOINT); - check_enabled_event (JVMTI_EVENT_FIELD_ACCESS); - check_enabled_event (JVMTI_EVENT_FIELD_MODIFICATION); - check_enabled_event (JVMTI_EVENT_METHOD_ENTRY); - check_enabled_event (JVMTI_EVENT_METHOD_EXIT); - check_enabled_event (JVMTI_EVENT_NATIVE_METHOD_BIND); - check_enabled_event (JVMTI_EVENT_COMPILED_METHOD_LOAD); - check_enabled_event (JVMTI_EVENT_COMPILED_METHOD_UNLOAD); - check_enabled_event (JVMTI_EVENT_DYNAMIC_CODE_GENERATED); - check_enabled_event (JVMTI_EVENT_DATA_DUMP_REQUEST); - check_enabled_event (JVMTI_EVENT_MONITOR_WAIT); - check_enabled_event (JVMTI_EVENT_MONITOR_WAITED); - check_enabled_event (JVMTI_EVENT_MONITOR_CONTENDED_ENTER); - check_enabled_event (JVMTI_EVENT_MONITOR_CONTENDED_ENTERED); - check_enabled_event (JVMTI_EVENT_GARBAGE_COLLECTION_START); - check_enabled_event (JVMTI_EVENT_GARBAGE_COLLECTION_FINISH); - check_enabled_event (JVMTI_EVENT_OBJECT_FREE); - check_enabled_event (JVMTI_EVENT_VM_OBJECT_ALLOC); -} - -static jvmtiError JNICALL -_Jv_JVMTI_SetEventNotificationMode (jvmtiEnv *env, jvmtiEventMode mode, - jvmtiEvent type, jthread event_thread, ...) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE); - - if (event_thread != NULL) - { - THREAD_CHECK_VALID (event_thread); - THREAD_CHECK_IS_ALIVE (event_thread); - } - - bool enabled; - switch (mode) - { - case JVMTI_DISABLE: - enabled = false; - break; - case JVMTI_ENABLE: - enabled = true; - break; - - default: - return JVMTI_ERROR_ILLEGAL_ARGUMENT; - } - - switch (type) - { - case JVMTI_EVENT_VM_INIT: - case JVMTI_EVENT_VM_DEATH: - case JVMTI_EVENT_THREAD_START: - case JVMTI_EVENT_VM_START: - case JVMTI_EVENT_COMPILED_METHOD_LOAD: - case JVMTI_EVENT_COMPILED_METHOD_UNLOAD: - case JVMTI_EVENT_DYNAMIC_CODE_GENERATED: - case JVMTI_EVENT_DATA_DUMP_REQUEST: - ILLEGAL_ARGUMENT (event_thread != NULL); - break; - - case JVMTI_EVENT_THREAD_END: - case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK: - case JVMTI_EVENT_CLASS_LOAD: - case JVMTI_EVENT_CLASS_PREPARE: - case JVMTI_EVENT_EXCEPTION: - case JVMTI_EVENT_EXCEPTION_CATCH: - case JVMTI_EVENT_SINGLE_STEP: - case JVMTI_EVENT_FRAME_POP: - case JVMTI_EVENT_BREAKPOINT: - case JVMTI_EVENT_FIELD_ACCESS: - case JVMTI_EVENT_FIELD_MODIFICATION: - case JVMTI_EVENT_METHOD_ENTRY: - case JVMTI_EVENT_METHOD_EXIT: - case JVMTI_EVENT_NATIVE_METHOD_BIND: - case JVMTI_EVENT_MONITOR_WAIT: - case JVMTI_EVENT_MONITOR_WAITED: - case JVMTI_EVENT_MONITOR_CONTENDED_ENTER: - case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED: - case JVMTI_EVENT_GARBAGE_COLLECTION_START: - case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH: - case JVMTI_EVENT_OBJECT_FREE: - case JVMTI_EVENT_VM_OBJECT_ALLOC: - break; - - default: - return JVMTI_ERROR_INVALID_EVENT_TYPE; - } - - env->thread[EVENT_INDEX(type)] = event_thread; - env->enabled[EVENT_INDEX(type)] = enabled; - check_enabled_event (type); - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_SetEventCallbacks (jvmtiEnv *env, - const jvmtiEventCallbacks *callbacks, - jint size_of_callbacks) -{ - REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE); - ILLEGAL_ARGUMENT (size_of_callbacks < 0); - - // Copy the list of callbacks into the environment - memcpy (&env->callbacks, callbacks, sizeof (jvmtiEventCallbacks)); - - /* Check which events are now enabeld (JVMTI makes no requirements - about the order in which SetEventCallbacks and SetEventNotifications - are called. So we must check all events here. */ - check_enabled_events (); - - return JVMTI_ERROR_NONE; -} - -static jvmtiError JNICALL -_Jv_JVMTI_GetErrorName (MAYBE_UNUSED jvmtiEnv *env, jvmtiError error, - char **name_ptr) -{ - NULL_CHECK (name_ptr); - - const char *name; - switch (error) - { - case JVMTI_ERROR_NONE: - name = "none"; - break; - - case JVMTI_ERROR_NULL_POINTER: - name = "null pointer"; - break; - - case JVMTI_ERROR_OUT_OF_MEMORY: - name = "out of memory"; - break; - - case JVMTI_ERROR_ACCESS_DENIED: - name = "access denied"; - break; - - case JVMTI_ERROR_WRONG_PHASE: - name = "wrong phase"; - break; - - case JVMTI_ERROR_INTERNAL: - name = "internal error"; - break; - - case JVMTI_ERROR_UNATTACHED_THREAD: - name = "unattached thread"; - break; - - case JVMTI_ERROR_INVALID_ENVIRONMENT: - name = "invalid environment"; - break; - - case JVMTI_ERROR_INVALID_PRIORITY: - name = "invalid priority"; - break; - - case JVMTI_ERROR_THREAD_NOT_SUSPENDED: - name = "thread not suspended"; - break; - - case JVMTI_ERROR_THREAD_SUSPENDED: - name = "thread suspended"; - break; - - case JVMTI_ERROR_THREAD_NOT_ALIVE: - name = "thread not alive"; - break; - - case JVMTI_ERROR_CLASS_NOT_PREPARED: - name = "class not prepared"; - break; - - case JVMTI_ERROR_NO_MORE_FRAMES: - name = "no more frames"; - break; - - case JVMTI_ERROR_OPAQUE_FRAME: - name = "opaque frame"; - break; - - case JVMTI_ERROR_DUPLICATE: - name = "duplicate"; - break; - - case JVMTI_ERROR_NOT_FOUND: - name = "not found"; - break; - - case JVMTI_ERROR_NOT_MONITOR_OWNER: - name = "not monitor owner"; - break; - - case JVMTI_ERROR_INTERRUPT: - name = "interrupted"; - break; - - case JVMTI_ERROR_UNMODIFIABLE_CLASS: - name = "unmodifiable class"; - break; - - case JVMTI_ERROR_NOT_AVAILABLE: - name = "not available"; - break; - - case JVMTI_ERROR_ABSENT_INFORMATION: - name = "absent information"; - break; - - case JVMTI_ERROR_INVALID_EVENT_TYPE: - name = "invalid event type"; - break; - - case JVMTI_ERROR_NATIVE_METHOD: - name = "native method"; - break; - - case JVMTI_ERROR_INVALID_THREAD: - name = "invalid thread"; - break; - - case JVMTI_ERROR_INVALID_THREAD_GROUP: - name = "invalid thread group"; - break; - - case JVMTI_ERROR_INVALID_OBJECT: - name = "invalid object"; - break; - - case JVMTI_ERROR_INVALID_CLASS: - name = "invalid class"; - break; - - case JVMTI_ERROR_INVALID_METHODID: - name = "invalid method ID"; - break; - - case JVMTI_ERROR_INVALID_LOCATION: - name = "invalid location"; - break; - - case JVMTI_ERROR_INVALID_FIELDID: - name = "invalid field ID"; - break; - - case JVMTI_ERROR_TYPE_MISMATCH: - name = "type mismatch"; - break; - - case JVMTI_ERROR_INVALID_SLOT: - name = "invalid slot"; - break; - - case JVMTI_ERROR_INVALID_MONITOR: - name = "invalid monitor"; - break; - - case JVMTI_ERROR_INVALID_CLASS_FORMAT: - name = "invalid class format"; - break; - - case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION: - name = "circular class definition"; - break; - - case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED: - name = "unsupported redefinition: method added"; - break; - - case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED: - name = "unsupported redefinition: schema changed"; - break; - - case JVMTI_ERROR_INVALID_TYPESTATE: - name = "invalid type state"; - break; - - case JVMTI_ERROR_FAILS_VERIFICATION: - name = "fails verification"; - break; - - case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED: - name = "unsupported redefinition: hierarchy changed"; - break; - - case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED: - name = "unsupported redefinition: method deleted"; - break; - - case JVMTI_ERROR_UNSUPPORTED_VERSION: - name = "unsupported version"; - break; - - case JVMTI_ERROR_NAMES_DONT_MATCH: - name = "names do not match"; - break; - - case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED: - name = "unsupported redefinition: class modifiers changed"; - break; - - case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED: - name = "unsupported redefinition: method modifiers changed"; - break; - - case JVMTI_ERROR_MUST_POSSESS_CAPABILITY: - name = "must possess capability"; - break; - - case JVMTI_ERROR_ILLEGAL_ARGUMENT: - name = "illegal argument"; - break; - - default: - return JVMTI_ERROR_ILLEGAL_ARGUMENT; - } - - *name_ptr = (char *) _Jv_MallocUnchecked (strlen (name) + 1); - if (*name_ptr == NULL) - return JVMTI_ERROR_OUT_OF_MEMORY; - - strcpy (*name_ptr, name); - return JVMTI_ERROR_NONE; -} - -#define RESERVED NULL -#define UNIMPLEMENTED NULL - -struct _Jv_jvmtiEnv _Jv_JVMTI_Interface = -{ - RESERVED, // reserved1 - _Jv_JVMTI_SetEventNotificationMode, // SetEventNotificationMode - RESERVED, // reserved3 - _Jv_JVMTI_GetAllThreads, // GetAllThreads - _Jv_JVMTI_SuspendThread, // SuspendThread - _Jv_JVMTI_ResumeThread, // ResumeThread - UNIMPLEMENTED, // StopThread - _Jv_JVMTI_InterruptThread, // InterruptThread - UNIMPLEMENTED, // GetThreadInfo - UNIMPLEMENTED, // GetOwnedMonitorInfo - UNIMPLEMENTED, // GetCurrentContendedMonitor - UNIMPLEMENTED, // RunAgentThread - UNIMPLEMENTED, // GetTopThreadGroups - UNIMPLEMENTED, // GetThreadGroupInfo - UNIMPLEMENTED, // GetThreadGroupChildren - _Jv_JVMTI_GetFrameCount, // GetFrameCount - _Jv_JVMTI_GetThreadState, // GetThreadState - RESERVED, // reserved18 - UNIMPLEMENTED, // GetFrameLocation - UNIMPLEMENTED, // NotifyPopFrame - _Jv_JVMTI_GetLocalObject, // GetLocalObject - _Jv_JVMTI_GetLocalInt, // GetLocalInt - _Jv_JVMTI_GetLocalLong, // GetLocalLong - _Jv_JVMTI_GetLocalFloat, // GetLocalFloat - _Jv_JVMTI_GetLocalDouble, // GetLocalDouble - _Jv_JVMTI_SetLocalObject, // SetLocalObject - _Jv_JVMTI_SetLocalInt, // SetLocalInt - _Jv_JVMTI_SetLocalLong, // SetLocalLong - _Jv_JVMTI_SetLocalFloat, // SetLocalFloat - _Jv_JVMTI_SetLocalDouble, // SetLocalDouble - _Jv_JVMTI_CreateRawMonitor, // CreateRawMonitor - _Jv_JVMTI_DestroyRawMonitor, // DestroyRawMonitor - _Jv_JVMTI_RawMonitorEnter, // RawMonitorEnter - _Jv_JVMTI_RawMonitorExit, // RawMonitorExit - _Jv_JVMTI_RawMonitorWait, // RawMonitorWait - _Jv_JVMTI_RawMonitorNotify, // RawMonitorNotify - _Jv_JVMTI_RawMonitorNotifyAll, // RawMonitorNotifyAll - _Jv_JVMTI_SetBreakpoint, // SetBreakpoint - _Jv_JVMTI_ClearBreakpoint, // ClearBreakpoint - RESERVED, // reserved40 - UNIMPLEMENTED, // SetFieldAccessWatch - UNIMPLEMENTED, // ClearFieldAccessWatch - UNIMPLEMENTED, // SetFieldModificationWatch - UNIMPLEMENTED, // ClearFieldModificationWatch - RESERVED, // reserved45 - _Jv_JVMTI_Allocate, // Allocate - _Jv_JVMTI_Deallocate, // Deallocate - UNIMPLEMENTED, // GetClassSignature - _Jv_JVMTI_GetClassStatus, // GetClassStatus - UNIMPLEMENTED, // GetSourceFileName - _Jv_JVMTI_GetClassModifiers, // GetClassModifiers - _Jv_JVMTI_GetClassMethods, // GetClassMethods - UNIMPLEMENTED, // GetClassFields - UNIMPLEMENTED, // GetImplementedInterfaces - _Jv_JVMTI_IsInterface, // IsInterface - _Jv_JVMTI_IsArrayClass, // IsArrayClass - _Jv_JVMTI_GetClassLoader, // GetClassLoader - _Jv_JVMTI_GetObjectHashCode, // GetObjectHashCode - UNIMPLEMENTED, // GetObjectMonitorUsage - UNIMPLEMENTED, // GetFieldName - UNIMPLEMENTED, // GetFieldDeclaringClass - _Jv_JVMTI_GetFieldModifiers, // GetFieldModifiers - _Jv_JVMTI_IsFieldSynthetic, // IsFieldSynthetic - _Jv_JVMTI_GetMethodName, // GetMethodName - _Jv_JVMTI_GetMethodDeclaringClass, // GetMethodDeclaringClass - _Jv_JVMTI_GetMethodModifiers, // GetMethodModifers - RESERVED, // reserved67 - _Jv_JVMTI_GetMaxLocals, // GetMaxLocals - _Jv_JVMTI_GetArgumentsSize, // GetArgumentsSize - _Jv_JVMTI_GetLineNumberTable, // GetLineNumberTable - UNIMPLEMENTED, // GetMethodLocation - _Jv_JVMTI_GetLocalVariableTable, // GetLocalVariableTable - RESERVED, // reserved73 - RESERVED, // reserved74 - UNIMPLEMENTED, // GetBytecodes - _Jv_JVMTI_IsMethodNative, // IsMethodNative - _Jv_JVMTI_IsMethodSynthetic, // IsMethodSynthetic - UNIMPLEMENTED, // GetLoadedClasses - _Jv_JVMTI_GetClassLoaderClasses, // GetClassLoaderClasses - UNIMPLEMENTED, // PopFrame - RESERVED, // reserved81 - RESERVED, // reserved82 - RESERVED, // reserved83 - RESERVED, // reserved84 - RESERVED, // reserved85 - RESERVED, // reserved86 - UNIMPLEMENTED, // RedefineClasses - UNIMPLEMENTED, // GetVersionNumber - UNIMPLEMENTED, // GetCapabilities - UNIMPLEMENTED, // GetSourceDebugExtension - UNIMPLEMENTED, // IsMethodObsolete - UNIMPLEMENTED, // SuspendThreadList - UNIMPLEMENTED, // ResumeThreadList - RESERVED, // reserved94 - RESERVED, // reserved95 - RESERVED, // reserved96 - RESERVED, // reserved97 - RESERVED, // reserved98 - RESERVED, // reserved99 - UNIMPLEMENTED, // GetAllStackTraces - UNIMPLEMENTED, // GetThreadListStackTraces - UNIMPLEMENTED, // GetThreadLocalStorage - UNIMPLEMENTED, // SetThreadLocalStorage - _Jv_JVMTI_GetStackTrace, // GetStackTrace - RESERVED, // reserved105 - UNIMPLEMENTED, // GetTag - UNIMPLEMENTED, // SetTag - _Jv_JVMTI_ForceGarbageCollection, // ForceGarbageCollection - UNIMPLEMENTED, // IterateOverObjectsReachable - UNIMPLEMENTED, // IterateOverReachableObjects - UNIMPLEMENTED, // IterateOverHeap - UNIMPLEMENTED, // IterateOverInstanceOfClass - RESERVED, // reserved113 - UNIMPLEMENTED, // GetObjectsWithTags - RESERVED, // reserved115 - RESERVED, // reserved116 - RESERVED, // reserved117 - RESERVED, // reserved118 - RESERVED, // reserved119 - _Jv_JVMTI_SetJNIFunctionTable, // SetJNIFunctionTable - _Jv_JVMTI_GetJNIFunctionTable, // GetJNIFunctionTable - _Jv_JVMTI_SetEventCallbacks, // SetEventCallbacks - UNIMPLEMENTED, // GenerateEvents - UNIMPLEMENTED, // GetExtensionFunctions - UNIMPLEMENTED, // GetExtensionEvents - UNIMPLEMENTED, // SetExtensionEventCallback - _Jv_JVMTI_DisposeEnvironment, // DisposeEnvironment - _Jv_JVMTI_GetErrorName, // GetErrorName - UNIMPLEMENTED, // GetJLocationFormat - UNIMPLEMENTED, // GetSystemProperties - _Jv_JVMTI_GetSystemProperty, // GetSystemProperty - _Jv_JVMTI_SetSystemProperty, // SetSystemProperty - UNIMPLEMENTED, // GetPhase - UNIMPLEMENTED, // GetCurrentThreadCpuTimerInfo - UNIMPLEMENTED, // GetCurrentThreadCpuTime - UNIMPLEMENTED, // GetThreadCpuTimerInfo - UNIMPLEMENTED, // GetThreadCpuTime - UNIMPLEMENTED, // GetTimerInfo - _Jv_JVMTI_GetTime, // GetTime - UNIMPLEMENTED, // GetPotentialCapabilities - RESERVED, // reserved141 - UNIMPLEMENTED, // AddCapabilities - UNIMPLEMENTED, // RelinquishCapabilities - _Jv_JVMTI_GetAvailableProcessors, // GetAvailableProcessors - RESERVED, // reserved145 - RESERVED, // reserved146 - UNIMPLEMENTED, // GetEnvironmentLocalStorage - UNIMPLEMENTED, // SetEnvironmentLocalStorage - _Jv_JVMTI_AddToBootstrapClassLoaderSearch, // AddToBootstrapClassLoaderSearch - _Jv_JVMTI_SetVerboseFlag, // SetVerboseFlag - RESERVED, // reserved151 - RESERVED, // reserved152 - RESERVED, // reserved153 - _Jv_JVMTI_GetObjectSize // GetObjectSize -}; - -_Jv_JVMTIEnv * -_Jv_GetJVMTIEnv (void) -{ - _Jv_JVMTIEnv *env - = (_Jv_JVMTIEnv *) _Jv_MallocUnchecked (sizeof (_Jv_JVMTIEnv)); - memset (env, 0, sizeof (_Jv_JVMTIEnv)); - env->p = &_Jv_JVMTI_Interface; - struct jvmti_env_list *element - = (struct jvmti_env_list *) _Jv_MallocUnchecked (sizeof (struct jvmti_env_list)); - element->env = env; - element->next = NULL; - - _envListLock->writeLock ()->lock (); - if (_jvmtiEnvironments == NULL) - _jvmtiEnvironments = element; - else - { - struct jvmti_env_list *e; - for (e = _jvmtiEnvironments; e->next != NULL; e = e->next) - ; - e->next = element; - } - _envListLock->writeLock ()->unlock (); - - /* Mark JVMTI active. This is used to force the interpreter - to use either debugging or non-debugging code. Once JVMTI - has been enabled, the non-debug interpreter cannot be used. */ - JVMTI::enabled = true; - return env; -} - -void -_Jv_JVMTI_Init () -{ - _jvmtiEnvironments = NULL; - _envListLock - = new java::util::concurrent::locks::ReentrantReadWriteLock (); - - // No environments, so this should set all JVMTI:: members to false - check_enabled_events (); -} - -static void -post_event (jvmtiEnv *env, jvmtiEvent type, jthread event_thread, va_list args) -{ -#define ARG(Type,Name) Type Name = (Type) va_arg (args, Type) - -#define GET_BOOLEAN_ARG(Name) \ - ARG (int, b); \ - jboolean Name = (b == 0) ? false : true - -#define GET_CHAR_ARG(Name) \ - ARG (int, c); \ - char Name = static_cast<char> (c) - - switch (type) - { - case JVMTI_EVENT_VM_INIT: - if (env->callbacks.VMInit != NULL) - { - ARG (JNIEnv *, jni_env); - env->callbacks.VMInit (env, jni_env, event_thread); - } - break; - - case JVMTI_EVENT_VM_DEATH: - if (env->callbacks.VMDeath != NULL) - { - ARG (JNIEnv *, jni_env); - env->callbacks.VMDeath (env, jni_env); - } - break; - - case JVMTI_EVENT_THREAD_START: - if (env->callbacks.ThreadStart != NULL) - { - ARG (JNIEnv *, jni_env); - env->callbacks.ThreadStart (env, jni_env, event_thread); - } - break; - - case JVMTI_EVENT_THREAD_END: - if (env->callbacks.ThreadEnd != NULL) - { - ARG (JNIEnv *, jni_env); - env->callbacks.ThreadEnd (env, jni_env, event_thread); - } - break; - - case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK: - if (env->callbacks.ClassFileLoadHook != NULL) - { - ARG (JNIEnv *, jni_env); - ARG (jclass, class_being_redefined); - ARG (jobject, loader); - ARG (const char *, name); - ARG (jobject, protection_domain); - ARG (jint, class_data_len); - ARG (const unsigned char *, class_data); - ARG (jint *, new_class_data_len); - ARG (unsigned char **, new_class_data); - env->callbacks.ClassFileLoadHook (env, jni_env, - class_being_redefined, loader, - name, protection_domain, - class_data_len, class_data, - new_class_data_len, - new_class_data); - } - break; - - case JVMTI_EVENT_CLASS_LOAD: - if (env->callbacks.ClassLoad != NULL) - { - ARG (JNIEnv *, jni_env); - ARG (jclass, klass); - env->callbacks.ClassLoad (env, jni_env, event_thread, klass); - } - break; - - case JVMTI_EVENT_CLASS_PREPARE: - if (env->callbacks.ClassPrepare != NULL) - { - ARG (JNIEnv *, jni_env); - ARG (jclass, klass); - env->callbacks.ClassPrepare (env, jni_env, event_thread, klass); - } - break; - - case JVMTI_EVENT_VM_START: - if (env->callbacks.VMStart != NULL) - { - ARG (JNIEnv *, jni_env); - env->callbacks.VMStart (env, jni_env); - } - break; - - case JVMTI_EVENT_EXCEPTION: - if (env->callbacks.Exception != NULL) - { - ARG (JNIEnv *, jni_env); - ARG (jmethodID, method); - ARG (jlocation, location); - ARG (jobject, exception); - ARG (jmethodID, catch_method); - ARG (jlocation, catch_location); - env->callbacks.Exception (env, jni_env, event_thread, method, - location, exception, catch_method, - catch_location); - } - break; - - case JVMTI_EVENT_EXCEPTION_CATCH: - if (env->callbacks.ExceptionCatch != NULL) - { - ARG (JNIEnv *, jni_env); - ARG (jmethodID, method); - ARG (jlocation, location); - ARG (jobject, exception); - env->callbacks.ExceptionCatch (env, jni_env, event_thread, method, - location, exception); - } - break; - - case JVMTI_EVENT_SINGLE_STEP: - if (env->callbacks.SingleStep != NULL) - { - ARG (JNIEnv *, jni_env); - ARG (jmethodID, method); - ARG (jlocation, location); - env->callbacks.SingleStep (env, jni_env, event_thread, method, - location); - } - break; - - case JVMTI_EVENT_FRAME_POP: - if (env->callbacks.FramePop != NULL) - { - ARG (JNIEnv *, jni_env); - ARG (jmethodID, method); - GET_BOOLEAN_ARG (was_popped_by_exception); - env->callbacks.FramePop (env, jni_env, event_thread, method, - was_popped_by_exception); - } - break; - - case JVMTI_EVENT_BREAKPOINT: - if (env->callbacks.Breakpoint != NULL) - { - ARG (JNIEnv *, jni_env); - ARG (jmethodID, method); - ARG (jlocation, location); - env->callbacks.Breakpoint (env, jni_env, event_thread, method, - location); - } - break; - - case JVMTI_EVENT_FIELD_ACCESS: - if (env->callbacks.FieldAccess != NULL) - { - ARG (JNIEnv *, jni_env); - ARG (jmethodID, method); - ARG (jlocation, location); - ARG (jclass, field_class); - ARG (jobject, object); - ARG (jfieldID, field); - env->callbacks.FieldAccess (env, jni_env, event_thread, method, - location, field_class, object, field); - } - break; - - case JVMTI_EVENT_FIELD_MODIFICATION: - if (env->callbacks.FieldModification != NULL) - { - ARG (JNIEnv *, jni_env); - ARG (jmethodID, method); - ARG (jlocation, location); - ARG (jclass, field_class); - ARG (jobject, object); - ARG (jfieldID, field); - GET_CHAR_ARG (signature_type); - ARG (jvalue, new_value); - env->callbacks.FieldModification (env, jni_env, event_thread, method, - location, field_class, object, - field, signature_type, new_value); - } - break; - - case JVMTI_EVENT_METHOD_ENTRY: - if (env->callbacks.MethodEntry != NULL) - { - ARG (JNIEnv *, jni_env); - ARG (jmethodID, method); - env->callbacks.MethodEntry (env, jni_env, event_thread, method); - } - break; - - case JVMTI_EVENT_METHOD_EXIT: - if (env->callbacks.MethodExit != NULL) - { - ARG (JNIEnv *, jni_env); - ARG (jmethodID, method); - GET_BOOLEAN_ARG (was_popped_by_exception); - ARG (jvalue, return_value); - env->callbacks.MethodExit (env, jni_env, event_thread, method, - was_popped_by_exception, return_value); - } - break; - - case JVMTI_EVENT_NATIVE_METHOD_BIND: - if (env->callbacks.NativeMethodBind != NULL) - { - ARG (JNIEnv *, jni_env); - ARG (jmethodID, method); - ARG (void *, address); - ARG (void **, new_address_ptr); - env->callbacks.NativeMethodBind (env, jni_env, event_thread, method, - address, new_address_ptr); - } - break; - - case JVMTI_EVENT_COMPILED_METHOD_LOAD: - if (env->callbacks.CompiledMethodLoad != NULL) - { - ARG (jmethodID, method); - ARG (jint, code_size); - ARG (const void *, code_addr); - ARG (jint, map_length); - ARG (const jvmtiAddrLocationMap *, map); - ARG (const void *, compile_info); - env->callbacks.CompiledMethodLoad (env, method, code_size, code_addr, - map_length, map, compile_info); - } - break; - - case JVMTI_EVENT_COMPILED_METHOD_UNLOAD: - if (env->callbacks.CompiledMethodUnload != NULL) - { - ARG (jmethodID, method); - ARG (const void *, code_addr); - env->callbacks.CompiledMethodUnload (env, method, code_addr); - } - break; - - case JVMTI_EVENT_DYNAMIC_CODE_GENERATED: - if (env->callbacks.DynamicCodeGenerated != NULL) - { - ARG (const char *, name); - ARG (const void *, address); - ARG (jint, length); - env->callbacks.DynamicCodeGenerated (env, name, address, length); - } - break; - - case JVMTI_EVENT_DATA_DUMP_REQUEST: - if (env->callbacks.DataDumpRequest != NULL) - { - env->callbacks.DataDumpRequest (env); - } - break; - - case JVMTI_EVENT_MONITOR_WAIT: - if (env->callbacks.MonitorWait != NULL) - { - ARG (JNIEnv *, jni_env); - ARG (jobject, object); - ARG (jlong, timeout); - env->callbacks.MonitorWait (env, jni_env, event_thread, object, - timeout); - } - break; - - case JVMTI_EVENT_MONITOR_WAITED: - if (env->callbacks.MonitorWaited != NULL) - { - ARG (JNIEnv *, jni_env); - ARG (jobject, object); - GET_BOOLEAN_ARG (timed_out); - env->callbacks.MonitorWaited (env, jni_env, event_thread, object, - timed_out); - } - break; - - case JVMTI_EVENT_MONITOR_CONTENDED_ENTER: - if (env->callbacks.MonitorContendedEnter != NULL) - { - ARG (JNIEnv *, jni_env); - ARG (jobject, object); - env->callbacks.MonitorContendedEnter (env, jni_env, event_thread, - object); - } - break; - - case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED: - if (env->callbacks.MonitorContendedEntered != NULL) - { - ARG (JNIEnv *, jni_env); - ARG (jobject, object); - env->callbacks.MonitorContendedEntered (env, jni_env, event_thread, - object); - } - break; - - case JVMTI_EVENT_GARBAGE_COLLECTION_START: - if (env->callbacks.GarbageCollectionStart != NULL) - { - env->callbacks.GarbageCollectionStart (env); - } - break; - - case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH: - if (env->callbacks.GarbageCollectionFinish != NULL) - { - env->callbacks.GarbageCollectionFinish (env); - } - break; - - case JVMTI_EVENT_OBJECT_FREE: - if (env->callbacks.ObjectFree != NULL) - { - ARG (jlong, tag); - env->callbacks.ObjectFree (env, tag); - } - break; - - case JVMTI_EVENT_VM_OBJECT_ALLOC: - if (env->callbacks.VMObjectAlloc != NULL) - { - ARG (JNIEnv *, jni_env); - ARG (jobject, object); - ARG (jclass, object_class); - ARG (jlong, size); - env->callbacks.VMObjectAlloc (env, jni_env, event_thread, - object, object_class, size); - } - break; - - default: - fprintf (stderr, "libgcj: post of unknown JVMTI event (%d)\n", - (int) type); - break; - } - va_end (args); -#undef ARG -#undef GET_BOOLEAN_ARG -#undef GET_CHAR_ARG -} - -/* Post an event to requesting JVMTI environments - * - * This function should not be called without consulting the - * JVMTI_REQUESTED_EVENT macro first (for speed). It does no real - * harm (other than kill speed), since this function will still - * only send the event if it was properly requested by an environment. - */ -void -_Jv_JVMTI_PostEvent (jvmtiEvent type, jthread event_thread, ...) -{ - va_list args; - va_start (args, event_thread); - - _envListLock->readLock ()->lock (); - struct jvmti_env_list *e; - FOREACH_ENVIRONMENT (e) - { - /* Events are only posted if the event was explicitly enabled, - it has a registered event handler, and the event thread - matches (either globally or restricted to a specific thread). - Here we check all but the event handler, which will be handled - by post_event. */ - if (e->env->enabled[EVENT_INDEX(type)] - && (e->env->thread[EVENT_INDEX(type)] == NULL - || e->env->thread[EVENT_INDEX(type)] == event_thread)) - { - post_event (e->env, type, event_thread, args); - } - } - _envListLock->readLock ()->unlock (); - va_end (args); -} |