In the resolver, we maintain a list of undefined symbols, and when we visit an archive file, we check that file if undefined symbols can be resolved using files in the archive. The archive file class provides find() function to lookup a symbol. Previously, we call find() for each undefined symbols. Archive files may be visited multiple times if they are in a --start-group and --end-group. If we visit a file M times and if we have N undefined symbols, find() is called M*N times. I found that that is one of the most significant bottlenecks in LLD when linking a large executable. find() is not a very cheap operation because it looks up a hash table for a given string. And a string, or a symbol name, can be pretty long if you are dealing with C++ symbols. We can eliminate the bottleneck. Calling find() with the same symbol multiple times is a waste. If a result of looking up a symbol is "not found", it stays "not found" forever because the symbol simply doesn't exist in the archive. Thus, we should call find() only for newly-added undefined symbols. This optimization makes O(M*N) O(N). In this patch, all undefined symbols are added to a vector. For each archive/shared library file, we maintain a start position P. All symbols [0, P) are already searched. [P, end of the vector) are not searched yet. For each file, we scan the vector only once. This patch changes the order in which undefined symbols are looked for. Previously, we iterated over the result of _symbolTable.undefines(). Now we iterate over the new vector. This is a benign change but caused differences in output if remaining undefines exist. This is why some tests are updated. The performance improvement of this patch seems sometimes significant. Previously, linking chrome.dll on my workstation (Xeon 2.4GHz 8 cores) took about 70 seconds. Now it takes (only?) 30 seconds! http://reviews.llvm.org/D8091 llvm-svn: 231434
81 lines
2.3 KiB
Plaintext
81 lines
2.3 KiB
Plaintext
# Checks functionality of dynamic executables
|
|
RUN: lld -flavor gnu -target x86_64-linux %p/Inputs/use-shared.x86-64 \
|
|
RUN: %p/Inputs/shared.so-x86-64 -o %t -e main --allow-shlib-undefined \
|
|
RUN: -rpath /l1:/l2 -rpath /l3
|
|
RUN: lld -flavor gnu -target x86_64-linux %p/Inputs/use-shared.x86-64 \
|
|
RUN: %p/Inputs/shared.so-x86-64 --output-filetype=yaml -o %t2 --allow-shlib-undefined \
|
|
RUN: --noinhibit-exec
|
|
RUN: llvm-objdump -p %t >> %t2
|
|
RUN: llvm-readobj -s -dyn-symbols -dynamic-table %t >> %t2
|
|
RUN: FileCheck %s < %t2
|
|
|
|
CHECK: name: main
|
|
CHECK: kind: R_X86_64_PC32
|
|
CHECK: offset: 18
|
|
CHECK: target: [[PLTNAME:[-a-zA-Z0-9_]+]]
|
|
|
|
CHECK: name: [[PLTNAME]]
|
|
CHECK: type: stub
|
|
|
|
CHECK: type: got
|
|
CHECK: references:
|
|
CHECK: kind: R_X86_64_JUMP_SLOT
|
|
|
|
CHECK: shared-library-atoms:
|
|
CHECK: name: foo
|
|
CHECK: load-name: shared.so-x86-64
|
|
|
|
CHECK: PHDR off 0x{{0+}}40
|
|
CHECK: INTERP
|
|
CHECK: flags r--
|
|
|
|
CHECK: Section {
|
|
CHECK: Name: .hash
|
|
CHECK-NEXT: Type: SHT_HASH
|
|
CHECK-NEXT: Flags [
|
|
CHECK-NEXT: SHF_ALLOC
|
|
CHECK-NEXT: ]
|
|
CHECK-NEXT: Address:
|
|
CHECK-NEXT: Offset:
|
|
CHECK-NEXT: Size: 32
|
|
CHECK-NEXT: Link:
|
|
CHECK-NEXT: Info:
|
|
CHECK-NEXT: AddressAlignment: 8
|
|
CHECK-NEXT: EntrySize:
|
|
CHECK-NEXT: }
|
|
|
|
CHECK: DynamicSymbols [
|
|
CHECK: Symbol {
|
|
CHECK: Name: foo
|
|
CHECK-NEXT: Value: 0
|
|
CHECK-NEXT: Size:
|
|
CHECK-NEXT: Binding: Global
|
|
CHECK-NEXT: Type: Function
|
|
CHECK: }
|
|
CHECK: Symbol {
|
|
CHECK: Name: i
|
|
CHECK-NEXT: Value: 0
|
|
CHECK-NEXT: Size:
|
|
CHECK-NEXT: Binding: Global
|
|
CHECK-NEXT: Type: Object
|
|
CHECK: }
|
|
|
|
CHECK: DynamicSection [ (15 entries)
|
|
CHECK: Tag Type Name/Value
|
|
CHECK: 0x0000000000000004 HASH
|
|
CHECK: 0x0000000000000005 STRTAB
|
|
CHECK: 0x0000000000000006 SYMTAB
|
|
CHECK: 0x000000000000000A STRSZ
|
|
CHECK: 0x000000000000000B SYMENT 24
|
|
CHECK: 0x0000000000000007 RELA
|
|
CHECK: 0x0000000000000008 RELASZ 24
|
|
CHECK: 0x0000000000000009 RELAENT 24
|
|
CHECK: 0x0000000000000002 PLTRELSZ 24
|
|
CHECK: 0x0000000000000003 PLTGOT
|
|
CHECK: 0x0000000000000014 PLTREL RELA
|
|
CHECK: 0x0000000000000017 JMPREL
|
|
CHECK: 0x0000000000000001 NEEDED SharedLibrary (shared.so-x86-64)
|
|
CHECK: 0x000000000000000F RPATH /l1:/l2:/l3
|
|
CHECK: 0x0000000000000000 NULL 0x0
|
|
CHECK: ]
|