diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py
index 6b134662ed8e52d241d65d2f8de6f88f8225af2f..67171330a00ea3f204cfa1d9ad41c99194df59b2 100644
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -6371,8 +6371,7 @@ class CGMemberJITInfo(CGThing):
                 "  %s,  /* isInSlot.  Only relevant for getters. */\n"
                 "  %s,  /* Reserved slot index, if we're stored in a slot, else 0. */\n"
                 "  JSJitInfo::%s,  /* aliasSet.  Not relevant for setters. */\n"
-                "  %s,  /* argTypes.  Only relevant for methods */\n"
-                "  nullptr /* parallelNative */\n"
+                "  %s   /* argTypes.  Only relevant for methods */\n"
                 "};\n" % (argTypesDecl, infoName, opName, protoID, depth,
                           opType, returnType, failstr, movablestr, slotStr,
                           slotIndex, aliasSet, argTypes))
diff --git a/js/src/builtin/TypedObject.cpp b/js/src/builtin/TypedObject.cpp
index eac3c0d669649557c261f7950776282eb6d7aa28..1cf9906263f3d2a4971c9077a1d1a46697d4eebe 100644
--- a/js/src/builtin/TypedObject.cpp
+++ b/js/src/builtin/TypedObject.cpp
@@ -2539,9 +2539,7 @@ js::AttachHandle(ThreadSafeContext *, unsigned argc, Value *vp)
     return true;
 }
 
-const JSJitInfo js::AttachHandleJitInfo =
-    JS_JITINFO_NATIVE_PARALLEL(
-        JSParallelNativeThreadSafeWrapper<js::AttachHandle>);
+JS_JITINFO_NATIVE_PARALLEL(js::AttachHandleJitInfo, AttachHandleJitInfo, js::AttachHandle);
 
 bool
 js::ObjectIsTypeObject(ThreadSafeContext *, unsigned argc, Value *vp)
@@ -2553,9 +2551,7 @@ js::ObjectIsTypeObject(ThreadSafeContext *, unsigned argc, Value *vp)
     return true;
 }
 
-const JSJitInfo js::ObjectIsTypeObjectJitInfo =
-    JS_JITINFO_NATIVE_PARALLEL(
-        JSParallelNativeThreadSafeWrapper<js::ObjectIsTypeObject>);
+JS_JITINFO_NATIVE_PARALLEL(js::ObjectIsTypeObjectJitInfo, ObjectIsTypeObjectJitInfo, js::ObjectIsTypeObject);
 
 bool
 js::ObjectIsTypeRepresentation(ThreadSafeContext *, unsigned argc, Value *vp)
@@ -2567,9 +2563,7 @@ js::ObjectIsTypeRepresentation(ThreadSafeContext *, unsigned argc, Value *vp)
     return true;
 }
 
-const JSJitInfo js::ObjectIsTypeRepresentationJitInfo =
-    JS_JITINFO_NATIVE_PARALLEL(
-        JSParallelNativeThreadSafeWrapper<js::ObjectIsTypeRepresentation>);
+JS_JITINFO_NATIVE_PARALLEL(js::ObjectIsTypeRepresentationJitInfo, ObjectIsTypeRepresentationJitInfo, js::ObjectIsTypeRepresentation);
 
 bool
 js::ObjectIsTypedHandle(ThreadSafeContext *, unsigned argc, Value *vp)
@@ -2581,9 +2575,7 @@ js::ObjectIsTypedHandle(ThreadSafeContext *, unsigned argc, Value *vp)
     return true;
 }
 
-const JSJitInfo js::ObjectIsTypedHandleJitInfo =
-    JS_JITINFO_NATIVE_PARALLEL(
-        JSParallelNativeThreadSafeWrapper<js::ObjectIsTypedHandle>);
+JS_JITINFO_NATIVE_PARALLEL(js::ObjectIsTypedHandleJitInfo, ObjectIsTypedHandleJitInfo, js::ObjectIsTypedHandle);
 
 bool
 js::ObjectIsTypedObject(ThreadSafeContext *, unsigned argc, Value *vp)
@@ -2595,9 +2587,7 @@ js::ObjectIsTypedObject(ThreadSafeContext *, unsigned argc, Value *vp)
     return true;
 }
 
-const JSJitInfo js::ObjectIsTypedObjectJitInfo =
-    JS_JITINFO_NATIVE_PARALLEL(
-        JSParallelNativeThreadSafeWrapper<js::ObjectIsTypedObject>);
+JS_JITINFO_NATIVE_PARALLEL(js::ObjectIsTypedObjectJitInfo, ObjectIsTypedObjectJitInfo, js::ObjectIsTypedObject);
 
 bool
 js::IsAttached(ThreadSafeContext *cx, unsigned argc, Value *vp)
@@ -2608,9 +2598,7 @@ js::IsAttached(ThreadSafeContext *cx, unsigned argc, Value *vp)
     return true;
 }
 
-const JSJitInfo js::IsAttachedJitInfo =
-    JS_JITINFO_NATIVE_PARALLEL(
-        JSParallelNativeThreadSafeWrapper<js::IsAttached>);
+JS_JITINFO_NATIVE_PARALLEL(js::IsAttachedJitInfo, IsAttachedJitInfo, js::IsAttached);
 
 bool
 js::ClampToUint8(ThreadSafeContext *, unsigned argc, Value *vp)
@@ -2622,9 +2610,7 @@ js::ClampToUint8(ThreadSafeContext *, unsigned argc, Value *vp)
     return true;
 }
 
-const JSJitInfo js::ClampToUint8JitInfo =
-    JS_JITINFO_NATIVE_PARALLEL(
-        JSParallelNativeThreadSafeWrapper<js::ClampToUint8>);
+JS_JITINFO_NATIVE_PARALLEL(js::ClampToUint8JitInfo, ClampToUint8JitInfo, js::ClampToUint8);
 
 bool
 js::Memcpy(ThreadSafeContext *, unsigned argc, Value *vp)
@@ -2645,9 +2631,7 @@ js::Memcpy(ThreadSafeContext *, unsigned argc, Value *vp)
     return true;
 }
 
-const JSJitInfo js::MemcpyJitInfo =
-    JS_JITINFO_NATIVE_PARALLEL(
-        JSParallelNativeThreadSafeWrapper<js::Memcpy>);
+JS_JITINFO_NATIVE_PARALLEL(js::MemcpyJitInfo, MemcpyJitInfo, js::Memcpy);
 
 bool
 js::GetTypedObjectModule(JSContext *cx, unsigned argc, Value *vp)
@@ -2701,10 +2685,7 @@ js::StoreScalar##T::Func(ThreadSafeContext *, unsigned argc, Value *vp)       \
     return true;                                                              \
 }                                                                             \
                                                                               \
-const JSJitInfo                                                               \
-js::StoreScalar##T::JitInfo =                                                 \
-    JS_JITINFO_NATIVE_PARALLEL(                                               \
-        JSParallelNativeThreadSafeWrapper<Func>);
+ JS_JITINFO_NATIVE_PARALLEL(js::StoreScalar##T::JitInfo, StoreScalar##T, js::StoreScalar##T::Func);
 
 #define JS_STORE_REFERENCE_CLASS_IMPL(_constant, T, _name)                      \
 bool                                                                            \
@@ -2727,10 +2708,7 @@ js::StoreReference##T::Func(ThreadSafeContext *, unsigned argc, Value *vp)
     return true;                                                                \
 }                                                                               \
                                                                                 \
-const JSJitInfo                                                                 \
-js::StoreReference##T::JitInfo =                                                \
-    JS_JITINFO_NATIVE_PARALLEL(                                                 \
-        JSParallelNativeThreadSafeWrapper<Func>);
+ JS_JITINFO_NATIVE_PARALLEL(js::StoreReference##T::JitInfo, StoreReference##T, js::StoreReference##T::Func);
 
 #define JS_LOAD_SCALAR_CLASS_IMPL(_constant, T, _name)                        \
 bool                                                                          \
@@ -2751,10 +2729,7 @@ js::LoadScalar##T::Func(ThreadSafeContext *, unsigned argc, Value *vp)        \
     return true;                                                              \
 }                                                                             \
                                                                               \
-const JSJitInfo                                                               \
-js::LoadScalar##T::JitInfo =                                                  \
-    JS_JITINFO_NATIVE_PARALLEL(                                               \
-        JSParallelNativeThreadSafeWrapper<Func>);
+ JS_JITINFO_NATIVE_PARALLEL(js::LoadScalar##T::JitInfo, LoadScalar##T, js::LoadScalar##T::Func);
 
 #define JS_LOAD_REFERENCE_CLASS_IMPL(_constant, T, _name)                     \
 bool                                                                          \
@@ -2776,10 +2751,7 @@ js::LoadReference##T::Func(ThreadSafeContext *, unsigned argc, Value *vp)     \
     return true;                                                              \
 }                                                                             \
                                                                               \
-const JSJitInfo                                                               \
-js::LoadReference##T::JitInfo =                                               \
-    JS_JITINFO_NATIVE_PARALLEL(                                               \
-        JSParallelNativeThreadSafeWrapper<Func>);
+ JS_JITINFO_NATIVE_PARALLEL(js::LoadReference##T::JitInfo, LoadReference##T, js::LoadReference##T::Func);
 
 // Because the precise syntax for storing values/objects/strings
 // differs, we abstract it away using specialized variants of the
diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h
index 35f755d65ee00859c0ddeb51dc0e515ade15fcf4..0b371991090764151fffe8d25612d7543dc77c3f 100644
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -1452,7 +1452,7 @@ struct JSJitInfo {
         Getter,
         Setter,
         Method,
-        OpType_None
+        ParallelNative
     };
 
     enum ArgType {
@@ -1494,20 +1494,27 @@ struct JSJitInfo {
         AliasEverything
     };
 
+    bool hasParallelNative() const
+    {
+        return type == ParallelNative;
+    }
+
     bool isDOMJitInfo() const
     {
-        return type != OpType_None;
+        return type != ParallelNative;
     }
 
     union {
         JSJitGetterOp getter;
         JSJitSetterOp setter;
         JSJitMethodOp method;
+        /* An alternative native that's safe to call in parallel mode. */
+        JSParallelNative parallelNative;
     };
 
     uint32_t protoID;
     uint32_t depth;
-    // type not being OpType_None means this is a DOM method.  If you
+    // type not being ParallelNative means this is a DOM method.  If you
     // change that, come up with a different way of implementing
     // isDOMJitInfo().
     OpType type;
@@ -1536,9 +1543,6 @@ struct JSJitInfo {
                                       if we have no type information for
                                       arguments. */
 
-    /* An alternative native that's safe to call in parallel mode. */
-    JSParallelNative parallelNative;
-
 private:
     static void staticAsserts()
     {
@@ -1551,8 +1555,27 @@ private:
     }
 };
 
-#define JS_JITINFO_NATIVE_PARALLEL(op)                                         \
-    {{nullptr},0,0,JSJitInfo::OpType_None,JSVAL_TYPE_MISSING,false,false,false,0,JSJitInfo::AliasEverything,nullptr,op}
+/*
+ * You may ask yourself: why do we define a wrapper around a wrapper here?
+ * The answer is that some compilers don't understand initializing a union
+ * as we do below with a construct like:
+ *
+ * reinterpret_cast<JSJitGetterOp>(JSParallelNativeThreadSafeWrapper<op>)
+ *
+ * (We need the reinterpret_cast because we must initialize the union with
+ * a datum of the type of the union's first member.)
+ *
+ * Presumably this has something to do with template instantiation.
+ * Initializing with a normal function pointer seems to work fine. Hence
+ * the ugliness that you see before you.
+ */
+#define JS_JITINFO_NATIVE_PARALLEL(infoName, wrapperName, serialOp)     \
+    bool wrapperName##_ParallelNativeThreadSafeWrapper(js::ForkJoinSlice *slice, unsigned argc, JS::Value *vp) \
+    {                                                                   \
+        return JSParallelNativeThreadSafeWrapper<serialOp>(slice, argc, vp); \
+    }                                                                   \
+    const JSJitInfo infoName =                                          \
+        {{reinterpret_cast<JSJitGetterOp>(wrapperName##_ParallelNativeThreadSafeWrapper)},0,0,JSJitInfo::ParallelNative,JSVAL_TYPE_MISSING,false,false,false,0,JSJitInfo::AliasEverything,nullptr}
 
 static JS_ALWAYS_INLINE const JSJitInfo *
 FUNCTION_VALUE_TO_JITINFO(const JS::Value& v)
diff --git a/js/src/jsfun.h b/js/src/jsfun.h
index bdf1d733f0113b07022d7fe82f32b9018e584eed..502843c2a9e734a397e2742fd10804d2d693c9f9 100644
--- a/js/src/jsfun.h
+++ b/js/src/jsfun.h
@@ -179,7 +179,7 @@ class JSFunction : public JSObject
         return isLambda() && displayAtom() && !hasGuessedAtom();
     }
     bool hasParallelNative() const {
-        return isNative() && jitInfo() && !!jitInfo()->parallelNative;
+        return isNative() && jitInfo() && jitInfo()->hasParallelNative();
     }
 
     bool isBuiltinFunctionConstructor();
diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp
index c267a2764c3f30c602b7bf239f015833764354f9..f844c6b0d9121dc7a2c3366ae4989b18c9c1653d 100644
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -4840,8 +4840,7 @@ static const JSJitInfo dom_x_getterinfo = {
     false,    /* isInSlot */
     0,        /* slotIndex */
     JSJitInfo::AliasNone, /* aliasSet */
-    nullptr,  /* argTypes */
-    nullptr   /* parallelNative */
+    nullptr   /* argTypes */
 };
 
 static const JSJitInfo dom_x_setterinfo = {
@@ -4855,8 +4854,7 @@ static const JSJitInfo dom_x_setterinfo = {
     false,    /* isInSlot */
     0,        /* slotIndex */
     JSJitInfo::AliasEverything, /* aliasSet */
-    nullptr,  /* argTypes */
-    nullptr   /* parallelNative */
+    nullptr   /* argTypes */
 };
 
 static const JSJitInfo doFoo_methodinfo = {
@@ -4870,8 +4868,7 @@ static const JSJitInfo doFoo_methodinfo = {
     false,    /* isInSlot */
     0,        /* slotIndex */
     JSJitInfo::AliasEverything, /* aliasSet */
-    nullptr,  /* argTypes */
-    nullptr   /* parallelNative */
+    nullptr   /* argTypes */
 };
 
 static const JSPropertySpec dom_props[] = {
diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp
index f9676bc54c6d963d8cb528c2b700993669780772..828b4894b933ed7ce80045ec0757b0aa5cfd4413 100644
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -266,8 +266,7 @@ intrinsic_Dump(ThreadSafeContext *cx, unsigned argc, Value *vp)
     return true;
 }
 
-const JSJitInfo intrinsic_Dump_jitInfo =
-    JS_JITINFO_NATIVE_PARALLEL(JSParallelNativeThreadSafeWrapper<intrinsic_Dump>);
+JS_JITINFO_NATIVE_PARALLEL(intrinsic_Dump_jitInfo, intrinsic_Dump_jitInfo, intrinsic_Dump);
 
 bool
 intrinsic_ParallelSpew(ThreadSafeContext *cx, unsigned argc, Value *vp)
@@ -287,8 +286,7 @@ intrinsic_ParallelSpew(ThreadSafeContext *cx, unsigned argc, Value *vp)
     return true;
 }
 
-const JSJitInfo intrinsic_ParallelSpew_jitInfo =
-    JS_JITINFO_NATIVE_PARALLEL(JSParallelNativeThreadSafeWrapper<intrinsic_ParallelSpew>);
+JS_JITINFO_NATIVE_PARALLEL(intrinsic_ParallelSpew_jitInfo, intrinsic_ParallelSpew_jitInfo, intrinsic_ParallelSpew);
 #endif
 
 /*