From patchwork Sat Jun 22 02:02:24 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 253331 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 164612C0409 for ; Sat, 22 Jun 2013 12:02:50 +1000 (EST) Received: from localhost ([::1]:42022 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UqDA7-0001RS-4g for incoming@patchwork.ozlabs.org; Fri, 21 Jun 2013 22:02:47 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55753) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UqD9q-0001RJ-5y for qemu-devel@nongnu.org; Fri, 21 Jun 2013 22:02:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UqD9m-0000Dw-Lg for qemu-devel@nongnu.org; Fri, 21 Jun 2013 22:02:30 -0400 Received: from cantor2.suse.de ([195.135.220.15]:36708 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UqD9m-0000De-CG; Fri, 21 Jun 2013 22:02:26 -0400 Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 49BF6A3DDF; Sat, 22 Jun 2013 04:02:25 +0200 (CEST) From: Alexander Graf To: qemu-ppc@nongnu.org Date: Sat, 22 Jun 2013 04:02:24 +0200 Message-Id: <1371866544-47302-1-git-send-email-agraf@suse.de> X-Mailer: git-send-email 1.8.1.4 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x X-Received-From: 195.135.220.15 Cc: qemu-devel@nongnu.org, =?UTF-8?q?Andreas=20F=C3=A4rber?= Subject: [Qemu-devel] [PATCH] PPC: Introduce an alias cache for faster lookups 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 When running QEMU with "-cpu ?" we walk through every alias for every target CPU we know about. This takes several seconds on my very fast host system. Let's introduce a class object cache in the alias table. Using that we don't have to go through the tedious work of finding our target class. Instead, we can just go directly from the alias name to the target class pointer. This patch brings -cpu "?" to reasonable times again. Before: real 0m4.716s After: real 0m0.025s Signed-off-by: Alexander Graf --- It would be even nicer if we could have the alias table parsed during compile time. Then instead of having { string alias, string base_model } we would simply get { string alias, Class *klass } in the .rodata section. But I can't really think of a clever way to do this. Especially since we want to have the ability to have aliases that don't ever match any implemented CPU. --- target-ppc/cpu-models.c | 2 +- target-ppc/cpu-models.h | 3 ++- target-ppc/translate_init.c | 32 +++++++++++++++++++++++++++----- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/target-ppc/cpu-models.c b/target-ppc/cpu-models.c index 17f56b7..9bb68c8 100644 --- a/target-ppc/cpu-models.c +++ b/target-ppc/cpu-models.c @@ -1227,7 +1227,7 @@ /***************************************************************************/ /* PowerPC CPU aliases */ -const PowerPCCPUAlias ppc_cpu_aliases[] = { +PowerPCCPUAlias ppc_cpu_aliases[] = { { "403", "403GC" }, { "405", "405D4" }, { "405CR", "405CRc" }, diff --git a/target-ppc/cpu-models.h b/target-ppc/cpu-models.h index a94f835..262ca47 100644 --- a/target-ppc/cpu-models.h +++ b/target-ppc/cpu-models.h @@ -31,9 +31,10 @@ typedef struct PowerPCCPUAlias { const char *alias; const char *model; + ObjectClass *klass; } PowerPCCPUAlias; -extern const PowerPCCPUAlias ppc_cpu_aliases[]; +extern PowerPCCPUAlias ppc_cpu_aliases[]; /*****************************************************************************/ /* PVR definitions for most known PowerPC */ diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index bf68d46..d8758d5 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -7936,6 +7936,28 @@ static gint ppc_cpu_compare_class_name(gconstpointer a, gconstpointer b) #include +static ObjectClass *ppc_cpu_class_by_name(const char *name); + +static ObjectClass *ppc_cpu_class_by_alias(PowerPCCPUAlias *alias) +{ + ObjectClass *invalid_class = (void*)ppc_cpu_class_by_alias; + + /* Cache target class lookups in the alias table */ + if (!alias->klass) { + alias->klass = ppc_cpu_class_by_name(alias->model); + if (!alias->klass) { + /* Fast check for non-existing aliases */ + alias->klass = invalid_class; + } + } + + if (alias->klass == invalid_class) { + return NULL; + } else { + return alias->klass; + } +} + static ObjectClass *ppc_cpu_class_by_name(const char *name) { GSList *list, *item; @@ -7963,7 +7985,7 @@ static ObjectClass *ppc_cpu_class_by_name(const char *name) for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) { if (strcmp(ppc_cpu_aliases[i].alias, name) == 0) { - return ppc_cpu_class_by_name(ppc_cpu_aliases[i].model); + return ppc_cpu_class_by_alias(&ppc_cpu_aliases[i]); } } @@ -8053,8 +8075,8 @@ static void ppc_cpu_list_entry(gpointer data, gpointer user_data) (*s->cpu_fprintf)(s->file, "PowerPC %-16s PVR %08x\n", name, pcc->pvr); for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) { - const PowerPCCPUAlias *alias = &ppc_cpu_aliases[i]; - ObjectClass *alias_oc = ppc_cpu_class_by_name(alias->model); + PowerPCCPUAlias *alias = &ppc_cpu_aliases[i]; + ObjectClass *alias_oc = ppc_cpu_class_by_alias(alias); if (alias_oc != oc) { continue; @@ -8121,12 +8143,12 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp) g_slist_free(list); for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) { - const PowerPCCPUAlias *alias = &ppc_cpu_aliases[i]; + PowerPCCPUAlias *alias = &ppc_cpu_aliases[i]; ObjectClass *oc; CpuDefinitionInfoList *entry; CpuDefinitionInfo *info; - oc = ppc_cpu_class_by_name(alias->model); + oc = ppc_cpu_class_by_alias(alias); if (oc == NULL) { continue; }