diff --git a/js/src/builtin/SIMD.cpp b/js/src/builtin/SIMD.cpp index e9c5a95e8307..0922059d6ee4 100644 --- a/js/src/builtin/SIMD.cpp +++ b/js/src/builtin/SIMD.cpp @@ -278,6 +278,7 @@ CreateSimdClass(JSContext *cx, proto = NewObjectWithProto(cx, objProto, nullptr, TenuredObject); if (!proto) return nullptr; + proto->initTypeDescrSlot(*typeDescr); typeDescr->initReservedSlot(JS_DESCR_SLOT_TYPROTO, ObjectValue(*proto)); // Link constructor to prototype and install properties. diff --git a/js/src/builtin/TypedObject.cpp b/js/src/builtin/TypedObject.cpp index 77d707da5ef2..e23aa68646c7 100644 --- a/js/src/builtin/TypedObject.cpp +++ b/js/src/builtin/TypedObject.cpp @@ -478,10 +478,16 @@ CreatePrototypeObjectForComplexTypeInstance(JSContext *cx, if (!ctorPrototypePrototype) return nullptr; - return NewObjectWithProto(cx, - &*ctorPrototypePrototype, - nullptr, - TenuredObject); + Rooted result(cx); + result = NewObjectWithProto(cx, + &*ctorPrototypePrototype, + nullptr, + TenuredObject); + if (!result) + return nullptr; + + result->initTypeDescrSlot(*descr); + return result; } const Class ArrayTypeDescr::class_ = { @@ -1166,6 +1172,7 @@ DefineSimpleTypeDescr(JSContext *cx, proto = NewObjectWithProto(cx, objProto, nullptr, TenuredObject); if (!proto) return false; + proto->initTypeDescrSlot(*descr); descr->initReservedSlot(JS_DESCR_SLOT_TYPROTO, ObjectValue(*proto)); RootedValue descrValue(cx, ObjectValue(*descr)); @@ -1461,6 +1468,24 @@ OutlineTypedObject::createUnattached(JSContext *cx, return createUnattachedWithClass(cx, &OutlineTransparentTypedObject::class_, descr, length, heap); } +static JSObject * +PrototypeForTypeDescr(JSContext *cx, HandleTypeDescr descr) +{ + if (descr->is()) { + // FIXME Bug 929651 -- What prototype to use? + return cx->global()->getOrCreateObjectPrototype(cx); + } + + RootedValue protoVal(cx); + if (!JSObject::getProperty(cx, descr, descr, + cx->names().prototype, &protoVal)) + { + return nullptr; + } + + return &protoVal.toObject(); +} + void OutlineTypedObject::setOwnerAndData(JSObject *owner, uint8_t *data) { @@ -1483,25 +1508,26 @@ OutlineTypedObject::setOwnerAndData(JSObject *owner, uint8_t *data) /*static*/ OutlineTypedObject * OutlineTypedObject::createUnattachedWithClass(JSContext *cx, const Class *clasp, - HandleTypeDescr descr, + HandleTypeDescr type, int32_t length, gc::InitialHeap heap) { MOZ_ASSERT(clasp == &OutlineTransparentTypedObject::class_ || clasp == &OutlineOpaqueTypedObject::class_); - RootedTypeObject type(cx, cx->getNewType(clasp, TaggedProto(&descr->typedProto()), descr)); - if (!type) + RootedObject proto(cx, PrototypeForTypeDescr(cx, type)); + if (!proto) return nullptr; NewObjectKind newKind = (heap == gc::TenuredHeap) ? MaybeSingletonObject : GenericObject; - OutlineTypedObject *obj = NewObjectWithType(cx, type, cx->global(), - gc::FINALIZE_OBJECT0, newKind); + JSObject *obj = NewObjectWithClassProto(cx, clasp, proto, nullptr, gc::FINALIZE_OBJECT0, newKind); if (!obj) return nullptr; - obj->setOwnerAndData(nullptr, nullptr); - return obj; + OutlineTypedObject *typedObj = &obj->as(); + + typedObj->setOwnerAndData(nullptr, nullptr); + return typedObj; } void @@ -2191,16 +2217,20 @@ InlineTypedObject::create(JSContext *cx, HandleTypeDescr descr, gc::InitialHeap { gc::AllocKind allocKind = allocKindForTypeDescriptor(descr); + RootedObject proto(cx, PrototypeForTypeDescr(cx, descr)); + if (!proto) + return nullptr; + const Class *clasp = descr->opaque() ? &InlineOpaqueTypedObject::class_ : &InlineTransparentTypedObject::class_; - RootedTypeObject type(cx, cx->getNewType(clasp, TaggedProto(&descr->typedProto()), descr)); - if (!type) + NewObjectKind newKind = (heap == gc::TenuredHeap) ? MaybeSingletonObject : GenericObject; + RootedObject obj(cx, NewObjectWithClassProto(cx, clasp, proto, nullptr, allocKind, newKind)); + if (!obj) return nullptr; - NewObjectKind newKind = (heap == gc::TenuredHeap) ? MaybeSingletonObject : GenericObject; - return NewObjectWithType(cx, type, cx->global(), allocKind, newKind); + return &obj->as(); } /* static */ InlineTypedObject * @@ -2748,19 +2778,6 @@ JS_JITINFO_NATIVE_PARALLEL_THREADSAFE(js::TypedObjectIsAttachedJitInfo, TypedObjectIsAttachedJitInfo, js::TypedObjectIsAttached); -bool -js::TypedObjectTypeDescr(ThreadSafeContext *cx, unsigned argc, Value *vp) -{ - CallArgs args = CallArgsFromVp(argc, vp); - TypedObject &typedObj = args[0].toObject().as(); - args.rval().setObject(typedObj.typeDescr()); - return true; -} - -JS_JITINFO_NATIVE_PARALLEL_THREADSAFE(js::TypedObjectTypeDescrJitInfo, - TypedObjectTypeDescrJitInfo, - js::TypedObjectTypeDescr); - bool js::ClampToUint8(ThreadSafeContext *, unsigned argc, Value *vp) { diff --git a/js/src/builtin/TypedObject.h b/js/src/builtin/TypedObject.h index 70ed8e439737..ca3687e03b08 100644 --- a/js/src/builtin/TypedObject.h +++ b/js/src/builtin/TypedObject.h @@ -134,12 +134,30 @@ class StructTypeDescr; class TypedProto; /* - * The prototype for a typed object. + * The prototype for a typed object. Currently, carries a link to the + * type descriptor. Eventually will carry most of the type information + * we want. */ class TypedProto : public NativeObject { public: static const Class class_; + + inline void initTypeDescrSlot(TypeDescr &descr); + + TypeDescr &typeDescr() const { + return getReservedSlot(JS_TYPROTO_SLOT_DESCR).toObject().as(); + } + + TypeDescr &maybeForwardedTypeDescr() const { + return MaybeForwarded(&getReservedSlot(JS_TYPROTO_SLOT_DESCR).toObject())->as(); + } + + inline type::Kind kind() const; + + static int32_t offsetOfTypeDescr() { + return getFixedSlotOffset(JS_TYPROTO_SLOT_DESCR); + } }; class TypeDescr : public NativeObject @@ -576,11 +594,11 @@ class TypedObject : public JSObject } TypeDescr &typeDescr() const { - return type()->typeDescr(); + return typedProto().typeDescr(); } TypeDescr &maybeForwardedTypeDescr() const { - return MaybeForwarded(&typeDescr())->as(); + return maybeForwardedTypedProto().maybeForwardedTypeDescr(); } int32_t offset() const; @@ -853,14 +871,6 @@ extern const JSJitInfo TypeDescrIsArrayTypeJitInfo; bool TypedObjectIsAttached(ThreadSafeContext *cx, unsigned argc, Value *vp); extern const JSJitInfo TypedObjectIsAttachedJitInfo; -/* - * Usage: TypedObjectTypeDescr(obj) - * - * Given a TypedObject `obj`, returns the object's type descriptor. - */ -bool TypedObjectTypeDescr(ThreadSafeContext *cx, unsigned argc, Value *vp); -extern const JSJitInfo TypedObjectTypeDescrJitInfo; - /* * Usage: ClampToUint8(v) * @@ -1120,4 +1130,17 @@ JSObject::is() const getClass() == &js::InlineOpaqueTypedObject::class_; } +inline void +js::TypedProto::initTypeDescrSlot(TypeDescr &descr) +{ + initReservedSlot(JS_TYPROTO_SLOT_DESCR, ObjectValue(descr)); +} + +inline js::type::Kind +js::TypedProto::kind() const { + // Defined out of line because it depends on def'n of both + // TypedProto and TypeDescr + return typeDescr().kind(); +} + #endif /* builtin_TypedObject_h */ diff --git a/js/src/builtin/TypedObject.js b/js/src/builtin/TypedObject.js index 5420fca6ae6d..26b14b640b26 100644 --- a/js/src/builtin/TypedObject.js +++ b/js/src/builtin/TypedObject.js @@ -28,11 +28,20 @@ #define DESCR_STRUCT_FIELD_OFFSETS(obj) \ UnsafeGetReservedSlot(obj, JS_DESCR_SLOT_STRUCT_FIELD_OFFSETS) +// Typed prototype slots + +#define TYPROTO_DESCR(obj) \ + UnsafeGetReservedSlot(obj, JS_TYPROTO_SLOT_DESCR) + // Other #define HAS_PROPERTY(obj, prop) \ callFunction(std_Object_hasOwnProperty, obj, prop) +function TypedObjectTypeDescr(typedObj) { + return TYPROTO_DESCR(std_Object_getPrototypeOf(typedObj)); +} + /////////////////////////////////////////////////////////////////////////// // Getting values // diff --git a/js/src/builtin/TypedObjectConstants.h b/js/src/builtin/TypedObjectConstants.h index 9c6dcc1c2641..61f29c5a061d 100644 --- a/js/src/builtin/TypedObjectConstants.h +++ b/js/src/builtin/TypedObjectConstants.h @@ -12,7 +12,8 @@ /////////////////////////////////////////////////////////////////////////// // Slots for typed prototypes -#define JS_TYPROTO_SLOTS 0 +#define JS_TYPROTO_SLOT_DESCR 0 +#define JS_TYPROTO_SLOTS 1 /////////////////////////////////////////////////////////////////////////// // Slots for type objects diff --git a/js/src/gc/Barrier.h b/js/src/gc/Barrier.h index d4e08dbbfe84..db45c33c111a 100644 --- a/js/src/gc/Barrier.h +++ b/js/src/gc/Barrier.h @@ -778,6 +778,10 @@ class UnownedBaseShape; namespace jit { class JitCode; } +namespace types { +struct TypeObject; +class TypeNewScript; +} typedef PreBarriered PreBarrieredObject; typedef PreBarriered PreBarrieredScript; @@ -807,6 +811,7 @@ typedef HeapPtr HeapPtrShape; typedef HeapPtr HeapPtrUnownedBaseShape; typedef HeapPtr HeapPtrJitCode; typedef HeapPtr HeapPtrTypeObject; +typedef HeapPtr HeapPtrTypeNewScript; typedef PreBarriered PreBarrieredValue; typedef RelocatablePtr RelocatableValue; diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index 022804f17c7a..c952c59e7414 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -4677,8 +4677,8 @@ LoadTypedThingLength(MacroAssembler &masm, TypedThingLayout layout, Register obj break; case Layout_OutlineTypedObject: case Layout_InlineTypedObject: - masm.loadPtr(Address(obj, JSObject::offsetOfType()), result); - masm.loadPtr(Address(result, types::TypeObject::offsetOfAddendum()), result); + masm.loadObjProto(obj, result); + masm.unboxObject(Address(result, TypedProto::offsetOfTypeDescr()), result); masm.unboxInt32(Address(result, ArrayTypeDescr::offsetOfLength()), result); break; default: @@ -8516,7 +8516,7 @@ ICSetPropNativeAddCompiler::generateStubCode(MacroAssembler &masm) // Check if the old type still has a newScript. masm.loadPtr(Address(objReg, JSObject::offsetOfType()), scratch); masm.branchPtr(Assembler::Equal, - Address(scratch, types::TypeObject::offsetOfAddendum()), + Address(scratch, types::TypeObject::offsetOfNewScript()), ImmWord(0), &noTypeChange); diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index 7e916a824bc2..6f913c0f0f04 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -4884,13 +4884,19 @@ CodeGenerator::visitTypedArrayElements(LTypedArrayElements *lir) } void -CodeGenerator::visitTypedObjectDescr(LTypedObjectDescr *lir) +CodeGenerator::visitTypedObjectProto(LTypedObjectProto *lir) { Register obj = ToRegister(lir->object()); - Register out = ToRegister(lir->output()); + MOZ_ASSERT(ToRegister(lir->output()) == ReturnReg); - masm.loadPtr(Address(obj, JSObject::offsetOfType()), out); - masm.loadPtr(Address(out, types::TypeObject::offsetOfAddendum()), out); + // Eventually we ought to inline this helper function for + // efficiency, but it's mildly non-trivial since we must reach + // into the type object and so on. + + const Register tempReg = ToRegister(lir->temp()); + masm.setupUnalignedABICall(1, tempReg); + masm.passABIArg(obj); + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, TypedObjectProto)); } void diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h index 6e38cfa11c8b..c4aa4ad9e082 100644 --- a/js/src/jit/CodeGenerator.h +++ b/js/src/jit/CodeGenerator.h @@ -186,7 +186,7 @@ class CodeGenerator : public CodeGeneratorSpecific void visitTypedArrayElements(LTypedArrayElements *lir); void visitTypedObjectElements(LTypedObjectElements *lir); void visitSetTypedObjectOffset(LSetTypedObjectOffset *lir); - void visitTypedObjectDescr(LTypedObjectDescr *ins); + void visitTypedObjectProto(LTypedObjectProto *ins); void visitStringLength(LStringLength *lir); void visitSubstr(LSubstr *lir); void visitInitializedLength(LInitializedLength *lir); diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 82f843f9ba1b..ac02064febc2 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -11271,7 +11271,14 @@ IonBuilder::typedObjectPrediction(types::TemporaryTypeSet *types) if (!IsTypedObjectClass(type->clasp())) return TypedObjectPrediction(); - out.addDescr(type->typeDescr()); + TaggedProto proto = type->proto(); + + // typed objects have immutable prototypes, and they are + // always instances of TypedProto + MOZ_ASSERT(proto.isObject() && proto.toObject()->is()); + + TypedProto &typedProto = proto.toObject()->as(); + out.addDescr(typedProto.typeDescr()); } return out; @@ -11287,10 +11294,16 @@ IonBuilder::loadTypedObjectType(MDefinition *typedObj) if (typedObj->isNewDerivedTypedObject()) return typedObj->toNewDerivedTypedObject()->type(); - MInstruction *descr = MTypedObjectDescr::New(alloc(), typedObj); - current->add(descr); + MInstruction *proto = MTypedObjectProto::New(alloc(), typedObj); + current->add(proto); - return descr; + MInstruction *load = MLoadFixedSlot::New(alloc(), proto, JS_TYPROTO_SLOT_DESCR); + current->add(load); + + MInstruction *unbox = MUnbox::New(alloc(), load, MIRType_Object, MUnbox::Infallible); + current->add(unbox); + + return unbox; } // Given a typed object `typedObj` and an offset `offset` into that diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp index f436b7ed2baf..0545a9d562d1 100644 --- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -2596,7 +2596,7 @@ GenerateAddSlot(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &att masm.push(object); masm.loadPtr(Address(object, JSObject::offsetOfType()), object); masm.branchPtr(Assembler::Equal, - Address(object, types::TypeObject::offsetOfAddendum()), + Address(object, types::TypeObject::offsetOfNewScript()), ImmWord(0), &noTypeChange); masm.pop(object); diff --git a/js/src/jit/LIR-Common.h b/js/src/jit/LIR-Common.h index 647e7ebe8d83..869f20cd92f1 100644 --- a/js/src/jit/LIR-Common.h +++ b/js/src/jit/LIR-Common.h @@ -4295,18 +4295,23 @@ class LTypedArrayElements : public LInstructionHelper<1, 1, 0> } }; -// Load a typed object's descriptor. -class LTypedObjectDescr : public LInstructionHelper<1, 1, 0> +// Load a typed object's prototype, which is guaranteed to be a +// TypedProto object. +class LTypedObjectProto : public LCallInstructionHelper<1, 1, 1> { public: - LIR_HEADER(TypedObjectDescr) + LIR_HEADER(TypedObjectProto) - LTypedObjectDescr(const LAllocation &object) { + LTypedObjectProto(const LAllocation &object, const LDefinition &temp1) { setOperand(0, object); + setTemp(0, temp1); } const LAllocation *object() { return getOperand(0); } + const LDefinition *temp() { + return getTemp(0); + } }; // Load a typed object's elements vector. diff --git a/js/src/jit/LOpcodes.h b/js/src/jit/LOpcodes.h index 52f270a148a7..23d594881e49 100644 --- a/js/src/jit/LOpcodes.h +++ b/js/src/jit/LOpcodes.h @@ -285,7 +285,7 @@ _(SetArrayLength) \ _(TypedArrayLength) \ _(TypedArrayElements) \ - _(TypedObjectDescr) \ + _(TypedObjectProto) \ _(TypedObjectElements) \ _(SetTypedObjectOffset) \ _(StringLength) \ diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index 69d2207f4cae..3125d6bb6150 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -2496,10 +2496,12 @@ LIRGenerator::visitTypedArrayElements(MTypedArrayElements *ins) } void -LIRGenerator::visitTypedObjectDescr(MTypedObjectDescr *ins) +LIRGenerator::visitTypedObjectProto(MTypedObjectProto *ins) { MOZ_ASSERT(ins->type() == MIRType_Object); - define(new(alloc()) LTypedObjectDescr(useRegisterAtStart(ins->object())), ins); + defineReturn(new(alloc()) LTypedObjectProto(useFixed(ins->object(), CallTempReg0), + tempFixed(CallTempReg1)), + ins); } void diff --git a/js/src/jit/Lowering.h b/js/src/jit/Lowering.h index 0092a3a4773b..83bbf1fbd967 100644 --- a/js/src/jit/Lowering.h +++ b/js/src/jit/Lowering.h @@ -192,7 +192,7 @@ class LIRGenerator : public LIRGeneratorSpecific void visitTypedArrayElements(MTypedArrayElements *ins); void visitTypedObjectElements(MTypedObjectElements *ins); void visitSetTypedObjectOffset(MSetTypedObjectOffset *ins); - void visitTypedObjectDescr(MTypedObjectDescr *ins); + void visitTypedObjectProto(MTypedObjectProto *ins); void visitInitializedLength(MInitializedLength *ins); void visitSetInitializedLength(MSetInitializedLength *ins); void visitNot(MNot *ins); diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index a033794e47ed..1298c88788d2 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -2829,12 +2829,12 @@ class MNewTypedObject : public MNullaryInstruction } }; -class MTypedObjectDescr +class MTypedObjectProto : public MUnaryInstruction, public SingleObjectPolicy::Data { private: - explicit MTypedObjectDescr(MDefinition *object) + explicit MTypedObjectProto(MDefinition *object) : MUnaryInstruction(object) { setResultType(MIRType_Object); @@ -2842,10 +2842,10 @@ class MTypedObjectDescr } public: - INSTRUCTION_HEADER(TypedObjectDescr) + INSTRUCTION_HEADER(TypedObjectProto) - static MTypedObjectDescr *New(TempAllocator &alloc, MDefinition *object) { - return new(alloc) MTypedObjectDescr(object); + static MTypedObjectProto *New(TempAllocator &alloc, MDefinition *object) { + return new(alloc) MTypedObjectProto(object); } MDefinition *object() const { diff --git a/js/src/jit/MOpcodes.h b/js/src/jit/MOpcodes.h index 6449147a19bb..a78f28c3a9bb 100644 --- a/js/src/jit/MOpcodes.h +++ b/js/src/jit/MOpcodes.h @@ -164,7 +164,7 @@ namespace jit { _(SetArrayLength) \ _(TypedArrayLength) \ _(TypedArrayElements) \ - _(TypedObjectDescr) \ + _(TypedObjectProto) \ _(TypedObjectElements) \ _(SetTypedObjectOffset) \ _(InitializedLength) \ diff --git a/js/src/jit/ParallelSafetyAnalysis.cpp b/js/src/jit/ParallelSafetyAnalysis.cpp index dae921e833b2..77e9573428ca 100644 --- a/js/src/jit/ParallelSafetyAnalysis.cpp +++ b/js/src/jit/ParallelSafetyAnalysis.cpp @@ -244,7 +244,7 @@ class ParallelSafetyVisitor : public MDefinitionVisitor WRITE_GUARDED_OP(SetArrayLength, elements) SAFE_OP(TypedArrayLength) SAFE_OP(TypedArrayElements) - SAFE_OP(TypedObjectDescr) + SAFE_OP(TypedObjectProto) SAFE_OP(TypedObjectElements) SAFE_OP(SetTypedObjectOffset) SAFE_OP(InitializedLength) diff --git a/js/src/jit/VMFunctions.cpp b/js/src/jit/VMFunctions.cpp index fe6809c543e0..aac7872f250b 100644 --- a/js/src/jit/VMFunctions.cpp +++ b/js/src/jit/VMFunctions.cpp @@ -1291,6 +1291,15 @@ AssertValidValue(JSContext *cx, Value *v) } #endif +// Definition of the MTypedObjectProto MIR. +JSObject * +TypedObjectProto(JSObject *obj) +{ + MOZ_ASSERT(obj->is()); + TypedObject &typedObj = obj->as(); + return &typedObj.typedProto(); +} + bool ObjectIsCallable(JSObject *obj) { diff --git a/js/src/jit/VMFunctions.h b/js/src/jit/VMFunctions.h index 50c08ddd0701..79d4c7321238 100644 --- a/js/src/jit/VMFunctions.h +++ b/js/src/jit/VMFunctions.h @@ -791,6 +791,8 @@ void AssertValidSymbolPtr(JSContext *cx, JS::Symbol *sym); void AssertValidValue(JSContext *cx, Value *v); #endif +JSObject *TypedObjectProto(JSObject *obj); + void MarkValueFromIon(JSRuntime *rt, Value *vp); void MarkStringFromIon(JSRuntime *rt, JSString **stringp); void MarkObjectFromIon(JSRuntime *rt, JSObject **objp); diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index 741f76b21e31..3b77a926facd 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -375,8 +375,7 @@ class ExclusiveContext : public ThreadSafeContext } // Zone local methods that can be used freely from an ExclusiveContext. - types::TypeObject *getNewType(const Class *clasp, TaggedProto proto, - JSObject *associated = nullptr); + types::TypeObject *getNewType(const Class *clasp, TaggedProto proto, JSFunction *fun = nullptr); types::TypeObject *getSingletonType(const Class *clasp, TaggedProto proto); inline js::LifoAlloc &typeLifoAlloc(); diff --git a/js/src/jscompartment.h b/js/src/jscompartment.h index edf774984036..54bbc73c7bd1 100644 --- a/js/src/jscompartment.h +++ b/js/src/jscompartment.h @@ -271,13 +271,13 @@ struct JSCompartment void sweepInitialShapeTable(); /* Set of default 'new' or lazy types in the compartment. */ - js::types::NewTypeObjectTable newTypeObjects; - js::types::NewTypeObjectTable lazyTypeObjects; - void sweepNewTypeObjectTable(js::types::NewTypeObjectTable &table); + js::types::TypeObjectWithNewScriptSet newTypeObjects; + js::types::TypeObjectWithNewScriptSet lazyTypeObjects; + void sweepNewTypeObjectTable(js::types::TypeObjectWithNewScriptSet &table); #ifdef JSGC_HASH_TABLE_CHECKS void checkTypeObjectTablesAfterMovingGC(); - void checkTypeObjectTableAfterMovingGC(js::types::NewTypeObjectTable &table); + void checkTypeObjectTableAfterMovingGC(js::types::TypeObjectWithNewScriptSet &table); void checkInitialShapesTableAfterMovingGC(); void checkWrapperMapAfterMovingGC(); #endif @@ -394,7 +394,7 @@ struct JSCompartment #ifdef JSGC_COMPACTING void fixupInitialShapeTable(); - void fixupNewTypeObjectTable(js::types::NewTypeObjectTable &table); + void fixupNewTypeObjectTable(js::types::TypeObjectWithNewScriptSet &table); void fixupAfterMovingGC(); void fixupGlobal(); #endif diff --git a/js/src/jsinfer.cpp b/js/src/jsinfer.cpp index 919eb58234f5..111b492f6263 100644 --- a/js/src/jsinfer.cpp +++ b/js/src/jsinfer.cpp @@ -3264,7 +3264,7 @@ TypeObject::maybeClearNewScriptOnOOM() if (!isMarked()) return; - if (!newScript()) + if (!newScript_) return; for (unsigned i = 0; i < getPropertyCount(); i++) { @@ -3278,7 +3278,7 @@ TypeObject::maybeClearNewScriptOnOOM() // This method is called during GC sweeping, so there is no write barrier // that needs to be triggered. js_delete(newScript()); - addendum_ = nullptr; + newScript_.unsafeSet(nullptr); } void @@ -4083,12 +4083,12 @@ TypeNewScript::maybeAnalyze(JSContext *cx, TypeObject *type, bool *regenerate, b if (!type->addDefiniteProperties(cx, prefixShape)) return false; - NewTypeObjectTable &table = cx->compartment()->newTypeObjects; - NewTypeObjectTable::Lookup lookup(type->clasp(), type->proto(), fun); + TypeObjectWithNewScriptSet &table = cx->compartment()->newTypeObjects; + TypeObjectWithNewScriptSet::Lookup lookup(type->clasp(), type->proto(), fun); MOZ_ASSERT(table.lookup(lookup)->object == type); table.remove(lookup); - table.putNew(lookup, NewTypeObjectEntry(initialType, fun)); + table.putNew(lookup, TypeObjectWithNewScriptEntry(initialType, fun)); templateObject()->setType(initialType); @@ -4322,32 +4322,31 @@ JSObject::makeLazyType(JSContext *cx, HandleObject obj) } /* static */ inline HashNumber -NewTypeObjectEntry::hash(const Lookup &lookup) +TypeObjectWithNewScriptEntry::hash(const Lookup &lookup) { return PointerHasher::hash(lookup.hashProto.raw()) ^ PointerHasher::hash(lookup.clasp) ^ - PointerHasher::hash(lookup.associated); + PointerHasher::hash(lookup.newFunction); } /* static */ inline bool -NewTypeObjectEntry::match(const NewTypeObjectEntry &key, const Lookup &lookup) +TypeObjectWithNewScriptEntry::match(const TypeObjectWithNewScriptEntry &key, const Lookup &lookup) { return key.object->proto() == lookup.matchProto && key.object->clasp() == lookup.clasp && - key.associated == lookup.associated; + key.newFunction == lookup.newFunction; } #ifdef DEBUG bool JSObject::hasNewType(const Class *clasp, TypeObject *type) { - NewTypeObjectTable &table = compartment()->newTypeObjects; + TypeObjectWithNewScriptSet &table = compartment()->newTypeObjects; if (!table.initialized()) return false; - NewTypeObjectTable::Ptr p = - table.lookup(NewTypeObjectTable::Lookup(clasp, TaggedProto(this), nullptr)); + TypeObjectWithNewScriptSet::Ptr p = table.lookup(TypeObjectWithNewScriptSet::Lookup(clasp, TaggedProto(this), nullptr)); return p && p->object == type; } #endif /* DEBUG */ @@ -4363,12 +4362,10 @@ JSObject::setNewTypeUnknown(JSContext *cx, const Class *clasp, HandleObject obj) * not have the SETS_MARKED_UNKNOWN bit set, so may require a type set * crawl if prototypes of the object change dynamically in the future. */ - NewTypeObjectTable &table = cx->compartment()->newTypeObjects; + TypeObjectWithNewScriptSet &table = cx->compartment()->newTypeObjects; if (table.initialized()) { Rooted taggedProto(cx, TaggedProto(obj)); - NewTypeObjectTable::Ptr p = - table.lookup(NewTypeObjectTable::Lookup(clasp, taggedProto, nullptr)); - if (p) + if (TypeObjectWithNewScriptSet::Ptr p = table.lookup(TypeObjectWithNewScriptSet::Lookup(clasp, taggedProto, nullptr))) MarkTypeObjectUnknownProperties(cx, p->object); } @@ -4382,14 +4379,14 @@ JSObject::setNewTypeUnknown(JSContext *cx, const Class *clasp, HandleObject obj) */ class NewTypeObjectsSetRef : public BufferableRef { - NewTypeObjectTable *set; + TypeObjectWithNewScriptSet *set; const Class *clasp; JSObject *proto; - JSObject *associated; + JSFunction *newFunction; public: - NewTypeObjectsSetRef(NewTypeObjectTable *s, const Class *clasp, JSObject *proto, JSObject *associated) - : set(s), clasp(clasp), proto(proto), associated(associated) + NewTypeObjectsSetRef(TypeObjectWithNewScriptSet *s, const Class *clasp, JSObject *proto, JSFunction *newFunction) + : set(s), clasp(clasp), proto(proto), newFunction(newFunction) {} void mark(JSTracer *trc) { @@ -4399,21 +4396,19 @@ class NewTypeObjectsSetRef : public BufferableRef if (prior == proto) return; - NewTypeObjectTable::Ptr p = - set->lookup(NewTypeObjectTable::Lookup(clasp, TaggedProto(prior), TaggedProto(proto), - associated)); + TypeObjectWithNewScriptSet::Ptr p = set->lookup(TypeObjectWithNewScriptSet::Lookup(clasp, TaggedProto(prior), TaggedProto(proto), newFunction)); MOZ_ASSERT(p); // newTypeObjects set must still contain original entry. - set->rekeyAs(NewTypeObjectTable::Lookup(clasp, TaggedProto(prior), TaggedProto(proto), associated), - NewTypeObjectTable::Lookup(clasp, TaggedProto(proto), associated), *p); + set->rekeyAs(TypeObjectWithNewScriptSet::Lookup(clasp, TaggedProto(prior), TaggedProto(proto), newFunction), + TypeObjectWithNewScriptSet::Lookup(clasp, TaggedProto(proto), newFunction), *p); } }; static void -TypeObjectTablePostBarrier(ExclusiveContext *cx, NewTypeObjectTable *table, - const Class *clasp, TaggedProto proto, JSObject *associated) +TypeObjectTablePostBarrier(ExclusiveContext *cx, TypeObjectWithNewScriptSet *table, + const Class *clasp, TaggedProto proto, JSFunction *fun) { - MOZ_ASSERT_IF(associated, !IsInsideNursery(associated)); + MOZ_ASSERT_IF(fun, !IsInsideNursery(fun)); if (!proto.isObject()) return; @@ -4425,35 +4420,33 @@ TypeObjectTablePostBarrier(ExclusiveContext *cx, NewTypeObjectTable *table, if (IsInsideNursery(proto.toObject())) { StoreBuffer &sb = cx->asJSContext()->runtime()->gc.storeBuffer; - sb.putGeneric(NewTypeObjectsSetRef(table, clasp, proto.toObject(), associated)); + sb.putGeneric(NewTypeObjectsSetRef(table, clasp, proto.toObject(), fun)); } } TypeObject * -ExclusiveContext::getNewType(const Class *clasp, TaggedProto proto, JSObject *associated) +ExclusiveContext::getNewType(const Class *clasp, TaggedProto proto, JSFunction *fun) { - MOZ_ASSERT_IF(associated, proto.isObject()); - MOZ_ASSERT_IF(associated, associated->is() || associated->is()); + MOZ_ASSERT_IF(fun, proto.isObject()); MOZ_ASSERT_IF(proto.isObject(), isInsideCurrentCompartment(proto.toObject())); - NewTypeObjectTable &newTypeObjects = compartment()->newTypeObjects; + TypeObjectWithNewScriptSet &newTypeObjects = compartment()->newTypeObjects; if (!newTypeObjects.initialized() && !newTypeObjects.init()) return nullptr; // Canonicalize new functions to use the original one associated with its script. - if (associated && associated->is()) { - JSFunction *fun = &associated->as(); + if (fun) { if (fun->hasScript()) - associated = fun->nonLazyScript()->functionNonDelazifying(); + fun = fun->nonLazyScript()->functionNonDelazifying(); else if (fun->isInterpretedLazy() && !fun->isSelfHostedBuiltin()) - associated = fun->lazyScript()->functionNonDelazifying(); + fun = fun->lazyScript()->functionNonDelazifying(); else - associated = nullptr; + fun = nullptr; } - NewTypeObjectTable::AddPtr p = - newTypeObjects.lookupForAdd(NewTypeObjectTable::Lookup(clasp, proto, associated)); + TypeObjectWithNewScriptSet::AddPtr p = + newTypeObjects.lookupForAdd(TypeObjectWithNewScriptSet::Lookup(clasp, proto, fun)); if (p) { TypeObject *type = p->object; MOZ_ASSERT(type->clasp() == clasp); @@ -4482,20 +4475,16 @@ ExclusiveContext::getNewType(const Class *clasp, TaggedProto proto, JSObject *as if (!type) return nullptr; - if (!newTypeObjects.add(p, NewTypeObjectEntry(type, associated))) + if (!newTypeObjects.add(p, TypeObjectWithNewScriptEntry(type, fun))) return nullptr; - TypeObjectTablePostBarrier(this, &newTypeObjects, clasp, proto, associated); + TypeObjectTablePostBarrier(this, &newTypeObjects, clasp, proto, fun); if (proto.isObject()) { RootedObject obj(this, proto.toObject()); - if (associated) { - if (associated->is()) - TypeNewScript::make(asJSContext(), type, &associated->as()); - else - type->setTypeDescr(&associated->as()); - } + if (fun) + TypeNewScript::make(asJSContext(), type, fun); /* * Some builtin objects have slotful native properties baked in at @@ -4534,12 +4523,12 @@ ExclusiveContext::getSingletonType(const Class *clasp, TaggedProto proto) AutoEnterAnalysis enter(this); - NewTypeObjectTable &table = compartment()->lazyTypeObjects; + TypeObjectWithNewScriptSet &table = compartment()->lazyTypeObjects; if (!table.initialized() && !table.init()) return nullptr; - NewTypeObjectTable::AddPtr p = table.lookupForAdd(NewTypeObjectTable::Lookup(clasp, proto, nullptr)); + TypeObjectWithNewScriptSet::AddPtr p = table.lookupForAdd(TypeObjectWithNewScriptSet::Lookup(clasp, proto, nullptr)); if (p) { TypeObject *type = p->object; MOZ_ASSERT(type->lazy()); @@ -4552,7 +4541,7 @@ ExclusiveContext::getSingletonType(const Class *clasp, TaggedProto proto) if (!type) return nullptr; - if (!table.add(p, NewTypeObjectEntry(type, nullptr))) + if (!table.add(p, TypeObjectWithNewScriptEntry(type, nullptr))) return nullptr; TypeObjectTablePostBarrier(this, &table, clasp, proto, nullptr); @@ -4860,20 +4849,20 @@ TypeCompartment::sweep(FreeOp *fop) } void -JSCompartment::sweepNewTypeObjectTable(NewTypeObjectTable &table) +JSCompartment::sweepNewTypeObjectTable(TypeObjectWithNewScriptSet &table) { MOZ_ASSERT(zone()->runtimeFromAnyThread()->isHeapCollecting()); if (table.initialized()) { - for (NewTypeObjectTable::Enum e(table); !e.empty(); e.popFront()) { - NewTypeObjectEntry entry = e.front(); + for (TypeObjectWithNewScriptSet::Enum e(table); !e.empty(); e.popFront()) { + TypeObjectWithNewScriptEntry entry = e.front(); if (IsTypeObjectAboutToBeFinalizedFromAnyThread(entry.object.unsafeGet()) || - (entry.associated && IsObjectAboutToBeFinalizedFromAnyThread(&entry.associated))) + (entry.newFunction && IsObjectAboutToBeFinalizedFromAnyThread(&entry.newFunction))) { e.removeFront(); } else { /* Any rekeying necessary is handled by fixupNewTypeObjectTable() below. */ MOZ_ASSERT(entry.object.unbarrieredGet() == e.front().object.unbarrieredGet()); - MOZ_ASSERT(entry.associated == e.front().associated); + MOZ_ASSERT(entry.newFunction == e.front().newFunction); } } } @@ -4882,7 +4871,7 @@ JSCompartment::sweepNewTypeObjectTable(NewTypeObjectTable &table) #ifdef JSGC_COMPACTING void -JSCompartment::fixupNewTypeObjectTable(NewTypeObjectTable &table) +JSCompartment::fixupNewTypeObjectTable(TypeObjectWithNewScriptSet &table) { /* * Each entry's hash depends on the object's prototype and we can't tell @@ -4890,8 +4879,8 @@ JSCompartment::fixupNewTypeObjectTable(NewTypeObjectTable &table) */ MOZ_ASSERT(zone()->isCollecting()); if (table.initialized()) { - for (NewTypeObjectTable::Enum e(table); !e.empty(); e.popFront()) { - NewTypeObjectEntry entry = e.front(); + for (TypeObjectWithNewScriptSet::Enum e(table); !e.empty(); e.popFront()) { + TypeObjectWithNewScriptEntry entry = e.front(); bool needRekey = false; if (IsForwarded(entry.object.get())) { entry.object.set(Forwarded(entry.object.get())); @@ -4907,9 +4896,9 @@ JSCompartment::fixupNewTypeObjectTable(NewTypeObjectTable &table) needRekey = true; } if (needRekey) { - NewTypeObjectTable::Lookup lookup(entry.object->clasp(), - proto, - entry.newFunction); + TypeObjectWithNewScriptSet::Lookup lookup(entry.object->clasp(), + proto, + entry.newFunction); e.rekeyFront(lookup, entry); } } @@ -4953,7 +4942,7 @@ JSCompartment::checkTypeObjectTablesAfterMovingGC() } void -JSCompartment::checkTypeObjectTableAfterMovingGC(NewTypeObjectTable &table) +JSCompartment::checkTypeObjectTableAfterMovingGC(TypeObjectWithNewScriptSet &table) { /* * Assert that nothing points into the nursery or needs to be relocated, and @@ -4962,17 +4951,17 @@ JSCompartment::checkTypeObjectTableAfterMovingGC(NewTypeObjectTable &table) if (!table.initialized()) return; - for (NewTypeObjectTable::Enum e(table); !e.empty(); e.popFront()) { - NewTypeObjectEntry entry = e.front(); + for (TypeObjectWithNewScriptSet::Enum e(table); !e.empty(); e.popFront()) { + TypeObjectWithNewScriptEntry entry = e.front(); CheckGCThingAfterMovingGC(entry.object.get()); TaggedProto proto = entry.object->proto(); if (proto.isObject()) CheckGCThingAfterMovingGC(proto.toObject()); - CheckGCThingAfterMovingGC(entry.associated); + CheckGCThingAfterMovingGC(entry.newFunction); - NewTypeObjectTable::Lookup - lookup(entry.object->clasp(), proto, entry.associated); - NewTypeObjectTable::Ptr ptr = table.lookup(lookup); + TypeObjectWithNewScriptEntry::Lookup + lookup(entry.object->clasp(), proto, entry.newFunction); + TypeObjectWithNewScriptSet::Ptr ptr = table.lookup(lookup); MOZ_ASSERT(ptr.found() && &*ptr == &e.front()); } } @@ -5083,7 +5072,7 @@ TypeCompartment::addSizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf, size_t TypeObject::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return mallocSizeOf(newScriptDontCheckGeneration()); + return mallocSizeOf(newScript_); } TypeZone::TypeZone(Zone *zone) @@ -5248,14 +5237,8 @@ TypeScript::printTypes(JSContext *cx, HandleScript script) const #endif /* DEBUG */ void -TypeObject::setAddendum(AddendumKind kind, void *addendum) +TypeObject::setNewScript(TypeNewScript *newScript) { MOZ_ASSERT(!needsSweep()); - MOZ_ASSERT(kind <= (OBJECT_FLAG_ADDENDUM_MASK >> OBJECT_FLAG_ADDENDUM_SHIFT)); - MOZ_ASSERT(!(flags_ & OBJECT_FLAG_ADDENDUM_MASK)); - - writeBarrierPre(this); - - flags_ |= kind << OBJECT_FLAG_ADDENDUM_SHIFT; - addendum_ = addendum; + newScript_ = newScript; } diff --git a/js/src/jsinfer.h b/js/src/jsinfer.h index eef6dbf99b11..a480eab39924 100644 --- a/js/src/jsinfer.h +++ b/js/src/jsinfer.h @@ -512,14 +512,10 @@ enum MOZ_ENUM_TYPE(uint32_t) { OBJECT_FLAG_DYNAMIC_MASK | OBJECT_FLAG_SETS_MARKED_UNKNOWN, - // Mask/shift for the kind of addendum attached to this type object. - OBJECT_FLAG_ADDENDUM_MASK = 0x04000000, - OBJECT_FLAG_ADDENDUM_SHIFT = 26, - // Mask/shift for this type object's generation. If out of sync with the // TypeZone's generation, this TypeObject hasn't been swept yet. - OBJECT_FLAG_GENERATION_MASK = 0x08000000, - OBJECT_FLAG_GENERATION_SHIFT = 27, + OBJECT_FLAG_GENERATION_MASK = 0x04000000, + OBJECT_FLAG_GENERATION_SHIFT = 26, }; typedef uint32_t TypeObjectFlags; @@ -980,6 +976,9 @@ class TypeNewScript js_free(initializerList); } + static inline void writeBarrierPre(TypeNewScript *newScript); + static void writeBarrierPost(TypeNewScript *newScript, void *addr) {} + bool analyzed() const { if (preliminaryObjects) { MOZ_ASSERT(!templateObject()); @@ -1100,27 +1099,12 @@ struct TypeObject : public gc::TenuredCell /* Flags for this object. */ TypeObjectFlags flags_; - enum AddendumKind { - Addendum_NewScript, - Addendum_TypeDescr - }; - - // If non-null, holds additional information about this object, whose - // format is indicated by the object's addendum kind. - void *addendum_; - - void setAddendum(AddendumKind kind, void *addendum); - - AddendumKind addendumKind() const { - return (AddendumKind) - ((flags_ & OBJECT_FLAG_ADDENDUM_MASK) >> OBJECT_FLAG_ADDENDUM_SHIFT); - } - - TypeNewScript *newScriptDontCheckGeneration() const { - return addendumKind() == Addendum_NewScript - ? reinterpret_cast(addendum_) - : nullptr; - } + /* + * If specified, holds information about properties which are definitely + * added to objects of this type after being constructed by a particular + * script. + */ + HeapPtrTypeNewScript newScript_; public: @@ -1141,23 +1125,10 @@ struct TypeObject : public gc::TenuredCell TypeNewScript *newScript() { maybeSweep(nullptr); - return newScriptDontCheckGeneration(); + return newScript_; } - void setNewScript(TypeNewScript *newScript) { - setAddendum(Addendum_NewScript, newScript); - } - - TypeDescr &typeDescr() { - // Note: there is no need to sweep when accessing the type descriptor - // of an object, as it is strongly held and immutable. - MOZ_ASSERT(addendumKind() == Addendum_TypeDescr); - return *reinterpret_cast(addendum_); - } - - void setTypeDescr(TypeDescr *descr) { - setAddendum(Addendum_TypeDescr, descr); - } + void setNewScript(TypeNewScript *newScript); private: /* @@ -1318,8 +1289,8 @@ struct TypeObject : public gc::TenuredCell return offsetof(TypeObject, proto_); } - static inline uint32_t offsetOfAddendum() { - return offsetof(TypeObject, addendum_); + static inline uint32_t offsetOfNewScript() { + return offsetof(TypeObject, newScript_); } static inline uint32_t offsetOfFlags() { @@ -1336,50 +1307,49 @@ struct TypeObject : public gc::TenuredCell }; /* - * Entries for the per-compartment set of type objects which are the default - * types to use for some prototype. An optional associated object is used which - * allows multiple type objects to be created with the same prototype. The - * associated object may be a function (for types constructed with 'new') or a - * type descriptor (for typed objects). These entries are also used for the set - * of lazy type objects in the compartment, which use a null associated object - * (though there are only a few of these per compartment). + * Entries for the per-compartment set of type objects which are 'new' types to + * use for some prototype and constructed with an optional script. This also + * includes entries for the set of lazy type objects in the compartment, which + * use a null script (though there are only a few of these per compartment). */ -struct NewTypeObjectEntry +struct TypeObjectWithNewScriptEntry { ReadBarrieredTypeObject object; // Note: This pointer is only used for equality and does not need a read barrier. - JSObject *associated; + JSFunction *newFunction; - NewTypeObjectEntry(TypeObject *object, JSObject *associated) - : object(object), associated(associated) + TypeObjectWithNewScriptEntry(TypeObject *object, JSFunction *newFunction) + : object(object), newFunction(newFunction) {} struct Lookup { const Class *clasp; TaggedProto hashProto; TaggedProto matchProto; - JSObject *associated; + JSFunction *newFunction; - Lookup(const Class *clasp, TaggedProto proto, JSObject *associated) - : clasp(clasp), hashProto(proto), matchProto(proto), associated(associated) + Lookup(const Class *clasp, TaggedProto proto, JSFunction *newFunction) + : clasp(clasp), hashProto(proto), matchProto(proto), newFunction(newFunction) {} /* * For use by generational post barriers only. Look up an entry whose * proto has been moved, but was hashed with the original value. */ - Lookup(const Class *clasp, TaggedProto hashProto, TaggedProto matchProto, JSObject *associated) - : clasp(clasp), hashProto(hashProto), matchProto(matchProto), associated(associated) + Lookup(const Class *clasp, TaggedProto hashProto, TaggedProto matchProto, JSFunction *newFunction) + : clasp(clasp), hashProto(hashProto), matchProto(matchProto), newFunction(newFunction) {} }; static inline HashNumber hash(const Lookup &lookup); - static inline bool match(const NewTypeObjectEntry &key, const Lookup &lookup); - static void rekey(NewTypeObjectEntry &k, const NewTypeObjectEntry& newKey) { k = newKey; } + static inline bool match(const TypeObjectWithNewScriptEntry &key, const Lookup &lookup); + static void rekey(TypeObjectWithNewScriptEntry &k, const TypeObjectWithNewScriptEntry& newKey) { k = newKey; } }; -typedef HashSet NewTypeObjectTable; +typedef HashSet TypeObjectWithNewScriptSet; /* Whether to use a new type object when calling 'new' at script/pc. */ bool diff --git a/js/src/jsinferinlines.h b/js/src/jsinferinlines.h index 8fdd8c869441..2c8198078a88 100644 --- a/js/src/jsinferinlines.h +++ b/js/src/jsinferinlines.h @@ -1208,7 +1208,7 @@ inline TypeObject::TypeObject(const Class *clasp, TaggedProto proto, TypeObjectF inline void TypeObject::finalize(FreeOp *fop) { - fop->delete_(newScriptDontCheckGeneration()); + fop->delete_(newScript_.get()); } inline uint32_t @@ -1300,6 +1300,17 @@ TypeObject::getProperty(unsigned i) return propertySet[i]; } +inline void +TypeNewScript::writeBarrierPre(TypeNewScript *newScript) +{ + if (!newScript || !newScript->fun->runtimeFromAnyThread()->needsIncrementalBarrier()) + return; + + JS::Zone *zone = newScript->fun->zoneFromAnyThread(); + if (zone->needsIncrementalBarrier()) + newScript->trace(zone->barrierTracer()); +} + } } /* namespace js::types */ inline js::types::TypeScript * diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp index 07bbc0c26e90..c7f43ef49cb8 100644 --- a/js/src/vm/SelfHosting.cpp +++ b/js/src/vm/SelfHosting.cpp @@ -1166,9 +1166,6 @@ static const JSFunctionSpec intrinsic_functions[] = { JS_FNINFO("TypedObjectIsAttached", JSNativeThreadSafeWrapper, &js::TypedObjectIsAttachedJitInfo, 1, 0), - JS_FNINFO("TypedObjectTypeDescr", - JSNativeThreadSafeWrapper, - &js::TypedObjectTypeDescrJitInfo, 1, 0), JS_FNINFO("ObjectIsOpaqueTypedObject", intrinsic_ObjectIsOpaqueTypedObject, &js::ObjectIsOpaqueTypedObjectJitInfo, 1, 0),