diff --git a/xpcom/build/nsXPCOM.h b/xpcom/build/nsXPCOM.h index 5ff61268d910..5c85e49372c8 100644 --- a/xpcom/build/nsXPCOM.h +++ b/xpcom/build/nsXPCOM.h @@ -39,9 +39,6 @@ extern bool gXPCOMMainThreadEventsAreDoomed; #ifdef __cplusplus # include "nsStringFwd.h" -namespace mozilla { -struct Module; -} // namespace mozilla #endif /** diff --git a/xpcom/build/nsXULAppAPI.h b/xpcom/build/nsXULAppAPI.h index 95e0571ca862..cbe0ab8ed457 100644 --- a/xpcom/build/nsXULAppAPI.h +++ b/xpcom/build/nsXULAppAPI.h @@ -28,7 +28,6 @@ struct XREShellData; namespace mozilla { class XREAppData; struct BootstrapConfig; -struct Module; } // namespace mozilla /** @@ -219,11 +218,6 @@ nsresult XRE_GetFileFromPath(const char* aPath, nsIFile** aResult); */ nsresult XRE_GetBinaryPath(nsIFile** aResult); -/** - * Get the static module built in to libxul. - */ -const mozilla::Module* XRE_GetStaticModule(); - /** * Lock a profile directory using platform-specific semantics. * @@ -257,13 +251,6 @@ nsresult XRE_LockProfileDirectory(nsIFile* aDirectory, nsresult XRE_InitEmbedding2(nsIFile* aLibXULDirectory, nsIFile* aAppDirectory, nsIDirectoryServiceProvider* aAppDirProvider); -/** - * Register static XPCOM component information. - * This method may be called at any time before or after XRE_main or - * XRE_InitEmbedding. - */ -nsresult XRE_AddStaticComponent(const mozilla::Module* aComponent); - /** * Register XPCOM components found in an array of files/directories. * This method may be called at any time before or after XRE_main or diff --git a/xpcom/components/GenericFactory.h b/xpcom/components/GenericFactory.h index 2554057033ca..3fb2186e12cc 100644 --- a/xpcom/components/GenericFactory.h +++ b/xpcom/components/GenericFactory.h @@ -7,9 +7,7 @@ #ifndef mozilla_GenericFactory_h #define mozilla_GenericFactory_h -#include "mozilla/Attributes.h" - -#include "mozilla/Module.h" +#include "nsIFactory.h" namespace mozilla { @@ -19,10 +17,10 @@ namespace mozilla { * module. */ class GenericFactory final : public nsIFactory { - ~GenericFactory() {} + ~GenericFactory() = default; public: - typedef Module::ConstructorProcPtr ConstructorProcPtr; + typedef nsresult (*ConstructorProcPtr)(const nsIID& aIID, void** aResult); NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSIFACTORY diff --git a/xpcom/components/Module.h b/xpcom/components/Module.h index 25c8ff5a2a88..23a9e775414d 100644 --- a/xpcom/components/Module.h +++ b/xpcom/components/Module.h @@ -8,31 +8,12 @@ #define mozilla_Module_h #include "nscore.h" -#include "nsID.h" -#include "nsIFactory.h" -#include "nsCOMPtr.h" // for already_AddRefed namespace mozilla { -/** - * A module implements one or more XPCOM components. This structure is used - * for binary modules. - */ -struct Module { - static const unsigned int kVersion = 103; - - struct CIDEntry; - - typedef already_AddRefed (*GetFactoryProcPtr)( - const Module& module, const CIDEntry& entry); - - typedef nsresult (*ConstructorProcPtr)(const nsIID& aIID, void** aResult); - - typedef nsresult (*LoadFuncPtr)(); - typedef void (*UnloadFuncPtr)(); - +namespace Module { /** - * This selector allows CIDEntrys to be marked so that they're only loaded + * This selector allows components to be marked so that they're only loaded * into certain kinds of processes. Selectors can be combined. */ // Note: This must be kept in sync with the selector matching in @@ -88,76 +69,6 @@ struct Module { NO_TASKS = 0x0, ALL_TASKS = 0xFFFF, }; - - /** - * The constructor callback is an implementation detail of the default binary - * loader and may be null. - */ - struct CIDEntry { - const nsCID* cid; - bool service; - GetFactoryProcPtr getFactoryProc; - ConstructorProcPtr constructorProc; - ProcessSelector processSelector; - }; - - struct ContractIDEntry { - const char* contractid; - nsID const* cid; - ProcessSelector processSelector; - }; - - struct CategoryEntry { - const char* category; - const char* entry; - const char* value; - }; - - /** - * Binary compatibility check, should be kModuleVersion. - */ - unsigned int mVersion; - - /** - * An array of CIDs (class IDs) implemented by this module. The final entry - * should be { nullptr }. - */ - const CIDEntry* mCIDs; - - /** - * An array of mappings from contractid to CID. The final entry should - * be { nullptr }. - */ - const ContractIDEntry* mContractIDs; - - /** - * An array of category manager entries. The final entry should be - * { nullptr }. - */ - const CategoryEntry* mCategoryEntries; - - /** - * When the component manager tries to get the factory for a CID, it first - * checks for this module-level getfactory callback. If this function is - * not implemented, it checks the CIDEntry getfactory callback. If that is - * also nullptr, a generic factory is generated using the CIDEntry - * constructor callback which must be non-nullptr. - */ - GetFactoryProcPtr getFactoryProc; - - /** - * Optional Function which are called when this module is loaded and - * at shutdown. These are not C++ constructor/destructors to avoid - * calling them too early in startup or too late in shutdown. - */ - LoadFuncPtr loadProc; - UnloadFuncPtr unloadProc; - - /** - * Optional flags which control whether the module loads on a process-type - * basis. - */ - ProcessSelector selector; }; } // namespace mozilla diff --git a/xpcom/components/ModuleUtils.h b/xpcom/components/ModuleUtils.h index 77e8cfc8080c..92ec8aa173c2 100644 --- a/xpcom/components/ModuleUtils.h +++ b/xpcom/components/ModuleUtils.h @@ -9,6 +9,7 @@ #include +#include "mozilla/AlreadyAddRefed.h" #include "mozilla/Attributes.h" #include "mozilla/Module.h" diff --git a/xpcom/components/nsComponentManager.cpp b/xpcom/components/nsComponentManager.cpp index 30dbae56345a..b4c7a7ccc000 100644 --- a/xpcom/components/nsComponentManager.cpp +++ b/xpcom/components/nsComponentManager.cpp @@ -163,7 +163,7 @@ class MOZ_STACK_CLASS EntryWrapper final { return mEntry.match((Matcher())) const nsID& CID() { - MATCH(const nsID&, return *entry->mCIDEntry->cid, return entry->CID()); + MATCH(const nsID&, return entry->mCID, return entry->CID()); } already_AddRefed GetFactory() { @@ -202,14 +202,11 @@ class MOZ_STACK_CLASS EntryWrapper final { } /** - * Returns the description string for the module this entry belongs to. For - * static entries, always returns "". + * Returns the description string for the module this entry belongs to. + * Currently always returns "". */ nsCString ModuleDescription() { - MATCH(nsCString, - return entry->mModule ? entry->mModule->Description() - : ""_ns, - return ""_ns); + return ""_ns; } private: @@ -271,17 +268,6 @@ nsComponentManagerImpl::nsComponentManagerImpl() mLock("nsComponentManagerImpl.mLock"), mStatus(NOT_INITIALIZED) {} -static nsTArray* sExtraStaticModules; - -/* static */ -void nsComponentManagerImpl::InitializeStaticModules() { - if (sExtraStaticModules) { - return; - } - - sExtraStaticModules = new nsTArray; -} - nsTArray* nsComponentManagerImpl::sModuleLocations; @@ -350,14 +336,8 @@ nsresult nsComponentManagerImpl::Init() { nsCOMPtr appDir = GetLocationFromDirectoryService(NS_XPCOM_CURRENT_PROCESS_DIR); - InitializeStaticModules(); - nsCategoryManager::GetSingleton()->SuppressNotifications(true); - for (uint32_t i = 0; i < sExtraStaticModules->Length(); ++i) { - RegisterModule((*sExtraStaticModules)[i]); - } - auto* catMan = nsCategoryManager::GetSingleton(); for (const auto& cat : gStaticCategories) { for (const auto& entry : cat) { @@ -468,8 +448,6 @@ nsresult nsComponentManagerImpl::Init() { return NS_OK; } -static const int kModuleVersionWithSelector = 51; - template static void AssertNotMallocAllocated(T* aPtr) { #if defined(DEBUG) && defined(MOZ_MEMORY) @@ -510,140 +488,6 @@ static void AssertNotStackAllocated(T* aPtr) { #endif } -static inline nsCString AsLiteralCString(const char* aStr) { - AssertNotMallocAllocated(aStr); - AssertNotStackAllocated(aStr); - - nsCString str; - str.AssignLiteral(aStr, strlen(aStr)); - return str; -} - -void nsComponentManagerImpl::RegisterModule(const mozilla::Module* aModule) { - mLock.AssertNotCurrentThreadOwns(); - - if (aModule->mVersion >= kModuleVersionWithSelector && - !ProcessSelectorMatches(aModule->selector)) { - return; - } - - { - // Scope the monitor so that we don't hold it while calling into the - // category manager. - MonitorAutoLock lock(mLock); - - KnownModule* m = new KnownModule(aModule); - mKnownStaticModules.AppendElement(m); - - if (aModule->mCIDs) { - const mozilla::Module::CIDEntry* entry; - for (entry = aModule->mCIDs; entry->cid; ++entry) { - RegisterCIDEntryLocked(entry, m); - } - } - - if (aModule->mContractIDs) { - const mozilla::Module::ContractIDEntry* entry; - for (entry = aModule->mContractIDs; entry->contractid; ++entry) { - RegisterContractIDLocked(entry); - } - MOZ_ASSERT(!entry->cid, "Incorrectly terminated contract list"); - } - } - - if (aModule->mCategoryEntries) { - const mozilla::Module::CategoryEntry* entry; - for (entry = aModule->mCategoryEntries; entry->category; ++entry) - nsCategoryManager::GetSingleton()->AddCategoryEntry( - AsLiteralCString(entry->category), AsLiteralCString(entry->entry), - AsLiteralCString(entry->value)); - } -} - -void nsComponentManagerImpl::RegisterCIDEntryLocked( - const mozilla::Module::CIDEntry* aEntry, KnownModule* aModule) { - mLock.AssertCurrentThreadOwns(); - - if (!ProcessSelectorMatches(aEntry->processSelector)) { - return; - } - -#ifdef DEBUG - // If we're still in the static initialization phase, check that we're not - // registering something that was already registered. - if (mStatus != NORMAL) { - if (StaticComponents::LookupByCID(*aEntry->cid)) { - MOZ_CRASH_UNSAFE_PRINTF( - "While registering XPCOM module %s, trying to re-register CID '%s' " - "already registered by a static component.", - aModule->Description().get(), AutoIDString(*aEntry->cid).get()); - } - } -#endif - - mFactories.WithEntryHandle(aEntry->cid, [&](auto&& entry) { - mLock.AssertCurrentThreadOwns(); - if (entry) { - nsFactoryEntry* f = entry.Data(); - NS_WARNING("Re-registering a CID?"); - - nsCString existing; - if (f->mModule) { - existing = f->mModule->Description(); - } else { - existing = ""; - } - MonitorAutoUnlock unlock(mLock); - LogMessage( - "While registering XPCOM module %s, trying to re-register CID '%s' " - "already registered by %s.", - aModule->Description().get(), AutoIDString(*aEntry->cid).get(), - existing.get()); - } else { - entry.Insert(new nsFactoryEntry(aEntry, aModule)); - } - }); -} - -void nsComponentManagerImpl::RegisterContractIDLocked( - const mozilla::Module::ContractIDEntry* aEntry) { - mLock.AssertCurrentThreadOwns(); - - if (!ProcessSelectorMatches(aEntry->processSelector)) { - return; - } - -#ifdef DEBUG - // If we're still in the static initialization phase, check that we're not - // registering something that was already registered. - if (mStatus != NORMAL) { - if (const StaticModule* module = StaticComponents::LookupByContractID( - nsAutoCString(aEntry->contractid))) { - MOZ_CRASH_UNSAFE_PRINTF( - "Could not map contract ID '%s' to CID %s because it is already " - "mapped to CID %s.", - aEntry->contractid, AutoIDString(*aEntry->cid).get(), - AutoIDString(module->CID()).get()); - } - } -#endif - - nsFactoryEntry* f = mFactories.Get(aEntry->cid); - if (!f) { - NS_WARNING("No CID found when attempting to map contract ID"); - - MonitorAutoUnlock unlock(mLock); - LogMessage( - "Could not map contract ID '%s' to CID %s because no implementation of " - "the CID is registered.", - aEntry->contractid, AutoIDString(*aEntry->cid).get()); - - return; - } - - mContractIDs.InsertOrUpdate(AsLiteralCString(aEntry->contractid), f); -} - static void DoRegisterManifest(NSLocationType aType, FileLocation& aFile, bool aChromeOnly) { auto result = URLPreloader::Read(aFile); @@ -693,28 +537,6 @@ void nsComponentManagerImpl::RereadChromeManifests(bool aChromeOnly) { } } -bool nsComponentManagerImpl::KnownModule::Load() { - if (mFailed) { - return false; - } - MOZ_ASSERT(mModule); - if (!mLoaded) { - if (mModule->loadProc) { - nsresult rv = mModule->loadProc(); - if (NS_FAILED(rv)) { - mFailed = true; - return false; - } - } - mLoaded = true; - } - return true; -} - -nsCString nsComponentManagerImpl::KnownModule::Description() const { - return ""_ns; -} - nsresult nsComponentManagerImpl::Shutdown(void) { MOZ_ASSERT(NORMAL == mStatus); @@ -729,11 +551,9 @@ nsresult nsComponentManagerImpl::Shutdown(void) { // Release all cached factories mContractIDs.Clear(); mFactories.Clear(); // XXX release the objects, don't just clear - mKnownStaticModules.Clear(); StaticComponents::Shutdown(); - delete sExtraStaticModules; delete sModuleLocations; mStatus = SHUTDOWN_COMPLETE; @@ -799,7 +619,7 @@ Maybe nsComponentManagerImpl::LookupByContractID( // UnregisterFactory might have left a stale nsFactoryEntry in // mContractIDs, so we should check to see whether this entry has // anything useful. - if (entry->mModule || entry->mFactory || entry->mServiceObject) { + if (entry->mFactory || entry->mServiceObject) { return Some(EntryWrapper(entry)); } } @@ -1382,11 +1202,11 @@ nsComponentManagerImpl::RegisterFactory(const nsCID& aClass, const char* aName, auto f = MakeUnique(aClass, aFactory); MonitorAutoLock lock(mLock); - return mFactories.WithEntryHandle(f->mCIDEntry->cid, [&](auto&& entry) { + return mFactories.WithEntryHandle(&f->mCID, [&](auto&& entry) { if (entry) { return NS_ERROR_FACTORY_EXISTS; } - if (StaticComponents::LookupByCID(*f->mCIDEntry->cid)) { + if (StaticComponents::LookupByCID(f->mCID)) { return NS_ERROR_FACTORY_EXISTS; } if (aContractID) { @@ -1541,20 +1361,16 @@ size_t nsComponentManagerImpl::SizeOfIncludingThis( n += key.SizeOfExcludingThisIfUnshared(aMallocSizeOf); } - n += sExtraStaticModules->ShallowSizeOfIncludingThis(aMallocSizeOf); if (sModuleLocations) { n += sModuleLocations->ShallowSizeOfIncludingThis(aMallocSizeOf); } - n += mKnownStaticModules.ShallowSizeOfExcludingThis(aMallocSizeOf); - n += mPendingServices.ShallowSizeOfExcludingThis(aMallocSizeOf); // Measurement of the following members may be added later if DMD finds it is // worthwhile: // - mMon // - sModuleLocations' entries - // - mKnownStaticModules' entries? return n; } @@ -1563,63 +1379,13 @@ size_t nsComponentManagerImpl::SizeOfIncludingThis( // nsFactoryEntry //////////////////////////////////////////////////////////////////////////////// -nsFactoryEntry::nsFactoryEntry(const mozilla::Module::CIDEntry* aEntry, - nsComponentManagerImpl::KnownModule* aModule) - : mCIDEntry(aEntry), mModule(aModule) {} - nsFactoryEntry::nsFactoryEntry(const nsCID& aCID, nsIFactory* aFactory) - : mCIDEntry(nullptr), mModule(nullptr), mFactory(aFactory) { - auto* e = new mozilla::Module::CIDEntry(); - auto* cid = new nsCID; - *cid = aCID; - e->cid = cid; - mCIDEntry = e; -} - -nsFactoryEntry::~nsFactoryEntry() { - // If this was a RegisterFactory entry, we own the CIDEntry/CID - if (!mModule) { - delete mCIDEntry->cid; - delete mCIDEntry; - } + : mCID(aCID), mFactory(aFactory) { } already_AddRefed nsFactoryEntry::GetFactory() { nsComponentManagerImpl::gComponentManager->mLock.AssertNotCurrentThreadOwns(); - if (!mFactory) { - // RegisterFactory then UnregisterFactory can leave an entry in mContractIDs - // pointing to an unusable nsFactoryEntry. - if (!mModule) { - return nullptr; - } - - if (!mModule->Load()) { - return nullptr; - } - - // Don't set mFactory directly, it needs to be locked - nsCOMPtr factory; - - if (mModule->Module()->getFactoryProc) { - factory = - mModule->Module()->getFactoryProc(*mModule->Module(), *mCIDEntry); - } else if (mCIDEntry->getFactoryProc) { - factory = mCIDEntry->getFactoryProc(*mModule->Module(), *mCIDEntry); - } else { - NS_ASSERTION(mCIDEntry->constructorProc, "no getfactory or constructor"); - factory = new mozilla::GenericFactory(mCIDEntry->constructorProc); - } - if (!factory) { - return nullptr; - } - - MonitorAutoLock lock(nsComponentManagerImpl::gComponentManager->mLock); - // Threads can race to set mFactory - if (!mFactory) { - factory.swap(mFactory); - } - } nsCOMPtr factory = mFactory; return factory.forget(); } @@ -1635,8 +1401,7 @@ size_t nsFactoryEntry::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) { // Measurement of the following members may be added later if DMD finds it is // worthwhile: - // - mCIDEntry; - // - mModule; + // - mCID; // - mFactory; // - mServiceObject; @@ -1674,20 +1439,6 @@ nsresult NS_GetComponentRegistrar(nsIComponentRegistrar** aResult) { return NS_OK; } -EXPORT_XPCOM_API(nsresult) -XRE_AddStaticComponent(const mozilla::Module* aComponent) { - nsComponentManagerImpl::InitializeStaticModules(); - sExtraStaticModules->AppendElement(aComponent); - - if (nsComponentManagerImpl::gComponentManager && - nsComponentManagerImpl::NORMAL == - nsComponentManagerImpl::gComponentManager->mStatus) { - nsComponentManagerImpl::gComponentManager->RegisterModule(aComponent); - } - - return NS_OK; -} - NS_IMETHODIMP nsComponentManagerImpl::AddBootstrappedManifestLocation(nsIFile* aLocation) { NS_ENSURE_ARG_POINTER(aLocation); diff --git a/xpcom/components/nsComponentManager.h b/xpcom/components/nsComponentManager.h index dde5a2d5fb59..5ad555b53b46 100644 --- a/xpcom/components/nsComponentManager.h +++ b/xpcom/components/nsComponentManager.h @@ -137,48 +137,6 @@ class nsComponentManagerImpl final : public nsIComponentManager, static nsTArray* sModuleLocations; - class KnownModule { - public: - /** - * Static or binary module. - */ - explicit KnownModule(const mozilla::Module* aModule) - : mModule(aModule), mLoaded(false), mFailed(false) {} - - ~KnownModule() { - if (mLoaded && mModule->unloadProc) { - mModule->unloadProc(); - } - } - - bool Load(); - - const mozilla::Module* Module() const { return mModule; } - - /** - * For error logging, get a description of this module, either the - * file path, or . - */ - nsCString Description() const; - - private: - const mozilla::Module* mModule; - bool mLoaded; - bool mFailed; - }; - - // The KnownModule is kept alive by these members, it is - // referenced by pointer from the factory entries. - nsTArray> mKnownStaticModules; - - // Mutex not held - void RegisterModule(const mozilla::Module* aModule); - - // Mutex held - void RegisterCIDEntryLocked(const mozilla::Module::CIDEntry* aEntry, - KnownModule* aModule); - void RegisterContractIDLocked(const mozilla::Module::ContractIDEntry* aEntry); - // Mutex not held void RegisterManifest(NSLocationType aType, mozilla::FileLocation& aFile, bool aChromeOnly); @@ -240,13 +198,10 @@ class nsComponentManagerImpl final : public nsIComponentManager, #define NS_ERROR_IS_DIR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XPCOM, 24) struct nsFactoryEntry { - nsFactoryEntry(const mozilla::Module::CIDEntry* aEntry, - nsComponentManagerImpl::KnownModule* aModule); - // nsIComponentRegistrar.registerFactory support nsFactoryEntry(const nsCID& aClass, nsIFactory* aFactory); - ~nsFactoryEntry(); + ~nsFactoryEntry() = default; already_AddRefed GetFactory(); @@ -254,8 +209,7 @@ struct nsFactoryEntry { size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf); - const mozilla::Module::CIDEntry* mCIDEntry; - nsComponentManagerImpl::KnownModule* mModule; + const nsCID mCID; nsCOMPtr mFactory; nsCOMPtr mServiceObject;