Bug 903519 - Make js::Allocate cast strings to requested type, r=jonco
☠☠ backed out by 65e92478e09d ☠ ☠
authorSteve Fink <sfink@mozilla.com>
Tue, 13 Jun 2017 15:15:48 -0700
changeset 453149 80b9d97bf1fe4e23066f4ac7283ab276c3e942f0
parent 453148 1fc5ee0d0116300963a2490fb485207eaa9ada02
child 453150 457008b194a87ec4dd57858d25fa94f2606492db
push id1648
push usermtabara@mozilla.com
push dateThu, 01 Mar 2018 12:45:47 +0000
treeherdermozilla-release@cbb9688c2eeb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonco
bugs903519
milestone59.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 903519 - Make js::Allocate cast strings to requested type, r=jonco Note that this patch passes in a dummy gc::InitialHeap parameter that is required to be TenuredHeap, since strings cannot yet be nursery-allocated. This restriction will be lifted in a later patch.
js/src/gc/Allocator.h
js/src/vm/String-inl.h
--- a/js/src/gc/Allocator.h
+++ b/js/src/gc/Allocator.h
@@ -5,32 +5,62 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef gc_Allocator_h
 #define gc_Allocator_h
 
 #include "gc/Heap.h"
 #include "js/RootingAPI.h"
 
+class JSFatInlineString;
+
 namespace js {
 
 struct Class;
 
 // Allocate a new GC thing. After a successful allocation the caller must
 // fully initialize the thing before calling any function that can potentially
 // trigger GC. This will ensure that GC tracing never sees junk values stored
 // in the partially initialized thing.
-//
-// Note that JSObject allocation must use the longer signature below that
-// includes slot, heap, and finalizer information in support of various
-// object-specific optimizations.
+
 template <typename T, AllowGC allowGC = CanGC>
 T*
 Allocate(JSContext* cx);
 
+// Use for JSObject. A longer signature that includes additional information in
+// support of various optimizations.
 template <typename, AllowGC allowGC = CanGC>
 JSObject*
 Allocate(JSContext* cx, gc::AllocKind kind, size_t nDynamicSlots, gc::InitialHeap heap,
          const Class* clasp);
 
+// Use for nursery-allocatable strings. Returns a value cast to the correct
+// type.
+template <typename StringT, AllowGC allowGC = CanGC>
+StringT*
+Allocate(JSContext* cx, gc::InitialHeap heap)
+{
+    MOZ_ASSERT(heap == gc::TenuredHeap);
+    return static_cast<StringT*>(js::Allocate<JSString, allowGC>(cx));
+}
+
+// Specialization for JSFatInlineString that must use a different allocation
+// type. Note that we have to explicitly specialize for both values of AllowGC
+// because partial function specialization is not allowed.
+template <>
+inline JSFatInlineString*
+Allocate<JSFatInlineString, CanGC>(JSContext* cx, gc::InitialHeap heap)
+{
+    MOZ_ASSERT(heap == gc::TenuredHeap);
+    return static_cast<JSFatInlineString*>(js::Allocate<JSFatInlineString, CanGC>(cx));
+}
+
+template <>
+inline JSFatInlineString*
+Allocate<JSFatInlineString, NoGC>(JSContext* cx, gc::InitialHeap heap)
+{
+    MOZ_ASSERT(heap == gc::TenuredHeap);
+    return static_cast<JSFatInlineString*>(js::Allocate<JSFatInlineString, NoGC>(cx));
+}
+
 } // namespace js
 
 #endif // gc_Allocator_h
--- a/js/src/vm/String-inl.h
+++ b/js/src/vm/String-inl.h
@@ -121,17 +121,17 @@ template <js::AllowGC allowGC>
 MOZ_ALWAYS_INLINE JSRope*
 JSRope::new_(JSContext* cx,
              typename js::MaybeRooted<JSString*, allowGC>::HandleType left,
              typename js::MaybeRooted<JSString*, allowGC>::HandleType right,
              size_t length)
 {
     if (!validateLength(cx, length))
         return nullptr;
-    JSRope* str = static_cast<JSRope*>(js::Allocate<JSString, allowGC>(cx));
+    JSRope* str = js::Allocate<JSRope, allowGC>(cx, js::gc::TenuredHeap);
     if (!str)
         return nullptr;
     str->init(cx, left, right, length);
     return str;
 }
 
 MOZ_ALWAYS_INLINE void
 JSDependentString::init(JSContext* cx, JSLinearString* base, size_t start,
@@ -181,25 +181,25 @@ JSDependentString::new_(JSContext* cx, J
         return baseArg->hasLatin1Chars()
                ? js::NewInlineString<JS::Latin1Char>(cx, base, start, length)
                : js::NewInlineString<char16_t>(cx, base, start, length);
     }
 
     if (baseArg->isExternal() && !baseArg->ensureFlat(cx))
         return nullptr;
 
-    JSDependentString* str = static_cast<JSDependentString*>(js::Allocate<JSString, js::NoGC>(cx));
+    JSDependentString* str = js::Allocate<JSDependentString, js::NoGC>(cx, js::gc::TenuredHeap);
     if (str) {
         str->init(cx, baseArg, start, length);
         return str;
     }
 
     js::RootedLinearString base(cx, baseArg);
 
-    str = static_cast<JSDependentString*>(js::Allocate<JSString>(cx));
+    str = js::Allocate<JSDependentString>(cx, js::gc::TenuredHeap);
     if (!str)
         return nullptr;
     str->init(cx, base, start, length);
     return str;
 }
 
 MOZ_ALWAYS_INLINE void
 JSFlatString::init(const char16_t* chars, size_t length)
@@ -225,17 +225,17 @@ JSFlatString::new_(JSContext* cx, const 
 
     if (!validateLength(cx, length))
         return nullptr;
 
     JSFlatString* str;
     if (cx->compartment()->isAtomsCompartment())
         str = js::Allocate<js::NormalAtom, allowGC>(cx);
     else
-        str = static_cast<JSFlatString*>(js::Allocate<JSString, allowGC>(cx));
+        str = js::Allocate<JSFlatString, allowGC>(cx, js::gc::TenuredHeap);
     if (!str)
         return nullptr;
 
     str->init(chars, length);
     return str;
 }
 
 inline js::PropertyName*
@@ -255,27 +255,27 @@ JSFlatString::toPropertyName(JSContext* 
 
 template <js::AllowGC allowGC>
 MOZ_ALWAYS_INLINE JSThinInlineString*
 JSThinInlineString::new_(JSContext* cx)
 {
     if (cx->compartment()->isAtomsCompartment())
         return (JSThinInlineString*)(js::Allocate<js::NormalAtom, allowGC>(cx));
 
-    return static_cast<JSThinInlineString*>(js::Allocate<JSString, allowGC>(cx));
+    return js::Allocate<JSThinInlineString, allowGC>(cx, js::gc::TenuredHeap);
 }
 
 template <js::AllowGC allowGC>
 MOZ_ALWAYS_INLINE JSFatInlineString*
 JSFatInlineString::new_(JSContext* cx)
 {
     if (cx->compartment()->isAtomsCompartment())
         return (JSFatInlineString*)(js::Allocate<js::FatInlineAtom, allowGC>(cx));
 
-    return js::Allocate<JSFatInlineString, allowGC>(cx);
+    return js::Allocate<JSFatInlineString, allowGC>(cx, js::gc::TenuredHeap);
 }
 
 template<>
 MOZ_ALWAYS_INLINE JS::Latin1Char*
 JSThinInlineString::init<JS::Latin1Char>(size_t length)
 {
     MOZ_ASSERT(lengthFits<JS::Latin1Char>(length));
     d.u1.length = length;