]> git.proxmox.com Git - qemu.git/commitdiff
PPC: Introduce an alias cache for faster lookups
authorAlexander Graf <agraf@suse.de>
Sat, 22 Jun 2013 01:53:35 +0000 (03:53 +0200)
committerAlexander Graf <agraf@suse.de>
Sun, 30 Jun 2013 23:11:17 +0000 (01:11 +0200)
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 <agraf@suse.de>
target-ppc/cpu-models.c
target-ppc/cpu-models.h
target-ppc/translate_init.c

index 17f56b7504ea96515007f4a8832beaf75c15ef84..9bb68c8191cd5328114bc54c5caf88aad21189ef 100644 (file)
 /***************************************************************************/
 /* PowerPC CPU aliases                                                     */
 
-const PowerPCCPUAlias ppc_cpu_aliases[] = {
+PowerPCCPUAlias ppc_cpu_aliases[] = {
     { "403", "403GC" },
     { "405", "405D4" },
     { "405CR", "405CRc" },
index a94f83512110c87dcc2a6c4da332a4bd01f47b2d..ae8f7c743e28a5e02bf61e50bcfe49dd40f5073b 100644 (file)
 typedef struct PowerPCCPUAlias {
     const char *alias;
     const char *model;
+    ObjectClass *oc;
 } PowerPCCPUAlias;
 
-extern const PowerPCCPUAlias ppc_cpu_aliases[];
+extern PowerPCCPUAlias ppc_cpu_aliases[];
 
 /*****************************************************************************/
 /* PVR definitions for most known PowerPC                                    */
index f01e9e7d91e750bf7b58883e9ee930e3ac36d9d8..937390a9676af4cc03201776119a07f335dfd807 100644 (file)
@@ -7934,6 +7934,28 @@ static gint ppc_cpu_compare_class_name(gconstpointer a, gconstpointer b)
 
 #include <ctype.h>
 
+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->oc) {
+        alias->oc = ppc_cpu_class_by_name(alias->model);
+        if (!alias->oc) {
+            /* Fast check for non-existing aliases */
+            alias->oc = invalid_class;
+        }
+    }
+
+    if (alias->oc == invalid_class) {
+        return NULL;
+    } else {
+        return alias->oc;
+    }
+}
+
 static ObjectClass *ppc_cpu_class_by_name(const char *name)
 {
     GSList *list, *item;
@@ -7961,7 +7983,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]);
         }
     }
 
@@ -8051,8 +8073,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;
@@ -8119,12 +8141,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;
         }