|
45 | 45 | #if HAVE_BOEHM_GC
|
46 | 46 |
|
47 | 47 | #define GC_dirty(x)
|
| 48 | +#include <private/gc_pmark.h> |
| 49 | +#include <gc_vector.h> |
48 | 50 |
|
49 | 51 | #if defined(HOST_DARWIN) && defined(HAVE_PTHREAD_GET_STACKADDR_NP)
|
50 | 52 | void *pthread_get_stackaddr_np(pthread_t);
|
@@ -112,6 +114,45 @@ static void on_gc_notification (GC_EventType event);
|
112 | 114 | // GC_word here to precisely match Boehm. Not size_t, not gsize.
|
113 | 115 | static void on_gc_heap_resize (GC_word new_size);
|
114 | 116 |
|
| 117 | +#define ELEMENT_CHUNK_SIZE 256 |
| 118 | +#define VECTOR_PROC_INDEX 6 |
| 119 | +static mse * GC_gcj_vector_proc (word * addr, mse * mark_stack_ptr, |
| 120 | + mse * mark_stack_limit, word env) |
| 121 | +{ |
| 122 | + MonoArray* a = NULL; |
| 123 | + if (env) |
| 124 | + { |
| 125 | + g_assert (env == 1); |
| 126 | + |
| 127 | + a = (MonoArray*)GC_base (addr); |
| 128 | + } else { |
| 129 | + g_assert (addr == GC_base (addr)); |
| 130 | + |
| 131 | + a = (MonoArray*)addr; |
| 132 | + } |
| 133 | + |
| 134 | + if (!a->max_length) |
| 135 | + return mark_stack_ptr; |
| 136 | + |
| 137 | + mono_array_size_t length = a->max_length; |
| 138 | + MonoClass* array_type = a->obj.vtable->klass; |
| 139 | + MonoClass *element_type = array_type->element_class; |
| 140 | + GC_descr element_desc = element_type->gc_descr; |
| 141 | + |
| 142 | + g_assert ((element_desc & GC_DS_TAGS) == GC_DS_BITMAP); |
| 143 | + g_assert (element_type->valuetype); |
| 144 | + |
| 145 | + int words_per_element = array_type->sizes.element_size / BYTES_PER_WORD; |
| 146 | + word *actual_start = (word *)a->vector; |
| 147 | + |
| 148 | + /* start at first element or resume from last iteration */ |
| 149 | + word *start = env ? addr : actual_start; |
| 150 | + /* end at last element or max chunk size */ |
| 151 | + word *actual_end = actual_start + length * words_per_element; |
| 152 | + |
| 153 | + return GC_gcj_vector_mark_proc (mark_stack_ptr, element_desc, start, actual_end, words_per_element); |
| 154 | +} |
| 155 | + |
115 | 156 | void
|
116 | 157 | mono_gc_base_init (void)
|
117 | 158 | {
|
@@ -163,6 +204,7 @@ mono_gc_base_init (void)
|
163 | 204 | GC_set_finalizer_notifier(mono_gc_finalize_notify);
|
164 | 205 |
|
165 | 206 | GC_init_gcj_malloc (5, NULL);
|
| 207 | + GC_init_gcj_vector (VECTOR_PROC_INDEX, GC_gcj_vector_proc); |
166 | 208 | GC_allow_register_threads ();
|
167 | 209 |
|
168 | 210 | params_opts = mono_gc_params_get();
|
@@ -722,7 +764,9 @@ mono_gc_make_descr_for_object (gsize *bitmap, int numbits, size_t obj_size)
|
722 | 764 | void*
|
723 | 765 | mono_gc_make_descr_for_array (int vector, gsize *elem_bitmap, int numbits, size_t elem_size)
|
724 | 766 | {
|
725 |
| - /* libgc has no usable support for arrays... */ |
| 767 | + /* libgc has no usable support for arrays... |
| 768 | + * but Unity added support with newer bdwgc |
| 769 | + * we don't need descriptor though, as arrays have custom mark proc */ |
726 | 770 | return GC_NO_DESCRIPTOR;
|
727 | 771 | }
|
728 | 772 |
|
@@ -821,8 +865,11 @@ mono_gc_alloc_vector (MonoVTable *vtable, size_t size, uintptr_t max_length)
|
821 | 865 | obj->obj.synchronisation = NULL;
|
822 | 866 |
|
823 | 867 | memset (mono_object_get_data ((MonoObject*)obj), 0, size - MONO_ABI_SIZEOF (MonoObject));
|
824 |
| - } else if (vtable->gc_descr != GC_NO_DESCRIPTOR) { |
825 |
| - obj = (MonoArray *)GC_GCJ_MALLOC (size, vtable); |
| 868 | + } else if (vtable->klass->element_class->valuetype && |
| 869 | + vtable->klass->element_class->gc_descr != GC_NO_DESCRIPTOR && |
| 870 | + vtable->domain == mono_get_root_domain () /* && |
| 871 | + max_length > 50 */) { |
| 872 | + obj = (MonoArray *)GC_gcj_vector_malloc (size, vtable); |
826 | 873 | if (G_UNLIKELY (!obj))
|
827 | 874 | return NULL;
|
828 | 875 | } else {
|
|
0 commit comments