mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-02 00:04:30 +08:00
jvmti.cc (_Jv_JVMTI_DisposeEnvironment): Check for enabled events.
* jvmti.cc (_Jv_JVMTI_DisposeEnvironment): Check for enabled events. (check_enabled_event): New function. (check_enabled_events): New function. (post_event): New function. (_Jv_JVMTI_SetEventNotificationMode): New function. (_Jv_JVMTI_SetEventCallbacks): New function. (_Jv_JVMTI_Interface): Define SetEventNotificationMode and SetEventCallbacks members. * include/jvmti-int.h: New file. * include/jvmti_md.h (EVENT_SLOTS) [__GCJ_JNI_IMP__]: Define. (_CLASSPATH_JVMTIENV_CONTENTS) [__GCJ_JNI_IMPL__]: Define. * testsuite/libjava.jvmti/events.java: New file. * testsuite/libjava.jvmti/events.out: New file. * testsuite/libjava.jvmti/natevents.cc: New file. From-SVN: r117133
This commit is contained in:
parent
14c7148908
commit
ebf29cf63f
@ -1,3 +1,21 @@
|
||||
2006-09-21 Keith Seitz <keiths@redhat.com>
|
||||
|
||||
* jvmti.cc (_Jv_JVMTI_DisposeEnvironment): Check for enabled
|
||||
events.
|
||||
(check_enabled_event): New function.
|
||||
(check_enabled_events): New function.
|
||||
(post_event): New function.
|
||||
(_Jv_JVMTI_SetEventNotificationMode): New function.
|
||||
(_Jv_JVMTI_SetEventCallbacks): New function.
|
||||
(_Jv_JVMTI_Interface): Define SetEventNotificationMode and
|
||||
SetEventCallbacks members.
|
||||
* include/jvmti-int.h: New file.
|
||||
* include/jvmti_md.h (EVENT_SLOTS) [__GCJ_JNI_IMP__]: Define.
|
||||
(_CLASSPATH_JVMTIENV_CONTENTS) [__GCJ_JNI_IMPL__]: Define.
|
||||
* testsuite/libjava.jvmti/events.java: New file.
|
||||
* testsuite/libjava.jvmti/events.out: New file.
|
||||
* testsuite/libjava.jvmti/natevents.cc: New file.
|
||||
|
||||
2006-09-21 Sandro Tolaini <tolaini@libero.it>
|
||||
|
||||
* configure.ac: Don't use darwin-signal.h as signal handler for
|
||||
|
85
libjava/include/jvmti-int.h
Normal file
85
libjava/include/jvmti-int.h
Normal file
@ -0,0 +1,85 @@
|
||||
/* jvmti-int.h -- Internal JVMTI definitions
|
||||
Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
#ifndef __GCJ_JVTMI_INT_H__
|
||||
#define __GCJ_JVMTI_INT_H__
|
||||
|
||||
/* A macro to map jvmtiEvent to an index in thread[] and enabled[]
|
||||
in the jvmtiEnv. This will only work if the order of events listed
|
||||
in jvmtiEvent and jvmtiEventCallbacks is kept the same (which should
|
||||
not be a problem). */
|
||||
#define EVENT_INDEX(jvmtievent) (int)(jvmtievent - JVMTI_EVENT_VM_INIT)
|
||||
|
||||
/* A few globals to help limit the impact of JVMTI on normal operations.
|
||||
False means no JVMTI environment requested that event type. */
|
||||
namespace JVMTI
|
||||
{
|
||||
bool VMInit;
|
||||
bool VMDeath;
|
||||
bool ThreadStart;
|
||||
bool ThreadEnd;
|
||||
bool ClassFileLoadHook;
|
||||
bool ClassLoad;
|
||||
bool ClassPrepare;
|
||||
bool VMStart;
|
||||
bool Exception;
|
||||
bool ExceptionCatch;
|
||||
bool SingleStep;
|
||||
bool FramePop;
|
||||
bool Breakpoint;
|
||||
bool FieldAccess;
|
||||
bool FieldModification;
|
||||
bool MethodEntry;
|
||||
bool MethodExit;
|
||||
bool NativeMethodBind;
|
||||
bool CompiledMethodLoad;
|
||||
bool CompiledMethodUnload;
|
||||
bool DynamicCodeGenerated;
|
||||
bool DataDumpRequest;
|
||||
bool reserved72;
|
||||
bool MonitorWait;
|
||||
bool MonitorWaited;
|
||||
bool MonitorContendedEnter;
|
||||
bool MonitorContendedEntered;
|
||||
bool reserved77;
|
||||
bool reserved78;
|
||||
bool reserved79;
|
||||
bool reserved80;
|
||||
bool GarbageCollectionStart;
|
||||
bool GarbageCollectionFinish;
|
||||
bool ObjectFree;
|
||||
bool VMObjectAlloc;
|
||||
};
|
||||
|
||||
/* A macro to test whether an event should be posted to JVMTI.*/
|
||||
#define JVMTI_REQUESTED_EVENT(Event) __builtin_expect (JVMTI::Event, false)
|
||||
|
||||
/* Post the event to requesting JVMTI environments.
|
||||
|
||||
For speed, this function should only be called after
|
||||
JVMTI_REQUESTED_EVENT is checked. */
|
||||
extern void _Jv_JVMTI_PostEvent (jvmtiEvent type, jthread event_thread, ...);
|
||||
#endif /* __GCJ_JVMTI_INT_H__ */
|
@ -27,6 +27,32 @@ executable file might be covered by the GNU General Public License. */
|
||||
#ifndef __GCJ_JVMTI_MD_H__
|
||||
#define __GCJ_JVMTI_MD_H__
|
||||
|
||||
// nothing
|
||||
#ifdef __GCJ_JNI_IMPL__
|
||||
|
||||
/* If __GCJ_JNI_IMPL__ is defined, then we assume that we're building
|
||||
libgcj itself, and we include functions which should not be exposed
|
||||
to JVMTI users. */
|
||||
|
||||
/* The number of event slots needed to keep track of event reporting
|
||||
constraints for an environment. This will only work if the order of
|
||||
events listed in jvmtiEvent and jvmtiEventCallbacks is kept the same
|
||||
(which should not be a problem). */
|
||||
#define EVENT_SLOTS \
|
||||
(int)(JVMTI_EVENT_VM_OBJECT_ALLOC - JVMTI_EVENT_VM_INIT + 1)
|
||||
|
||||
/* Contents of the jvmtiEnv; but only inside the implementation. */
|
||||
#define _CLASSPATH_JVMTIENV_CONTENTS \
|
||||
/* Event handlers registered via SetEventCallbacks */ \
|
||||
jvmtiEventCallbacks callbacks; \
|
||||
\
|
||||
/* Array of event thread for which to report event. */ \
|
||||
/* NULL means all threads. One for each callback. */ \
|
||||
jthread thread[EVENT_SLOTS]; \
|
||||
\
|
||||
/* Array of notification modes for callbacks. */ \
|
||||
/* One for each callback. */ \
|
||||
bool enabled[EVENT_SLOTS];
|
||||
|
||||
#endif /* __GCJ_JNI_IMPL__ */
|
||||
|
||||
#endif /* __GCJ_JVMTI_MD_H__ */
|
||||
|
686
libjava/jvmti.cc
686
libjava/jvmti.cc
@ -15,6 +15,7 @@ details. */
|
||||
#include <java-threads.h>
|
||||
#include <java-gc.h>
|
||||
#include <jvmti.h>
|
||||
#include "jvmti-int.h"
|
||||
|
||||
#include <gcj/method.h>
|
||||
|
||||
@ -32,6 +33,9 @@ details. */
|
||||
#include <java/util/HashMap.h>
|
||||
#include <java/net/URL.h>
|
||||
|
||||
static void check_enabled_events (void);
|
||||
static void check_enabled_event (jvmtiEvent);
|
||||
|
||||
extern struct JNINativeInterface _Jv_JNIFunctions;
|
||||
|
||||
struct _Jv_rawMonitorID
|
||||
@ -519,6 +523,9 @@ _Jv_JVMTI_DisposeEnvironment (jvmtiEnv *env)
|
||||
}
|
||||
|
||||
_Jv_Free (env);
|
||||
|
||||
check_enabled_events ();
|
||||
|
||||
return JVMTI_ERROR_NONE;
|
||||
}
|
||||
|
||||
@ -665,6 +672,300 @@ _Jv_JVMTI_GetObjectSize (MAYBE_UNUSED jvmtiEnv *env, jobject object,
|
||||
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
|
||||
|
||||
JvSynchronize dummy (_envListLock);
|
||||
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;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
*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)
|
||||
{
|
||||
using namespace java::lang;
|
||||
Thread *t = reinterpret_cast<Thread *> (event_thread);
|
||||
THREAD_CHECK_VALID (t);
|
||||
THREAD_CHECK_IS_ALIVE (t);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
jvmtiError
|
||||
_Jv_JVMTI_GetErrorName (MAYBE_UNUSED jvmtiEnv *env, jvmtiError error,
|
||||
char **name_ptr)
|
||||
@ -884,7 +1185,7 @@ _Jv_JVMTI_GetErrorName (MAYBE_UNUSED jvmtiEnv *env, jvmtiError error,
|
||||
struct _Jv_jvmtiEnv _Jv_JVMTI_Interface =
|
||||
{
|
||||
RESERVED, // reserved1
|
||||
UNIMPLEMENTED, // SetEventNotification
|
||||
_Jv_JVMTI_SetEventNotificationMode, // SetEventNotificationMode
|
||||
RESERVED, // reserved3
|
||||
UNIMPLEMENTED, // GetAllThreads
|
||||
_Jv_JVMTI_SuspendThread, // SuspendThread
|
||||
@ -1004,7 +1305,7 @@ struct _Jv_jvmtiEnv _Jv_JVMTI_Interface =
|
||||
RESERVED, // reserved119
|
||||
_Jv_JVMTI_SetJNIFunctionTable, // SetJNIFunctionTable
|
||||
_Jv_JVMTI_GetJNIFunctionTable, // GetJNIFunctionTable
|
||||
UNIMPLEMENTED, // SetEventCallbacks
|
||||
_Jv_JVMTI_SetEventCallbacks, // SetEventCallbacks
|
||||
UNIMPLEMENTED, // GenerateEvents
|
||||
UNIMPLEMENTED, // GetExtensionFunctions
|
||||
UNIMPLEMENTED, // GetExtensionEvents
|
||||
@ -1072,4 +1373,385 @@ _Jv_JVMTI_Init ()
|
||||
{
|
||||
_jvmtiEnvironments = NULL;
|
||||
_envListLock = new java::lang::Object ();
|
||||
|
||||
// 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);
|
||||
|
||||
JvSynchronize dummy (_envListLock);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
va_end (args);
|
||||
}
|
||||
|
12
libjava/testsuite/libjava.jvmti/events.java
Normal file
12
libjava/testsuite/libjava.jvmti/events.java
Normal file
@ -0,0 +1,12 @@
|
||||
// Test JVMTI event notifications
|
||||
|
||||
public class events
|
||||
{
|
||||
public static native void do_events_tests ();
|
||||
|
||||
public static void main (String[] args)
|
||||
{
|
||||
System.out.println ("JVMTI event notification tests");
|
||||
do_events_tests ();
|
||||
}
|
||||
}
|
59
libjava/testsuite/libjava.jvmti/events.out
Normal file
59
libjava/testsuite/libjava.jvmti/events.out
Normal file
@ -0,0 +1,59 @@
|
||||
JVMTI event notification tests
|
||||
- enable tests -
|
||||
created JVMTI environment #0
|
||||
created JVMTI environment #1
|
||||
created JVMTI environment #2
|
||||
setting callbacks for envs
|
||||
RequestedEvents:
|
||||
enable VM_INIT for env0, env1, env2
|
||||
RequestedEvents: VMInit,
|
||||
enable VM_DEATH for env1,env2
|
||||
RequestedEvents: VMInit,VMDeath,
|
||||
enable THREAD_END for env2
|
||||
RequestedEvents: VMInit,VMDeath,ThreadEnd,
|
||||
disposing of env1
|
||||
RequestedEvents: VMInit,VMDeath,ThreadEnd,
|
||||
disposing of env0
|
||||
RequestedEvents: VMInit,VMDeath,ThreadEnd,
|
||||
disable VMInit in env2
|
||||
RequestedEvents: VMDeath,ThreadEnd,
|
||||
clear VMDeath callback in env2
|
||||
RequestedEvents: ThreadEnd,
|
||||
sending VMInit
|
||||
sending ThreadEnd
|
||||
ThreadEndCB jni_env=0x5678 thread=0x1234
|
||||
sending VMDeath
|
||||
disposing of env2
|
||||
RequestedEvents:
|
||||
- callback arg tests -
|
||||
RequestedEvents: VMInit,VMDeath,ThreadStart,ThreadEnd,ClassFileLoadHook,ClassLoad,ClassPrepare,VMStart,Exception,ExceptionCatch,SingleStep,FramePop,Breakpoint,FieldAccess,FieldModification,MethodEntry,MethodExit,NativeMethodBind,CompiledMethodLoad,CompiledMethodUnload,DynamicCodeGenerated,DataDumpRequest,MonitorWait,MonitorWaited,MonitorContendedEnter,MonitorContendedEntered,GarbageCollectionStart,GarbageCollectionFinish,ObjectFree,VMObjectAlloc,
|
||||
VMInitCB jni_env=0x1 thread=0x2
|
||||
VMDeathCB jni_env=0x1
|
||||
ThreadStartCB jni_env=0x1 thread=0x2
|
||||
ThreadEndCB jni_env=0x1 thread=0x2
|
||||
ClassFileLoadHookCB jni_env=0x1 class_being_redefined=0x2 loader=0x3 name=4 protection_domain=0x5 class_data_len=6 class_data=0x7 new_class_data_len=0x8 new_class_data=0x9
|
||||
ClassLoadCB jni_env=0x1 thread=0x2 klass=0x3
|
||||
ClassPrepareCB jni_env=0x1 thread=0x2 klass=0x3
|
||||
VMStartCB jni_env=0x1
|
||||
ExceptionCB jni_env=0x1 thread=0x2 method=0x3 location=0x4 exception=0x5 catch_method=0x6 catch_location=0x7
|
||||
ExceptionCatchCB jni_env=0x1 thread=0x2 method=0x3 location=0x4 exception=0x5
|
||||
SingleStepCB jni_env=0x1 thread=0x2 method=0x3 location=0x4
|
||||
FramePopCB jni_env=0x1 thread=0x2 method=0x3 was_pooped_by_exception=1
|
||||
BreakpointCB jni_env=0x1 thread=0x2 method=0x3 location=0x4
|
||||
FieldAccessCB jni_env=0x1 thread=0x2 method=0x3 location=0x4 field_klass=0x5 object=0x6 field=0x7
|
||||
FieldModificationCB jni_env=0x1 thread=0x2 method=0x3 location=0x4 field_klass=0x5 object=0x6 field=0x7 signature_type=8 new_value=9
|
||||
MethodEntryCB jni_env=0x1 thread=0x2 method=0x3
|
||||
MethodExitCB jni_env=0x1 thread=0x2 method=0x3 was_popped_by_exception=1 return_value=5
|
||||
NativeMethodBindCB jni_env=0x1 thread=0x2 method=0x3 address=0x4 new_address_ptr=0x5
|
||||
CompiledMethodLoadCB method=0x1 code_size=0x2 code_addr=0x3 map_length=4 map=0x5 compile_info=0x6
|
||||
CompiledMethodUnloadCB method=0x1 code_addr=0x2
|
||||
DynamicCodeGeneratedCB name=1 address=0x2 length=3
|
||||
DataDumpRequestCB
|
||||
MonitorWaitCB jni_env=0x1 thread=0x2 object=0x3 timeout=4
|
||||
MonitorWaitedCB jni_env=0x1 thread=0x2 object=0x3 timed_out=1
|
||||
MonitorContendedEnterCB jni_env=0x1 thread=0x2 object=0x3
|
||||
MonitorContendedEnteredCB jni_env=0x1 thread=0x2 object=0x3
|
||||
GarbageCollectionStartCB
|
||||
GarbageCollectionFinishCB
|
||||
ObjectFreeCB tag=1
|
||||
VMObjectAllocCB jni_env=0x1 thread=0x2 object=0x3 object_klass=0x4 size=5
|
544
libjava/testsuite/libjava.jvmti/natevents.cc
Normal file
544
libjava/testsuite/libjava.jvmti/natevents.cc
Normal file
@ -0,0 +1,544 @@
|
||||
#include <gcj/cni.h>
|
||||
|
||||
#include <jvm.h>
|
||||
#include <jvmti.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "jvmti-int.h"
|
||||
#include "events.h"
|
||||
|
||||
static jvmtiEnv *env = NULL;
|
||||
|
||||
void
|
||||
print_events ()
|
||||
{
|
||||
#define DO(X) \
|
||||
do \
|
||||
{ \
|
||||
if (JVMTI_REQUESTED_EVENT (X)) \
|
||||
printf (#X ","); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
printf ("RequestedEvents: ");
|
||||
DO (VMInit);
|
||||
DO (VMDeath);
|
||||
DO (ThreadStart);
|
||||
DO (ThreadEnd);
|
||||
DO (ClassFileLoadHook);
|
||||
DO (ClassLoad);
|
||||
DO (ClassPrepare);
|
||||
DO (VMStart);
|
||||
DO (Exception);
|
||||
DO (ExceptionCatch);
|
||||
DO (SingleStep);
|
||||
DO (FramePop);
|
||||
DO (Breakpoint);
|
||||
DO (FieldAccess);
|
||||
DO (FieldModification);
|
||||
DO (MethodEntry);
|
||||
DO (MethodExit);
|
||||
DO (NativeMethodBind);
|
||||
DO (CompiledMethodLoad);
|
||||
DO (CompiledMethodUnload);
|
||||
DO (DynamicCodeGenerated);
|
||||
DO (DataDumpRequest);
|
||||
DO (MonitorWait);
|
||||
DO (MonitorWaited);
|
||||
DO (MonitorContendedEnter);
|
||||
DO (MonitorContendedEntered);
|
||||
DO (GarbageCollectionStart);
|
||||
DO (GarbageCollectionFinish);
|
||||
DO (ObjectFree);
|
||||
DO (VMObjectAlloc);
|
||||
printf ("\n");
|
||||
#undef DO
|
||||
}
|
||||
|
||||
static void
|
||||
VMInitCB (jvmtiEnv *env, JNIEnv *jni_env, jthread thread)
|
||||
{
|
||||
printf ("VMInitCB jni_env=%p thread=%p\n", jni_env, thread);
|
||||
}
|
||||
|
||||
static void
|
||||
VMDeathCB (jvmtiEnv *env, JNIEnv *jni_env)
|
||||
{
|
||||
printf ("VMDeathCB jni_env=%p\n", jni_env);
|
||||
}
|
||||
|
||||
static void
|
||||
ThreadStartCB (jvmtiEnv *env, JNIEnv *jni_env, jthread thread)
|
||||
{
|
||||
printf ("ThreadStartCB jni_env=%p thread=%p\n", jni_env, thread);
|
||||
}
|
||||
|
||||
static void
|
||||
ThreadEndCB (jvmtiEnv *env, JNIEnv *jni_env, jthread thread)
|
||||
{
|
||||
printf ("ThreadEndCB jni_env=%p thread=%p\n", jni_env, thread);
|
||||
}
|
||||
|
||||
static void
|
||||
ClassFileLoadHookCB (jvmtiEnv *env, JNIEnv *jni_env,
|
||||
jclass class_being_redefined, jobject loader,
|
||||
const char *name, jobject protection_domain,
|
||||
jint class_data_len, const unsigned char *class_data,
|
||||
jint *new_class_data_len, unsigned char **new_class_data)
|
||||
{
|
||||
printf ("ClassFileLoadHookCB jni_env=%p class_being_redefined=%p loader=%p",
|
||||
jni_env, class_being_redefined, loader);
|
||||
printf (" name=%s protection_domain=%p class_data_len=%d class_data=%p",
|
||||
name, protection_domain, (int) class_data_len, class_data);
|
||||
printf (" new_class_data_len=%p new_class_data=%p\n", new_class_data_len,
|
||||
new_class_data);
|
||||
}
|
||||
|
||||
static void
|
||||
ClassLoadCB (jvmtiEnv *env, JNIEnv *jni_env, jthread thread, jclass klass)
|
||||
{
|
||||
printf ("ClassLoadCB jni_env=%p thread=%p klass=%p\n", jni_env, thread,
|
||||
klass);
|
||||
}
|
||||
|
||||
static void
|
||||
ClassPrepareCB (jvmtiEnv *env, JNIEnv *jni_env, jthread thread, jclass klass)
|
||||
{
|
||||
printf ("ClassPrepareCB jni_env=%p thread=%p klass=%p\n", jni_env,
|
||||
thread, klass);
|
||||
}
|
||||
|
||||
static void
|
||||
VMStartCB (jvmtiEnv *env, JNIEnv *jni_env)
|
||||
{
|
||||
printf ("VMStartCB jni_env=%p\n", jni_env);
|
||||
}
|
||||
|
||||
static void
|
||||
ExceptionCB (jvmtiEnv *env, JNIEnv *jni_env, jthread thread, jmethodID method,
|
||||
jlocation location, jobject exception, jmethodID catch_method,
|
||||
jlocation catch_location)
|
||||
{
|
||||
printf ("ExceptionCB jni_env=%p thread=%p method=%p location=%p", jni_env,
|
||||
thread, method, location);
|
||||
printf (" exception=%p catch_method=%p catch_location=%p\n", exception,
|
||||
catch_method, catch_location);
|
||||
}
|
||||
|
||||
static void
|
||||
ExceptionCatchCB (jvmtiEnv *env, JNIEnv *jni_env, jthread thread,
|
||||
jmethodID method, jlocation location, jobject exception)
|
||||
{
|
||||
printf ("ExceptionCatchCB jni_env=%p thread=%p method=%p location=%p",
|
||||
jni_env, thread, method, location);
|
||||
printf (" exception=%p\n", exception);
|
||||
}
|
||||
|
||||
static void
|
||||
SingleStepCB (jvmtiEnv *env, JNIEnv *jni_env, jthread thread, jmethodID method,
|
||||
jlocation location)
|
||||
{
|
||||
printf ("SingleStepCB jni_env=%p thread=%p method=%p location=%p\n",
|
||||
jni_env, thread, method, location);
|
||||
}
|
||||
|
||||
static void
|
||||
FramePopCB (jvmtiEnv *env, JNIEnv *jni_env, jthread thread, jmethodID method,
|
||||
jboolean was_popped_by_exception)
|
||||
{
|
||||
printf ("FramePopCB jni_env=%p thread=%p method=%p", jni_env, thread,
|
||||
method);
|
||||
printf (" was_pooped_by_exception=%d\n", (was_popped_by_exception ?
|
||||
1 : 0));
|
||||
}
|
||||
|
||||
static void
|
||||
BreakpointCB (jvmtiEnv *env, JNIEnv *jni_env, jthread thread, jmethodID method,
|
||||
jlocation location)
|
||||
{
|
||||
printf ("BreakpointCB jni_env=%p thread=%p method=%p location=%p\n",
|
||||
jni_env, thread, method, location);
|
||||
}
|
||||
|
||||
static void
|
||||
FieldAccessCB (jvmtiEnv *env, JNIEnv *jni_env, jthread thread,
|
||||
jmethodID method, jlocation location, jclass field_klass,
|
||||
jobject object, jfieldID field)
|
||||
{
|
||||
printf ("FieldAccessCB jni_env=%p thread=%p method=%p location=%p",
|
||||
jni_env, thread, method, location);
|
||||
printf (" field_klass=%p object=%p field=%p\n", field_klass, object, field);
|
||||
}
|
||||
|
||||
static void
|
||||
FieldModificationCB (jvmtiEnv *env, JNIEnv *jni_env, jthread thread,
|
||||
jmethodID method, jlocation location, jclass field_klass,
|
||||
jobject object, jfieldID field, char signature_type,
|
||||
jvalue new_value)
|
||||
|
||||
{
|
||||
printf ("FieldModificationCB jni_env=%p thread=%p method=%p location=%p",
|
||||
jni_env, thread, method, location);
|
||||
printf (" field_klass=%p object=%p field=%p signature_type=%c", field_klass,
|
||||
object, field, signature_type);
|
||||
printf (" new_value=%d\n", (int) new_value.i);
|
||||
}
|
||||
|
||||
static void
|
||||
MethodEntryCB (jvmtiEnv *env, JNIEnv *jni_env, jthread thread,
|
||||
jmethodID method)
|
||||
{
|
||||
printf ("MethodEntryCB jni_env=%p thread=%p method=%p\n", jni_env, thread,
|
||||
method);
|
||||
}
|
||||
|
||||
static void
|
||||
MethodExitCB (jvmtiEnv *env, JNIEnv *jni_env, jthread thread,
|
||||
jmethodID method, jboolean was_popped_by_exception,
|
||||
jvalue return_value)
|
||||
{
|
||||
printf ("MethodExitCB jni_env=%p thread=%p method=%p", jni_env, thread,
|
||||
method);
|
||||
printf (" was_popped_by_exception=%d return_value=%d\n",
|
||||
(was_popped_by_exception) ? 1 : 0, (int) return_value.i);
|
||||
}
|
||||
|
||||
static void
|
||||
NativeMethodBindCB (jvmtiEnv *env, JNIEnv *jni_env, jthread thread,
|
||||
jmethodID method, void *address, void **new_address_ptr)
|
||||
{
|
||||
printf ("NativeMethodBindCB jni_env=%p thread=%p method=%p", jni_env,
|
||||
thread, method);
|
||||
printf (" address=%p new_address_ptr=%p\n", address, new_address_ptr);
|
||||
}
|
||||
|
||||
static void
|
||||
CompiledMethodLoadCB (jvmtiEnv *env, jmethodID method, jint code_size,
|
||||
const void *code_addr, jint map_length,
|
||||
const jvmtiAddrLocationMap *map,
|
||||
const void *compile_info)
|
||||
{
|
||||
printf ("CompiledMethodLoadCB method=%p code_size=%p code_addr=%p",
|
||||
method, code_size, code_addr);
|
||||
printf (" map_length=%d map=%p compile_info=%p\n", (int) map_length, map,
|
||||
compile_info);
|
||||
}
|
||||
|
||||
static void
|
||||
CompiledMethodUnloadCB (jvmtiEnv *env, jmethodID method, const void *code_addr)
|
||||
{
|
||||
printf ("CompiledMethodUnloadCB method=%p code_addr=%p\n", method,
|
||||
code_addr);
|
||||
}
|
||||
|
||||
static void
|
||||
DynamicCodeGeneratedCB (jvmtiEnv *env, const char *name, const void *address,
|
||||
jint length)
|
||||
{
|
||||
printf ("DynamicCodeGeneratedCB name=%s address=%p length=%d\n", name,
|
||||
address, (int) length);
|
||||
}
|
||||
|
||||
static void
|
||||
DataDumpRequestCB (jvmtiEnv *env)
|
||||
{
|
||||
printf ("DataDumpRequestCB\n");
|
||||
}
|
||||
|
||||
static void
|
||||
MonitorWaitCB (jvmtiEnv *env, JNIEnv *jni_env, jthread thread, jobject object,
|
||||
jlong timeout)
|
||||
{
|
||||
printf ("MonitorWaitCB jni_env=%p thread=%p object=%p timeout=%ld\n",
|
||||
jni_env, thread, object, (long) timeout);
|
||||
}
|
||||
|
||||
static void
|
||||
MonitorWaitedCB (jvmtiEnv *env, JNIEnv *jni_env, jthread thread,
|
||||
jobject object, jboolean timed_out)
|
||||
{
|
||||
printf ("MonitorWaitedCB jni_env=%p thread=%p object=%p timed_out=%d\n",
|
||||
jni_env, thread, object, (timed_out) ? 1 : 0);
|
||||
}
|
||||
|
||||
static void
|
||||
MonitorContendedEnterCB (jvmtiEnv *env, JNIEnv *jni_env, jthread thread,
|
||||
jobject object)
|
||||
{
|
||||
printf ("MonitorContendedEnterCB jni_env=%p thread=%p object=%p\n",
|
||||
jni_env, thread, object);
|
||||
}
|
||||
|
||||
static void
|
||||
MonitorContendedEnteredCB (jvmtiEnv *env, JNIEnv *jni_env, jthread thread,
|
||||
jobject object)
|
||||
{
|
||||
printf ("MonitorContendedEnteredCB jni_env=%p thread=%p object=%p\n",
|
||||
jni_env, thread, object);
|
||||
}
|
||||
|
||||
static void
|
||||
GarbageCollectionStartCB (jvmtiEnv *env)
|
||||
{
|
||||
printf ("GarbageCollectionStartCB\n");
|
||||
}
|
||||
|
||||
static void
|
||||
GarbageCollectionFinishCB (jvmtiEnv *env)
|
||||
{
|
||||
printf ("GarbageCollectionFinishCB\n");
|
||||
}
|
||||
|
||||
static void
|
||||
ObjectFreeCB (jvmtiEnv *env, jlong tag)
|
||||
{
|
||||
printf ("ObjectFreeCB tag=%ld\n", (long) tag);
|
||||
}
|
||||
|
||||
static void
|
||||
VMObjectAllocCB (jvmtiEnv *env, JNIEnv *jni_env, jthread thread,
|
||||
jobject object, jclass object_klass, jlong size)
|
||||
{
|
||||
printf ("VMObjectAllocCB jni_env=%p thread=%p object=%p", jni_env,
|
||||
thread, object);
|
||||
printf (" object_klass=%p size=%ld\n", object_klass, (long) size);
|
||||
}
|
||||
|
||||
static void
|
||||
do_enable_tests ()
|
||||
{
|
||||
printf ("- enable tests -\n");
|
||||
JavaVM *vm = _Jv_GetJavaVM ();
|
||||
jvmtiEnv *env[3];
|
||||
int i;
|
||||
for (i = 0; i < 3; ++i)
|
||||
{
|
||||
vm->GetEnv (reinterpret_cast<void **> (&env[i]), JVMTI_VERSION_1_0);
|
||||
printf ("created JVMTI environment #%d\n", i);
|
||||
}
|
||||
|
||||
jvmtiEventCallbacks callbacks;
|
||||
memset (&callbacks, 0, sizeof (jvmtiEventCallbacks));
|
||||
|
||||
printf ("setting callbacks for envs\n");
|
||||
callbacks.VMInit = VMInitCB;
|
||||
env[0]->SetEventCallbacks (&callbacks, sizeof (callbacks));
|
||||
callbacks.VMDeath = VMDeathCB;
|
||||
env[1]->SetEventCallbacks (&callbacks, sizeof (callbacks));
|
||||
callbacks.ThreadEnd = ThreadEndCB;
|
||||
env[2]->SetEventCallbacks (&callbacks, sizeof (callbacks));
|
||||
print_events ();
|
||||
|
||||
printf ("enable VM_INIT for env0, env1, env2\n");
|
||||
env[0]->SetEventNotificationMode (JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, NULL);
|
||||
env[1]->SetEventNotificationMode (JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, NULL);
|
||||
env[2]->SetEventNotificationMode (JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, NULL);
|
||||
print_events ();
|
||||
|
||||
printf ("enable VM_DEATH for env1,env2\n");
|
||||
env[1]->SetEventNotificationMode (JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH, NULL);
|
||||
env[2]->SetEventNotificationMode (JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH, NULL);
|
||||
print_events ();
|
||||
|
||||
/* Used to use a non-NULL event thread, but that causes problems
|
||||
when SetEventNotificationMode tries to validate the thread. */
|
||||
printf ("enable THREAD_END for env2\n");
|
||||
env[2]->SetEventNotificationMode (JVMTI_ENABLE, JVMTI_EVENT_THREAD_END,
|
||||
NULL);
|
||||
print_events ();
|
||||
|
||||
printf ("disposing of env1\n");
|
||||
env[1]->DisposeEnvironment ();
|
||||
print_events ();
|
||||
|
||||
printf ("disposing of env0\n");
|
||||
env[0]->DisposeEnvironment ();
|
||||
print_events ();
|
||||
|
||||
printf ("disable VMInit in env2\n");
|
||||
env[2]->SetEventNotificationMode (JVMTI_DISABLE, JVMTI_EVENT_VM_INIT, NULL);
|
||||
print_events ();
|
||||
|
||||
printf ("clear VMDeath callback in env2\n");
|
||||
callbacks.VMDeath = NULL;
|
||||
env[2]->SetEventCallbacks (&callbacks, sizeof (callbacks));
|
||||
print_events ();
|
||||
|
||||
printf ("sending VMInit\n");
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_VM_INIT, (jthread) 0x1234,
|
||||
(JNIEnv *) 0x5678);
|
||||
|
||||
printf ("sending ThreadEnd\n");
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_THREAD_END, (jthread) 0x1234,
|
||||
(JNIEnv *) 0x5678);
|
||||
|
||||
/* See comment above re: SetEventNotificationMode and validity
|
||||
checking
|
||||
printf ("sending ThreadEnd (no match)\n");
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_THREAD_END, (jthread) 0x4321,
|
||||
(JNIEnv *) 0x5678);
|
||||
*/
|
||||
|
||||
printf ("sending VMDeath\n");
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_VM_DEATH, (jthread) NULL,
|
||||
(JNIEnv *) 0x5678);
|
||||
|
||||
printf ("disposing of env2\n");
|
||||
env[2]->DisposeEnvironment ();
|
||||
print_events ();
|
||||
}
|
||||
|
||||
static void
|
||||
do_callback_arg_tests ()
|
||||
{
|
||||
printf ("- callback arg tests -\n");
|
||||
JavaVM *vm = _Jv_GetJavaVM ();
|
||||
jvmtiEnv *env;
|
||||
vm->GetEnv (reinterpret_cast<void **> (&env), JVMTI_VERSION_1_0);
|
||||
|
||||
// Define all the callbacks
|
||||
#define DEFINE(Event) callbacks.Event = Event ## CB;
|
||||
jvmtiEventCallbacks callbacks;
|
||||
DEFINE(VMInit);
|
||||
DEFINE(VMDeath);
|
||||
DEFINE(ThreadStart);
|
||||
DEFINE(ThreadEnd);
|
||||
DEFINE(ClassFileLoadHook);
|
||||
DEFINE(ClassLoad);
|
||||
DEFINE(ClassPrepare);
|
||||
DEFINE(VMStart);
|
||||
DEFINE(Exception);
|
||||
DEFINE(ExceptionCatch);
|
||||
DEFINE(SingleStep);
|
||||
DEFINE(FramePop);
|
||||
DEFINE(Breakpoint);
|
||||
DEFINE(FieldAccess);
|
||||
DEFINE(FieldModification);
|
||||
DEFINE(MethodEntry);
|
||||
DEFINE(MethodExit);
|
||||
DEFINE(NativeMethodBind);
|
||||
DEFINE(CompiledMethodLoad);
|
||||
DEFINE(CompiledMethodUnload);
|
||||
DEFINE(DynamicCodeGenerated);
|
||||
DEFINE(DataDumpRequest);
|
||||
DEFINE(MonitorWait);
|
||||
DEFINE(MonitorWaited);
|
||||
DEFINE(MonitorContendedEnter);
|
||||
DEFINE(MonitorContendedEntered);
|
||||
DEFINE(GarbageCollectionStart);
|
||||
DEFINE(GarbageCollectionFinish);
|
||||
DEFINE(ObjectFree);
|
||||
DEFINE(VMObjectAlloc);
|
||||
#undef DEFINE
|
||||
env->SetEventCallbacks (&callbacks, sizeof (callbacks));
|
||||
|
||||
// Enable all the callbacks
|
||||
#define ENABLE(Event) \
|
||||
env->SetEventNotificationMode (JVMTI_ENABLE, JVMTI_EVENT_ ## Event, NULL)
|
||||
ENABLE (VM_INIT);
|
||||
ENABLE (VM_DEATH);
|
||||
ENABLE (THREAD_START);
|
||||
ENABLE (THREAD_END);
|
||||
ENABLE (CLASS_FILE_LOAD_HOOK);
|
||||
ENABLE (CLASS_LOAD);
|
||||
ENABLE (CLASS_PREPARE);
|
||||
ENABLE (VM_START);
|
||||
ENABLE (EXCEPTION);
|
||||
ENABLE (EXCEPTION_CATCH);
|
||||
ENABLE (SINGLE_STEP);
|
||||
ENABLE (FRAME_POP);
|
||||
ENABLE (BREAKPOINT);
|
||||
ENABLE (FIELD_ACCESS);
|
||||
ENABLE (FIELD_MODIFICATION);
|
||||
ENABLE (METHOD_ENTRY);
|
||||
ENABLE (METHOD_EXIT);
|
||||
ENABLE (NATIVE_METHOD_BIND);
|
||||
ENABLE (COMPILED_METHOD_LOAD);
|
||||
ENABLE (COMPILED_METHOD_UNLOAD);
|
||||
ENABLE (DYNAMIC_CODE_GENERATED);
|
||||
ENABLE (DATA_DUMP_REQUEST);
|
||||
ENABLE (MONITOR_WAIT);
|
||||
ENABLE (MONITOR_WAITED);
|
||||
ENABLE (MONITOR_CONTENDED_ENTER);
|
||||
ENABLE (MONITOR_CONTENDED_ENTERED);
|
||||
ENABLE (GARBAGE_COLLECTION_START);
|
||||
ENABLE (GARBAGE_COLLECTION_FINISH);
|
||||
ENABLE (OBJECT_FREE);
|
||||
ENABLE (VM_OBJECT_ALLOC);
|
||||
|
||||
// All events should now be enabled.
|
||||
print_events ();
|
||||
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_VM_INIT, (jthread) 0x2, (JNIEnv *) 0x1);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_VM_DEATH, (jthread) 0x2, (JNIEnv *) 0x1);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_THREAD_START, (jthread) 0x2,
|
||||
(JNIEnv *) 0x1);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_THREAD_END, (jthread) 0x2,
|
||||
(JNIEnv *) 0x1);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, (jthread) 0xb00,
|
||||
(JNIEnv *) 0x1, (jclass) 0x2, (jobject) 0x3,
|
||||
"4", (jobject) 0x5, (jint) 6,
|
||||
(const unsigned char *) 0x7, (jint *) 0x8,
|
||||
(unsigned char **) 0x9);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_CLASS_LOAD, (jthread) 0x2, (JNIEnv *) 0x1,
|
||||
(jclass) 0x3);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_CLASS_PREPARE, (jthread) 0x2,
|
||||
(JNIEnv *) 0x1, (jclass) 0x3);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_VM_START, (jthread) 0xb00, (JNIEnv *) 0x1);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_EXCEPTION, (jthread) 0x2, (JNIEnv *) 0x1,
|
||||
(jmethodID) 0x3, (jlocation) 0x4, (jobject) 0x5,
|
||||
(jmethodID) 0x6, (jlocation) 0x7);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_EXCEPTION_CATCH, (jthread) 0x2,
|
||||
(JNIEnv *) 0x1, (jmethodID) 0x3, (jlocation) 0x4,
|
||||
(jobject) 0x5);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_SINGLE_STEP, (jthread) 0x2, (JNIEnv *) 0x1,
|
||||
(jmethodID) 0x3, (jlocation) 0x4);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_FRAME_POP, (jthread) 0x2, (JNIEnv *) 0x1,
|
||||
(jmethodID) 0x3, 4);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_BREAKPOINT, (jthread) 0x2, (JNIEnv *) 0x1,
|
||||
(jmethodID) 0x3, (jlocation) 0x4);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_FIELD_ACCESS, (jthread) 0x2,
|
||||
(JNIEnv *) 0x1, (jmethodID) 0x3, (jlocation) 0x4,
|
||||
(jclass) 0x5, (jobject) 0x6, (jfieldID) 0x7);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_FIELD_MODIFICATION, (jthread) 0x2,
|
||||
(JNIEnv *) 0x1, (jmethodID) 0x3, (jlocation) 0x4,
|
||||
(jclass) 0x5, (jobject) 0x6, (jfieldID) 0x7,
|
||||
(int) '8', (/*jvalue*/ jobject) 0x9);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_METHOD_ENTRY, (jthread) 0x2,
|
||||
(JNIEnv *) 0x1, (jmethodID) 0x3);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_METHOD_EXIT, (jthread) 0x2,
|
||||
(JNIEnv *) 0x1, (jmethodID) 0x3, 4, /*jvalue*/ 5);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_NATIVE_METHOD_BIND, (jthread) 0x2,
|
||||
(JNIEnv *) 0x1, (jmethodID) 0x3, (void *) 0x4,
|
||||
(void **) 0x5);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_COMPILED_METHOD_LOAD, (jthread) 0xb00,
|
||||
(jmethodID) 0x1, (jint) 2, (const void *) 0x3,
|
||||
(jint) 4, (const jvmtiAddrLocationMap *) 0x5,
|
||||
(const void *) 0x6);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_COMPILED_METHOD_UNLOAD, (jthread) 0xb00,
|
||||
(jmethodID) 0x1, (const void *) 0x2);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_DYNAMIC_CODE_GENERATED, (jthread) 0xb00,
|
||||
"1", (const void *) 0x2, (jint) 3);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_DATA_DUMP_REQUEST, (jthread) 0xb00);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_MONITOR_WAIT, (jthread) 0x2,
|
||||
(JNIEnv *) 0x1, (jobject) 0x3, (jlong) 4);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_MONITOR_WAITED, (jthread) 0x2,
|
||||
(JNIEnv *) 0x1, (jobject) 0x3, (int) 4);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_MONITOR_CONTENDED_ENTER, (jthread) 0x2,
|
||||
(JNIEnv *) 0x1, (jobject) 0x3);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_MONITOR_CONTENDED_ENTERED, (jthread) 0x2,
|
||||
(JNIEnv *) 0x1, (jobject) 0x3);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_GARBAGE_COLLECTION_START, (jthread) 0xb00);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_GARBAGE_COLLECTION_FINISH, (jthread) 0xb00);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_OBJECT_FREE, (jthread) 0xb00, (jlong) 1);
|
||||
_Jv_JVMTI_PostEvent (JVMTI_EVENT_VM_OBJECT_ALLOC, (jthread) 0x2,
|
||||
(JNIEnv *) 0x1, (jobject) 0x3, (jclass) 0x4,
|
||||
(jlong) 5);
|
||||
}
|
||||
|
||||
void
|
||||
events::do_events_tests ()
|
||||
{
|
||||
do_enable_tests ();
|
||||
do_callback_arg_tests ();
|
||||
}
|
Loading…
Reference in New Issue
Block a user