Bug 1052579 - Add new JSAPI calls for allocating string buffers r=sfink
authorChris Martin <cmartin@mozilla.com>
Fri, 12 Apr 2019 17:09:26 +0000
changeset 469391 ec340bb2dd46575db5d3c2f87b3c1e64b00b6648
parent 469390 bf08ffab68b1df2994baeed67d414271cdecd8b6
child 469392 bcf9b5a72198cb74f6fc063234652583201e4c3e
push id35865
push userapavel@mozilla.com
push dateSat, 13 Apr 2019 21:44:49 +0000
treeherdermozilla-central@2c3837b46068 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1052579
milestone68.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 1052579 - Add new JSAPI calls for allocating string buffers r=sfink Currently, JSAPI malloc calls can only allocate in MallocArena. Now there are calls for when the user intends to allocate a buffer that will be "stolen" by one of the NewString calls. Differential Revision: https://phabricator.services.mozilla.com/D25709
js/public/MemoryFunctions.h
js/src/jsapi.cpp
js/xpconnect/src/XPCConvert.cpp
--- a/js/public/MemoryFunctions.h
+++ b/js/public/MemoryFunctions.h
@@ -38,16 +38,28 @@ extern JS_PUBLIC_API void* JS_realloc(JS
 
 /**
  * A wrapper for |js_free(p)| that may delay |js_free(p)| invocation as a
  * performance optimization.  |cx| may be nullptr.
  */
 extern JS_PUBLIC_API void JS_free(JSContext* cx, void* p);
 
 /**
+ * Same as above, but for buffers that will be used with the BYOB
+ * (Bring Your Own Buffer) JSString creation functions, such as
+ * JS_NewLatin1String and JS_NewUCString
+ */
+extern JS_PUBLIC_API void* JS_string_malloc(JSContext* cx, size_t nbytes);
+
+extern JS_PUBLIC_API void* JS_string_realloc(JSContext* cx, void* p,
+                                             size_t oldBytes, size_t newBytes);
+
+extern JS_PUBLIC_API void JS_string_free(JSContext* cx, void* p);
+
+/**
  * A wrapper for |js_free(p)| that may delay |js_free(p)| invocation as a
  * performance optimization as specified by the given JSFreeOp instance.
  */
 extern JS_PUBLIC_API void JS_freeop(JSFreeOp* fop, void* p);
 
 extern JS_PUBLIC_API void JS_updateMallocCounter(JSContext* cx, size_t nbytes);
 
 #endif /* js_MemoryFunctions_h */
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -1127,16 +1127,33 @@ JS_PUBLIC_API void* JS_realloc(JSContext
   AssertHeapIsIdle();
   CHECK_THREAD(cx);
   return static_cast<void*>(cx->maybe_pod_realloc<uint8_t>(
       static_cast<uint8_t*>(p), oldBytes, newBytes));
 }
 
 JS_PUBLIC_API void JS_free(JSContext* cx, void* p) { return js_free(p); }
 
+JS_PUBLIC_API void* JS_string_malloc(JSContext* cx, size_t nbytes) {
+  AssertHeapIsIdle();
+  CHECK_THREAD(cx);
+  return static_cast<void*>(
+      cx->maybe_pod_malloc<uint8_t>(nbytes, js::MallocArena));
+}
+
+JS_PUBLIC_API void* JS_string_realloc(JSContext* cx, void* p, size_t oldBytes,
+                                      size_t newBytes) {
+  AssertHeapIsIdle();
+  CHECK_THREAD(cx);
+  return static_cast<void*>(cx->maybe_pod_realloc<uint8_t>(
+      static_cast<uint8_t*>(p), oldBytes, newBytes, js::MallocArena));
+}
+
+JS_PUBLIC_API void JS_string_free(JSContext* cx, void* p) { return js_free(p); }
+
 JS_PUBLIC_API void JS_freeop(JSFreeOp* fop, void* p) {
   return FreeOp::get(fop)->free_(p);
 }
 
 JS_PUBLIC_API void JS_updateMallocCounter(JSContext* cx, size_t nbytes) {
   return cx->updateMallocCounter(nbytes);
 }
 
--- a/js/xpconnect/src/XPCConvert.cpp
+++ b/js/xpconnect/src/XPCConvert.cpp
@@ -260,18 +260,18 @@ bool XPCConvert::NativeData2JS(JSContext
       // Usage of UTF-8 in XPConnect is mostly for things that are
       // almost always ASCII, so the inexact allocations below
       // should be fine.
 
       if (IsUTF8Latin1(*utf8String)) {
         using UniqueLatin1Chars =
             js::UniquePtr<JS::Latin1Char[], JS::FreePolicy>;
 
-        UniqueLatin1Chars buffer(
-            static_cast<JS::Latin1Char*>(JS_malloc(cx, allocLen.value())));
+        UniqueLatin1Chars buffer(static_cast<JS::Latin1Char*>(
+            JS_string_malloc(cx, allocLen.value())));
         if (!buffer) {
           return false;
         }
 
         size_t written = LossyConvertUTF8toLatin1(
             *utf8String, MakeSpan(reinterpret_cast<char*>(buffer.get()), len));
         buffer[written] = 0;
 
@@ -294,17 +294,17 @@ bool XPCConvert::NativeData2JS(JSContext
       // below). allocLen already takes the zero terminator
       // into account.
       allocLen *= sizeof(char16_t);
       if (!allocLen.isValid()) {
         return false;
       }
 
       JS::UniqueTwoByteChars buffer(
-          static_cast<char16_t*>(JS_malloc(cx, allocLen.value())));
+          static_cast<char16_t*>(JS_string_malloc(cx, allocLen.value())));
       if (!buffer) {
         return false;
       }
 
       // For its internal simplicity, ConvertUTF8toUTF16 requires the
       // destination to be one code unit longer than the source, but
       // it never actually writes more code units than the number of
       // code units in the source. That's why it's OK to claim the