Incomplete promotion of selector info to per-file data.

Store all selectors in the selector hash table instead of only those from the method pool.

llvm-svn: 110158
This commit is contained in:
Sebastian Redl 2010-08-03 21:58:15 +00:00
parent 5442c71f2e
commit a19a67f899
4 changed files with 58 additions and 70 deletions

View File

@ -285,6 +285,23 @@ private:
/// \brief Method selectors used in a @selector expression. Used for
/// implementation of -Wselector.
llvm::SmallVector<long long unsigned int,64u> 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<IdentifierInfo *> 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;

View File

@ -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);

View File

@ -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<ObjCMethodList, ObjCMethodList>
PCHReader::ReadMethodPool(Selector Sel) {
if (!MethodPoolLookupTable)
if (!Chain[0]->MethodPoolLookupTable)
return std::pair<ObjCMethodList, ObjCMethodList>();
// 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];

View File

@ -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<PCHMethodPoolTrait> 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);