FileManager.cpp (198398) | FileManager.cpp (200583) |
---|---|
1///===--- FileManager.cpp - File System Probing and Caching ----------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// --- 133 unchanged lines hidden (view full) --- 142 DirEntries(64), FileEntries(64), NextFileUID(0) { 143 NumDirLookups = NumFileLookups = 0; 144 NumDirCacheMisses = NumFileCacheMisses = 0; 145} 146 147FileManager::~FileManager() { 148 delete &UniqueDirs; 149 delete &UniqueFiles; | 1///===--- FileManager.cpp - File System Probing and Caching ----------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// --- 133 unchanged lines hidden (view full) --- 142 DirEntries(64), FileEntries(64), NextFileUID(0) { 143 NumDirLookups = NumFileLookups = 0; 144 NumDirCacheMisses = NumFileCacheMisses = 0; 145} 146 147FileManager::~FileManager() { 148 delete &UniqueDirs; 149 delete &UniqueFiles; |
150 for (llvm::SmallVectorImpl<FileEntry *>::iterator 151 V = VirtualFileEntries.begin(), 152 VEnd = VirtualFileEntries.end(); 153 V != VEnd; 154 ++V) 155 delete *V; |
|
150} 151 152void FileManager::addStatCache(StatSysCallCache *statCache, bool AtBeginning) { 153 assert(statCache && "No stat cache provided?"); 154 if (AtBeginning || StatCache.get() == 0) { 155 statCache->setNextStatCache(StatCache.take()); 156 StatCache.reset(statCache); 157 return; --- 21 unchanged lines hidden (view full) --- 179 while (PrevCache && PrevCache->getNextStatCache() != statCache) 180 PrevCache = PrevCache->getNextStatCache(); 181 if (PrevCache) 182 PrevCache->setNextStatCache(statCache->getNextStatCache()); 183 else 184 assert(false && "Stat cache not found for removal"); 185} 186 | 156} 157 158void FileManager::addStatCache(StatSysCallCache *statCache, bool AtBeginning) { 159 assert(statCache && "No stat cache provided?"); 160 if (AtBeginning || StatCache.get() == 0) { 161 statCache->setNextStatCache(StatCache.take()); 162 StatCache.reset(statCache); 163 return; --- 21 unchanged lines hidden (view full) --- 185 while (PrevCache && PrevCache->getNextStatCache() != statCache) 186 PrevCache = PrevCache->getNextStatCache(); 187 if (PrevCache) 188 PrevCache->setNextStatCache(statCache->getNextStatCache()); 189 else 190 assert(false && "Stat cache not found for removal"); 191} 192 |
193/// \brief Retrieve the directory that the given file name resides in. 194static const DirectoryEntry *getDirectoryFromFile(FileManager &FileMgr, 195 const char *NameStart, 196 const char *NameEnd) { 197 // Figure out what directory it is in. If the string contains a / in it, 198 // strip off everything after it. 199 // FIXME: this logic should be in sys::Path. 200 const char *SlashPos = NameEnd-1; 201 while (SlashPos >= NameStart && !IS_DIR_SEPARATOR_CHAR(SlashPos[0])) 202 --SlashPos; 203 // Ignore duplicate //'s. 204 while (SlashPos > NameStart && IS_DIR_SEPARATOR_CHAR(SlashPos[-1])) 205 --SlashPos; 206 207 if (SlashPos < NameStart) { 208 // Use the current directory if file has no path component. 209 const char *Name = "."; 210 return FileMgr.getDirectory(Name, Name+1); 211 } else if (SlashPos == NameEnd-1) 212 return 0; // If filename ends with a /, it's a directory. 213 else 214 return FileMgr.getDirectory(NameStart, SlashPos); 215} 216 |
|
187/// getDirectory - Lookup, cache, and verify the specified directory. This 188/// returns null if the directory doesn't exist. 189/// 190const DirectoryEntry *FileManager::getDirectory(const char *NameStart, 191 const char *NameEnd) { 192 ++NumDirLookups; 193 llvm::StringMapEntry<DirectoryEntry *> &NamedDirEnt = 194 DirEntries.GetOrCreateValue(NameStart, NameEnd); --- 52 unchanged lines hidden (view full) --- 247 return NamedFileEnt.getValue() == NON_EXISTENT_FILE 248 ? 0 : NamedFileEnt.getValue(); 249 250 ++NumFileCacheMisses; 251 252 // By default, initialize it to invalid. 253 NamedFileEnt.setValue(NON_EXISTENT_FILE); 254 | 217/// getDirectory - Lookup, cache, and verify the specified directory. This 218/// returns null if the directory doesn't exist. 219/// 220const DirectoryEntry *FileManager::getDirectory(const char *NameStart, 221 const char *NameEnd) { 222 ++NumDirLookups; 223 llvm::StringMapEntry<DirectoryEntry *> &NamedDirEnt = 224 DirEntries.GetOrCreateValue(NameStart, NameEnd); --- 52 unchanged lines hidden (view full) --- 277 return NamedFileEnt.getValue() == NON_EXISTENT_FILE 278 ? 0 : NamedFileEnt.getValue(); 279 280 ++NumFileCacheMisses; 281 282 // By default, initialize it to invalid. 283 NamedFileEnt.setValue(NON_EXISTENT_FILE); 284 |
255 // Figure out what directory it is in. If the string contains a / in it, 256 // strip off everything after it. 257 // FIXME: this logic should be in sys::Path. 258 const char *SlashPos = NameEnd-1; 259 while (SlashPos >= NameStart && !IS_DIR_SEPARATOR_CHAR(SlashPos[0])) 260 --SlashPos; 261 // Ignore duplicate //'s. 262 while (SlashPos > NameStart && IS_DIR_SEPARATOR_CHAR(SlashPos[-1])) 263 --SlashPos; | |
264 | 285 |
265 const DirectoryEntry *DirInfo; 266 if (SlashPos < NameStart) { 267 // Use the current directory if file has no path component. 268 const char *Name = "."; 269 DirInfo = getDirectory(Name, Name+1); 270 } else if (SlashPos == NameEnd-1) 271 return 0; // If filename ends with a /, it's a directory. 272 else 273 DirInfo = getDirectory(NameStart, SlashPos); 274 275 if (DirInfo == 0) // Directory doesn't exist, file can't exist. 276 return 0; 277 | |
278 // Get the null-terminated file name as stored as the key of the 279 // FileEntries map. 280 const char *InterndFileName = NamedFileEnt.getKeyData(); 281 | 286 // Get the null-terminated file name as stored as the key of the 287 // FileEntries map. 288 const char *InterndFileName = NamedFileEnt.getKeyData(); 289 |
290 const DirectoryEntry *DirInfo 291 = getDirectoryFromFile(*this, NameStart, NameEnd); 292 if (DirInfo == 0) // Directory doesn't exist, file can't exist. 293 return 0; 294 |
|
282 // FIXME: Use the directory info to prune this, before doing the stat syscall. 283 // FIXME: This will reduce the # syscalls. 284 285 // Nope, there isn't. Check to see if the file exists. 286 struct stat StatBuf; 287 //llvm::errs() << "STATING: " << Filename; 288 if (stat_cached(InterndFileName, &StatBuf) || // Error stat'ing. 289 S_ISDIR(StatBuf.st_mode)) { // A directory? --- 17 unchanged lines hidden (view full) --- 307 UFE.Name = InterndFileName; 308 UFE.Size = StatBuf.st_size; 309 UFE.ModTime = StatBuf.st_mtime; 310 UFE.Dir = DirInfo; 311 UFE.UID = NextFileUID++; 312 return &UFE; 313} 314 | 295 // FIXME: Use the directory info to prune this, before doing the stat syscall. 296 // FIXME: This will reduce the # syscalls. 297 298 // Nope, there isn't. Check to see if the file exists. 299 struct stat StatBuf; 300 //llvm::errs() << "STATING: " << Filename; 301 if (stat_cached(InterndFileName, &StatBuf) || // Error stat'ing. 302 S_ISDIR(StatBuf.st_mode)) { // A directory? --- 17 unchanged lines hidden (view full) --- 320 UFE.Name = InterndFileName; 321 UFE.Size = StatBuf.st_size; 322 UFE.ModTime = StatBuf.st_mtime; 323 UFE.Dir = DirInfo; 324 UFE.UID = NextFileUID++; 325 return &UFE; 326} 327 |
328const FileEntry * 329FileManager::getVirtualFile(const llvm::StringRef &Filename, 330 off_t Size, time_t ModificationTime) { 331 const char *NameStart = Filename.begin(), *NameEnd = Filename.end(); 332 333 ++NumFileLookups; 334 335 // See if there is already an entry in the map. 336 llvm::StringMapEntry<FileEntry *> &NamedFileEnt = 337 FileEntries.GetOrCreateValue(NameStart, NameEnd); 338 339 // See if there is already an entry in the map. 340 if (NamedFileEnt.getValue()) 341 return NamedFileEnt.getValue() == NON_EXISTENT_FILE 342 ? 0 : NamedFileEnt.getValue(); 343 344 ++NumFileCacheMisses; 345 346 // By default, initialize it to invalid. 347 NamedFileEnt.setValue(NON_EXISTENT_FILE); 348 349 const DirectoryEntry *DirInfo 350 = getDirectoryFromFile(*this, NameStart, NameEnd); 351 if (DirInfo == 0) // Directory doesn't exist, file can't exist. 352 return 0; 353 354 FileEntry *UFE = new FileEntry(); 355 VirtualFileEntries.push_back(UFE); 356 NamedFileEnt.setValue(UFE); 357 358 UFE->Name = NamedFileEnt.getKeyData(); 359 UFE->Size = Size; 360 UFE->ModTime = ModificationTime; 361 UFE->Dir = DirInfo; 362 UFE->UID = NextFileUID++; 363 return UFE; 364} 365 |
|
315void FileManager::PrintStats() const { 316 llvm::errs() << "\n*** File Manager Stats:\n"; 317 llvm::errs() << UniqueFiles.size() << " files found, " 318 << UniqueDirs.size() << " dirs found.\n"; 319 llvm::errs() << NumDirLookups << " dir lookups, " 320 << NumDirCacheMisses << " dir cache misses.\n"; 321 llvm::errs() << NumFileLookups << " file lookups, " 322 << NumFileCacheMisses << " file cache misses.\n"; 323 324 //llvm::errs() << PagesMapped << BytesOfPagesMapped << FSLookups; 325} 326 327int MemorizeStatCalls::stat(const char *path, struct stat *buf) { 328 int result = StatSysCallCache::stat(path, buf); 329 | 366void FileManager::PrintStats() const { 367 llvm::errs() << "\n*** File Manager Stats:\n"; 368 llvm::errs() << UniqueFiles.size() << " files found, " 369 << UniqueDirs.size() << " dirs found.\n"; 370 llvm::errs() << NumDirLookups << " dir lookups, " 371 << NumDirCacheMisses << " dir cache misses.\n"; 372 llvm::errs() << NumFileLookups << " file lookups, " 373 << NumFileCacheMisses << " file cache misses.\n"; 374 375 //llvm::errs() << PagesMapped << BytesOfPagesMapped << FSLookups; 376} 377 378int MemorizeStatCalls::stat(const char *path, struct stat *buf) { 379 int result = StatSysCallCache::stat(path, buf); 380 |
330 if (result != 0) { 331 // Cache failed 'stat' results. 332 struct stat empty; 333 memset(&empty, 0, sizeof(empty)); 334 StatCalls[path] = StatResult(result, empty); 335 } 336 else if (!S_ISDIR(buf->st_mode) || llvm::sys::Path(path).isAbsolute()) { 337 // Cache file 'stat' results and directories with absolutely 338 // paths. | 381 // Do not cache failed stats, it is easy to construct common inconsistent 382 // situations if we do, and they are not important for PCH performance (which 383 // currently only needs the stats to construct the initial FileManager 384 // entries). 385 if (result != 0) 386 return result; 387 388 // Cache file 'stat' results and directories with absolutely paths. 389 if (!S_ISDIR(buf->st_mode) || llvm::sys::Path(path).isAbsolute()) |
339 StatCalls[path] = StatResult(result, *buf); | 390 StatCalls[path] = StatResult(result, *buf); |
340 } | |
341 342 return result; 343} | 391 392 return result; 393} |