From: Justin Bogner Date: Mon, 14 Apr 2014 16:34:29 +0000 (+0000) Subject: OnDiskHashTable: Make the iterable version separate. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ed3bdc5f9ada3d87f1a7e7892305d240edd15c68;p=clang OnDiskHashTable: Make the iterable version separate. Currently the on disk hash table's key_iterator and data_iterator make the assumption that the table data starts exactly four bytes after the base of the table. This happens to be true for all of the tables we currently iterate over, but not for all of the OnDiskHashTables we currently use. For example, key_ and data_iterator would iterate over meaningless data if they were used on the hash tables in PTHLexer. We make the API safer by breaking this into two types. One doesn't have the iterators, and the other must be told where the payload starts. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@206189 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/OnDiskHashTable.h b/include/clang/Basic/OnDiskHashTable.h index f9ac613f28..1a9a96abe8 100644 --- a/include/clang/Basic/OnDiskHashTable.h +++ b/include/clang/Basic/OnDiskHashTable.h @@ -266,6 +266,41 @@ public: iterator end() const { return iterator(); } + Info &getInfoObj() { return InfoObj; } + + static OnDiskChainedHashTable* Create(const unsigned char* Buckets, + const unsigned char* const Base, + const Info &InfoObj = Info()) { + using namespace llvm::support; + assert(Buckets > Base); + assert((reinterpret_cast(Buckets) & 0x3) == 0 && + "buckets should be 4-byte aligned."); + + unsigned NumBuckets = endian::readNext(Buckets); + unsigned NumEntries = endian::readNext(Buckets); + return new OnDiskChainedHashTable(NumBuckets, NumEntries, Buckets, + Base, InfoObj); + } +}; + +template +class OnDiskIterableChainedHashTable : public OnDiskChainedHashTable { + const unsigned char *Payload; + +public: + typedef OnDiskChainedHashTable base_type; + typedef typename base_type::internal_key_type internal_key_type; + typedef typename base_type::external_key_type external_key_type; + typedef typename base_type::data_type data_type; + + OnDiskIterableChainedHashTable(unsigned NumBuckets, unsigned NumEntries, + const unsigned char *Buckets, + const unsigned char *Payload, + const unsigned char *Base, + const Info &InfoObj = Info()) + : base_type(NumBuckets, NumEntries, Buckets, Base, InfoObj), + Payload(Payload) {} + /// \brief Iterates over all of the keys in the table. class key_iterator { const unsigned char *Ptr; @@ -329,7 +364,7 @@ public: }; key_iterator key_begin() { - return key_iterator(Base + 4, getNumEntries(), &InfoObj); + return key_iterator(Payload, this->getNumEntries(), &this->getInfoObj()); } key_iterator key_end() { return key_iterator(); } @@ -396,15 +431,13 @@ public: }; data_iterator data_begin() { - return data_iterator(Base + 4, getNumEntries(), &InfoObj); + return data_iterator(Payload, this->getNumEntries(), &this->getInfoObj()); } data_iterator data_end() { return data_iterator(); } - Info &getInfoObj() { return InfoObj; } - - static OnDiskChainedHashTable *Create(const unsigned char *Buckets, - const unsigned char *const Base, - const Info &InfoObj = Info()) { + static OnDiskIterableChainedHashTable * + Create(const unsigned char *Buckets, const unsigned char *const Payload, + const unsigned char *const Base, const Info &InfoObj = Info()) { using namespace llvm::support; assert(Buckets > Base); assert((reinterpret_cast(Buckets) & 0x3) == 0 && @@ -412,8 +445,8 @@ public: unsigned NumBuckets = endian::readNext(Buckets); unsigned NumEntries = endian::readNext(Buckets); - return new OnDiskChainedHashTable(NumBuckets, NumEntries, Buckets, - Base, InfoObj); + return new OnDiskIterableChainedHashTable( + NumBuckets, NumEntries, Buckets, Payload, Base, InfoObj); } }; diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index b19991a6ea..54002aa52a 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -254,7 +254,7 @@ class ReadMethodPoolVisitor; namespace reader { class ASTIdentifierLookupTrait; /// \brief The on-disk hash table used for the DeclContext's Name lookup table. - typedef OnDiskChainedHashTable + typedef OnDiskIterableChainedHashTable ASTDeclContextNameLookupTable; } diff --git a/include/clang/Serialization/Module.h b/include/clang/Serialization/Module.h index 469785de7c..626901ed79 100644 --- a/include/clang/Serialization/Module.h +++ b/include/clang/Serialization/Module.h @@ -29,6 +29,7 @@ class FileEntry; class DeclContext; class Module; template class OnDiskChainedHashTable; +template class OnDiskIterableChainedHashTable; namespace serialization { @@ -49,7 +50,7 @@ struct DeclContextInfo { DeclContextInfo() : NameLookupTableData(), LexicalDecls(), NumLexicalDecls() {} - OnDiskChainedHashTable + OnDiskIterableChainedHashTable *NameLookupTableData; // an ASTDeclContextNameLookupTable. const KindDeclIDPair *LexicalDecls; unsigned NumLexicalDecls; diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 18768353c1..1d1957d6bf 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -851,11 +851,11 @@ bool ASTReader::ReadDeclContextStorage(ModuleFile &M, Error("Expected visible lookup table block"); return true; } - Info.NameLookupTableData - = ASTDeclContextNameLookupTable::Create( - (const unsigned char *)Blob.data() + Record[0], - (const unsigned char *)Blob.data(), - ASTDeclContextNameLookupTrait(*this, M)); + Info.NameLookupTableData = ASTDeclContextNameLookupTable::Create( + (const unsigned char *)Blob.data() + Record[0], + (const unsigned char *)Blob.data() + sizeof(uint32_t), + (const unsigned char *)Blob.data(), + ASTDeclContextNameLookupTrait(*this, M)); } return false; @@ -2509,10 +2509,11 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { unsigned Idx = 0; serialization::DeclID ID = ReadDeclID(F, Record, Idx); ASTDeclContextNameLookupTable *Table = - ASTDeclContextNameLookupTable::Create( - (const unsigned char *)Blob.data() + Record[Idx++], - (const unsigned char *)Blob.data(), - ASTDeclContextNameLookupTrait(*this, F)); + ASTDeclContextNameLookupTable::Create( + (const unsigned char *)Blob.data() + Record[Idx++], + (const unsigned char *)Blob.data() + sizeof(uint32_t), + (const unsigned char *)Blob.data(), + ASTDeclContextNameLookupTrait(*this, F)); if (ID == PREDEF_DECL_TRANSLATION_UNIT_ID) { // Is it the TU? DeclContext *TU = Context.getTranslationUnitDecl(); F.DeclContextInfos[TU].NameLookupTableData = Table; @@ -2531,11 +2532,11 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { case IDENTIFIER_TABLE: F.IdentifierTableData = Blob.data(); if (Record[0]) { - F.IdentifierLookupTable - = ASTIdentifierLookupTable::Create( - (const unsigned char *)F.IdentifierTableData + Record[0], - (const unsigned char *)F.IdentifierTableData, - ASTIdentifierLookupTrait(*this, F)); + F.IdentifierLookupTable = ASTIdentifierLookupTable::Create( + (const unsigned char *)F.IdentifierTableData + Record[0], + (const unsigned char *)F.IdentifierTableData + sizeof(uint32_t), + (const unsigned char *)F.IdentifierTableData, + ASTIdentifierLookupTrait(*this, F)); PP.getIdentifierTable().setExternalIdentifierLookup(this); } diff --git a/lib/Serialization/ASTReaderInternals.h b/lib/Serialization/ASTReaderInternals.h index 9149b18480..fd328926eb 100644 --- a/lib/Serialization/ASTReaderInternals.h +++ b/lib/Serialization/ASTReaderInternals.h @@ -140,7 +140,7 @@ public: /// \brief The on-disk hash table used to contain information about /// all of the identifiers in the program. -typedef OnDiskChainedHashTable +typedef OnDiskIterableChainedHashTable ASTIdentifierLookupTable; /// \brief Class that performs lookup for a selector's entries in the global diff --git a/lib/Serialization/GlobalModuleIndex.cpp b/lib/Serialization/GlobalModuleIndex.cpp index 14b149f078..804a14363a 100644 --- a/lib/Serialization/GlobalModuleIndex.cpp +++ b/lib/Serialization/GlobalModuleIndex.cpp @@ -114,7 +114,8 @@ public: } }; -typedef OnDiskChainedHashTable IdentifierIndexTable; +typedef OnDiskIterableChainedHashTable + IdentifierIndexTable; } @@ -210,9 +211,9 @@ GlobalModuleIndex::GlobalModuleIndex(llvm::MemoryBuffer *Buffer, // Wire up the identifier index. if (Record[0]) { IdentifierIndex = IdentifierIndexTable::Create( - (const unsigned char *)Blob.data() + Record[0], - (const unsigned char *)Blob.data(), - IdentifierIndexReaderTrait()); + (const unsigned char *)Blob.data() + Record[0], + (const unsigned char *)Blob.data() + sizeof(uint32_t), + (const unsigned char *)Blob.data(), IdentifierIndexReaderTrait()); } break; } @@ -591,11 +592,13 @@ bool GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) { // Handle the identifier table if (State == ASTBlock && Code == IDENTIFIER_TABLE && Record[0] > 0) { - typedef OnDiskChainedHashTable - InterestingIdentifierTable; + typedef + OnDiskIterableChainedHashTable + InterestingIdentifierTable; std::unique_ptr Table( InterestingIdentifierTable::Create( (const unsigned char *)Blob.data() + Record[0], + (const unsigned char *)Blob.data() + sizeof(uint32_t), (const unsigned char *)Blob.data())); for (InterestingIdentifierTable::data_iterator D = Table->data_begin(), DEnd = Table->data_end();