even more data on that jitter buggy

Godmar Back gback at cs.utah.edu
Wed Jul 8 00:22:10 PDT 1998


 Hi,

if you're not interested in the intricacies of how to optimize
null pointer exceptions in Kaffe jitter, you better hit 'd' now.

Otherwise, read on.

It occurred to me that the check as to which synchronous exceptions
should be caught was too imprecise.  Specifically, it would signal
canCatch if an exception was caught anywhere in a method.

So I changed it to compute the willCatch flag per instruction.
(This will have a negative impact on the time it takes to
JIT a method.)  The diffs are appended.

For my non-representative benchmark, this reduced the number of
spills from 3959 to 1633 (and to 21742 vs. 19416 CHECK_NULLs that
do not spill) and the total number of emitted instructions
from 312067 to 308865, compared to 306914 for the incorrect version
and 434420 for the version that emits checks every time.
So, that means that we now only spill about 1 in 13 times.

I know that javac is probably not a good benchmark for this.
I still suspect that the performance hit will be lower than one 
might expect.

An additional optimization might use the fact that a nullpointer
exception cannot be thrown when a second putfield is performed
on the same object, as in a.x = b; a.y = c;

I append the diffs for baseClasses.c and jit/machine.? for those 
interested.

	- Godmar

-- diffs for per instruction check --
Index: baseClasses.c
===================================================================
RCS file: /home/cvspublic/kaffe/kaffe/kaffevm/baseClasses.c,v
retrieving revision 1.5
diff -u -r1.5 baseClasses.c
--- baseClasses.c	1998/07/06 23:43:01	1.5
+++ baseClasses.c	1998/07/08 07:02:55
@@ -56,6 +56,7 @@
 Hjava_lang_Class* javaLangDoubleClass;
 
 Hjava_lang_Class* javaLangArrayIndexOutOfBoundsException;
+Hjava_lang_Class* javaLangNullPointerException;
 
 #define SYSTEMCLASS "java/lang/System"
 #define	SERIALCLASS "java/io/Serializable"
@@ -163,6 +164,7 @@
 
 	/* Exception handling types */
 	loadStaticClass(&javaLangArrayIndexOutOfBoundsException, "java/lang/ArrayIndexOutOfBoundsException");
+	loadStaticClass(&javaLangNullPointerException, "java/lang/NullPointerException");
 
 	/* Fixup primitive types */
 	finishTypes();
cvs server: Diffing jit
Index: jit/machine.c
===================================================================
RCS file: /home/cvspublic/kaffe/kaffe/kaffevm/jit/machine.c,v
retrieving revision 1.3
diff -u -r1.3 machine.c
--- machine.c	1998/05/28 18:37:01	1.3
+++ machine.c	1998/07/08 07:02:55
@@ -1,4 +1,4 @@
-/* machine.c
+/*
  * Translate the Kaffe instruction set to the native one.
  *
  * Copyright (c) 1996, 1997
@@ -66,6 +66,7 @@
 
 /* Various exception related things */
 extern Hjava_lang_Class javaLangArrayIndexOutOfBoundsException;
+extern Hjava_lang_Class javaLangNullPointerException;
 
 jitflags willcatch;
 
@@ -77,7 +78,10 @@
       softcall_nullpointer();                                 \
       set_label(_i, _n)
 #else
-#define CHECK_NULL(_i, _s, _n)
+#define CHECK_NULL(_i, _s, _n)	\
+	if (canCatch(NULLPOINTER)) {		\
+		prepare_function_call();  	\
+	}
 #endif
 
 /* Unit in which code block is increased when overrun */
@@ -103,6 +107,7 @@
 void	finishInsnSequence(nativeCodeInfo*);
 static void generateInsnSequence(void);
 static void installMethodCode(Method*, nativeCodeInfo*);
+static void checkCaughtExceptions(Method* meth, int pc);
 
 void	endBlock(sequence*);
 void	startBlock(sequence*);
@@ -192,24 +197,6 @@
 	base = (bytecode*)meth->c.bcode.code;
 	len = meth->c.bcode.codelen;
 
-	willcatch.BADARRAYINDEX = false;
-
-	/* Deterimine various exception conditions */
-	if (meth->exception_table != 0) {
-		for (i = 0; i < meth->exception_table->length; i++) {
-			Hjava_lang_Class* etype;
-			etype = meth->exception_table->entry[i].catch_type;
-			if (etype == 0) {
-				willCatch(BADARRAYINDEX);
-			}
-			else {
-				if (instanceof(&javaLangArrayIndexOutOfBoundsException, etype)) {
-					willCatch(BADARRAYINDEX);
-				}
-			}
-		}
-	}
-
 	/* Scan the code and determine the basic blocks */
 	verifyMethod(meth);
 
@@ -233,6 +220,8 @@
 
 		npc = pc + insnLen[base[pc]];
 
+		checkCaughtExceptions(meth, pc);
+
 		start_instruction();
 
 		/* Note start of exception handling blocks */
@@ -640,3 +629,42 @@
 	}
 }
 
+/*
+ * check what synchronous exceptions are caught for a given instruction
+ */
+static
+void checkCaughtExceptions(Method* meth, int pc)
+{
+	int i;
+
+	willcatch.BADARRAYINDEX = false;
+	willcatch.NULLPOINTER = false;
+
+	if (meth->exception_table == 0) 
+		return;
+
+	/* Determine various exception conditions */
+
+	for (i = 0; i < meth->exception_table->length; i++) {
+		Hjava_lang_Class* etype;
+
+		/* include only if exception range matches pc */
+		if (meth->exception_table->entry[i].start_pc > pc ||
+		    meth->exception_table->entry[i].end_pc <= pc)
+			continue;
+
+		etype = meth->exception_table->entry[i].catch_type;
+		if (etype == 0) {
+			willCatch(BADARRAYINDEX);
+			willCatch(NULLPOINTER);
+		}
+		else {
+			if (instanceof(&javaLangArrayIndexOutOfBoundsException, etype)) {
+				willCatch(BADARRAYINDEX);
+			}
+			if (instanceof(&javaLangNullPointerException, etype)) {
+				willCatch(NULLPOINTER);
+			}
+		}
+	}
+}
Index: jit/machine.h
===================================================================
RCS file: /home/cvspublic/kaffe/kaffe/kaffevm/jit/machine.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 machine.h
--- machine.h	1998/03/31 19:10:54	1.1.1.1
+++ machine.h	1998/07/08 07:02:55
@@ -98,6 +98,7 @@
 
 typedef struct {
         bool BADARRAYINDEX;
+        bool NULLPOINTER;
 } jitflags;
 
 extern jitflags willcatch;


More information about the kaffe mailing list