diff options
author | Dmitriy Ivanov <dimitry@google.com> | 2014-08-13 16:28:06 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-08-13 01:32:01 +0000 |
commit | db0785cbf9ee6cc0ace5c89496d7e9f12c288a83 (patch) | |
tree | 1bb60c12cee9972a1cc86cd3e43b63ad2d0dbc33 | |
parent | 6e3823d37e54929558990d7c475bc30d381098fe (diff) | |
parent | 042426ba6375f5c145379e598486ec6d675533c9 (diff) | |
download | android_bionic-db0785cbf9ee6cc0ace5c89496d7e9f12c288a83.tar.gz android_bionic-db0785cbf9ee6cc0ace5c89496d7e9f12c288a83.tar.bz2 android_bionic-db0785cbf9ee6cc0ace5c89496d7e9f12c288a83.zip |
Merge "Optimize symbol lookup"
-rw-r--r-- | linker/linked_list.h | 9 | ||||
-rw-r--r-- | linker/linker.cpp | 8 |
2 files changed, 17 insertions, 0 deletions
diff --git a/linker/linked_list.h b/linker/linked_list.h index 7f8c90160..8096e623d 100644 --- a/linker/linked_list.h +++ b/linker/linked_list.h @@ -100,6 +100,15 @@ class LinkedList { } } + bool contains(const T* el) { + for (LinkedListEntry<T>* e = head_; e != nullptr; e = e->next) { + if (e->element != nullptr && e->element == el) { + return true; + } + } + return false; + } + private: LinkedListEntry<T>* head_; LinkedListEntry<T>* tail_; diff --git a/linker/linker.cpp b/linker/linker.cpp index f8b35d7a8..77fb70c29 100644 --- a/linker/linker.cpp +++ b/linker/linker.cpp @@ -607,17 +607,24 @@ class SoinfoListAllocatorRW { // specified soinfo object and its dependencies in breadth first order. ElfW(Sym)* dlsym_handle_lookup(soinfo* si, soinfo** found, const char* name, soinfo* caller) { LinkedList<soinfo, SoinfoListAllocatorRW> visit_list; + LinkedList<soinfo, SoinfoListAllocatorRW> visited; visit_list.push_back(si); soinfo* current_soinfo; while ((current_soinfo = visit_list.pop_front()) != nullptr) { + if (visited.contains(current_soinfo)) { + continue; + } + ElfW(Sym)* result = soinfo_elf_lookup(current_soinfo, elfhash(name), name, caller == current_soinfo ? SymbolLookupScope::kAllowLocal : SymbolLookupScope::kExcludeLocal); if (result != nullptr) { *found = current_soinfo; visit_list.clear(); + visited.clear(); return result; } + visited.push_back(current_soinfo); current_soinfo->get_children().for_each([&](soinfo* child) { visit_list.push_back(child); @@ -625,6 +632,7 @@ ElfW(Sym)* dlsym_handle_lookup(soinfo* si, soinfo** found, const char* name, soi } visit_list.clear(); + visited.clear(); return nullptr; } |