Bug 1461948 - Uncouple ReferenceType from TypedObject's ReferenceTypeDescr. r=till
authorLars T Hansen <lhansen@mozilla.com>
Wed, 16 May 2018 13:44:40 +0200
changeset 423131 1d069afa41fa40ba8c5835dbd83f1218c46b83e7
parent 423130 c8434494445c6b5403c292226498a78b3d428331
child 423132 b58c103b639f29520c952137cd607148e2b01675
push id34164
push usercsabou@mozilla.com
push dateThu, 21 Jun 2018 01:17:13 +0000
treeherdermozilla-central@d231a3231680 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstill
bugs1461948
milestone62.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 1461948 - Uncouple ReferenceType from TypedObject's ReferenceTypeDescr. r=till The coupling created some problems for a later patch where I need to reference ReferenceTypeDescr::Type in GlobalObject.h, but can't, because this creates a circular include path. As for SIMD and Scalar, there's no reason to embed the type all the way inside the TypedObject machinery, we can just have it as its own thing.
js/src/builtin/TypedObject.cpp
js/src/builtin/TypedObject.h
js/src/jit/BaselineCacheIRCompiler.cpp
js/src/jit/BaselineIC.cpp
js/src/jit/CacheIR.cpp
js/src/jit/CacheIR.h
js/src/jit/CacheIRCompiler.cpp
js/src/jit/CacheIRCompiler.h
js/src/jit/IonBuilder.cpp
js/src/jit/IonBuilder.h
js/src/jit/IonCacheIRCompiler.cpp
js/src/jit/SharedIC.h
js/src/jit/TypedObjectPrediction.cpp
js/src/jit/TypedObjectPrediction.h
--- a/js/src/builtin/TypedObject.cpp
+++ b/js/src/builtin/TypedObject.cpp
@@ -334,23 +334,23 @@ static const uint32_t ReferenceSizes[] =
     sizeof(_type),
     JS_FOR_EACH_REFERENCE_TYPE_REPR(REFERENCE_SIZE) 0
 #undef REFERENCE_SIZE
 };
 
 uint32_t
 ReferenceTypeDescr::size(Type t)
 {
-    return ReferenceSizes[t];
+    return ReferenceSizes[uint32_t(t)];
 }
 
 uint32_t
 ReferenceTypeDescr::alignment(Type t)
 {
-    return ReferenceSizes[t];
+    return ReferenceSizes[uint32_t(t)];
 }
 
 /*static*/ const char*
 ReferenceTypeDescr::typeName(Type type)
 {
     switch (type) {
 #define NUMERIC_TYPE_TO_STRING(constant_, type_, name_) \
         case constant_: return #name_;
@@ -370,30 +370,30 @@ js::ReferenceTypeDescr::call(JSContext* 
 
     if (args.length() < 1) {
         JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
                                   descr->typeName(), "0", "s");
         return false;
     }
 
     switch (descr->type()) {
-      case ReferenceTypeDescr::TYPE_ANY:
+      case ReferenceType::TYPE_ANY:
         args.rval().set(args[0]);
         return true;
 
-      case ReferenceTypeDescr::TYPE_OBJECT:
+      case ReferenceType::TYPE_OBJECT:
       {
         RootedObject obj(cx, ToObject(cx, args[0]));
         if (!obj)
             return false;
         args.rval().setObject(*obj);
         return true;
       }
 
-      case ReferenceTypeDescr::TYPE_STRING:
+      case ReferenceType::TYPE_STRING:
       {
         RootedString obj(cx, ToString<CanGC>(cx, args[0]));
         if (!obj)
             return false;
         args.rval().setString(&*obj);
         return true;
       }
     }
@@ -787,17 +787,17 @@ StructMetaTypeDescr::Layout::addField(in
 
 CheckedInt32
 StructMetaTypeDescr::Layout::addScalar(Scalar::Type type) {
     return addField(ScalarTypeDescr::alignment(type),
                     ScalarTypeDescr::size(type));
 }
 
 CheckedInt32
-StructMetaTypeDescr::Layout::addReference(ReferenceTypeDescr::Type type) {
+StructMetaTypeDescr::Layout::addReference(ReferenceType type) {
     return addField(ReferenceTypeDescr::alignment(type),
                     ReferenceTypeDescr::size(type));
 }
 
 CheckedInt32
 StructMetaTypeDescr::Layout::close(int32_t *alignment) {
     if (alignment)
         *alignment = structAlignment;
@@ -1171,17 +1171,17 @@ DefineSimpleTypeDescr(JSContext* cx,
     if (!descr)
         return false;
 
     descr->initReservedSlot(JS_DESCR_SLOT_KIND, Int32Value(T::Kind));
     descr->initReservedSlot(JS_DESCR_SLOT_STRING_REPR, StringValue(className));
     descr->initReservedSlot(JS_DESCR_SLOT_ALIGNMENT, Int32Value(T::alignment(type)));
     descr->initReservedSlot(JS_DESCR_SLOT_SIZE, Int32Value(AssertedCast<int32_t>(T::size(type))));
     descr->initReservedSlot(JS_DESCR_SLOT_OPAQUE, BooleanValue(T::Opaque));
-    descr->initReservedSlot(JS_DESCR_SLOT_TYPE, Int32Value(type));
+    descr->initReservedSlot(JS_DESCR_SLOT_TYPE, Int32Value(int32_t(type)));
 
     if (!CreateUserSizeAndAlignmentProperties(cx, descr))
         return false;
 
     if (!JS_DefineFunctions(cx, descr, T::typeObjectMethods))
         return false;
 
     // Create the typed prototype for the scalar type. This winds up
@@ -2784,32 +2784,32 @@ class MemoryInitVisitor {
 };
 
 } // namespace
 
 void
 MemoryInitVisitor::visitReference(ReferenceTypeDescr& descr, uint8_t* mem)
 {
     switch (descr.type()) {
-      case ReferenceTypeDescr::TYPE_ANY:
+      case ReferenceType::TYPE_ANY:
       {
         js::GCPtrValue* heapValue = reinterpret_cast<js::GCPtrValue*>(mem);
         heapValue->init(UndefinedValue());
         return;
       }
 
-      case ReferenceTypeDescr::TYPE_OBJECT:
+      case ReferenceType::TYPE_OBJECT:
       {
         js::GCPtrObject* objectPtr =
             reinterpret_cast<js::GCPtrObject*>(mem);
         objectPtr->init(nullptr);
         return;
       }
 
-      case ReferenceTypeDescr::TYPE_STRING:
+      case ReferenceType::TYPE_STRING:
       {
         js::GCPtrString* stringPtr =
             reinterpret_cast<js::GCPtrString*>(mem);
         stringPtr->init(rt_->emptyString);
         return;
       }
     }
 
@@ -2854,31 +2854,31 @@ class MemoryTracingVisitor {
 };
 
 } // namespace
 
 void
 MemoryTracingVisitor::visitReference(ReferenceTypeDescr& descr, uint8_t* mem)
 {
     switch (descr.type()) {
-      case ReferenceTypeDescr::TYPE_ANY:
+      case ReferenceType::TYPE_ANY:
       {
         GCPtrValue* heapValue = reinterpret_cast<js::GCPtrValue*>(mem);
         TraceEdge(trace_, heapValue, "reference-val");
         return;
       }
 
-      case ReferenceTypeDescr::TYPE_OBJECT:
+      case ReferenceType::TYPE_OBJECT:
       {
         GCPtrObject* objectPtr = reinterpret_cast<js::GCPtrObject*>(mem);
         TraceNullableEdge(trace_, objectPtr, "reference-obj");
         return;
       }
 
-      case ReferenceTypeDescr::TYPE_STRING:
+      case ReferenceType::TYPE_STRING:
       {
         GCPtrString* stringPtr = reinterpret_cast<js::GCPtrString*>(mem);
         TraceNullableEdge(trace_, stringPtr, "reference-str");
         return;
       }
     }
 
     MOZ_CRASH("Invalid kind");
@@ -2908,19 +2908,19 @@ struct TraceListVisitor {
 
 } // namespace
 
 void
 TraceListVisitor::visitReference(ReferenceTypeDescr& descr, uint8_t* mem)
 {
     VectorType* offsets;
     switch (descr.type()) {
-      case ReferenceTypeDescr::TYPE_ANY: offsets = &valueOffsets; break;
-      case ReferenceTypeDescr::TYPE_OBJECT: offsets = &objectOffsets; break;
-      case ReferenceTypeDescr::TYPE_STRING: offsets = &stringOffsets; break;
+      case ReferenceType::TYPE_ANY: offsets = &valueOffsets; break;
+      case ReferenceType::TYPE_OBJECT: offsets = &objectOffsets; break;
+      case ReferenceType::TYPE_STRING: offsets = &stringOffsets; break;
       default: MOZ_CRASH("Invalid kind");
     }
 
     AutoEnterOOMUnsafeRegion oomUnsafe;
     if (!offsets->append((uintptr_t) mem))
         oomUnsafe.crash("TraceListVisitor::visitReference");
 }
 
--- a/js/src/builtin/TypedObject.h
+++ b/js/src/builtin/TypedObject.h
@@ -283,53 +283,55 @@ class ScalarTypeDescr : public SimpleTyp
     macro_(Scalar::Float32, float,    float32)                  \
     macro_(Scalar::Float64, double,   float64)
 
 // Must be in same order as the enum ScalarTypeDescr::Type:
 #define JS_FOR_EACH_SCALAR_TYPE_REPR(macro_)                    \
     JS_FOR_EACH_UNIQUE_SCALAR_TYPE_REPR_CTYPE(macro_)           \
     macro_(Scalar::Uint8Clamped, uint8_t, uint8Clamped)
 
+enum class ReferenceType {
+    TYPE_ANY = JS_REFERENCETYPEREPR_ANY,
+    TYPE_OBJECT = JS_REFERENCETYPEREPR_OBJECT,
+    TYPE_STRING = JS_REFERENCETYPEREPR_STRING
+};
+
 // Type for reference type constructors like `Any`, `String`, and
 // `Object`. All such type constructors share a common js::Class and
 // JSFunctionSpec. All these types are opaque.
 class ReferenceTypeDescr : public SimpleTypeDescr
 {
   public:
     // Must match order of JS_FOR_EACH_REFERENCE_TYPE_REPR below
-    enum Type {
-        TYPE_ANY = JS_REFERENCETYPEREPR_ANY,
-        TYPE_OBJECT = JS_REFERENCETYPEREPR_OBJECT,
-        TYPE_STRING = JS_REFERENCETYPEREPR_STRING,
-    };
-    static const int32_t TYPE_MAX = TYPE_STRING + 1;
+    typedef ReferenceType Type;
     static const char* typeName(Type type);
 
+    static const int32_t TYPE_MAX = int32_t(ReferenceType::TYPE_STRING) + 1;
     static const type::Kind Kind = type::Reference;
     static const bool Opaque = true;
     static const Class class_;
     static uint32_t size(Type t);
     static uint32_t alignment(Type t);
     static const JSFunctionSpec typeObjectMethods[];
 
-    ReferenceTypeDescr::Type type() const {
-        return (ReferenceTypeDescr::Type) getReservedSlot(JS_DESCR_SLOT_TYPE).toInt32();
+    ReferenceType type() const {
+        return (ReferenceType) getReservedSlot(JS_DESCR_SLOT_TYPE).toInt32();
     }
 
     const char* typeName() const {
         return typeName(type());
     }
 
     static MOZ_MUST_USE bool call(JSContext* cx, unsigned argc, Value* vp);
 };
 
 #define JS_FOR_EACH_REFERENCE_TYPE_REPR(macro_) \
-    macro_(ReferenceTypeDescr::TYPE_ANY, GCPtrValue, Any) \
-    macro_(ReferenceTypeDescr::TYPE_OBJECT, GCPtrObject, Object) \
-    macro_(ReferenceTypeDescr::TYPE_STRING, GCPtrString, string)
+    macro_(ReferenceType::TYPE_ANY, GCPtrValue, Any) \
+    macro_(ReferenceType::TYPE_OBJECT, GCPtrObject, Object) \
+    macro_(ReferenceType::TYPE_STRING, GCPtrString, string)
 
 // Type descriptors whose instances are objects and hence which have
 // an associated `prototype` property.
 class ComplexTypeDescr : public TypeDescr
 {
   public:
     // Returns the prototype that instances of this type descriptor
     // will have.
@@ -468,17 +470,17 @@ class StructMetaTypeDescr : public Nativ
         mozilla::CheckedInt32 sizeSoFar = 0;
         int32_t structAlignment = 1;
 
         mozilla::CheckedInt32 addField(int32_t fieldAlignment, int32_t fieldSize);
 
       public:
         // The field adders return the offset of the the field.
         mozilla::CheckedInt32 addScalar(Scalar::Type type);
-        mozilla::CheckedInt32 addReference(ReferenceTypeDescr::Type type);
+        mozilla::CheckedInt32 addReference(ReferenceType type);
 
         // The close method rounds up the structure size to the appropriate
         // alignment and returns that size.  If `alignment` is not NULL then
         // return the structure alignment through that pointer.
         mozilla::CheckedInt32 close(int32_t* alignment = nullptr);
     };
 };
 
--- a/js/src/jit/BaselineCacheIRCompiler.cpp
+++ b/js/src/jit/BaselineCacheIRCompiler.cpp
@@ -1238,28 +1238,28 @@ BaselineCacheIRCompiler::emitStoreUnboxe
 }
 
 bool
 BaselineCacheIRCompiler::emitStoreTypedObjectReferenceProperty()
 {
     ObjOperandId objId = reader.objOperandId();
     Address offsetAddr = stubAddress(reader.stubOffset());
     TypedThingLayout layout = reader.typedThingLayout();
-    ReferenceTypeDescr::Type type = reader.referenceTypeDescrType();
+    ReferenceType type = reader.referenceTypeDescrType();
 
     // Allocate the fixed registers first. These need to be fixed for
     // callTypeUpdateIC.
     AutoScratchRegister scratch1(allocator, masm, R1.scratchReg());
     ValueOperand val = allocator.useFixedValueRegister(masm, reader.valOperandId(), R0);
 
     Register obj = allocator.useRegister(masm, objId);
     AutoScratchRegister scratch2(allocator, masm);
 
     // We don't need a type update IC if the property is always a string.
-    if (type != ReferenceTypeDescr::TYPE_STRING) {
+    if (type != ReferenceType::TYPE_STRING) {
         LiveGeneralRegisterSet saveRegs;
         saveRegs.add(obj);
         saveRegs.add(val);
         if (!callTypeUpdateIC(obj, val, scratch1, saveRegs))
             return false;
     }
 
     // Compute the address being written to.
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -301,24 +301,24 @@ DoTypeUpdateFallback(JSContext* cx, Base
     // we want to include it in this property's type information.
     bool addType = true;
     if (MOZ_UNLIKELY(obj->is<TypedObject>()) && value.isNullOrUndefined()) {
         StructTypeDescr* structDescr = &obj->as<TypedObject>().typeDescr().as<StructTypeDescr>();
         size_t fieldIndex;
         MOZ_ALWAYS_TRUE(structDescr->fieldIndex(id, &fieldIndex));
 
         TypeDescr* fieldDescr = &structDescr->fieldDescr(fieldIndex);
-        ReferenceTypeDescr::Type type = fieldDescr->as<ReferenceTypeDescr>().type();
-        if (type == ReferenceTypeDescr::TYPE_ANY) {
+        ReferenceType type = fieldDescr->as<ReferenceTypeDescr>().type();
+        if (type == ReferenceType::TYPE_ANY) {
             // Ignore undefined values, which are included implicitly in type
             // information for this property.
             if (value.isUndefined())
                 addType = false;
         } else {
-            MOZ_ASSERT(type == ReferenceTypeDescr::TYPE_OBJECT);
+            MOZ_ASSERT(type == ReferenceType::TYPE_OBJECT);
 
             // Ignore null values being written here. Null is included
             // implicitly in type information for this property. Note that
             // non-object, non-null values are not possible here, these
             // should have been filtered out by the IR emitter.
             if (value.isNull())
                 addType = false;
         }
--- a/js/src/jit/CacheIR.cpp
+++ b/js/src/jit/CacheIR.cpp
@@ -1636,18 +1636,18 @@ GetPropIRGenerator::tryAttachTypedObject
     writer.loadTypedObjectResult(objId, fieldOffset, layout, typeDescr);
 
     // Only monitor the result if the type produced by this stub might vary.
     bool monitorLoad = false;
     if (SimpleTypeDescrKeyIsScalar(typeDescr)) {
         Scalar::Type type = ScalarTypeFromSimpleTypeDescrKey(typeDescr);
         monitorLoad = type == Scalar::Uint32;
     } else {
-        ReferenceTypeDescr::Type type = ReferenceTypeFromSimpleTypeDescrKey(typeDescr);
-        monitorLoad = type != ReferenceTypeDescr::TYPE_STRING;
+        ReferenceType type = ReferenceTypeFromSimpleTypeDescrKey(typeDescr);
+        monitorLoad = type != ReferenceType::TYPE_STRING;
     }
 
     if (monitorLoad)
         writer.typeMonitorResult();
     else
         writer.returnFromIC();
 
     trackAttached("TypedObject");
@@ -3332,24 +3332,24 @@ SetPropIRGenerator::tryAttachTypedObject
         writer.returnFromIC();
 
         trackAttached("TypedObject");
         return true;
     }
 
     // For reference types, guard on the RHS type first, so that
     // StoreTypedObjectReferenceProperty is infallible.
-    ReferenceTypeDescr::Type type = fieldDescr->as<ReferenceTypeDescr>().type();
+    ReferenceType type = fieldDescr->as<ReferenceTypeDescr>().type();
     switch (type) {
-      case ReferenceTypeDescr::TYPE_ANY:
+      case ReferenceType::TYPE_ANY:
         break;
-      case ReferenceTypeDescr::TYPE_OBJECT:
+      case ReferenceType::TYPE_OBJECT:
         writer.guardIsObjectOrNull(rhsId);
         break;
-      case ReferenceTypeDescr::TYPE_STRING:
+      case ReferenceType::TYPE_STRING:
         writer.guardType(rhsId, JSVAL_TYPE_STRING);
         break;
     }
 
     writer.storeTypedObjectReferenceProperty(objId, fieldOffset, layout, type, rhsId);
     writer.returnFromIC();
 
     trackAttached("TypedObject");
--- a/js/src/jit/CacheIR.h
+++ b/js/src/jit/CacheIR.h
@@ -868,17 +868,17 @@ class MOZ_RAII CacheIRWriter : public JS
         writeOperandId(rhs);
         buffer_.writeByte(changeGroup);
         addStubField(uintptr_t(newGroup), StubField::Type::ObjectGroup);
         addStubField(uintptr_t(newShape), StubField::Type::Shape);
         addStubField(numNewSlots, StubField::Type::RawWord);
     }
 
     void storeTypedObjectReferenceProperty(ObjOperandId obj, uint32_t offset,
-                                           TypedThingLayout layout, ReferenceTypeDescr::Type type,
+                                           TypedThingLayout layout, ReferenceType type,
                                            ValOperandId rhs)
     {
         writeOpWithOperandId(CacheOp::StoreTypedObjectReferenceProperty, obj);
         addStubField(offset, StubField::Type::RawWord);
         buffer_.writeByte(uint32_t(layout));
         buffer_.writeByte(uint32_t(type));
         writeOperandId(rhs);
     }
@@ -1220,18 +1220,18 @@ class MOZ_RAII CacheIRReader
     Scalar::Type scalarType() { return Scalar::Type(buffer_.readByte()); }
     uint32_t typeDescrKey() { return buffer_.readByte(); }
     JSWhyMagic whyMagic() { return JSWhyMagic(buffer_.readByte()); }
     JSOp jsop() { return JSOp(buffer_.readByte()); }
     int32_t int32Immediate() { return buffer_.readSigned(); }
     uint32_t uint32Immediate() { return buffer_.readUnsigned(); }
     void* pointer() { return buffer_.readRawPointer(); }
 
-    ReferenceTypeDescr::Type referenceTypeDescrType() {
-        return ReferenceTypeDescr::Type(buffer_.readByte());
+    ReferenceType referenceTypeDescrType() {
+        return ReferenceType(buffer_.readByte());
     }
 
     uint8_t readByte() {
         return buffer_.readByte();
     }
     bool readBool() {
         uint8_t b = buffer_.readByte();
         MOZ_ASSERT(b <= 1);
--- a/js/src/jit/CacheIRCompiler.cpp
+++ b/js/src/jit/CacheIRCompiler.cpp
@@ -2427,35 +2427,35 @@ CacheIRCompiler::emitLoadTypedObjectResu
 {
     MOZ_ASSERT(output.hasValue());
 
     if (SimpleTypeDescrKeyIsScalar(typeDescr)) {
         Scalar::Type type = ScalarTypeFromSimpleTypeDescrKey(typeDescr);
         masm.loadFromTypedArray(type, fieldAddr, output.valueReg(),
                                 /* allowDouble = */ true, scratch, nullptr);
     } else {
-        ReferenceTypeDescr::Type type = ReferenceTypeFromSimpleTypeDescrKey(typeDescr);
+        ReferenceType type = ReferenceTypeFromSimpleTypeDescrKey(typeDescr);
         switch (type) {
-          case ReferenceTypeDescr::TYPE_ANY:
+          case ReferenceType::TYPE_ANY:
             masm.loadValue(fieldAddr, output.valueReg());
             break;
 
-          case ReferenceTypeDescr::TYPE_OBJECT: {
+          case ReferenceType::TYPE_OBJECT: {
             Label notNull, done;
             masm.loadPtr(fieldAddr, scratch);
             masm.branchTestPtr(Assembler::NonZero, scratch, scratch, &notNull);
             masm.moveValue(NullValue(), output.valueReg());
             masm.jump(&done);
             masm.bind(&notNull);
             masm.tagValue(JSVAL_TYPE_OBJECT, scratch, output.valueReg());
             masm.bind(&done);
             break;
           }
 
-          case ReferenceTypeDescr::TYPE_STRING:
+          case ReferenceType::TYPE_STRING:
             masm.loadPtr(fieldAddr, scratch);
             masm.tagValue(JSVAL_TYPE_STRING, scratch, output.valueReg());
             break;
 
           default:
             MOZ_CRASH("Invalid ReferenceTypeDescr");
         }
     }
@@ -2661,41 +2661,41 @@ CacheIRCompiler::emitCallPrintString()
 bool
 CacheIRCompiler::emitBreakpoint()
 {
     masm.breakpoint();
     return true;
 }
 
 void
-CacheIRCompiler::emitStoreTypedObjectReferenceProp(ValueOperand val, ReferenceTypeDescr::Type type,
+CacheIRCompiler::emitStoreTypedObjectReferenceProp(ValueOperand val, ReferenceType type,
                                                    const Address& dest, Register scratch)
 {
     // Callers will post-barrier this store.
 
     switch (type) {
-      case ReferenceTypeDescr::TYPE_ANY:
+      case ReferenceType::TYPE_ANY:
         EmitPreBarrier(masm, dest, MIRType::Value);
         masm.storeValue(val, dest);
         break;
 
-      case ReferenceTypeDescr::TYPE_OBJECT: {
+      case ReferenceType::TYPE_OBJECT: {
         EmitPreBarrier(masm, dest, MIRType::Object);
         Label isNull, done;
         masm.branchTestObject(Assembler::NotEqual, val, &isNull);
         masm.unboxObject(val, scratch);
         masm.storePtr(scratch, dest);
         masm.jump(&done);
         masm.bind(&isNull);
         masm.storePtr(ImmWord(0), dest);
         masm.bind(&done);
         break;
       }
 
-      case ReferenceTypeDescr::TYPE_STRING:
+      case ReferenceType::TYPE_STRING:
         EmitPreBarrier(masm, dest, MIRType::String);
         masm.unboxString(val, scratch);
         masm.storePtr(scratch, dest);
         break;
     }
 }
 
 void
--- a/js/src/jit/CacheIRCompiler.h
+++ b/js/src/jit/CacheIRCompiler.h
@@ -651,17 +651,17 @@ class MOZ_RAII CacheIRCompiler
         // zeroing its register is pointless).
         return JitOptions.spectreObjectMitigationsMisc && !allocator.isDeadAfterInstruction(objId);
     }
 
     void emitLoadTypedObjectResultShared(const Address& fieldAddr, Register scratch,
                                          uint32_t typeDescr,
                                          const AutoOutputRegister& output);
 
-    void emitStoreTypedObjectReferenceProp(ValueOperand val, ReferenceTypeDescr::Type type,
+    void emitStoreTypedObjectReferenceProp(ValueOperand val, ReferenceType type,
                                            const Address& dest, Register scratch);
 
     void emitRegisterEnumerator(Register enumeratorsList, Register iter, Register scratch);
 
   private:
     void emitPostBarrierShared(Register obj, const ConstantOrRegister& val, Register scratch,
                                Register maybeIndex);
 
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -7953,17 +7953,17 @@ AbortReasonOr<Ok>
 IonBuilder::getElemTryReferenceElemOfTypedObject(bool* emitted,
                                                  MDefinition* obj,
                                                  MDefinition* index,
                                                  TypedObjectPrediction objPrediction,
                                                  TypedObjectPrediction elemPrediction)
 {
     MOZ_ASSERT(objPrediction.ofArrayKind());
 
-    ReferenceTypeDescr::Type elemType = elemPrediction.referenceType();
+    ReferenceType elemType = elemPrediction.referenceType();
     uint32_t elemSize = ReferenceTypeDescr::size(elemType);
 
     LinearSum indexAsByteOffset(alloc());
     if (!checkTypedObjectIndexInBounds(elemSize, index, objPrediction, &indexAsByteOffset))
         return Ok();
 
     trackOptimizationSuccess();
     *emitted = true;
@@ -8011,57 +8011,57 @@ IonBuilder::pushScalarLoadFromTypedObjec
     load->setResultType(knownType);
 
     return Ok();
 }
 
 AbortReasonOr<Ok>
 IonBuilder::pushReferenceLoadFromTypedObject(MDefinition* typedObj,
                                              const LinearSum& byteOffset,
-                                             ReferenceTypeDescr::Type type,
+                                             ReferenceType type,
                                              PropertyName* name)
 {
     // Find location within the owner object.
     MDefinition* elements;
     MDefinition* scaledOffset;
     int32_t adjustment;
     uint32_t alignment = ReferenceTypeDescr::alignment(type);
     MOZ_TRY(loadTypedObjectElements(typedObj, byteOffset, alignment, &elements, &scaledOffset, &adjustment));
 
     TemporaryTypeSet* observedTypes = bytecodeTypes(pc);
 
     MInstruction* load = nullptr;  // initialize to silence GCC warning
     BarrierKind barrier = PropertyReadNeedsTypeBarrier(analysisContext, alloc(), constraints(),
                                                        typedObj, name, observedTypes);
 
     switch (type) {
-      case ReferenceTypeDescr::TYPE_ANY: {
+      case ReferenceType::TYPE_ANY: {
         // Make sure the barrier reflects the possibility of reading undefined.
         bool bailOnUndefined = barrier == BarrierKind::NoBarrier &&
                                !observedTypes->hasType(TypeSet::UndefinedType());
         if (bailOnUndefined)
             barrier = BarrierKind::TypeTagOnly;
         load = MLoadElement::New(alloc(), elements, scaledOffset, false, false, adjustment);
         break;
       }
-      case ReferenceTypeDescr::TYPE_OBJECT: {
+      case ReferenceType::TYPE_OBJECT: {
         // Make sure the barrier reflects the possibility of reading null. When
         // there is no other barrier needed we include the null bailout with
         // MLoadUnboxedObjectOrNull, which avoids the need to box the result
         // for a type barrier instruction.
         MLoadUnboxedObjectOrNull::NullBehavior nullBehavior;
         if (barrier == BarrierKind::NoBarrier && !observedTypes->hasType(TypeSet::NullType()))
             nullBehavior = MLoadUnboxedObjectOrNull::BailOnNull;
         else
             nullBehavior = MLoadUnboxedObjectOrNull::HandleNull;
         load = MLoadUnboxedObjectOrNull::New(alloc(), elements, scaledOffset, nullBehavior,
                                              adjustment);
         break;
       }
-      case ReferenceTypeDescr::TYPE_STRING: {
+      case ReferenceType::TYPE_STRING: {
         load = MLoadUnboxedString::New(alloc(), elements, scaledOffset, adjustment);
         observedTypes->addType(TypeSet::StringType(), alloc().lifoAlloc());
         break;
       }
     }
 
     current->add(load);
     current->push(load);
@@ -8950,17 +8950,17 @@ IonBuilder::setElemTryTypedObject(bool* 
 AbortReasonOr<Ok>
 IonBuilder::setElemTryReferenceElemOfTypedObject(bool* emitted,
                                                  MDefinition* obj,
                                                  MDefinition* index,
                                                  TypedObjectPrediction objPrediction,
                                                  MDefinition* value,
                                                  TypedObjectPrediction elemPrediction)
 {
-    ReferenceTypeDescr::Type elemType = elemPrediction.referenceType();
+    ReferenceType elemType = elemPrediction.referenceType();
     uint32_t elemSize = ReferenceTypeDescr::size(elemType);
 
     LinearSum indexAsByteOffset(alloc());
     if (!checkTypedObjectIndexInBounds(elemSize, index, objPrediction, &indexAsByteOffset))
         return Ok();
 
     return setPropTryReferenceTypedObjectValue(emitted, obj, indexAsByteOffset,
                                                elemType, value, nullptr);
@@ -10598,17 +10598,17 @@ IonBuilder::getPropTryScalarPropOfTypedO
 }
 
 AbortReasonOr<Ok>
 IonBuilder::getPropTryReferencePropOfTypedObject(bool* emitted, MDefinition* typedObj,
                                                  int32_t fieldOffset,
                                                  TypedObjectPrediction fieldPrediction,
                                                  PropertyName* name)
 {
-    ReferenceTypeDescr::Type fieldType = fieldPrediction.referenceType();
+    ReferenceType fieldType = fieldPrediction.referenceType();
 
     TypeSet::ObjectKey* globalKey = TypeSet::ObjectKey::get(&script()->global());
     if (globalKey->hasFlags(constraints(), OBJECT_FLAG_TYPED_OBJECT_HAS_DETACHED_BUFFER))
         return Ok();
 
     trackOptimizationSuccess();
     *emitted = true;
 
@@ -11713,17 +11713,17 @@ IonBuilder::setPropTryTypedObject(bool* 
 AbortReasonOr<Ok>
 IonBuilder::setPropTryReferencePropOfTypedObject(bool* emitted,
                                                  MDefinition* obj,
                                                  int32_t fieldOffset,
                                                  MDefinition* value,
                                                  TypedObjectPrediction fieldPrediction,
                                                  PropertyName* name)
 {
-    ReferenceTypeDescr::Type fieldType = fieldPrediction.referenceType();
+    ReferenceType fieldType = fieldPrediction.referenceType();
 
     TypeSet::ObjectKey* globalKey = TypeSet::ObjectKey::get(&script()->global());
     if (globalKey->hasFlags(constraints(), OBJECT_FLAG_TYPED_OBJECT_HAS_DETACHED_BUFFER))
         return Ok();
 
     LinearSum byteOffset(alloc());
     if (!byteOffset.add(fieldOffset))
         return abort(AbortReason::Disable, "Overflow of field offset.");
@@ -13558,29 +13558,29 @@ IonBuilder::setPropTryScalarTypedObjectV
     *emitted = true;
     return resumeAfter(store);
 }
 
 AbortReasonOr<Ok>
 IonBuilder::setPropTryReferenceTypedObjectValue(bool* emitted,
                                                 MDefinition* typedObj,
                                                 const LinearSum& byteOffset,
-                                                ReferenceTypeDescr::Type type,
+                                                ReferenceType type,
                                                 MDefinition* value,
                                                 PropertyName* name)
 {
     MOZ_ASSERT(!*emitted);
 
     // Make sure we aren't adding new type information for writes of object and value
     // references.
-    if (type != ReferenceTypeDescr::TYPE_STRING) {
-        MOZ_ASSERT(type == ReferenceTypeDescr::TYPE_ANY ||
-                   type == ReferenceTypeDescr::TYPE_OBJECT);
+    if (type != ReferenceType::TYPE_STRING) {
+        MOZ_ASSERT(type == ReferenceType::TYPE_ANY ||
+                   type == ReferenceType::TYPE_OBJECT);
         MIRType implicitType =
-            (type == ReferenceTypeDescr::TYPE_ANY) ? MIRType::Undefined : MIRType::Null;
+            (type == ReferenceType::TYPE_ANY) ? MIRType::Undefined : MIRType::Null;
 
         if (PropertyWriteNeedsTypeBarrier(alloc(), constraints(), current, &typedObj, name, &value,
                                           /* canModify = */ true, implicitType))
         {
             trackOptimizationOutcome(TrackedOutcome::NeedsTypeBarrier);
             return Ok();
         }
     }
@@ -13590,30 +13590,30 @@ IonBuilder::setPropTryReferenceTypedObje
     MDefinition* scaledOffset;
     int32_t adjustment;
     uint32_t alignment = ReferenceTypeDescr::alignment(type);
     MOZ_TRY(loadTypedObjectElements(typedObj, byteOffset, alignment,
                                     &elements, &scaledOffset, &adjustment));
 
     MInstruction* store = nullptr;  // initialize to silence GCC warning
     switch (type) {
-      case ReferenceTypeDescr::TYPE_ANY:
+      case ReferenceType::TYPE_ANY:
         if (needsPostBarrier(value))
             current->add(MPostWriteBarrier::New(alloc(), typedObj, value));
         store = MStoreElement::New(alloc(), elements, scaledOffset, value, false, adjustment);
         store->toStoreElement()->setNeedsBarrier();
         break;
-      case ReferenceTypeDescr::TYPE_OBJECT:
+      case ReferenceType::TYPE_OBJECT:
         // Note: We cannot necessarily tell at this point whether a post
         // barrier is needed, because the type policy may insert ToObjectOrNull
         // instructions later, and those may require a post barrier. Therefore,
         // defer the insertion of post barriers to the type policy.
         store = MStoreUnboxedObjectOrNull::New(alloc(), elements, scaledOffset, value, typedObj, adjustment);
         break;
-      case ReferenceTypeDescr::TYPE_STRING:
+      case ReferenceType::TYPE_STRING:
         // See previous comment. The StoreUnboxedString type policy may insert
         // ToString instructions that require a post barrier.
         store = MStoreUnboxedString::New(alloc(), elements, scaledOffset, value, typedObj, adjustment);
         break;
     }
 
     current->add(store);
     current->push(value);
--- a/js/src/jit/IonBuilder.h
+++ b/js/src/jit/IonBuilder.h
@@ -283,17 +283,17 @@ class IonBuilder
                                             PropertyName* name, MDefinition* value);
     AbortReasonOr<Ok> setPropTryReferencePropOfTypedObject(bool* emitted, MDefinition* obj,
                                                            int32_t fieldOffset, MDefinition* value,
                                                            TypedObjectPrediction fieldPrediction,
                                                            PropertyName* name);
     AbortReasonOr<Ok> setPropTryReferenceTypedObjectValue(bool* emitted,
                                                           MDefinition* typedObj,
                                                           const LinearSum& byteOffset,
-                                                          ReferenceTypeDescr::Type type,
+                                                          ReferenceType type,
                                                           MDefinition* value,
                                                           PropertyName* name);
     AbortReasonOr<Ok> setPropTryScalarPropOfTypedObject(bool* emitted,
                                                         MDefinition* obj,
                                                         int32_t fieldOffset,
                                                         MDefinition* value,
                                                         TypedObjectPrediction fieldTypeReprs);
     AbortReasonOr<Ok> setPropTryScalarTypedObjectValue(bool* emitted,
@@ -380,17 +380,17 @@ class IonBuilder
                                              const LinearSum& byteOffset,
                                              TypedObjectPrediction derivedTypeDescrs,
                                              MDefinition* derivedTypeObj);
     AbortReasonOr<Ok> pushScalarLoadFromTypedObject(MDefinition* obj,
                                                     const LinearSum& byteoffset,
                                                     ScalarTypeDescr::Type type);
     AbortReasonOr<Ok> pushReferenceLoadFromTypedObject(MDefinition* typedObj,
                                                        const LinearSum& byteOffset,
-                                                       ReferenceTypeDescr::Type type,
+                                                       ReferenceType type,
                                                        PropertyName* name);
 
     // jsop_setelem() helpers.
     AbortReasonOr<Ok> setElemTryTypedArray(bool* emitted, MDefinition* object,
                                            MDefinition* index, MDefinition* value);
     AbortReasonOr<Ok> setElemTryTypedObject(bool* emitted, MDefinition* obj,
                                             MDefinition* index, MDefinition* value);
     AbortReasonOr<Ok> initOrSetElemTryDense(bool* emitted, MDefinition* object,
--- a/js/src/jit/IonCacheIRCompiler.cpp
+++ b/js/src/jit/IonCacheIRCompiler.cpp
@@ -1690,40 +1690,40 @@ IonCacheIRCompiler::emitStoreUnboxedProp
 }
 
 bool
 IonCacheIRCompiler::emitStoreTypedObjectReferenceProperty()
 {
     Register obj = allocator.useRegister(masm, reader.objOperandId());
     int32_t offset = int32StubField(reader.stubOffset());
     TypedThingLayout layout = reader.typedThingLayout();
-    ReferenceTypeDescr::Type type = reader.referenceTypeDescrType();
+    ReferenceType type = reader.referenceTypeDescrType();
 
     ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
 
     AutoScratchRegister scratch1(allocator, masm);
     AutoScratchRegister scratch2(allocator, masm);
 
     // We don't need to check property types if the property is always a
     // string.
-    if (type != ReferenceTypeDescr::TYPE_STRING) {
+    if (type != ReferenceType::TYPE_STRING) {
         FailurePath* failure;
         if (!addFailurePath(&failure))
             return false;
         EmitCheckPropertyTypes(masm, typeCheckInfo_, obj, TypedOrValueRegister(val),
                                *liveRegs_, failure->label());
     }
 
     // Compute the address being written to.
     LoadTypedThingData(masm, layout, obj, scratch1);
     Address dest(scratch1, offset);
 
     emitStoreTypedObjectReferenceProp(val, type, dest, scratch2);
 
-    if (needsPostBarrier() && type != ReferenceTypeDescr::TYPE_STRING)
+    if (needsPostBarrier() && type != ReferenceType::TYPE_STRING)
         emitPostBarrierSlot(obj, val, scratch1);
     return true;
 }
 
 bool
 IonCacheIRCompiler::emitStoreTypedObjectScalarProperty()
 {
     Register obj = allocator.useRegister(masm, reader.objOperandId());
--- a/js/src/jit/SharedIC.h
+++ b/js/src/jit/SharedIC.h
@@ -2303,21 +2303,21 @@ SimpleTypeDescrKeyIsScalar(uint32_t key)
 
 inline ScalarTypeDescr::Type
 ScalarTypeFromSimpleTypeDescrKey(uint32_t key)
 {
     MOZ_ASSERT(SimpleTypeDescrKeyIsScalar(key));
     return ScalarTypeDescr::Type(key >> 1);
 }
 
-inline ReferenceTypeDescr::Type
+inline ReferenceType
 ReferenceTypeFromSimpleTypeDescrKey(uint32_t key)
 {
     MOZ_ASSERT(!SimpleTypeDescrKeyIsScalar(key));
-    return ReferenceTypeDescr::Type(key >> 1);
+    return ReferenceType(key >> 1);
 }
 
 // JSOP_NEWARRAY
 // JSOP_NEWINIT
 
 class ICNewArray_Fallback : public ICFallbackStub
 {
     friend class ICStubSpace;
--- a/js/src/jit/TypedObjectPrediction.cpp
+++ b/js/src/jit/TypedObjectPrediction.cpp
@@ -196,17 +196,17 @@ TypedObjectPrediction::extractType() con
 }
 
 ScalarTypeDescr::Type
 TypedObjectPrediction::scalarType() const
 {
     return extractType<ScalarTypeDescr>();
 }
 
-ReferenceTypeDescr::Type
+ReferenceType
 TypedObjectPrediction::referenceType() const
 {
     return extractType<ReferenceTypeDescr>();
 }
 
 SimdType
 TypedObjectPrediction::simdType() const
 {
--- a/js/src/jit/TypedObjectPrediction.h
+++ b/js/src/jit/TypedObjectPrediction.h
@@ -161,18 +161,18 @@ class TypedObjectPrediction {
     // of its type is known.
     bool hasKnownSize(uint32_t* out) const;
 
     //////////////////////////////////////////////////////////////////////
     // Simple operations
     //
     // Only valid when |kind()| is Scalar, Reference, or Simd (as appropriate).
 
-    ScalarTypeDescr::Type scalarType() const;
-    ReferenceTypeDescr::Type referenceType() const;
+    Scalar::Type scalarType() const;
+    ReferenceType referenceType() const;
     SimdType simdType() const;
 
     ///////////////////////////////////////////////////////////////////////////
     // Queries valid only for arrays.
 
     // Returns true if the length of the array is statically known,
     // and sets |*length| appropriately. Otherwise returns false.
     bool hasKnownArrayLength(int32_t* length) const;