summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2015-07-05 22:05:08 +0000
committerRui Ueyama <ruiu@google.com>2015-07-05 22:05:08 +0000
commite2eb15577d10a690af2f8d195fa31bfe1a617bf9 (patch)
treefdbf762c91aa05d210adf48830aeb4661b60304c
parentc80c03da6c032102d279c82315e89c0a476695ae (diff)
downloadbcm5719-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.cpp70
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) {
OpenPOWER on IntegriCloud