Bug 564369 - streamline TokenStream::getChar(), part 5. r=cdleary.
authorNicholas Nethercote <nnethercote@mozilla.com>
Wed, 12 May 2010 21:41:24 -0700
changeset 42699 51399ee0229094e237da6ed1d9a8ff797a2953c1
parent 42698 1135b2628d73bf08aca63cc468447b681c9d3a83
child 42700 65f84aca73d15fb3effa162e0d33491ced4b54ff
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscdleary
bugs564369
milestone1.9.3a5pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
Bug 564369 - streamline TokenStream::getChar(), part 5. r=cdleary.
js/src/jsscan.cpp
--- a/js/src/jsscan.cpp
+++ b/js/src/jsscan.cpp
@@ -314,42 +314,41 @@ TokenStream::fillUserbuf()
 
 /*
  * This gets the next char, normalizing all EOL sequences to '\n' as it goes.
  */
 int32
 TokenStream::getChar()
 {
     int32 c;
-    ptrdiff_t len, olen;
+    ptrdiff_t llen, ulen;
 
     if (ungetpos != 0) {
         c = ungetbuf[--ungetpos];
     } else {
         if (linebuf.ptr == linebuf.limit) {
-            len = userbuf.limit - userbuf.ptr;
-            if (len <= 0) {
+            ulen = userbuf.limit - userbuf.ptr;
+            if (ulen <= 0) {
                 if (!file) {
                     flags |= TSF_EOF;
                     return EOF;
                 }
 
                 /* Fill userbuf so that \r and \r\n convert to \n. */
-                len = fillUserbuf();
-                JS_ASSERT(len >= 0);
-                if (len == 0) {
+                ulen = fillUserbuf();
+                JS_ASSERT(ulen >= 0);
+                if (ulen == 0) {
                     flags |= TSF_EOF;
                     return EOF;
                 }
-                olen = len;
-                userbuf.limit = userbuf.base + len;
+                userbuf.limit = userbuf.base + ulen;
                 userbuf.ptr = userbuf.base;
             }
             if (listener)
-                listener(filename, lineno, userbuf.ptr, len, &listenerTSData, listenerData);
+                listener(filename, lineno, userbuf.ptr, ulen, &listenerTSData, listenerData);
 
             jschar *nl = saveEOL;
             if (!nl) {
                 /*
                  * Any one of \n, \r, or \r\n ends a line (the longest
                  * match wins).  Also allow the Unicode line and paragraph
                  * separators.
                  */
@@ -365,79 +364,83 @@ TokenStream::getChar()
                             if (nl + 1 < userbuf.limit && nl[1] == '\n')
                                 nl++;
                             break;
                         }
                         if (*nl == LINE_SEPARATOR || *nl == PARA_SEPARATOR)
                             break;
                     }
                 }
+            } else {
+                JS_ASSERT(!file);   // must be scanning from memory to have saved 'nl'
             }
 
             /*
              * If there was a line terminator, copy thru it into linebuf.
-             * Else copy LINE_LIMIT-1 bytes into linebuf.
+             * Else copy at most LINE_LIMIT-1 bytes into linebuf.
              */
             if (nl < userbuf.limit)
-                len = (nl - userbuf.ptr) + 1;
-            if (len >= (ptrdiff_t) LINE_LIMIT) {
-                len = LINE_LIMIT - 1;
-                saveEOL = nl;
+                ulen = (nl - userbuf.ptr) + 1;
+
+            if (ulen >= (ptrdiff_t) LINE_LIMIT) {
+                JS_ASSERT(!file);
+                ulen = LINE_LIMIT - 1;
+                saveEOL = nl;       // remember the position to avoid looking for it next time
             } else {
                 saveEOL = NULL;
             }
-            js_strncpy(linebuf.base, userbuf.ptr, len);
-            userbuf.ptr += len;
-            olen = len;
+            js_strncpy(linebuf.base, userbuf.ptr, ulen);
+            userbuf.ptr += ulen;
+            llen = ulen;    // llen == ulen at first, but it may be shortened during normalization
 
             /*
              * Normalize all EOL sequences to \n in linebuf (don't do this in
              * userbuf because the user's string might be readonly).
              */
             if (nl < userbuf.limit) {
                 if (*nl == '\r') {
                     // If nl points to a \r that means it mustn't be followed
                     // by a \n, in which case \r must have been the last char
                     // copied.  Replace it with \n.
-                    JS_ASSERT(linebuf.base[len-1] == '\r');
-                    linebuf.base[len-1] = '\n';
+                    JS_ASSERT(linebuf.base[llen-1] == '\r');
+                    linebuf.base[llen-1] = '\n';
                 } else if (*nl == '\n') {
                     if (nl > userbuf.base && nl[-1] == '\r') {
                         // If nl points to a \n that's preceded by a \r, we
-                        // overwrite the \r with \n and pull len back by one
+                        // overwrite the \r with \n and pull llen back by one
                         // so the \n pointed to by nl ends up beyond
                         // linebuf.limit.
-                        JS_ASSERT(linebuf.base[len-2] == '\r' &&
-                                  linebuf.base[len-1] == '\n');
-                        linebuf.base[len-2] = '\n';
-                        len--;
+                        JS_ASSERT(linebuf.base[llen-2] == '\r' &&
+                                  linebuf.base[llen-1] == '\n');
+                        linebuf.base[llen-2] = '\n';
+                        llen--;
                     }
                 } else if (*nl == LINE_SEPARATOR || *nl == PARA_SEPARATOR) {
-                    JS_ASSERT(linebuf.base[len-1] == LINE_SEPARATOR ||
-                              linebuf.base[len-1] == PARA_SEPARATOR);
-                    linebuf.base[len-1] = '\n';
+                    JS_ASSERT(linebuf.base[llen-1] == LINE_SEPARATOR ||
+                              linebuf.base[llen-1] == PARA_SEPARATOR);
+                    linebuf.base[llen-1] = '\n';
                 }
             }
 
-            /* Reset linebuf based on adjusted segment length. */
-            linebuf.limit = linebuf.base + len;
+            /* Reset linebuf based on normalized length. */
+            linebuf.limit = linebuf.base + llen;
             linebuf.ptr = linebuf.base;
 
             /* Update position of linebuf within physical userbuf line. */
             if (!(flags & TSF_NLFLAG))
                 linepos += linelen;
             else
                 linepos = 0;
             if (linebuf.limit[-1] == '\n')
                 flags |= TSF_NLFLAG;
             else
                 flags &= ~TSF_NLFLAG;
 
-            /* Update linelen from original segment length. */
-            linelen = olen;
+            /* Update linelen from un-normalized length. */
+            linelen = ulen;
         }
         c = *linebuf.ptr++;
     }
     if (c == '\n')
         lineno++;
     return c;
 }