diff --git a/lld/MachO/Symbols.h b/lld/MachO/Symbols.h --- a/lld/MachO/Symbols.h +++ b/lld/MachO/Symbols.h @@ -92,14 +92,14 @@ protected: Symbol(Kind k, StringRefZ name, InputFile *file) - : symbolKind(k), nameData(name.data), nameSize(name.size), file(file), + : symbolKind(k), nameData(name.data), file(file), nameSize(name.size), isUsedInRegularObj(!file || isa(file)), used(!config->deadStrip) {} Kind symbolKind; const char *nameData; - mutable uint32_t nameSize; InputFile *file; + mutable uint32_t nameSize; public: // True if this symbol was referenced by a regular (non-bitcode) object. @@ -109,6 +109,9 @@ bool used : 1; }; +static_assert(sizeof(void *) != 8 || sizeof(Symbol) == 48, + "Try to minimize Symbol's size; we create many instances"); + class Defined : public Symbol { public: Defined(StringRefZ name, InputFile *file, InputSection *isec, uint64_t value, @@ -133,14 +136,8 @@ static bool classof(const Symbol *s) { return s->kind() == DefinedKind; } - InputSection *isec; - // Contains the offset from the containing subsection. Note that this is - // different from nlist::n_value, which is the absolute address of the symbol. - uint64_t value; - // size is only calculated for regular (non-bitcode) symbols. - uint64_t size; - ConcatInputSection *compactUnwind = nullptr; - + // Place the bitfields first so that they can get placed in the tail padding + // of the parent class, on platforms which support it. bool overridesWeakDef : 1; // Whether this symbol should appear in the output binary's export trie. bool privateExtern : 1; @@ -166,8 +163,24 @@ private: const bool weakDef : 1; const bool external : 1; + +public: + InputSection *isec; + // Contains the offset from the containing subsection. Note that this is + // different from nlist::n_value, which is the absolute address of the symbol. + uint64_t value; + // size is only calculated for regular (non-bitcode) symbols. + uint64_t size; + ConcatInputSection *compactUnwind = nullptr; }; +// The Microsoft ABI doesn't support using parent class tail padding for child +// members, hence the _MSC_VER check. +#if !defined(_MSC_VER) +static_assert(sizeof(void *) != 8 || sizeof(Defined) == 80, + "Try to minimize Defined's size; we create many instances"); +#endif + // This enum does double-duty: as a symbol property, it indicates whether & how // a dylib symbol is referenced. As a DylibFile property, it indicates the kind // of referenced symbols contained within the file. If there are both weak @@ -294,6 +307,9 @@ alignas(LazySymbol) char e[sizeof(LazySymbol)]; }; +static_assert(sizeof(SymbolUnion) == sizeof(Defined), + "Defined should be the largest Symbol kind"); + template T *replaceSymbol(Symbol *s, ArgT &&...arg) { static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small"); diff --git a/lld/MachO/Symbols.cpp b/lld/MachO/Symbols.cpp --- a/lld/MachO/Symbols.cpp +++ b/lld/MachO/Symbols.cpp @@ -36,12 +36,11 @@ bool isPrivateExtern, bool isThumb, bool isReferencedDynamically, bool noDeadStrip, bool canOverrideWeakDef, bool isWeakDefCanBeHidden) - : Symbol(DefinedKind, name, file), isec(isec), value(value), size(size), - overridesWeakDef(canOverrideWeakDef), privateExtern(isPrivateExtern), - includeInSymtab(true), thumb(isThumb), + : Symbol(DefinedKind, name, file), overridesWeakDef(canOverrideWeakDef), + privateExtern(isPrivateExtern), includeInSymtab(true), thumb(isThumb), referencedDynamically(isReferencedDynamically), noDeadStrip(noDeadStrip), weakDefCanBeHidden(isWeakDefCanBeHidden), weakDef(isWeakDef), - external(isExternal) { + external(isExternal), isec(isec), value(value), size(size) { if (isec) { isec->symbols.push_back(this); // Maintain sorted order.