diff options
author | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2018-04-04 12:13:05 +0200 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2018-04-04 12:13:05 +0200 |
commit | 9d8e8f445c1a021a1e381f4bd0bbc756b4258038 (patch) | |
tree | 9c525142c2dce2687d24bda075f470a82f245d44 /ld/deffilep.y | |
parent | 317ff0084bc68bfae2eabd82015e9239a68b5195 (diff) | |
download | gdb-9d8e8f445c1a021a1e381f4bd0bbc756b4258038.zip gdb-9d8e8f445c1a021a1e381f4bd0bbc756b4258038.tar.gz gdb-9d8e8f445c1a021a1e381f4bd0bbc756b4258038.tar.bz2 |
Speed up direct linking with DLLs on Windows (2/2).
This patch deals with the generation of the import library on the fly.
The implementation is inefficient because the linker makes a lot of
calls to realloc and memmove when importing the symbols in order to
maintain a sorted list of symbols.
This is fixable by relying on the fact that, for every linked DLL,
the list of symbols it exports is already sorted so you can import
them en masse once you have found the insertion point.
ld/
* deffile.h (def_file_add_import_from): Declare.
(def_file_add_import_at): Likewise.
* deffilep.y (fill_in_import): New function extracted from...
(def_file_add_import): ...here. Call it.
(def_file_add_import_from): New function.
(def_file_add_import_at): Likewise.
* pe-dll.c (pe_implied_import_dll): Use an optimized version of the
insertion loop for imported symbols if possible.
Diffstat (limited to 'ld/deffilep.y')
-rw-r--r-- | ld/deffilep.y | 100 |
1 files changed, 88 insertions, 12 deletions
diff --git a/ld/deffilep.y b/ld/deffilep.y index 1931c00..1aebdf6 100644 --- a/ld/deffilep.y +++ b/ld/deffilep.y @@ -816,6 +816,26 @@ find_import_in_list (def_file_import *b, int max, return l; } +static void +fill_in_import (def_file_import *i, + const char *name, + def_file_module *module, + int ordinal, + const char *internal_name, + const char *its_name) +{ + memset (i, 0, sizeof (def_file_import)); + if (name) + i->name = xstrdup (name); + i->module = module; + i->ordinal = ordinal; + if (internal_name) + i->internal_name = xstrdup (internal_name); + else + i->internal_name = i->name; + i->its_name = (its_name ? xstrdup (its_name) : NULL); +} + def_file_import * def_file_add_import (def_file *fdef, const char *name, @@ -850,18 +870,74 @@ def_file_add_import (def_file *fdef, } i = fdef->imports + pos; if (pos != fdef->num_imports) - memmove (&i[1], i, (sizeof (def_file_import) * (fdef->num_imports - pos))); - memset (i, 0, sizeof (def_file_import)); - if (name) - i->name = xstrdup (name); - if (module) - i->module = def_stash_module (fdef, module); - i->ordinal = ordinal; - if (internal_name) - i->internal_name = xstrdup (internal_name); - else - i->internal_name = i->name; - i->its_name = (its_name ? xstrdup (its_name) : NULL); + memmove (i + 1, i, sizeof (def_file_import) * (fdef->num_imports - pos)); + + fill_in_import (i, name, def_stash_module (fdef, module), ordinal, + internal_name, its_name); + fdef->num_imports++; + + return i; +} + +int +def_file_add_import_from (def_file *fdef, + int num_imports, + const char *name, + const char *module, + int ordinal, + const char *internal_name, + const char *its_name ATTRIBUTE_UNUSED) +{ + def_file_import *i; + int is_dup; + int pos; + int max_imports = ROUND_UP (fdef->num_imports, 16); + + /* We need to avoid here duplicates. */ + is_dup = 0; + pos = find_import_in_list (fdef->imports, fdef->num_imports, + name, internal_name ? internal_name : name, + module, ordinal, &is_dup); + if (is_dup != 0) + return -1; + if (fdef->imports && pos != fdef->num_imports) + { + i = fdef->imports + pos; + if (i->module && strcmp (i->module->name, module) == 0) + return -1; + } + + if (fdef->num_imports + num_imports - 1 >= max_imports) + { + max_imports = ROUND_UP (fdef->num_imports + num_imports, 16); + + if (fdef->imports) + fdef->imports = xrealloc (fdef->imports, + max_imports * sizeof (def_file_import)); + else + fdef->imports = xmalloc (max_imports * sizeof (def_file_import)); + } + i = fdef->imports + pos; + if (pos != fdef->num_imports) + memmove (i + num_imports, i, + sizeof (def_file_import) * (fdef->num_imports - pos)); + + return pos; +} + +def_file_import * +def_file_add_import_at (def_file *fdef, + int pos, + const char *name, + const char *module, + int ordinal, + const char *internal_name, + const char *its_name) +{ + def_file_import *i = fdef->imports + pos; + + fill_in_import (i, name, def_stash_module (fdef, module), ordinal, + internal_name, its_name); fdef->num_imports++; return i; |