Procházet zdrojové kódy

Tue Aug 20 15:42:15 CEST 2002 Paolo Molaro <[email protected]>

	* appdomain.h, gc.c: added mono_domain_finalize ().

svn path=/trunk/mono/; revision=6807
Paolo Molaro před 23 roky
rodič
revize
d945b27f76
3 změnil soubory, kde provedl 93 přidání a 2 odebrání
  1. 5 0
      mono/metadata/ChangeLog
  2. 3 0
      mono/metadata/appdomain.h
  3. 85 2
      mono/metadata/gc.c

+ 5 - 0
mono/metadata/ChangeLog

@@ -1,3 +1,8 @@
+
+Tue Aug 20 15:42:15 CEST 2002 Paolo Molaro <[email protected]>
+
+	* appdomain.h, gc.c: added mono_domain_finalize ().
+
 2002-08-20  Gonzalo Paniagua Javier <[email protected]>
 
 	* object.c:

+ 3 - 0
mono/metadata/appdomain.h

@@ -116,6 +116,9 @@ mono_domain_set            (MonoDomain *domain);
 MonoAssembly *
 mono_domain_assembly_open  (MonoDomain *domain, const char *name);
 
+void
+mono_domain_finalize       (MonoDomain *domain);
+
 void
 mono_domain_unload         (MonoDomain *domain, gboolean force);
 

+ 85 - 2
mono/metadata/gc.c

@@ -12,6 +12,7 @@
 
 #include <mono/metadata/gc.h>
 #include <mono/metadata/threads.h>
+#include <mono/metadata/tabledefs.h>
 #if HAVE_BOEHM_GC
 #define GC_I_HIDE_POINTERS
 #include <gc/gc.h>
@@ -44,8 +45,8 @@ run_finalize (void *obj, void *data)
 			}
 		}
 	}
-	/* speedup later... */
-	/* g_print ("Finalize run on %s\n", mono_object_class (o)->name); */
+	/* speedup later... and use a timeout */
+	/*g_print ("Finalize run on %s\n", mono_object_class (o)->name);*/
 	mono_runtime_invoke (o->vtable->klass->vtable [finalize_slot], o, NULL, &exc);
 
 	if (exc) {
@@ -78,6 +79,88 @@ mono_object_register_finalizer (MonoObject *obj)
 	object_register_finalizer (obj, run_finalize);
 }
 
+/* 
+ * to speedup, at class init time, check if a class or struct
+ * have fields that need to be finalized and set a flag.
+ */
+static void
+finalize_fields (MonoClass *class, char *data, gboolean instance, GHashTable *todo) {
+	int i;
+	MonoClassField *field;
+	MonoObject *obj;
+
+	/*if (!instance)
+		g_print ("Finalize statics on on %s\n", class->name);*/
+	if (instance && class->valuetype)
+		data -= sizeof (MonoObject);
+	do {
+		for (i = 0; i < class->field.count; ++i) {
+			field = &class->fields [i];
+			if (instance) {
+				if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
+					continue;
+			} else {
+				if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC))
+					continue;
+			}
+			switch (field->type->type) {
+			case MONO_TYPE_OBJECT:
+			case MONO_TYPE_CLASS:
+				obj = *((MonoObject**)(data + field->offset));
+				if (obj) {
+					if (mono_object_class (obj)->has_finalize) {
+						/* disable the registered finalizer */
+						object_register_finalizer (obj, NULL);
+						run_finalize (obj, NULL);
+					} else {
+						/* 
+						 * if the type doesn't have a finalizer, we finalize 
+						 * the fields ourselves just like we do for structs.
+						 * Disabled for now: how do we handle loops?
+						 */
+						/*finalize_fields (mono_object_class (obj), obj, TRUE, todo);*/
+					}
+				}
+				break;
+			case MONO_TYPE_VALUETYPE: {
+				MonoClass *fclass = mono_class_from_mono_type (field->type);
+				if (fclass->enumtype)
+					continue;
+				/*finalize_fields (fclass, data + field->offset, TRUE, todo);*/
+				break;
+			}
+			case MONO_TYPE_ARRAY:
+			case MONO_TYPE_SZARRAY:
+				/* FIXME: foreach item... */
+				break;
+			}
+		}
+		if (!instance)
+			return;
+		class = class->parent;
+	} while (class);
+}
+
+static void
+finalize_static_data (MonoClass *class, MonoVTable *vtable, GHashTable *todo) {
+
+	if (class->enumtype || !vtable->data)
+		return;
+	finalize_fields (class, vtable->data, FALSE, todo);
+}
+
+void
+mono_domain_finalize (MonoDomain *domain) {
+
+	GHashTable *todo = g_hash_table_new (NULL, NULL);
+#if HAVE_BOEHM_GC
+	GC_gcollect ();
+#endif
+	mono_g_hash_table_foreach (domain->class_vtable_hash, (GHFunc)finalize_static_data, todo);
+	/* FIXME: finalize objects in todo... */
+	g_hash_table_destroy (todo);
+}
+
 void
 ves_icall_System_GC_InternalCollect (int generation)
 {