mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 19:52:54 +01:00
* 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. llvm-svn: 17576
This commit is contained in:
parent
31e899d3ee
commit
1446cd065f
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user