dbghelp: Speed up source string creation (by using rb trees).
This commit is contained in:
parent
cbd5811e90
commit
c7c8c0dea7
@ -31,6 +31,7 @@
|
|||||||
#include "winnls.h"
|
#include "winnls.h"
|
||||||
#include "wine/list.h"
|
#include "wine/list.h"
|
||||||
#include "wine/unicode.h"
|
#include "wine/unicode.h"
|
||||||
|
#include "wine/rbtree.h"
|
||||||
|
|
||||||
#include "cvconst.h"
|
#include "cvconst.h"
|
||||||
|
|
||||||
@ -348,6 +349,7 @@ struct module_format
|
|||||||
} u;
|
} u;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern const struct wine_rb_functions source_rb_functions;
|
||||||
struct module
|
struct module
|
||||||
{
|
{
|
||||||
struct process* process;
|
struct process* process;
|
||||||
@ -382,6 +384,7 @@ struct module
|
|||||||
unsigned sources_used;
|
unsigned sources_used;
|
||||||
unsigned sources_alloc;
|
unsigned sources_alloc;
|
||||||
char* sources;
|
char* sources;
|
||||||
|
struct wine_rb_tree sources_offsets_tree;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct process
|
struct process
|
||||||
|
@ -189,6 +189,7 @@ struct module* module_new(struct process* pcs, const WCHAR* name,
|
|||||||
module->sources_used = 0;
|
module->sources_used = 0;
|
||||||
module->sources_alloc = 0;
|
module->sources_alloc = 0;
|
||||||
module->sources = 0;
|
module->sources = 0;
|
||||||
|
wine_rb_init(&module->sources_offsets_tree, &source_rb_functions);
|
||||||
|
|
||||||
return module;
|
return module;
|
||||||
}
|
}
|
||||||
@ -638,6 +639,7 @@ BOOL module_remove(struct process* pcs, struct module* module)
|
|||||||
}
|
}
|
||||||
hash_table_destroy(&module->ht_symbols);
|
hash_table_destroy(&module->ht_symbols);
|
||||||
hash_table_destroy(&module->ht_types);
|
hash_table_destroy(&module->ht_types);
|
||||||
|
wine_rb_destroy(&module->sources_offsets_tree, NULL, NULL);
|
||||||
HeapFree(GetProcessHeap(), 0, module->sources);
|
HeapFree(GetProcessHeap(), 0, module->sources);
|
||||||
HeapFree(GetProcessHeap(), 0, module->addr_sorttab);
|
HeapFree(GetProcessHeap(), 0, module->addr_sorttab);
|
||||||
pool_destroy(&module->pool);
|
pool_destroy(&module->pool);
|
||||||
|
@ -29,21 +29,55 @@
|
|||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
|
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
|
||||||
|
|
||||||
|
static struct module* rb_module;
|
||||||
|
struct source_rb
|
||||||
|
{
|
||||||
|
struct wine_rb_entry entry;
|
||||||
|
unsigned source;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void *source_rb_alloc(size_t size)
|
||||||
|
{
|
||||||
|
return HeapAlloc(GetProcessHeap(), 0, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *source_rb_realloc(void *ptr, size_t size)
|
||||||
|
{
|
||||||
|
return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void source_rb_free(void *ptr)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int source_rb_compare(const void *key, const struct wine_rb_entry *entry)
|
||||||
|
{
|
||||||
|
const struct source_rb *t = WINE_RB_ENTRY_VALUE(entry, const struct source_rb, entry);
|
||||||
|
|
||||||
|
return strcmp((const char*)key, rb_module->sources + t->source);
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct wine_rb_functions source_rb_functions =
|
||||||
|
{
|
||||||
|
source_rb_alloc,
|
||||||
|
source_rb_realloc,
|
||||||
|
source_rb_free,
|
||||||
|
source_rb_compare,
|
||||||
|
};
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* source_find
|
* source_find
|
||||||
*
|
*
|
||||||
* check whether a source file has already been stored
|
* check whether a source file has already been stored
|
||||||
*/
|
*/
|
||||||
static unsigned source_find(const struct module* module, const char* name)
|
static unsigned source_find(const char* name)
|
||||||
{
|
{
|
||||||
char* ptr = module->sources;
|
struct wine_rb_entry* e;
|
||||||
|
|
||||||
while (*ptr)
|
e = wine_rb_get(&rb_module->sources_offsets_tree, name);
|
||||||
{
|
if (!e) return -1;
|
||||||
if (strcmp(ptr, name) == 0) return ptr - module->sources;
|
return WINE_RB_ENTRY_VALUE(e, struct source_rb, entry)->source;
|
||||||
ptr += strlen(ptr) + 1;
|
|
||||||
}
|
|
||||||
return (unsigned)-1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
@ -71,10 +105,13 @@ unsigned source_new(struct module* module, const char* base, const char* name)
|
|||||||
if (tmp[bsz - 1] != '/') tmp[bsz++] = '/';
|
if (tmp[bsz - 1] != '/') tmp[bsz++] = '/';
|
||||||
strcpy(&tmp[bsz], name);
|
strcpy(&tmp[bsz], name);
|
||||||
}
|
}
|
||||||
if (!module->sources || (ret = source_find(module, full)) == (unsigned)-1)
|
rb_module = module;
|
||||||
|
if (!module->sources || (ret = source_find(full)) == (unsigned)-1)
|
||||||
{
|
{
|
||||||
char* new;
|
char* new;
|
||||||
int len = strlen(full) + 1;
|
int len = strlen(full) + 1;
|
||||||
|
struct source_rb* rb;
|
||||||
|
|
||||||
if (module->sources_used + len + 1 > module->sources_alloc)
|
if (module->sources_used + len + 1 > module->sources_alloc)
|
||||||
{
|
{
|
||||||
if (!module->sources)
|
if (!module->sources)
|
||||||
@ -96,6 +133,11 @@ unsigned source_new(struct module* module, const char* base, const char* name)
|
|||||||
memcpy(module->sources + module->sources_used, full, len);
|
memcpy(module->sources + module->sources_used, full, len);
|
||||||
module->sources_used += len;
|
module->sources_used += len;
|
||||||
module->sources[module->sources_used] = '\0';
|
module->sources[module->sources_used] = '\0';
|
||||||
|
if ((rb = pool_alloc(&module->pool, sizeof(*rb))))
|
||||||
|
{
|
||||||
|
rb->source = ret;
|
||||||
|
wine_rb_put(&module->sources_offsets_tree, full, &rb->entry);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
HeapFree(GetProcessHeap(), 0, tmp);
|
HeapFree(GetProcessHeap(), 0, tmp);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user