Closed
Bug 847248
Opened 12 years ago
Closed 12 years ago
Reduce use of nsFixedSizeAllocator
Categories
(Core :: General, defect)
Core
General
Tracking
()
RESOLVED
FIXED
mozilla22
People
(Reporter: n.nethercote, Assigned: n.nethercote)
References
Details
(Whiteboard: [MemShrink:P3])
Attachments
(10 files, 1 obsolete file)
8.89 KB,
patch
|
bzbarsky
:
review+
|
Details | Diff | Splinter Review |
981 bytes,
patch
|
bzbarsky
:
review+
|
Details | Diff | Splinter Review |
7.06 KB,
patch
|
bzbarsky
:
review+
|
Details | Diff | Splinter Review |
38.05 KB,
patch
|
bzbarsky
:
review+
|
Details | Diff | Splinter Review |
20.31 KB,
patch
|
enndeakin
:
review+
|
Details | Diff | Splinter Review |
16.89 KB,
patch
|
enndeakin
:
review+
|
Details | Diff | Splinter Review |
6.84 KB,
patch
|
bzbarsky
:
review+
|
Details | Diff | Splinter Review |
19.16 KB,
patch
|
hsivonen
:
review+
|
Details | Diff | Splinter Review |
16.64 KB,
patch
|
ehsan.akhgari
:
review+
benjamin
:
superreview+
|
Details | Diff | Splinter Review |
15.09 KB,
patch
|
bzbarsky
:
review+
|
Details | Diff | Splinter Review |
Most of the uses of nsFixedSizeAllocator add nothing but complexity to the code base. They should be removed. (Bug 847210 and bug 847236 are already open to remove two of the existing cases.) TimerEventAllocator is an exception, but the sizes of the chunks it allocates are much bigger than necessary.
Better explanation of the circumstances when nsFixedSizeAllocator is useful would also be a good thing.
Assignee | ||
Comment 1•12 years ago
|
||
This patch:
- Extends and cleans up the existing comments for nsFixedSizeAllocator.
- Excludes the |bucketSpace| from the chunk size passed to PL_InitArenaPool.
When a power-of-two is passed to nsFixedSizeAllocator::Init(), the underlying
plarena will now see the same size, and no slop will occur. (Note that most
of the existing nsFixedSizeAllocators do not yet pass in a power-of-two
|aChunkSize|. I'll fix that subsequently.)
Attachment #720503 -
Flags: review?(bzbarsky)
Assignee | ||
Comment 2•12 years ago
|
||
TimerEventAllocator uses a chunk size of 1024 * sizeof(nsTimerEvent). On
64-bit platforms this is 32 KiB, and on 32-bit platforms it is (I think) 16
KiB.
With 150 tabs open (http://gregor-wagner.com/tmp/mem) I couldn't get above 200
simultaneously live timers. A starting chunk size that allows 1024 is
excessive, especially given that this is memory that isn't freed until
shutdown. So I reduced it to 4096 bytes, which allows 127 timers per chunk on
64-bit bit, and 255 timers per chunk on 32-bit.
Attachment #720505 -
Flags: review?(bzbarsky)
Assignee | ||
Comment 3•12 years ago
|
||
This case is funny/sad. The chunk size passed to the nsFixedSizeAllocator is
only 16 bytes, which means that we'll fit exactly one Row per chunk. So the
nsFixedSizeAllocator is genuinely just a wrapper around malloc/new that
complicates things and wastes space (due to the chunk overhead).
This patch just rips out that nsFixedSizeAllocator.
Attachment #720506 -
Flags: review?(bzbarsky)
Assignee | ||
Comment 4•12 years ago
|
||
This patch removes nsFixedSizeAllocator from rdf/, removing the Create/Destroy
methods in numerous classes and replacing calls to them with with calls to
vanilla new/delete. It seems extremely unlikely this will affect performance
noticeably; besides, AFAIK the RDF stuff is very obscure.
About the only non-mechanical thing in the patch is that I had to move some
hash table destruction code out of Assertion::Destroy into ~Assertion.
Hmm, I just realized that I haven't taken advantage of the fact that |new| is
infallible. I could remove some post-|new| null checks if you think it's
worthwhile.
Attachment #720576 -
Flags: review?(bzbarsky)
Comment 5•12 years ago
|
||
Comment on attachment 720503 [details] [diff] [review]
(part 1) - Improve documentation and reduce slop potential of nsFixedSizeAllocator.
>+ * chunk will be used to by the nsFixedSizeAllocator (or the underlying
>+ * plarena) itself.
s/to by/by/
s/plarena/PLArena/.
r=me
Attachment #720503 -
Flags: review?(bzbarsky) → review+
Comment 6•12 years ago
|
||
Comment on attachment 720505 [details] [diff] [review]
(part 2) - Use a smaller chunk size in TimerEventAllocator.
r=me
Attachment #720505 -
Flags: review?(bzbarsky) → review+
Comment 7•12 years ago
|
||
Comment on attachment 720506 [details] [diff] [review]
(part 3) - Remove the nsFixedSizeAllocator from nsTreeContentView.
r=me, though worth filing a followup to make mRows into an nsTArray<nsAutoPtr<Row> >
Attachment #720506 -
Flags: review?(bzbarsky) → review+
Assignee | ||
Comment 8•12 years ago
|
||
This patch removes nsFixedSizeAllocator from nsXULTemplateBuilder. Unlike the
previous patch, I kept the Create/Destroy methods because the Destroy() method
takes an argument.
This code appears to not be hot -- it didn't trigger when I started the browser
and viewed a couple of sites. And the chunk size of 256 is small enough that
it's unlikely to have any performance/fragmentation advantages even if the code
was hotter.
Attachment #721044 -
Flags: review?(bzbarsky)
Comment 9•12 years ago
|
||
Comment on attachment 720576 [details] [diff] [review]
(part 4) - Remove all uses of nsFixedSizeAllocator from rdf/.
r=me
Attachment #720576 -
Flags: review?(bzbarsky) → review+
Comment 10•12 years ago
|
||
Comment on attachment 721044 [details] [diff] [review]
(part 5) - Remove nsFixedSizeAllocator from nsXULTemplateBuilder.
Going to pass this one to enn.
Attachment #721044 -
Flags: review?(bzbarsky) → review?(enndeakin)
Assignee | ||
Comment 11•12 years ago
|
||
> (part 3) - Remove the nsFixedSizeAllocator from nsTreeContentView.
>
> r=me, though worth filing a followup to make mRows into an
> nsTArray<nsAutoPtr<Row> >
I filed bug 847790.
Assignee | ||
Comment 12•12 years ago
|
||
This patch removes nsFixedSizeAllocator from MemoryElement. This time I got
rid of the Create/Destroy methods. The relevant destructors are all virtual so
it should be fine.
Like the last patch, the chunk size is only 256, so the fixed-size allocator is
unlikely to be having any performance effect.
Attachment #721056 -
Flags: review?(enndeakin)
Comment 14•12 years ago
|
||
Comment on attachment 721059 [details] [diff] [review]
(part 7) - Remove nsFixedSizeAllocator from nsXBLService.
r=me
Attachment #721059 -
Flags: review?(bzbarsky) → review+
Updated•12 years ago
|
Attachment #721044 -
Flags: review?(enndeakin) → review+
Updated•12 years ago
|
Attachment #721056 -
Flags: review?(enndeakin) → review+
Assignee | ||
Updated•12 years ago
|
Whiteboard: [MemShrink] → [MemShrink:P3]
Assignee | ||
Comment 15•12 years ago
|
||
The old HTML parser appears to be barely used. This patch removes its use of
nsFixedSizeAllocator in a minimally-invasive fashion, by replacing
nsFixedSizeAllocator with a new nsDummyAllocator class which trivally wraps
malloc/free.
I could do a more extensive patch that gets rid of nsDummyAllocator, but it
doesn't seem worthwhile.
Attachment #721533 -
Flags: review?(hsivonen)
Assignee | ||
Comment 16•12 years ago
|
||
Attachment #721562 -
Flags: review?(bzbarsky)
Updated•12 years ago
|
Attachment #721533 -
Flags: review?(hsivonen) → review+
Comment 17•12 years ago
|
||
Comment on attachment 721562 [details] [diff] [review]
(part 10) - Rewrite TimerEventAllocator and remove nsFixedSizeAllocator.
> void* Alloc(size_t aSize)
Worth asserting that aSize >= sizeof(void*), since we assume in Free that all our allocated chunks are at least that size.
r=me with that.
Attachment #721562 -
Flags: review?(bzbarsky) → review+
Assignee | ||
Comment 18•12 years ago
|
||
> Worth asserting that aSize >= sizeof(void*), since we assume in Free that
> all our allocated chunks are at least that size.
The real assumption is that |aSize == sizeof(nsTimerEvent)|, which is stronger. I assert that in |nsTimerEvent::operator new|, but |TimerEventAllocator::Alloc| would be a better place for it. I'll do that.
Assignee | ||
Comment 19•12 years ago
|
||
Updated version for super-review.
Assignee | ||
Updated•12 years ago
|
Attachment #721562 -
Attachment is obsolete: true
Assignee | ||
Comment 20•12 years ago
|
||
Comment on attachment 721905 [details] [diff] [review]
(part 10) - Rewrite TimerEventAllocator and remove nsFixedSizeAllocator.
bsmedberg, I'm asking for super-review on the removal of nsFixedSizeAllocator.
It's a crappy allocator. It's a mild extension to PLArenaPool -- it can handle freeing and subsequent recycling of objects. It causes slop bytes by making non-power-of-two requests, but fortunately it's not used in places that allocate a lot of memory.
However, in bug 847210 it was causing us to hold onto several MBs of nsNodeInfo structs forever. In bug 847236 it made the ETCI recycle pool much more complex, and required it to be flushed empty each time it became full. In all but one of the cases in this bug, it had no beneficial effect but made the code substantially more complex -- vanilla malloc/free or new/delete was much simpler. (I've removed ~700 lines of code as a result.)
The one case where it's genuinely helpful is in TimerEventAllocator, where the lack of contention with the main malloc lock is a performance win. So I just changed TimerEventAllocator to be a one-off custom allocator, rather than using nsFixedSizeAllocator. It was much simpler that way because it only has to handle a single size of object.
Like nsRecyclingAllocator, which I killed off in bug 715770, nsFixedSizeAllocator might have been useful in pre-jemalloc days, but no longer. It's an attractive nuisance that needs to go!
Attachment #721905 -
Flags: superreview?(benjamin)
Comment 21•12 years ago
|
||
> The real assumption is that |aSize == sizeof(nsTimerEvent)|, which is stronger.
What guarantees sizeof(nsTimerEvent) >= sizeof(void*)? I know it is right now, but in general seems like a good thing to assert. Statically, perhaps, since that's statically assertable.
Assignee | ||
Comment 22•12 years ago
|
||
> What guarantees sizeof(nsTimerEvent) >= sizeof(void*)? I know it is right
> now, but in general seems like a good thing to assert.
Fair enough. I'll add that too.
Comment 23•12 years ago
|
||
https://hg.mozilla.org/mozilla-central/rev/47ada7ee45de
https://hg.mozilla.org/mozilla-central/rev/f3ad021e88f0
Status: ASSIGNED → RESOLVED
Closed: 12 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla22
Comment 24•12 years ago
|
||
Only the first 2 parts landed, right?
Updated•12 years ago
|
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Assignee | ||
Updated•12 years ago
|
Whiteboard: [MemShrink:P3] → [MemShrink:P3][leave open]
Assignee | ||
Comment 25•12 years ago
|
||
Oh, I forgot to upload this patch.
Attachment #722809 -
Flags: review?(bzbarsky)
Assignee | ||
Comment 26•12 years ago
|
||
Assignee | ||
Comment 27•12 years ago
|
||
Comment 28•12 years ago
|
||
Comment on attachment 722809 [details] [diff] [review]
(part 8) - Remove nsFixedSizeAllocator from xbl/.
r=me
Attachment #722809 -
Flags: review?(bzbarsky) → review+
Comment 29•12 years ago
|
||
Assignee | ||
Comment 30•12 years ago
|
||
Comment 31•12 years ago
|
||
Comment 32•12 years ago
|
||
Comment on attachment 721905 [details] [diff] [review]
(part 10) - Rewrite TimerEventAllocator and remove nsFixedSizeAllocator.
I'm going to mark sr+ on this, but I think ehsan should at least rubberstamp the timer allocator bits since he has touched that code recently.
Attachment #721905 -
Flags: superreview?(benjamin)
Attachment #721905 -
Flags: superreview+
Attachment #721905 -
Flags: review?(ehsan)
Comment 33•12 years ago
|
||
Comment on attachment 721905 [details] [diff] [review]
(part 10) - Rewrite TimerEventAllocator and remove nsFixedSizeAllocator.
Review of attachment 721905 [details] [diff] [review]:
-----------------------------------------------------------------
::: xpcom/threads/nsTimerImpl.cpp
@@ +68,5 @@
> +// "freed" nsTimerEvents aren't truly freed, they're just put onto a free-list
> +// for later recycling. So the amount of memory consumed will always be equal
> +// to the high-water mark consumption. But nsTimerEvents are small and it's
> +// unusual to have more than a few hundred of them, so this shouldn't be a
> +// problem in practice.
It would be interesting to hook this up to the memory reporter infrastructure so that we can verify this in practice.
@@ +88,4 @@
> mMonitor("TimerEventAllocator")
> {
> + PL_InitArenaPool(&mPool, "TimerEventPool", 4096, /* align = */ 0);
> + mFirstFree = nullptr;
No need to re-assign null here.
Attachment #721905 -
Flags: review?(ehsan) → review+
Assignee | ||
Comment 34•12 years ago
|
||
> It would be interesting to hook this up to the memory reporter
> infrastructure so that we can verify this in practice.
I did some ad hoc measurement while running MemBench (http://gregor-wagner.com/tmp/mem) which opens 150 tabs at once, and 202 was the maximum number of timers live at once. And in DMD profiles I've never seen more than 32 KiB, which was the old chunk size. So I don't think it's worth hooking up for something that rarely goes above 4 or 8 KiB.
Comment 35•12 years ago
|
||
(In reply to comment #34)
> > It would be interesting to hook this up to the memory reporter
> > infrastructure so that we can verify this in practice.
>
> I did some ad hoc measurement while running MemBench
> (http://gregor-wagner.com/tmp/mem) which opens 150 tabs at once, and 202 was
> the maximum number of timers live at once. And in DMD profiles I've never seen
> more than 32 KiB, which was the old chunk size. So I don't think it's worth
> hooking up for something that rarely goes above 4 or 8 KiB.
Fair enough!
Assignee | ||
Comment 36•12 years ago
|
||
Part 10:
https://hg.mozilla.org/integration/mozilla-inbound/rev/5cd5d96f223c
That's the last patch.
Whiteboard: [MemShrink:P3][leave open] → [MemShrink:P3]
Comment 37•12 years ago
|
||
Status: REOPENED → RESOLVED
Closed: 12 years ago → 12 years ago
Resolution: --- → FIXED
Comment 38•12 years ago
|
||
(In reply to Boris Zbarsky from comment #7)
> worth filing a followup to make mRows into an nsTArray<nsAutoPtr<Row> >
Out of interest, what are the pros and cons against nsTArray<Row> ?
Comment 39•12 years ago
|
||
If the structure can be memmoved and memcopied, probably none.
You need to log in
before you can comment on or make changes to this bug.
Description
•