Bug 1516007 - Avoid extra work in nsIDocument::ScrollToRef. r=ehsan
authorEric Rahm <erahm@mozilla.com>
Wed, 19 Dec 2018 17:02:43 -0800
changeset 510094 632ce013755e9616ffb69d73959fb7bebab5a9c7
parent 510093 f6a85c2b0dffda801e097f6efea14b46a35626e2
child 510095 f0bf0b42b3cf98615a6a911282761b2ffa9122cb
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs1516007
milestone66.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 1516007 - Avoid extra work in nsIDocument::ScrollToRef. r=ehsan We can avoid making an extra copy when unescaping `mScrollToRef` by using `NS_UnescapeURL` instead of `nsUnescape`. Additionally we can avoid calling `GoToAnchor` a second time if nothing was unescaped.
dom/base/Document.cpp
--- a/dom/base/Document.cpp
+++ b/dom/base/Document.cpp
@@ -8697,35 +8697,35 @@ void Document::ScrollToRef() {
     if (!ref.IsEmpty()) {
       // Note that GoToAnchor will handle flushing layout as needed.
       rv = shell->GoToAnchor(ref, mChangeScrollPosWhenScrollingToRef);
     } else {
       rv = NS_ERROR_FAILURE;
     }
 
     if (NS_FAILED(rv)) {
-      char* tmpstr = ToNewCString(mScrollToRef);
-      if (!tmpstr) {
-        return;
-      }
-      nsUnescape(tmpstr);
-      nsAutoCString unescapedRef;
-      unescapedRef.Assign(tmpstr);
-      free(tmpstr);
-
-      NS_ConvertUTF8toUTF16 utf16Str(unescapedRef);
-      if (!utf16Str.IsEmpty()) {
-        rv = shell->GoToAnchor(utf16Str, mChangeScrollPosWhenScrollingToRef);
+      nsAutoCString buff;
+      const bool unescaped =
+          NS_UnescapeURL(mScrollToRef.BeginReading(), mScrollToRef.Length(),
+                         /*aFlags =*/0, buff);
+
+      // This attempt is only necessary if characters were unescaped.
+      if (unescaped) {
+        NS_ConvertUTF8toUTF16 utf16Str(buff);
+        if (!utf16Str.IsEmpty()) {
+          rv = shell->GoToAnchor(utf16Str, mChangeScrollPosWhenScrollingToRef);
+        }
       }
 
       // If UTF-8 URI failed then try to assume the string as a
       // document's charset.
       if (NS_FAILED(rv)) {
         const Encoding* encoding = GetDocumentCharacterSet();
-        rv = encoding->DecodeWithoutBOMHandling(unescapedRef, ref);
+        rv = encoding->DecodeWithoutBOMHandling(
+            unescaped ? buff : mScrollToRef, ref);
         if (NS_SUCCEEDED(rv) && !ref.IsEmpty()) {
           rv = shell->GoToAnchor(ref, mChangeScrollPosWhenScrollingToRef);
         }
       }
     }
     if (NS_SUCCEEDED(rv)) {
       mScrolledToRefAlready = true;
     }