Bug 1286911. r=wchen, a=ritu
authorHenri Sivonen <hsivonen@hsivonen.fi>
Tue, 27 Sep 2016 13:47:53 +0300
changeset 350560 1deb126ed5bb1f9bc4b67867c0ca120c4ce788ae
parent 350559 f599f4e3d84fe2f99c7c0995f224152ebdb87a34
child 350561 98f174fa9b903aca83ecfb596e13c4cadc6ac2f4
push id1230
push userjlund@mozilla.com
push dateMon, 31 Oct 2016 18:13:35 +0000
treeherdermozilla-release@5e06e3766db2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswchen, ritu
bugs1286911
milestone50.0
Bug 1286911. r=wchen, a=ritu MozReview-Commit-ID: hzAu0jKAxt
parser/html/javasrc/HtmlAttributes.java
parser/html/javasrc/Tokenizer.java
parser/html/nsHtml5Tokenizer.cpp
parser/html/nsHtml5Tokenizer.h
parser/html/nsHtml5TreeBuilderCppSupplement.h
--- a/parser/html/javasrc/HtmlAttributes.java
+++ b/parser/html/javasrc/HtmlAttributes.java
@@ -57,17 +57,17 @@ public final class HtmlAttributes implem
 
     private int mode;
 
     private int length;
 
     private @Auto AttributeName[] names;
 
     private @Auto String[] values; // XXX perhaps make this @NoLength?
-
+    
     // CPPONLY: private @Auto int[] lines; // XXX perhaps make this @NoLength?
 
     // [NOCPP[
 
     private String idValue;
 
     private int xmlnsLength;
 
--- a/parser/html/javasrc/Tokenizer.java
+++ b/parser/html/javasrc/Tokenizer.java
@@ -812,16 +812,18 @@ public class Tokenizer implements Locato
             // ]NOCPP]
             return HtmlAttributes.EMPTY_ATTRIBUTES;
             // [NOCPP[
         }
         // ]NOCPP]
     }
 
     @Inline private void appendCharRefBuf(char c) {
+        // CPPONLY: assert charRefBufLen < charRefBuf.length:
+        // CPPONLY:     "RELEASE: Attempted to overrun charRefBuf!";
         charRefBuf[charRefBufLen++] = c;
     }
 
     @Inline private void clearCharRefBufAndAppend(char c) {
         charRefBuf[0] = c;
         charRefBufLen = 1;
     }
 
@@ -845,17 +847,23 @@ public class Tokenizer implements Locato
     }
 
     /**
      * Appends to the buffer.
      * 
      * @param c
      *            the UTF-16 code unit to append
      */
-    private void appendStrBuf(char c) {
+    @Inline private void appendStrBuf(char c) {
+        // CPPONLY: assert strBufLen < strBuf.length: "Previous buffer length insufficient.";
+        // CPPONLY: if (strBufLen == strBuf.length) {
+        // CPPONLY:     if (!EnsureBufferSpace(1)) {
+        // CPPONLY:         assert false: "RELEASE: Unable to recover from buffer reallocation failure";
+        // CPPONLY:     } // TODO: Add telemetry when outer if fires but inner does not
+        // CPPONLY: }
         strBuf[strBufLen++] = c;
     }
 
     /**
      * The buffer as a String. Currently only used for error reporting.
      * 
      * <p>
      * C++ memory note: The return value must be released.
@@ -946,24 +954,25 @@ public class Tokenizer implements Locato
             case FATAL:
                 fatal("The document is not mappable to XML 1.0 due to two consecutive hyphens in a comment.");
                 break;
         }
         // ]NOCPP]
     }
 
     private void appendStrBuf(@NoLength char[] buffer, int offset, int length) {
-        int reqLen = strBufLen + length;
-        if (strBuf.length < reqLen) {
-            char[] newBuf = new char[reqLen + (reqLen >> 1)];
-            System.arraycopy(strBuf, 0, newBuf, 0, strBuf.length);
-            strBuf = newBuf;
-        }
+        int newLen = strBufLen + length;
+        // CPPONLY: assert newLen <= strBuf.length: "Previous buffer length insufficient.";
+        // CPPONLY: if (strBuf.length < newLen) {
+        // CPPONLY:     if (!EnsureBufferSpace(length)) {
+        // CPPONLY:         assert false: "RELEASE: Unable to recover from buffer reallocation failure";
+        // CPPONLY:     } // TODO: Add telemetry when outer if fires but inner does not
+        // CPPONLY: }
         System.arraycopy(buffer, offset, strBuf, strBufLen, length);
-        strBufLen = reqLen;
+        strBufLen = newLen;
     }
 
     /**
      * Append the contents of the char reference buffer to the main one.
      */
     @Inline private void appendCharRefBufToStrBuf() {
         appendStrBuf(charRefBuf, 0, charRefBufLen);
     }
--- a/parser/html/nsHtml5Tokenizer.cpp
+++ b/parser/html/nsHtml5Tokenizer.cpp
@@ -216,22 +216,16 @@ nsHtml5Tokenizer::emitOrAppendCharRefBuf
     appendCharRefBufToStrBuf();
   } else {
     if (charRefBufLen > 0) {
       tokenHandler->characters(charRefBuf, 0, charRefBufLen);
     }
   }
 }
 
-void 
-nsHtml5Tokenizer::appendStrBuf(char16_t c)
-{
-  strBuf[strBufLen++] = c;
-}
-
 nsString* 
 nsHtml5Tokenizer::strBufToString()
 {
   return nsHtml5Portability::newStringFromBuffer(strBuf, 0, strBufLen, tokenHandler);
 }
 
 void 
 nsHtml5Tokenizer::strBufToDoctypeName()
@@ -245,24 +239,25 @@ nsHtml5Tokenizer::emitStrBuf()
   if (strBufLen > 0) {
     tokenHandler->characters(strBuf, 0, strBufLen);
   }
 }
 
 void 
 nsHtml5Tokenizer::appendStrBuf(char16_t* buffer, int32_t offset, int32_t length)
 {
-  int32_t reqLen = strBufLen + length;
-  if (strBuf.length < reqLen) {
-    jArray<char16_t,int32_t> newBuf = jArray<char16_t,int32_t>::newJArray(reqLen + (reqLen >> 1));
-    nsHtml5ArrayCopy::arraycopy(strBuf, newBuf, strBuf.length);
-    strBuf = newBuf;
+  int32_t newLen = strBufLen + length;
+  MOZ_ASSERT(newLen <= strBuf.length, "Previous buffer length insufficient.");
+  if (MOZ_UNLIKELY(strBuf.length < newLen)) {
+    if (MOZ_UNLIKELY(!EnsureBufferSpace(length))) {
+      MOZ_CRASH("Unable to recover from buffer reallocation failure");
+    }
   }
   nsHtml5ArrayCopy::arraycopy(buffer, offset, strBuf, strBufLen, length);
-  strBufLen = reqLen;
+  strBufLen = newLen;
 }
 
 void 
 nsHtml5Tokenizer::emitComment(int32_t provisionalHyphens, int32_t pos)
 {
   tokenHandler->comment(strBuf, 0, strBufLen - provisionalHyphens);
   cstart = pos + 1;
 }
--- a/parser/html/nsHtml5Tokenizer.h
+++ b/parser/html/nsHtml5Tokenizer.h
@@ -153,16 +153,17 @@ class nsHtml5Tokenizer
     {
       return line;
     }
 
     nsHtml5HtmlAttributes* emptyAttributes();
   private:
     inline void appendCharRefBuf(char16_t c)
     {
+      MOZ_RELEASE_ASSERT(charRefBufLen < charRefBuf.length, "Attempted to overrun charRefBuf!");
       charRefBuf[charRefBufLen++] = c;
     }
 
     inline void clearCharRefBufAndAppend(char16_t c)
     {
       charRefBuf[0] = c;
       charRefBufLen = 1;
     }
@@ -174,17 +175,27 @@ class nsHtml5Tokenizer
       strBufLen = 1;
     }
 
     inline void clearStrBuf()
     {
       strBufLen = 0;
     }
 
-    void appendStrBuf(char16_t c);
+    inline void appendStrBuf(char16_t c)
+    {
+      MOZ_ASSERT(strBufLen < strBuf.length, "Previous buffer length insufficient.");
+      if (MOZ_UNLIKELY(strBufLen == strBuf.length)) {
+        if (MOZ_UNLIKELY(!EnsureBufferSpace(1))) {
+          MOZ_CRASH("Unable to recover from buffer reallocation failure");
+        }
+      }
+      strBuf[strBufLen++] = c;
+    }
+
   protected:
     nsString* strBufToString();
   private:
     void strBufToDoctypeName();
     void emitStrBuf();
     inline void appendSecondHyphenToBogusComment()
     {
       appendStrBuf('-');
--- a/parser/html/nsHtml5TreeBuilderCppSupplement.h
+++ b/parser/html/nsHtml5TreeBuilderCppSupplement.h
@@ -950,18 +950,18 @@ nsHtml5TreeBuilder::elementPopped(int32_
     mSpeculativeLoadQueue.AppendElement()->InitEndPicture();
   }
   return;
 }
 
 void
 nsHtml5TreeBuilder::accumulateCharacters(const char16_t* aBuf, int32_t aStart, int32_t aLength)
 {
-  MOZ_ASSERT(charBufferLen + aLength <= charBuffer.length,
-             "About to memcpy past the end of the buffer!");
+  MOZ_RELEASE_ASSERT(charBufferLen + aLength <= charBuffer.length,
+                     "About to memcpy past the end of the buffer!");
   memcpy(charBuffer + charBufferLen, aBuf + aStart, sizeof(char16_t) * aLength);
   charBufferLen += aLength;
 }
 
 bool
 nsHtml5TreeBuilder::EnsureBufferSpace(size_t aLength)
 {
   // TODO: Unify nsHtml5Tokenizer::strBuf and nsHtml5TreeBuilder::charBuffer