[Mono-list] patch: use relative numbering for runtime type checks

Dietmar Maurer dietmar@ximian.com
25 Oct 2001 11:32:05 +0200


Index: mono/interpreter/ChangeLog
===================================================================
RCS file: /cvs/public/mono/mono/interpreter/ChangeLog,v
retrieving revision 1.72
diff -u -r1.72 ChangeLog
--- mono/interpreter/ChangeLog	2001/10/15 09:50:03	1.72
+++ mono/interpreter/ChangeLog	2001/10/25 05:31:50
@@ -1,3 +1,8 @@
+2001-10-25  Dietmar Maurer  <dietmar@ximian.com>
+
+	* interp.c (ves_exec_method): use relative numbering for runtime
+	type checks (and make it work with interfaces)
+
 2001-10-15  Dietmar Maurer  <dietmar@ximian.com>
 
 	* interp.c: removed newobj()
Index: mono/interpreter/interp.c
===================================================================
RCS file: /cvs/public/mono/mono/interpreter/interp.c,v
retrieving revision 1.88
diff -u -r1.88 interp.c
--- mono/interpreter/interp.c	2001/10/15 09:50:03	1.88
+++ mono/interpreter/interp.c	2001/10/25 05:31:50
@@ -2061,22 +2061,27 @@
 			token = read32 (ip);
 			c = mono_class_get (image, token);
 
+			if (!c->inited)
+				init_class (c);
+
 			g_assert (sp [-1].type == VAL_OBJ);
 
 			if ((o = sp [-1].data.p)) {
-				/* 
-				 * fixme: this only works for class casts, but not for 
-				 * interface casts. 
-				 */
+
 				oclass = o->klass;
-				while (oclass) {
-					if (c == oclass) {
-						sp [-1].data.vt.klass = oclass;
+
+				if (c->flags & TYPE_ATTRIBUTE_INTERFACE) {
+					if ((c->interface_id < oclass->interface_count) &&
+					    oclass->interface_offsets [c->interface_id])
 						found = TRUE;
-						break;
+					g_error ("fixme: dont know if this works");
+				} else {
+					if ((oclass->baseval - c->baseval) <= c->diffval) {
+						sp [-1].data.vt.klass = c;
+						found = TRUE;
 					}
-					oclass = oclass->parent;
 				}
+
 				if (!found) {
 					if (do_isinst) {
 						sp [-1].data.p = NULL;
Index: mono/metadata/ChangeLog
===================================================================
RCS file: /cvs/public/mono/mono/metadata/ChangeLog,v
retrieving revision 1.77
diff -u -r1.77 ChangeLog
--- mono/metadata/ChangeLog	2001/10/17 03:58:33	1.77
+++ mono/metadata/ChangeLog	2001/10/25 05:31:50
@@ -1,3 +1,8 @@
+2001-10-25  Dietmar Maurer  <dietmar@ximian.com>
+
+	* class.c (mono_compute_relative_numbering): use relative
+	numbering to support fast runtime type checks.
+
 2001-10-17  Sean MacIsaac  <macisaac@ximian.com>
 
 	* class.c (mono_class_create_from_typeref): added debugging output
Index: mono/metadata/class.c
===================================================================
RCS file: /cvs/public/mono/mono/metadata/class.c,v
retrieving revision 1.43
diff -u -r1.43 class.c
--- mono/metadata/class.c	2001/10/17 03:58:33	1.43
+++ mono/metadata/class.c	2001/10/25 05:31:50
@@ -394,6 +394,25 @@
 	//printf ("METAEND %s.%s\n", class->name_space, class->name);
 }
 
+/*
+ * Compute a relative numbering of the class hierarchy as described in
+ * "Java for Large-Scale Scientific Computations?"
+ */
+static void
+mono_compute_relative_numbering (MonoClass *class, int *c)
+{
+	GList *s;
+
+	(*c)++;
+
+	class->baseval = *c;
+
+	for (s = class->subclasses; s; s = s->next)
+		mono_compute_relative_numbering ((MonoClass *)s->data, c); 
+	
+	class->diffval = *c -  class->baseval;
+}
+
 /**
  * @image: context where the image is created
  * @type_token:  typedef token
@@ -468,9 +487,12 @@
 		class->parent = NULL;
 		class->instance_size = sizeof (MonoObject);
 	} else if (!(cols [0] & TYPE_ATTRIBUTE_INTERFACE)) {
+		int rnum = 0;
 		class->parent = mono_class_get (image,  mono_metadata_token_from_dor
(cols [3]));
 		class->valuetype = class->parent->valuetype;
 		class->enumtype = class->parent->enumtype;
+		class->parent->subclasses = g_list_prepend
(class->parent->subclasses, class);
+		mono_compute_relative_numbering (mono_defaults.object_class, &rnum);
 	}
 
 	if (!strcmp (nspace, "System")) {
@@ -703,6 +725,7 @@
 	MonoClass *class;
 	static MonoClass *parent = NULL;
 	guint32 key;
+	int rnum = 0;
 
 	g_assert (rank <= 255);
 
@@ -732,6 +755,8 @@
 	class->instance_size = mono_class_instance_size (class->parent);
 	class->class_size = 0;
 	class->vtable_size = parent->vtable_size;
+	class->parent->subclasses = g_list_prepend (class->parent->subclasses,
class);
+	mono_compute_relative_numbering (mono_defaults.object_class, &rnum);
 
 	class->rank = rank;
 	class->element_class = eclass;
Index: mono/metadata/class.h
===================================================================
RCS file: /cvs/public/mono/mono/metadata/class.h,v
retrieving revision 1.24
diff -u -r1.24 class.h
--- mono/metadata/class.h	2001/10/15 09:50:03	1.24
+++ mono/metadata/class.h	2001/10/25 05:31:50
@@ -24,7 +24,8 @@
 	guint valuetype       : 1; /* derives from System.ValueType */
 	guint enumtype        : 1; /* derives from System.Enum */
 
-	MonoClass *parent;
+	MonoClass  *parent;
+	GList      *subclasses; /* list of all subclasses */
 
 	const char *name;
 	const char *name_space;
@@ -40,6 +41,12 @@
 	int        instance_size;
 	int        class_size;
 	int        vtable_size; /* number of slots */
+
+	/*
+	 * relartive numbering for fast type checking
+	 */
+	unsigned int baseval;
+	unsigned int diffval;
 
 	/*
 	 * From the TypeDef table