diff --git a/js/public/JSON.h b/js/public/JSON.h
--- a/js/public/JSON.h
+++ b/js/public/JSON.h
@@ -24,16 +24,23 @@
  * writing stringified data by exactly one call of |callback|, passing |data| as
  * argument.
  *
  * In cases where JSON.stringify would return undefined, this function calls
  * |callback| with the string "null".
+ *
+ * If a length hint is passed, space will be reserved for at least that many
+ * characters.
  */
 extern JS_PUBLIC_API bool JS_Stringify(JSContext* cx,
                                        JS::MutableHandle<JS::Value> value,
                                        JS::Handle<JSObject*> replacer,
                                        JS::Handle<JS::Value> space,
                                        JSONWriteCallback callback, void* data);
+extern JS_PUBLIC_API bool JS_StringifyWithLengthHint(
+    JSContext* cx, JS::MutableHandle<JS::Value> value,
+    JS::Handle<JSObject*> replacer, JS::Handle<JS::Value> space,
+    JSONWriteCallback callback, void* data, size_t lengthHint);
 
 namespace JS {
 
 /**
  * An API akin to JS_Stringify but with the goal of not having observable
diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -3663,17 +3663,29 @@
 }
 
 JS_PUBLIC_API bool JS_Stringify(JSContext* cx, MutableHandleValue vp,
                                 HandleObject replacer, HandleValue space,
                                 JSONWriteCallback callback, void* data) {
+  return JS_StringifyWithLengthHint(cx, vp, replacer, space, callback, data, 0);
+}
+
+JS_PUBLIC_API bool JS_StringifyWithLengthHint(JSContext* cx,
+                                              MutableHandleValue vp,
+                                              HandleObject replacer,
+                                              HandleValue space,
+                                              JSONWriteCallback callback,
+                                              void* data, size_t lengthHint) {
   AssertHeapIsIdle();
   CHECK_THREAD(cx);
   cx->check(replacer, space);
   StringBuilder sb(cx);
   if (!sb.ensureTwoByteChars()) {
     return false;
   }
+  if (lengthHint && !sb.reserve(lengthHint)) {
+    return false;
+  }
   if (!Stringify(cx, vp, replacer, space, sb, StringifyBehavior::Normal)) {
     return false;
   }
   if (sb.empty() && !sb.append(cx->names().null)) {
     return false;

