diff options
| author | Rui Ueyama <ruiu@google.com> | 2015-07-05 22:05:08 +0000 |
|---|---|---|
| committer | Rui Ueyama <ruiu@google.com> | 2015-07-05 22:05:08 +0000 |
| commit | e2eb15577d10a690af2f8d195fa31bfe1a617bf9 (patch) | |
| tree | fdbf762c91aa05d210adf48830aeb4661b60304c | |
| parent | c80c03da6c032102d279c82315e89c0a476695ae (diff) | |
| download | bcm5719-llvm-e2eb15577d10a690af2f8d195fa31bfe1a617bf9.tar.gz bcm5719-llvm-e2eb15577d10a690af2f8d195fa31bfe1a617bf9.zip | |
COFF: Use CAS to update Sym->Body.
Note that the linker is not multi-threaded yet.
This is a preparation for that.
llvm-svn: 241417
| -rw-r--r-- | lld/COFF/SymbolTable.cpp | 70 |
1 files changed, 41 insertions, 29 deletions
diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp index dc8758be408..780e47ebc47 100644 --- a/lld/COFF/SymbolTable.cpp +++ b/lld/COFF/SymbolTable.cpp @@ -167,12 +167,19 @@ void SymbolTable::addLazy(Lazy *New, std::vector<Symbol *> *Accum) { Symbol *Sym = insert(New); if (Sym->Body == New) return; - SymbolBody *Existing = Sym->Body; - if (!isa<Undefined>(Existing)) + for (;;) { + SymbolBody *Existing = Sym->Body; + if (isa<Defined>(Existing)) + return; + if (Lazy *L = dyn_cast<Lazy>(Existing)) + if (L->getFileIndex() < New->getFileIndex()) + return; + if (!Sym->Body.compare_exchange_strong(Existing, New)) + continue; + New->setBackref(Sym); + Accum->push_back(Sym); return; - Sym->Body = New; - New->setBackref(Sym); - Accum->push_back(Sym); + } } std::error_code SymbolTable::addSymbol(SymbolBody *New) { @@ -181,32 +188,37 @@ std::error_code SymbolTable::addSymbol(SymbolBody *New) { Symbol *Sym = insert(New); if (Sym->Body == New) return std::error_code(); - SymbolBody *Existing = Sym->Body; - - // If we have an undefined symbol and a lazy symbol, - // let the lazy symbol to read a member file. - if (auto *L = dyn_cast<Lazy>(Existing)) { - // Undefined symbols with weak aliases need not to be resolved, - // since they would be replaced with weak aliases if they remain - // undefined. - if (auto *U = dyn_cast<Undefined>(New)) - if (!U->WeakAlias) - return addMemberFile(L); - Sym->Body = New; - return std::error_code(); - } - // compare() returns -1, 0, or 1 if the lhs symbol is less preferable, - // equivalent (conflicting), or more preferable, respectively. - int Comp = Existing->compare(New); - if (Comp == 0) { - llvm::errs() << "duplicate symbol: " << Existing->getDebugName() - << " and " << New->getDebugName() << "\n"; - return make_error_code(LLDError::DuplicateSymbols); + for (;;) { + SymbolBody *Existing = Sym->Body; + + // If we have an undefined symbol and a lazy symbol, + // let the lazy symbol to read a member file. + if (auto *L = dyn_cast<Lazy>(Existing)) { + // Undefined symbols with weak aliases need not to be resolved, + // since they would be replaced with weak aliases if they remain + // undefined. + if (auto *U = dyn_cast<Undefined>(New)) + if (!U->WeakAlias) + return addMemberFile(L); + if (!Sym->Body.compare_exchange_strong(Existing, New)) + continue; + return std::error_code(); + } + + // compare() returns -1, 0, or 1 if the lhs symbol is less preferable, + // equivalent (conflicting), or more preferable, respectively. + int Comp = Existing->compare(New); + if (Comp == 0) { + llvm::errs() << "duplicate symbol: " << Existing->getDebugName() + << " and " << New->getDebugName() << "\n"; + return make_error_code(LLDError::DuplicateSymbols); + } + if (Comp < 0) + if (!Sym->Body.compare_exchange_strong(Existing, New)) + continue; + return std::error_code(); } - if (Comp < 0) - Sym->Body = New; - return std::error_code(); } Symbol *SymbolTable::insert(SymbolBody *New) { |

