+static void
+sgen_card_table_wbarrier_set_field (MonoObject *obj, gpointer field_ptr, MonoObject* value)
+{
+ *(void**)field_ptr = value;
+ if (sgen_ptr_in_nursery (value))
+ sgen_card_table_mark_address ((mword)field_ptr);
+ sgen_dummy_use (value);
+}
+
+static void
+sgen_card_table_wbarrier_set_arrayref (MonoArray *arr, gpointer slot_ptr, MonoObject* value)
+{
+ *(void**)slot_ptr = value;
+ if (sgen_ptr_in_nursery (value))
+ sgen_card_table_mark_address ((mword)slot_ptr);
+ sgen_dummy_use (value);
+}
+
+static void
+sgen_card_table_wbarrier_arrayref_copy (gpointer dest_ptr, gpointer src_ptr, int count)
+{
+ gpointer *dest = dest_ptr;
+ gpointer *src = src_ptr;
+
+ /*overlapping that required backward copying*/
+ if (src < dest && (src + count) > dest) {
+ gpointer *start = dest;
+ dest += count - 1;
+ src += count - 1;
+
+ for (; dest >= start; --src, --dest) {
+ gpointer value = *src;
+ *dest = value;
+ if (sgen_ptr_in_nursery (value))
+ sgen_card_table_mark_address ((mword)dest);
+ sgen_dummy_use (value);
+ }
+ } else {
+ gpointer *end = dest + count;
+ for (; dest < end; ++src, ++dest) {
+ gpointer value = *src;
+ *dest = value;
+ if (sgen_ptr_in_nursery (value))
+ sgen_card_table_mark_address ((mword)dest);
+ sgen_dummy_use (value);
+ }
+ }
+}
+
+static void
+sgen_card_table_wbarrier_value_copy (gpointer dest, gpointer src, int count, MonoClass *klass)
+{
+ size_t element_size = mono_class_value_size (klass, NULL);
+ size_t size = count * element_size;
+
+#ifdef DISABLE_CRITICAL_REGION
+ LOCK_GC;
+#else
+ TLAB_ACCESS_INIT;
+ ENTER_CRITICAL_REGION;
+#endif
+ mono_gc_memmove (dest, src, size);
+ sgen_card_table_mark_range ((mword)dest, size);
+#ifdef DISABLE_CRITICAL_REGION
+ UNLOCK_GC;
+#else
+ EXIT_CRITICAL_REGION;
+#endif
+}
+
+static void
+sgen_card_table_wbarrier_object_copy (MonoObject* obj, MonoObject *src)
+{
+ int size = mono_object_class (obj)->instance_size;
+
+#ifdef DISABLE_CRITICAL_REGION
+ LOCK_GC;
+#else
+ TLAB_ACCESS_INIT;
+ ENTER_CRITICAL_REGION;
+#endif
+ mono_gc_memmove ((char*)obj + sizeof (MonoObject), (char*)src + sizeof (MonoObject),
+ size - sizeof (MonoObject));
+ sgen_card_table_mark_range ((mword)obj, size);
+#ifdef DISABLE_CRITICAL_REGION
+ UNLOCK_GC;
+#else
+ EXIT_CRITICAL_REGION;
+#endif
+}
+
+static void
+sgen_card_table_wbarrier_generic_nostore (gpointer ptr)
+{
+ sgen_card_table_mark_address ((mword)ptr);
+}
+