Merge pull request #2200 from xmcclure/image-audit-oops
[mono.git] / mono / metadata / sgen-toggleref.c
index cd53191df22e3b6d2309209f87e5c3ec0ac2d875..9622c7599dd75da07b8c5e65794f240bbaf00923 100644 (file)
@@ -1,45 +1,39 @@
 /*
- *
  * sgen-toggleref.c: toggleref support for sgen
  *
- * Copyright 2011 Xamarin, Inc.
- *
  * Author:
  *  Rodrigo Kumpera (kumpera@gmail.com)
- * 
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Copyright 2011 Xamarin, Inc.
+ * Copyright (C) 2012 Xamarin Inc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License 2.0 as published by the Free Software Foundation;
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License 2.0 along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-
 #include "config.h"
 
 #ifdef HAVE_SGEN_GC
 
-#include "sgen-gc.h"
+#include "sgen/sgen-gc.h"
 #include "sgen-toggleref.h"
+#include "sgen/sgen-client.h"
 
 
 /*only one of the two can be non null at a given time*/
 typedef struct {
-       void *strong_ref;
-       void *weak_ref;
+       GCObject *strong_ref;
+       GCObject *weak_ref;
 } MonoGCToggleRef;
 
 static MonoToggleRefStatus (*toggleref_callback) (MonoObject *obj);
@@ -53,7 +47,7 @@ sgen_process_togglerefs (void)
        int i, w;
        int toggle_ref_counts [3] = { 0, 0, 0 };
 
-       DEBUG (4, fprintf (gc_debug_file, "Proccessing ToggleRefs %d\n", toggleref_array_size));
+       SGEN_LOG (4, "Proccessing ToggleRefs %d", toggleref_array_size);
 
        for (i = w = 0; i < toggleref_array_size; ++i) {
                int res;
@@ -90,41 +84,57 @@ sgen_process_togglerefs (void)
 
        toggleref_array_size = w;
 
-       DEBUG (4, fprintf (gc_debug_file, "Done Proccessing ToggleRefs dropped %d strong %d weak %d final size %d\n",
+       SGEN_LOG (4, "Done Proccessing ToggleRefs dropped %d strong %d weak %d final size %d",
                toggle_ref_counts [MONO_TOGGLE_REF_DROP],
                toggle_ref_counts [MONO_TOGGLE_REF_STRONG],
                toggle_ref_counts [MONO_TOGGLE_REF_WEAK],
-               w));
+               w);
 }
 
-void
-sgen_scan_togglerefs (CopyOrMarkObjectFunc copy_func, char *start, char *end, SgenGrayQueue *queue)
+void sgen_client_mark_togglerefs (char *start, char *end, ScanCopyContext ctx)
 {
+       CopyOrMarkObjectFunc copy_func = ctx.ops->copy_or_mark_object;
+       SgenGrayQueue *queue = ctx.queue;
        int i;
 
-       DEBUG (4, fprintf (gc_debug_file, "Scanning ToggleRefs %d\n", toggleref_array_size));
+       SGEN_LOG (4, "Marking ToggleRefs %d", toggleref_array_size);
 
        for (i = 0; i < toggleref_array_size; ++i) {
                if (toggleref_array [i].strong_ref) {
-                       char *object = toggleref_array [i].strong_ref;
-                       if (object >= start && object < end) {
-                               DEBUG (6, fprintf (gc_debug_file, "\tcopying strong slot %d\n", i));
+                       GCObject *object = toggleref_array [i].strong_ref;
+                       if ((char*)object >= start && (char*)object < end) {
+                               SGEN_LOG (6, "\tcopying strong slot %d", i);
                                copy_func (&toggleref_array [i].strong_ref, queue);
                        }
-               } else if (toggleref_array [i].weak_ref) {
-                       char *object = toggleref_array [i].weak_ref;
+               }
+       }
+       sgen_drain_gray_stack (ctx);
+}
 
-                       if (object >= start && object < end) {
+void sgen_client_clear_togglerefs (char *start, char *end, ScanCopyContext ctx)
+{
+       CopyOrMarkObjectFunc copy_func = ctx.ops->copy_or_mark_object;
+       SgenGrayQueue *queue = ctx.queue;
+       int i;
+
+       SGEN_LOG (4, "Clearing ToggleRefs %d", toggleref_array_size);
+
+       for (i = 0; i < toggleref_array_size; ++i) {
+               if (toggleref_array [i].weak_ref) {
+                       GCObject *object = toggleref_array [i].weak_ref;
+
+                       if ((char*)object >= start && (char*)object < end) {
                                if (sgen_gc_is_object_ready_for_finalization (object)) {
-                                       DEBUG (6, fprintf (gc_debug_file, "\tcleaning weak slot %d\n", i));
+                                       SGEN_LOG (6, "\tcleaning weak slot %d", i);
                                        toggleref_array [i].weak_ref = NULL; /* We defer compaction to only happen on the callback step. */
                                } else {
-                                       DEBUG (6, fprintf (gc_debug_file, "\tkeeping weak slot %d\n", i));
+                                       SGEN_LOG (6, "\tkeeping weak slot %d", i);
                                        copy_func (&toggleref_array [i].weak_ref, queue);
                                }
                        }
                }
        }
+       sgen_drain_gray_stack (ctx);
 }
 
 static void
@@ -134,17 +144,19 @@ ensure_toggleref_capacity (int capacity)
                toggleref_array_capacity = 32;
                toggleref_array = sgen_alloc_internal_dynamic (
                        toggleref_array_capacity * sizeof (MonoGCToggleRef),
-                       INTERNAL_MEM_TOGGLEREF_DATA);   
+                       INTERNAL_MEM_TOGGLEREF_DATA,
+                       TRUE);
        }
        if (toggleref_array_size + capacity >= toggleref_array_capacity) {
                MonoGCToggleRef *tmp;
                int old_capacity = toggleref_array_capacity;
                while (toggleref_array_capacity < toggleref_array_size + capacity)
-                       toggleref_array_size *= 2;
+                       toggleref_array_capacity *= 2;
 
                tmp = sgen_alloc_internal_dynamic (
                        toggleref_array_capacity * sizeof (MonoGCToggleRef),
-                       INTERNAL_MEM_TOGGLEREF_DATA);
+                       INTERNAL_MEM_TOGGLEREF_DATA,
+                       TRUE);
 
                memcpy (tmp, toggleref_array, toggleref_array_size * sizeof (MonoGCToggleRef));
 
@@ -167,7 +179,7 @@ mono_gc_toggleref_add (MonoObject *object, mono_bool strong_ref)
        if (!toggleref_callback)
                return;
 
-       DEBUG (4, fprintf (gc_debug_file, "Adding toggleref %p %d\n", object, strong_ref));
+       SGEN_LOG (4, "Adding toggleref %p %d", object, strong_ref);
 
        sgen_gc_lock ();
 
@@ -194,4 +206,26 @@ mono_gc_toggleref_register_callback (MonoToggleRefStatus (*proccess_toggleref) (
        toggleref_callback = proccess_toggleref;
 }
 
+static MonoToggleRefStatus
+test_toggleref_callback (MonoObject *obj)
+{
+       static MonoClassField *mono_toggleref_test_field;
+       int status = MONO_TOGGLE_REF_DROP;
+
+       if (!mono_toggleref_test_field) {
+               mono_toggleref_test_field = mono_class_get_field_from_name (mono_object_get_class (obj), "__test");
+               g_assert (mono_toggleref_test_field);
+       }
+
+       mono_field_get_value (obj, mono_toggleref_test_field, &status);
+       printf ("toggleref-cb obj %d\n", status);
+       return status;
+}
+
+void
+sgen_register_test_toggleref_callback (void)
+{
+       toggleref_callback = test_toggleref_callback;
+}
+
 #endif