|
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();
|
@@ -734,7 +776,9 @@ mono_gc_make_descr_for_object (gsize *bitmap, int numbits, size_t obj_size)
|
734 | 776 | void*
|
735 | 777 | mono_gc_make_descr_for_array (int vector, gsize *elem_bitmap, int numbits, size_t elem_size)
|
736 | 778 | {
|
737 |
| - /* libgc has no usable support for arrays... */ |
| 779 | + /* libgc has no usable support for arrays... |
| 780 | + * but Unity added support with newer bdwgc |
| 781 | + * we don't need descriptor though, as arrays have custom mark proc */ |
738 | 782 | return GC_NO_DESCRIPTOR;
|
739 | 783 | }
|
740 | 784 |
|
@@ -833,8 +877,11 @@ mono_gc_alloc_vector (MonoVTable *vtable, size_t size, uintptr_t max_length)
|
833 | 877 | obj->obj.synchronisation = NULL;
|
834 | 878 |
|
835 | 879 | memset (mono_object_get_data ((MonoObject*)obj), 0, size - MONO_ABI_SIZEOF (MonoObject));
|
836 |
| - } else if (vtable->gc_descr != GC_NO_DESCRIPTOR) { |
837 |
| - obj = (MonoArray *)GC_GCJ_MALLOC (size, vtable); |
| 880 | + } else if (vtable->klass->element_class->valuetype && |
| 881 | + vtable->klass->element_class->gc_descr != GC_NO_DESCRIPTOR && |
| 882 | + vtable->domain == mono_get_root_domain () /* && |
| 883 | + max_length > 50 */) { |
| 884 | + obj = (MonoArray *)GC_gcj_vector_malloc (size, vtable); |
838 | 885 | if (G_UNLIKELY (!obj))
|
839 | 886 | return NULL;
|
840 | 887 | } else {
|
|
0 commit comments