[PATCH 10/12] [DbgHelp]: added helper to get global address out of symt, instead of going though symt_get_info

Eric Pouech eric.pouech at orange.fr
Tue Mar 8 14:31:38 CST 2011


(up to 15% speed increase of very large modules)

A+
---

 dlls/dbghelp/coff.c            |    7 ++--
 dlls/dbghelp/dbghelp_private.h |    2 +
 dlls/dbghelp/elf_module.c      |    4 +-
 dlls/dbghelp/macho_module.c    |    2 +
 dlls/dbghelp/symbol.c          |   37 ++++++++-----------
 dlls/dbghelp/type.c            |   80 +++++++++++++++++++++-------------------
 6 files changed, 65 insertions(+), 67 deletions(-)


diff --git a/dlls/dbghelp/coff.c b/dlls/dbghelp/coff.c
index 3a9f2a2..b0a085c 100644
--- a/dlls/dbghelp/coff.c
+++ b/dlls/dbghelp/coff.c
@@ -167,7 +167,7 @@ BOOL coff_process_info(const struct msc_debug_info* msc_dbg)
     const char*                         nampnt;
     int		       		        naux;
     BOOL                                ret = FALSE;
-    DWORD                               addr;
+    ULONG64                             addr;
 
     TRACE("Processing COFF symbols...\n");
 
@@ -399,7 +399,6 @@ BOOL coff_process_info(const struct msc_debug_info* msc_dbg)
         {
             if (coff_files.files[j].entries != NULL)
             {
-                symt_cmp_addr_module = msc_dbg->module;
                 qsort(coff_files.files[j].entries, coff_files.files[j].neps,
                       sizeof(struct symt*), symt_cmp_addr);
             }
@@ -424,7 +423,7 @@ BOOL coff_process_info(const struct msc_debug_info* msc_dbg)
                     for (;;)
                     {
                         if (l+1 >= coff_files.files[j].neps) break;
-                        symt_get_info(msc_dbg->module, coff_files.files[j].entries[l+1], TI_GET_ADDRESS, &addr);
+                        symt_get_address(coff_files.files[j].entries[l+1], &addr);
                         if (((msc_dbg->module->module.BaseOfImage + linepnt->Type.VirtualAddress) < addr))
                             break;
                         l++;
@@ -437,7 +436,7 @@ BOOL coff_process_info(const struct msc_debug_info* msc_dbg)
                          * start of the function, so we need to subtract that offset
                          * first.
                          */
-                        symt_get_info(msc_dbg->module, coff_files.files[j].entries[l+1], TI_GET_ADDRESS, &addr);
+                        symt_get_address(coff_files.files[j].entries[l+1], &addr);
                         symt_add_func_line(msc_dbg->module, (struct symt_function*)coff_files.files[j].entries[l+1], 
                                            coff_files.files[j].compiland->source, linepnt->Linenumber,
                                            msc_dbg->module->module.BaseOfImage + linepnt->Type.VirtualAddress - addr);
diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h
index e6ef594..7975379 100644
--- a/dlls/dbghelp/dbghelp_private.h
+++ b/dlls/dbghelp/dbghelp_private.h
@@ -619,7 +619,7 @@ extern DWORD64      sw_module_base(struct cpu_stack_walk* csw, DWORD64 addr);
 
 /* symbol.c */
 extern const char*  symt_get_name(const struct symt* sym);
-extern struct module* symt_cmp_addr_module;
+extern BOOL         symt_get_address(const struct symt* type, ULONG64* addr);
 extern int          symt_cmp_addr(const void* p1, const void* p2);
 extern void         copy_symbolW(SYMBOL_INFOW* siw, const SYMBOL_INFO* si);
 extern struct symt_ht*
diff --git a/dlls/dbghelp/elf_module.c b/dlls/dbghelp/elf_module.c
index de61fc1..c663455 100644
--- a/dlls/dbghelp/elf_module.c
+++ b/dlls/dbghelp/elf_module.c
@@ -732,7 +732,7 @@ static int elf_new_wine_thunks(struct module* module, const struct hash_table* h
             struct location loc;
 
             symt = symt_find_nearest(module, addr);
-            if (symt && !symt_get_info(module, &symt->symt, TI_GET_ADDRESS, &ref_addr))
+            if (symt && !symt_get_address(&symt->symt, &ref_addr))
                 ref_addr = addr;
             if (!symt || addr != ref_addr)
             {
@@ -772,7 +772,7 @@ static int elf_new_wine_thunks(struct module* module, const struct hash_table* h
                 ULONG64 xaddr = 0, xsize = 0;
                 DWORD   kind = -1;
 
-                symt_get_info(module, &symt->symt, TI_GET_ADDRESS,  &xaddr);
+                symt_get_address(&symt->symt, &xaddr);
                 symt_get_info(module, &symt->symt, TI_GET_LENGTH,   &xsize);
                 symt_get_info(module, &symt->symt, TI_GET_DATAKIND, &kind);
 
diff --git a/dlls/dbghelp/macho_module.c b/dlls/dbghelp/macho_module.c
index f45e63c..4d908a6 100644
--- a/dlls/dbghelp/macho_module.c
+++ b/dlls/dbghelp/macho_module.c
@@ -778,7 +778,7 @@ static void macho_finish_stabs(struct module* module, struct hash_table* ht_symt
 
             sym = symt_find_nearest(module, ste->addr);
             if (sym)
-                symt_get_info(module, &sym->symt, TI_GET_ADDRESS, &addr);
+                symt_get_address(&sym->symt, &addr);
             if (sym && ste->addr == addr)
             {
                 ULONG64 size = 0;
diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c
index 78b0b2c..64bc4eb 100644
--- a/dlls/dbghelp/symbol.c
+++ b/dlls/dbghelp/symbol.c
@@ -51,21 +51,18 @@ static inline int cmp_addr(ULONG64 a1, ULONG64 a2)
 static inline int cmp_sorttab_addr(struct module* module, int idx, ULONG64 addr)
 {
     ULONG64     ref;
-
-    symt_get_info(module, &module->addr_sorttab[idx]->symt, TI_GET_ADDRESS, &ref);
+    symt_get_address(&module->addr_sorttab[idx]->symt, &ref);
     return cmp_addr(ref, addr);
 }
 
-struct module*  symt_cmp_addr_module = NULL;
-
 int symt_cmp_addr(const void* p1, const void* p2)
 {
     const struct symt*  sym1 = *(const struct symt* const *)p1;
     const struct symt*  sym2 = *(const struct symt* const *)p2;
     ULONG64     a1, a2;
 
-    symt_get_info(symt_cmp_addr_module, sym1, TI_GET_ADDRESS, &a1);
-    symt_get_info(symt_cmp_addr_module, sym2, TI_GET_ADDRESS, &a2);
+    symt_get_address(sym1, &a1);
+    symt_get_address(sym2, &a2);
     return cmp_addr(a1, a2);
 }
 
@@ -131,7 +128,7 @@ static void symt_add_module_ht(struct module* module, struct symt_ht* ht)
     /* Don't store in sorttab a symbol without address, they are of
      * no use here (e.g. constant values)
      */
-    if (symt_get_info(module, &ht->symt, TI_GET_ADDRESS, &addr) &&
+    if (symt_get_address(&ht->symt, &addr) &&
         symt_grow_sorttab(module, module->num_symbols + 1))
     {
         module->addr_sorttab[module->num_symbols++] = ht;
@@ -746,7 +743,7 @@ static void symt_fill_sym_info(struct module_pair* pair,
                     sym_info->Flags |= SYMFLAG_TLSREL;
                     /* fall through */
                 case loc_absolute:
-                    symt_get_info(pair->effective, sym, TI_GET_ADDRESS, &sym_info->Address);
+                    symt_get_address(sym, &sym_info->Address);
                     sym_info->Register = 0;
                     break;
                 default:
@@ -779,18 +776,18 @@ static void symt_fill_sym_info(struct module_pair* pair,
         break;
     case SymTagPublicSymbol:
         sym_info->Flags |= SYMFLAG_EXPORT;
-        symt_get_info(pair->effective, sym, TI_GET_ADDRESS, &sym_info->Address);
+        symt_get_address(sym, &sym_info->Address);
         break;
     case SymTagFunction:
         sym_info->Flags |= SYMFLAG_FUNCTION;
-        symt_get_info(pair->effective, sym, TI_GET_ADDRESS, &sym_info->Address);
+        symt_get_address(sym, &sym_info->Address);
         break;
     case SymTagThunk:
         sym_info->Flags |= SYMFLAG_THUNK;
-        symt_get_info(pair->effective, sym, TI_GET_ADDRESS, &sym_info->Address);
+        symt_get_address(sym, &sym_info->Address);
         break;
     default:
-        symt_get_info(pair->effective, sym, TI_GET_ADDRESS, &sym_info->Address);
+        symt_get_address(sym, &sym_info->Address);
         sym_info->Register = 0;
         break;
     }
@@ -861,7 +858,7 @@ static inline unsigned where_to_insert(struct module* module, unsigned high, con
     ULONG64     addr;
 
     if (!high) return 0;
-    symt_get_info(module, &elt->symt, TI_GET_ADDRESS, &addr);
+    symt_get_address(&elt->symt, &addr);
     do
     {
         switch (cmp_sorttab_addr(module, mid, addr))
@@ -893,13 +890,12 @@ static BOOL resort_symbols(struct module* module)
 
         delta = module->num_symbols - module->num_sorttab;
         memcpy(tmp, &module->addr_sorttab[module->num_sorttab], delta * sizeof(struct symt_ht*));
-        symt_cmp_addr_module = module;
         qsort(tmp, delta, sizeof(struct symt_ht*), symt_cmp_addr);
 
         for (i = delta - 1; i >= 0; i--)
         {
             prev_ins_idx = ins_idx;
-            ins_idx = where_to_insert(module, prev_ins_idx = ins_idx, tmp[i]);
+            ins_idx = where_to_insert(module, ins_idx, tmp[i]);
             memmove(&module->addr_sorttab[ins_idx + i + 1],
                     &module->addr_sorttab[ins_idx],
                     (prev_ins_idx - ins_idx) * sizeof(struct symt_ht*));
@@ -908,7 +904,6 @@ static BOOL resort_symbols(struct module* module)
     }
     else
     {
-        symt_cmp_addr_module = module;
         qsort(module->addr_sorttab, module->num_symbols, sizeof(struct symt_ht*), symt_cmp_addr);
     }
     module->num_sorttab = module->num_symbols;
@@ -944,11 +939,11 @@ struct symt_ht* symt_find_nearest(struct module* module, DWORD_PTR addr)
     low = 0;
     high = module->num_sorttab;
 
-    symt_get_info(module, &module->addr_sorttab[0]->symt, TI_GET_ADDRESS, &ref_addr);
+    symt_get_address(&module->addr_sorttab[0]->symt, &ref_addr);
     if (addr < ref_addr) return NULL;
     if (high)
     {
-        symt_get_info(module, &module->addr_sorttab[high - 1]->symt, TI_GET_ADDRESS, &ref_addr);
+        symt_get_address(&module->addr_sorttab[high - 1]->symt, &ref_addr);
         symt_get_length(module, &module->addr_sorttab[high - 1]->symt, &ref_size);
         if (addr >= ref_addr + ref_size) return NULL;
     }
@@ -969,8 +964,8 @@ struct symt_ht* symt_find_nearest(struct module* module, DWORD_PTR addr)
      * might also have the same address, but would get better information
      */
     if (module->addr_sorttab[low]->symt.tag == SymTagPublicSymbol)
-    {   
-        symt_get_info(module, &module->addr_sorttab[low]->symt, TI_GET_ADDRESS, &ref_addr);
+    {
+        symt_get_address(&module->addr_sorttab[low]->symt, &ref_addr);
         if (low > 0 &&
             module->addr_sorttab[low - 1]->symt.tag != SymTagPublicSymbol &&
             !cmp_sorttab_addr(module, low - 1, ref_addr))
@@ -981,7 +976,7 @@ struct symt_ht* symt_find_nearest(struct module* module, DWORD_PTR addr)
             low++;
     }
     /* finally check that we fit into the found symbol */
-    symt_get_info(module, &module->addr_sorttab[low]->symt, TI_GET_ADDRESS, &ref_addr);
+    symt_get_address(&module->addr_sorttab[low]->symt, &ref_addr);
     if (addr < ref_addr) return NULL;
     symt_get_length(module, &module->addr_sorttab[low]->symt, &ref_size);
     if (addr >= ref_addr + ref_size) return NULL;
diff --git a/dlls/dbghelp/type.c b/dlls/dbghelp/type.c
index 9715436..42696f5 100644
--- a/dlls/dbghelp/type.c
+++ b/dlls/dbghelp/type.c
@@ -102,6 +102,47 @@ const char* symt_get_name(const struct symt* sym)
     }
 }
 
+BOOL symt_get_address(const struct symt* type, ULONG64* addr)
+{
+    switch (type->tag)
+    {
+    case SymTagData:
+        switch (((const struct symt_data*)type)->kind)
+        {
+        case DataIsGlobal:
+        case DataIsFileStatic:
+            *addr = ((const struct symt_data*)type)->u.var.offset;
+            break;
+        default: return FALSE;
+        }
+        break;
+    case SymTagFunction:
+        *addr = ((const struct symt_function*)type)->address;
+        break;
+    case SymTagPublicSymbol:
+        *addr = ((const struct symt_public*)type)->address;
+        break;
+    case SymTagFuncDebugStart:
+    case SymTagFuncDebugEnd:
+    case SymTagLabel:
+        if (!((const struct symt_hierarchy_point*)type)->parent ||
+            !symt_get_address(((const struct symt_hierarchy_point*)type)->parent, addr))
+            return FALSE;
+        *addr += ((const struct symt_hierarchy_point*)type)->loc.offset;
+        break;
+    case SymTagThunk:
+        *addr = ((const struct symt_thunk*)type)->address;
+        break;
+    case SymTagCompiland:
+        *addr = ((const struct symt_compiland*)type)->address;
+        break;
+    default:
+        FIXME("Unsupported sym-tag %s for get-address\n", symt_get_tag_str(type->tag));
+        return FALSE;
+    }
+    return TRUE;
+}
+
 static struct symt* symt_find_type_by_name(const struct module* module,
                                            enum SymTagEnum sym_tag, 
                                            const char* typename)
@@ -517,44 +558,7 @@ BOOL symt_get_info(struct module* module, const struct symt* type,
         break;
 
     case TI_GET_ADDRESS:
-        switch (type->tag)
-        {
-        case SymTagData:
-            switch (((const struct symt_data*)type)->kind)
-            {
-            case DataIsGlobal:
-            case DataIsFileStatic:
-                X(ULONG64) = ((const struct symt_data*)type)->u.var.offset;
-                break;
-            default: return FALSE;
-            }
-            break;
-        case SymTagFunction:
-            X(ULONG64) = ((const struct symt_function*)type)->address;
-            break;
-        case SymTagPublicSymbol:
-            X(ULONG64) = ((const struct symt_public*)type)->address;
-            break;
-        case SymTagFuncDebugStart:
-        case SymTagFuncDebugEnd:
-        case SymTagLabel:
-            if (!symt_get_info(module, ((const struct symt_hierarchy_point*)type)->parent,
-                               req, pInfo))
-                return FALSE;
-            X(ULONG64) += ((const struct symt_hierarchy_point*)type)->loc.offset;
-            break;
-        case SymTagThunk:
-            X(ULONG64) = ((const struct symt_thunk*)type)->address;
-            break;
-        case SymTagCompiland:
-            X(ULONG64) = ((const struct symt_compiland*)type)->address;
-            break;
-        default:
-            FIXME("Unsupported sym-tag %s for get-address\n", 
-                  symt_get_tag_str(type->tag));
-            return FALSE;
-        }
-        break;
+        return symt_get_address(type, (ULONG64*)pInfo);
 
     case TI_GET_BASETYPE:
         switch (type->tag)




More information about the wine-patches mailing list