Bug 1166492 - Handle huge strings in the profile JSON writer. (r=mstange)
authorShu-yu Guo <shu@rfrn.org>
Tue, 26 May 2015 22:58:40 -0700
changeset 268018 da5bcffc250245b6c8be151657cceabbe0708a36
parent 268017 14f0933c537c26fb26050fb952fdd94c48756969
child 268019 7eb1c387ca5f019a8f7d416f7733e567ffac9d67
push id2294
push userbsmedberg@mozilla.com
push dateWed, 27 May 2015 15:05:10 +0000
reviewersmstange
bugs1166492
milestone41.0a1
Bug 1166492 - Handle huge strings in the profile JSON writer. (r=mstange)
tools/profiler/ProfileJSONWriter.h
--- a/tools/profiler/ProfileJSONWriter.h
+++ b/tools/profiler/ProfileJSONWriter.h
@@ -20,39 +20,47 @@ class ChunkedJSONWriteFunc : public mozi
   friend class SpliceableJSONWriter;
 
   const static size_t kChunkSize = 4096 * 512;
   char* mChunkPtr;
   char* mChunkEnd;
   mozilla::Vector<mozilla::UniquePtr<char[]>> mChunkList;
   mozilla::Vector<size_t> mChunkLengths;
 
-  void AllocChunk() {
+  void AllocChunk(size_t aChunkSize) {
     MOZ_ASSERT(mChunkLengths.length() == mChunkList.length());
-    mozilla::UniquePtr<char[]> newChunk = mozilla::MakeUnique<char[]>(kChunkSize);
+    mozilla::UniquePtr<char[]> newChunk = mozilla::MakeUnique<char[]>(aChunkSize);
     mChunkPtr = newChunk.get();
-    mChunkEnd = mChunkPtr + kChunkSize;
+    mChunkEnd = mChunkPtr + aChunkSize;
     MOZ_ALWAYS_TRUE(mChunkLengths.append(0));
     MOZ_ALWAYS_TRUE(mChunkList.append(mozilla::Move(newChunk)));
   }
 
 public:
   ChunkedJSONWriteFunc() {
-    AllocChunk();
+    AllocChunk(kChunkSize);
   }
 
   void Write(const char* aStr) override {
-    MOZ_ASSERT(strlen(aStr) < kChunkSize);
+    size_t len = strlen(aStr);
 
-    size_t len = strlen(aStr);
-    char* newPtr = mChunkPtr + len;
-    if (newPtr >= mChunkEnd) {
-      MOZ_ASSERT(*mChunkPtr == '\0');
-      AllocChunk();
+    // Most strings to be written are small, but subprocess profiles (e.g.,
+    // from the content process in e10s) may be huge. If the string is larger
+    // than a chunk, allocate its own chunk.
+    char* newPtr;
+    if (len >= kChunkSize) {
+      AllocChunk(len + 1);
       newPtr = mChunkPtr + len;
+    } else {
+      newPtr = mChunkPtr + len;
+      if (newPtr >= mChunkEnd) {
+        MOZ_ASSERT(*mChunkPtr == '\0');
+        AllocChunk(kChunkSize);
+        newPtr = mChunkPtr + len;
+      }
     }
 
     memcpy(mChunkPtr, aStr, len);
     mChunkPtr = newPtr;
     mChunkLengths.back() += len;
     *mChunkPtr = '\0';
   }