[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