Bug 880575, part 4 - Use a Vector<char> instead of manually allocating the input buffer in ReadEvalPrintLoop. r=jwalden.
authorJason Orendorff <jorendorff@mozilla.com>
Fri, 07 Jun 2013 22:25:08 -0500
changeset 141563 abeb2688806251cc0e839a14dd94b0887fd354e1
parent 141562 d496b277486de6e8ce94b4866bc9ce94dc1131c5
child 141564 efe5d05176dc955e9eba349f5c3d0c7c08c195f9
push id3911
push userakeybl@mozilla.com
push dateMon, 24 Jun 2013 20:17:26 +0000
treeherdermozilla-aurora@7e26ca8db92b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwalden
bugs880575
milestone24.0a1
Bug 880575, part 4 - Use a Vector<char> instead of manually allocating the input buffer in ReadEvalPrintLoop. r=jwalden.
js/src/shell/js.cpp
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -446,88 +446,64 @@ static void
 ReadEvalPrintLoop(JSContext *cx, JSObject *obj, FILE *file, bool compileOnly)
 {
     RootedScript script(cx);
     RootedValue result(cx);
     RootedString str(cx);
 
     int lineno = 1;
     bool hitEOF = false;
-    char *buffer = NULL;
-    size_t size = 0;           /* assign here to avoid warnings */
+
     do {
         /*
          * Accumulate lines until we get a 'compilable unit' - one that either
          * generates an error (before running out of source) or that compiles
          * cleanly.  This should be whenever we get a complete statement that
          * coincides with the end of a line.
          */
         int startline = lineno;
-        size_t len = 0; /* initialize to avoid warnings */
+        typedef Vector<char, 32, ContextAllocPolicy> CharBuffer;
+        CharBuffer buffer(cx);
         do {
             ScheduleWatchdog(cx->runtime, -1);
             gTimedOut = false;
             errno = 0;
 
             char *line = GetLine(file, startline == lineno ? "js> " : "");
             if (!line) {
                 if (errno) {
                     JS_ReportError(cx, strerror(errno));
-                    free(buffer);
                     return;
                 }
                 hitEOF = true;
                 break;
             }
-            if (!buffer) {
-                buffer = line;
-                len = strlen(buffer);
-                size = len + 1;
-            } else {
-                /*
-                 * len + 1 is required to store '\n' in the end of line.
-                 */
-                size_t newlen = strlen(line) + (len ? len + 1 : 0);
-                if (newlen + 1 > size) {
-                    size = newlen + 1 > size * 2 ? newlen + 1 : size * 2;
-                    char *newBuf = (char *) realloc(buffer, size);
-                    if (!newBuf) {
-                        free(buffer);
-                        free(line);
-                        JS_ReportOutOfMemory(cx);
-                        return;
-                    }
-                    buffer = newBuf;
-                }
-                char *current = buffer + len;
-                if (startline != lineno)
-                    *current++ = '\n';
-                strcpy(current, line);
-                len = newlen;
-                free(line);
-            }
+
+            if (!buffer.append(line, strlen(line)) || !buffer.append('\n'))
+                return;
+
             lineno++;
             if (!ScheduleWatchdog(cx->runtime, gTimeoutInterval)) {
                 hitEOF = true;
                 break;
             }
-        } while (!JS_BufferIsCompilableUnit(cx, obj, buffer, len));
-
-        if (hitEOF && !buffer)
+        } while (!JS_BufferIsCompilableUnit(cx, obj, buffer.begin(), buffer.length()));
+
+        if (hitEOF && buffer.empty())
             break;
 
         size_t uc_len;
-        if (!InflateUTF8StringToBuffer(cx, buffer, len, NULL, &uc_len)) {
+        if (!InflateUTF8StringToBuffer(cx, buffer.begin(), buffer.length(), NULL, &uc_len)) {
             JS_ReportError(cx, "Invalid UTF-8 in input");
             gExitCode = EXITCODE_RUNTIME_ERROR;
             return;
         }
 
         jschar *uc_buffer = (jschar*)malloc(uc_len * sizeof(jschar));
-        InflateUTF8StringToBuffer(cx, buffer, len, uc_buffer, &uc_len);
+        InflateUTF8StringToBuffer(cx, buffer.begin(), buffer.length(), uc_buffer, &uc_len);
 
         /* Clear any pending exception from previous failed compiles. */
         JS_ClearPendingException(cx);
 
         /* Even though we're interactive, we have a compile-n-go opportunity. */
         uint32_t oldopts = JS_GetOptions(cx);
         gGotError = false;
         if (!compileOnly)
@@ -548,21 +524,19 @@ ReadEvalPrintLoop(JSContext *cx, JSObjec
                     ok = !!utf8chars;
                     if (ok) {
                         fprintf(gOutFile, "%s\n", utf8chars);
                         JS_free(cx, utf8chars);
                     }
                 }
             }
         }
-        *buffer = '\0';
         free(uc_buffer);
     } while (!hitEOF && !gQuitting);
 
-    free(buffer);
     fprintf(gOutFile, "\n");
 }
 
 class AutoCloseInputFile
 {
   private:
     FILE *f_;
   public: