Reapply r202420 hopefully fixed for other STLs

Keep the copy constructor around, and add a FIXME that we should really
remove it as soon as we have C++11 std::map's emplace function.

llvm-svn: 202439
This commit is contained in:
Ben Langmuir 2014-02-27 22:21:32 +00:00
parent c329937011
commit c9b7234e5c
2 changed files with 20 additions and 64 deletions

View File

@ -27,6 +27,7 @@
#include "llvm/Support/Allocator.h" #include "llvm/Support/Allocator.h"
// FIXME: Enhance libsystem to support inode and other fields in stat. // FIXME: Enhance libsystem to support inode and other fields in stat.
#include <sys/types.h> #include <sys/types.h>
#include <map>
#ifdef _MSC_VER #ifdef _MSC_VER
typedef unsigned short mode_t; typedef unsigned short mode_t;
@ -76,25 +77,19 @@ class FileEntry {
File.reset(0); // rely on destructor to close File File.reset(0); // rely on destructor to close File
} }
void operator=(const FileEntry &) LLVM_DELETED_FUNCTION;
public: public:
FileEntry(llvm::sys::fs::UniqueID UniqueID, bool IsNamedPipe, bool InPCH)
: Name(0), UniqueID(UniqueID), IsNamedPipe(IsNamedPipe), InPCH(InPCH),
IsValid(false)
{}
// Add a default constructor for use with llvm::StringMap
FileEntry() FileEntry()
: Name(0), UniqueID(0, 0), IsNamedPipe(false), InPCH(false), : Name(0), UniqueID(0, 0), IsNamedPipe(false), InPCH(false),
IsValid(false) IsValid(false)
{} {}
// FIXME: this is here to allow putting FileEntry in std::map. Once we have
// emplace, we shouldn't need a copy constructor anymore.
FileEntry(const FileEntry &FE) { FileEntry(const FileEntry &FE) {
memcpy(this, &FE, sizeof(FE)); memcpy(this, &FE, sizeof(FE));
assert(!File && "Cannot copy a file-owning FileEntry"); assert(!isValid() && "Cannot copy an initialized FileEntry");
}
void operator=(const FileEntry &FE) {
memcpy(this, &FE, sizeof(FE));
assert(!File && "Cannot assign a file-owning FileEntry");
} }
const char *getName() const { return Name; } const char *getName() const { return Name; }
@ -128,14 +123,11 @@ class FileManager : public RefCountedBase<FileManager> {
IntrusiveRefCntPtr<vfs::FileSystem> FS; IntrusiveRefCntPtr<vfs::FileSystem> FS;
FileSystemOptions FileSystemOpts; FileSystemOptions FileSystemOpts;
class UniqueDirContainer;
class UniqueFileContainer;
/// \brief Cache for existing real directories. /// \brief Cache for existing real directories.
UniqueDirContainer &UniqueRealDirs; std::map<llvm::sys::fs::UniqueID, DirectoryEntry> UniqueRealDirs;
/// \brief Cache for existing real files. /// \brief Cache for existing real files.
UniqueFileContainer &UniqueRealFiles; std::map<llvm::sys::fs::UniqueID, FileEntry> UniqueRealFiles;
/// \brief The virtual directories that we have allocated. /// \brief The virtual directories that we have allocated.
/// ///

View File

@ -43,41 +43,6 @@ using namespace clang;
/// represent a filename that doesn't exist on the disk. /// represent a filename that doesn't exist on the disk.
#define NON_EXISTENT_FILE reinterpret_cast<FileEntry*>((intptr_t)-1) #define NON_EXISTENT_FILE reinterpret_cast<FileEntry*>((intptr_t)-1)
class FileManager::UniqueDirContainer {
/// UniqueDirs - Cache from ID's to existing directories/files.
std::map<llvm::sys::fs::UniqueID, DirectoryEntry> UniqueDirs;
public:
/// getDirectory - Return an existing DirectoryEntry with the given
/// ID's if there is already one; otherwise create and return a
/// default-constructed DirectoryEntry.
DirectoryEntry &getDirectory(const llvm::sys::fs::UniqueID &UniqueID) {
return UniqueDirs[UniqueID];
}
size_t size() const { return UniqueDirs.size(); }
};
class FileManager::UniqueFileContainer {
/// UniqueFiles - Cache from ID's to existing directories/files.
std::set<FileEntry> UniqueFiles;
public:
/// getFile - Return an existing FileEntry with the given ID's if
/// there is already one; otherwise create and return a
/// default-constructed FileEntry.
FileEntry &getFile(llvm::sys::fs::UniqueID UniqueID, bool IsNamedPipe,
bool InPCH) {
return const_cast<FileEntry &>(
*UniqueFiles.insert(FileEntry(UniqueID, IsNamedPipe, InPCH)).first);
}
size_t size() const { return UniqueFiles.size(); }
void erase(const FileEntry *Entry) { UniqueFiles.erase(*Entry); }
};
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Common logic. // Common logic.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -85,8 +50,6 @@ public:
FileManager::FileManager(const FileSystemOptions &FSO, FileManager::FileManager(const FileSystemOptions &FSO,
IntrusiveRefCntPtr<vfs::FileSystem> FS) IntrusiveRefCntPtr<vfs::FileSystem> FS)
: FS(FS), FileSystemOpts(FSO), : FS(FS), FileSystemOpts(FSO),
UniqueRealDirs(*new UniqueDirContainer()),
UniqueRealFiles(*new UniqueFileContainer()),
SeenDirEntries(64), SeenFileEntries(64), NextFileUID(0) { SeenDirEntries(64), SeenFileEntries(64), NextFileUID(0) {
NumDirLookups = NumFileLookups = 0; NumDirLookups = NumFileLookups = 0;
NumDirCacheMisses = NumFileCacheMisses = 0; NumDirCacheMisses = NumFileCacheMisses = 0;
@ -98,8 +61,6 @@ FileManager::FileManager(const FileSystemOptions &FSO,
} }
FileManager::~FileManager() { FileManager::~FileManager() {
delete &UniqueRealDirs;
delete &UniqueRealFiles;
for (unsigned i = 0, e = VirtualFileEntries.size(); i != e; ++i) for (unsigned i = 0, e = VirtualFileEntries.size(); i != e; ++i)
delete VirtualFileEntries[i]; delete VirtualFileEntries[i];
for (unsigned i = 0, e = VirtualDirectoryEntries.size(); i != e; ++i) for (unsigned i = 0, e = VirtualDirectoryEntries.size(); i != e; ++i)
@ -243,8 +204,7 @@ const DirectoryEntry *FileManager::getDirectory(StringRef DirName,
// same inode (this occurs on Unix-like systems when one dir is // same inode (this occurs on Unix-like systems when one dir is
// symlinked to another, for example) or the same path (on // symlinked to another, for example) or the same path (on
// Windows). // Windows).
DirectoryEntry &UDE = DirectoryEntry &UDE = UniqueRealDirs[Data.UniqueID];
UniqueRealDirs.getDirectory(Data.UniqueID);
NamedDirEnt.setValue(&UDE); NamedDirEnt.setValue(&UDE);
if (!UDE.getName()) { if (!UDE.getName()) {
@ -310,8 +270,7 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile,
// It exists. See if we have already opened a file with the same inode. // It exists. See if we have already opened a file with the same inode.
// This occurs when one dir is symlinked to another, for example. // This occurs when one dir is symlinked to another, for example.
FileEntry &UFE = FileEntry &UFE = UniqueRealFiles[Data.UniqueID];
UniqueRealFiles.getFile(Data.UniqueID, Data.IsNamedPipe, Data.InPCH);
NamedFileEnt.setValue(&UFE); NamedFileEnt.setValue(&UFE);
if (UFE.isValid()) { // Already have an entry with this inode, return it. if (UFE.isValid()) { // Already have an entry with this inode, return it.
@ -322,14 +281,15 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile,
return &UFE; return &UFE;
} }
// Otherwise, we don't have this directory yet, add it. // Otherwise, we don't have this file yet, add it.
// FIXME: Change the name to be a char* that points back to the
// 'SeenFileEntries' key.
UFE.Name = InterndFileName; UFE.Name = InterndFileName;
UFE.Size = Data.Size; UFE.Size = Data.Size;
UFE.ModTime = Data.ModTime; UFE.ModTime = Data.ModTime;
UFE.Dir = DirInfo; UFE.Dir = DirInfo;
UFE.UID = NextFileUID++; UFE.UID = NextFileUID++;
UFE.UniqueID = Data.UniqueID;
UFE.IsNamedPipe = Data.IsNamedPipe;
UFE.InPCH = Data.InPCH;
UFE.File.reset(F); UFE.File.reset(F);
UFE.IsValid = true; UFE.IsValid = true;
return &UFE; return &UFE;
@ -370,7 +330,7 @@ FileManager::getVirtualFile(StringRef Filename, off_t Size,
if (getStatValue(InterndFileName, Data, true, 0) == 0) { if (getStatValue(InterndFileName, Data, true, 0) == 0) {
Data.Size = Size; Data.Size = Size;
Data.ModTime = ModificationTime; Data.ModTime = ModificationTime;
UFE = &UniqueRealFiles.getFile(Data.UniqueID, Data.IsNamedPipe, Data.InPCH); UFE = &UniqueRealFiles[Data.UniqueID];
NamedFileEnt.setValue(UFE); NamedFileEnt.setValue(UFE);
@ -383,6 +343,10 @@ FileManager::getVirtualFile(StringRef Filename, off_t Size,
// If we already have an entry with this inode, return it. // If we already have an entry with this inode, return it.
if (UFE->isValid()) if (UFE->isValid())
return UFE; return UFE;
UFE->UniqueID = Data.UniqueID;
UFE->IsNamedPipe = Data.IsNamedPipe;
UFE->InPCH = Data.InPCH;
} }
if (!UFE) { if (!UFE) {
@ -509,7 +473,7 @@ void FileManager::invalidateCache(const FileEntry *Entry) {
// FileEntry invalidation should not block future optimizations in the file // FileEntry invalidation should not block future optimizations in the file
// caches. Possible alternatives are cache truncation (invalidate last N) or // caches. Possible alternatives are cache truncation (invalidate last N) or
// invalidation of the whole cache. // invalidation of the whole cache.
UniqueRealFiles.erase(Entry); UniqueRealFiles.erase(Entry->getUniqueID());
} }