[lld] r361667 - [COFF] De-virtualize Chunk and SectionChunk

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Fri May 24 13:25:40 PDT 2019


Author: rnk
Date: Fri May 24 13:25:40 2019
New Revision: 361667

URL: http://llvm.org/viewvc/llvm-project?rev=361667&view=rev
Log:
[COFF] De-virtualize Chunk and SectionChunk

Shaves another pointer off of SectionChunk, reducing the size from 96 to
88 bytes, down from 144 before I started working on this. Combined with
D62356, this reduced peak memory usage when linking chrome_child.dll
from 713MB to 675MB, or 5%.

Create NonSectionChunk to provide virtual dispatch to the rest of the
chunk types.

Reviewers: ruiu, aganea

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

Modified:
    lld/trunk/COFF/Chunks.cpp
    lld/trunk/COFF/Chunks.h
    lld/trunk/COFF/DLL.cpp
    lld/trunk/COFF/Writer.cpp

Modified: lld/trunk/COFF/Chunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Chunks.cpp?rev=361667&r1=361666&r2=361667&view=diff
==============================================================================
--- lld/trunk/COFF/Chunks.cpp (original)
+++ lld/trunk/COFF/Chunks.cpp Fri May 24 13:25:40 2019
@@ -43,6 +43,8 @@ SectionChunk::SectionChunk(ObjFile *F, c
 
   setAlignment(Header->getAlignment());
 
+  HasData = !(Header->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA);
+
   // If linker GC is disabled, every chunk starts out alive.  If linker GC is
   // enabled, treat non-comdat sections as roots. Generally optimized object
   // files will be built with -ffunction-sections or /Gy, so most things worth
@@ -53,7 +55,7 @@ SectionChunk::SectionChunk(ObjFile *F, c
 // SectionChunk is one of the most frequently allocated classes, so it is
 // important to keep it as compact as possible. As of this writing, the number
 // below is the size of this class on x64 platforms.
-static_assert(sizeof(SectionChunk) <= 96, "SectionChunk grew unexpectedly");
+static_assert(sizeof(SectionChunk) <= 88, "SectionChunk grew unexpectedly");
 
 static void add16(uint8_t *P, int16_t V) { write16le(P, read16le(P) + V); }
 static void add32(uint8_t *P, int32_t V) { write32le(P, read32le(P) + V); }
@@ -559,14 +561,6 @@ void SectionChunk::getRuntimePseudoReloc
   }
 }
 
-bool SectionChunk::hasData() const {
-  return !(Header->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA);
-}
-
-uint32_t SectionChunk::getOutputCharacteristics() const {
-  return Header->Characteristics & (PermMask | TypeMask);
-}
-
 bool SectionChunk::isCOMDAT() const {
   return Header->Characteristics & IMAGE_SCN_LNK_COMDAT;
 }
@@ -578,7 +572,7 @@ void SectionChunk::printDiscardedMessage
     message("Discarded " + Sym->getName());
 }
 
-StringRef SectionChunk::getDebugName() {
+StringRef SectionChunk::getDebugName() const {
   if (Sym)
     return Sym->getName();
   return "";
@@ -642,6 +636,7 @@ CommonChunk::CommonChunk(const COFFSymbo
   // than 32 bytes naturally, i.e. round the size up to the next power of two.
   // This is what MSVC link.exe does.
   setAlignment(std::min(32U, uint32_t(PowerOf2Ceil(Sym.getValue()))));
+  HasData = false;
 }
 
 uint32_t CommonChunk::getOutputCharacteristics() const {
@@ -858,7 +853,7 @@ uint8_t Baserel::getDefaultType() {
 MergeChunk *MergeChunk::Instances[Log2MaxSectionAlignment + 1] = {};
 
 MergeChunk::MergeChunk(uint32_t Alignment)
-    : Chunk(OtherKind), Builder(StringTableBuilder::RAW, Alignment) {
+    : Builder(StringTableBuilder::RAW, Alignment) {
   setAlignment(Alignment);
 }
 

Modified: lld/trunk/COFF/Chunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Chunks.h?rev=361667&r1=361666&r2=361667&view=diff
==============================================================================
--- lld/trunk/COFF/Chunks.h (original)
+++ lld/trunk/COFF/Chunks.h Fri May 24 13:25:40 2019
@@ -13,6 +13,7 @@
 #include "InputFiles.h"
 #include "lld/Common/LLVM.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/PointerIntPair.h"
 #include "llvm/ADT/iterator.h"
 #include "llvm/ADT/iterator_range.h"
 #include "llvm/MC/StringTableBuilder.h"
@@ -55,14 +56,16 @@ class Chunk {
 public:
   enum Kind : uint8_t { SectionKind, OtherKind };
   Kind kind() const { return ChunkKind; }
-  virtual ~Chunk() = default;
 
   // Returns the size of this chunk (even if this is a common or BSS.)
-  virtual size_t getSize() const = 0;
+  size_t getSize() const;
 
   // Returns chunk alignment in power of two form. Value values are powers of
   // two from 1 to 8192.
   uint32_t getAlignment() const { return 1U << P2Align; }
+
+  // Update the chunk section alignment measured in bytes. Internally alignment
+  // is stored in log2.
   void setAlignment(uint32_t Align) {
     // Treat zero byte alignment as 1 byte alignment.
     Align = Align ? Align : 1;
@@ -76,7 +79,7 @@ public:
   // beginning of the file. Because this function may use RVA values
   // of other chunks for relocations, you need to set them properly
   // before calling this function.
-  virtual void writeTo(uint8_t *Buf) const {}
+  void writeTo(uint8_t *Buf) const;
 
   // The writer sets and uses the addresses. In practice, PE images cannot be
   // larger than 2GB. Chunks are always laid as part of the image, so Chunk RVAs
@@ -90,16 +93,14 @@ public:
   // Returns true if this has non-zero data. BSS chunks return
   // false. If false is returned, the space occupied by this chunk
   // will be filled with zeros.
-  virtual bool hasData() const { return true; }
+  bool hasData() const { return HasData; }
 
   // Returns readable/writable/executable bits.
-  virtual uint32_t getOutputCharacteristics() const { return 0; }
+  uint32_t getOutputCharacteristics() const;
 
   // Returns the section name if this is a section chunk.
   // It is illegal to call this function on non-section chunks.
-  virtual StringRef getSectionName() const {
-    llvm_unreachable("unimplemented getSectionName");
-  }
+  StringRef getSectionName() const;
 
   // An output section has pointers to chunks in the section, and each
   // chunk has a back pointer to an output section.
@@ -109,22 +110,29 @@ public:
 
   // Windows-specific.
   // Collect all locations that contain absolute addresses for base relocations.
-  virtual void getBaserels(std::vector<Baserel> *Res) {}
+  void getBaserels(std::vector<Baserel> *Res);
 
   // Returns a human-readable name of this chunk. Chunks are unnamed chunks of
   // bytes, so this is used only for logging or debugging.
-  virtual StringRef getDebugName() { return ""; }
+  StringRef getDebugName() const;
 
-  virtual bool isHotPatchable() const { return false; }
+  // Return true if this file has the hotpatch flag set to true in the
+  // S_COMPILE3 record in codeview debug info. Also returns true for some thunks
+  // synthesized by the linker.
+  bool isHotPatchable() const;
 
 protected:
-  Chunk(Kind K = OtherKind) : ChunkKind(K) {}
+  Chunk(Kind K = OtherKind) : ChunkKind(K), HasData(true), P2Align(0) {}
 
   const Kind ChunkKind;
 
+  // True if the section has data. Corresponds to the
+  // IMAGE_SCN_CNT_UNINITIALIZED_DATA section characteristic bit.
+  uint8_t HasData : 1;
+
   // The alignment of this chunk, stored in log2 form. The writer uses the
   // value.
-  uint8_t P2Align = 0;
+  uint8_t P2Align : 7;
 
   // The output section index for this chunk. The first valid section number is
   // one.
@@ -134,6 +142,46 @@ protected:
   uint32_t RVA = 0;
 };
 
+class NonSectionChunk : public Chunk {
+public:
+  virtual ~NonSectionChunk() = default;
+
+  // Returns the size of this chunk (even if this is a common or BSS.)
+  virtual size_t getSize() const = 0;
+
+  virtual uint32_t getOutputCharacteristics() const { return 0; }
+
+  // Write this chunk to a mmap'ed file, assuming Buf is pointing to
+  // beginning of the file. Because this function may use RVA values
+  // of other chunks for relocations, you need to set them properly
+  // before calling this function.
+  virtual void writeTo(uint8_t *Buf) const {}
+
+  // Returns the section name if this is a section chunk.
+  // It is illegal to call this function on non-section chunks.
+  virtual StringRef getSectionName() const {
+    llvm_unreachable("unimplemented getSectionName");
+  }
+
+  // Windows-specific.
+  // Collect all locations that contain absolute addresses for base relocations.
+  virtual void getBaserels(std::vector<Baserel> *Res) {}
+
+  // Return true if this file has the hotpatch flag set to true in the
+  // S_COMPILE3 record in codeview debug info. Also returns true for some thunks
+  // synthesized by the linker.
+  virtual bool isHotPatchable() const { return false; }
+
+  // Returns a human-readable name of this chunk. Chunks are unnamed chunks of
+  // bytes, so this is used only for logging or debugging.
+  virtual StringRef getDebugName() const { return ""; }
+
+  static bool classof(const Chunk *C) { return C->kind() == OtherKind; }
+
+protected:
+  NonSectionChunk() : Chunk(OtherKind) {}
+};
+
 // A chunk corresponding a section of an input file.
 class SectionChunk final : public Chunk {
   // Identical COMDAT Folding feature accesses section internal data.
@@ -158,15 +206,17 @@ public:
 
   SectionChunk(ObjFile *File, const coff_section *Header);
   static bool classof(const Chunk *C) { return C->kind() == SectionKind; }
-  size_t getSize() const override { return Header->SizeOfRawData; }
+  size_t getSize() const { return Header->SizeOfRawData; }
   ArrayRef<uint8_t> getContents() const;
-  void writeTo(uint8_t *Buf) const override;
-  bool hasData() const override;
-  uint32_t getOutputCharacteristics() const override;
-  StringRef getSectionName() const override {
+  void writeTo(uint8_t *Buf) const;
+
+  uint32_t getOutputCharacteristics() const {
+    return Header->Characteristics & (PermMask | TypeMask);
+  }
+  StringRef getSectionName() const {
     return StringRef(SectionNameData, SectionNameSize);
   }
-  void getBaserels(std::vector<Baserel> *Res) override;
+  void getBaserels(std::vector<Baserel> *Res);
   bool isCOMDAT() const;
   void applyRelX64(uint8_t *Off, uint16_t Type, OutputSection *OS, uint64_t S,
                    uint64_t P) const;
@@ -187,7 +237,7 @@ public:
   // and its children are treated as a group by the garbage collector.
   void addAssociative(SectionChunk *Child);
 
-  StringRef getDebugName() override;
+  StringRef getDebugName() const;
 
   // True if this is a codeview debug info chunk. These will not be laid out in
   // the image. Instead they will end up in the PDB, if one is requested.
@@ -200,6 +250,8 @@ public:
     return getSectionName().startswith(".debug_") || getSectionName() == ".eh_frame";
   }
 
+  bool isHotPatchable() const { return File->HotPatchable; }
+
   // Allow iteration over the bodies of this chunk's relocated symbols.
   llvm::iterator_range<symbol_iterator> symbols() const {
     return llvm::make_range(symbol_iterator(File, RelocsData),
@@ -257,8 +309,6 @@ public:
   static SectionChunk *findByName(ArrayRef<SectionChunk *> Sections,
                                   StringRef Name);
 
-  bool isHotPatchable() const override { return File->HotPatchable; }
-
   // The file that this chunk was created from.
   ObjFile *File;
 
@@ -305,6 +355,58 @@ private:
   uint32_t SectionNameSize = 0;
 };
 
+// Inline methods to implement faux-virtual dispatch for SectionChunk.
+
+inline size_t Chunk::getSize() const {
+  if (isa<SectionChunk>(this))
+    return static_cast<const SectionChunk *>(this)->getSize();
+  else
+    return static_cast<const NonSectionChunk *>(this)->getSize();
+}
+
+inline uint32_t Chunk::getOutputCharacteristics() const {
+  if (isa<SectionChunk>(this))
+    return static_cast<const SectionChunk *>(this)->getOutputCharacteristics();
+  else
+    return static_cast<const NonSectionChunk *>(this)
+        ->getOutputCharacteristics();
+}
+
+inline void Chunk::writeTo(uint8_t *Buf) const {
+  if (isa<SectionChunk>(this))
+    static_cast<const SectionChunk *>(this)->writeTo(Buf);
+  else
+    static_cast<const NonSectionChunk *>(this)->writeTo(Buf);
+}
+
+inline bool Chunk::isHotPatchable() const {
+  if (isa<SectionChunk>(this))
+    return static_cast<const SectionChunk *>(this)->isHotPatchable();
+  else
+    return static_cast<const NonSectionChunk *>(this)->isHotPatchable();
+}
+
+inline StringRef Chunk::getSectionName() const {
+  if (isa<SectionChunk>(this))
+    return static_cast<const SectionChunk *>(this)->getSectionName();
+  else
+    return static_cast<const NonSectionChunk *>(this)->getSectionName();
+}
+
+inline void Chunk::getBaserels(std::vector<Baserel> *Res) {
+  if (isa<SectionChunk>(this))
+    static_cast<SectionChunk *>(this)->getBaserels(Res);
+  else
+    static_cast<NonSectionChunk *>(this)->getBaserels(Res);
+}
+
+inline StringRef Chunk::getDebugName() const {
+  if (isa<SectionChunk>(this))
+    return static_cast<const SectionChunk *>(this)->getDebugName();
+  else
+    return static_cast<const NonSectionChunk *>(this)->getDebugName();
+}
+
 // This class is used to implement an lld-specific feature (not implemented in
 // MSVC) that minimizes the output size by finding string literals sharing tail
 // parts and merging them.
@@ -314,7 +416,7 @@ private:
 // The MergeChunk then tail merges the strings using the StringTableBuilder
 // class and assigns RVAs and section offsets to each of the member chunks based
 // on the offsets assigned by the StringTableBuilder.
-class MergeChunk : public Chunk {
+class MergeChunk : public NonSectionChunk {
 public:
   MergeChunk(uint32_t Alignment);
   static void addSection(SectionChunk *C);
@@ -335,11 +437,10 @@ private:
 };
 
 // A chunk for common symbols. Common chunks don't have actual data.
-class CommonChunk : public Chunk {
+class CommonChunk : public NonSectionChunk {
 public:
   CommonChunk(const COFFSymbolRef Sym);
   size_t getSize() const override { return Sym.getValue(); }
-  bool hasData() const override { return false; }
   uint32_t getOutputCharacteristics() const override;
   StringRef getSectionName() const override { return ".bss"; }
 
@@ -348,7 +449,7 @@ private:
 };
 
 // A chunk for linker-created strings.
-class StringChunk : public Chunk {
+class StringChunk : public NonSectionChunk {
 public:
   explicit StringChunk(StringRef S) : Str(S) {}
   size_t getSize() const override { return Str.size() + 1; }
@@ -377,7 +478,7 @@ static const uint8_t ImportThunkARM64[]
 // Windows-specific.
 // A chunk for DLL import jump table entry. In a final output, its
 // contents will be a JMP instruction to some __imp_ symbol.
-class ImportThunkChunkX64 : public Chunk {
+class ImportThunkChunkX64 : public NonSectionChunk {
 public:
   explicit ImportThunkChunkX64(Defined *S);
   size_t getSize() const override { return sizeof(ImportThunkX86); }
@@ -389,9 +490,10 @@ private:
   Defined *ImpSymbol;
 };
 
-class ImportThunkChunkX86 : public Chunk {
+class ImportThunkChunkX86 : public NonSectionChunk {
 public:
-  explicit ImportThunkChunkX86(Defined *S) : ImpSymbol(S) {}
+  explicit ImportThunkChunkX86(Defined *S) : ImpSymbol(S) {
+  }
   size_t getSize() const override { return sizeof(ImportThunkX86); }
   void getBaserels(std::vector<Baserel> *Res) override;
   void writeTo(uint8_t *Buf) const override;
@@ -402,9 +504,10 @@ private:
   Defined *ImpSymbol;
 };
 
-class ImportThunkChunkARM : public Chunk {
+class ImportThunkChunkARM : public NonSectionChunk {
 public:
-  explicit ImportThunkChunkARM(Defined *S) : ImpSymbol(S) {}
+  explicit ImportThunkChunkARM(Defined *S) : ImpSymbol(S) {
+  }
   size_t getSize() const override { return sizeof(ImportThunkARM); }
   void getBaserels(std::vector<Baserel> *Res) override;
   void writeTo(uint8_t *Buf) const override;
@@ -415,9 +518,10 @@ private:
   Defined *ImpSymbol;
 };
 
-class ImportThunkChunkARM64 : public Chunk {
+class ImportThunkChunkARM64 : public NonSectionChunk {
 public:
-  explicit ImportThunkChunkARM64(Defined *S) : ImpSymbol(S) {}
+  explicit ImportThunkChunkARM64(Defined *S) : ImpSymbol(S) {
+  }
   size_t getSize() const override { return sizeof(ImportThunkARM64); }
   void writeTo(uint8_t *Buf) const override;
 
@@ -427,7 +531,7 @@ private:
   Defined *ImpSymbol;
 };
 
-class RangeExtensionThunkARM : public Chunk {
+class RangeExtensionThunkARM : public NonSectionChunk {
 public:
   explicit RangeExtensionThunkARM(Defined *T) : Target(T) {}
   size_t getSize() const override;
@@ -436,7 +540,7 @@ public:
   Defined *Target;
 };
 
-class RangeExtensionThunkARM64 : public Chunk {
+class RangeExtensionThunkARM64 : public NonSectionChunk {
 public:
   explicit RangeExtensionThunkARM64(Defined *T) : Target(T) {}
   size_t getSize() const override;
@@ -447,7 +551,7 @@ public:
 
 // Windows-specific.
 // See comments for DefinedLocalImport class.
-class LocalImportChunk : public Chunk {
+class LocalImportChunk : public NonSectionChunk {
 public:
   explicit LocalImportChunk(Defined *S) : Sym(S) {
     setAlignment(Config->Wordsize);
@@ -487,7 +591,7 @@ struct ChunkAndOffset {
 using SymbolRVASet = llvm::DenseSet<ChunkAndOffset>;
 
 // Table which contains symbol RVAs. Used for /safeseh and /guard:cf.
-class RVATableChunk : public Chunk {
+class RVATableChunk : public NonSectionChunk {
 public:
   explicit RVATableChunk(SymbolRVASet S) : Syms(std::move(S)) {}
   size_t getSize() const override { return Syms.size() * 4; }
@@ -500,7 +604,7 @@ private:
 // Windows-specific.
 // This class represents a block in .reloc section.
 // See the PE/COFF spec 5.6 for details.
-class BaserelChunk : public Chunk {
+class BaserelChunk : public NonSectionChunk {
 public:
   BaserelChunk(uint32_t Page, Baserel *Begin, Baserel *End);
   size_t getSize() const override { return Data.size(); }
@@ -524,7 +628,7 @@ public:
 // specific place in a section, without any data. This is used for the MinGW
 // specific symbol __RUNTIME_PSEUDO_RELOC_LIST_END__, even though the concept
 // of an empty chunk isn't MinGW specific.
-class EmptyChunk : public Chunk {
+class EmptyChunk : public NonSectionChunk {
 public:
   EmptyChunk() {}
   size_t getSize() const override { return 0; }
@@ -537,7 +641,7 @@ public:
 // the reference didn't use the dllimport attribute. The MinGW runtime will
 // process this table after loading, before handling control over to user
 // code.
-class PseudoRelocTableChunk : public Chunk {
+class PseudoRelocTableChunk : public NonSectionChunk {
 public:
   PseudoRelocTableChunk(std::vector<RuntimePseudoReloc> &Relocs)
       : Relocs(std::move(Relocs)) {
@@ -568,7 +672,7 @@ public:
 };
 
 // MinGW specific. A Chunk that contains one pointer-sized absolute value.
-class AbsolutePointerChunk : public Chunk {
+class AbsolutePointerChunk : public NonSectionChunk {
 public:
   AbsolutePointerChunk(uint64_t Value) : Value(Value) {
     setAlignment(getSize());

Modified: lld/trunk/COFF/DLL.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/DLL.cpp?rev=361667&r1=361666&r2=361667&view=diff
==============================================================================
--- lld/trunk/COFF/DLL.cpp (original)
+++ lld/trunk/COFF/DLL.cpp Fri May 24 13:25:40 2019
@@ -35,7 +35,7 @@ namespace {
 // Import table
 
 // A chunk for the import descriptor table.
-class HintNameChunk : public Chunk {
+class HintNameChunk : public NonSectionChunk {
 public:
   HintNameChunk(StringRef N, uint16_t H) : Name(N), Hint(H) {}
 
@@ -57,7 +57,7 @@ private:
 };
 
 // A chunk for the import descriptor table.
-class LookupChunk : public Chunk {
+class LookupChunk : public NonSectionChunk {
 public:
   explicit LookupChunk(Chunk *C) : HintName(C) {
     setAlignment(Config->Wordsize);
@@ -77,7 +77,7 @@ public:
 // A chunk for the import descriptor table.
 // This chunk represent import-by-ordinal symbols.
 // See Microsoft PE/COFF spec 7.1. Import Header for details.
-class OrdinalOnlyChunk : public Chunk {
+class OrdinalOnlyChunk : public NonSectionChunk {
 public:
   explicit OrdinalOnlyChunk(uint16_t V) : Ordinal(V) {
     setAlignment(Config->Wordsize);
@@ -98,7 +98,7 @@ public:
 };
 
 // A chunk for the import descriptor table.
-class ImportDirectoryChunk : public Chunk {
+class ImportDirectoryChunk : public NonSectionChunk {
 public:
   explicit ImportDirectoryChunk(Chunk *N) : DLLName(N) {}
   size_t getSize() const override { return sizeof(ImportDirectoryTableEntry); }
@@ -119,10 +119,9 @@ public:
 
 // A chunk representing null terminator in the import table.
 // Contents of this chunk is always null bytes.
-class NullChunk : public Chunk {
+class NullChunk : public NonSectionChunk {
 public:
-  explicit NullChunk(size_t N) : Size(N) {}
-  bool hasData() const override { return false; }
+  explicit NullChunk(size_t N) : Size(N) { HasData = false; }
   size_t getSize() const override { return Size; }
 
   void writeTo(uint8_t *Buf) const override {
@@ -162,7 +161,7 @@ binImports(const std::vector<DefinedImpo
 // See Microsoft PE/COFF spec 4.3 for details.
 
 // A chunk for the delay import descriptor table etnry.
-class DelayDirectoryChunk : public Chunk {
+class DelayDirectoryChunk : public NonSectionChunk {
 public:
   explicit DelayDirectoryChunk(Chunk *N) : DLLName(N) {}
 
@@ -274,7 +273,7 @@ static const uint8_t ThunkARM64[] = {
 };
 
 // A chunk for the delay import thunk.
-class ThunkChunkX64 : public Chunk {
+class ThunkChunkX64 : public NonSectionChunk {
 public:
   ThunkChunkX64(Defined *I, Chunk *D, Defined *H)
       : Imp(I), Desc(D), Helper(H) {}
@@ -293,7 +292,7 @@ public:
   Defined *Helper = nullptr;
 };
 
-class ThunkChunkX86 : public Chunk {
+class ThunkChunkX86 : public NonSectionChunk {
 public:
   ThunkChunkX86(Defined *I, Chunk *D, Defined *H)
       : Imp(I), Desc(D), Helper(H) {}
@@ -317,7 +316,7 @@ public:
   Defined *Helper = nullptr;
 };
 
-class ThunkChunkARM : public Chunk {
+class ThunkChunkARM : public NonSectionChunk {
 public:
   ThunkChunkARM(Defined *I, Chunk *D, Defined *H)
       : Imp(I), Desc(D), Helper(H) {}
@@ -341,7 +340,7 @@ public:
   Defined *Helper = nullptr;
 };
 
-class ThunkChunkARM64 : public Chunk {
+class ThunkChunkARM64 : public NonSectionChunk {
 public:
   ThunkChunkARM64(Defined *I, Chunk *D, Defined *H)
       : Imp(I), Desc(D), Helper(H) {}
@@ -363,7 +362,7 @@ public:
 };
 
 // A chunk for the import descriptor table.
-class DelayAddressChunk : public Chunk {
+class DelayAddressChunk : public NonSectionChunk {
 public:
   explicit DelayAddressChunk(Chunk *C) : Thunk(C) {
     setAlignment(Config->Wordsize);
@@ -393,7 +392,7 @@ public:
 // Read Microsoft PE/COFF spec 5.3 for details.
 
 // A chunk for the export descriptor table.
-class ExportDirectoryChunk : public Chunk {
+class ExportDirectoryChunk : public NonSectionChunk {
 public:
   ExportDirectoryChunk(int I, int J, Chunk *D, Chunk *A, Chunk *N, Chunk *O)
       : MaxOrdinal(I), NameTabSize(J), DLLName(D), AddressTab(A), NameTab(N),
@@ -424,7 +423,7 @@ public:
   Chunk *OrdinalTab;
 };
 
-class AddressTableChunk : public Chunk {
+class AddressTableChunk : public NonSectionChunk {
 public:
   explicit AddressTableChunk(size_t MaxOrdinal) : Size(MaxOrdinal + 1) {}
   size_t getSize() const override { return Size * 4; }
@@ -450,7 +449,7 @@ private:
   size_t Size;
 };
 
-class NamePointersChunk : public Chunk {
+class NamePointersChunk : public NonSectionChunk {
 public:
   explicit NamePointersChunk(std::vector<Chunk *> &V) : Chunks(V) {}
   size_t getSize() const override { return Chunks.size() * 4; }
@@ -466,7 +465,7 @@ private:
   std::vector<Chunk *> Chunks;
 };
 
-class ExportOrdinalChunk : public Chunk {
+class ExportOrdinalChunk : public NonSectionChunk {
 public:
   explicit ExportOrdinalChunk(size_t I) : Size(I) {}
   size_t getSize() const override { return Size * 2; }

Modified: lld/trunk/COFF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Writer.cpp?rev=361667&r1=361666&r2=361667&view=diff
==============================================================================
--- lld/trunk/COFF/Writer.cpp (original)
+++ lld/trunk/COFF/Writer.cpp Fri May 24 13:25:40 2019
@@ -88,7 +88,7 @@ OutputSection *Chunk::getOutputSection()
 
 namespace {
 
-class DebugDirectoryChunk : public Chunk {
+class DebugDirectoryChunk : public NonSectionChunk {
 public:
   DebugDirectoryChunk(const std::vector<Chunk *> &R, bool WriteRepro)
       : Records(R), WriteRepro(WriteRepro) {}
@@ -143,7 +143,7 @@ private:
   bool WriteRepro;
 };
 
-class CVDebugRecordChunk : public Chunk {
+class CVDebugRecordChunk : public NonSectionChunk {
 public:
   size_t getSize() const override {
     return sizeof(codeview::DebugInfo) + Config->PDBAltPath.size() + 1;




More information about the llvm-commits mailing list