[kaffe] CVS kaffe (guilhem): Warning fixes.

Kaffe CVS cvs-commits at kaffe.org
Sun Apr 24 08:15:30 PDT 2005


PatchSet 6420 
Date: 2005/04/24 15:10:43
Author: guilhem
Branch: HEAD
Tag: (none) 
Log:
Warning fixes.

2005-04-24  Eric Anholt <eta at lclark.edu>

        * kaffe/kaffevm/exception.c,
        kaffe/kaffevm/locks.c,
        kaffe/kaffevm/locks.h,
        kaffe/kaffevm/string.c,
        kaffe/kaffevm/intrp/checks.h,
        kaffe/kaffevm/intrp/icode.h,
        kaffe/kaffevm/jni/jni-base.c,
        kaffe/kaffevm/jni/jni-helpers.c,
        kaffe/kaffevm/jni/jni.c
        kaffe/kaffevm/jni/jni_funcs.h
        kaffe/kaffevm/kaffe-gc/gc-mem.c:
        Fixed a few warnings.

Members: 
	ChangeLog:1.3948->1.3949 
	kaffe/kaffevm/exception.c:INITIAL->1.96 
	kaffe/kaffevm/locks.c:INITIAL->1.62 
	kaffe/kaffevm/locks.h:INITIAL->1.30 
	kaffe/kaffevm/string.c:INITIAL->1.43 
	kaffe/kaffevm/intrp/checks.h:1.4->1.5 
	kaffe/kaffevm/jni/jni-base.c:1.17->1.18 
	kaffe/kaffevm/jni/jni-helpers.c:1.4->1.5 
	kaffe/kaffevm/jni/jni.c:1.23->1.24 
	kaffe/kaffevm/jni/jni_funcs.h:1.7->1.8 
	kaffe/kaffevm/kaffe-gc/gc-mem.c:1.26->1.27 

Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.3948 kaffe/ChangeLog:1.3949
--- kaffe/ChangeLog:1.3948	Sun Apr 24 13:46:01 2005
+++ kaffe/ChangeLog	Sun Apr 24 15:10:43 2005
@@ -1,3 +1,18 @@
+2005-04-24  Eric Anholt <eta at lclark.edu>
+
+	* kaffe/kaffevm/exception.c,
+	kaffe/kaffevm/locks.c,
+	kaffe/kaffevm/locks.h,
+	kaffe/kaffevm/string.c,
+	kaffe/kaffevm/intrp/checks.h,
+	kaffe/kaffevm/intrp/icode.h,
+	kaffe/kaffevm/jni/jni-base.c,
+	kaffe/kaffevm/jni/jni-helpers.c,
+	kaffe/kaffevm/jni/jni.c
+	kaffe/kaffevm/jni/jni_funcs.h
+	kaffe/kaffevm/kaffe-gc/gc-mem.c:
+	Fixed a few warnings.
+
 2005-04-24  Dalibor Topic  <robilad at kaffe.org>
 
 	* config/i386/netbsd1/md.h:
===================================================================
Checking out kaffe/kaffe/kaffevm/exception.c
RCS:  /home/cvs/kaffe/kaffe/kaffe/kaffevm/exception.c,v
VERS: 1.96
***************
--- /dev/null	Sun Aug  4 19:57:58 2002
+++ kaffe/kaffe/kaffevm/exception.c	Sun Apr 24 15:15:29 2005
@@ -0,0 +1,689 @@
+/*
+ * exception.c
+ * Handle exceptions for the interpreter or translator.
+ *
+ * Copyright (c) 1996, 1997, 2004
+ *	Transvirtual Technologies, Inc.  All rights reserved.
+ * Copyright (c) 2003
+ * 	Mark J. Wielaard <mark at klomp.org>
+ * Copyright (c) 2004
+ *      Kaffe.org contributors. See ChangeLogs for details. All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file.
+ */
+
+#if defined(HAVE_STDARG_H)
+#include <stdarg.h>
+#endif /* defined(HAVE_STDARG_H) */
+
+#include <stdio.h>
+
+#include "config.h"
+#include "debug.h"
+#include "config-std.h"
+#include "config-signal.h"
+#include "config-mem.h"
+#include "config-setjmp.h"
+#include "config-hacks.h"
+#include "kaffe/jni_md.h"
+#include "gtypes.h"
+#include "access.h"
+#include "object.h"
+#include "constants.h"
+#include "md.h"
+#include "callKaffeException.h"
+#include "classMethod.h"
+#include "code.h"
+#include "exception.h"
+#include "baseClasses.h"
+#include "lookup.h"
+#include "thread.h"
+#include "thread-impl.h"
+#include "errors.h"
+#include "itypes.h"
+#include "external.h"
+#include "soft.h"
+#include "locks.h"
+#include "stackTrace.h"
+#include "machine.h"
+#include "slots.h"
+#include "gcj/gcj.h"
+
+#include "java_lang_Throwable.h"
+#include "java_lang_VMThrowable.h"
+
+#if defined(INTERPRETER)
+
+static struct Hjava_lang_Object*
+vmExcept_getSyncObj(VmExceptHandler* eh)
+{
+	assert(eh != NULL);
+	assert(eh->meth != NULL);
+	assert(eh->meth != VMEXCEPTHANDLER_KAFFEJNI_HANDLER);
+	return eh->frame.intrp.syncobj;
+}
+
+#define FRAMEOBJECT(O, F, E)    (O) = vmExcept_getSyncObj((VmExceptHandler*)(F))
+
+
+#define DISPATCH_EXCEPTION(F, H, E) vmExcept_setPC((VmExceptHandler *)(F), (H));  \
+                                    vmExcept_jumpToHandler((VmExceptHandler *)(F)); /* Does not return */
+#else
+
+#define DISPATCH_EXCEPTION(F,H,E) thread_data->exceptObj = NULL;\
+                                  CALL_KAFFE_EXCEPTION((F),(H),(E));
+
+#endif	/* TRANSLATOR */
+
+static void nullException(struct _exceptionFrame *);
+static void floatingException(struct _exceptionFrame *);
+static void stackOverflowException(struct _exceptionFrame *);
+static void dispatchException(Hjava_lang_Throwable*, stackTraceInfo*);
+
+static bool findExceptionBlockInMethod(uintp, Hjava_lang_Class*, Method*, uintp*);
+
+bool
+vmExcept_isJNIFrame(VmExceptHandler* eh)
+{
+	assert(eh != NULL);
+	return (eh->meth == VMEXCEPTHANDLER_KAFFEJNI_HANDLER);
+}
+
+static bool
+vmExcept_JNIContains(VmExceptHandler* eh, JNIFrameAddress fp)
+{
+	assert(eh != NULL);
+	assert(eh->meth == VMEXCEPTHANDLER_KAFFEJNI_HANDLER);
+	assert(fp != (JNIFrameAddress)0);
+
+	return (eh->frame.jni.fp == fp);
+}
+
+void 
+vmExcept_setJNIFrame(VmExceptHandler* eh, JNIFrameAddress fp)
+{
+	assert(eh != NULL);
+	assert(fp != (JNIFrameAddress)0);
+
+	eh->meth = VMEXCEPTHANDLER_KAFFEJNI_HANDLER;
+	eh->frame.jni.fp = fp;
+}
+
+static void
+vmExcept_jumpToHandler(VmExceptHandler* frame)
+{
+	JTHREAD_LONGJMP(frame->jbuf, 1);
+}
+
+void 
+vmExcept_setSyncObj(VmExceptHandler* eh, struct Hjava_lang_Object* syncobj)
+{
+	assert(eh != NULL);
+	assert(eh->meth != NULL);
+	assert(eh->meth != VMEXCEPTHANDLER_KAFFEJNI_HANDLER);
+	eh->frame.intrp.syncobj = syncobj;
+}
+
+void 
+vmExcept_setPC(volatile VmExceptHandler* eh, u4 pc)
+{
+	assert(eh != NULL);
+	assert(eh->meth != NULL);
+	assert(eh->meth != VMEXCEPTHANDLER_KAFFEJNI_HANDLER);
+	eh->frame.intrp.pc = pc;
+}
+
+u4 
+vmExcept_getPC(const VmExceptHandler* eh)
+{
+	assert(eh != NULL);
+	assert(eh->meth != NULL);
+	assert(eh->meth != VMEXCEPTHANDLER_KAFFEJNI_HANDLER);
+	return eh->frame.intrp.pc;
+}
+
+/*
+ * Create an exception from error information.
+ */
+Hjava_lang_Throwable*
+error2Throwable(errorInfo* einfo)
+{
+	Hjava_lang_Throwable *err = NULL;
+
+	switch (einfo->type & KERR_CODE_MASK) {
+	case KERR_EXCEPTION:
+		if (einfo->mess == 0 || *einfo->mess == '\0') {
+			err = (Hjava_lang_Throwable*)execute_java_constructor(
+				    einfo->classname, NULL, NULL, "()V");
+		} else {
+			err = (Hjava_lang_Throwable*)execute_java_constructor(
+				    einfo->classname,
+				    NULL, NULL, "(Ljava/lang/String;)V",
+				    checkPtr(stringC2Java(einfo->mess)));
+		}
+		break;
+
+	case KERR_INITIALIZER_ERROR:
+		if (strcmp(CLASS_CNAME(OBJECT_CLASS(&einfo->throwable->base)),
+			   "java/lang/ExceptionInInitializerError") != 0) {
+			err = (Hjava_lang_Throwable*)execute_java_constructor(
+				    JAVA_LANG(ExceptionInInitializerError),
+				    NULL, NULL, "(Ljava/lang/Throwable;)V",
+				    einfo->throwable);
+			break;
+		}
+		/* FALLTHRU */
+
+	case KERR_RETHROW:
+		err = einfo->throwable;
+		break;
+
+	case KERR_OUT_OF_MEMORY:
+		err = gc_throwOOM();
+		break;
+	default:
+	        assert(!!!"Unexpected error info mask");
+	}
+
+	discardErrorInfo(einfo);
+	return (err);
+}
+
+/*
+ * post out-of-memory condition
+ */
+void
+postOutOfMemory(errorInfo *einfo)
+{
+	memset(einfo, 0, sizeof(*einfo));
+    	einfo->type = KERR_OUT_OF_MEMORY;
+}
+
+/*
+ * post a simple exception using its full name without a message
+ */
+void
+postException(errorInfo *einfo, const char *name)
+{
+	einfo->type = KERR_EXCEPTION;
+	einfo->classname = name;
+	einfo->mess = "";
+	einfo->throwable = NULL;
+}
+
+void
+vpostExceptionMessage(errorInfo *einfo,
+	const char * fullname, const char * fmt, va_list args)
+{
+        char *msgBuf;
+        int msgLen;
+
+	msgBuf = KMALLOC(MAX_ERROR_MESSAGE_SIZE);
+	if (msgBuf == 0) {
+		einfo->type = KERR_OUT_OF_MEMORY;
+		return;
+	}
+
+#ifdef HAVE_VSNPRINTF
+        msgLen = vsnprintf(msgBuf, MAX_ERROR_MESSAGE_SIZE, fmt, args);
+#else
+        /* XXX potential buffer overruns problem: */
+        msgLen = vsprintf(msgBuf, fmt, args);
+#endif
+	einfo->type = KERR_EXCEPTION | KERR_FREE_MESSAGE;
+	einfo->classname = fullname;
+	einfo->mess = msgBuf;
+	einfo->throwable = NULL;
+}
+
+/*
+ * post a longer exception with a message using full name
+ */
+void
+postExceptionMessage(errorInfo *einfo,
+	const char * fullname, const char * fmt, ...)
+{
+        va_list args;
+
+        va_start(args, fmt);
+	vpostExceptionMessage(einfo, fullname, fmt, args);
+        va_end(args);
+}
+
+/*
+ * post a NoClassDefFoundError - we handle this specially since it might
+ * not be a fatal error (depending no where it's generated).
+ */
+void
+postNoClassDefFoundError(errorInfo* einfo, const char* cname)
+{
+	postExceptionMessage(einfo, JAVA_LANG(NoClassDefFoundError), "%s", cname);
+	einfo->type |= KERR_NO_CLASS_FOUND;
+}
+
+/*
+ * Check whether we threw a NoClassFoundError and if we did clear it.
+ * We need this in code-analyse.c to avoid throwing errors when we can't find
+ * classes but to terminate when we get real errors.
+ */
+int
+checkNoClassDefFoundError(errorInfo* einfo)
+{
+	if (einfo->type & KERR_NO_CLASS_FOUND) {
+		discardErrorInfo(einfo);
+		return (1);
+	}
+	else {
+		return (0);
+	}
+}
+
+/*
+ * dump error info to stderr
+ */
+void
+dumpErrorInfo(errorInfo *einfo UNUSED)
+{
+	/* XXX */
+}
+
+/*
+ * discard the errorinfo, freeing a message if necessary
+ */
+void
+discardErrorInfo(errorInfo *einfo)
+{
+	if (einfo->type & KERR_FREE_MESSAGE) {
+		KFREE((void *)einfo->mess);
+		einfo->type &= ~KERR_FREE_MESSAGE;
+	}
+}
+
+/*
+ * Create and throw an exception resulting from an error during VM processing.
+ */
+void
+throwError(errorInfo* einfo)
+{
+	Hjava_lang_Throwable* eobj = error2Throwable (einfo);
+	throwException(eobj);
+}
+
+/*
+ * Throw an exception with backtrace recomputed.
+ *
+ * Semantic: take stacktrace right now (overwrite whatever stacktrace
+ * is in the exception object) and dispatch.
+ */
+void
+throwException(struct Hjava_lang_Throwable* eobj)
+{
+	Hjava_lang_VMThrowable* vmstate;
+	Hjava_lang_Object* backtrace;
+
+	if (eobj == 0) {
+		dprintf("Exception thrown on null object ... aborting\n");
+		ABORT();
+		EXIT(1);
+	}
+	vmstate = unhand(eobj)->vmState;
+	if (vmstate == 0) {
+		vmstate =
+		  (Hjava_lang_VMThrowable*)newObject(javaLangVMThrowable);
+		unhand(eobj)->vmState = vmstate;
+	}
+	backtrace = buildStackTrace(NULL);
+	unhand(vmstate)->backtrace = backtrace;
+	dispatchException(eobj, (stackTraceInfo*)backtrace);
+}
+
+/*
+ * Throw an exception without altering backtrace.
+ *
+ * Semantic: just dispatch from here and leave whatever stacktrace is
+ * in the exception object.
+ */
+void
+throwExternalException(Hjava_lang_Throwable* eobj)
+{
+	if (eobj == 0) {
+		dprintf("Exception thrown on null object ... aborting\n");
+		ABORT();
+		EXIT(1);
+	}
+	dispatchException(eobj, (stackTraceInfo*)buildStackTrace(NULL));
+}
+
+#if 0
+void
+throwOutOfMemory(void)
+{
+	Hjava_lang_Throwable* err;
+
+	err = OutOfMemoryError;
+	if (err != NULL) {
+		throwException(err);
+	}
+	dprintf("(Insufficient memory)\n");
+	EXIT(-1);
+}
+#endif
+
+static void
+dispatchException(Hjava_lang_Throwable* eobj, stackTraceInfo* baseFrame)
+{
+	threadData*		thread_data;
+	VmExceptHandler*	lastJniFrame;
+	stackTraceInfo*		frame;
+
+#if defined(INTS_DISABLED)
+	/*
+	 * We should never try to dispatch an exception while interrupts are
+	 * disabled.  If the threading system provides a means to do so,
+	 * check that we don't attempt to do it anyway.
+	 */
+	assert(!INTS_DISABLED());
+#endif
+	thread_data = THREAD_DATA(); 
+
+	/* Save exception object */
+	thread_data->exceptObj = eobj;
+
+#if defined (HAVE_GCJ_SUPPORT)
+	/* XXX */
+	_Jv_Throw(eobj); /* no return */
+#endif
+
+	/* Search down exception stack for a match */
+	DBG(ELOOKUP,
+	    dprintf ("dispatchException(): %s\n", ((Hjava_lang_Object*)eobj)->vtable->class->name->data););
+
+	/*
+	 * find the last jni frame
+	 * (there is _always_ a jni frame somewhere on the stack,
+	 *  except during initialiseKaffe() )
+	 */
+	for (lastJniFrame = thread_data->exceptPtr;
+	     lastJniFrame && !vmExcept_isJNIFrame(lastJniFrame);
+	     lastJniFrame = lastJniFrame->prev);
+
+	DBG(ELOOKUP,
+		dprintf ("dispatchException(): lastJniFrame is %p, fp %p\n", lastJniFrame, (lastJniFrame?lastJniFrame->frame.jni.fp:0)); );
+
+	/*
+	 * now walk up the stack 
+	 */
+	for (frame = baseFrame; frame->meth != ENDOFSTACK; frame++) {
+		bool 			foundHandler;
+		uintp 			handler;
+		Hjava_lang_Object*	obj;
+
+		/*
+		 * if we reach the last jni frame, we're done
+		 */
+		if (lastJniFrame && vmExcept_JNIContains(lastJniFrame, frame->fp)) {
+			thread_data->exceptPtr = lastJniFrame;
+			vmExcept_jumpToHandler(lastJniFrame); /* doesn't return */
+		}
+
+		/*
+		 * if we could not determine the java method of this stack frame,
+		 * simply ignore that frame
+		 */
+		if (frame->meth == 0) {
+			continue;
+		}
+
+		/*
+		 * check whether that method contains a suitable handler
+		 */
+		foundHandler = findExceptionBlockInMethod(frame->pc,
+							  eobj->base.vtable->class,
+							  frame->meth,
+							  &handler);
+
+		/* Find the sync. object */
+		if ((frame->meth->accflags & ACC_SYNCHRONISED)==0) {
+			obj = NULL;
+		} else if (frame->meth->accflags & ACC_STATIC) {
+			obj = &frame->meth->class->head;
+		} else {
+			FRAMEOBJECT(obj, frame->fp, frame->meth);
+		}
+
+		/* If handler found, call it */
+		if (foundHandler) {
+			thread_data->needOnStack = STACK_HIGH;
+			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, NULL);
+		}	    
+
+		/* If method found and profiler enable, fix self+children time */
+#if defined(TRANSLATOR) && defined(KAFFE_PROFILER)
+		if (profFlag) {
+			profiler_click_t end;
+			profiler_get_clicks(end);
+			frame->meth->totalClicks += end;
+		}
+#endif    
+	}
+
+	/*
+	 * we did not find a handler...
+	 */
+	unhandledException (eobj);
+}
+
+void
+unhandledException(Hjava_lang_Throwable *eobj)
+{
+	const char* cname;
+	Hjava_lang_Class* class;
+
+	/* Clear held exception object */
+	THREAD_DATA()->exceptObj = NULL;
+
+	class = OBJECT_CLASS(&eobj->base);
+	cname = CLASS_CNAME(class);
+
+	/* We don't know what to do here. */
+	dprintf("Internal error: caught an unexpected exception.\n"
+		"Please check your CLASSPATH and your installation.\n");
+
+	/*
+	 * Display the exception and stack trace to help in debugging.
+	 */
+	{
+		Hjava_lang_String *msg;
+		msg = unhand((Hjava_lang_Throwable*)eobj)->detailMessage;
+		if (msg) {
+			dprintf("%s: %s\n", cname, stringJava2C(msg));
+		} else {
+			dprintf("%s\n", cname);
+			if (strcmp(cname, "java/lang/StackOverflowError") == 0)
+			  dprintf("This error may occur because the stack size is not sufficient. \n"
+				  "Try to increase the stack size using 'ulimit -s' or with the '-ss'\n"
+				  "option on kaffe.\n");
+		}
+	}
+	printStackTrace((Hjava_lang_Throwable*)eobj, NULL, 1);
+	ABORT();
+}
+
+/*
+ * Setup the internal exceptions.
+ */
+void
+initExceptions(void)
+{
+DBG(INIT,
+	dprintf("initExceptions()\n");
+    );
+	/* Catch signals we need to convert to exceptions */
+	KTHREAD(initexceptions)(nullException, floatingException, stackOverflowException);
+}
+
+/*
+ * Stack Overflow exception - catches stack overflows.
+ */
+static void
+stackOverflowException(struct _exceptionFrame *frame)
+{
+  	Hjava_lang_Throwable* soe;
+	Hjava_lang_VMThrowable* vmstate;
+	Hjava_lang_Object* backtrace;
+
+	soe = (Hjava_lang_Throwable*)newObject(javaLangStackOverflowError);
+	vmstate = (Hjava_lang_VMThrowable*)newObject(javaLangVMThrowable);
+	backtrace = buildStackTrace(frame);
+	unhand(vmstate)->backtrace = backtrace;
+	unhand(soe)->vmState = vmstate;
+#if defined(HAVE_GCJ_SUPPORT)
+	FAKE_THROW_FRAME();
+#endif /* defined(HAVE_GCJ_SUPPORT) */
+	dispatchException(soe, (stackTraceInfo*)backtrace);
+}
+
+/*
+ * Null exception - catches bad memory accesses.
+ */
+static void
+nullException(struct _exceptionFrame *frame)
+{
+	Hjava_lang_Throwable* npe;
+	Hjava_lang_VMThrowable* vmstate;
+	Hjava_lang_Object* backtrace;
+
+	npe = (Hjava_lang_Throwable*)newObject(javaLangNullPointerException);
+	vmstate = (Hjava_lang_VMThrowable*)newObject(javaLangVMThrowable);
+	backtrace = buildStackTrace(frame);
+	unhand(vmstate)->backtrace = backtrace;
+	unhand(npe)->vmState = vmstate;
+#if defined(HAVE_GCJ_SUPPORT)
+	FAKE_THROW_FRAME();
+#endif /* defined(HAVE_GCJ_SUPPORT) */
+	dispatchException(npe, (stackTraceInfo*)backtrace);
+}
+
+/*
+ * Division by zero.
+ */
+static void
+floatingException(struct _exceptionFrame *frame)
+{
+	Hjava_lang_Throwable* ae;
+	Hjava_lang_VMThrowable* vmstate;
+	Hjava_lang_Object* backtrace;
+
+	ae = (Hjava_lang_Throwable*)newObject(javaLangArithmeticException);
+	vmstate = (Hjava_lang_VMThrowable*)newObject(javaLangVMThrowable);
+	backtrace = buildStackTrace(frame);
+	unhand(vmstate)->backtrace = backtrace;
+	unhand(ae)->vmState = vmstate;
+#if defined(HAVE_GCJ_SUPPORT)
+	FAKE_THROW_FRAME();
+#endif /* defined(HAVE_GCJ_SUPPORT) */
+	dispatchException(ae, (stackTraceInfo*)backtrace);
+}
+
+/*
+ * Look for exception block in method.
+ * Returns true if there is an exception handler, false otherwise.
+ *
+ * Passed 'pc' is the program counter where the exception entered
+ * the current frame (the 'throw' or from a nested method call).
+ */
+static bool
+findExceptionBlockInMethod(uintp _pc, Hjava_lang_Class* class, Method* ptr, uintp* handler)
+{
+	jexceptionEntry* eptr;
+	Hjava_lang_Class* cptr;
+	unsigned int i;
+
+	assert(handler);
+
+	/* Right method - look for exception */
+	if (ptr->exception_table == 0) {
+DBG(ELOOKUP,
+		dprintf("%s.%s has no handlers.\n", ptr->class->name->data, ptr->name->data); );
+		return (false);
+	}
+
+	eptr = &ptr->exception_table->entry[0];
+
+DBG(ELOOKUP,
+	dprintf("%s.%s has %d handlers (throw was pc=%#lx):\n",
+		ptr->class->name->data, ptr->name->data,
+		ptr->exception_table->length, (long) _pc); );
+
+	for (i = 0; i < ptr->exception_table->length; i++) {
+		uintp start_pc = eptr[i].start_pc;
+		uintp end_pc = eptr[i].end_pc;
+		uintp handler_pc = eptr[i].handler_pc;
+
+DBG(ELOOKUP,	dprintf("  Handler %d covers %#lx-%#lx\n", i, 
+			(long) start_pc, (long) end_pc); );
+		if (_pc < start_pc || _pc >= end_pc) {
+			continue;
+		}
+
+		/* Found exception - is it right type */
+		if (eptr[i].catch_idx == 0) {
+			*handler = handler_pc;
+DBG(ELOOKUP,		dprintf("  Found handler @ %#lx: catches all exceptions.\n", 
+				(long) handler_pc); );
+			return (true);
+		}
+		/* Did I try to resolve that catch type before */
+		if (eptr[i].catch_type == UNRESOLVABLE_CATCHTYPE) {
+DBG(ELOOKUP,		dprintf("  Found handler @ %#lx: Unresolvable catch type.\n", 
+				(long) handler_pc); );
+			return (false);
+		}
+		/* Resolve catch class if necessary */
+		if (eptr[i].catch_type == NULL) {
+			/*
+			 * XXX Since we pre-load all catch clause exceptions
+			 * in code-analyse.c now, this code should never
+			 * be called.  Right?
+			 */
+			errorInfo info;
+			eptr[i].catch_type = getClass(eptr[i].catch_idx, ptr->class, &info);
+			/*
+			 * If we could not resolve the catch class, then we
+			 * must a) record that fact to guard against possible
+			 * recursive attempts to load it and b) throw the error
+			 * resulting from that failure and forget about the
+			 * current exception.
+			 */
+			if (eptr[i].catch_type == NULL) {
+DBG(ELOOKUP|DBG_RESERROR,
+				dprintf("Couldn't resolve catch class @ cp idx=%d\n",
+					eptr[i].catch_idx); );
+				eptr[i].catch_type = UNRESOLVABLE_CATCHTYPE;
+				throwError(&info);
+				return (false);
+			}
+		}
+                for (cptr = class; cptr != 0; cptr = cptr->superclass) {
+                        if (cptr == eptr[i].catch_type) {
+DBG(ELOOKUP,	dprintf("  Found matching handler at %#lx: Handles %s.\n",
+			(long) handler_pc, CLASS_CNAME(eptr[i].catch_type)); );
+                                *handler = handler_pc;
+                                return (true);
+                        }
+                }
+DBG(ELOOKUP,	dprintf("  Handler at %#lx (handles %s), does not match.\n",
+			(long) handler_pc, CLASS_CNAME(eptr[i].catch_type)); );
+	}
+	return (false);
+}
===================================================================
Checking out kaffe/kaffe/kaffevm/locks.c
RCS:  /home/cvs/kaffe/kaffe/kaffe/kaffevm/locks.c,v
VERS: 1.62
***************
--- /dev/null	Sun Aug  4 19:57:58 2002
+++ kaffe/kaffe/kaffevm/locks.c	Sun Apr 24 15:15:29 2005
@@ -0,0 +1,588 @@
+/*
+ * locks.c
+ * Manage locking system
+ *
+ * Copyright (c) 1996-1999
+ *	Transvirtual Technologies, Inc.  All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution 
+ * of this file. 
+ */
+
+#include "config.h"
+#include "config-std.h"
+#include "object.h"
+#include "classMethod.h"
+#include "baseClasses.h"
+#include "thread.h"
+#include "locks.h"
+#include "ksem.h"
+#include "errors.h"
+#include "exception.h"
+#include "md.h"
+#include "jthread.h"
+#include "debug.h"
+#include "gc.h"
+#include "jvmpi_kaffe.h"
+#include "stats.h"
+
+/*
+ * If we don't have an atomic compare and exchange defined then make
+ * one out of a simple atomic exchange (using the LOCKINPROGRESS value
+ * as the place holder).  If we don't have ATOMIC_EXCHANGE, we'll just
+ * fake it.
+ */
+#if !defined(COMPARE_AND_EXCHANGE)
+#if defined(ATOMIC_EXCHANGE)
+#define	COMPARE_AND_EXCHANGE(A,O,N) \
+	({ \
+		iLock* val = LOCKINPROGRESS; \
+		ATOMIC_EXCHANGE((A), val); \
+		if (val == (O)) { \
+			*(A) = (N); \
+		} \
+		else { \
+			*(A) = (O); \
+		} \
+		(val == (O) ? 1 :  0); \
+	})
+#else
+#error Please define COMPARE_AND_EXCHANGE or ATOMIC_EXCHANGE 
+#endif
+#endif
+
+/*
+ * Initialise the locking system.
+ */
+void
+initLocking(void)
+{
+}
+
+#if defined(KAFFE_STATS)
+static timespent heavyLockTime;
+static timespent locksTime;
+#endif
+
+/*
+ * Get a heavy lock for the object and hold it.  If the object doesn't
+ * have a heavy lock then we create one.
+ */
+
+#define IS_HEAVY_LOCK(ptr) ((((uintp)ptr)&1)==1)
+
+static volatile iLock *
+getHeavyLock(volatile iLock* volatile * lkp, volatile iLock *heavyLock)
+{
+  volatile iLock *lk;
+  iLock *newLock;
+
+  DBG(SLOWLOCKS,
+      dprintf("  getHeavyLock(lk=%p, th=%p)\n",
+	      *lkp, KTHREAD(current)());
+      );
+
+  for (;;)
+    {
+      lk = *lkp;
+
+      /* Check if it has been allocated, if not acquire the lock by putting our
+       * temporary structure.
+       */
+      if (!IS_HEAVY_LOCK(lk))
+	{
+	  startTiming(&heavyLockTime, "heavylock-handling");
+
+	  if (heavyLock != NULL)
+	    {
+	      /* First we try to acquire the static heavy lock. */   
+	      if (COMPARE_AND_EXCHANGE(&heavyLock->in_progress, 0, 1))
+		{
+		  /* We succeed. So anyway the other threads using this lock knows
+		   * already about it.
+		   */
+		  /* Now we check whether the other thread holding the thin lock
+		   * has released it or not. If it is so mark the holder as free.
+		   * We loop until we are sure to have placed the heavylock and to have
+		   * the correct value in lk.
+		   */
+		  while (!COMPARE_AND_EXCHANGE(lkp, lk, (iLock *)(((uintp)heavyLock) | 1)))
+		    lk = *lkp;
+		  
+		  /* Remind the holder. */
+		  heavyLock->holder = lk;
+		  if (lk != LOCKFREE)
+		    heavyLock->lockCount = 1;
+		  
+		  return heavyLock;
+		}
+	      lk = heavyLock;
+	      break;
+	    }
+
+	  /* Build a temporary lock */
+	  newLock = gc_malloc (sizeof(iLock), KGC_ALLOC_LOCK);
+
+	  /* initialize the new lock. */
+	  KSEM(init)(&newLock->sem);
+
+	  // preserve current state of lock
+	  newLock->holder = lk;
+	  if (lk != LOCKFREE)
+	    newLock->lockCount = 1;
+
+	  if (!COMPARE_AND_EXCHANGE(lkp, lk, (iLock *)((uintp)newLock |1) ))
+	    {
+	      /* heavyLock exchange must always succeed as we have already exchanged it
+	       * sooner.
+	       */
+	      newLock->lockCount = 0;
+	      continue;
+	    }
+
+	  /* Now the lock is acquired by this thread and ready to use for the others.
+	   */
+	  lk = newLock;
+	  stopTiming(&heavyLockTime);
+	}
+      else
+	break;
+    }
+
+  lk = GET_HEAVYLOCK(lk);
+  
+  /* The lock is allocated and ready to use. */
+  for (;;) {
+    /* Try to acquire the lock. We try to do an "atomic" incrementation. */
+    atomic_increment(&(lk->num_wait));
+    if (!COMPARE_AND_EXCHANGE(&(lk->in_progress), 0, 1))
+      {
+	KSEM(get)(&lk->sem, (jlong)0);
+        atomic_decrement(&(lk->num_wait));
+	continue;
+      }
+    lk->hlockHolder = KTHREAD(current)();
+    atomic_decrement(&(lk->num_wait));
+    return lk;
+  }
+}
+
+void initStaticLock(iStaticLock *slock)
+{
+  slock->lock = NULL;
+  slock->heavyLock.num_wait = 0;
+  slock->heavyLock.lockCount = 0;
+  slock->heavyLock.mux = NULL;
+  slock->heavyLock.cv = NULL;
+  slock->heavyLock.in_progress = 0;
+  slock->heavyLock.holder = NULL;
+  KSEM(init)(&slock->heavyLock.sem);
+}
+
+void destroyStaticLock(iStaticLock *slock)
+{
+  assert(slock->lock == NULL || GET_HEAVYLOCK(slock->lock) == &slock->heavyLock);
+  assert(slock->heavyLock.lockCount == 0);
+  assert(slock->heavyLock.num_wait == 0);
+  assert(slock->heavyLock.in_progress == 0);
+  KSEM(destroy)(&slock->heavyLock.sem);
+}
+
+/*
+ * Release the lock - only the one who has claimed it can do this
+ * so there's no need for locked instructions.
+ */
+static void
+putHeavyLock(volatile iLock* lk)
+{
+  DBG(SLOWLOCKS,
+      dprintf("  putHeavyLock(lk=%p, th=%p)\n", 
+	      lk, KTHREAD(current)());
+      );
+
+  assert(lk->in_progress == 1);
+  
+  lk->hlockHolder = NULL;
+  lk->in_progress = 0;
+  if (lk->num_wait != 0)
+    KSEM(put)(&(lk->sem));
+}
+
+/*
+ * Slowly lock a mutex.  We get the heavy lock and lock that instead.
+ * If we can't lock it we suspend until we can.
+ */
+static void
+slowLockMutex(volatile iLock* volatile * lkp, iLock *heavyLock)
+{
+  volatile iLock* lk;
+  jthread_t cur = KTHREAD(current) ();
+  threadData *tdata;
+
+DBG(SLOWLOCKS,
+    dprintf("slowLockMutex(lk=%p, th=%p)\n",
+	    *lkp, KTHREAD(current)());
+    );
+
+ KTHREAD(disable_stop)(); /* protect the heavy lock, and its queues */
+
+ tdata = KTHREAD(get_data)(cur);
+ for (;;) {
+   lk = getHeavyLock(lkp, heavyLock);
+   
+   startTiming(&locksTime, "slowlocks-time");
+   /* If I hold the heavy lock then just keep on going */
+   if (cur == lk->holder) {
+     lk->lockCount++;

*** Patch too long, truncated ***




More information about the kaffe mailing list