qom: allow turning cast debugging off

Cast debugging can have a substantial cost (20% or more).  Instead of adding
special-cased "fast casts" in the hot paths, we can just disable it in
releases.  The tracing facilities we just added make it easier to analyze
those problems that cast debugging would reveal.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-id: 1368188203-3407-7-git-send-email-pbonzini@redhat.com
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
Paolo Bonzini 2013-05-10 14:16:40 +02:00 committed by Anthony Liguori
parent fa131d94a5
commit 3556c233d9
3 changed files with 26 additions and 9 deletions

9
configure vendored
View File

@ -220,6 +220,7 @@ blobs="yes"
pkgversion="" pkgversion=""
pie="" pie=""
zero_malloc="" zero_malloc=""
qom_cast_debug="yes"
trace_backend="nop" trace_backend="nop"
trace_file="trace" trace_file="trace"
spice="" spice=""
@ -688,6 +689,10 @@ for opt do
;; ;;
--enable-sdl) sdl="yes" --enable-sdl) sdl="yes"
;; ;;
--disable-qom-cast-debug) qom_cast_debug="no"
;;
--enable-qom-cast-debug) qom_cast_debug="yes"
;;
--disable-virtfs) virtfs="no" --disable-virtfs) virtfs="no"
;; ;;
--enable-virtfs) virtfs="yes" --enable-virtfs) virtfs="yes"
@ -3575,6 +3580,7 @@ echo "gcov enabled $gcov"
echo "TPM support $tpm" echo "TPM support $tpm"
echo "libssh2 support $libssh2" echo "libssh2 support $libssh2"
echo "TPM passthrough $tpm_passthrough" echo "TPM passthrough $tpm_passthrough"
echo "QOM debugging $qom_cast_debug"
if test "$sdl_too_old" = "yes"; then if test "$sdl_too_old" = "yes"; then
echo "-> Your SDL version is too old - please upgrade to have SDL support" echo "-> Your SDL version is too old - please upgrade to have SDL support"
@ -3909,6 +3915,9 @@ echo "CONFIG_UNAME_RELEASE=\"$uname_release\"" >> $config_host_mak
if test "$zero_malloc" = "yes" ; then if test "$zero_malloc" = "yes" ; then
echo "CONFIG_ZERO_MALLOC=y" >> $config_host_mak echo "CONFIG_ZERO_MALLOC=y" >> $config_host_mak
fi fi
if test "$qom_cast_debug" = "yes" ; then
echo "CONFIG_QOM_CAST_DEBUG=y" >> $config_host_mak
fi
if test "$rbd" = "yes" ; then if test "$rbd" = "yes" ; then
echo "CONFIG_RBD=y" >> $config_host_mak echo "CONFIG_RBD=y" >> $config_host_mak
fi fi

View File

@ -615,8 +615,9 @@ Object *object_dynamic_cast(Object *obj, const char *typename);
* *
* See object_dynamic_cast() for a description of the parameters of this * See object_dynamic_cast() for a description of the parameters of this
* function. The only difference in behavior is that this function asserts * function. The only difference in behavior is that this function asserts
* instead of returning #NULL on failure. This function is not meant to be * instead of returning #NULL on failure if QOM cast debugging is enabled.
* called directly, but only through the wrapper macro OBJECT_CHECK. * This function is not meant to be called directly, but only through
* the wrapper macro OBJECT_CHECK.
*/ */
Object *object_dynamic_cast_assert(Object *obj, const char *typename, Object *object_dynamic_cast_assert(Object *obj, const char *typename,
const char *file, int line, const char *func); const char *file, int line, const char *func);
@ -666,9 +667,9 @@ Type type_register(const TypeInfo *info);
* *
* See object_class_dynamic_cast() for a description of the parameters * See object_class_dynamic_cast() for a description of the parameters
* of this function. The only difference in behavior is that this function * of this function. The only difference in behavior is that this function
* asserts instead of returning #NULL on failure. This function is not * asserts instead of returning #NULL on failure if QOM cast debugging is
* meant to be called directly, but only through the wrapper macros * enabled. This function is not meant to be called directly, but only through
* OBJECT_CLASS_CHECK and INTERFACE_CHECK. * the wrapper macros OBJECT_CLASS_CHECK and INTERFACE_CHECK.
*/ */
ObjectClass *object_class_dynamic_cast_assert(ObjectClass *klass, ObjectClass *object_class_dynamic_cast_assert(ObjectClass *klass,
const char *typename, const char *typename,

View File

@ -435,12 +435,11 @@ Object *object_dynamic_cast(Object *obj, const char *typename)
Object *object_dynamic_cast_assert(Object *obj, const char *typename, Object *object_dynamic_cast_assert(Object *obj, const char *typename,
const char *file, int line, const char *func) const char *file, int line, const char *func)
{ {
Object *inst;
trace_object_dynamic_cast_assert(obj ? obj->class->type->name : "(null)", trace_object_dynamic_cast_assert(obj ? obj->class->type->name : "(null)",
typename, file, line, func); typename, file, line, func);
inst = object_dynamic_cast(obj, typename); #ifdef CONFIG_QOM_CAST_DEBUG
Object *inst = object_dynamic_cast(obj, typename);
if (!inst && obj) { if (!inst && obj) {
fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n", fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n",
@ -448,7 +447,9 @@ Object *object_dynamic_cast_assert(Object *obj, const char *typename,
abort(); abort();
} }
return inst; assert(obj == inst);
#endif
return obj;
} }
ObjectClass *object_class_dynamic_cast(ObjectClass *class, ObjectClass *object_class_dynamic_cast(ObjectClass *class,
@ -509,6 +510,12 @@ ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
trace_object_class_dynamic_cast_assert(class ? class->type->name : "(null)", trace_object_class_dynamic_cast_assert(class ? class->type->name : "(null)",
typename, file, line, func); typename, file, line, func);
#ifndef CONFIG_QOM_CAST_DEBUG
if (!class->interfaces) {
return class;
}
#endif
ret = object_class_dynamic_cast(class, typename); ret = object_class_dynamic_cast(class, typename);
if (!ret && class) { if (!ret && class) {
fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n", fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n",