Bug 1295017 - Part 1: Make lossy conversion available off main thread. r=jwalden
authorTooru Fujisawa <arai_a@mac.com>
Sat, 13 Aug 2016 23:50:30 +0900
changeset 315601 4b2d47b727467980a41f31428bde7308b689446f
parent 315600 3a1255c1e0ca098128f7a4e920ac38c14a43c708
child 315602 f69bdda3779b11fba984cc21296004bc89edeb49
push id82228
push userarai_a@mac.com
push dateThu, 29 Sep 2016 03:04:21 +0000
treeherdermozilla-inbound@e78af6564ec3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwalden
bugs1295017
milestone52.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 1295017 - Part 1: Make lossy conversion available off main thread. r=jwalden
js/src/jscntxt.h
js/src/vm/CharacterEncoding.cpp
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -6,16 +6,17 @@
 
 /* JS execution context. */
 
 #ifndef jscntxt_h
 #define jscntxt_h
 
 #include "mozilla/MemoryReporting.h"
 
+#include "js/CharacterEncoding.h"
 #include "js/GCVector.h"
 #include "js/Vector.h"
 #include "vm/Caches.h"
 #include "vm/Runtime.h"
 
 #ifdef _MSC_VER
 #pragma warning(push)
 #pragma warning(disable:4100) /* Silence unreferenced formal parameter warnings */
@@ -812,16 +813,29 @@ class MOZ_RAII AutoLockForExclusiveAcces
             runtime->mainThreadHasExclusiveAccess = false;
 #endif
         }
     }
 
     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
+/*
+ * ExclusiveContext variants of encoding functions, for off-main-thread use.
+ * Refer to CharacterEncoding.h for details.
+ */
+extern JS::TwoByteCharsZ
+LossyUTF8CharsToNewTwoByteCharsZ(ExclusiveContext* cx, const JS::UTF8Chars utf8, size_t* outlen);
+
+extern JS::TwoByteCharsZ
+LossyUTF8CharsToNewTwoByteCharsZ(ExclusiveContext* cx, const JS::ConstUTF8CharsZ& utf8, size_t* outlen);
+
+extern JS::Latin1CharsZ
+LossyUTF8CharsToNewLatin1CharsZ(ExclusiveContext* cx, const JS::UTF8Chars utf8, size_t* outlen);
+
 } /* namespace js */
 
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
 
 inline JSContext*
 JSRuntime::unsafeContextFromAnyThread()
--- a/js/src/vm/CharacterEncoding.cpp
+++ b/js/src/vm/CharacterEncoding.cpp
@@ -231,46 +231,61 @@ ReportInvalidCharacter(JSContext* cx, ui
 {
     char buffer[10];
     SprintfLiteral(buffer, "%u", offset);
     JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, GetErrorMessage, nullptr,
                                  JSMSG_MALFORMED_UTF8_CHAR, buffer);
 }
 
 static void
+ReportInvalidCharacter(js::ExclusiveContext* cx, uint32_t offset)
+{
+}
+
+static void
 ReportBufferTooSmall(JSContext* cx, uint32_t dummy)
 {
     JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_BUFFER_TOO_SMALL);
 }
 
 static void
+ReportBufferTooSmall(js::ExclusiveContext* cx, uint32_t dummy)
+{
+}
+
+static void
 ReportTooBigCharacter(JSContext* cx, uint32_t v)
 {
     char buffer[10];
     SprintfLiteral(buffer, "0x%x", v + 0x10000);
     JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, GetErrorMessage, nullptr,
                                  JSMSG_UTF8_CHAR_TOO_LARGE, buffer);
 }
 
+static void
+ReportTooBigCharacter(js::ExclusiveContext* cx, uint32_t v)
+{
+}
+
 enum InflateUTF8Action {
     CountAndReportInvalids,
     CountAndIgnoreInvalids,
     AssertNoInvalids,
     Copy,
     FindEncoding
 };
 
 static const char16_t REPLACE_UTF8 = 0xFFFD;
 static const Latin1Char REPLACE_UTF8_LATIN1 = '?';
 
 // If making changes to this algorithm, make sure to also update
 // LossyConvertUTF8toUTF16() in dom/wifi/WifiUtils.cpp
-template <InflateUTF8Action Action, typename CharT>
+template <InflateUTF8Action Action, typename CharT, class ContextT>
 static bool
-InflateUTF8StringToBuffer(JSContext* cx, const UTF8Chars src, CharT* dst, size_t* dstlenp,
+InflateUTF8StringToBuffer(ContextT* cx, const UTF8Chars src, CharT* dst, size_t* dstlenp,
                           JS::SmallestEncoding *smallestEncoding)
 {
     if (Action != AssertNoInvalids)
         *smallestEncoding = JS::SmallestEncoding::ASCII;
     auto RequireLatin1 = [&smallestEncoding]{
         *smallestEncoding = std::max(JS::SmallestEncoding::Latin1, *smallestEncoding);
     };
     auto RequireUTF16 = [&smallestEncoding]{
@@ -378,34 +393,34 @@ InflateUTF8StringToBuffer(JSContext* cx,
             // header will do the final i++ to move to the start of the next
             // code unit.
             i += n - 1;
             if (Action != AssertNoInvalids)
                 RequireUTF16();
         }
     }
 
-    if (Action != AssertNoInvalids || Action != FindEncoding)
+    if (Action != AssertNoInvalids && Action != FindEncoding)
         *dstlenp = j;
 
     return true;
 }
 
-template <InflateUTF8Action Action, typename CharsT>
+template <InflateUTF8Action Action, typename CharsT, class ContextT>
 static CharsT
-InflateUTF8StringHelper(JSContext* cx, const UTF8Chars src, size_t* outlen)
+InflateUTF8StringHelper(ContextT* cx, const UTF8Chars src, size_t* outlen)
 {
     using CharT = typename CharsT::CharT;
     *outlen = 0;
 
     JS::SmallestEncoding encoding;
     if (!InflateUTF8StringToBuffer<Action, CharT>(cx, src, /* dst = */ nullptr, outlen, &encoding))
         return CharsT();
 
-    CharT* dst = cx->pod_malloc<CharT>(*outlen + 1);  // +1 for NUL
+    CharT* dst = cx->template pod_malloc<CharT>(*outlen + 1);  // +1 for NUL
     if (!dst) {
         ReportOutOfMemory(cx);
         return CharsT();
     }
 
     if (encoding == JS::SmallestEncoding::ASCII) {
         size_t srclen = src.length();
         MOZ_ASSERT(*outlen == srclen);
@@ -429,55 +444,77 @@ JS::UTF8CharsToNewTwoByteCharsZ(JSContex
 TwoByteCharsZ
 JS::UTF8CharsToNewTwoByteCharsZ(JSContext* cx, const ConstUTF8CharsZ& utf8, size_t* outlen)
 {
     UTF8Chars chars(utf8.c_str(), strlen(utf8.c_str()));
     return InflateUTF8StringHelper<CountAndReportInvalids, TwoByteCharsZ>(cx, chars, outlen);
 }
 
 TwoByteCharsZ
-JS::LossyUTF8CharsToNewTwoByteCharsZ(JSContext* cx, const UTF8Chars utf8, size_t* outlen)
+js::LossyUTF8CharsToNewTwoByteCharsZ(js::ExclusiveContext* cx, const JS::UTF8Chars utf8, size_t* outlen)
 {
     return InflateUTF8StringHelper<CountAndIgnoreInvalids, TwoByteCharsZ>(cx, utf8, outlen);
 }
 
 TwoByteCharsZ
-JS::LossyUTF8CharsToNewTwoByteCharsZ(JSContext* cx, const ConstUTF8CharsZ& utf8, size_t* outlen)
+JS::LossyUTF8CharsToNewTwoByteCharsZ(JSContext* cx, const UTF8Chars utf8, size_t* outlen)
+{
+    return js::LossyUTF8CharsToNewTwoByteCharsZ(cx, utf8, outlen);
+}
+
+TwoByteCharsZ
+js::LossyUTF8CharsToNewTwoByteCharsZ(js::ExclusiveContext* cx, const JS::ConstUTF8CharsZ& utf8, size_t* outlen)
 {
     UTF8Chars chars(utf8.c_str(), strlen(utf8.c_str()));
     return InflateUTF8StringHelper<CountAndIgnoreInvalids, TwoByteCharsZ>(cx, chars, outlen);
 }
 
+TwoByteCharsZ
+JS::LossyUTF8CharsToNewTwoByteCharsZ(JSContext* cx, const ConstUTF8CharsZ& utf8, size_t* outlen)
+{
+    return js::LossyUTF8CharsToNewTwoByteCharsZ(cx, utf8, outlen);
+}
+
 JS::SmallestEncoding
 JS::FindSmallestEncoding(UTF8Chars utf8)
 {
     JS::SmallestEncoding encoding;
-    MOZ_ALWAYS_TRUE((InflateUTF8StringToBuffer<FindEncoding, char16_t>(
+    MOZ_ALWAYS_TRUE((InflateUTF8StringToBuffer<FindEncoding, char16_t, JSContext>(
                          /* cx = */ nullptr,
                          utf8,
                          /* dst = */ nullptr,
                          /* dstlen = */ nullptr,
                          &encoding)));
     return encoding;
 }
 
 Latin1CharsZ
 JS::UTF8CharsToNewLatin1CharsZ(JSContext* cx, const UTF8Chars utf8, size_t* outlen)
 {
     return InflateUTF8StringHelper<CountAndReportInvalids, Latin1CharsZ>(cx, utf8, outlen);
 }
 
 Latin1CharsZ
+js::LossyUTF8CharsToNewLatin1CharsZ(js::ExclusiveContext* cx, const JS::UTF8Chars utf8, size_t* outlen)
+{
+    return InflateUTF8StringHelper<CountAndIgnoreInvalids, Latin1CharsZ>(cx, utf8, outlen);
+}
+
+Latin1CharsZ
 JS::LossyUTF8CharsToNewLatin1CharsZ(JSContext* cx, const UTF8Chars utf8, size_t* outlen)
 {
-    return InflateUTF8StringHelper<CountAndIgnoreInvalids, Latin1CharsZ>(cx, utf8, outlen);
+    return js::LossyUTF8CharsToNewLatin1CharsZ(cx, utf8, outlen);
 }
 
 #ifdef DEBUG
 void
 JS::ConstUTF8CharsZ::validate(size_t aLength)
 {
     MOZ_ASSERT(data_);
     UTF8Chars chars(data_, aLength);
-    InflateUTF8StringToBuffer<AssertNoInvalids, char16_t>(nullptr, chars, nullptr, nullptr,
-                                                          nullptr);
+    InflateUTF8StringToBuffer<AssertNoInvalids, char16_t, JSContext>(
+        /* cx = */ nullptr,
+        chars,
+        /* dst = */ nullptr,
+        /* dstlen = */ nullptr,
+        /* smallestEncoding = */ nullptr);
 }
 #endif