diff --git a/clang/include/clang/Frontend/PCHReader.h b/clang/include/clang/Frontend/PCHReader.h index e19669ec7f40..d50979379b88 100644 --- a/clang/include/clang/Frontend/PCHReader.h +++ b/clang/include/clang/Frontend/PCHReader.h @@ -285,6 +285,23 @@ private: /// \brief Method selectors used in a @selector expression. Used for /// implementation of -Wselector. llvm::SmallVector ReferencedSelectorsData; + + /// \brief A pointer to an on-disk hash table of opaque type + /// PCHMethodPoolLookupTable. + /// + /// This hash table provides the instance and factory methods + /// associated with every selector known in the PCH file. + void *MethodPoolLookupTable; + + /// \brief A pointer to the character data that comprises the method + /// pool. + /// + /// The SelectorOffsets table refers into this memory. + const unsigned char *MethodPoolLookupTableData; + + /// \brief Offsets into the method pool lookup table's data array + /// where each selector resides. + const uint32_t *SelectorOffsets; }; /// \brief The chain of PCH files. The first entry is the one named by the @@ -337,26 +354,9 @@ private: /// been loaded. std::vector IdentifiersLoaded; - /// \brief A pointer to an on-disk hash table of opaque type - /// PCHMethodPoolLookupTable. - /// - /// This hash table provides the instance and factory methods - /// associated with every selector known in the PCH file. - void *MethodPoolLookupTable; - - /// \brief A pointer to the character data that comprises the method - /// pool. - /// - /// The SelectorOffsets table refers into this memory. - const unsigned char *MethodPoolLookupTableData; - /// \brief The number of selectors stored in the method pool itself. unsigned TotalSelectorsInMethodPool; - /// \brief Offsets into the method pool lookup table's data array - /// where each selector resides. - const uint32_t *SelectorOffsets; - /// \brief The total number of selectors stored in the PCH file. unsigned TotalNumSelectors; diff --git a/clang/include/clang/Frontend/PCHWriter.h b/clang/include/clang/Frontend/PCHWriter.h index 3ba5691ebc1c..86ff02674842 100644 --- a/clang/include/clang/Frontend/PCHWriter.h +++ b/clang/include/clang/Frontend/PCHWriter.h @@ -259,7 +259,7 @@ private: uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC); uint64_t WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC); void WriteTypeDeclOffsets(); - void WriteMethodPool(Sema &SemaRef); + void WriteSelectors(Sema &SemaRef); void WriteReferencedSelectorsPool(Sema &SemaRef); void WriteIdentifierTable(Preprocessor &PP); void WriteAttributeRecord(const Attr *Attr); diff --git a/clang/lib/Frontend/PCHReader.cpp b/clang/lib/Frontend/PCHReader.cpp index 35909a055566..7d3a25f367a5 100644 --- a/clang/lib/Frontend/PCHReader.cpp +++ b/clang/lib/Frontend/PCHReader.cpp @@ -418,15 +418,14 @@ PCHReader::PCHReader(Preprocessor &PP, ASTContext *Context, : Listener(new PCHValidator(PP, *this)), DeserializationListener(0), SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()), Diags(PP.getDiagnostics()), SemaObj(0), PP(&PP), Context(Context), - Consumer(0), MethodPoolLookupTable(0), MethodPoolLookupTableData(0), - TotalSelectorsInMethodPool(0), SelectorOffsets(0), - TotalNumSelectors(0), isysroot(isysroot), - DisableValidation(DisableValidation), NumStatHits(0), NumStatMisses(0), - NumSLocEntriesRead(0), TotalNumSLocEntries(0), NumStatementsRead(0), - TotalNumStatements(0), NumMacrosRead(0), NumMethodPoolSelectorsRead(0), - NumMethodPoolMisses(0), TotalNumMacros(0), NumLexicalDeclContextsRead(0), - TotalLexicalDeclContexts(0), NumVisibleDeclContextsRead(0), - TotalVisibleDeclContexts(0), NumCurrentElementsDeserializing(0) { + Consumer(0), TotalSelectorsInMethodPool(0), TotalNumSelectors(0), + isysroot(isysroot), DisableValidation(DisableValidation), NumStatHits(0), + NumStatMisses(0), NumSLocEntriesRead(0), TotalNumSLocEntries(0), + NumStatementsRead(0), TotalNumStatements(0), NumMacrosRead(0), + NumMethodPoolSelectorsRead(0), NumMethodPoolMisses(0), TotalNumMacros(0), + NumLexicalDeclContextsRead(0), TotalLexicalDeclContexts(0), + NumVisibleDeclContextsRead(0), TotalVisibleDeclContexts(0), + NumCurrentElementsDeserializing(0) { RelocatablePCH = false; } @@ -435,9 +434,7 @@ PCHReader::PCHReader(SourceManager &SourceMgr, FileManager &FileMgr, bool DisableValidation) : DeserializationListener(0), SourceMgr(SourceMgr), FileMgr(FileMgr), Diags(Diags), SemaObj(0), PP(0), Context(0), Consumer(0), - MethodPoolLookupTable(0), MethodPoolLookupTableData(0), - TotalSelectorsInMethodPool(0), SelectorOffsets(0), - TotalNumSelectors(0), isysroot(isysroot), + TotalSelectorsInMethodPool(0), TotalNumSelectors(0), isysroot(isysroot), DisableValidation(DisableValidation), NumStatHits(0), NumStatMisses(0), NumSLocEntriesRead(0), TotalNumSLocEntries(0), NumStatementsRead(0), TotalNumStatements(0), NumMacrosRead(0), NumMethodPoolSelectorsRead(0), @@ -457,7 +454,8 @@ PCHReader::PerFileData::PerFileData() LocalNumDecls(0), DeclOffsets(0), LocalNumIdentifiers(0), IdentifierOffsets(0), IdentifierTableData(0), IdentifierLookupTable(0), LocalNumMacroDefinitions(0), MacroDefinitionOffsets(0), - NumPreallocatedPreprocessingEntities(0) + NumPreallocatedPreprocessingEntities(0), MethodPoolLookupTable(0), + MethodPoolLookupTableData(0), SelectorOffsets(0) {} void @@ -1648,18 +1646,18 @@ PCHReader::ReadPCHBlock(PerFileData &F) { break; case pch::SELECTOR_OFFSETS: - SelectorOffsets = (const uint32_t *)BlobStart; + F.SelectorOffsets = (const uint32_t *)BlobStart; TotalNumSelectors = Record[0]; SelectorsLoaded.resize(TotalNumSelectors); break; case pch::METHOD_POOL: - MethodPoolLookupTableData = (const unsigned char *)BlobStart; + F.MethodPoolLookupTableData = (const unsigned char *)BlobStart; if (Record[0]) - MethodPoolLookupTable + F.MethodPoolLookupTable = PCHMethodPoolLookupTable::Create( - MethodPoolLookupTableData + Record[0], - MethodPoolLookupTableData, + Chain[0]->MethodPoolLookupTableData + Record[0], + Chain[0]->MethodPoolLookupTableData, PCHMethodPoolLookupTrait(*this)); TotalSelectorsInMethodPool = Record[1]; break; @@ -3208,12 +3206,12 @@ IdentifierInfo* PCHReader::get(const char *NameStart, const char *NameEnd) { std::pair PCHReader::ReadMethodPool(Selector Sel) { - if (!MethodPoolLookupTable) + if (!Chain[0]->MethodPoolLookupTable) return std::pair(); // Try to find this selector within our on-disk hash table. PCHMethodPoolLookupTable *PoolTable - = (PCHMethodPoolLookupTable*)MethodPoolLookupTable; + = (PCHMethodPoolLookupTable*)Chain[0]->MethodPoolLookupTable; PCHMethodPoolLookupTable::iterator Pos = PoolTable->find(Sel); if (Pos == PoolTable->end()) { ++NumMethodPoolMisses; @@ -3329,7 +3327,7 @@ Selector PCHReader::DecodeSelector(unsigned ID) { if (ID == 0) return Selector(); - if (!MethodPoolLookupTableData) + if (!Chain[0]->MethodPoolLookupTableData) return Selector(); if (ID > TotalNumSelectors) { @@ -3340,10 +3338,10 @@ Selector PCHReader::DecodeSelector(unsigned ID) { unsigned Index = ID - 1; if (SelectorsLoaded[Index].getAsOpaquePtr() == 0) { // Load this selector from the selector table. - // FIXME: endianness portability issues with SelectorOffsets table PCHMethodPoolLookupTrait Trait(*this); SelectorsLoaded[Index] - = Trait.ReadKey(MethodPoolLookupTableData + SelectorOffsets[Index], 0); + = Trait.ReadKey(Chain[0]->MethodPoolLookupTableData + + Chain[0]->SelectorOffsets[Index], 0); } return SelectorsLoaded[Index]; diff --git a/clang/lib/Frontend/PCHWriter.cpp b/clang/lib/Frontend/PCHWriter.cpp index 776a40940d76..4517bf20734a 100644 --- a/clang/lib/Frontend/PCHWriter.cpp +++ b/clang/lib/Frontend/PCHWriter.cpp @@ -1640,51 +1640,41 @@ public: }; } // end anonymous namespace -/// \brief Write the method pool into the PCH file. +/// \brief Write ObjC data: selectors and the method pool. /// /// The method pool contains both instance and factory methods, stored -/// in an on-disk hash table indexed by the selector. -void PCHWriter::WriteMethodPool(Sema &SemaRef) { +/// in an on-disk hash table indexed by the selector. The hash table also +/// contains an empty entry for every other selector known to Sema. +void PCHWriter::WriteSelectors(Sema &SemaRef) { using namespace llvm; - // Create and write out the blob that contains the instance and - // factor method pools. - bool Empty = true; + // Do we have to do anything at all? + if (SemaRef.MethodPool.empty() && SelVector.empty()) + return; + // Create and write out the blob that contains selectors and the method pool. { OnDiskChainedHashTableGenerator Generator; - // Create the on-disk hash table representation. Start by - // iterating through the method pool. - PCHMethodPoolTrait::key_type Key; - unsigned NumSelectorsInMethodPool = 0; - for (Sema::GlobalMethodPool::iterator I = SemaRef.MethodPool.begin(), - E = SemaRef.MethodPool.end(); - I != E; ++I) { - Generator.insert(I->first, I->second); - ++NumSelectorsInMethodPool; - Empty = false; + // Create the on-disk hash table representation. We walk through every + // selector we've seen and look it up in the method pool. + SelectorOffsets.resize(SelVector.size()); + for (unsigned I = 0, N = SelVector.size(); I != N; ++I) { + Selector S = SelVector[I]; + Sema::GlobalMethodPool::iterator F = SemaRef.MethodPool.find(S); + Generator.insert(S, F != SemaRef.MethodPool.end() ? F->second : + std::make_pair(ObjCMethodList(), ObjCMethodList())); + } - if (Empty && SelectorOffsets.empty()) - return; - // Create the on-disk hash table in a buffer. llvm::SmallString<4096> MethodPool; uint32_t BucketOffset; - SelectorOffsets.resize(SelVector.size()); { PCHMethodPoolTrait Trait(*this); llvm::raw_svector_ostream Out(MethodPool); // Make sure that no bucket is at offset 0 clang::io::Emit32(Out, 0); BucketOffset = Generator.Emit(Out, Trait); - - // For every selector that we have seen but which was not - // written into the hash table, write the selector itself and - // record it's offset. - for (unsigned I = 0, N = SelVector.size(); I != N; ++I) - if (SelectorOffsets[I] == 0) - Trait.EmitKey(Out, SelVector[I], 0); } // Create a blob abbreviation @@ -1699,7 +1689,7 @@ void PCHWriter::WriteMethodPool(Sema &SemaRef) { RecordData Record; Record.push_back(pch::METHOD_POOL); Record.push_back(BucketOffset); - Record.push_back(NumSelectorsInMethodPool); + Record.push_back(SelVector.size()); Stream.EmitRecordWithBlob(MethodPoolAbbrev, Record, MethodPool.str()); // Create a blob abbreviation for the selector table offsets. @@ -2262,7 +2252,7 @@ void PCHWriter::WritePCHCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, Stream.ExitBlock(); WritePreprocessor(PP); - WriteMethodPool(SemaRef); + WriteSelectors(SemaRef); WriteReferencedSelectorsPool(SemaRef); WriteIdentifierTable(PP);