2 * sgen-copy-object.h: This is where objects are copied.
4 * Copyright 2001-2003 Ximian, Inc
5 * Copyright 2003-2010 Novell, Inc.
6 * Copyright (C) 2012 Xamarin Inc
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License 2.0 as published by the Free Software Foundation;
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License 2.0 along with this library; if not, write to the Free
19 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "mono/utils/mono-compiler.h"
24 extern guint64 stat_copy_object_called_nursery
;
25 extern guint64 stat_objects_copied_nursery
;
27 extern guint64 stat_nursery_copy_object_failed_from_space
;
28 extern guint64 stat_nursery_copy_object_failed_forwarded
;
29 extern guint64 stat_nursery_copy_object_failed_pinned
;
31 extern guint64 stat_slots_allocated_in_vain
;
34 * Copies an object and enqueues it if a queue is given.
36 * This function can be used even if the vtable of obj is not valid
37 * anymore, which is the case in the parallel collector.
39 static MONO_ALWAYS_INLINE
void
40 par_copy_object_no_checks (char *destination
, MonoVTable
*vt
, void *obj
, mword objsize
, SgenGrayQueue
*queue
)
42 SGEN_ASSERT (9, vt
->klass
->inited
, "vtable %p for class %s:%s was not initialized", vt
, vt
->klass
->name_space
, vt
->klass
->name
);
43 SGEN_LOG (9, " (to %p, %s size: %lu)", destination
, ((MonoObject
*)obj
)->vtable
->klass
->name
, (unsigned long)objsize
);
44 binary_protocol_copy (obj
, destination
, vt
, objsize
);
47 if (G_UNLIKELY (MONO_GC_OBJ_MOVED_ENABLED ())) {
48 int dest_gen
= sgen_ptr_in_nursery (destination
) ? GENERATION_NURSERY
: GENERATION_OLD
;
49 int src_gen
= sgen_ptr_in_nursery (obj
) ? GENERATION_NURSERY
: GENERATION_OLD
;
50 MONO_GC_OBJ_MOVED ((mword
)destination
, (mword
)obj
, dest_gen
, src_gen
, objsize
, vt
->klass
->name_space
, vt
->klass
->name
);
54 memcpy (destination
+ sizeof (mword
), (char*)obj
+ sizeof (mword
), objsize
- sizeof (mword
));
56 /* adjust array->bounds */
57 SGEN_ASSERT (9, vt
->gc_descr
, "vtable %p for class %s:%s has no gc descriptor", vt
, vt
->klass
->name_space
, vt
->klass
->name
);
59 if (G_UNLIKELY (vt
->rank
&& ((MonoArray
*)obj
)->bounds
)) {
60 MonoArray
*array
= (MonoArray
*)destination
;
61 array
->bounds
= (MonoArrayBounds
*)((char*)destination
+ ((char*)((MonoArray
*)obj
)->bounds
- (char*)obj
));
62 SGEN_LOG (9, "Array instance %p: size: %lu, rank: %d, length: %lu", array
, (unsigned long)objsize
, vt
->rank
, (unsigned long)mono_array_length (array
));
64 if (G_UNLIKELY (mono_profiler_events
& MONO_PROFILE_GC_MOVES
))
65 sgen_register_moved_object (obj
, destination
);
68 SGEN_LOG (9, "Enqueuing gray object %p (%s)", obj
, sgen_safe_name (obj
));
69 GRAY_OBJECT_ENQUEUE (queue
, obj
, sgen_vtable_get_descriptor (vt
));
74 * This can return OBJ itself on OOM.
76 static MONO_NEVER_INLINE
void*
77 copy_object_no_checks (void *obj
, SgenGrayQueue
*queue
)
79 MonoVTable
*vt
= ((MonoObject
*)obj
)->vtable
;
80 gboolean has_references
= SGEN_VTABLE_HAS_REFERENCES (vt
);
81 mword objsize
= SGEN_ALIGN_UP (sgen_par_object_get_size (vt
, (MonoObject
*)obj
));
82 /* FIXME: Does this not mark the newly allocated object? */
83 char *destination
= COLLECTOR_SERIAL_ALLOC_FOR_PROMOTION (vt
, obj
, objsize
, has_references
);
85 if (G_UNLIKELY (!destination
)) {
86 /* FIXME: Is this path ever tested? */
87 collector_pin_object (obj
, queue
);
88 sgen_set_pinned_from_failed_allocation (objsize
);
95 par_copy_object_no_checks (destination
, vt
, obj
, objsize
, queue
);
96 /* FIXME: mark mod union cards if necessary */
98 /* set the forwarding pointer */
99 SGEN_FORWARD_OBJECT (obj
, destination
);