diff options
-rw-r--r-- | include/qom/object.h | 5 | ||||
-rw-r--r-- | qom/object.c | 36 |
2 files changed, 38 insertions, 3 deletions
diff --git a/include/qom/object.h b/include/qom/object.h index 32524d72cc..405a2c67b0 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -691,6 +691,7 @@ struct Object .parent = TYPE_##PARENT_MODULE_OBJ_NAME, \ .name = TYPE_##MODULE_OBJ_NAME, \ .instance_size = sizeof(ModuleObjName), \ + .instance_align = __alignof__(ModuleObjName), \ .instance_init = module_obj_name##_init, \ .instance_finalize = module_obj_name##_finalize, \ .class_size = sizeof(ModuleObjName##Class), \ @@ -770,6 +771,9 @@ struct Object * @instance_size: The size of the object (derivative of #Object). If * @instance_size is 0, then the size of the object will be the size of the * parent object. + * @instance_align: The required alignment of the object. If @instance_align + * is 0, then normal malloc alignment is sufficient; if non-zero, then we + * must use qemu_memalign for allocation. * @instance_init: This function is called to initialize an object. The parent * class will have already been initialized so the type is only responsible * for initializing its own members. @@ -807,6 +811,7 @@ struct TypeInfo const char *parent; size_t instance_size; + size_t instance_align; void (*instance_init)(Object *obj); void (*instance_post_init)(Object *obj); void (*instance_finalize)(Object *obj); 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; } |