forked from OSchip/llvm-project
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:
parent
c329937011
commit
c9b7234e5c
|
@ -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.
|
||||||
///
|
///
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue