#include <mono/metadata/class-internals.h>
#include <mono/metadata/method-builder.h>
#include <mono/metadata/opcodes.h>
+#include <mono/metadata/domain-internals.h>
+#include <mono/metadata/metadata-internals.h>
#include <mono/utils/mono-logger.h>
#include <mono/utils/mono-time.h>
#include <mono/utils/dtrace.h>
}
void
-mono_gc_weak_link_add (void **link_addr, MonoObject *obj)
+mono_gc_weak_link_add (void **link_addr, MonoObject *obj, gboolean track)
{
/* libgc requires that we use HIDE_POINTER... */
*link_addr = (void*)HIDE_POINTER (obj);
return GC_should_invoke_finalizers ();
}
+/*
+ * LOCKING: Assumes the domain_finalizers lock is held.
+ */
+static void
+add_weak_track_handle_internal (MonoDomain *domain, MonoObject *obj, guint32 gchandle)
+{
+ GSList *refs;
+
+ if (!domain->track_resurrection_objects_hash)
+ domain->track_resurrection_objects_hash = g_hash_table_new (mono_aligned_addr_hash, NULL);
+
+ refs = g_hash_table_lookup (domain->track_resurrection_objects_hash, obj);
+ refs = g_slist_prepend (refs, GUINT_TO_POINTER (gchandle));
+ g_hash_table_insert (domain->track_resurrection_objects_hash, obj, refs);
+}
+
+void
+mono_gc_add_weak_track_handle (MonoObject *obj, guint32 handle)
+{
+ MonoDomain *domain;
+
+ if (!obj)
+ return;
+
+ domain = mono_object_get_domain (obj);
+
+ mono_domain_finalizers_lock (domain);
+
+ add_weak_track_handle_internal (domain, obj, handle);
+
+ g_hash_table_insert (domain->track_resurrection_handles_hash, GUINT_TO_POINTER (handle), obj);
+
+ mono_domain_finalizers_unlock (domain);
+}
+
+/*
+ * LOCKING: Assumes the domain_finalizers lock is held.
+ */
+static void
+remove_weak_track_handle_internal (MonoDomain *domain, MonoObject *obj, guint32 gchandle)
+{
+ GSList *refs;
+
+ if (!domain->track_resurrection_objects_hash)
+ return;
+
+ refs = g_hash_table_lookup (domain->track_resurrection_objects_hash, obj);
+ refs = g_slist_remove (refs, GUINT_TO_POINTER (gchandle));
+ g_hash_table_insert (domain->track_resurrection_objects_hash, obj, refs);
+}
+
+void
+mono_gc_change_weak_track_handle (MonoObject *old_obj, MonoObject *obj, guint32 gchandle)
+{
+ MonoDomain *domain = mono_domain_get ();
+
+ mono_domain_finalizers_lock (domain);
+
+ if (old_obj)
+ remove_weak_track_handle_internal (domain, old_obj, gchandle);
+ if (obj)
+ add_weak_track_handle_internal (domain, obj, gchandle);
+
+ mono_domain_finalizers_unlock (domain);
+}
+
+void
+mono_gc_remove_weak_track_handle (guint32 gchandle)
+{
+ MonoDomain *domain = mono_domain_get ();
+ MonoObject *obj;
+
+ /* Clean our entries in the two hashes in MonoDomain */
+
+ mono_domain_finalizers_lock (domain);
+
+ /* Get the original object this handle pointed to */
+ obj = g_hash_table_lookup (domain->track_resurrection_handles_hash, GUINT_TO_POINTER (gchandle));
+ if (obj) {
+ g_hash_table_remove (domain->track_resurrection_handles_hash, GUINT_TO_POINTER (gchandle));
+
+ remove_weak_track_handle_internal (domain, obj, gchandle);
+ }
+
+ mono_domain_finalizers_unlock (domain);
+}
+
+GSList*
+mono_gc_remove_weak_track_object (MonoDomain *domain, MonoObject *obj)
+{
+ GSList *refs = NULL;
+
+ if (domain->track_resurrection_objects_hash) {
+ refs = g_hash_table_lookup (domain->track_resurrection_objects_hash, obj);
+
+ if (refs)
+ /*
+ * Since we don't run finalizers again for resurrected objects,
+ * no need to keep these around.
+ */
+ g_hash_table_remove (domain->track_resurrection_objects_hash, obj);
+ }
+
+ return refs;
+}
+
void
mono_gc_wbarrier_set_field (MonoObject *obj, gpointer field_ptr, MonoObject* value)
{
}
void
-mono_gc_wbarrier_arrayref_copy (MonoArray *arr, gpointer slot_ptr, int count)
+mono_gc_wbarrier_arrayref_copy (gpointer dest_ptr, gpointer src_ptr, int count)
{
- /* no need to do anything */
+ memmove (dest_ptr, src_ptr, count * sizeof (gpointer));
}
void
*(void**)ptr = value;
}
+void
+mono_gc_wbarrier_generic_nostore (gpointer ptr)
+{
+}
+
void
mono_gc_wbarrier_value_copy (gpointer dest, gpointer src, int count, MonoClass *klass)
{
+ memmove (dest, src, count * mono_class_value_size (klass, NULL));
}
void
-mono_gc_wbarrier_object (MonoObject *object)
+mono_gc_wbarrier_object_copy (MonoObject* obj, MonoObject *src)
{
+ /* do not copy the sync state */
+ memcpy ((char*)obj + sizeof (MonoObject), (char*)src + sizeof (MonoObject),
+ mono_object_class (obj)->instance_size - sizeof (MonoObject));
+}
+
+void
+mono_gc_clear_domain (MonoDomain *domain)
+{
+}
+
+int
+mono_gc_get_suspend_signal (void)
+{
+ return GC_get_suspend_signal ();
}
#if defined(USE_INCLUDED_LIBGC) && defined(USE_COMPILER_TLS) && defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
return mono_gc_get_managed_allocator_by_type (atype);
}
+MonoMethod*
+mono_gc_get_managed_array_allocator (MonoVTable *vtable, int rank)
+{
+ return NULL;
+}
+
/**
* mono_gc_get_managed_allocator_id:
*
return NULL;
}
+MonoMethod*
+mono_gc_get_managed_array_allocator (MonoVTable *vtable, int rank)
+{
+ return NULL;
+}
+
int
mono_gc_get_managed_allocator_type (MonoMethod *managed_alloc)
{