[lld] r325150 - [WebAssembly] Use a Symbol class heirarchy. NFC.

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 14 10:27:59 PST 2018


Author: sbc
Date: Wed Feb 14 10:27:59 2018
New Revision: 325150

URL: http://llvm.org/viewvc/llvm-project?rev=325150&view=rev
Log:
[WebAssembly] Use a Symbol class heirarchy. NFC.

This brings wasm into line with ELF and COFF in terms of
symbol types are represented.

Differential Revision: https://reviews.llvm.org/D43112

Modified:
    lld/trunk/wasm/InputFiles.cpp
    lld/trunk/wasm/InputFiles.h
    lld/trunk/wasm/SymbolTable.cpp
    lld/trunk/wasm/SymbolTable.h
    lld/trunk/wasm/Symbols.cpp
    lld/trunk/wasm/Symbols.h
    lld/trunk/wasm/Writer.cpp

Modified: lld/trunk/wasm/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/InputFiles.cpp?rev=325150&r1=325149&r2=325150&view=diff
==============================================================================
--- lld/trunk/wasm/InputFiles.cpp (original)
+++ lld/trunk/wasm/InputFiles.cpp Wed Feb 14 10:27:59 2018
@@ -51,11 +51,14 @@ void ObjFile::dumpInfo() const {
 }
 
 uint32_t ObjFile::relocateVirtualAddress(uint32_t GlobalIndex) const {
-  return getGlobalSymbol(GlobalIndex)->getVirtualAddress();
+  if (auto *DG = dyn_cast<DefinedGlobal>(getGlobalSymbol(GlobalIndex)))
+    return DG->getVirtualAddress();
+  else
+    return 0;
 }
 
 uint32_t ObjFile::relocateFunctionIndex(uint32_t Original) const {
-  const Symbol *Sym = getFunctionSymbol(Original);
+  const FunctionSymbol *Sym = getFunctionSymbol(Original);
   uint32_t Index = Sym->getOutputIndex();
   DEBUG(dbgs() << "relocateFunctionIndex: " << toString(*Sym) << ": "
                << Original << " -> " << Index << "\n");
@@ -68,7 +71,7 @@ uint32_t ObjFile::relocateTypeIndex(uint
 }
 
 uint32_t ObjFile::relocateTableIndex(uint32_t Original) const {
-  const Symbol *Sym = getFunctionSymbol(Original);
+  const FunctionSymbol *Sym = getFunctionSymbol(Original);
   uint32_t Index = Sym->hasTableIndex() ? Sym->getTableIndex() : 0;
   DEBUG(dbgs() << "relocateTableIndex: " << toString(*Sym) << ": " << Original
                << " -> " << Index << "\n");
@@ -249,7 +252,7 @@ void ObjFile::initializeSymbols() {
     case WasmSymbol::SymbolType::FUNCTION_EXPORT: {
       InputFunction *Function = getFunction(WasmSym);
       if (!isExcludedByComdat(Function)) {
-        S = createDefined(WasmSym, Symbol::Kind::DefinedFunctionKind, Function);
+        S = createDefinedFunction(WasmSym, Function);
         break;
       } else {
         Function->Live = false;
@@ -263,8 +266,7 @@ void ObjFile::initializeSymbols() {
     case WasmSymbol::SymbolType::GLOBAL_EXPORT: {
       InputSegment *Segment = getSegment(WasmSym);
       if (!isExcludedByComdat(Segment)) {
-        S = createDefined(WasmSym, Symbol::Kind::DefinedGlobalKind, Segment,
-                          getGlobalValue(WasmSym));
+        S = createDefinedGlobal(WasmSym, Segment, getGlobalValue(WasmSym));
         break;
       } else {
         Segment->Live = false;
@@ -302,15 +304,18 @@ Symbol *ObjFile::createUndefined(const W
   return Symtab->addUndefined(Sym.Name, Kind, Sym.Flags, this, Signature);
 }
 
-Symbol *ObjFile::createDefined(const WasmSymbol &Sym, Symbol::Kind Kind,
-                               InputChunk *Chunk, uint32_t Address) {
-  Symbol *S;
-  if (Sym.isBindingLocal()) {
-    S = make<Symbol>(Sym.Name, true);
-    S->update(Kind, this, Sym.Flags, Chunk, Address);
-    return S;
-  }
-  return Symtab->addDefined(Sym.Name, Kind, Sym.Flags, this, Chunk, Address);
+Symbol *ObjFile::createDefinedFunction(const WasmSymbol &Sym,
+                                       InputChunk *Chunk) {
+  if (Sym.isBindingLocal())
+    return make<DefinedFunction>(Sym.Name, Sym.Flags, this, Chunk);
+  return Symtab->addDefined(true, Sym.Name, Sym.Flags, this, Chunk);
+}
+
+Symbol *ObjFile::createDefinedGlobal(const WasmSymbol &Sym, InputChunk *Chunk,
+                                     uint32_t Address) {
+  if (Sym.isBindingLocal())
+    return make<DefinedGlobal>(Sym.Name, Sym.Flags, this, Chunk, Address);
+  return Symtab->addDefined(false, Sym.Name, Sym.Flags, this, Chunk, Address);
 }
 
 void ArchiveFile::parse() {

Modified: lld/trunk/wasm/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/InputFiles.h?rev=325150&r1=325149&r2=325150&view=diff
==============================================================================
--- lld/trunk/wasm/InputFiles.h (original)
+++ lld/trunk/wasm/InputFiles.h Wed Feb 14 10:27:59 2018
@@ -107,11 +107,13 @@ public:
 
   ArrayRef<Symbol *> getSymbols() const { return Symbols; }
 
-  Symbol *getFunctionSymbol(uint32_t Index) const {
-    return FunctionSymbols[Index];
+  FunctionSymbol *getFunctionSymbol(uint32_t Index) const {
+    return cast<FunctionSymbol>(FunctionSymbols[Index]);
   }
 
-  Symbol *getGlobalSymbol(uint32_t Index) const { return GlobalSymbols[Index]; }
+  GlobalSymbol *getGlobalSymbol(uint32_t Index) const {
+    return cast<GlobalSymbol>(GlobalSymbols[Index]);
+  }
 
 private:
   uint32_t relocateVirtualAddress(uint32_t Index) const;
@@ -119,9 +121,9 @@ private:
   uint32_t relocateGlobalIndex(uint32_t Original) const;
   uint32_t relocateTableIndex(uint32_t Original) const;
 
-  Symbol *createDefined(const WasmSymbol &Sym, Symbol::Kind Kind,
-                        InputChunk *Chunk = nullptr,
-                        uint32_t Address = UINT32_MAX);
+  Symbol *createDefinedGlobal(const WasmSymbol &Sym, InputChunk *Chunk,
+                              uint32_t Address);
+  Symbol *createDefinedFunction(const WasmSymbol &Sym, InputChunk *Chunk);
   Symbol *createUndefined(const WasmSymbol &Sym, Symbol::Kind Kind,
                           const WasmSignature *Signature = nullptr);
   void initializeSymbols();

Modified: lld/trunk/wasm/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/SymbolTable.cpp?rev=325150&r1=325149&r2=325150&view=diff
==============================================================================
--- lld/trunk/wasm/SymbolTable.cpp (original)
+++ lld/trunk/wasm/SymbolTable.cpp Wed Feb 14 10:27:59 2018
@@ -66,7 +66,7 @@ std::pair<Symbol *, bool> SymbolTable::i
   Symbol *&Sym = SymMap[CachedHashStringRef(Name)];
   if (Sym)
     return {Sym, false};
-  Sym = make<Symbol>(Name, false);
+  Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
   SymVector.emplace_back(Sym);
   return {Sym, true};
 }
@@ -80,13 +80,10 @@ void SymbolTable::reportDuplicate(Symbol
 // Check the type of new symbol matches that of the symbol is replacing.
 // For functions this can also involve verifying that the signatures match.
 static void checkSymbolTypes(const Symbol &Existing, const InputFile &F,
-                             Symbol::Kind Kind, const WasmSignature *NewSig) {
+                             bool NewIsFunction, const WasmSignature *NewSig) {
   if (Existing.isLazy())
     return;
 
-  bool NewIsFunction = Kind == Symbol::Kind::UndefinedFunctionKind ||
-                       Kind == Symbol::Kind::DefinedFunctionKind;
-
   // First check the symbol types match (i.e. either both are function
   // symbols or both are data symbols).
   if (Existing.isFunction() != NewIsFunction) {
@@ -98,105 +95,102 @@ static void checkSymbolTypes(const Symbo
   }
 
   // For function symbols, optionally check the function signature matches too.
-  if (!NewIsFunction || !Config->CheckSignatures)
+  auto *ExistingFunc = dyn_cast<FunctionSymbol>(&Existing);
+  if (!ExistingFunc || !Config->CheckSignatures)
     return;
+
   // Skip the signature check if the existing function has no signature (e.g.
   // if it is an undefined symbol generated by --undefined command line flag).
-  if (!Existing.hasFunctionType())
+  if (!ExistingFunc->hasFunctionType())
     return;
 
-  DEBUG(dbgs() << "checkSymbolTypes: " << Existing.getName() << "\n");
+  DEBUG(dbgs() << "checkSymbolTypes: " << ExistingFunc->getName() << "\n");
   assert(NewSig);
 
-  const WasmSignature &OldSig = Existing.getFunctionType();
+  const WasmSignature &OldSig = ExistingFunc->getFunctionType();
   if (*NewSig == OldSig)
     return;
 
-  error("function signature mismatch: " + Existing.getName() +
+  error("function signature mismatch: " + ExistingFunc->getName() +
         "\n>>> defined as " + toString(OldSig) + " in " +
-        toString(Existing.getFile()) + "\n>>> defined as " + toString(*NewSig) +
-        " in " + F.getName());
+        toString(ExistingFunc->getFile()) + "\n>>> defined as " +
+        toString(*NewSig) + " in " + F.getName());
 }
 
 static void checkSymbolTypes(const Symbol &Existing, const InputFile &F,
-                             Symbol::Kind Kind, const InputChunk *Chunk) {
+                             bool IsFunction, const InputChunk *Chunk) {
   const WasmSignature *Sig = nullptr;
   if (auto *F = dyn_cast_or_null<InputFunction>(Chunk))
     Sig = &F->Signature;
-  return checkSymbolTypes(Existing, F, Kind, Sig);
+  return checkSymbolTypes(Existing, F, IsFunction, Sig);
 }
 
-Symbol *SymbolTable::addSyntheticFunction(StringRef Name,
-                                          const WasmSignature *Type,
-                                          uint32_t Flags) {
+DefinedFunction *SymbolTable::addSyntheticFunction(StringRef Name,
+                                                   const WasmSignature *Type,
+                                                   uint32_t Flags) {
   DEBUG(dbgs() << "addSyntheticFunction: " << Name << "\n");
   Symbol *S;
   bool WasInserted;
   std::tie(S, WasInserted) = insert(Name);
   assert(WasInserted);
-  S->update(Symbol::DefinedFunctionKind, nullptr, Flags);
-  S->setFunctionType(Type);
-  return S;
+  return replaceSymbol<DefinedFunction>(S, Name, Flags, Type);
 }
 
-Symbol *SymbolTable::addSyntheticGlobal(StringRef Name) {
+DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef Name, uint32_t Flags) {
   DEBUG(dbgs() << "addSyntheticGlobal: " << Name << "\n");
   Symbol *S;
   bool WasInserted;
   std::tie(S, WasInserted) = insert(Name);
   assert(WasInserted);
-  S->update(Symbol::DefinedGlobalKind);
-  return S;
+  return replaceSymbol<DefinedGlobal>(S, Name, Flags);
 }
 
-Symbol *SymbolTable::addDefined(StringRef Name, Symbol::Kind Kind,
-                                uint32_t Flags, InputFile *F, InputChunk *Chunk,
+Symbol *SymbolTable::addDefined(bool IsFunction, StringRef Name, uint32_t Flags,
+                                InputFile *F, InputChunk *Chunk,
                                 uint32_t Address) {
-  DEBUG(dbgs() << "addDefined: " << Name << " addr:" << Address << "\n");
+  if (IsFunction)
+    DEBUG(dbgs() << "addDefined: func:" << Name << "\n");
+  else
+    DEBUG(dbgs() << "addDefined: global:" << Name << " addr:" << Address
+                 << "\n");
   Symbol *S;
   bool WasInserted;
+  bool Replace = false;
+  bool CheckTypes = false;
 
   std::tie(S, WasInserted) = insert(Name);
   if (WasInserted) {
-    S->update(Kind, F, Flags, Chunk, Address);
+    Replace = true;
   } else if (S->isLazy()) {
-    // The existing symbol is lazy. Replace it without checking types since
+    // Existing symbol is lazy. Replace it without checking types since
     // lazy symbols don't have any type information.
     DEBUG(dbgs() << "replacing existing lazy symbol: " << Name << "\n");
-    S->update(Kind, F, Flags, Chunk, Address);
+    Replace = true;
   } else if (!S->isDefined()) {
-    // The existing symbol table entry is undefined. The new symbol replaces
-    // it, after checking the type matches
+    // Existing symbol is undefined: replace it, while check types.
     DEBUG(dbgs() << "resolving existing undefined symbol: " << Name << "\n");
-    checkSymbolTypes(*S, *F, Kind, Chunk);
-    S->update(Kind, F, Flags, Chunk, Address);
+    Replace = true;
+    CheckTypes = true;
   } else if ((Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK) {
     // the new symbol is weak we can ignore it
     DEBUG(dbgs() << "existing symbol takes precedence\n");
   } else if (S->isWeak()) {
-    // the new symbol is not weak and the existing symbol is, so we replace
-    // it
+    // the existing symbol is, so we replace it
     DEBUG(dbgs() << "replacing existing weak symbol\n");
-    checkSymbolTypes(*S, *F, Kind, Chunk);
-    S->update(Kind, F, Flags, Chunk, Address);
+    Replace = true;
+    CheckTypes = true;
   } else {
     // neither symbol is week. They conflict.
     reportDuplicate(S, F);
   }
-  return S;
-}
 
-Symbol *SymbolTable::addUndefinedFunction(StringRef Name,
-                                          const WasmSignature *Type) {
-  DEBUG(dbgs() << "addUndefinedFunction: " << Name << "\n");
-  Symbol *S;
-  bool WasInserted;
-  std::tie(S, WasInserted) = insert(Name);
-  if (WasInserted) {
-    S->update(Symbol::UndefinedFunctionKind);
-    S->setFunctionType(Type);
-  } else if (!S->isFunction()) {
-    error("symbol type mismatch: " + Name);
+  if (Replace) {
+    if (CheckTypes)
+      checkSymbolTypes(*S, *F, IsFunction, Chunk);
+    if (IsFunction)
+      replaceSymbol<DefinedFunction>(S, Name, Flags, F, Chunk);
+    else
+      replaceSymbol<DefinedGlobal>(S, Name, Flags, F, Chunk, Address);
   }
   return S;
 }
@@ -208,17 +202,19 @@ Symbol *SymbolTable::addUndefined(String
   Symbol *S;
   bool WasInserted;
   std::tie(S, WasInserted) = insert(Name);
+  bool IsFunction = Kind == Symbol::UndefinedFunctionKind;
   if (WasInserted) {
-    S->update(Kind, F, Flags);
-    if (Type)
-      S->setFunctionType(Type);
-  } else if (S->isLazy()) {
+    if (IsFunction)
+      replaceSymbol<UndefinedFunction>(S, Name, Flags, F, Type);
+    else
+      replaceSymbol<UndefinedGlobal>(S, Name, Flags, F);
+  } else if (auto *LazySym = dyn_cast<LazySymbol>(S)) {
     DEBUG(dbgs() << "resolved by existing lazy\n");
-    auto *AF = cast<ArchiveFile>(S->getFile());
-    AF->addMember(&S->getArchiveSymbol());
+    auto *AF = cast<ArchiveFile>(LazySym->getFile());
+    AF->addMember(&LazySym->getArchiveSymbol());
   } else if (S->isDefined()) {
     DEBUG(dbgs() << "resolved by existing\n");
-    checkSymbolTypes(*S, *F, Kind, Type);
+    checkSymbolTypes(*S, *F, IsFunction, Type);
   }
   return S;
 }
@@ -230,8 +226,7 @@ void SymbolTable::addLazy(ArchiveFile *F
   bool WasInserted;
   std::tie(S, WasInserted) = insert(Name);
   if (WasInserted) {
-    S->update(Symbol::LazyKind, F);
-    S->setArchiveSymbol(*Sym);
+    replaceSymbol<LazySymbol>(S, Name, F, *Sym);
   } else if (S->isUndefined()) {
     // There is an existing undefined symbol.  The can load from the
     // archive.

Modified: lld/trunk/wasm/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/SymbolTable.h?rev=325150&r1=325149&r2=325150&view=diff
==============================================================================
--- lld/trunk/wasm/SymbolTable.h (original)
+++ lld/trunk/wasm/SymbolTable.h Wed Feb 14 10:27:59 2018
@@ -49,7 +49,7 @@ public:
   Symbol *find(StringRef Name);
   ObjFile *findComdat(StringRef Name) const;
 
-  Symbol *addDefined(StringRef Name, Symbol::Kind Kind, uint32_t Flags,
+  Symbol *addDefined(bool IsFunction, StringRef Name, uint32_t Flags,
                      InputFile *F, InputChunk *Chunk = nullptr,
                      uint32_t Address = 0);
   Symbol *addUndefined(StringRef Name, Symbol::Kind Kind, uint32_t Flags,
@@ -58,9 +58,10 @@ public:
   void addLazy(ArchiveFile *F, const Archive::Symbol *Sym);
   bool addComdat(StringRef Name, ObjFile *);
 
-  Symbol *addSyntheticGlobal(StringRef Name);
-  Symbol *addSyntheticFunction(StringRef Name, const WasmSignature *Type,
-                               uint32_t Flags);
+  DefinedGlobal *addSyntheticGlobal(StringRef Name, uint32_t Flags = 0);
+  DefinedFunction *addSyntheticFunction(StringRef Name,
+                                        const WasmSignature *Type,
+                                        uint32_t Flags = 0);
 private:
   std::pair<Symbol *, bool> insert(StringRef Name);
 

Modified: lld/trunk/wasm/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Symbols.cpp?rev=325150&r1=325149&r2=325150&view=diff
==============================================================================
--- lld/trunk/wasm/Symbols.cpp (original)
+++ lld/trunk/wasm/Symbols.cpp Wed Feb 14 10:27:59 2018
@@ -22,32 +22,11 @@ using namespace llvm::wasm;
 using namespace lld;
 using namespace lld::wasm;
 
-Symbol *WasmSym::CallCtors;
-Symbol *WasmSym::DsoHandle;
-Symbol *WasmSym::DataEnd;
-Symbol *WasmSym::HeapBase;
-Symbol *WasmSym::StackPointer;
-
-const WasmSignature &Symbol::getFunctionType() const {
-  if (Chunk != nullptr)
-    return dyn_cast<InputFunction>(Chunk)->Signature;
-
-  assert(FunctionType != nullptr);
-  return *FunctionType;
-}
-
-void Symbol::setFunctionType(const WasmSignature *Type) {
-  assert(FunctionType == nullptr);
-  assert(!Chunk);
-  FunctionType = Type;
-}
-
-uint32_t Symbol::getVirtualAddress() const {
-  assert(isGlobal());
-  DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n");
-  return Chunk ? dyn_cast<InputSegment>(Chunk)->translateVA(VirtualAddress)
-               : VirtualAddress;
-}
+DefinedFunction *WasmSym::CallCtors;
+DefinedGlobal *WasmSym::DsoHandle;
+DefinedGlobal *WasmSym::DataEnd;
+DefinedGlobal *WasmSym::HeapBase;
+DefinedGlobal *WasmSym::StackPointer;
 
 bool Symbol::hasOutputIndex() const {
   if (auto *F = dyn_cast_or_null<InputFunction>(Chunk))
@@ -61,12 +40,6 @@ uint32_t Symbol::getOutputIndex() const
   return OutputIndex.getValue();
 }
 
-void Symbol::setVirtualAddress(uint32_t Value) {
-  DEBUG(dbgs() << "setVirtualAddress " << Name << " -> " << Value << "\n");
-  assert(isGlobal());
-  VirtualAddress = Value;
-}
-
 void Symbol::setOutputIndex(uint32_t Index) {
   DEBUG(dbgs() << "setOutputIndex " << Name << " -> " << Index << "\n");
   assert(!dyn_cast_or_null<InputFunction>(Chunk));
@@ -74,19 +47,54 @@ void Symbol::setOutputIndex(uint32_t Ind
   OutputIndex = Index;
 }
 
-uint32_t Symbol::getTableIndex() const {
+bool Symbol::isWeak() const {
+  return (Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK;
+}
+
+bool Symbol::isLocal() const {
+  return (Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_LOCAL;
+}
+
+bool Symbol::isHidden() const {
+  return (Flags & WASM_SYMBOL_VISIBILITY_MASK) == WASM_SYMBOL_VISIBILITY_HIDDEN;
+}
+
+void Symbol::setHidden(bool IsHidden) {
+  DEBUG(dbgs() << "setHidden: " << Name << " -> " << IsHidden << "\n");
+  Flags &= ~WASM_SYMBOL_VISIBILITY_MASK;
+  if (IsHidden)
+    Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN;
+  else
+    Flags |= WASM_SYMBOL_VISIBILITY_DEFAULT;
+}
+
+const WasmSignature &FunctionSymbol::getFunctionType() const {
+  if (auto *F = dyn_cast_or_null<InputFunction>(Chunk))
+    return F->Signature;
+
+  assert(FunctionType != nullptr);
+  return *FunctionType;
+}
+
+void FunctionSymbol::setFunctionType(const WasmSignature *Type) {
+  assert(FunctionType == nullptr);
+  assert(!Chunk);
+  FunctionType = Type;
+}
+
+uint32_t FunctionSymbol::getTableIndex() const {
   if (auto *F = dyn_cast_or_null<InputFunction>(Chunk))
     return F->getTableIndex();
   return TableIndex.getValue();
 }
 
-bool Symbol::hasTableIndex() const {
+bool FunctionSymbol::hasTableIndex() const {
   if (auto *F = dyn_cast_or_null<InputFunction>(Chunk))
     return F->hasTableIndex();
   return TableIndex.hasValue();
 }
 
-void Symbol::setTableIndex(uint32_t Index) {
+void FunctionSymbol::setTableIndex(uint32_t Index) {
   // For imports, we set the table index here on the Symbol; for defined
   // functions we set the index on the InputFunction so that we don't export
   // the same thing twice (keeps the table size down).
@@ -99,35 +107,17 @@ void Symbol::setTableIndex(uint32_t Inde
   TableIndex = Index;
 }
 
-void Symbol::update(Kind K, InputFile *F, uint32_t Flags_, InputChunk *Chunk_,
-                    uint32_t Address) {
-  SymbolKind = K;
-  File = F;
-  Flags = Flags_;
-  Chunk = Chunk_;
-  if (Address != UINT32_MAX)
-    setVirtualAddress(Address);
-}
-
-bool Symbol::isWeak() const {
-  return (Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK;
-}
-
-bool Symbol::isLocal() const {
-  return (Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_LOCAL;
-}
-
-bool Symbol::isHidden() const {
-  return (Flags & WASM_SYMBOL_VISIBILITY_MASK) == WASM_SYMBOL_VISIBILITY_HIDDEN;
+uint32_t DefinedGlobal::getVirtualAddress() const {
+  assert(isGlobal());
+  DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n");
+  return Chunk ? dyn_cast<InputSegment>(Chunk)->translateVA(VirtualAddress)
+               : VirtualAddress;
 }
 
-void Symbol::setHidden(bool IsHidden) {
-  DEBUG(dbgs() << "setHidden: " << Name << " -> " << IsHidden << "\n");
-  Flags &= ~WASM_SYMBOL_VISIBILITY_MASK;
-  if (IsHidden)
-    Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN;
-  else
-    Flags |= WASM_SYMBOL_VISIBILITY_DEFAULT;
+void DefinedGlobal::setVirtualAddress(uint32_t Value) {
+  DEBUG(dbgs() << "setVirtualAddress " << Name << " -> " << Value << "\n");
+  assert(isGlobal());
+  VirtualAddress = Value;
 }
 
 std::string lld::toString(const wasm::Symbol &Sym) {

Modified: lld/trunk/wasm/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Symbols.h?rev=325150&r1=325149&r2=325150&view=diff
==============================================================================
--- lld/trunk/wasm/Symbols.h (original)
+++ lld/trunk/wasm/Symbols.h Wed Feb 14 10:27:59 2018
@@ -23,6 +23,7 @@ namespace wasm {
 class InputFile;
 class InputChunk;
 
+// The base class for real symbol classes.
 class Symbol {
 public:
   enum Kind {
@@ -37,9 +38,7 @@ public:
     InvalidKind,
   };
 
-  Symbol(StringRef Name, uint32_t Flags) : Flags(Flags), Name(Name) {}
-
-  Kind getKind() const { return SymbolKind; }
+  Kind kind() const { return static_cast<Kind>(SymbolKind); }
 
   bool isLazy() const { return SymbolKind == LazyKind; }
   bool isDefined() const { return SymbolKind <= LastDefinedKind; }
@@ -63,9 +62,6 @@ public:
   InputFile *getFile() const { return File; }
   InputChunk *getChunk() const { return Chunk; }
 
-  bool hasFunctionType() const { return FunctionType != nullptr; }
-  const WasmSignature &getFunctionType() const;
-  void setFunctionType(const WasmSignature *Type);
   void setHidden(bool IsHidden);
 
   uint32_t getOutputIndex() const;
@@ -77,6 +73,28 @@ public:
   // space of the output object.
   void setOutputIndex(uint32_t Index);
 
+protected:
+  Symbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F, InputChunk *C)
+      : Name(Name), SymbolKind(K), Flags(Flags), File(F), Chunk(C) {}
+
+  StringRef Name;
+  Kind SymbolKind;
+  uint32_t Flags;
+  InputFile *File;
+  InputChunk *Chunk;
+  llvm::Optional<uint32_t> OutputIndex;
+};
+
+class FunctionSymbol : public Symbol {
+public:
+  static bool classof(const Symbol *S) {
+    return S->kind() == DefinedFunctionKind ||
+           S->kind() == UndefinedFunctionKind;
+  }
+
+  bool hasFunctionType() const { return FunctionType != nullptr; }
+  const WasmSignature &getFunctionType() const;
+
   uint32_t getTableIndex() const;
 
   // Returns true if a table index has been set for this symbol
@@ -85,30 +103,99 @@ public:
   // Set the table index of the symbol
   void setTableIndex(uint32_t Index);
 
-  // Returns the virtual address of a defined global.
-  // Only works for globals, not functions.
+protected:
+  void setFunctionType(const WasmSignature *Type);
+
+  FunctionSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F,
+                 InputChunk *C)
+      : Symbol(Name, K, Flags, F, C) {}
+
+  llvm::Optional<uint32_t> TableIndex;
+
+  // Explict function type, needed for undefined or synthetic functions only.
+  const WasmSignature *FunctionType = nullptr;
+};
+
+class DefinedFunction : public FunctionSymbol {
+public:
+  DefinedFunction(StringRef Name, uint32_t Flags, InputFile *F = nullptr,
+                  InputChunk *C = nullptr)
+      : FunctionSymbol(Name, DefinedFunctionKind, Flags, F, C) {}
+
+  DefinedFunction(StringRef Name, uint32_t Flags, const WasmSignature *Type)
+      : FunctionSymbol(Name, DefinedFunctionKind, Flags, nullptr, nullptr) {
+    setFunctionType(Type);
+  }
+
+  static bool classof(const Symbol *S) {
+    return S->kind() == DefinedFunctionKind;
+  }
+};
+
+class UndefinedFunction : public FunctionSymbol {
+public:
+  UndefinedFunction(StringRef Name, uint32_t Flags, InputFile *File = nullptr,
+                    const WasmSignature *Type = nullptr)
+      : FunctionSymbol(Name, UndefinedFunctionKind, Flags, File, nullptr) {
+    setFunctionType(Type);
+  }
+
+  static bool classof(const Symbol *S) {
+    return S->kind() == UndefinedFunctionKind;
+  }
+};
+
+class GlobalSymbol : public Symbol {
+public:
+  static bool classof(const Symbol *S) {
+    return S->kind() == DefinedGlobalKind || S->kind() == UndefinedGlobalKind;
+  }
+
+protected:
+  GlobalSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F,
+               InputChunk *C)
+      : Symbol(Name, K, Flags, F, C) {}
+};
+
+class DefinedGlobal : public GlobalSymbol {
+public:
+  DefinedGlobal(StringRef Name, uint32_t Flags, InputFile *F = nullptr,
+                InputChunk *C = nullptr, uint32_t Address = 0)
+      : GlobalSymbol(Name, DefinedGlobalKind, Flags, F, C),
+        VirtualAddress(Address) {}
+
+  static bool classof(const Symbol *S) {
+    return S->kind() == DefinedGlobalKind;
+  }
+
   uint32_t getVirtualAddress() const;
 
   void setVirtualAddress(uint32_t VA);
 
-  void update(Kind K, InputFile *F = nullptr, uint32_t Flags = 0,
-              InputChunk *chunk = nullptr, uint32_t Address = UINT32_MAX);
+protected:
+  uint32_t VirtualAddress;
+};
+
+class UndefinedGlobal : public GlobalSymbol {
+public:
+  UndefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File = nullptr)
+      : GlobalSymbol(Name, UndefinedGlobalKind, Flags, File, nullptr) {}
+  static bool classof(const Symbol *S) {
+    return S->kind() == UndefinedGlobalKind;
+  }
+};
+
+class LazySymbol : public Symbol {
+public:
+  LazySymbol(StringRef Name, InputFile *File, const Archive::Symbol &Sym)
+      : Symbol(Name, LazyKind, 0, File, nullptr), ArchiveSymbol(Sym) {}
+
+  static bool classof(const Symbol *S) { return S->kind() == LazyKind; }
 
-  void setArchiveSymbol(const Archive::Symbol &Sym) { ArchiveSymbol = Sym; }
   const Archive::Symbol &getArchiveSymbol() { return ArchiveSymbol; }
 
 protected:
-  uint32_t Flags;
-  uint32_t VirtualAddress = 0;
-
-  StringRef Name;
-  Archive::Symbol ArchiveSymbol = {nullptr, 0, 0};
-  Kind SymbolKind = InvalidKind;
-  InputFile *File = nullptr;
-  InputChunk *Chunk = nullptr;
-  llvm::Optional<uint32_t> OutputIndex;
-  llvm::Optional<uint32_t> TableIndex;
-  const WasmSignature *FunctionType = nullptr;
+  Archive::Symbol ArchiveSymbol;
 };
 
 // linker-generated symbols
@@ -116,27 +203,50 @@ struct WasmSym {
   // __stack_pointer
   // Global that holds the address of the top of the explicit value stack in
   // linear memory.
-  static Symbol *StackPointer;
+  static DefinedGlobal *StackPointer;
 
   // __data_end
   // Symbol marking the end of the data and bss.
-  static Symbol *DataEnd;
+  static DefinedGlobal *DataEnd;
 
   // __heap_base
   // Symbol marking the end of the data, bss and explicit stack.  Any linear
   // memory following this address is not used by the linked code and can
   // therefore be used as a backing store for brk()/malloc() implementations.
-  static Symbol *HeapBase;
+  static DefinedGlobal *HeapBase;
 
   // __wasm_call_ctors
   // Function that directly calls all ctors in priority order.
-  static Symbol *CallCtors;
+  static DefinedFunction *CallCtors;
 
   // __dso_handle
   // Global used in calls to __cxa_atexit to determine current DLL
-  static Symbol *DsoHandle;
+  static DefinedGlobal *DsoHandle;
+};
+
+// A buffer class that is large enough to hold any Symbol-derived
+// object. We allocate memory using this class and instantiate a symbol
+// using the placement new.
+union SymbolUnion {
+  alignas(DefinedFunction) char A[sizeof(DefinedFunction)];
+  alignas(DefinedGlobal) char B[sizeof(DefinedGlobal)];
+  alignas(LazySymbol) char C[sizeof(LazySymbol)];
+  alignas(UndefinedFunction) char D[sizeof(UndefinedFunction)];
+  alignas(UndefinedGlobal) char E[sizeof(UndefinedFunction)];
 };
 
+template <typename T, typename... ArgT>
+T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
+  static_assert(std::is_trivially_destructible<T>(),
+                "Symbol types must be trivially destructible");
+  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
+  static_assert(alignof(T) <= alignof(SymbolUnion),
+                "SymbolUnion not aligned enough");
+  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
+         "Not a Symbol");
+  return new (S) T(std::forward<ArgT>(Arg)...);
+}
+
 } // namespace wasm
 
 // Returns a symbol name for an error message.

Modified: lld/trunk/wasm/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Writer.cpp?rev=325150&r1=325149&r2=325150&view=diff
==============================================================================
--- lld/trunk/wasm/Writer.cpp (original)
+++ lld/trunk/wasm/Writer.cpp Wed Feb 14 10:27:59 2018
@@ -119,12 +119,12 @@ private:
 
   std::vector<const WasmSignature *> Types;
   DenseMap<WasmSignature, int32_t, WasmSignatureDenseMapInfo> TypeIndices;
-  std::vector<const Symbol *> ImportedFunctions;
-  std::vector<const Symbol *> ImportedGlobals;
+  std::vector<const FunctionSymbol *> ImportedFunctions;
+  std::vector<const GlobalSymbol *> ImportedGlobals;
   std::vector<WasmExportEntry> ExportedSymbols;
-  std::vector<const Symbol *> DefinedGlobals;
+  std::vector<const DefinedGlobal *> DefinedGlobals;
   std::vector<InputFunction *> DefinedFunctions;
-  std::vector<const Symbol *> IndirectFunctions;
+  std::vector<const FunctionSymbol *> IndirectFunctions;
   std::vector<WasmInitFunc> InitFunctions;
 
   // Elements that are used to construct the final output
@@ -164,7 +164,7 @@ void Writer::createImportSection() {
 
   writeUleb128(OS, NumImports, "import count");
 
-  for (const Symbol *Sym : ImportedFunctions) {
+  for (const FunctionSymbol *Sym : ImportedFunctions) {
     WasmImport Import;
     Import.Module = "env";
     Import.Field = Sym->getName();
@@ -234,7 +234,7 @@ void Writer::createGlobalSection() {
   raw_ostream &OS = Section->getStream();
 
   writeUleb128(OS, DefinedGlobals.size(), "global count");
-  for (const Symbol *Sym : DefinedGlobals) {
+  for (const DefinedGlobal *Sym : DefinedGlobals) {
     WasmGlobal Global;
     Global.Type.Type = WASM_TYPE_I32;
     Global.Type.Mutable = Sym == WasmSym::StackPointer;
@@ -316,7 +316,7 @@ void Writer::createElemSection() {
   writeUleb128(OS, IndirectFunctions.size(), "elem count");
 
   uint32_t TableIndex = kInitialTableOffset;
-  for (const Symbol *Sym : IndirectFunctions) {
+  for (const FunctionSymbol *Sym : IndirectFunctions) {
     assert(Sym->getTableIndex() == TableIndex);
     writeUleb128(OS, Sym->getOutputIndex(), "function index");
     ++TableIndex;
@@ -619,12 +619,12 @@ void Writer::calculateImports() {
     if (!Sym->isUndefined() || (Sym->isWeak() && !Config->Relocatable))
       continue;
 
-    if (Sym->isFunction()) {
-      Sym->setOutputIndex(ImportedFunctions.size());
-      ImportedFunctions.push_back(Sym);
-    } else {
-      Sym->setOutputIndex(ImportedGlobals.size());
-      ImportedGlobals.push_back(Sym);
+    if (auto *F = dyn_cast<FunctionSymbol>(Sym)) {
+      F->setOutputIndex(ImportedFunctions.size());
+      ImportedFunctions.push_back(F);
+    } else if (auto *G = dyn_cast<GlobalSymbol>(Sym)) {
+      G->setOutputIndex(ImportedGlobals.size());
+      ImportedGlobals.push_back(G);
     }
   }
 }
@@ -712,7 +712,7 @@ void Writer::calculateTypes() {
         File->TypeMap[I] = registerType(Types[I]);
   }
 
-  for (const Symbol *Sym : ImportedFunctions)
+  for (const FunctionSymbol *Sym : ImportedFunctions)
     registerType(Sym->getFunctionType());
 
   for (const InputFunction *F : DefinedFunctions)
@@ -723,7 +723,7 @@ void Writer::assignIndexes() {
   uint32_t GlobalIndex = ImportedGlobals.size() + DefinedGlobals.size();
   uint32_t FunctionIndex = ImportedFunctions.size() + DefinedFunctions.size();
 
-  auto AddDefinedGlobal = [&](Symbol* Sym) {
+  auto AddDefinedGlobal = [&](DefinedGlobal *Sym) {
     if (Sym) {
       DefinedGlobals.emplace_back(Sym);
       Sym->setOutputIndex(GlobalIndex++);
@@ -743,12 +743,10 @@ void Writer::assignIndexes() {
       DEBUG(dbgs() << "Globals: " << File->getName() << "\n");
       for (Symbol *Sym : File->getSymbols()) {
         // Create wasm globals for data symbols defined in this file
-        if (!Sym->isDefined() || File != Sym->getFile())
+        if (File != Sym->getFile())
           continue;
-        if (Sym->isFunction())
-          continue;
-
-        AddDefinedGlobal(Sym);
+        if (auto *G = dyn_cast<DefinedGlobal>(Sym))
+          AddDefinedGlobal(G);
       }
     }
   }
@@ -772,7 +770,7 @@ void Writer::assignIndexes() {
       for (const WasmRelocation& Reloc : Chunk->getRelocations()) {
         if (Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_I32 ||
             Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_SLEB) {
-          Symbol *Sym = File->getFunctionSymbol(Reloc.Index);
+          FunctionSymbol *Sym = File->getFunctionSymbol(Reloc.Index);
           if (Sym->hasTableIndex() || !Sym->hasOutputIndex())
             continue;
           Sym->setTableIndex(TableIndex++);




More information about the llvm-commits mailing list