diff options
author | Reid Spencer <rspencer@reidspencer.com> | 2004-11-07 18:17:38 +0000 |
---|---|---|
committer | Reid Spencer <rspencer@reidspencer.com> | 2004-11-07 18:17:38 +0000 |
commit | 83296f5496ddfd913bce94e9bc987af52044a20d (patch) | |
tree | 29e55348b3746da76d5f8b2df412df8f1f39e3b9 | |
parent | 92c0d6561bd0390a71a9012f5fea126c2a83f664 (diff) | |
download | external_llvm-83296f5496ddfd913bce94e9bc987af52044a20d.zip external_llvm-83296f5496ddfd913bce94e9bc987af52044a20d.tar.gz external_llvm-83296f5496ddfd913bce94e9bc987af52044a20d.tar.bz2 |
* Add comments and cleanup per CL code review
* Make signature for compressed bytecode llvc instead of unreadable
* Make the CompressionContext have a constructor and destructor.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@17576 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Bytecode/Writer/Writer.cpp | 96 |
1 files changed, 65 insertions, 31 deletions
diff --git a/lib/Bytecode/Writer/Writer.cpp b/lib/Bytecode/Writer/Writer.cpp index 15d6051..2fe0ee5 100644 --- a/lib/Bytecode/Writer/Writer.cpp +++ b/lib/Bytecode/Writer/Writer.cpp @@ -1086,22 +1086,65 @@ void BytecodeWriter::outputSymbolTable(const SymbolTable &MST) { } } +// This structure retains the context when compressing the bytecode file. The +// WriteCompressedData function below uses it to keep track of the previously +// filled chunk of memory (which it writes) and how many bytes have been +// written. struct CompressionContext { - char* chunk; - unsigned sz; - unsigned written; - std::ostream* Out; + // Initialize the context + CompressionContext(std::ostream*OS, unsigned CS) + : chunk(0), sz(0), written(0), compSize(CS), Out(OS) {} + + // Make sure we clean up memory + ~CompressionContext() { + if (chunk) + delete [] chunk; + } + + // Write the chunk + void write(unsigned size = 0) { + unsigned write_size = (size == 0 ? sz : size); + Out->write(chunk,write_size); + written += write_size; + delete [] chunk; + chunk = 0; + sz = 0; + } + + char* chunk; // pointer to the chunk of memory filled by compression + unsigned sz; // size of chunk + unsigned written; // aggregate total of bytes written in all chunks + unsigned compSize; // size of the uncompressed buffer + std::ostream* Out; // The stream we write the data to. }; +// This function is a callback used by the Compressor::compress function to +// allocate memory for the compression buffer. This function fulfills that +// responsibility but also writes the previous (now filled) buffer out to the +// stream. static unsigned WriteCompressedData(char*&buffer, unsigned& size, void* context) { + // Cast the context to the structure it must point to. CompressionContext* ctxt = reinterpret_cast<CompressionContext*>(context); + + // If there's a previously allocated chunk, it must now be filled with + // compressed data, so we write it out and deallocate it. if (ctxt->chunk != 0 && ctxt->sz > 0 ) { - ctxt->Out->write(ctxt->chunk,ctxt->sz); - delete [] ctxt->chunk; - ctxt->written += ctxt->sz; + ctxt->write(); } - size = ctxt->sz = 1024*1024; - buffer = ctxt->chunk = new char [ctxt->sz]; + + // Compute the size of the next chunk to allocate. We attempt to allocate + // enough memory to handle the compression in a single memory allocation. In + // general, the worst we do on compression of bytecode is about 50% so we + // conservatively estimate compSize / 2 as the size needed for the + // compression buffer. compSize is the size of the compressed data, provided + // by WriteBytecodeToFile. + size = ctxt->sz = ctxt->compSize / 2; + + // Allocate the chunks + buffer = ctxt->chunk = new char [size]; + + // We must return 1 if the allocation failed so that the Compressor knows + // not to use the buffer pointer. return (ctxt->chunk == 0 ? 1 : 0); } @@ -1125,31 +1168,24 @@ void llvm::WriteBytecodeToFile(const Module *M, std::ostream &Out, BytesWritten += Buffer.size(); // Determine start and end points of the Buffer - std::vector<unsigned char>::iterator I = Buffer.begin(); - const unsigned char *FirstByte = &(*I); - const unsigned char *LastByte = FirstByte + Buffer.size(); + const unsigned char *FirstByte = &Buffer.front(); // If we're supposed to compress this mess ... if (compress) { // We signal compression by using an alternate magic number for the - // file. The compressed bytecode file's magic number is the same as - // the uncompressed one but with the high bits set. So, "llvm", which - // is 0x6C 0x6C 0x76 0x6D becomes 0xEC 0xEC 0xF6 0xED - unsigned char compressed_magic[4]; - compressed_magic[0] = 0xEC; // 'l' + 0x80 - compressed_magic[1] = 0xEC; // 'l' + 0x80 - compressed_magic[2] = 0xF6; // 'v' + 0x80 - compressed_magic[3] = 0xED; // 'm' + 0x80 + // file. The compressed bytecode file's magic number is "llvc" instead + // of "llvm". + char compressed_magic[4]; + compressed_magic[0] = 'l'; + compressed_magic[1] = 'l'; + compressed_magic[2] = 'v'; + compressed_magic[3] = 'c'; - Out.write((char*)compressed_magic,4); + Out.write(compressed_magic,4); // Do the compression, writing as we go. - CompressionContext ctxt; - ctxt.chunk = 0; - ctxt.sz = 0; - ctxt.written = 0; - ctxt.Out = &Out; + CompressionContext ctxt(&Out,Buffer.size()); // Compress everything after the magic number (which we'll alter) uint64_t zipSize = Compressor::compress( @@ -1160,15 +1196,13 @@ void llvm::WriteBytecodeToFile(const Module *M, std::ostream &Out, (void*)&ctxt // Keep track of allocated memory ); - if (ctxt.chunk && ctxt.sz > 0) { - Out.write(ctxt.chunk, zipSize - ctxt.written); - delete [] ctxt.chunk; + if (ctxt.chunk) { + ctxt.write(zipSize - ctxt.written); } } else { // We're not compressing, so just write the entire block. - Out.write((char*)FirstByte, LastByte-FirstByte); - + Out.write((char*)FirstByte, Buffer.size()); } // make sure it hits disk now |