COFF: Use atomic pointers in preparation for parallelizing.
In the new design, mutation of Symbol pointers is the name resolution operation. This patch makes them atomic pointers so that they can be mutated by multiple threads safely. I'm going to use atomic compare-exchange on these pointers. dyn_cast<> doesn't recognize atomic pointers as pointers, so we need to call load(). This is unfortunate, but in other places automatic type conversion works fine. llvm-svn: 241416
This commit is contained in:
parent
cc9fad0bf7
commit
c80c03da6c
|
@ -220,7 +220,7 @@ StringRef LinkerDriver::findDefaultEntry() {
|
|||
};
|
||||
for (auto E : Entries) {
|
||||
Symbol *Sym = Symtab.find(E[0]);
|
||||
if (Sym && !isa<Undefined>(Sym->Body))
|
||||
if (Sym && !isa<Undefined>(Sym->Body.load()))
|
||||
return E[1];
|
||||
}
|
||||
return "";
|
||||
|
@ -591,7 +591,7 @@ bool LinkerDriver::link(llvm::ArrayRef<const char *> ArgsArr) {
|
|||
Symbol *Sym = Symtab.find(From);
|
||||
if (!Sym)
|
||||
continue;
|
||||
if (auto *U = dyn_cast<Undefined>(Sym->Body))
|
||||
if (auto *U = dyn_cast<Undefined>(Sym->Body.load()))
|
||||
if (!U->WeakAlias)
|
||||
U->WeakAlias = Symtab.addUndefined(To);
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ std::error_code SymbolTable::readArchives() {
|
|||
// Add archive member files to ObjectQueue that should resolve
|
||||
// existing undefined symbols.
|
||||
for (Symbol *Sym : LazySyms)
|
||||
if (auto EC = addMemberFile(cast<Lazy>(Sym->Body)))
|
||||
if (auto EC = addMemberFile(cast<Lazy>(Sym->Body.load())))
|
||||
return EC;
|
||||
return std::error_code();
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ bool SymbolTable::reportRemainingUndefines(bool Resolve) {
|
|||
bool Ret = false;
|
||||
for (auto &I : Symtab) {
|
||||
Symbol *Sym = I.second;
|
||||
auto *Undef = dyn_cast<Undefined>(Sym->Body);
|
||||
auto *Undef = dyn_cast<Undefined>(Sym->Body.load());
|
||||
if (!Undef)
|
||||
continue;
|
||||
StringRef Name = Undef->getName();
|
||||
|
@ -140,10 +140,10 @@ bool SymbolTable::reportRemainingUndefines(bool Resolve) {
|
|||
// This odd rule is for compatibility with MSVC linker.
|
||||
if (Name.startswith("__imp_")) {
|
||||
Symbol *Imp = find(Name.substr(strlen("__imp_")));
|
||||
if (Imp && isa<Defined>(Imp->Body)) {
|
||||
if (Imp && isa<Defined>(Imp->Body.load())) {
|
||||
if (!Resolve)
|
||||
continue;
|
||||
auto *D = cast<Defined>(Imp->Body);
|
||||
auto *D = cast<Defined>(Imp->Body.load());
|
||||
auto *S = new (Alloc) DefinedLocalImport(Name, D);
|
||||
LocalImportChunks.push_back(S->getChunk());
|
||||
Sym->Body = S;
|
||||
|
@ -320,11 +320,11 @@ std::error_code SymbolTable::addCombinedLTOObject() {
|
|||
StringRef Name = Body->getName();
|
||||
Symbol *Sym = insert(Body);
|
||||
|
||||
if (isa<DefinedBitcode>(Sym->Body)) {
|
||||
if (isa<DefinedBitcode>(Sym->Body.load())) {
|
||||
Sym->Body = Body;
|
||||
continue;
|
||||
}
|
||||
if (auto *L = dyn_cast<Lazy>(Sym->Body)) {
|
||||
if (auto *L = dyn_cast<Lazy>(Sym->Body.load())) {
|
||||
// We may see new references to runtime library symbols such as __chkstk
|
||||
// here. These symbols must be wholly defined in non-bitcode files.
|
||||
if (auto EC = addMemberFile(L))
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/Object/Archive.h"
|
||||
#include "llvm/Object/COFF.h"
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
|
@ -38,7 +39,7 @@ class SymbolBody;
|
|||
// The resolver updates SymbolBody pointers as it resolves symbols.
|
||||
struct Symbol {
|
||||
explicit Symbol(SymbolBody *P) : Body(P) {}
|
||||
SymbolBody *Body;
|
||||
std::atomic<SymbolBody *> Body;
|
||||
};
|
||||
|
||||
// The base class for real symbol classes.
|
||||
|
@ -80,7 +81,7 @@ public:
|
|||
// has chosen the object among other objects having the same name,
|
||||
// you can access P->Backref->Body to get the resolver's result.
|
||||
void setBackref(Symbol *P) { Backref = P; }
|
||||
SymbolBody *repl() { return Backref ? Backref->Body : this; }
|
||||
SymbolBody *repl() { return Backref ? Backref->Body.load() : this; }
|
||||
|
||||
// Decides which symbol should "win" in the symbol table, this or
|
||||
// the Other. Returns 1 if this wins, -1 if the Other wins, or 0 if
|
||||
|
|
|
@ -243,7 +243,8 @@ void Writer::createImportTables() {
|
|||
Sec->addChunk(C);
|
||||
}
|
||||
if (!DelayIdata.empty()) {
|
||||
Defined *Helper = cast<Defined>(Symtab->find("__delayLoadHelper2")->Body);
|
||||
Symbol *Sym = Symtab->find("__delayLoadHelper2");
|
||||
Defined *Helper = cast<Defined>(Sym->Body.load());
|
||||
DelayIdata.create(Helper);
|
||||
OutputSection *Sec = createSection(".didat");
|
||||
for (Chunk *C : DelayIdata.getChunks())
|
||||
|
@ -535,7 +536,7 @@ OutputSection *Writer::createSection(StringRef Name) {
|
|||
// Dest is .reloc section. Add contents to that section.
|
||||
void Writer::addBaserels(OutputSection *Dest) {
|
||||
std::vector<uint32_t> V;
|
||||
Defined *ImageBase = cast<Defined>(Symtab->find("__ImageBase")->Body);
|
||||
Defined *ImageBase = cast<Defined>(Symtab->find("__ImageBase")->Body.load());
|
||||
for (OutputSection *Sec : OutputSections) {
|
||||
if (Sec == Dest)
|
||||
continue;
|
||||
|
|
Loading…
Reference in New Issue