From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60803) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VrHhH-0002wR-Qm for qemu-devel@nongnu.org; Thu, 12 Dec 2013 20:37:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VrHhA-0007E9-M6 for qemu-devel@nongnu.org; Thu, 12 Dec 2013 20:37:43 -0500 Received: from mail-pb0-x235.google.com ([2607:f8b0:400e:c01::235]:46599) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VrHhA-0007E5-Ae for qemu-devel@nongnu.org; Thu, 12 Dec 2013 20:37:36 -0500 Received: by mail-pb0-f53.google.com with SMTP id ma3so1574824pbc.12 for ; Thu, 12 Dec 2013 17:37:32 -0800 (PST) Date: Fri, 13 Dec 2013 11:36:56 +1000 From: "Edgar E. Iglesias" Message-ID: <20131213013656.GA12096@edvb> References: <23ad4a5a9283ffcf4fc384832f369df46db18ef6.1385612379.git.peter.crosthwaite@xilinx.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <23ad4a5a9283ffcf4fc384832f369df46db18ef6.1385612379.git.peter.crosthwaite@xilinx.com> Subject: Re: [Qemu-devel] [PATCH qom v1 1/1] qom/object.c: Split out object and class caches. List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Peter Crosthwaite Cc: pbonzini@redhat.com, aliguori@us.ibm.com, qemu-devel@nongnu.org, afaerber@suse.de On Wed, Nov 27, 2013 at 08:27:33PM -0800, Peter Crosthwaite wrote: > 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: 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 > -- > 1.8.4.4 > >