[Mono-list] mcs compiles on linux. Now what?

Dietmar Maurer dietmar@ximian.com
08 Mar 2002 14:45:17 +0100


On Fri, 2002-03-08 at 14:39, Piers Haken wrote:
> microsoft's implementation of ValueType.GetHashCode() basically uses
> reflection to find the first non-zero field and returns that [1]. I'm
> not sure what Object's GetHashCode() does. I'll look into it. I have a
> feeling it's internal, though.
> 

Another solution is to check if a class implements its own GetHashCode
function. If not the runtime can add a unique object id to each
allocated object. This adds 4 additional bytes to some objects, but it
also works with a compacting GC. At first glance it looks easy to
implement:


Index: mono/metadata/class.c
===================================================================
RCS file: /cvs/public/mono/mono/metadata/class.c,v
retrieving revision 1.90
diff -u -r1.90 class.c
--- mono/metadata/class.c	2002/03/07 06:39:57	1.90
+++ mono/metadata/class.c	2002/03/08 09:40:33
@@ -327,6 +327,7 @@
 	MonoClass *k, *ic;
 	MonoMethod **vtable = class->vtable;
 	int i, max_iid, cur_slot = 0;
+	static MonoMethod *default_ghc = NULL;
 
 	g_assert (class);
 
@@ -622,6 +623,23 @@
 						ic->method.count, ic->name_space, ic->name);
 				}
 			}
+		}
+	}
+
+#define GHC_SLOT 2
+
+	if (!default_ghc) {
+		if (class == mono_defaults.object_class) { 
+			default_ghc = vtable [GHC_SLOT];
+			g_assert (!strcmp (default_ghc->name, "GetHashCode"));
+		}
+	}
+	
+	class->ghcimpl = 1;
+	if (class != mono_defaults.object_class) { 
+		if (vtable [GHC_SLOT] == default_ghc) {
+			printf ("TEST %s.%s\n", class->name_space, class->name);
+			class->ghcimpl = 0;
 		}
 	}
 }
Index: mono/metadata/class.h
===================================================================
RCS file: /cvs/public/mono/mono/metadata/class.h,v
retrieving revision 1.41
diff -u -r1.41 class.h
--- mono/metadata/class.h	2002/03/07 06:39:57	1.41
+++ mono/metadata/class.h	2002/03/08 09:40:33
@@ -41,6 +41,7 @@
 	guint inited          : 1;
 	guint valuetype       : 1; /* derives from System.ValueType */
 	guint enumtype        : 1; /* derives from System.Enum */
+	guint ghcimpl         : 1; /* class has its own GetHashCode impl */ 
 	guint min_align       : 4;
 
 	MonoClass  *parent;
Index: mono/metadata/object.c
===================================================================
RCS file: /cvs/public/mono/mono/metadata/object.c,v
retrieving revision 1.46
diff -u -r1.46 object.c
--- mono/metadata/object.c	2002/03/08 07:02:28	1.46
+++ mono/metadata/object.c	2002/03/08 09:40:33
@@ -90,13 +90,22 @@
 MonoObject *
 mono_object_new (MonoDomain *domain, MonoClass *klass)
 {
+	static guint32 uoid = 0;
 	MonoObject *o;
 
 	if (!klass->inited)
 		mono_class_init (klass);
 
-	o = mono_object_allocate (klass->instance_size);
-	o->vtable = mono_class_vtable (domain, klass);
+
+	if (klass->ghcimpl) {
+		o = mono_object_allocate (klass->instance_size);
+		o->vtable = mono_class_vtable (domain, klass);
+	} else {
+		o = mono_object_allocate (klass->instance_size + 4);
+		*((guint32 *)o) = uoid;
+		((char *)o) += 4;
+		o->vtable = mono_class_vtable (domain, klass);
+	}
 
 	return o;
 }