[llvm-commits] CVS: llvm/lib/Bytecode/Writer/Writer.cpp

Reid Spencer reid at x10sys.com
Sun Nov 7 10:17:48 PST 2004



Changes in directory llvm/lib/Bytecode/Writer:

Writer.cpp updated: 1.85 -> 1.86
---
Log message:

* 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.


---
Diffs of the changes:  (+65 -31)

Index: llvm/lib/Bytecode/Writer/Writer.cpp
diff -u llvm/lib/Bytecode/Writer/Writer.cpp:1.85 llvm/lib/Bytecode/Writer/Writer.cpp:1.86
--- llvm/lib/Bytecode/Writer/Writer.cpp:1.85	Sat Nov  6 17:17:23 2004
+++ llvm/lib/Bytecode/Writer/Writer.cpp	Sun Nov  7 12:17:38 2004
@@ -1086,22 +1086,65 @@
   }
 }
 
+// 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 @@
   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*)&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






More information about the llvm-commits mailing list