1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 19:52:54 +01:00

Fix massive resource leaks in the bytecode reader. Reading a bytecode file

with ParseBytecodeFile used to leak both a ModuleProvider (and related
bytecode parser stuff attached to it) AND a file descriptor, which was
never closed.  This prevented gccld/llvm-ld/llvm-link from linking together
apps with more that ~252 .bc files on darwin.

llvm-svn: 30912
This commit is contained in:
Chris Lattner 2006-10-12 18:32:30 +00:00
parent b7ff3d59f7
commit 08684eac36
2 changed files with 46 additions and 45 deletions

View File

@ -248,6 +248,12 @@ protected:
/// @brief Parse a string constants block /// @brief Parse a string constants block
void ParseStringConstants(unsigned NumEntries, ValueTable &Tab); void ParseStringConstants(unsigned NumEntries, ValueTable &Tab);
/// @brief Release our memory.
void freeState() {
freeTable(FunctionValues);
freeTable(ModuleValues);
}
/// @} /// @}
/// @name Data /// @name Data
/// @{ /// @{
@ -467,12 +473,6 @@ private:
/// given constant. /// given constant.
void ResolveReferencesToConstant(Constant *C, unsigned Typ, unsigned Slot); void ResolveReferencesToConstant(Constant *C, unsigned Typ, unsigned Slot);
/// @brief Release our memory.
void freeState() {
freeTable(FunctionValues);
freeTable(ModuleValues);
}
/// @brief Free a table, making sure to free the ValueList in the table. /// @brief Free a table, making sure to free the ValueList in the table.
void freeTable(ValueTable &Tab) { void freeTable(ValueTable &Tab) {
while (!Tab.empty()) { while (!Tab.empty()) {

View File

@ -44,15 +44,17 @@ namespace {
public: public:
BytecodeFileReader(const std::string &Filename, llvm::BytecodeHandler* H=0); BytecodeFileReader(const std::string &Filename, llvm::BytecodeHandler* H=0);
bool read(std::string* ErrMsg); bool read(std::string* ErrMsg);
void freeState() {
BytecodeReader::freeState();
mapFile.close();
}
}; };
} }
BytecodeFileReader::BytecodeFileReader(const std::string &Filename, BytecodeFileReader::BytecodeFileReader(const std::string &Filename,
llvm::BytecodeHandler* H ) llvm::BytecodeHandler* H)
: BytecodeReader(H) : BytecodeReader(H), fileName(Filename) {
, fileName(Filename)
, mapFile()
{
} }
bool BytecodeFileReader::read(std::string* ErrMsg) { bool BytecodeFileReader::read(std::string* ErrMsg) {
@ -63,10 +65,7 @@ bool BytecodeFileReader::read(std::string* ErrMsg) {
return true; return true;
} }
unsigned char* buffer = reinterpret_cast<unsigned char*>(mapFile.base()); unsigned char* buffer = reinterpret_cast<unsigned char*>(mapFile.base());
if (ParseBytecode(buffer, mapFile.size(), fileName, ErrMsg)) { return ParseBytecode(buffer, mapFile.size(), fileName, ErrMsg);
return true;
}
return false;
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -101,14 +100,9 @@ namespace {
BytecodeBufferReader::BytecodeBufferReader(const unsigned char *buf, BytecodeBufferReader::BytecodeBufferReader(const unsigned char *buf,
unsigned len, unsigned len,
const std::string &modID, const std::string &modID,
llvm::BytecodeHandler* H) llvm::BytecodeHandler *H)
: BytecodeReader(H) : BytecodeReader(H), Buffer(0), Buf(buf), Length(len), ModuleID(modID)
, Buffer(0) , MustDelete(false) {
, Buf(buf)
, Length(len)
, ModuleID(modID)
, MustDelete(false)
{
} }
BytecodeBufferReader::~BytecodeBufferReader() { BytecodeBufferReader::~BytecodeBufferReader() {
@ -300,8 +294,8 @@ ModuleProvider*
llvm::getBytecodeBufferModuleProvider(const unsigned char *Buffer, llvm::getBytecodeBufferModuleProvider(const unsigned char *Buffer,
unsigned Length, unsigned Length,
const std::string &ModuleID, const std::string &ModuleID,
std::string* ErrMsg, std::string *ErrMsg,
BytecodeHandler* H) { BytecodeHandler *H) {
BytecodeBufferReader* rdr = BytecodeBufferReader* rdr =
new BytecodeBufferReader(Buffer, Length, ModuleID, H); new BytecodeBufferReader(Buffer, Length, ModuleID, H);
if (rdr->read(ErrMsg)) if (rdr->read(ErrMsg))
@ -313,12 +307,13 @@ llvm::getBytecodeBufferModuleProvider(const unsigned char *Buffer,
/// ///
Module *llvm::ParseBytecodeBuffer(const unsigned char *Buffer, unsigned Length, Module *llvm::ParseBytecodeBuffer(const unsigned char *Buffer, unsigned Length,
const std::string &ModuleID, const std::string &ModuleID,
std::string *ErrMsg){ std::string *ErrMsg) {
ModuleProvider* MP = ModuleProvider *MP =
getBytecodeBufferModuleProvider(Buffer, Length, ModuleID, ErrMsg, 0); getBytecodeBufferModuleProvider(Buffer, Length, ModuleID, ErrMsg, 0);
if (!MP) if (!MP) return 0;
return 0; Module *M = MP->releaseModule();
return MP->releaseModule(); delete MP;
return M;
} }
/// getBytecodeModuleProvider - lazy function-at-a-time loading from a file /// getBytecodeModuleProvider - lazy function-at-a-time loading from a file
@ -347,9 +342,10 @@ llvm::getBytecodeModuleProvider(const std::string &Filename,
Module *llvm::ParseBytecodeFile(const std::string &Filename, Module *llvm::ParseBytecodeFile(const std::string &Filename,
std::string *ErrMsg) { std::string *ErrMsg) {
ModuleProvider* MP = getBytecodeModuleProvider(Filename, ErrMsg); ModuleProvider* MP = getBytecodeModuleProvider(Filename, ErrMsg);
if (!MP) if (!MP) return 0;
return 0; Module *M = MP->releaseModule();
return MP->releaseModule(); delete MP;
return M;
} }
// AnalyzeBytecodeFile - analyze one file // AnalyzeBytecodeFile - analyze one file
@ -358,13 +354,13 @@ Module* llvm::AnalyzeBytecodeFile(
BytecodeAnalysis& bca, ///< Statistical output BytecodeAnalysis& bca, ///< Statistical output
std::string *ErrMsg, ///< Error output std::string *ErrMsg, ///< Error output
std::ostream* output ///< Dump output std::ostream* output ///< Dump output
) ) {
{
BytecodeHandler* AH = createBytecodeAnalyzerHandler(bca,output); BytecodeHandler* AH = createBytecodeAnalyzerHandler(bca,output);
ModuleProvider* MP = getBytecodeModuleProvider(Filename, ErrMsg, AH); ModuleProvider* MP = getBytecodeModuleProvider(Filename, ErrMsg, AH);
if (!MP) if (!MP) return 0;
return 0; Module *M = MP->releaseModule();
return MP->releaseModule(); delete MP;
return M;
} }
// AnalyzeBytecodeBuffer - analyze a buffer // AnalyzeBytecodeBuffer - analyze a buffer
@ -380,15 +376,16 @@ Module* llvm::AnalyzeBytecodeBuffer(
BytecodeHandler* hdlr = createBytecodeAnalyzerHandler(bca, output); BytecodeHandler* hdlr = createBytecodeAnalyzerHandler(bca, output);
ModuleProvider* MP = ModuleProvider* MP =
getBytecodeBufferModuleProvider(Buffer, Length, ModuleID, ErrMsg, hdlr); getBytecodeBufferModuleProvider(Buffer, Length, ModuleID, ErrMsg, hdlr);
if (!MP) if (!MP) return 0;
return 0; Module *M = MP->releaseModule();
return MP->releaseModule(); delete MP;
return M;
} }
bool llvm::GetBytecodeDependentLibraries(const std::string &fname, bool llvm::GetBytecodeDependentLibraries(const std::string &fname,
Module::LibraryListType& deplibs, Module::LibraryListType& deplibs,
std::string* ErrMsg) { std::string* ErrMsg) {
ModuleProvider* MP = getBytecodeModuleProvider(fname, ErrMsg); ModuleProvider* MP = getBytecodeModuleProvider(fname, ErrMsg);
if (!MP) { if (!MP) {
deplibs.clear(); deplibs.clear();
return true; return true;
@ -396,6 +393,7 @@ bool llvm::GetBytecodeDependentLibraries(const std::string &fname,
Module* M = MP->releaseModule(); Module* M = MP->releaseModule();
deplibs = M->getLibraries(); deplibs = M->getLibraries();
delete M; delete M;
delete MP;
return false; return false;
} }
@ -417,19 +415,22 @@ static void getSymbols(Module*M, std::vector<std::string>& symbols) {
bool llvm::GetBytecodeSymbols(const sys::Path& fName, bool llvm::GetBytecodeSymbols(const sys::Path& fName,
std::vector<std::string>& symbols, std::vector<std::string>& symbols,
std::string* ErrMsg) { std::string* ErrMsg) {
ModuleProvider* MP = getBytecodeModuleProvider(fName.toString(), ErrMsg); ModuleProvider *MP = getBytecodeModuleProvider(fName.toString(), ErrMsg);
if (!MP) if (!MP)
return true; return true;
// Get the module from the provider // Get the module from the provider
Module* M = MP->materializeModule(); Module* M = MP->materializeModule();
if (M == 0) if (M == 0) {
delete MP;
return true; return true;
}
// Get the symbols // Get the symbols
getSymbols(M, symbols); getSymbols(M, symbols);
// Done with the module // Done with the module.
delete MP;
return true; return true;
} }