Closed Bug 1111885 Opened 10 years ago Closed 10 years ago

Millions of heap allocations to fill rectangles and glyphs when viewing Treeherder

Categories

(Core :: Layout, defect)

x86_64
Linux
defect
Not set
normal

Tracking

()

RESOLVED WORKSFORME

People

(Reporter: n.nethercote, Unassigned)

References

Details

Attachments

(1 file)

I have some more Treeherder heap allocation measurements from DMD. First, we create a *lot* of Cairo patterns in order to fill rectangles and glyphs: > Cumulative { > 1,075,692 blocks in heap block record 2 of 15,540 > 172,110,720 bytes (163,505,184 requested / 8,605,536 slop) > Individual block sizes: 160 x 1,075,692 > 4.48% of the heap (11.71% cumulative) > Allocated at { > #01: _cairo_pattern_create_solid (/home/njn/moz/mi4/o64dmd/gfx/cairo/cairo/src/../../../../../gfx/cairo/cairo/src/cairo-pattern.c:489) > #02: INT__moz_cairo_pattern_create_rgba (/home/njn/moz/mi4/o64dmd/gfx/cairo/cairo/src/../../../../../gfx/cairo/cairo/src/cairo-pattern.c:593) > #03: mozilla::gfx::GfxPatternToCairoPattern(mozilla::gfx::Pattern const&, float) (/home/njn/moz/mi4/o64dmd/gfx/2d/../../../gfx/2d/DrawTargetCairo.cpp:469) > #04: mozilla::gfx::DrawTargetCairo::DrawPattern(mozilla::gfx::Pattern const&, mozilla::gfx::StrokeOptions const&, mozilla::gfx::DrawOptions const&, mozilla::gfx::DrawTargetCairo::DrawPatternType, bool) (/home/njn/moz/mi4/o64dmd/gfx/2d/../../../gfx/2d/DrawTargetCairo.cpp:866) > #05: mozilla::gfx::DrawTargetCairo::FillRect(mozilla::gfx::RectTyped<mozilla::gfx::UnknownUnits> const&, mozilla::gfx::Pattern const&, mozilla::gfx::DrawOptions const&) (/home/njn/moz/mi4/o64dmd/gfx/2d/../../../gfx/2d/DrawTargetCairo.cpp:961) > } > } > > Cumulative { > 161,180 blocks in heap block record 12 of 15,540 > 25,788,800 bytes (24,499,360 requested / 1,289,440 slop) > Individual block sizes: 160 x 161,180 > 0.67% of the heap (44.14% cumulative) > Allocated at { > #01: _cairo_pattern_create_solid (/home/njn/moz/mi4/o64dmd/gfx/cairo/cairo/src/../../../../../gfx/cairo/cairo/src/cairo-pattern.c:489) > #02: INT__moz_cairo_pattern_create_rgba (/home/njn/moz/mi4/o64dmd/gfx/cairo/cairo/src/../../../../../gfx/cairo/cairo/src/cairo-pattern.c:593) > #03: mozilla::gfx::GfxPatternToCairoPattern(mozilla::gfx::Pattern const&, float) (/home/njn/moz/mi4/o64dmd/gfx/2d/../../../gfx/2d/DrawTargetCairo.cpp:469) > #04: mozilla::gfx::DrawTargetCairo::FillGlyphs(mozilla::gfx::ScaledFont*, mozilla::gfx::GlyphBuffer const&, mozilla::gfx::Pattern const&, mozilla::gfx::DrawOptions const&, mozilla::gfx::GlyphRenderingOptions const*) (/home/njn/moz/mi4/o64dmd/gfx/2d/../../../gfx/2d/DrawTargetCairo.cpp:1143) > #05: GlyphBufferAzure::Flush(bool) (/home/njn/moz/mi4/o64dmd/gfx/thebes/../../../gfx/thebes/gfxFont.cpp:1611) > } > } And then, for the rectangles (which dominate), we create a clip path as well: > Cumulative { > 625,379 blocks in heap block record 3 of 28,149 > 640,388,096 bytes (395,239,528 requested / 245,148,568 slop) > Individual block sizes: 1,024 x 625,379 > 16.66% of the heap (23.82% cumulative) > Allocated at { > #01: _cairo_clip_path_create (/home/njn/moz/mi4/o64dmd/gfx/cairo/cairo/src/../../../../../gfx/cairo/cairo/src/cairo-clip.c:62) > #02: _cairo_clip_intersect_rectangle (/home/njn/moz/mi4/o64dmd/gfx/cairo/cairo/src/../../../../../gfx/cairo/cairo/src/cairo-clip.c:143) > #03: _cairo_clip_to_boxes (/home/njn/moz/mi4/o64dmd/gfx/cairo/cairo/src/../../../../../gfx/cairo/cairo/src/cairo-clip.c:1446) > #04: _cairo_surface_fallback_fill (/home/njn/moz/mi4/o64dmd/gfx/cairo/cairo/src/../../../../../gfx/cairo/cairo/src/cairo-surface-fallback.c:1156) > #05: _cairo_surface_fill (/home/njn/moz/mi4/o64dmd/gfx/cairo/cairo/src/../../../../../gfx/cairo/cairo/src/cairo-surface.c:2363) > #06: _cairo_gstate_fill (/home/njn/moz/mi4/o64dmd/gfx/cairo/cairo/src/../../../../../gfx/cairo/cairo/src/cairo-gstate.c:1290) > #07: INT__moz_cairo_fill_preserve (/home/njn/moz/mi4/o64dmd/gfx/cairo/cairo/src/../../../../../gfx/cairo/cairo/src/cairo.c:2464) > #08: mozilla::gfx::DrawTargetCairo::DrawPattern(mozilla::gfx::Pattern const&, mozilla::gfx::StrokeOptions const&, mozilla::gfx::DrawOptions const&, mozilla::gfx::DrawTargetCairo::DrawPatternType, bool) (/home/njn/moz/mi4/o64dmd/gfx/2d/../../../gfx/2d/DrawTargetCairo.cpp:910) > #09: mozilla::gfx::DrawTargetCairo::FillRect(mozilla::gfx::RectTyped<mozilla::gfx::UnknownUnits> const&, mozilla::gfx::Pattern const&, mozilla::gfx::DrawOptions const&) (/home/njn/moz/mi4/o64dmd/gfx/2d/../../../gfx/2d/DrawTargetCairo.cpp:961) > #10: DrawSolidBorderSegment(nsRenderingContext&, nsRect, unsigned int, int, int, unsigned char, int, unsigned char, int) (/home/njn/moz/mi4/o64dmd/layout/base/../../../layout/base/nsCSSRendering.cpp:3727) > } > } In total, these account for over 10% of all heap allocations in the child process (this is allocation *counts*, not *size*). This feels rather heavyweight for filling in rectangles. But I don't know this code at all; maybe it's unavoidable.
One thing to note: _cairo_pattern_create_solid() has a pattern pool which allows patterns to be reused. But we configure Cairo such that it's not used. This may be a perfectly reasonable thing to do; I'm just pointing it out because it's potentially confusing.
The attached file shows the data from comment 0, but with longer stack traces, in case that's helpful.
(In reply to Nicholas Nethercote [:njn] from comment #1) > One thing to note: _cairo_pattern_create_solid() has a pattern pool which > allows patterns to be reused. But we configure Cairo such that it's not > used. This may be a perfectly reasonable thing to do; I'm just pointing it > out because it's potentially confusing. I believe not using the pattern pool is a mistake. Just using that is probably the right way to fix this.
> I believe not using the pattern pool is a mistake. Just using that is > probably the right way to fix this. The pattern pool is enabled if HAS_ATOMIC_OPS is true. It is set to true if any of HAVE_INTEL_ATOMIC_PRIMITIVES, HAVE_LIB_ATOMIC_OPS, HAVE_OS_ATOMIC_OPS are true. I don't know what dictates if they are true; each of those identifiers appear exactly once in the codebase, so they must have to be defined from outside, and I don't recognize the atomic primitives used within the three cases. So I don't know how to enable this.
Depends on: 1112121
(In reply to Nicholas Nethercote [:njn] from comment #4) > > I believe not using the pattern pool is a mistake. Just using that is > > probably the right way to fix this. > > The pattern pool is enabled if HAS_ATOMIC_OPS is true. It is set to true if > any of HAVE_INTEL_ATOMIC_PRIMITIVES, See https://gcc.gnu.org/onlinedocs/gcc-4.7.4/gcc/_005f_005fsync-Builtins.html#_005f_005fsync-Builtins > HAVE_LIB_ATOMIC_OPS, See https://github.com/ivmai/libatomic_ops/ > HAVE_OS_ATOMIC_OPS See https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/OSAtomicAdd32.3.html
Nicholas, thank you for filing this and the others! :-)
Depends on: 967300
No longer depends on: 1112121
I just checked with DMD -- with bug 967300 having been fixed all the calls _cairo_pattern_create_solid() on Linux are gone. When I measured earlier on Windows there weren't many calls to that function. And on Linux almost all of the calls to _cairo_clip_path_create() have gone as well. Not sure why. But I think we can declare victory here.
Status: NEW → RESOLVED
Closed: 10 years ago
Resolution: --- → WORKSFORME
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: