#endif
#ifdef HEAVY_STATISTICS
-extern long long stat_objects_alloced_degraded;
-extern long long stat_bytes_alloced_degraded;
-extern long long stat_copy_object_called_major;
-extern long long stat_objects_copied_major;
+extern guint64 stat_objects_alloced_degraded;
+extern guint64 stat_bytes_alloced_degraded;
+extern guint64 stat_copy_object_called_major;
+extern guint64 stat_objects_copied_major;
#endif
#define SGEN_ASSERT(level, a, ...) do { \
mword desc;
} GCVTable;
-/* these bits are set in the object vtable: we could merge them since an object can be
- * either pinned or forwarded but not both.
- * We store them in the vtable slot because the bits are used in the sync block for
- * other purposes: if we merge them and alloc the sync blocks aligned to 8 bytes, we can change
+/*
+ * We use the lowest three bits in the vtable pointer of objects to tag whether they're
+ * forwarded, pinned, and/or cemented. These are the valid states:
+ *
+ * | State | bits |
+ * |------------------+------+
+ * | default | 000 |
+ * | forwarded | 001 |
+ * | pinned | 010 |
+ * | pinned, cemented | 110 |
+ *
+ * We store them in the vtable slot because the bits are used in the sync block for other
+ * purposes: if we merge them and alloc the sync blocks aligned to 8 bytes, we can change
* this and use bit 3 in the syncblock (with the lower two bits both set for forwarded, that
* would be an invalid combination for the monitor and hash code).
- * The values are already shifted.
- * The forwarding address is stored in the sync block.
*/
-#define SGEN_VTABLE_BITS_MASK 0x7
-
#include "sgen-tagged-pointer.h"
+#define SGEN_VTABLE_BITS_MASK SGEN_TAGGED_POINTER_MASK
+
#define SGEN_POINTER_IS_TAGGED_FORWARDED(p) SGEN_POINTER_IS_TAGGED_1((p))
-#define SGEN_POINTER_TAG_FORWARDED(p) SGEN_POINTER_TAG_1((p))
+#define SGEN_POINTER_TAG_FORWARDED(p) SGEN_POINTER_TAG_1((p))
#define SGEN_POINTER_IS_TAGGED_PINNED(p) SGEN_POINTER_IS_TAGGED_2((p))
-#define SGEN_POINTER_TAG_PINNED(p) SGEN_POINTER_TAG_2((p))
+#define SGEN_POINTER_TAG_PINNED(p) SGEN_POINTER_TAG_2((p))
#define SGEN_POINTER_IS_TAGGED_CEMENTED(p) SGEN_POINTER_IS_TAGGED_4((p))
-#define SGEN_POINTER_TAG_CEMENTED(p) SGEN_POINTER_TAG_4((p))
+#define SGEN_POINTER_TAG_CEMENTED(p) SGEN_POINTER_TAG_4((p))
-#define SGEN_POINTER_UNTAG_VTABLE(p) SGEN_POINTER_UNTAG_ALL((p))
+#define SGEN_POINTER_UNTAG_VTABLE(p) SGEN_POINTER_UNTAG_ALL((p))
/* returns NULL if not forwarded, or the forwarded address */
#define SGEN_VTABLE_IS_FORWARDED(vtable) (SGEN_POINTER_IS_TAGGED_FORWARDED ((vtable)) ? SGEN_POINTER_UNTAG_VTABLE ((vtable)) : NULL)
} while (0)
/* Unpins and uncements */
#define SGEN_UNPIN_OBJECT(obj) do { \
- *(void**)(obj) = SGEN_POINTER_UNTAG_24 (*(void**)(obj)); \
+ *(void**)(obj) = SGEN_POINTER_UNTAG_VTABLE (*(void**)(obj)); \
} while (0)
/*
* mono_array_length_fast not using the object's vtable.
*/
if (klass == mono_defaults.string_class) {
- return offsetof (MonoString, chars) + 2 * mono_string_length_fast ((MonoString*) o) + 2;
+ return G_STRUCT_OFFSET (MonoString, chars) + 2 * mono_string_length_fast ((MonoString*) o) + 2;
} else if (klass->rank) {
MonoArray *array = (MonoArray*)o;
size_t size = sizeof (MonoArray) + klass->sizes.element_size * mono_array_length_fast (array);
sgen_obj_get_descriptor (char *obj)
{
MonoVTable *vtable = ((MonoObject*)obj)->vtable;
- SGEN_ASSERT (0, !SGEN_POINTER_IS_TAGGED_ANY (vtable), "Object can't be tagged");
+ SGEN_ASSERT (9, !SGEN_POINTER_IS_TAGGED_ANY (vtable), "Object can't be tagged");
return sgen_vtable_get_descriptor (vtable);
}
* vtable field, is not intact. This is necessary for the parallel
* collector.
*/
-static inline mword
+static MONO_NEVER_INLINE mword
sgen_par_object_get_size (MonoVTable *vtable, MonoObject* o)
{
mword descr = (mword)vtable->gc_descr;
- mword type = descr & 0x7;
+ mword type = descr & DESC_TYPE_MASK;
- if (type == DESC_TYPE_RUN_LENGTH || type == DESC_TYPE_SMALL_BITMAP) {
+ if (type == DESC_TYPE_RUN_LENGTH || type == DESC_TYPE_SMALL_PTRFREE) {
mword size = descr & 0xfff8;
- if (size == 0) /* This is used to encode a string */
- return offsetof (MonoString, chars) + 2 * mono_string_length_fast ((MonoString*) o) + 2;
+ SGEN_ASSERT (9, size >= sizeof (MonoObject), "Run length object size to small");
return size;
+ } else if (descr == SGEN_DESC_STRING) {
+ return G_STRUCT_OFFSET (MonoString, chars) + 2 * mono_string_length_fast ((MonoString*) o) + 2;
} else if (type == DESC_TYPE_VECTOR) {
int element_size = ((descr) >> VECTOR_ELSIZE_SHIFT) & MAX_ELEMENT_SIZE;
MonoArray *array = (MonoArray*)o;
char* canary_ptr = (char*) (addr) + sgen_safe_object_get_size_unaligned ((MonoObject *) (addr)); \
if (!CANARY_VALID(canary_ptr)) { \
char canary_copy[CANARY_SIZE +1]; \
- strncpy (canary_copy, canary_ptr, 8); \
+ strncpy (canary_copy, canary_ptr, CANARY_SIZE); \
canary_copy[CANARY_SIZE] = 0; \
g_error ("CORRUPT CANARY:\naddr->%p\ntype->%s\nexcepted->'%s'\nfound->'%s'\n", (char*) addr, ((MonoObject*)addr)->vtable->klass->name, CANARY_STRING, canary_copy); \
} }