aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorReid Spencer <rspencer@reidspencer.com>2004-11-07 18:17:38 +0000
committerReid Spencer <rspencer@reidspencer.com>2004-11-07 18:17:38 +0000
commit83296f5496ddfd913bce94e9bc987af52044a20d (patch)
tree29e55348b3746da76d5f8b2df412df8f1f39e3b9
parent92c0d6561bd0390a71a9012f5fea126c2a83f664 (diff)
downloadexternal_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.cpp96
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