aboutsummaryrefslogtreecommitdiff
path: root/qom
diff options
context:
space:
mode:
Diffstat (limited to 'qom')
-rw-r--r--qom/object.c36
1 files changed, 33 insertions, 3 deletions
diff --git a/qom/object.c b/qom/object.c
index cecad35b99..a91a6a515a 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -50,6 +50,7 @@ struct TypeImpl
size_t class_size;
size_t instance_size;
+ size_t instance_align;
void (*class_init)(ObjectClass *klass, void *data);
void (*class_base_init)(ObjectClass *klass, void *data);
@@ -114,6 +115,7 @@ static TypeImpl *type_new(const TypeInfo *info)
ti->class_size = info->class_size;
ti->instance_size = info->instance_size;
+ ti->instance_align = info->instance_align;
ti->class_init = info->class_init;
ti->class_base_init = info->class_base_init;
@@ -688,16 +690,44 @@ static void object_finalize(void *data)
}
}
+/* Find the minimum alignment guaranteed by the system malloc. */
+#if __STDC_VERSION__ >= 201112L
+typddef max_align_t qemu_max_align_t;
+#else
+typedef union {
+ long l;
+ void *p;
+ double d;
+ long double ld;
+} qemu_max_align_t;
+#endif
+
static Object *object_new_with_type(Type type)
{
Object *obj;
+ size_t size, align;
+ void (*obj_free)(void *);
g_assert(type != NULL);
type_initialize(type);
- obj = g_malloc(type->instance_size);
- object_initialize_with_type(obj, type->instance_size, type);
- obj->free = g_free;
+ size = type->instance_size;
+ align = type->instance_align;
+
+ /*
+ * Do not use qemu_memalign unless required. Depending on the
+ * implementation, extra alignment implies extra overhead.
+ */
+ if (likely(align <= __alignof__(qemu_max_align_t))) {
+ obj = g_malloc(size);
+ obj_free = g_free;
+ } else {
+ obj = qemu_memalign(align, size);
+ obj_free = qemu_vfree;
+ }
+
+ object_initialize_with_type(obj, size, type);
+ obj->free = obj_free;
return obj;
}