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:
Keith Seitz 2006-09-22 02:12:12 +00:00 committed by Keith Seitz
parent 14c7148908
commit ebf29cf63f
7 changed files with 1429 additions and 3 deletions

View File

@ -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

View 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__ */

View File

@ -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__ */

View File

@ -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);
}

View 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 ();
}
}

View 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

View 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 ();
}