Bug 1529957 - Baldr: allow wasm functions to have func indices (r=bbouvier)
authorLuke Wagner <luke@mozilla.com>
Tue, 26 Mar 2019 18:47:14 -0500
changeset 466809 8fc0d70bdba10bc969603f5bcbbc3b4e86bb190b
parent 466651 b1374f2163b67338d0d0540b51010899452bde96
child 466810 5de97868cb80ae505bf52312dc47590e221d64bb
push id35781
push useropoprus@mozilla.com
push dateFri, 29 Mar 2019 21:56:26 +0000
treeherdermozilla-central@4526b65c502e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbouvier
bugs1529957
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 1529957 - Baldr: allow wasm functions to have func indices (r=bbouvier) Differential Revision: https://phabricator.services.mozilla.com/D25007
js/src/jit/CacheIR.cpp
js/src/jit/IonBuilder.cpp
js/src/jit/MCallOptimize.cpp
js/src/jit/MacroAssembler-inl.h
js/src/vm/JSFunction.cpp
js/src/vm/JSFunction.h
js/src/wasm/WasmCode.cpp
js/src/wasm/WasmJS.cpp
--- a/js/src/jit/CacheIR.cpp
+++ b/js/src/jit/CacheIR.cpp
@@ -432,17 +432,17 @@ static bool IsCacheableGetPropCallNative
     return false;
   }
 
   if (!shape->getterValue().toObject().is<JSFunction>()) {
     return false;
   }
 
   JSFunction& getter = shape->getterValue().toObject().as<JSFunction>();
-  if (!getter.isNativeWithCppEntry()) {
+  if (!getter.isBuiltinNative()) {
     return false;
   }
 
   if (getter.isClassConstructor()) {
     return false;
   }
 
   // Check for a getter that has jitinfo and whose jitinfo says it's
@@ -473,17 +473,17 @@ static bool IsCacheableGetPropCallScript
   }
 
   // See IsCacheableGetPropCallNative.
   if (IsWindow(obj)) {
     return false;
   }
 
   JSFunction& getter = shape->getterValue().toObject().as<JSFunction>();
-  if (getter.isNativeWithCppEntry()) {
+  if (getter.isBuiltinNative()) {
     return false;
   }
 
   // Natives with jit entry can use the scripted path.
   if (getter.isNativeWithJitEntry()) {
     return true;
   }
 
@@ -993,17 +993,17 @@ static void EmitReadSlotReturn(CacheIRWr
   }
 }
 
 static void EmitCallGetterResultNoGuards(CacheIRWriter& writer, JSObject* obj,
                                          JSObject* holder, Shape* shape,
                                          ObjOperandId receiverId) {
   if (IsCacheableGetPropCallNative(obj, holder, shape)) {
     JSFunction* target = &shape->getterValue().toObject().as<JSFunction>();
-    MOZ_ASSERT(target->isNativeWithCppEntry());
+    MOZ_ASSERT(target->isBuiltinNative());
     writer.callNativeGetterResult(receiverId, target);
     writer.typeMonitorResult();
     return;
   }
 
   MOZ_ASSERT(IsCacheableGetPropCallScripted(obj, holder, shape));
 
   JSFunction* target = &shape->getterValue().toObject().as<JSFunction>();
@@ -3523,17 +3523,17 @@ static bool IsCacheableSetPropCallNative
     return false;
   }
 
   if (!shape->setterObject() || !shape->setterObject()->is<JSFunction>()) {
     return false;
   }
 
   JSFunction& setter = shape->setterObject()->as<JSFunction>();
-  if (!setter.isNativeWithCppEntry()) {
+  if (!setter.isBuiltinNative()) {
     return false;
   }
 
   if (setter.isClassConstructor()) {
     return false;
   }
 
   if (setter.hasJitInfo() && !setter.jitInfo()->needsOuterizedThisObject()) {
@@ -3558,17 +3558,17 @@ static bool IsCacheableSetPropCallScript
     return false;
   }
 
   if (!shape->setterObject() || !shape->setterObject()->is<JSFunction>()) {
     return false;
   }
 
   JSFunction& setter = shape->setterObject()->as<JSFunction>();
-  if (setter.isNativeWithCppEntry()) {
+  if (setter.isBuiltinNative()) {
     return false;
   }
 
   // Natives with jit entry can use the scripted path.
   if (setter.isNativeWithJitEntry()) {
     return true;
   }
 
@@ -3612,17 +3612,17 @@ static bool CanAttachSetter(JSContext* c
   return true;
 }
 
 static void EmitCallSetterNoGuards(CacheIRWriter& writer, JSObject* obj,
                                    JSObject* holder, Shape* shape,
                                    ObjOperandId objId, ValOperandId rhsId) {
   if (IsCacheableSetPropCallNative(obj, holder, shape)) {
     JSFunction* target = &shape->setterValue().toObject().as<JSFunction>();
-    MOZ_ASSERT(target->isNativeWithCppEntry());
+    MOZ_ASSERT(target->isBuiltinNative());
     writer.callNativeSetter(objId, target, rhsId);
     writer.returnFromIC();
     return;
   }
 
   MOZ_ASSERT(IsCacheableSetPropCallScripted(obj, holder, shape));
 
   JSFunction* target = &shape->setterValue().toObject().as<JSFunction>();
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -5423,22 +5423,19 @@ MDefinition* IonBuilder::createThis(JSFu
   }
 
   // Native constructors build the new Object themselves.
   if (target->isNative()) {
     if (!target->isConstructor()) {
       return nullptr;
     }
 
-    if (target->isNativeWithJitEntry()) {
-      // Do not bother inlining constructor calls to asm.js, since it is
-      // not used much in practice.
-      MOZ_ASSERT(target->isWasmOptimized());
-      return nullptr;
-    }
+    // Only asm.js natives can be constructors and asm.js natives don't have
+    // jit entries.
+    MOZ_ASSERT(!target->isNativeWithJitEntry());
 
     MConstant* magic = MConstant::New(alloc(), MagicValue(JS_IS_CONSTRUCTING));
     current->add(magic);
     return magic;
   }
 
   if (target->isBoundFunction()) {
     return constant(MagicValue(JS_UNINITIALIZED_LEXICAL));
@@ -6099,17 +6096,17 @@ AbortReasonOr<MCall*> IonBuilder::makeCa
   if (targets && targets->length() == 1) {
     target = targets.ref()[0];
   }
 
   uint32_t targetArgs = callInfo.argc();
 
   // Collect number of missing arguments provided that the target is
   // scripted. Native functions are passed an explicit 'argc' parameter.
-  if (target && !target->isNativeWithCppEntry()) {
+  if (target && !target->isBuiltinNative()) {
     targetArgs = Max<uint32_t>(target->nargs(), callInfo.argc());
   }
 
   bool isDOMCall = false;
   DOMObjectKind objKind = DOMObjectKind::Unknown;
   if (target && !callInfo.constructing()) {
     // We know we have a single call target.  Check whether the "this" types
     // are DOM types and our function a DOM function, and if so flag the
@@ -6132,17 +6129,17 @@ AbortReasonOr<MCall*> IonBuilder::makeCa
 
   if (callInfo.constructing()) {
     call->addArg(targetArgs + 1, callInfo.getNewTarget());
   }
 
   // Explicitly pad any missing arguments with |undefined|.
   // This permits skipping the argumentsRectifier.
   MOZ_ASSERT_IF(target && targetArgs > callInfo.argc(),
-                !target->isNativeWithCppEntry());
+                !target->isBuiltinNative());
   for (int i = targetArgs; i > (int)callInfo.argc(); i--) {
     MConstant* undef = constant(UndefinedValue());
     if (!alloc().ensureBallast()) {
       return abort(AbortReason::Alloc);
     }
     call->addArg(i, undef);
   }
 
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -218,17 +218,17 @@ IonBuilder::InliningResult IonBuilder::i
                                                         JSFunction* target) {
   MOZ_ASSERT(target->isNative());
 
   if (!optimizationInfo().inlineNative()) {
     trackOptimizationOutcome(TrackedOutcome::CantInlineDisabledIon);
     return InliningStatus_NotInlined;
   }
 
-  bool isWasmCall = target->isWasmOptimized();
+  bool isWasmCall = target->isWasmWithJitEntry();
   if (!isWasmCall &&
       (!target->hasJitInfo() ||
        target->jitInfo()->type() != JSJitInfo::InlinableNative)) {
     // Reaching here means we tried to inline a native for which there is no
     // Ion specialization.
     trackOptimizationOutcome(TrackedOutcome::CantInlineNativeNoSpecialization);
     return InliningStatus_NotInlined;
   }
@@ -4317,17 +4317,17 @@ IonBuilder::InliningResult IonBuilder::i
   current->add(ins);
   current->push(ins);
 
   return InliningStatus_Inlined;
 }
 
 IonBuilder::InliningResult IonBuilder::inlineWasmCall(CallInfo& callInfo,
                                                       JSFunction* target) {
-  MOZ_ASSERT(target->isWasmOptimized());
+  MOZ_ASSERT(target->isWasmWithJitEntry());
 
   // Don't inline wasm constructors.
   if (callInfo.constructing()) {
     trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
     return InliningStatus_NotInlined;
   }
 
   if (target->realm() != script()->realm()) {
--- a/js/src/jit/MacroAssembler-inl.h
+++ b/js/src/jit/MacroAssembler-inl.h
@@ -358,17 +358,17 @@ void MacroAssembler::branchIfFunctionHas
   static_assert(JSFunction::offsetOfNargs() % sizeof(uint32_t) == 0,
                 "The code in this function and the ones below must change");
   static_assert(JSFunction::offsetOfFlags() == JSFunction::offsetOfNargs() + 2,
                 "The code in this function and the ones below must change");
 
   Address address(fun, JSFunction::offsetOfNargs());
   int32_t bit = JSFunction::INTERPRETED;
   if (!isConstructing) {
-    bit |= JSFunction::WASM_OPTIMIZED;
+    bit |= JSFunction::WASM_JIT_ENTRY;
   }
   bit = IMM32_16ADJ(bit);
   branchTest32(Assembler::Zero, address, Imm32(bit), label);
 }
 
 void MacroAssembler::branchIfInterpreted(Register fun, Label* label) {
   // 16-bit loads are slow and unaligned 32-bit loads may be too so
   // perform an aligned 32-bit load and adjust the bitmask accordingly.
--- a/js/src/vm/JSFunction.cpp
+++ b/js/src/vm/JSFunction.cpp
@@ -2105,21 +2105,17 @@ JSFunction* js::NewFunctionWithProto(
       fun->initLazyScript(nullptr);
     } else {
       fun->initScript(nullptr);
     }
     fun->initEnvironment(enclosingEnv);
   } else {
     MOZ_ASSERT(fun->isNative());
     MOZ_ASSERT(native);
-    if (fun->isWasmOptimized()) {
-      fun->initWasmNative(native);
-    } else {
-      fun->initNative(native, nullptr);
-    }
+    fun->initNative(native, nullptr);
   }
   if (allocKind == gc::AllocKind::FUNCTION_EXTENDED) {
     fun->initializeExtended();
   }
   fun->initAtom(atom);
 
   return fun;
 }
--- a/js/src/vm/JSFunction.h
+++ b/js/src/vm/JSFunction.h
@@ -39,25 +39,26 @@ class JSFunction : public js::NativeObje
   enum FunctionKind {
     NormalFunction = 0,
     Arrow,  /* ES6 '(args) => body' syntax */
     Method, /* ES6 MethodDefinition */
     ClassConstructor,
     Getter,
     Setter,
     AsmJS, /* function is an asm.js module or exported function */
+    Wasm,  /* function is an exported WebAssembly function */
     FunctionKindLimit
   };
 
   enum Flags {
     INTERPRETED = 0x0001, /* function has a JSScript and environment. */
     CONSTRUCTOR = 0x0002, /* function that can be called as a constructor */
     EXTENDED = 0x0004,    /* structure is FunctionExtended */
     BOUND_FUN = 0x0008, /* function was created with Function.prototype.bind. */
-    WASM_OPTIMIZED = 0x0010,   /* asm.js/wasm function that has a jit entry */
+    WASM_JIT_ENTRY = 0x0010,   /* the wasm function has a jit entry */
     HAS_GUESSED_ATOM = 0x0020, /* function had no explicit name, but a
                                   name was guessed for it anyway. See
                                   atom_ for more info about this flag. */
     HAS_BOUND_FUNCTION_NAME_PREFIX =
         0x0020,      /* bound functions reuse the HAS_GUESSED_ATOM
                         flag to track if atom_ already contains the
                         "bound " function name prefix */
     LAMBDA = 0x0040, /* function comes from a FunctionExpression, ArrowFunction,
@@ -80,30 +81,30 @@ class JSFunction : public js::NativeObje
     NEW_SCRIPT_CLEARED =
         0x1000, /* For a function used as an interpreted constructor, whether
                    a 'new' type had constructor information cleared. */
 
     FUNCTION_KIND_SHIFT = 13,
     FUNCTION_KIND_MASK = 0x7 << FUNCTION_KIND_SHIFT,
 
     ASMJS_KIND = AsmJS << FUNCTION_KIND_SHIFT,
+    WASM_KIND = Wasm << FUNCTION_KIND_SHIFT,
     ARROW_KIND = Arrow << FUNCTION_KIND_SHIFT,
     METHOD_KIND = Method << FUNCTION_KIND_SHIFT,
     CLASSCONSTRUCTOR_KIND = ClassConstructor << FUNCTION_KIND_SHIFT,
     GETTER_KIND = Getter << FUNCTION_KIND_SHIFT,
     SETTER_KIND = Setter << FUNCTION_KIND_SHIFT,
 
     /* Derived Flags values for convenience: */
     NATIVE_FUN = 0,
     NATIVE_CTOR = NATIVE_FUN | CONSTRUCTOR,
     NATIVE_CLASS_CTOR = NATIVE_FUN | CONSTRUCTOR | CLASSCONSTRUCTOR_KIND,
     ASMJS_CTOR = ASMJS_KIND | NATIVE_CTOR,
     ASMJS_LAMBDA_CTOR = ASMJS_KIND | NATIVE_CTOR | LAMBDA,
-    ASMJS_NATIVE = ASMJS_KIND | NATIVE_FUN,
-    WASM_FUN = NATIVE_FUN | WASM_OPTIMIZED,
+    WASM = WASM_KIND | NATIVE_FUN,
     INTERPRETED_METHOD = INTERPRETED | METHOD_KIND,
     INTERPRETED_CLASS_CONSTRUCTOR =
         INTERPRETED | CLASSCONSTRUCTOR_KIND | CONSTRUCTOR,
     INTERPRETED_GETTER = INTERPRETED | GETTER_KIND,
     INTERPRETED_SETTER = INTERPRETED | SETTER_KIND,
     INTERPRETED_LAMBDA = INTERPRETED | LAMBDA | CONSTRUCTOR,
     INTERPRETED_LAMBDA_ARROW = INTERPRETED | LAMBDA | ARROW_KIND,
     INTERPRETED_LAMBDA_GENERATOR_OR_ASYNC = INTERPRETED | LAMBDA,
@@ -136,19 +137,19 @@ class JSFunction : public js::NativeObje
   union U {
     class {
       friend class JSFunction;
       js::Native func_; /* native method pointer or null */
       union {
         // Information about this function to be used by the JIT, only
         // used if isBuiltinNative(); use the accessor!
         const JSJitInfo* jitInfo_;
-        // asm.js function index, only used if isAsmJSNative().
-        size_t asmJSFuncIndex_;
-        // for wasm, a pointer to a fast jit->wasm table entry.
+        // for wasm/asm.js without a jit entry
+        size_t wasmFuncIndex_;
+        // for wasm that has been given a jit entry
         void** wasmJitEntry_;
       } extra;
     } native;
     struct {
       JSObject* env_; /* environment for new activations */
       union {
         JSScript* script_;     /* interpreted bytecode descriptor or
                                   null; use the accessor! */
@@ -243,26 +244,35 @@ class JSFunction : public js::NativeObje
   bool isInterpreted() const {
     return flags() & (INTERPRETED | INTERPRETED_LAZY);
   }
   bool isNative() const { return !isInterpreted(); }
 
   bool isConstructor() const { return flags() & CONSTRUCTOR; }
 
   /* Possible attributes of a native function: */
-  bool isAsmJSNative() const { return kind() == AsmJS; }
-  bool isWasmOptimized() const { return (flags() & WASM_OPTIMIZED); }
-  bool isBuiltinNative() const {
-    return isNativeWithCppEntry() && !isAsmJSNative();
+  bool isAsmJSNative() const {
+    MOZ_ASSERT_IF(kind() == AsmJS, isNative());
+    return kind() == AsmJS;
+  }
+  bool isWasm() const {
+    MOZ_ASSERT_IF(kind() == Wasm, isNative());
+    return kind() == Wasm;
   }
-
-  // May be called from the JIT with the wasmJitEntry_ field.
-  bool isNativeWithJitEntry() const { return isNative() && isWasmOptimized(); }
-  // Must be called from the JIT with the native_ field.
-  bool isNativeWithCppEntry() const { return isNative() && !isWasmOptimized(); }
+  bool isWasmWithJitEntry() const {
+    MOZ_ASSERT_IF(flags() & WASM_JIT_ENTRY, isWasm());
+    return flags() & WASM_JIT_ENTRY;
+  }
+  bool isNativeWithJitEntry() const {
+    MOZ_ASSERT_IF(isWasmWithJitEntry(), isNative());
+    return isWasmWithJitEntry();
+  }
+  bool isBuiltinNative() const {
+    return isNative() && !isAsmJSNative() && !isWasm();
+  }
 
   /* Possible attributes of an interpreted function: */
   bool isBoundFunction() const { return flags() & BOUND_FUN; }
   bool hasInferredName() const { return flags() & HAS_INFERRED_NAME; }
   bool hasGuessedAtom() const {
     static_assert(HAS_GUESSED_ATOM == HAS_BOUND_FUNCTION_NAME_PREFIX,
                   "HAS_GUESSED_ATOM is unused for bound functions");
     return (flags() & (HAS_GUESSED_ATOM | BOUND_FUN)) == HAS_GUESSED_ATOM;
@@ -316,19 +326,17 @@ class JSFunction : public js::NativeObje
     }
 
     return nonLazyScript()->hasBaselineScript() ||
            nonLazyScript()->hasIonScript();
   }
   bool hasJitEntry() const { return hasScript() || isNativeWithJitEntry(); }
 
   /* Compound attributes: */
-  bool isBuiltin() const {
-    return isBuiltinNative() || isNativeWithJitEntry() || isSelfHostedBuiltin();
-  }
+  bool isBuiltin() const { return isBuiltinNative() || isSelfHostedBuiltin(); }
 
   bool isNamedLambda() const {
     return isLambda() && displayAtom() && !hasInferredName() &&
            !hasGuessedAtom();
   }
 
   bool hasLexicalThis() const { return isArrow(); }
 
@@ -684,17 +692,17 @@ class JSFunction : public js::NativeObje
   JSNative native() const {
     MOZ_ASSERT(isNative());
     return u.native.func_;
   }
 
   JSNative maybeNative() const { return isInterpreted() ? nullptr : native(); }
 
   void initNative(js::Native native, const JSJitInfo* jitInfo) {
-    MOZ_ASSERT(isNativeWithCppEntry());
+    MOZ_ASSERT(isNative());
     MOZ_ASSERT_IF(jitInfo, isBuiltinNative());
     MOZ_ASSERT(native);
     u.native.func_ = native;
     u.native.extra.jitInfo_ = jitInfo;
   }
   bool hasJitInfo() const {
     return isBuiltinNative() && u.native.extra.jitInfo_;
   }
@@ -702,49 +710,47 @@ class JSFunction : public js::NativeObje
     MOZ_ASSERT(hasJitInfo());
     return u.native.extra.jitInfo_;
   }
   void setJitInfo(const JSJitInfo* data) {
     MOZ_ASSERT(isBuiltinNative());
     u.native.extra.jitInfo_ = data;
   }
 
-  // Wasm natives are optimized and have a jit entry.
-  void initWasmNative(js::Native native) {
-    MOZ_ASSERT(isNativeWithJitEntry());
-    MOZ_ASSERT(native);
-    u.native.func_ = native;
-    u.native.extra.wasmJitEntry_ = nullptr;
+  // wasm functions are always natives and either:
+  //  - store a function-index in u.n.extra and can only be called through the
+  //    fun->native() entry point from C++.
+  //  - store a jit-entry code pointer in u.n.extra and can be called by jit
+  //    code directly. C++ callers can still use the fun->native() entry point
+  //    (computing the function index from the jit-entry point).
+  void setWasmFuncIndex(uint32_t funcIndex) {
+    MOZ_ASSERT(isWasm() || isAsmJSNative());
+    MOZ_ASSERT(!isWasmWithJitEntry());
+    MOZ_ASSERT(!u.native.extra.wasmFuncIndex_);
+    u.native.extra.wasmFuncIndex_ = funcIndex;
+  }
+  uint32_t wasmFuncIndex() const {
+    MOZ_ASSERT(isWasm() || isAsmJSNative());
+    MOZ_ASSERT(!isWasmWithJitEntry());
+    return u.native.extra.wasmFuncIndex_;
   }
   void setWasmJitEntry(void** entry) {
-    MOZ_ASSERT(isNativeWithJitEntry());
     MOZ_ASSERT(entry);
-    MOZ_ASSERT(!u.native.extra.wasmJitEntry_);
+    MOZ_ASSERT(isWasm());
+    MOZ_ASSERT(!isWasmWithJitEntry());
+    flags_ |= WASM_JIT_ENTRY;
     u.native.extra.wasmJitEntry_ = entry;
+    MOZ_ASSERT(isWasmWithJitEntry());
   }
   void** wasmJitEntry() const {
-    MOZ_ASSERT(isNativeWithJitEntry());
+    MOZ_ASSERT(isWasmWithJitEntry());
     MOZ_ASSERT(u.native.extra.wasmJitEntry_);
     return u.native.extra.wasmJitEntry_;
   }
 
-  // AsmJS functions store the func index in the jitinfo slot, since these
-  // don't have a jit info associated.
-  void setAsmJSIndex(uint32_t funcIndex) {
-    MOZ_ASSERT(isAsmJSNative());
-    MOZ_ASSERT(!isWasmOptimized());
-    MOZ_ASSERT(!u.native.extra.asmJSFuncIndex_);
-    u.native.extra.asmJSFuncIndex_ = funcIndex;
-  }
-  uint32_t asmJSFuncIndex() const {
-    MOZ_ASSERT(isAsmJSNative());
-    MOZ_ASSERT(!isWasmOptimized());
-    return u.native.extra.asmJSFuncIndex_;
-  }
-
   bool isDerivedClassConstructor();
 
   static unsigned offsetOfNative() {
     return offsetof(JSFunction, u.native.func_);
   }
   static unsigned offsetOfScript() {
     static_assert(offsetof(U, scripted.s.script_) ==
                       offsetof(U, native.extra.wasmJitEntry_),
--- a/js/src/wasm/WasmCode.cpp
+++ b/js/src/wasm/WasmCode.cpp
@@ -1156,18 +1156,19 @@ bool Code::setTier2(UniqueCodeTier tier2
 void Code::commitTier2() const {
   MOZ_RELEASE_ASSERT(!hasTier2());
   MOZ_RELEASE_ASSERT(tier2_.get());
   hasTier2_ = true;
   MOZ_ASSERT(hasTier2());
 }
 
 uint32_t Code::getFuncIndex(JSFunction* fun) const {
-  if (fun->isAsmJSNative()) {
-    return fun->asmJSFuncIndex();
+  MOZ_ASSERT(fun->isWasm() || fun->isAsmJSNative());
+  if (!fun->isWasmWithJitEntry()) {
+    return fun->wasmFuncIndex();
   }
   return jumpTables_.funcIndexFromJitEntry(fun->wasmJitEntry());
 }
 
 Tiers Code::tiers() const {
   if (hasTier2()) {
     return Tiers(tier1_->tier(), tier2_->tier());
   }
--- a/js/src/wasm/WasmJS.cpp
+++ b/js/src/wasm/WasmJS.cpp
@@ -1489,44 +1489,39 @@ bool WasmInstanceObject::getExportedFunc
       return false;
     }
     fun.set(NewNativeConstructor(cx, WasmCall, numArgs, name,
                                  gc::AllocKind::FUNCTION_EXTENDED,
                                  SingletonObject, JSFunction::ASMJS_CTOR));
     if (!fun) {
       return false;
     }
-    fun->setAsmJSIndex(funcIndex);
+    fun->setWasmFuncIndex(funcIndex);
   } else {
     RootedAtom name(cx, NumberToAtom(cx, funcIndex));
     if (!name) {
       return false;
     }
 
+    // Functions with anyref don't have jit entries yet.
     bool disableJitEntry = funcType.temporarilyUnsupportedAnyRef()
 #ifdef WASM_CODEGEN_DEBUG
                            || !JitOptions.enableWasmJitEntry;
 #endif
     ;
 
-    // Functions with anyref don't have jit entries yet, so they should
-    // mostly behave like asm.js functions. Pretend it's the case, until
-    // jit entries are implemented.
-    JSFunction::Flags flags =
-        disableJitEntry ? JSFunction::ASMJS_NATIVE : JSFunction::WASM_FUN;
-
     fun.set(NewNativeFunction(cx, WasmCall, numArgs, name,
                               gc::AllocKind::FUNCTION_EXTENDED, SingletonObject,
-                              flags));
+                              JSFunction::WASM));
     if (!fun) {
       return false;
     }
 
     if (disableJitEntry) {
-      fun->setAsmJSIndex(funcIndex);
+      fun->setWasmFuncIndex(funcIndex);
     } else {
       fun->setWasmJitEntry(instance.code().getAddressOfJitEntry(funcIndex));
     }
   }
 
   fun->setExtendedSlot(FunctionExtended::WASM_INSTANCE_SLOT,
                        ObjectValue(*instanceObj));