зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1709695 - Only init PropertyInfos and sort IDs for resolving Xray properties once needed. r=nika
Most of the time, a lot of the WebIDL interfaces are never used with Xray wrappers. We still always initialise the necessary PropertyInfo arrays whenever they're used normally (not through Xray wrappers). I think we should postpone that initialisation until we're actually going to use them with Xray wrappers. Differential Revision: https://phabricator.services.mozilla.com/D114402
This commit is contained in:
Родитель
ef4c757f2c
Коммит
2ffa0654be
|
@ -1275,8 +1275,8 @@ static inline JSPropertySpec::Name ToPropertySpecName(const char* name) {
|
|||
}
|
||||
|
||||
template <typename SpecT>
|
||||
static bool InitIdsInternal(JSContext* cx, const Prefable<SpecT>* pref,
|
||||
PropertyInfo* infos, PropertyType type) {
|
||||
static bool InitPropertyInfos(JSContext* cx, const Prefable<SpecT>* pref,
|
||||
PropertyInfo* infos, PropertyType type) {
|
||||
MOZ_ASSERT(pref);
|
||||
MOZ_ASSERT(pref->specs);
|
||||
|
||||
|
@ -1308,24 +1308,25 @@ static bool InitIdsInternal(JSContext* cx, const Prefable<SpecT>* pref,
|
|||
return true;
|
||||
}
|
||||
|
||||
#define INIT_IDS_IF_DEFINED(TypeName) \
|
||||
{ \
|
||||
if (nativeProperties->Has##TypeName##s() && \
|
||||
!InitIdsInternal(cx, nativeProperties->TypeName##s(), \
|
||||
nativeProperties->TypeName##PropertyInfos(), \
|
||||
e##TypeName)) { \
|
||||
return false; \
|
||||
} \
|
||||
#define INIT_PROPERTY_INFOS_IF_DEFINED(TypeName) \
|
||||
{ \
|
||||
if (nativeProperties->Has##TypeName##s() && \
|
||||
!InitPropertyInfos(cx, nativeProperties->TypeName##s(), \
|
||||
nativeProperties->TypeName##PropertyInfos(), \
|
||||
e##TypeName)) { \
|
||||
return false; \
|
||||
} \
|
||||
}
|
||||
|
||||
bool InitIds(JSContext* cx, const NativeProperties* nativeProperties) {
|
||||
INIT_IDS_IF_DEFINED(StaticMethod);
|
||||
INIT_IDS_IF_DEFINED(StaticAttribute);
|
||||
INIT_IDS_IF_DEFINED(Method);
|
||||
INIT_IDS_IF_DEFINED(Attribute);
|
||||
INIT_IDS_IF_DEFINED(UnforgeableMethod);
|
||||
INIT_IDS_IF_DEFINED(UnforgeableAttribute);
|
||||
INIT_IDS_IF_DEFINED(Constant);
|
||||
static bool InitPropertyInfos(JSContext* cx,
|
||||
const NativeProperties* nativeProperties) {
|
||||
INIT_PROPERTY_INFOS_IF_DEFINED(StaticMethod);
|
||||
INIT_PROPERTY_INFOS_IF_DEFINED(StaticAttribute);
|
||||
INIT_PROPERTY_INFOS_IF_DEFINED(Method);
|
||||
INIT_PROPERTY_INFOS_IF_DEFINED(Attribute);
|
||||
INIT_PROPERTY_INFOS_IF_DEFINED(UnforgeableMethod);
|
||||
INIT_PROPERTY_INFOS_IF_DEFINED(UnforgeableAttribute);
|
||||
INIT_PROPERTY_INFOS_IF_DEFINED(Constant);
|
||||
|
||||
// Initialize and sort the index array.
|
||||
uint16_t* indices = nativeProperties->sortedPropertyIndices;
|
||||
|
@ -1341,7 +1342,26 @@ bool InitIds(JSContext* cx, const NativeProperties* nativeProperties) {
|
|||
return true;
|
||||
}
|
||||
|
||||
#undef INIT_IDS_IF_DEFINED
|
||||
#undef INIT_PROPERTY_INFOS_IF_DEFINED
|
||||
|
||||
static inline bool InitPropertyInfos(
|
||||
JSContext* aCx, const NativePropertiesHolder& nativeProperties) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!*nativeProperties.inited) {
|
||||
if (nativeProperties.regular &&
|
||||
!InitPropertyInfos(aCx, nativeProperties.regular)) {
|
||||
return false;
|
||||
}
|
||||
if (nativeProperties.chromeOnly &&
|
||||
!InitPropertyInfos(aCx, nativeProperties.chromeOnly)) {
|
||||
return false;
|
||||
}
|
||||
*nativeProperties.inited = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GetInterfaceImpl(JSContext* aCx, nsIInterfaceRequestor* aRequestor,
|
||||
nsWrapperCache* aCache, JS::Handle<JS::Value> aIID,
|
||||
|
@ -1678,6 +1698,11 @@ static bool ResolvePrototypeOrConstructor(
|
|||
|
||||
const NativePropertiesHolder& nativePropertiesHolder =
|
||||
nativePropertyHooks->mNativeProperties;
|
||||
|
||||
if (!InitPropertyInfos(cx, nativePropertiesHolder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const NativeProperties* nativeProperties = nullptr;
|
||||
const PropertyInfo* found = nullptr;
|
||||
|
||||
|
@ -1949,6 +1974,10 @@ bool XrayOwnNativePropertyKeys(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
|||
const NativePropertiesHolder& nativeProperties =
|
||||
nativePropertyHooks->mNativeProperties;
|
||||
|
||||
if (!InitPropertyInfos(cx, nativeProperties)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (nativeProperties.regular &&
|
||||
!XrayOwnPropertyKeys(cx, wrapper, obj, flags, props, type,
|
||||
nativeProperties.regular)) {
|
||||
|
@ -2053,13 +2082,15 @@ JSObject* GetCachedSlotStorageObjectSlow(JSContext* cx,
|
|||
|
||||
DEFINE_XRAY_EXPANDO_CLASS(, DefaultXrayExpandoObjectClass, 0);
|
||||
|
||||
NativePropertyHooks sEmptyNativePropertyHooks = {nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
{nullptr, nullptr},
|
||||
prototypes::id::_ID_Count,
|
||||
constructors::id::_ID_Count,
|
||||
nullptr};
|
||||
bool sEmptyNativePropertiesInited = true;
|
||||
NativePropertyHooks sEmptyNativePropertyHooks = {
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
{nullptr, nullptr, &sEmptyNativePropertiesInited},
|
||||
prototypes::id::_ID_Count,
|
||||
constructors::id::_ID_Count,
|
||||
nullptr};
|
||||
|
||||
const JSClassOps sBoringInterfaceObjectClassClassOps = {
|
||||
nullptr, /* addProperty */
|
||||
|
|
|
@ -1770,8 +1770,6 @@ static inline bool AtomizeAndPinJSString(JSContext* cx, jsid& id,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool InitIds(JSContext* cx, const NativeProperties* properties);
|
||||
|
||||
void GetInterfaceImpl(JSContext* aCx, nsIInterfaceRequestor* aRequestor,
|
||||
nsWrapperCache* aCache, JS::Handle<JS::Value> aIID,
|
||||
JS::MutableHandle<JS::Value> aRetval,
|
||||
|
|
|
@ -544,11 +544,12 @@ class CGNativePropertyHooks(CGThing):
|
|||
|
||||
return fill(
|
||||
"""
|
||||
bool sNativePropertiesInited = false;
|
||||
const NativePropertyHooks sNativePropertyHooks[] = { {
|
||||
${resolveOwnProperty},
|
||||
${enumerateOwnProperties},
|
||||
${deleteNamedProperty},
|
||||
{ ${regular}, ${chrome} },
|
||||
{ ${regular}, ${chrome}, &sNativePropertiesInited },
|
||||
${prototypeID},
|
||||
${constructorID},
|
||||
${parentHooks},
|
||||
|
@ -2362,11 +2363,12 @@ class CGLegacyFactoryFunctions(CGThing):
|
|||
|
||||
return fill(
|
||||
"""
|
||||
bool sLegacyFactoryFunctionNativePropertiesInited = true;
|
||||
const NativePropertyHooks sLegacyFactoryFunctionNativePropertyHooks = {
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
{ nullptr, nullptr },
|
||||
{ nullptr, nullptr, &sLegacyFactoryFunctionNativePropertiesInited },
|
||||
prototypes::id::${name},
|
||||
${constructorID},
|
||||
nullptr
|
||||
|
@ -3614,36 +3616,6 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
|
|||
getConstructorProto=getConstructorProto,
|
||||
)
|
||||
|
||||
idsToInit = []
|
||||
# There is no need to init any IDs in bindings that don't want Xrays.
|
||||
if self.descriptor.wantsXrays:
|
||||
if self.properties.hasNonChromeOnly():
|
||||
idsToInit.append("sNativeProperties")
|
||||
if self.properties.hasChromeOnly():
|
||||
idsToInit.append("sChromeOnlyNativeProperties")
|
||||
if len(idsToInit) > 0:
|
||||
initIdCalls = [
|
||||
"!InitIds(aCx, %s.Upcast())" % (properties) for properties in idsToInit
|
||||
]
|
||||
idsInitedFlag = CGGeneric(
|
||||
"static Atomic<bool, Relaxed> sIdsInited(false);\n"
|
||||
)
|
||||
setFlag = CGGeneric("sIdsInited = true;\n")
|
||||
initIdConditionals = [
|
||||
CGIfWrapper(CGGeneric("return;\n"), call) for call in initIdCalls
|
||||
]
|
||||
initIds = CGList(
|
||||
[
|
||||
idsInitedFlag,
|
||||
CGIfWrapper(
|
||||
CGList(initIdConditionals + [setFlag]),
|
||||
"!sIdsInited && NS_IsMainThread()",
|
||||
),
|
||||
]
|
||||
)
|
||||
else:
|
||||
initIds = None
|
||||
|
||||
if self.descriptor.interface.ctor():
|
||||
constructArgs = methodLength(self.descriptor.interface.ctor())
|
||||
else:
|
||||
|
@ -3936,7 +3908,6 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
|
|||
[
|
||||
getParentProto,
|
||||
getConstructorProto,
|
||||
initIds,
|
||||
CGGeneric(call),
|
||||
defineAliases,
|
||||
unforgeableHolderSetup,
|
||||
|
|
|
@ -384,6 +384,11 @@ typedef NativePropertiesN<7> NativeProperties;
|
|||
struct NativePropertiesHolder {
|
||||
const NativeProperties* regular;
|
||||
const NativeProperties* chromeOnly;
|
||||
// Points to a static bool that's set to true once the regular and chromeOnly
|
||||
// NativeProperties have been inited. This is a pointer to a bool instead of
|
||||
// a bool value because NativePropertiesHolder is stored by value in
|
||||
// a static const NativePropertyHooks.
|
||||
bool* inited;
|
||||
};
|
||||
|
||||
// Helper structure for Xrays for DOM binding objects. The same instance is used
|
||||
|
|
Загрузка…
Ссылка в новой задаче