static void
run_finalize (void *obj, void *data)
{
- MonoObject *o = obj;
+ MonoObject *o;
+ o = (MonoObject*)((char*)obj + GPOINTER_TO_UINT (data));
if (finalize_slot < 0) {
int i;
}
/* speedup later... */
/*
- * Disabled: it seems to be called too early.
- * g_print ("finalizer is run on %s\n", mono_object_class(o)->name);
- mono_runtime_invoke (o->vtable->klass->vtable [finalize_slot], obj, NULL);*/
+ * mono crashes (see bug#23778)
+ g_print ("finalizer is run on %s at %p\n", mono_object_class(o)->name, o);
+ mono_runtime_invoke (o->vtable->klass->vtable [finalize_slot], obj, NULL);
+ */
}
-void
-mono_object_register_finalizer (MonoObject *obj)
+/*
+ * Some of our objects may point to a different address than the address returned by GC_malloc()
+ * (because of the GetHashCode hack), but we need to pass the real address to register_finalizer.
+ * This also means that in the callback we need to adjust the pointer to get back the real
+ * MonoObject*.
+ * We also need to be consistent in the use of the GC_debug* variants of malloc and register_finalizer,
+ * since that, too, can cause the underlying pointer to be offset.
+ */
+static void
+object_register_finalizer (MonoObject *obj, void (*callback)(void *, void*))
{
#if HAVE_BOEHM_GC
- GC_register_finalizer (obj, run_finalize, NULL, NULL, NULL);
+ guint offset = 0;
+ if (mono_object_class (obj)->ghcimpl)
+ offset += 4;
+ /*g_print ("registering %s at %p (base: %p)\n", mono_object_class (obj)->name, obj, GC_base (obj));*/
+ GC_register_finalizer ((char*)obj - offset, run_finalize, GUINT_TO_POINTER (offset), NULL, NULL);
#endif
}
+void
+mono_object_register_finalizer (MonoObject *obj)
+{
+ object_register_finalizer (obj, run_finalize);
+}
+
void
ves_icall_System_GC_InternalCollect (int generation)
{
void
ves_icall_System_GC_ReRegisterForFinalize (MonoObject *obj)
{
-#if HAVE_BOEHM_GC
- GC_register_finalizer (obj, run_finalize, NULL, NULL, NULL);
-#endif
+ object_register_finalizer (obj, run_finalize);
}
void
ves_icall_System_GC_SuppressFinalize (MonoObject *obj)
{
-#if HAVE_BOEHM_GC
- GC_register_finalizer (obj, NULL, NULL, NULL, NULL);
-#endif
+ object_register_finalizer (obj, NULL);
}
void
mono_object_allocate (size_t size)
{
#if HAVE_BOEHM_GC
- void *o = GC_debug_malloc (size, "object", 1);
+ /* if this is changed to GC_debug_malloc(), we need to change also metadata/gc.c */
+ void *o = GC_malloc (size);
#else
void *o = calloc (1, size);
#endif
mono_stats.new_object_count++; /* thread safe? */
+ /* if the returned pointer is not the same as the address returned by GC_malloc(),
+ * we need to change also metadata/gc.c to take into account the new offset.
+ */
if (vtable->klass->ghcimpl)
o = mono_object_allocate (vtable->klass->instance_size);
else {
len = lengths [0];
} else {
#if HAVE_BOEHM_GC
- bounds = GC_debug_malloc (sizeof (MonoArrayBounds) * array_class->rank, "bounds", 0);
+ bounds = GC_malloc (sizeof (MonoArrayBounds) * array_class->rank);
#else
bounds = g_malloc0 (sizeof (MonoArrayBounds) * array_class->rank);
#endif
{
MonoString *s;
+ /*
+ * enable to get a good speedup: we still need to figure out
+ * how the sync structure is freed.
+ */
+#ifdef 0 && HAVE_BOEHM_GC
+ s = GC_malloc_atomic (sizeof (MonoString) + ((len + 1) * 2));
+ s->object.synchronisation = 0;
+ mono_string_chars (s) [len] = 0;
+#else
s = (MonoString*)mono_object_allocate (sizeof (MonoString) + ((len + 1) * 2));
+#endif
if (!s)
G_BREAKPOINT ();