mirror of git://gcc.gnu.org/git/gcc.git
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>
|
2006-09-21 Sandro Tolaini <tolaini@libero.it>
|
||||||
|
|
||||||
* configure.ac: Don't use darwin-signal.h as signal handler for
|
* configure.ac: Don't use darwin-signal.h as signal handler for
|
||||||
|
|
|
||||||
|
|
@ -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__
|
#ifndef __GCJ_JVMTI_MD_H__
|
||||||
#define __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__ */
|
#endif /* __GCJ_JVMTI_MD_H__ */
|
||||||
|
|
|
||||||
686
libjava/jvmti.cc
686
libjava/jvmti.cc
|
|
@ -15,6 +15,7 @@ details. */
|
||||||
#include <java-threads.h>
|
#include <java-threads.h>
|
||||||
#include <java-gc.h>
|
#include <java-gc.h>
|
||||||
#include <jvmti.h>
|
#include <jvmti.h>
|
||||||
|
#include "jvmti-int.h"
|
||||||
|
|
||||||
#include <gcj/method.h>
|
#include <gcj/method.h>
|
||||||
|
|
||||||
|
|
@ -32,6 +33,9 @@ details. */
|
||||||
#include <java/util/HashMap.h>
|
#include <java/util/HashMap.h>
|
||||||
#include <java/net/URL.h>
|
#include <java/net/URL.h>
|
||||||
|
|
||||||
|
static void check_enabled_events (void);
|
||||||
|
static void check_enabled_event (jvmtiEvent);
|
||||||
|
|
||||||
extern struct JNINativeInterface _Jv_JNIFunctions;
|
extern struct JNINativeInterface _Jv_JNIFunctions;
|
||||||
|
|
||||||
struct _Jv_rawMonitorID
|
struct _Jv_rawMonitorID
|
||||||
|
|
@ -519,6 +523,9 @@ _Jv_JVMTI_DisposeEnvironment (jvmtiEnv *env)
|
||||||
}
|
}
|
||||||
|
|
||||||
_Jv_Free (env);
|
_Jv_Free (env);
|
||||||
|
|
||||||
|
check_enabled_events ();
|
||||||
|
|
||||||
return JVMTI_ERROR_NONE;
|
return JVMTI_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -665,6 +672,300 @@ _Jv_JVMTI_GetObjectSize (MAYBE_UNUSED jvmtiEnv *env, jobject object,
|
||||||
return JVMTI_ERROR_NONE;
|
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
|
jvmtiError
|
||||||
_Jv_JVMTI_GetErrorName (MAYBE_UNUSED jvmtiEnv *env, jvmtiError error,
|
_Jv_JVMTI_GetErrorName (MAYBE_UNUSED jvmtiEnv *env, jvmtiError error,
|
||||||
char **name_ptr)
|
char **name_ptr)
|
||||||
|
|
@ -884,7 +1185,7 @@ _Jv_JVMTI_GetErrorName (MAYBE_UNUSED jvmtiEnv *env, jvmtiError error,
|
||||||
struct _Jv_jvmtiEnv _Jv_JVMTI_Interface =
|
struct _Jv_jvmtiEnv _Jv_JVMTI_Interface =
|
||||||
{
|
{
|
||||||
RESERVED, // reserved1
|
RESERVED, // reserved1
|
||||||
UNIMPLEMENTED, // SetEventNotification
|
_Jv_JVMTI_SetEventNotificationMode, // SetEventNotificationMode
|
||||||
RESERVED, // reserved3
|
RESERVED, // reserved3
|
||||||
UNIMPLEMENTED, // GetAllThreads
|
UNIMPLEMENTED, // GetAllThreads
|
||||||
_Jv_JVMTI_SuspendThread, // SuspendThread
|
_Jv_JVMTI_SuspendThread, // SuspendThread
|
||||||
|
|
@ -1004,7 +1305,7 @@ struct _Jv_jvmtiEnv _Jv_JVMTI_Interface =
|
||||||
RESERVED, // reserved119
|
RESERVED, // reserved119
|
||||||
_Jv_JVMTI_SetJNIFunctionTable, // SetJNIFunctionTable
|
_Jv_JVMTI_SetJNIFunctionTable, // SetJNIFunctionTable
|
||||||
_Jv_JVMTI_GetJNIFunctionTable, // GetJNIFunctionTable
|
_Jv_JVMTI_GetJNIFunctionTable, // GetJNIFunctionTable
|
||||||
UNIMPLEMENTED, // SetEventCallbacks
|
_Jv_JVMTI_SetEventCallbacks, // SetEventCallbacks
|
||||||
UNIMPLEMENTED, // GenerateEvents
|
UNIMPLEMENTED, // GenerateEvents
|
||||||
UNIMPLEMENTED, // GetExtensionFunctions
|
UNIMPLEMENTED, // GetExtensionFunctions
|
||||||
UNIMPLEMENTED, // GetExtensionEvents
|
UNIMPLEMENTED, // GetExtensionEvents
|
||||||
|
|
@ -1072,4 +1373,385 @@ _Jv_JVMTI_Init ()
|
||||||
{
|
{
|
||||||
_jvmtiEnvironments = NULL;
|
_jvmtiEnvironments = NULL;
|
||||||
_envListLock = new java::lang::Object ();
|
_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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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