зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1288909, part 1 - Implement refcounting of XPCNativeSet. r=billm
This patch is similar to bug 1288870. Strong references: - XPCCallContext::mSet: Like XPCNativeInterface, this only roots it when |mState >= HAVE_NAME|, and again this only requires changing SystemIsBeingShutDown(). - XPCWrappedNativeProto::mSet and XPCWrappedNative::mSet. These become RefPtrs. - stack: AutoMarkingNativeSetPtr become RefPtr<XPCNativeSet>. This lets me eliminate some uses of AutoJSContext. This is the bulk of the patch. Weak references: - mNativeSetMap. This reference gets cleared in the dtor. This requires bug 1290239 to actually find the entry for removal. - mClassInfo2NativeSetMap. The reference is in the value for this hash table, and we don't have the key in the set dtor. Fortunately, the only code that adds to this table is XPCNativeSet::GetNewOrUsed(nsIClassInfo* classInfo), which in turn is only called by GetNewOrUsed(nsIClassInfo* classInfo). This code creates a new XPCWrappedNativeProto, which (with my patch) holds a strong reference to the set that has been added to the table. This set is never changed or released until the dtor for the proto, which calls ClearCacheEntryForClassInfo(), removing the entry from the hashtable. Thus, the lifetime of the set is always going to be longer than the lifetime of the entry. Other notes: - Like XPCNativeInterface, this class uses placement |new| that requires a special destruction function, which with my patch is hidden away in the refcounting code. - This patch delete a bunch of marking/sweeping code from XPCJSRuntime::FinalizeCallback(), because the lifetimes are managed by the refcounting now. Some of the marking code is left behind to be cleaned up in a later patch. - I didn't see any methods that had XPCNativeSet** outparams. - MOZ_COUNT_{CTOR,DTOR}(XPCNativeSet) is not needed because it is now refcounted. MozReview-Commit-ID: 7oTorCwda1n --HG-- extra : rebase_source : 0c477e18c405e4ea88393279cf8bea62c5b0f4c7
This commit is contained in:
Родитель
bd57d227da
Коммит
bbaa5c3f54
|
@ -199,6 +199,7 @@ XPCCallContext::SystemIsBeingShutDown()
|
|||
NS_WARNING("Shutting Down XPConnect even through there is a live XPCCallContext");
|
||||
mXPCJSContext = nullptr;
|
||||
mState = SYSTEM_SHUTDOWN;
|
||||
mSet = nullptr;
|
||||
mInterface = nullptr;
|
||||
|
||||
if (mPrevCallContext)
|
||||
|
|
|
@ -820,37 +820,6 @@ XPCJSContext::FinalizeCallback(JSFreeOp* fop,
|
|||
}
|
||||
}
|
||||
|
||||
// Do the sweeping. During a zone GC, only WrappedNativeProtos in
|
||||
// collected zones will be marked. Therefore, some reachable
|
||||
// NativeInterfaces will not be marked, so it is not safe to sweep
|
||||
// them. We still need to unmark them, since the ones pointed to by
|
||||
// WrappedNativeProtos in a zone being collected will be marked.
|
||||
//
|
||||
// Ideally, if NativeInterfaces from different zones were kept
|
||||
// separate, we could sweep only the ones belonging to zones being
|
||||
// collected. Currently, though, NativeInterfaces are shared between
|
||||
// zones. This ought to be fixed.
|
||||
bool doSweep = !isZoneGC;
|
||||
|
||||
if (doSweep) {
|
||||
for (auto i = self->mClassInfo2NativeSetMap->Iter(); !i.Done(); i.Next()) {
|
||||
auto entry = static_cast<ClassInfo2NativeSetMap::Entry*>(i.Get());
|
||||
if (!entry->value->IsMarked())
|
||||
i.Remove();
|
||||
}
|
||||
}
|
||||
|
||||
for (auto i = self->mNativeSetMap->Iter(); !i.Done(); i.Next()) {
|
||||
auto entry = static_cast<NativeSetMap::Entry*>(i.Get());
|
||||
XPCNativeSet* set = entry->key_value;
|
||||
if (set->IsMarked()) {
|
||||
set->Unmark();
|
||||
} else if (doSweep) {
|
||||
XPCNativeSet::DestroyInstance(set);
|
||||
i.Remove();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
XPCWrappedNativeScope::ASSERT_NoInterfaceSetsAreMarked();
|
||||
#endif
|
||||
|
|
|
@ -310,8 +310,6 @@ public:
|
|||
|
||||
inline uint32_t Count() { return mTable.EntryCount(); }
|
||||
|
||||
PLDHashTable::Iterator Iter() { return mTable.Iter(); }
|
||||
|
||||
// ClassInfo2NativeSetMap holds pointers to *some* XPCNativeSets.
|
||||
// So we don't want to count those XPCNativeSets, because they are better
|
||||
// counted elsewhere (i.e. in XPCJSContext::mNativeSetMap, which holds
|
||||
|
|
|
@ -431,15 +431,15 @@ XPCWrappedNative::GetNewOrUsed(xpcObjectHelper& helper,
|
|||
if (!iface)
|
||||
iface = XPCNativeInterface::GetISupports();
|
||||
|
||||
AutoMarkingNativeSetPtr set(cx);
|
||||
XPCNativeSetKey key(iface);
|
||||
set = XPCNativeSet::GetNewOrUsed(&key);
|
||||
RefPtr<XPCNativeSet> set =
|
||||
XPCNativeSet::GetNewOrUsed(&key);
|
||||
|
||||
if (!set)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
wrapper =
|
||||
new XPCWrappedNative(helper.forgetCanonical(), Scope, set);
|
||||
wrapper = new XPCWrappedNative(helper.forgetCanonical(), Scope,
|
||||
set.forget());
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(parent),
|
||||
|
@ -566,7 +566,7 @@ XPCWrappedNative::XPCWrappedNative(already_AddRefed<nsISupports>&& aIdentity,
|
|||
// This ctor is used if this object will NOT have a proto.
|
||||
XPCWrappedNative::XPCWrappedNative(already_AddRefed<nsISupports>&& aIdentity,
|
||||
XPCWrappedNativeScope* aScope,
|
||||
XPCNativeSet* aSet)
|
||||
already_AddRefed<XPCNativeSet>&& aSet)
|
||||
|
||||
: mMaybeScope(TagScope(aScope)),
|
||||
mSet(aSet),
|
||||
|
@ -578,7 +578,7 @@ XPCWrappedNative::XPCWrappedNative(already_AddRefed<nsISupports>&& aIdentity,
|
|||
mFlatJSObject.setFlags(FLAT_JS_OBJECT_VALID);
|
||||
|
||||
MOZ_ASSERT(aScope, "bad ctor param");
|
||||
MOZ_ASSERT(aSet, "bad ctor param");
|
||||
MOZ_ASSERT(mSet, "bad ctor param");
|
||||
}
|
||||
|
||||
XPCWrappedNative::~XPCWrappedNative()
|
||||
|
@ -1014,16 +1014,14 @@ private:
|
|||
bool
|
||||
XPCWrappedNative::ExtendSet(XPCNativeInterface* aInterface)
|
||||
{
|
||||
AutoJSContext cx;
|
||||
|
||||
if (!mSet->HasInterface(aInterface)) {
|
||||
AutoMarkingNativeSetPtr newSet(cx);
|
||||
XPCNativeSetKey key(mSet, aInterface);
|
||||
newSet = XPCNativeSet::GetNewOrUsed(&key);
|
||||
RefPtr<XPCNativeSet> newSet =
|
||||
XPCNativeSet::GetNewOrUsed(&key);
|
||||
if (!newSet)
|
||||
return false;
|
||||
|
||||
mSet = newSet;
|
||||
mSet = newSet.forget();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -2164,7 +2162,7 @@ NS_IMETHODIMP XPCWrappedNative::DebugDump(int16_t depth)
|
|||
if (depth && mSet)
|
||||
mSet->DebugDump(depth);
|
||||
else
|
||||
XPC_LOG_ALWAYS(("mSet @ %x", mSet));
|
||||
XPC_LOG_ALWAYS(("mSet @ %x", mSet.get()));
|
||||
|
||||
XPC_LOG_ALWAYS(("mFlatJSObject of %x", mFlatJSObject.getPtr()));
|
||||
XPC_LOG_ALWAYS(("mIdentity of %x", mIdentity.get()));
|
||||
|
|
|
@ -462,13 +462,21 @@ XPCNativeSetKey::Hash() const
|
|||
/***************************************************************************/
|
||||
// XPCNativeSet
|
||||
|
||||
XPCNativeSet::~XPCNativeSet()
|
||||
{
|
||||
// Remove |this| before we clear the interfaces to ensure that the
|
||||
// hashtable look up is correct.
|
||||
XPCJSContext::Get()->GetNativeSetMap()->Remove(this);
|
||||
|
||||
for (int i = 0; i < mInterfaceCount; i++) {
|
||||
NS_RELEASE(mInterfaces[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
XPCNativeSet*
|
||||
already_AddRefed<XPCNativeSet>
|
||||
XPCNativeSet::GetNewOrUsed(const nsIID* iid)
|
||||
{
|
||||
AutoJSContext cx;
|
||||
AutoMarkingNativeSetPtr set(cx);
|
||||
|
||||
RefPtr<XPCNativeInterface> iface =
|
||||
XPCNativeInterface::GetNewOrUsed(iid);
|
||||
if (!iface)
|
||||
|
@ -481,10 +489,10 @@ XPCNativeSet::GetNewOrUsed(const nsIID* iid)
|
|||
if (!map)
|
||||
return nullptr;
|
||||
|
||||
set = map->Find(&key);
|
||||
RefPtr<XPCNativeSet> set = map->Find(&key);
|
||||
|
||||
if (set)
|
||||
return set;
|
||||
return set.forget();
|
||||
|
||||
set = NewInstance({iface.forget()});
|
||||
if (!set)
|
||||
|
@ -492,29 +500,25 @@ XPCNativeSet::GetNewOrUsed(const nsIID* iid)
|
|||
|
||||
if (!map->AddNew(&key, set)) {
|
||||
NS_ERROR("failed to add our set!");
|
||||
DestroyInstance(set);
|
||||
set = nullptr;
|
||||
}
|
||||
|
||||
return set;
|
||||
return set.forget();
|
||||
}
|
||||
|
||||
// static
|
||||
XPCNativeSet*
|
||||
already_AddRefed<XPCNativeSet>
|
||||
XPCNativeSet::GetNewOrUsed(nsIClassInfo* classInfo)
|
||||
{
|
||||
AutoJSContext cx;
|
||||
AutoMarkingNativeSetPtr set(cx);
|
||||
XPCJSContext* xpccx = XPCJSContext::Get();
|
||||
|
||||
ClassInfo2NativeSetMap* map = xpccx->GetClassInfo2NativeSetMap();
|
||||
if (!map)
|
||||
return nullptr;
|
||||
|
||||
set = map->Find(classInfo);
|
||||
RefPtr<XPCNativeSet> set = map->Find(classInfo);
|
||||
|
||||
if (set)
|
||||
return set;
|
||||
return set.forget();
|
||||
|
||||
nsIID** iidArray = nullptr;
|
||||
uint32_t iidCount = 0;
|
||||
|
@ -567,14 +571,12 @@ XPCNativeSet::GetNewOrUsed(nsIClassInfo* classInfo)
|
|||
XPCNativeSet* set2 = map2->Add(&key, set);
|
||||
if (!set2) {
|
||||
NS_ERROR("failed to add our set!");
|
||||
DestroyInstance(set);
|
||||
set = nullptr;
|
||||
goto out;
|
||||
}
|
||||
// It is okay to find an existing entry here because
|
||||
// we did not look for one before we called Add().
|
||||
if (set2 != set) {
|
||||
DestroyInstance(set);
|
||||
set = set2;
|
||||
}
|
||||
}
|
||||
|
@ -596,7 +598,7 @@ out:
|
|||
if (iidArray)
|
||||
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(iidCount, iidArray);
|
||||
|
||||
return set;
|
||||
return set.forget();
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -610,20 +612,17 @@ XPCNativeSet::ClearCacheEntryForClassInfo(nsIClassInfo* classInfo)
|
|||
}
|
||||
|
||||
// static
|
||||
XPCNativeSet*
|
||||
already_AddRefed<XPCNativeSet>
|
||||
XPCNativeSet::GetNewOrUsed(XPCNativeSetKey* key)
|
||||
{
|
||||
AutoJSContext cx;
|
||||
AutoMarkingNativeSetPtr set(cx);
|
||||
XPCJSContext* xpccx = XPCJSContext::Get();
|
||||
NativeSetMap* map = xpccx->GetNativeSetMap();
|
||||
NativeSetMap* map = XPCJSContext::Get()->GetNativeSetMap();
|
||||
if (!map)
|
||||
return nullptr;
|
||||
|
||||
set = map->Find(key);
|
||||
RefPtr<XPCNativeSet> set = map->Find(key);
|
||||
|
||||
if (set)
|
||||
return set;
|
||||
return set.forget();
|
||||
|
||||
if (key->GetBaseSet())
|
||||
set = NewInstanceMutate(key);
|
||||
|
@ -635,15 +634,14 @@ XPCNativeSet::GetNewOrUsed(XPCNativeSetKey* key)
|
|||
|
||||
if (!map->AddNew(key, set)) {
|
||||
NS_ERROR("failed to add our set!");
|
||||
DestroyInstance(set);
|
||||
set = nullptr;
|
||||
}
|
||||
|
||||
return set;
|
||||
return set.forget();
|
||||
}
|
||||
|
||||
// static
|
||||
XPCNativeSet*
|
||||
already_AddRefed<XPCNativeSet>
|
||||
XPCNativeSet::GetNewOrUsed(XPCNativeSet* firstSet,
|
||||
XPCNativeSet* secondSet,
|
||||
bool preserveFirstSetOrder)
|
||||
|
@ -658,12 +656,12 @@ XPCNativeSet::GetNewOrUsed(XPCNativeSet* firstSet,
|
|||
// If everything in secondSet was a duplicate, we can just use the first
|
||||
// set.
|
||||
if (uniqueCount == firstSet->mInterfaceCount)
|
||||
return firstSet;
|
||||
return RefPtr<XPCNativeSet>(firstSet).forget();
|
||||
|
||||
// If the secondSet is just a superset of the first, we can use it provided
|
||||
// that the caller doesn't care about ordering.
|
||||
if (!preserveFirstSetOrder && uniqueCount == secondSet->mInterfaceCount)
|
||||
return secondSet;
|
||||
return RefPtr<XPCNativeSet>(secondSet).forget();
|
||||
|
||||
// Ok, darn. Now we have to make a new set.
|
||||
//
|
||||
|
@ -672,7 +670,7 @@ XPCNativeSet::GetNewOrUsed(XPCNativeSet* firstSet,
|
|||
// a lot of stuff assumes that sets are created by adding one interface to an
|
||||
// existing set. So let's just do the slow and easy thing and hope that the
|
||||
// above optimizations handle the common cases.
|
||||
XPCNativeSet* currentSet = firstSet;
|
||||
RefPtr<XPCNativeSet> currentSet = firstSet;
|
||||
for (uint32_t i = 0; i < secondSet->mInterfaceCount; ++i) {
|
||||
XPCNativeInterface* iface = secondSet->mInterfaces[i];
|
||||
if (!currentSet->HasInterface(iface)) {
|
||||
|
@ -686,11 +684,11 @@ XPCNativeSet::GetNewOrUsed(XPCNativeSet* firstSet,
|
|||
|
||||
// We've got the union set. Hand it back to the caller.
|
||||
MOZ_ASSERT(currentSet->mInterfaceCount == uniqueCount);
|
||||
return currentSet;
|
||||
return currentSet.forget();
|
||||
}
|
||||
|
||||
// static
|
||||
XPCNativeSet*
|
||||
already_AddRefed<XPCNativeSet>
|
||||
XPCNativeSet::NewInstance(nsTArray<RefPtr<XPCNativeInterface>>&& array)
|
||||
{
|
||||
if (array.Length() == 0)
|
||||
|
@ -715,7 +713,7 @@ XPCNativeSet::NewInstance(nsTArray<RefPtr<XPCNativeInterface>>&& array)
|
|||
if (slots > 1)
|
||||
size += (slots - 1) * sizeof(XPCNativeInterface*);
|
||||
void* place = new char[size];
|
||||
XPCNativeSet* obj = new(place) XPCNativeSet();
|
||||
RefPtr<XPCNativeSet> obj = new(place) XPCNativeSet();
|
||||
|
||||
// Stick the nsISupports in front and skip additional nsISupport(s)
|
||||
XPCNativeInterface** outp = (XPCNativeInterface**) &obj->mInterfaces;
|
||||
|
@ -733,11 +731,11 @@ XPCNativeSet::NewInstance(nsTArray<RefPtr<XPCNativeInterface>>&& array)
|
|||
obj->mMemberCount = memberCount;
|
||||
obj->mInterfaceCount = slots;
|
||||
|
||||
return obj;
|
||||
return obj.forget();
|
||||
}
|
||||
|
||||
// static
|
||||
XPCNativeSet*
|
||||
already_AddRefed<XPCNativeSet>
|
||||
XPCNativeSet::NewInstanceMutate(XPCNativeSetKey* key)
|
||||
{
|
||||
XPCNativeSet* otherSet = key->GetBaseSet();
|
||||
|
@ -753,7 +751,7 @@ XPCNativeSet::NewInstanceMutate(XPCNativeSetKey* key)
|
|||
int size = sizeof(XPCNativeSet);
|
||||
size += otherSet->mInterfaceCount * sizeof(XPCNativeInterface*);
|
||||
void* place = new char[size];
|
||||
XPCNativeSet* obj = new(place) XPCNativeSet();
|
||||
RefPtr<XPCNativeSet> obj = new(place) XPCNativeSet();
|
||||
|
||||
obj->mMemberCount = otherSet->GetMemberCount() +
|
||||
newInterface->GetMemberCount();
|
||||
|
@ -766,7 +764,7 @@ XPCNativeSet::NewInstanceMutate(XPCNativeSetKey* key)
|
|||
}
|
||||
NS_ADDREF(*dest++ = newInterface);
|
||||
|
||||
return obj;
|
||||
return obj.forget();
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
|
@ -17,7 +17,7 @@ int32_t XPCWrappedNativeProto::gDEBUG_LiveProtoCount = 0;
|
|||
|
||||
XPCWrappedNativeProto::XPCWrappedNativeProto(XPCWrappedNativeScope* Scope,
|
||||
nsIClassInfo* ClassInfo,
|
||||
XPCNativeSet* Set)
|
||||
already_AddRefed<XPCNativeSet>&& Set)
|
||||
: mScope(Scope),
|
||||
mJSProtoObject(nullptr),
|
||||
mClassInfo(ClassInfo),
|
||||
|
@ -166,12 +166,11 @@ XPCWrappedNativeProto::GetNewOrUsed(XPCWrappedNativeScope* scope,
|
|||
if (proto)
|
||||
return proto;
|
||||
|
||||
AutoMarkingNativeSetPtr set(cx);
|
||||
set = XPCNativeSet::GetNewOrUsed(classInfo);
|
||||
RefPtr<XPCNativeSet> set = XPCNativeSet::GetNewOrUsed(classInfo);
|
||||
if (!set)
|
||||
return nullptr;
|
||||
|
||||
proto = new XPCWrappedNativeProto(scope, classInfo, set);
|
||||
proto = new XPCWrappedNativeProto(scope, classInfo, set.forget());
|
||||
|
||||
if (!proto || !proto->Init(scriptableCreateInfo, callPostCreatePrototype)) {
|
||||
delete proto.get();
|
||||
|
@ -193,7 +192,7 @@ XPCWrappedNativeProto::DebugDump(int16_t depth)
|
|||
XPC_LOG_ALWAYS(("gDEBUG_LiveProtoCount is %d", gDEBUG_LiveProtoCount));
|
||||
XPC_LOG_ALWAYS(("mScope @ %x", mScope));
|
||||
XPC_LOG_ALWAYS(("mJSProtoObject @ %x", mJSProtoObject.get()));
|
||||
XPC_LOG_ALWAYS(("mSet @ %x", mSet));
|
||||
XPC_LOG_ALWAYS(("mSet @ %x", mSet.get()));
|
||||
XPC_LOG_ALWAYS(("mScriptableInfo @ %x", mScriptableInfo));
|
||||
if (depth && mScriptableInfo) {
|
||||
XPC_LOG_INDENT();
|
||||
|
|
|
@ -793,7 +793,7 @@ private:
|
|||
|
||||
XPCNativeScriptableInfo* mScriptableInfo;
|
||||
|
||||
XPCNativeSet* mSet;
|
||||
RefPtr<XPCNativeSet> mSet;
|
||||
RefPtr<XPCNativeInterface> mInterface;
|
||||
XPCNativeMember* mMember;
|
||||
|
||||
|
@ -1281,7 +1281,7 @@ private:
|
|||
// It represents a new XPCNativeSet we are considering constructing, without
|
||||
// requiring that the set actually be built.
|
||||
|
||||
class XPCNativeSetKey final
|
||||
class MOZ_STACK_CLASS XPCNativeSetKey final
|
||||
{
|
||||
public:
|
||||
// This represents an existing set |baseSet|.
|
||||
|
@ -1314,8 +1314,8 @@ public:
|
|||
// Allow shallow copy
|
||||
|
||||
private:
|
||||
XPCNativeSet* mBaseSet;
|
||||
XPCNativeInterface* mAddition;
|
||||
RefPtr<XPCNativeSet> mBaseSet;
|
||||
RefPtr<XPCNativeInterface> mAddition;
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -1324,9 +1324,12 @@ private:
|
|||
class XPCNativeSet final
|
||||
{
|
||||
public:
|
||||
static XPCNativeSet* GetNewOrUsed(const nsIID* iid);
|
||||
static XPCNativeSet* GetNewOrUsed(nsIClassInfo* classInfo);
|
||||
static XPCNativeSet* GetNewOrUsed(XPCNativeSetKey* key);
|
||||
NS_INLINE_DECL_REFCOUNTING_WITH_DESTROY(XPCNativeSet,
|
||||
DestroyInstance(this))
|
||||
|
||||
static already_AddRefed<XPCNativeSet> GetNewOrUsed(const nsIID* iid);
|
||||
static already_AddRefed<XPCNativeSet> GetNewOrUsed(nsIClassInfo* classInfo);
|
||||
static already_AddRefed<XPCNativeSet> GetNewOrUsed(XPCNativeSetKey* key);
|
||||
|
||||
// This generates a union set.
|
||||
//
|
||||
|
@ -1335,9 +1338,9 @@ class XPCNativeSet final
|
|||
// algorithm is applied; but if we detect that |secondSet| is a superset of
|
||||
// |firstSet|, we return |secondSet| without worrying about whether the
|
||||
// ordering might differ from |firstSet|.
|
||||
static XPCNativeSet* GetNewOrUsed(XPCNativeSet* firstSet,
|
||||
XPCNativeSet* secondSet,
|
||||
bool preserveFirstSetOrder);
|
||||
static already_AddRefed<XPCNativeSet> GetNewOrUsed(XPCNativeSet* firstSet,
|
||||
XPCNativeSet* secondSet,
|
||||
bool preserveFirstSetOrder);
|
||||
|
||||
static void ClearCacheEntryForClassInfo(nsIClassInfo* classInfo);
|
||||
|
||||
|
@ -1388,7 +1391,7 @@ class XPCNativeSet final
|
|||
mMarked = 0;
|
||||
}
|
||||
bool IsMarked() const {
|
||||
return !!mMarked;
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -1397,26 +1400,20 @@ class XPCNativeSet final
|
|||
|
||||
void DebugDump(int16_t depth);
|
||||
|
||||
static void DestroyInstance(XPCNativeSet* inst);
|
||||
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf);
|
||||
|
||||
protected:
|
||||
static XPCNativeSet* NewInstance(nsTArray<RefPtr<XPCNativeInterface>>&& array);
|
||||
static XPCNativeSet* NewInstanceMutate(XPCNativeSetKey* key);
|
||||
static already_AddRefed<XPCNativeSet> NewInstance(nsTArray<RefPtr<XPCNativeInterface>>&& array);
|
||||
static already_AddRefed<XPCNativeSet> NewInstanceMutate(XPCNativeSetKey* key);
|
||||
|
||||
XPCNativeSet()
|
||||
: mMemberCount(0), mInterfaceCount(0), mMarked(0)
|
||||
{
|
||||
MOZ_COUNT_CTOR(XPCNativeSet);
|
||||
}
|
||||
~XPCNativeSet() {
|
||||
for (int i = 0; i < mInterfaceCount; i++) {
|
||||
NS_RELEASE(mInterfaces[i]);
|
||||
}
|
||||
MOZ_COUNT_DTOR(XPCNativeSet);
|
||||
}
|
||||
{}
|
||||
~XPCNativeSet();
|
||||
void* operator new(size_t, void* p) CPP_THROW_NEW {return p;}
|
||||
|
||||
static void DestroyInstance(XPCNativeSet* inst);
|
||||
|
||||
private:
|
||||
uint16_t mMemberCount;
|
||||
uint16_t mInterfaceCount : 15;
|
||||
|
@ -1690,7 +1687,7 @@ protected:
|
|||
// hide ctor
|
||||
XPCWrappedNativeProto(XPCWrappedNativeScope* Scope,
|
||||
nsIClassInfo* ClassInfo,
|
||||
XPCNativeSet* Set);
|
||||
already_AddRefed<XPCNativeSet>&& Set);
|
||||
|
||||
bool Init(const XPCNativeScriptableCreateInfo* scriptableCreateInfo,
|
||||
bool callPostCreatePrototype);
|
||||
|
@ -1704,7 +1701,7 @@ private:
|
|||
XPCWrappedNativeScope* mScope;
|
||||
JS::ObjectPtr mJSProtoObject;
|
||||
nsCOMPtr<nsIClassInfo> mClassInfo;
|
||||
XPCNativeSet* mSet;
|
||||
RefPtr<XPCNativeSet> mSet;
|
||||
XPCNativeScriptableInfo* mScriptableInfo;
|
||||
};
|
||||
|
||||
|
@ -1856,7 +1853,7 @@ public:
|
|||
GetSet() const {return mSet;}
|
||||
|
||||
void
|
||||
SetSet(XPCNativeSet* set) {mSet = set;}
|
||||
SetSet(already_AddRefed<XPCNativeSet> set) {mSet = set;}
|
||||
|
||||
static XPCWrappedNative* Get(JSObject* obj) {
|
||||
MOZ_ASSERT(IS_WN_REFLECTOR(obj));
|
||||
|
@ -1999,7 +1996,7 @@ protected:
|
|||
// This ctor is used if this object will NOT have a proto.
|
||||
XPCWrappedNative(already_AddRefed<nsISupports>&& aIdentity,
|
||||
XPCWrappedNativeScope* aScope,
|
||||
XPCNativeSet* aSet);
|
||||
already_AddRefed<XPCNativeSet>&& aSet);
|
||||
|
||||
virtual ~XPCWrappedNative();
|
||||
void Destroy();
|
||||
|
@ -2035,7 +2032,7 @@ private:
|
|||
XPCWrappedNativeScope* mMaybeScope;
|
||||
XPCWrappedNativeProto* mMaybeProto;
|
||||
};
|
||||
XPCNativeSet* mSet;
|
||||
RefPtr<XPCNativeSet> mSet;
|
||||
JS::TenuredHeap<JSObject*> mFlatJSObject;
|
||||
XPCNativeScriptableInfo* mScriptableInfo;
|
||||
XPCWrappedNativeTearOff mFirstTearOff;
|
||||
|
@ -2881,7 +2878,6 @@ class TypedAutoMarkingPtr : public AutoMarkingPtr
|
|||
T* mPtr;
|
||||
};
|
||||
|
||||
typedef TypedAutoMarkingPtr<XPCNativeSet> AutoMarkingNativeSetPtr;
|
||||
typedef TypedAutoMarkingPtr<XPCWrappedNative> AutoMarkingWrappedNativePtr;
|
||||
typedef TypedAutoMarkingPtr<XPCWrappedNativeTearOff> AutoMarkingWrappedNativeTearOffPtr;
|
||||
typedef TypedAutoMarkingPtr<XPCWrappedNativeProto> AutoMarkingWrappedNativeProtoPtr;
|
||||
|
|
|
@ -313,12 +313,12 @@ WrapperFactory::PrepareForWrapping(JSContext* cx, HandleObject scope,
|
|||
// give the destination object the union of the two native sets. We try
|
||||
// to do this cleverly in the common case to avoid too much overhead.
|
||||
XPCWrappedNative* newwn = XPCWrappedNative::Get(obj);
|
||||
XPCNativeSet* unionSet = XPCNativeSet::GetNewOrUsed(newwn->GetSet(),
|
||||
wn->GetSet(), false);
|
||||
RefPtr<XPCNativeSet> unionSet = XPCNativeSet::GetNewOrUsed(newwn->GetSet(),
|
||||
wn->GetSet(), false);
|
||||
if (!unionSet) {
|
||||
return;
|
||||
}
|
||||
newwn->SetSet(unionSet);
|
||||
newwn->SetSet(unionSet.forget());
|
||||
|
||||
retObj.set(waive ? WaiveXray(cx, obj) : obj);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче