Closed
Bug 264456
Opened 20 years ago
Closed 20 years ago
do_GetService causes unnecessary bloat
Categories
(Core :: XPCOM, defect, P2)
Core
XPCOM
Tracking
()
RESOLVED
FIXED
mozilla1.8alpha5
People
(Reporter: dbaron, Assigned: dbaron)
References
Details
(Keywords: memory-footprint, Whiteboard: [patch])
Attachments
(4 files, 1 obsolete file)
|
7.79 KB,
patch
|
darin.moz
:
review+
|
Details | Diff | Splinter Review |
|
1.02 KB,
patch
|
darin.moz
:
review+
|
Details | Diff | Splinter Review |
|
9.44 KB,
patch
|
Details | Diff | Splinter Review | |
|
82.55 KB,
patch
|
darin.moz
:
review+
|
Details | Diff | Splinter Review |
do_GetService causes unnecessary code bloat due to having an nsCOMPtr member on nsGetServiceBy*, and doing a do_QueryInterface to initialize that member.
| Assignee | ||
Comment 1•20 years ago
|
||
| Assignee | ||
Comment 2•20 years ago
|
||
Attachment #162147 -
Attachment is obsolete: true
| Assignee | ||
Updated•20 years ago
|
Status: NEW → ASSIGNED
Priority: -- → P2
Whiteboard: [patch]
Target Milestone: --- → mozilla1.8alpha5
| Assignee | ||
Updated•20 years ago
|
Attachment #162148 -
Flags: review?(darin)
Comment 3•20 years ago
|
||
unrelated, but please note that do_GetInterface also has unnecessary bloat: http://lxr.mozilla.org/seamonkey/source/xpcom/glue/nsIInterfaceRequestorUtils.h#71 nsGetInterface::operator() can be modified to use raw mSource XPCOM pointer It would also save one implicit AddRef()/Release() call for every use of do_GetInterface
| Assignee | ||
Comment 4•20 years ago
|
||
Comment 5•20 years ago
|
||
Comment on attachment 162148 [details] [diff] [review] patch r=darin
Attachment #162148 -
Flags: review?(darin) → review+
| Assignee | ||
Updated•20 years ago
|
Attachment #162203 -
Flags: review?(darin)
Comment 6•20 years ago
|
||
Comment on attachment 162203 [details] [diff] [review] patch for nsIInterfaceRequestorUtils r=darin
Attachment #162203 -
Flags: review?(darin) → review+
| Assignee | ||
Comment 7•20 years ago
|
||
Fixes checked in to trunk, 2004-10-15 10:44/11:03 -0700.
Status: ASSIGNED → RESOLVED
Closed: 20 years ago
Resolution: --- → FIXED
| Assignee | ||
Comment 8•20 years ago
|
||
These together seem to have improved Tp by about 1.5% - 2% on btek.
| Assignee | ||
Comment 9•20 years ago
|
||
From luna (Suite Linux), for both patches: Z:17.93MB Zdiff:-202816 (+859/-203675) mZ:11.27MB mZdiff:-95724 (+223/-95947) From imola (Firefox Mac), for the first patch only, but with some of jst's changes as well: Z:15.53MB Zdiff:-82096 (+34644/-116740)
Comment 10•20 years ago
|
||
I think that second patch is more about performance (less refcounting). I think that most compilers will inline the nsGetInterface constructor after the second patch was checked in (I don't think it was inlined before because of the nsCOMPtr<> constructor, at least at -O1). So overall it is not evident that there's some code reduction with the second patch. I have another patch (almost ready) that does remove do_GetInterface() code bloat at all call sites by removing the inline error pointer assignment in nsGetInterface ctor. I think I'll file a new bug about that.
| Assignee | ||
Comment 11•20 years ago
|
||
From egg (minimo tinderbox):
first patch:
mZ:7.506MB
mZdiff:-51196 (+177/-51373)
second patch:
mZ:7.500MB
mZdiff:-6840 (+2/-6842)
Comment 12•20 years ago
|
||
great stuff!
Comment 13•20 years ago
|
||
Comment on attachment 162148 [details] [diff] [review] patch >+ nsCOMPtr<nsIServiceManager> serviceManager = >+ do_QueryInterface(mServiceManager); >+ if ( serviceManager ) { >+ status = serviceManager->GetService(mCID, aIID, (void**)aInstancePtr); > } else { > nsCOMPtr<nsIServiceManager> mgr; > NS_GetServiceManager(getter_AddRefs(mgr)); > if (mgr) > status = mgr->GetService(mCID, aIID, (void**)aInstancePtr); > } Is the compiler is smart enough to optimize this as follows? nsCOMPtr<nsIServiceManager> mgr(do_QueryInterface(mServiceManager)); if (!mgr) NS_GetServiceManager(getter_AddRefs(mgr)); if (mgr) status = mgr->GetService(mCID, aIID, (void**)aInstancePtr);
| Assignee | ||
Comment 14•20 years ago
|
||
Perhaps. But what's really meant is: nsCOMPtr<nsIServiceManager> mgr = do_QueryInterface(mServiceManager); if (mgr || (NS_GetServiceManager(getter_AddRefs(mgr)), mgr)) status = mgr->GetService(mCID, aIID, (void**)aInstancePtr);
Comment 15•20 years ago
|
||
We never actually pass a non-null service manager to do_GetService().
| Assignee | ||
Comment 16•20 years ago
|
||
Comment on attachment 162345 [details] [diff] [review] remove nsIServiceManager parameter >- nsCOMPtr<nsICategoryManager> catman = >- do_GetService(kCategoryManagerCID, &rv); >- if (NS_FAILED(rv)) goto error; >+ nsCOMPtr<nsICategoryManager> catman; This is wrong.
Attachment #162345 -
Flags: review-
Comment 17•20 years ago
|
||
(In reply to comment #16) > (From update of attachment 162345 [details] [diff] [review]) > >- nsCOMPtr<nsICategoryManager> catman = > >- do_GetService(kCategoryManagerCID, &rv); > >- if (NS_FAILED(rv)) goto error; > >+ nsCOMPtr<nsICategoryManager> catman; > > This is wrong. > What, exactly?
| Assignee | ||
Comment 18•20 years ago
|
||
Comment on attachment 162345 [details] [diff] [review] remove nsIServiceManager parameter Oh, I see. But still, having to write NS_GET_IID() with an argument that's something other than a template parameter is evil.
Attachment #162345 -
Flags: review-
Comment 19•20 years ago
|
||
(In reply to comment #18) > (From update of attachment 162345 [details] [diff] [review]) > Oh, I see. But still, having to write NS_GET_IID() with an argument that's > something other than a template parameter is evil. > Are you referring to using it in conjunction with getter_AddRefs() ? If so, I'm ok with making catman a raw pointer there, though I don't see what it gains us.
| Assignee | ||
Comment 20•20 years ago
|
||
No, I'm referring to having to type "nsICategoryManager" twice for the same variable rather than using do_GetService or CallGetService. If you think reusing the service manager pointer rather than calling NS_GetServiceManager twice is that useful here, then you probably shouldn't remove the functionality... :-)
Comment 21•20 years ago
|
||
Now it is clear that do_GetService() relies heavily on NS_GetServiceManager() http://lxr.mozilla.org/seamonkey/source/xpcom/components/nsComponentManager.cpp#3722 Could it be possible to add a special NS_GetServiceManager function that doesn't addref ? It would save a lot of AddRef/Release calls. There's more than 3000 occurrences of do_GetService().
Comment 22•20 years ago
|
||
I'm not just removing the functionality for the fun of it; passing the extra parameter to nsGetServiceBy* makes extra work for the caller, and most callers aren't able to reuse the service manager because they're only interested in a single service. Here inside the do_GetServiceFromCategory() implementation, I think it makes sense to be as efficient as we can be, even if it means typing nsICategoryManager twice. It's not going to be a big deal either way though, do_GetServiceFromCategory has exactly one caller, and it's not all that performance sensitive.
Comment 23•20 years ago
|
||
(In reply to comment #21) > Could it be possible to add a special NS_GetServiceManager function that doesn't > addref ? It would save a lot of AddRef/Release calls. There's more than 3000 > occurrences of do_GetService(). I thought about that as well.. seems like a good idea.
Comment 24•20 years ago
|
||
After the removal of mServiceManager, it is now possible to consider specializing nsGetServiceXX for the case where mErrorPtr is null, I mean doing what has been done with nsQueryInterface/nsQueryInterfaceWithError(but operator() would still be virtual here): http://lxr.mozilla.org/seamonkey/source/xpcom/glue/nsCOMPtr.h#359 It would remove another extra member for some (most ?) callers, simplify the inline constructor, possibly remove some more bloat. (3000 do_GetService is less than 8000 do_QueryInterface but still...)
Comment 25•20 years ago
|
||
Comment on attachment 162345 [details] [diff] [review] remove nsIServiceManager parameter So can we go ahead and do this? iirc this saved about 30KB code size on Linux.
Attachment #162345 -
Flags: review?(darin)
Comment 26•20 years ago
|
||
bryner: you might want to take a look at my patch in bug 263360. we might want to use the same approach for both of these bugs.
Comment 27•20 years ago
|
||
Comment on attachment 162345 [details] [diff] [review] remove nsIServiceManager parameter This needs to be revised now that the patch for bug 239088 has landed. Removing from my review queue.
Attachment #162345 -
Flags: review?(darin)
Comment 28•20 years ago
|
||
grr.. copy/paste error. i meant bug 263360 ;-)
Comment 29•20 years ago
|
||
reopening for new patch.
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Comment 30•20 years ago
|
||
Updated•20 years ago
|
Attachment #166953 -
Flags: review?(darin)
Comment 31•20 years ago
|
||
I like it !
Some remarks:
1)
all "operator()" in nscomptr.h could be simplified by changing the signature
from
nsresult NS_FASTCALL operator()( const nsIID&, void** ) const;
to
void* NS_FASTCALL operator()( const nsIID& ) const;
assuming that the implementations return NULL when an error occurs
then (for instance)
void
+nsCOMPtr_base::assign_from_gs_cid( const nsGetServiceByCID gs, const nsIID& iid )
+ {
+ nsISupports* newRawPtr;
+ if ( NS_FAILED( gs(iid, NS_REINTERPRET_CAST(void**, &newRawPtr)) ) )
+ newRawPtr = 0;
+ assign_assuming_AddRef(newRawPtr);
+ }
would be
void
+nsCOMPtr_base::assign_from_gs_cid( const nsGetServiceByCID gs, const nsIID& iid )
+ {
+ nsISupports* newRawPtr;
+ newRawPtr = gs(iid);
+ assign_assuming_AddRef(newRawPtr);
+ }
or simply
void
+nsCOMPtr_base::assign_from_gs_cid( const nsGetServiceByCID gs, const nsIID& iid )
+ {
+ assign_assuming_AddRef(gs(iid));
+ }
it will result in less call parameters overhead (push/pop, etc...)
2)
the same "WithError" trick could be used with nsGetInterface
http://lxr.mozilla.org/seamonkey/source/xpcom/glue/nsIInterfaceRequestorUtils.h#58
but it is probably another bug though it could be done easily
There are about 1000 do_GetInterface() calls iirc
3)
+ void assign_from_gs_cid( const nsGetServiceByCID, const nsIID& );
+ void assign_from_gs_cid_with_error( const nsGetServiceByCIDWithError&,
const nsIID& );
+ void assign_from_gs_contractid( const nsGetServiceByContractID, const
nsIID& );
+ void assign_from_gs_contractid_with_error( const
nsGetServiceByContractIDWithError&, const nsIID& );
they all could be called "assigned_from_helper" because the parameters type are
different : no need to find new names and it is shorter to write
4)
it looks like bug that bug 264710 is fixed by this patch too.
Comment 32•20 years ago
|
||
Comment on attachment 166953 [details] [diff] [review] revised patch >Index: xpcom/components/nsComponentManager.cpp >+ rv = compMgr->nsComponentManagerImpl::GetService(kCategoryManagerCID, >+ NS_GET_IID(nsICategoryManager), >+ getter_AddRefs(catman)); nit: indentation r=darin
Attachment #166953 -
Flags: review?(darin) → review+
Comment 33•20 years ago
|
||
> 1) > all "operator()" in nscomptr.h could be simplified by changing the signature > from > nsresult NS_FASTCALL operator()( const nsIID&, void** ) const; > to > void* NS_FASTCALL operator()( const nsIID& ) const; > > assuming that the implementations return NULL when an error occurs Let's hold off on that; I don't think we can say for sure that NULL will be returned when an error occurs. > 2) > the same "WithError" trick could be used with nsGetInterface > http://lxr.mozilla.org/seamonkey/source/xpcom/glue/nsIInterfaceRequestorUtils.h#58 > but it is probably another bug though it could be done easily > There are about 1000 do_GetInterface() calls iirc Sure, separate bug. > 3) > + void assign_from_gs_cid( const nsGetServiceByCID, const nsIID& ); > + void assign_from_gs_cid_with_error( const nsGetServiceByCIDWithError&, > const nsIID& ); > + void assign_from_gs_contractid( const nsGetServiceByContractID, const > nsIID& ); > + void assign_from_gs_contractid_with_error( const > nsGetServiceByContractIDWithError&, const nsIID& ); > > they all could be called "assigned_from_helper" because the parameters type are > different : no need to find new names and it is shorter to write True, but I actually like it being explicit so it's clear whether the error parameter is present.
Comment 34•20 years ago
|
||
checked in.
Status: REOPENED → RESOLVED
Closed: 20 years ago → 20 years ago
Resolution: --- → FIXED
Comment 35•20 years ago
|
||
I've submitted several bugs with patches to consider applying the same tricks with do_GetInterface (bug 271845), do_GetIOService (bug 271823), do_GetFastLoadService (bug 271824), do_CreateInstance (bug 271817)
You need to log in
before you can comment on or make changes to this bug.
Description
•