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 134438 abeb2688806251cc0e839a14dd94b0887fd354e1
parent 134437 d496b277486de6e8ce94b4866bc9ce94dc1131c5
child 134439 efe5d05176dc955e9eba349f5c3d0c7c08c195f9
push id29212
push userjorendorff@mozilla.com
push dateSat, 08 Jun 2013 03:28:09 +0000
treeherdermozilla-inbound@efe5d05176dc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwalden
bugs880575
milestone24.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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: