[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;
}