From patchwork Thu Nov 28 04:27:33 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Crosthwaite X-Patchwork-Id: 294766 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id DDF672C0077 for ; Thu, 28 Nov 2013 15:28:39 +1100 (EST) Received: from localhost ([::1]:39044 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VltDQ-00086z-2v for incoming@patchwork.ozlabs.org; Wed, 27 Nov 2013 23:28:36 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40536) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VltD4-00086t-Gz for qemu-devel@nongnu.org; Wed, 27 Nov 2013 23:28:20 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VltCy-00087g-C8 for qemu-devel@nongnu.org; Wed, 27 Nov 2013 23:28:14 -0500 Received: from mail-pd0-f175.google.com ([209.85.192.175]:55377) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VltCy-00086p-61 for qemu-devel@nongnu.org; Wed, 27 Nov 2013 23:28:08 -0500 Received: by mail-pd0-f175.google.com with SMTP id w10so11288654pde.34 for ; Wed, 27 Nov 2013 20:28:07 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id; bh=VL6ZdNH1jA8Ey5ftncSDDU//oWx1m1y6DfB9ko1ZxXg=; b=dfPGPnW5O1BHlCecrGommJqyCumiRxuNyK7ObFh94niJrvN0BxhHUiPhvQ3HaqrnE+ ulabKTuRzI5IaqsuA7ZN3dTIRD9EVD9xozyjx9R+dHqj3yhJAsXltGnibKZx57kMkYCE +w3bMPehLof8U5TVEjcMD/Ut2luUt5Ro6a+agUMzGmfkRiy0z769034+kkL34PRmu3UX 6etz1uZAepAbGumg08UHwP+uRQ5gCESusa/SdecDWPJj39uNYK13UGT93/8gV/58PZ6O d6x9k5lw+EjLMonizKp1Mtp4XZgozjwZYVP2dicfISs1x9lq2ucYtDm5phT2zAWtMkHb Ci3w== X-Gm-Message-State: ALoCoQn0UgGFhNkghL7zLKZNbpYsXm62MZkjSMv4xnsVpCu6mWkrZwst+lUix3BpVgKLhcIrZGeg X-Received: by 10.68.176.228 with SMTP id cl4mr108658pbc.196.1385612887216; Wed, 27 Nov 2013 20:28:07 -0800 (PST) Received: from localhost ([149.199.62.254]) by mx.google.com with ESMTPSA id ef10sm104019660pac.1.2013.11.27.20.28.05 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Wed, 27 Nov 2013 20:28:06 -0800 (PST) From: Peter Crosthwaite To: qemu-devel@nongnu.org, aliguori@us.ibm.com, pbonzini@redhat.com Date: Wed, 27 Nov 2013 20:27:33 -0800 Message-Id: <23ad4a5a9283ffcf4fc384832f369df46db18ef6.1385612379.git.peter.crosthwaite@xilinx.com> X-Mailer: git-send-email 1.8.4.4 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.85.192.175 Cc: afaerber@suse.de Subject: [Qemu-devel] [PATCH qom v1 1/1] qom/object.c: Split out object and class caches. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org The object-cast and class-cast caches cannot be shared because class caching is conditional on the target type not being an interface and object caching is unconditional. Leads to a bug when a class cast to an interface follows an object cast to the same interface type: FooObject = FOO(obj); FooClass = FOO_GET_CLASS(obj); Where TYPE_FOO is an interface. The first (object) cast will be successful and cache the casting result (i.e. TYPE_FOO will be cached). The second (class) cast will then check the shared cast cache and register a hit. The issue is, when a class cast hits in the cache it just returns a pointer cast of the input class (i.e. the concrete class). When casting to an interface, the cast itself must return the interface class, not the concrete class. The implementation of class cast caching already ensures that the returned cast result is only a pointer cast before caching. The object cast logic however does not have this check. Resolve by just splitting the object and class caches. Signed-off-by: Peter Crosthwaite Reviewed-by: Paolo Bonzini Tested-by: Nathan Rossi Reviewed-by: Edgar E. Iglesias --- include/qom/object.h | 3 ++- qom/object.c | 13 +++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/include/qom/object.h b/include/qom/object.h index a275db2..5f78847 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -358,7 +358,8 @@ struct ObjectClass Type type; GSList *interfaces; - const char *cast_cache[OBJECT_CLASS_CAST_CACHE]; + const char *object_cast_cache[OBJECT_CLASS_CAST_CACHE]; + const char *class_cast_cache[OBJECT_CLASS_CAST_CACHE]; ObjectUnparent *unparent; }; diff --git a/qom/object.c b/qom/object.c index fc19cf6..21b5a0b 100644 --- a/qom/object.c +++ b/qom/object.c @@ -458,7 +458,7 @@ Object *object_dynamic_cast_assert(Object *obj, const char *typename, Object *inst; for (i = 0; obj && i < OBJECT_CLASS_CAST_CACHE; i++) { - if (obj->class->cast_cache[i] == typename) { + if (obj->class->object_cast_cache[i] == typename) { goto out; } } @@ -475,9 +475,10 @@ Object *object_dynamic_cast_assert(Object *obj, const char *typename, if (obj && obj == inst) { for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) { - obj->class->cast_cache[i - 1] = obj->class->cast_cache[i]; + obj->class->object_cast_cache[i - 1] = + obj->class->object_cast_cache[i]; } - obj->class->cast_cache[i - 1] = typename; + obj->class->object_cast_cache[i - 1] = typename; } out: @@ -547,7 +548,7 @@ ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class, int i; for (i = 0; class && i < OBJECT_CLASS_CAST_CACHE; i++) { - if (class->cast_cache[i] == typename) { + if (class->class_cast_cache[i] == typename) { ret = class; goto out; } @@ -568,9 +569,9 @@ ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class, #ifdef CONFIG_QOM_CAST_DEBUG if (class && ret == class) { for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) { - class->cast_cache[i - 1] = class->cast_cache[i]; + class->class_cast_cache[i - 1] = class->class_cast_cache[i]; } - class->cast_cache[i - 1] = typename; + class->class_cast_cache[i - 1] = typename; } out: #endif