[kaffe] CVS kaffe (stack): JVMPI checkpoint

Kaffe CVS Kaffe Mailing List <kaffe@kaffe.org>
Sat Aug 30 17:00:04 2003


PatchSet 4000 
Date: 2003/08/30 23:57:08
Author: stack
Branch: HEAD
Tag: (none) 
Log:
JVMPI checkpoint

Members: 
	ChangeLog:1.1596->1.1597 
	include/jni.h:1.21->1.22 
	include/jvmpi.h:1.1->1.2 
	kaffe/jvmpi/jvmpi_kaffe.c:1.1->1.2 
	kaffe/kaffe/main.c:1.48->1.49 
	kaffe/kaffevm/classMethod.c:1.107->1.108 
	kaffe/kaffevm/exception.c:1.70->1.71 
	kaffe/kaffevm/jni.c:1.91->1.92 
	kaffe/kaffevm/kaffe.def:1.26->1.27 
	kaffe/kaffevm/soft.c:1.54->1.55 
	kaffe/kaffevm/soft.h:1.11->1.12 
	kaffe/kaffevm/jit3/codeproto.h:1.11->1.12 
	kaffe/kaffevm/jit3/icode.c:1.30->1.31 
	kaffe/kaffevm/jit3/machine.c:1.39->1.40 
	kaffe/kaffevm/jit3/machine.h:1.18->1.19 
	kaffe/kaffevm/systems/unix-jthreads/jthread.c:1.99->1.100 
	kaffe/kaffevm/systems/unix-jthreads/jthread.h:1.45->1.46 

Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.1596 kaffe/ChangeLog:1.1597
--- kaffe/ChangeLog:1.1596	Sat Aug 30 20:24:58 2003
+++ kaffe/ChangeLog	Sat Aug 30 23:57:08 2003
@@ -1,5 +1,51 @@
 2003-08-30  Timothy S. Stack <stack@cs.utah.edu>
 
+	* include/jni.h, include/jvmpi.h:
+	Change constant values to match the Sun versions so binaries are
+	compatible.
+
+	* kaffe/jvmpi/jvmpi_kaffe.c:
+	Update for change to stack trace stuff.  Add missing param in
+	jvmpiRawMonitorWait.  Implement jvmpiSuspendThread and
+	jvmpiThreadHasRun.
+
+	* kaffe/kaffe/main.c:
+	Add -Xrun command line argument.
+
+	* kaffe/kaffevm/classMethod.c:
+	Move up class load event so partially loaded classes aren't
+	missing from profiles.
+
+	* kaffe/kaffevm/exception.c:
+	Call soft_exit_method() when walking up the stack.
+
+	* kaffe/kaffevm/jni.c:
+	Add JVMPI stuff to GetEnv.  Call softcall_exit_method() when a
+	void method returns.
+
+	* kaffe/kaffevm/kaffe.def:
+	Call softcall_exit_method() when a void method returns.
+
+	* kaffe/kaffevm/soft.h, kaffe/kaffevm/soft.c:
+	Add soft_enter_method/soft_exit_method to call JVMPI stuff at
+	method entry/exit.
+
+	* kaffe/kaffevm/jit3/codeproto.h, 
+	kaffe/kaffevm/jit3/icode.c:
+	Add softcall_enter_method/softcall_exit_method to call JVMPI stuff
+	at method entry/exit.
+
+	* kaffe/kaffevm/jit3/machine.h,
+	kaffe/kaffevm/jit3/machine.c:
+	Always turn on globalMethod variable, not just when
+	--with-profiling is on...  Its also needed by JVMPI.
+
+	* kaffe/kaffevm/systems/unix-jthreads/jthread.h,
+	kaffe/kaffevm/systems/unix-jthreads/jthread.c:
+	Fix CPU usage computation.
+
+2003-08-30  Timothy S. Stack <stack@cs.utah.edu>
+
 	* libraries/clib/io/FileDescriptor.c:
 	Use '#ifdef's around O_SYNC/O_DSYNC since they are not defined on
 	FreeBSD.
Index: kaffe/include/jni.h
diff -u kaffe/include/jni.h:1.21 kaffe/include/jni.h:1.22
--- kaffe/include/jni.h:1.21	Thu Jul 31 22:46:43 2003
+++ kaffe/include/jni.h	Sat Aug 30 23:57:09 2003
@@ -582,9 +582,8 @@
 
 #define JNI_VERSION_1_1		0x00010001
 #define JNI_VERSION_1_2		0x00010002
-#define JVMPI_VERSION_1 	0x10010000
-#define JVMPI_VERSION_1_1	0x10010001
-#define JVMPI_VERSION_1_2	0x10010002
+#define JVMPI_VERSION_1 	0x10000001
+#define JVMPI_VERSION_1_1	0x10000002
 
 #if defined(__cplusplus)
 }
Index: kaffe/include/jvmpi.h
diff -u kaffe/include/jvmpi.h:1.1 kaffe/include/jvmpi.h:1.2
--- kaffe/include/jvmpi.h:1.1	Sat Jul 26 16:50:47 2003
+++ kaffe/include/jvmpi.h	Sat Aug 30 23:57:09 2003
@@ -7,63 +7,81 @@
 #define _KAFFE_JVMPI_H
 
 enum {
+	JVMPI_FAIL = -1,
 	JVMPI_SUCCESS,
-	JVMPI_FAIL,
 	JVMPI_NOT_AVAILABLE,
+};
 
-	JVMPI_THREAD_RUNNABLE,
+enum {
+	JVMPI_THREAD_RUNNABLE = 1,
 	JVMPI_THREAD_MONITOR_WAIT,
 	JVMPI_THREAD_CONDVAR_WAIT,
+};
 
-	JVMPI_THREAD_SUSPENDED = 0x40000000,
-	JVMPI_THREAD_INTERRUPTED = 0x80000000,
+enum {
+	JVMPI_THREAD_INTERRUPTED = 0x4000,
+	JVMPI_THREAD_SUSPENDED = 0x8000,
 };
 
 enum {
-	JVMPI_NORMAL_PRIORITY,
-	JVMPI_MAXIMUM_PRIORITY,
-	JVMPI_MINIMUM_PRIORITY,
+	JVMPI_MINIMUM_PRIORITY = 1,
+	JVMPI_NORMAL_PRIORITY = 5,
+	JVMPI_MAXIMUM_PRIORITY = 10,
 };
 
 enum {
-	JVMPI_EVENT_ARENA_DELETE,
-	JVMPI_EVENT_ARENA_NEW,
-	JVMPI_EVENT_CLASS_LOAD,
-	JVMPI_EVENT_CLASS_LOAD_HOOK,
-	JVMPI_EVENT_CLASS_UNLOAD,
-	JVMPI_EVENT_COMPILED_METHOD_LOAD,
+	JVMPI_EVENT_METHOD_ENTRY = 1,
+	JVMPI_EVENT_METHOD_ENTRY2,
+	JVMPI_EVENT_METHOD_EXIT,
+	
+	JVMPI_EVENT_OBJECT_ALLOC = 4,
+	JVMPI_EVENT_OBJECT_FREE,
+	JVMPI_EVENT_OBJECT_MOVE,
+	
+	JVMPI_EVENT_COMPILED_METHOD_LOAD = 7,
 	JVMPI_EVENT_COMPILED_METHOD_UNLOAD,
-	JVMPI_EVENT_DATA_DUMP_REQUEST,
-	JVMPI_EVENT_DATA_RESET_REQUEST,
-	JVMPI_EVENT_GC_FINISH,
-	JVMPI_EVENT_GC_START,
-	JVMPI_EVENT_HEAP_DUMP,
-	JVMPI_EVENT_JNI_GLOBALREF_ALLOC,
+	
+	JVMPI_EVENT_INSTRUCTION_START = 9,
+	
+	JVMPI_EVENT_THREAD_START = 33,
+	JVMPI_EVENT_THREAD_END,
+	
+	JVMPI_EVENT_CLASS_LOAD_HOOK = 35,
+	
+	JVMPI_EVENT_HEAP_DUMP = 37,
+	
+	JVMPI_EVENT_JNI_GLOBALREF_ALLOC = 38,
 	JVMPI_EVENT_JNI_GLOBALREF_FREE,
 	JVMPI_EVENT_JNI_WEAK_GLOBALREF_ALLOC,
 	JVMPI_EVENT_JNI_WEAK_GLOBALREF_FREE,
-	JVMPI_EVENT_JVM_INIT_DONE,
+	
+	JVMPI_EVENT_CLASS_LOAD = 42,
+	JVMPI_EVENT_CLASS_UNLOAD,
+	
+	JVMPI_EVENT_DATA_DUMP_REQUEST = 44,
+	JVMPI_EVENT_DATA_RESET_REQUEST,
+	
+	JVMPI_EVENT_JVM_INIT_DONE = 46,
 	JVMPI_EVENT_JVM_SHUT_DOWN,
-	JVMPI_EVENT_METHOD_ENTRY,
-	JVMPI_EVENT_METHOD_ENTRY2,
-	JVMPI_EVENT_METHOD_EXIT,
+	
+	JVMPI_EVENT_ARENA_NEW = 48,
+	JVMPI_EVENT_ARENA_DELETE,
+	
+	JVMPI_EVENT_OBJECT_DUMP = 50,
+	
+	JVMPI_EVENT_RAW_MONITOR_CONTENDED_ENTER = 51,
+	JVMPI_EVENT_RAW_MONITOR_CONTENDED_ENTERED,
+	JVMPI_EVENT_RAW_MONITOR_CONTENDED_EXIT,
 	JVMPI_EVENT_MONITOR_CONTENDED_ENTER,
 	JVMPI_EVENT_MONITOR_CONTENDED_ENTERED,
 	JVMPI_EVENT_MONITOR_CONTENDED_EXIT,
-	JVMPI_EVENT_MONITOR_DUMP,
 	JVMPI_EVENT_MONITOR_WAIT,
 	JVMPI_EVENT_MONITOR_WAITED,
-	JVMPI_EVENT_OBJECT_ALLOC,
-	JVMPI_EVENT_OBJECT_DUMP,
-	JVMPI_EVENT_OBJECT_FREE,
-	JVMPI_EVENT_OBJECT_MOVE,
-	JVMPI_EVENT_RAW_MONITOR_CONTENDED_ENTER,
-	JVMPI_EVENT_RAW_MONITOR_CONTENDED_ENTERED,
-	JVMPI_EVENT_RAW_MONITOR_CONTENDED_EXIT,
-	JVMPI_EVENT_THREAD_END,
-	JVMPI_EVENT_THREAD_START,
-	JVMPI_EVENT_INSTRUCTION_START,
-
+	JVMPI_EVENT_MONITOR_DUMP,
+	
+	JVMPI_EVENT_GC_START = 60,
+	JVMPI_EVENT_GC_FINISH,
+	
 	JVMPI_EVENT_COUNT
 };
 
@@ -74,35 +92,38 @@
 };
 
 enum {
-	JVMPI_NORMAL_OBJECT,
-	JVMPI_CLASS,
-	JVMPI_BOOLEAN,
-	JVMPI_BYTE,
-	JVMPI_CHAR,
-	JVMPI_SHORT,
-	JVMPI_INT,
-	JVMPI_LONG,
-	JVMPI_FLOAT,
-	JVMPI_DOUBLE,
+	JVMPI_NORMAL_OBJECT = 0,
+	JVMPI_CLASS = 2,
+	JVMPI_BOOLEAN = 4,
+	JVMPI_CHAR = 5,
+	JVMPI_FLOAT = 6,
+	JVMPI_DOUBLE = 7,
+	JVMPI_BYTE = 8,
+	JVMPI_SHORT = 9,
+	JVMPI_INT = 10,
+	JVMPI_LONG = 11,
 };
 
 enum {
-	JVMPI_GC_ROOT_UNKNOWN,
-	JVMPI_GC_ROOT_JNI_GLOBAL,
+	JVMPI_GC_ROOT_JNI_GLOBAL = 1,
 	JVMPI_GC_ROOT_JNI_LOCAL,
 	JVMPI_GC_ROOT_JAVA_FRAME,
 	JVMPI_GC_ROOT_NATIVE_STACK,
 	JVMPI_GC_ROOT_STICKY_CLASS,
 	JVMPI_GC_ROOT_THREAD_BLOCK,
 	JVMPI_GC_ROOT_MONITOR_USED,
-	JVMPI_GC_CLASS_DUMP,
+	JVMPI_GC_ROOT_THREAD_OBJ,
+	
+	JVMPI_GC_CLASS_DUMP = 0x20,
 	JVMPI_GC_INSTANCE_DUMP,
 	JVMPI_GC_OBJ_ARRAY_DUMP,
 	JVMPI_GC_PRIM_ARRAY_DUMP,
+	
+	JVMPI_GC_ROOT_UNKNOWN = 0xff,
 };
 
 enum {
-	JVMPI_MONITOR_JAVA,
+	JVMPI_MONITOR_JAVA = 1,
 	JVMPI_MONITOR_RAW,
 };
 
@@ -118,8 +139,8 @@
 } JVMPI_CallTrace;
 
 typedef struct {
-	char *field_name;
-	char *field_signature;
+	const char *field_name;
+	const char *field_signature;
 } JVMPI_Field;
 
 typedef struct {
@@ -132,8 +153,8 @@
 } JVMPI_Lineno;
 
 typedef struct {
-	char *method_name;
-	char *method_signature;
+	const char *method_name;
+	const char *method_signature;
 	jint start_lineno;
 	jint end_lineno;
 	jmethodID method_id;
@@ -164,7 +185,7 @@
 		} class_load_hook;
 
 		struct {
-			char *class_name;
+			const char *class_name;
 			char *source_name;
 			jint num_interfaces;
 			jint num_methods;
Index: kaffe/kaffe/jvmpi/jvmpi_kaffe.c
diff -u kaffe/kaffe/jvmpi/jvmpi_kaffe.c:1.1 kaffe/kaffe/jvmpi/jvmpi_kaffe.c:1.2
--- kaffe/kaffe/jvmpi/jvmpi_kaffe.c:1.1	Sat Jul 26 16:50:47 2003
+++ kaffe/kaffe/jvmpi/jvmpi_kaffe.c	Sat Aug 30 23:57:10 2003
@@ -177,7 +177,7 @@
 
 static jint jvmpiEnableEvent(jint event_type, void *arg)
 {
-	jint retval;
+	jint retval = JVMPI_NOT_AVAILABLE;
 	
 	switch( event_type )
 	{
@@ -187,8 +187,13 @@
 		retval = JVMPI_NOT_AVAILABLE;
 		break;
 	default:
-		BITMAP_SET(jvmpi_data.jk_EventMask, event_type);
-		retval = JVMPI_SUCCESS;
+		{
+			BITMAP_SET(jvmpi_data.jk_EventMask, event_type);
+			retval = JVMPI_SUCCESS;
+
+			assert(BITMAP_ISSET(jvmpi_data.jk_EventMask,
+					    event_type));
+		}
 		break;
 	}
 	return( retval );
@@ -230,7 +235,7 @@
 			JVMPI_CallFrame *cf;
 			Method *meth;
 
-			if( (meth = stacktraceFindMethod(&sti[lpc])) == NULL )
+			if( (meth = sti[lpc].meth) == NULL )
 				continue;
 			
 			cf = &trace->frames[trace->num_frames];
@@ -408,11 +413,11 @@
 	jcondvar_broadcast(&lock_id->cv, &lock_id->mux);
 }
 
-static void jvmpiRawMonitorWait(JVMPI_RawMonitor lock_id)
+static void jvmpiRawMonitorWait(JVMPI_RawMonitor lock_id, jlong ms)
 {
 	assert(lock_id != NULL);
 	
-	jcondvar_wait(&lock_id->cv, &lock_id->mux, 0);
+	jcondvar_wait(&lock_id->cv, &lock_id->mux, ms);
 }
 
 static jint jvmpiRequestEvent(jint event_type, void *arg)
@@ -468,7 +473,10 @@
 
 static void jvmpiSuspendThread(JNIEnv *env_id)
 {
-	jthread_from_data((threadData *)env_id, &jvmpi_data);
+	jthread_t jt;
+
+	jt = jthread_from_data((threadData *)env_id, &jvmpi_data);
+	jthread_clear_run(jt);
 }
 
 static void jvmpiSuspendThreadList(jint reqCount, JNIEnv **reqList, jint *results)
@@ -489,9 +497,14 @@
 
 static jboolean jvmpiThreadHasRun(JNIEnv *env)
 {
-	jboolean retval = JNI_TRUE;
+	jboolean retval = JNI_FALSE;
+	jthread_t jt;
 
-	/* XXX */
+	if( (jt = jthread_from_data((threadData *)env, &jvmpi_data)) != NULL )
+	{
+		retval = jthread_has_run(jt);
+		jthread_resume(jt, &jvmpi_data);
+	}
 	return( retval );
 }
 
@@ -508,7 +521,7 @@
 jvmpi_kaffe_t jvmpi_data = {
 	{ 0 },
 	{
-		JVMPI_VERSION_1_2,
+		JVMPI_VERSION_1_1,
 		
 		NULL,
 		
Index: kaffe/kaffe/kaffe/main.c
diff -u kaffe/kaffe/kaffe/main.c:1.48 kaffe/kaffe/kaffe/main.c:1.49
--- kaffe/kaffe/kaffe/main.c:1.48	Fri Aug 29 21:57:11 2003
+++ kaffe/kaffe/kaffe/main.c	Sat Aug 30 23:57:10 2003
@@ -33,6 +33,7 @@
 #include "fileSections.h"
 #include "feedback.h"
 #include "methodCache.h"
+#include "external.h"
 
 #if defined(KAFFE_PROFILER)
 extern int profFlag;
@@ -47,6 +48,7 @@
 JNIEnv* env;
 JavaVM* vm;
 static int isJar = 0;
+static char *jvm_onload;
 
 static int options(char**);
 static void usage(void);
@@ -147,6 +149,46 @@
 	/* Initialise */
 	JNI_CreateJavaVM(&vm, &env, &vmargs);
 
+	/* Handle the '-Xrun' argument. */
+	if( jvm_onload != NULL )
+	{
+		char *libpath, *libargs;
+		char errbuf[512];
+		int index;
+
+		/* XXX Pull findLibrary() from the JanosVM. */
+		libpath = &jvm_onload[2];
+		libpath[0] = 'l';
+		libpath[1] = 'i';
+		libpath[2] = 'b';
+
+		if( (libargs = strchr(jvm_onload, ':')) != NULL )
+		{
+			*libargs = '\0';
+			libargs += 1;
+		}
+		
+		index = loadNativeLibrary(libpath, errbuf, sizeof(errbuf));
+		if( index > 0 )
+		{
+			jint (*onload_func)(JavaVM *jvm, char *, void *);
+
+			if( (onload_func =
+			     loadNativeLibrarySym("JVM_OnLoad")) != NULL )
+			{
+				(void)onload_func(vm, libargs, NULL);
+			}
+		}
+		else
+		{
+			fprintf(stderr,
+				"Unable to load %s: %s\n",
+				libpath,
+				errbuf);
+			exit(1);
+		}
+	}
+
 	return (main2(env, argv, farg, argc));
 }
 
@@ -506,6 +548,9 @@
                 else if (strcmp(argv[i], "-jar") == 0) {
                         isJar = 1;
                 }
+		else if (strncmp(argv[i], "-Xrun", 5) == 0) {
+			jvm_onload = argv[i];
+		}
 #if defined(KAFFE_PROFILER)
 		else if (strcmp(argv[i], "-prof") == 0) {
 			profFlag = 1;
Index: kaffe/kaffe/kaffevm/classMethod.c
diff -u kaffe/kaffe/kaffevm/classMethod.c:1.107 kaffe/kaffe/kaffevm/classMethod.c:1.108
--- kaffe/kaffe/kaffevm/classMethod.c:1.107	Thu Aug  7 21:05:27 2003
+++ kaffe/kaffe/kaffevm/classMethod.c	Sat Aug 30 23:57:11 2003
@@ -324,6 +324,53 @@
 		SET_CLASS_STATE(CSTATE_PREPARED);
 		
 		setClassMappingState(ce, NMS_DONE);
+		
+#if defined(ENABLE_JVMPI)
+		if( JVMPI_EVENT_ISENABLED(JVMPI_EVENT_CLASS_LOAD) )
+		{
+			JVMPI_Method *jvmpi_methods;
+			JVMPI_Field *jvmpi_fields;
+			JVMPI_Event ev;
+			int lpc;
+			
+			jvmpi_methods = alloca(sizeof(JVMPI_Method) *
+					       class->nmethods);
+			for( lpc = 0; lpc < class->nmethods; lpc++ )
+			{
+				jvmpiConvertMethod(&jvmpi_methods[lpc],
+						   &class->methods[lpc]);
+			}
+			jvmpi_fields = alloca(sizeof(JVMPI_Field) *
+					      (class->nsfields +
+					       class->nfields));
+			for( lpc = 0;
+			     lpc < (class->nsfields + class->nfields);
+			     lpc++ )
+			{
+				jvmpiConvertField(&jvmpi_fields[lpc],
+						  &class->fields[lpc]);
+			}
+			ev.event_type = JVMPI_EVENT_CLASS_LOAD;
+			ev.u.class_load.class_name =
+				class->name->data;
+			ev.u.class_load.source_name =
+				class->sourcefile;
+			ev.u.class_load.num_interfaces =
+				class->interface_len;
+			ev.u.class_load.num_methods =
+				class->nmethods;
+			ev.u.class_load.methods = jvmpi_methods;
+			ev.u.class_load.num_static_fields =
+				class->nsfields;
+			ev.u.class_load.statics = &jvmpi_fields[0];
+			ev.u.class_load.num_instance_fields =
+				class->nfields;
+			ev.u.class_load.instances =
+				&jvmpi_fields[class->nsfields];
+			ev.u.class_load.class_id = class;
+			jvmpiPostEvent(&ev);
+		}
+#endif
 	}
 
 	assert((class == ObjectClass) || (class->superclass != NULL));
@@ -565,55 +612,6 @@
 			SET_CLASS_STATE(CSTATE_FAILED);
 		} else {
 			SET_CLASS_STATE(CSTATE_COMPLETE);
-
-#if defined(ENABLE_JVMPI)
-			if( JVMPI_EVENT_ISENABLED(JVMPI_EVENT_CLASS_LOAD) )
-			{
-				JVMPI_Method *jvmpi_methods;
-				JVMPI_Field *jvmpi_fields;
-				JVMPI_Event ev;
-				int lpc;
-
-				jvmpi_methods = alloca(sizeof(JVMPI_Method) *
-						       class->nmethods);
-				for( lpc = 0; lpc < class->nmethods; lpc++ )
-				{
-					jvmpiConvertMethod(
-						&jvmpi_methods[lpc],
-						&class->methods[lpc]);
-				}
-				jvmpi_fields = alloca(sizeof(JVMPI_Field) *
-						      (class->nsfields +
-						       class->nfields));
-				for( lpc = 0;
-				     lpc < (class->nsfields + class->nfields);
-				     lpc++ )
-				{
-					jvmpiConvertField(
-						&jvmpi_fields[lpc],
-						&class->fields[lpc]);
-				}
-				ev.event_type = JVMPI_EVENT_CLASS_LOAD;
-				ev.u.class_load.class_name =
-					class->name->data;
-				ev.u.class_load.source_name =
-					class->sourcefile;
-				ev.u.class_load.num_interfaces =
-					class->interface_len;
-				ev.u.class_load.num_methods =
-					class->nmethods;
-				ev.u.class_load.methods = jvmpi_methods;
-				ev.u.class_load.num_static_fields =
-					class->nsfields;
-				ev.u.class_load.statics = &jvmpi_fields[0];
-				ev.u.class_load.num_instance_fields =
-					class->nfields;
-				ev.u.class_load.instances =
-					&jvmpi_fields[class->nsfields];
-				ev.u.class_load.class_id = class;
-				jvmpiPostEvent(&ev);
-			}
-#endif
 		}
 
 		/* Since we'll never run this again we might as well
Index: kaffe/kaffe/kaffevm/exception.c
diff -u kaffe/kaffe/kaffevm/exception.c:1.70 kaffe/kaffe/kaffevm/exception.c:1.71
--- kaffe/kaffe/kaffevm/exception.c:1.70	Tue Aug  5 15:06:37 2003
+++ kaffe/kaffe/kaffevm/exception.c	Sat Aug 30 23:57:11 2003
@@ -375,6 +375,10 @@
 			DISPATCH_EXCEPTION(frame->fp, handler, eobj); /* doesn't return */
 		}
 
+#if defined(ENABLE_JVMPI)
+		soft_exit_method(frame->meth);
+#endif
+
 		/* If not here, exit monitor if synchronised. */
 		if (frame->meth->accflags & ACC_SYNCHRONISED) {
 			locks_internal_slowUnlockMutexIfHeld(&obj->lock, (void *)frame->fp, 0);
Index: kaffe/kaffe/kaffevm/jni.c
diff -u kaffe/kaffe/kaffevm/jni.c:1.91 kaffe/kaffe/kaffevm/jni.c:1.92
--- kaffe/kaffe/kaffevm/jni.c:1.91	Wed Aug 27 20:07:25 2003
+++ kaffe/kaffe/kaffevm/jni.c	Sat Aug 30 23:57:11 2003
@@ -3624,6 +3624,14 @@
 		(*penv) = (JVMDI_Interface_1*)&Kaffe_JVMDIEnv;
 		return (JNI_OK);
 #endif
+
+#if defined(ENABLE_JVMPI)
+	case JVMPI_VERSION_1:
+	case JVMPI_VERSION_1_1:
+		(*penv) = jvmpiCreateInterface(interface_id);
+		return (JNI_OK);
+#endif
+		
 	default:
 		return (JNI_EVERSION);
 	}
@@ -3703,9 +3711,9 @@
 		xmeth->callsCount = 0;
 		xmeth->totalClicks = 0;
 		xmeth->totalChildrenClicks = 0;
-		globalMethod = xmeth;
 	}
 #endif
+	globalMethod = xmeth;
 
 	maxArgs = maxLocal = count; /* make sure args are spilled if needed */
 	maxStack = 0;
@@ -3981,6 +3989,10 @@
 		}
 		if (use_JNI)
 			call_soft(finishJNIcall);
+#if defined(ENABLE_JVMPI)
+		softcall_exit_method(globalMethod);
+#endif
+		ret();
 		break;
 	}
 
@@ -4012,9 +4024,9 @@
 
 		profiler_get_clicks(end);
 		xmeth->jitClicks = end - xmeth->jitClicks;
-		globalMethod = 0;
 	}
 #endif
+	globalMethod = 0;
 
 	leaveTranslator();
 #if defined(KAFFE_FEEDBACK)
Index: kaffe/kaffe/kaffevm/kaffe.def
diff -u kaffe/kaffe/kaffevm/kaffe.def:1.26 kaffe/kaffe/kaffevm/kaffe.def:1.27
--- kaffe/kaffe/kaffevm/kaffe.def:1.26	Sat Jul 26 16:50:49 2003
+++ kaffe/kaffe/kaffevm/kaffe.def	Sat Aug 30 23:57:11 2003
@@ -2168,6 +2168,9 @@
 	trace_jcode (("return\n"));
 
 	monitor_exit();
+#if defined(ENABLE_JVMPI)
+	softcall_exit_method(globalMethod);
+#endif
 	ret();
 }
 
Index: kaffe/kaffe/kaffevm/soft.c
diff -u kaffe/kaffe/kaffevm/soft.c:1.54 kaffe/kaffe/kaffevm/soft.c:1.55
--- kaffe/kaffe/kaffevm/soft.c:1.54	Sun Jul 27 16:53:46 2003
+++ kaffe/kaffe/kaffevm/soft.c	Sat Aug 30 23:57:11 2003
@@ -36,6 +36,7 @@
 #include "itypes.h"
 #include "machine.h"
 #include "fp.h"
+#include "jvmpi_kaffe.h"
 
 /*
  * soft_new
@@ -1096,4 +1097,43 @@
 soft_trace(Method* meth, void* args)
 {
     dprintf("soft_trace: %s.%s%s\n", CLASS_CNAME(meth->class), meth->name->data, METHOD_SIGD(meth));
+}
+
+void
+soft_enter_method(Hjava_lang_Object *obj, Method *meth)
+{
+#if defined(ENABLE_JVMPI)
+	if( JVMPI_EVENT_ISENABLED(JVMPI_EVENT_METHOD_ENTRY) )
+	{
+		JVMPI_Event ev;
+
+		ev.event_type = JVMPI_EVENT_METHOD_ENTRY;
+		ev.u.method.method_id = meth;
+		jvmpiPostEvent(&ev);
+	}
+	if( JVMPI_EVENT_ISENABLED(JVMPI_EVENT_METHOD_ENTRY2) )
+	{
+		JVMPI_Event ev;
+
+		ev.event_type = JVMPI_EVENT_METHOD_ENTRY2;
+		ev.u.method_entry2.method_id = meth;
+		ev.u.method_entry2.obj_id = obj;
+		jvmpiPostEvent(&ev);
+	}
+#endif
+}
+
+void
+soft_exit_method(Method *meth)
+{
+#if defined(ENABLE_JVMPI)
+	if( JVMPI_EVENT_ISENABLED(JVMPI_EVENT_METHOD_EXIT) )
+	{
+		JVMPI_Event ev;
+
+		ev.event_type = JVMPI_EVENT_METHOD_EXIT;
+		ev.u.method.method_id = meth;
+		jvmpiPostEvent(&ev);
+	}
+#endif
 }
Index: kaffe/kaffe/kaffevm/soft.h
diff -u kaffe/kaffe/kaffevm/soft.h:1.11 kaffe/kaffe/kaffevm/soft.h:1.12
--- kaffe/kaffe/kaffevm/soft.h:1.11	Mon Aug 11 14:50:07 2003
+++ kaffe/kaffe/kaffevm/soft.h	Sat Aug 30 23:57:11 2003
@@ -94,5 +94,7 @@
 void	soft_debug1(void*, void*, void*);
 void	soft_debug2(void*, void*, void*);
 void	soft_trace(Method*, void*);
+void	soft_enter_method(struct Hjava_lang_Object *obj, Method *meth);
+void	soft_exit_method(Method *meth);
 
 #endif
Index: kaffe/kaffe/kaffevm/jit3/codeproto.h
diff -u kaffe/kaffe/kaffevm/jit3/codeproto.h:1.11 kaffe/kaffe/kaffevm/jit3/codeproto.h:1.12
--- kaffe/kaffe/kaffevm/jit3/codeproto.h:1.11	Sat Jul 26 16:50:51 2003
+++ kaffe/kaffe/kaffevm/jit3/codeproto.h	Sat Aug 30 23:57:11 2003
@@ -298,6 +298,8 @@
 void softcall_newarray_const(SlotInfo*, int, int);
 void softcall_anewarray_const(SlotInfo*, int, struct Hjava_lang_Class*);
 void softcall_trace(Method*);
+void softcall_enter_method(SlotInfo*, Method*);
+void softcall_exit_method(Method*);
 
 void build_call_frame(Utf8Const*, SlotInfo*, int);
 void load_globals(bool);
Index: kaffe/kaffe/kaffevm/jit3/icode.c
diff -u kaffe/kaffe/kaffevm/jit3/icode.c:1.30 kaffe/kaffe/kaffevm/jit3/icode.c:1.31
--- kaffe/kaffe/kaffevm/jit3/icode.c:1.30	Sat Jul 26 16:50:51 2003
+++ kaffe/kaffe/kaffevm/jit3/icode.c	Sat Aug 30 23:57:11 2003
@@ -228,6 +228,20 @@
 	/* Emit prologue code */
 	slot_const_const(0, (jword)l, (jword)meth, HAVE_prologue, Tnull);
         slot_const_const(0, (jword)createSpillMask(), SR_START, doReload, Tnull);
+	
+#if defined(ENABLE_JVMPI)
+	{
+		SlotInfo *tmp;
+
+		slot_alloctmp(tmp);
+		if( METHOD_IS_STATIC(meth) )
+			move_ref_const(tmp, NULL);
+		else
+			move_ref(tmp, local(0));
+		softcall_enter_method(tmp, meth);
+		slot_freetmp(tmp);
+	}
+#endif
 }
 
 void
@@ -280,7 +294,7 @@
 epilogue(Method* meth)
 {
 	label* l;
-
+	
 	l = newLabel();
 	l->type = Lnull;	/* Lnegframe|Labsolute|Lgeneral */
 	l->at = 0;
@@ -3769,6 +3783,10 @@
 void
 returnarg_int(SlotInfo* src)
 {
+#if defined(ENABLE_JVMPI)
+	softcall_exit_method(globalMethod);
+#endif
+
 	slot_slot_slot(0, 0, src, HAVE_returnarg_int, Tcopy);
 }
 #endif
@@ -3777,6 +3795,10 @@
 void
 returnarg_ref(SlotInfo* src)
 {
+#if defined(ENABLE_JVMPI)
+	softcall_exit_method(globalMethod);
+#endif
+
 	slot_slot_slot(0, 0, src, HAVE_returnarg_ref, Tcopy);
 }
 #endif
@@ -3785,6 +3807,10 @@
 void
 returnarg_long(SlotInfo* src)
 {
+#if defined(ENABLE_JVMPI)
+	softcall_exit_method(globalMethod);
+#endif
+
 	lslot_lslot_lslot(0, 0, src, HAVE_returnarg_long, Tcopy);
 }
 #endif
@@ -3792,6 +3818,10 @@
 void
 returnarg_float(SlotInfo* src)
 {
+#if defined(ENABLE_JVMPI)
+	softcall_exit_method(globalMethod);
+#endif
+
 #if defined(HAVE_returnarg_float)
 	slot_slot_slot(0, 0, src, HAVE_returnarg_float, Tcopy);
 #elif defined(HAVE_NO_FLOATING_POINT)
@@ -3804,6 +3834,10 @@
 void
 returnarg_double(SlotInfo* src)
 {
+#if defined(ENABLE_JVMPI)
+	softcall_exit_method(globalMethod);
+#endif
+
 #if defined(HAVE_returnarg_double)
 	lslot_lslot_lslot(0, 0, src, HAVE_returnarg_double, Tcopy);
 #elif defined(HAVE_NO_FLOATING_POINT)
@@ -5063,6 +5097,36 @@
 	popargs();
 	end_func_sync();
 #endif
+}
+
+void
+softcall_enter_method(SlotInfo *obj, Method* meth)
+{
+	begin_func_sync();
+#if defined(PUSHARG_FORWARDS)
+	pusharg_ref(obj, 0);
+        pusharg_ref_const(meth, 1);
+#else
+        pusharg_ref_const(meth, 1);
+	pusharg_ref(obj, 0);
+#endif
+	call_soft(soft_enter_method);
+	popargs();
+	end_func_sync();
+}
+
+void
+softcall_exit_method(Method* meth)
+{
+	begin_func_sync();
+#if defined(PUSHARG_FORWARDS)
+	pusharg_ref_const(meth, 0);
+#else
+	pusharg_ref_const(meth, 0);
+#endif
+	call_soft(soft_exit_method);
+	popargs();
+	end_func_sync();
 }
 
 #if defined(GC_INCREMENTAL)
Index: kaffe/kaffe/kaffevm/jit3/machine.c
diff -u kaffe/kaffe/kaffevm/jit3/machine.c:1.39 kaffe/kaffe/kaffevm/jit3/machine.c:1.40
--- kaffe/kaffe/kaffevm/jit3/machine.c:1.39	Sun Jul 27 16:53:48 2003
+++ kaffe/kaffe/kaffevm/jit3/machine.c	Sat Aug 30 23:57:12 2003
@@ -206,9 +206,9 @@
 		xmeth->callsCount = 0;
 		xmeth->totalClicks = 0;
 		xmeth->totalChildrenClicks = 0;
-		globalMethod = xmeth;
 	}
 #endif
+	globalMethod = xmeth;
 
 	codeInfo = mycodeInfo;
 
@@ -384,9 +384,9 @@
 
 		profiler_get_clicks(end);
 		xmeth->jitClicks = end - xmeth->jitClicks;
-		globalMethod = 0;
 	}
 #endif
+	globalMethod = 0;
 
 DBG(MOREJIT,
     dprintf("Translating %s.%s%s (%s) %p\n",
Index: kaffe/kaffe/kaffevm/jit3/machine.h
diff -u kaffe/kaffe/kaffevm/jit3/machine.h:1.18 kaffe/kaffe/kaffevm/jit3/machine.h:1.19
--- kaffe/kaffe/kaffevm/jit3/machine.h:1.18	Tue Jul  8 07:33:49 2003
+++ kaffe/kaffe/kaffevm/jit3/machine.h	Sat Aug 30 23:57:12 2003
@@ -140,10 +140,8 @@
 
 extern jitflags willcatch;
 extern struct codeinfo* codeInfo;
-#if defined(KAFFE_PROFILER)
 extern int profFlag;
 extern Method* globalMethod;
-#endif
 
 /**
  * Encapsulate information about the native code of a method.
Index: kaffe/kaffe/kaffevm/systems/unix-jthreads/jthread.c
diff -u kaffe/kaffe/kaffevm/systems/unix-jthreads/jthread.c:1.99 kaffe/kaffe/kaffevm/systems/unix-jthreads/jthread.c:1.100
--- kaffe/kaffe/kaffevm/systems/unix-jthreads/jthread.c:1.99	Mon Aug 25 07:48:26 2003
+++ kaffe/kaffe/kaffevm/systems/unix-jthreads/jthread.c	Sat Aug 30 23:57:12 2003
@@ -1841,13 +1841,12 @@
 					jlong ct;
 
 					getrusage(RUSAGE_SELF, &ru);
-					ct = ((jlong)ru.ru_utime.tv_sec * 1000)
-						+ ((jlong)ru.ru_utime.tv_usec /
-						   (jlong)1000);
+					ct = ((jlong)ru.ru_utime.tv_sec *
+					      1000000)
+						+ ((jlong)ru.ru_utime.tv_usec);
 					ct += ((jlong)ru.ru_stime.tv_sec *
-					       1000)
-						+ ((jlong)ru.ru_stime.tv_usec /
-						   (jlong)1000);
+					       1000000)
+						+ ((jlong)ru.ru_stime.tv_usec);
 
 					lastThread->totalUsed +=
 						(ct - lastThread->startUsed);
Index: kaffe/kaffe/kaffevm/systems/unix-jthreads/jthread.h
diff -u kaffe/kaffe/kaffevm/systems/unix-jthreads/jthread.h:1.45 kaffe/kaffe/kaffevm/systems/unix-jthreads/jthread.h:1.46
--- kaffe/kaffe/kaffevm/systems/unix-jthreads/jthread.h:1.45	Mon Aug 25 07:48:26 2003
+++ kaffe/kaffe/kaffevm/systems/unix-jthreads/jthread.h	Sat Aug 30 23:57:12 2003
@@ -428,10 +428,10 @@
 		jlong ct;
 		
 		getrusage(RUSAGE_SELF, &ru);
-		ct = ((jlong)ru.ru_utime.tv_sec * 1000)
-			+ ((jlong)ru.ru_utime.tv_usec / (jlong)1000);
-		ct += ((jlong)ru.ru_stime.tv_sec * 1000)
-			+ ((jlong)ru.ru_stime.tv_usec / (jlong)1000);
+		ct = ((jlong)ru.ru_utime.tv_sec * 1000000)
+			+ ((jlong)ru.ru_utime.tv_usec);
+		ct += ((jlong)ru.ru_stime.tv_sec * 1000000)
+			+ ((jlong)ru.ru_stime.tv_usec);
 
 		retval = jt->totalUsed + (ct - jt->startUsed);
 	}
@@ -465,6 +465,18 @@
 int jthread_on_condvar(jthread_t jt)
 {
 	return( jt->flags & THREAD_FLAGS_WAIT_CONDVAR );
+}
+
+static inline
+void jthread_clear_run(jthread_t jt)
+{
+	jt->startUsed = 0;
+}
+
+static inline
+int jthread_has_run(jthread_t jt)
+{
+	return( jt->startUsed != 0 );
 }
 
 #endif