Bug 23857 - Knock 4 bytes off line boxes by eliminating m_height member
Summary: Knock 4 bytes off line boxes by eliminating m_height member
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Layout and Rendering (show other bugs)
Version: 528+ (Nightly build)
Hardware: Mac OS X 10.5
: P2 Normal
Assignee: Dave Hyatt
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-02-09 15:17 PST by Dave Hyatt
Modified: 2009-03-24 12:46 PDT (History)
0 users

See Also:


Attachments
Patch (29.96 KB, patch)
2009-02-09 15:17 PST, Dave Hyatt
darin: review-
Details | Formatted Diff | Diff
Patch addressing most of Darin's comments (30.23 KB, patch)
2009-02-09 16:52 PST, Dave Hyatt
darin: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Dave Hyatt 2009-02-09 15:17:05 PST
The height for CSS layout is invariant across all lines typically so doesn't need to have a separate member.
Comment 1 Dave Hyatt 2009-02-09 15:17:25 PST
Created attachment 27498 [details]
Patch
Comment 2 Darin Adler 2009-02-09 15:42:10 PST
Comment on attachment 27498 [details]
Patch

>  class EllipsisBox : public InlineBox {
>  public:
>      EllipsisBox(RenderObject* obj, const AtomicString& ellipsisStr, InlineFlowBox* parent,
> -                int width, int y, int height, int baseline, bool firstLine, InlineBox* markupBox)
> -        : InlineBox(obj, 0, y, width, height, baseline, firstLine, true, false, false, 0, 0, parent)
> +                int width, int height, int y, int baseline, bool firstLine, InlineBox* markupBox)
> +        : InlineBox(obj, 0, y, width, baseline, firstLine, true, false, false, 0, 0, parent)
> +        , m_height(height)
>          , m_str(ellipsisStr)
>          , m_markupBox(markupBox)
>      {
>      }
>  
> +    virtual int height() const { return m_height; }

This is the perfect example of a virtual function that should be private. If anyone ever calls height() on a pointer knowing that it's an EllipsisBox, we don't want them to do that -- we'll want to add a faster version that just returns m_height. So you make the virtual function private to make sure nobody makes that mistake. The function in the base class is still public.

> +    ASSERT(m_object->isBox());
> +    return toRenderBox(m_object)->height();

The assertion here is redundant. Just sit back and relax and let toRenderBox handle the assertions for you.

> +    ASSERT(isRootInlineBox());
> +    return static_cast<const RootInlineBox*>(this);

You should make a toRootInlineBox casting macro instead of writing the assert by hand.

> +    const InlineFlowBox* box = static_cast<const InlineFlowBox*>(this);
> +    result += box->boxModelObject()->borderTop() + box->boxModelObject()->paddingTop() +
> +              box->boxModelObject()->borderBottom() + box->boxModelObject()->paddingBottom();

Seems to me that putting boxModelObject() into a local variable with a short name (renderer, perhaps) would make this fit all on one line and be easier to read.

>      virtual ~InlineFlowBox();
>  #endif
>  
> -    virtual bool isInlineFlowBox() { return true; }
> +    virtual bool isInlineFlowBox() const { return true; }

This should be private. If anyone ever calls it on something and already knows it's an InlineFlowBox then it's a bug.

> +    virtual int height() const;

This too, maybe. Why pay for a virtual function dispatch if some particular caller doesn't need to? Lets have the compiler notice that for us.

> -    IntRect rect(tx + m_x, ty + m_y, m_width, m_height);
> +    IntRect rect(tx + m_x, ty + m_y, m_width, height());

Seems lame to pay for a virtual function call here. Are there any classes derived from InlineTextBox that need to override height()?

> --- rendering/InlineTextBox.h	(revision 40769)
> +++ rendering/InlineTextBox.h	(working copy)
> @@ -50,6 +50,8 @@ public:
>      InlineTextBox* nextTextBox() const { return static_cast<InlineTextBox*>(nextLineBox()); }
>      InlineTextBox* prevTextBox() const { return static_cast<InlineTextBox*>(prevLineBox()); }
>  
> +    virtual int height() const;

Same comment about private inline functions.

Same applies to other classes like RootInlineBox.

I'm going to say review- because I'd like to see another patch that calls virtual functions a bit less often.
Comment 3 Dave Hyatt 2009-02-09 16:50:39 PST
(In reply to comment #2)
> (From update of attachment 27498 [details] [review])
> >  class EllipsisBox : public InlineBox {
> >  public:
> >      EllipsisBox(RenderObject* obj, const AtomicString& ellipsisStr, InlineFlowBox* parent,
> > -                int width, int y, int height, int baseline, bool firstLine, InlineBox* markupBox)
> > -        : InlineBox(obj, 0, y, width, height, baseline, firstLine, true, false, false, 0, 0, parent)
> > +                int width, int height, int y, int baseline, bool firstLine, InlineBox* markupBox)
> > +        : InlineBox(obj, 0, y, width, baseline, firstLine, true, false, false, 0, 0, parent)
> > +        , m_height(height)
> >          , m_str(ellipsisStr)
> >          , m_markupBox(markupBox)
> >      {
> >      }
> >  
> > +    virtual int height() const { return m_height; }
> 
> This is the perfect example of a virtual function that should be private. If
> anyone ever calls height() on a pointer knowing that it's an EllipsisBox, we
> don't want them to do that -- we'll want to add a faster version that just
> returns m_height. So you make the virtual function private to make sure nobody
> makes that mistake. The function in the base class is still public.
> 

Agreed.  Fixed.

> > +    ASSERT(m_object->isBox());
> > +    return toRenderBox(m_object)->height();
> 
> The assertion here is redundant. Just sit back and relax and let toRenderBox
> handle the assertions for you.
>

Agreed. Fixed.
 
> > +    ASSERT(isRootInlineBox());
> > +    return static_cast<const RootInlineBox*>(this);
> 
> You should make a toRootInlineBox casting macro instead of writing the assert
> by hand.
>

This is just a clone of a non-const form of the function.  While I completely agree with you, I don't want to mix cleanup work with this patch.  There are many places that do line box casts of all types, and we should add toXXX methods for all of those, but I don't want to mix that in with this patch.
 
> > +    const InlineFlowBox* box = static_cast<const InlineFlowBox*>(this);
> > +    result += box->boxModelObject()->borderTop() + box->boxModelObject()->paddingTop() +
> > +              box->boxModelObject()->borderBottom() + box->boxModelObject()->paddingBottom();
> 
> Seems to me that putting boxModelObject() into a local variable with a short
> name (renderer, perhaps) would make this fit all on one line and be easier to
> read.
>

Agreed. Fixed.
 
> >      virtual ~InlineFlowBox();
> >  #endif
> >  
> > -    virtual bool isInlineFlowBox() { return true; }
> > +    virtual bool isInlineFlowBox() const { return true; }
> 
> This should be private. If anyone ever calls it on something and already knows
> it's an InlineFlowBox then it's a bug.
>

Agreed, and moving this caught a place in SVG where they were doing just that.
 
> > +    virtual int height() const;
> 
> This too, maybe. Why pay for a virtual function dispatch if some particular
> caller doesn't need to? Lets have the compiler notice that for us.
> 

No.  This one can't be private.

> > -    IntRect rect(tx + m_x, ty + m_y, m_width, m_height);
> > +    IntRect rect(tx + m_x, ty + m_y, m_width, height());
> 
> Seems lame to pay for a virtual function call here. Are there any classes
> derived from InlineTextBox that need to override height()?
>

Yes. SVGInlineTextBox.
 
> > --- rendering/InlineTextBox.h	(revision 40769)
> > +++ rendering/InlineTextBox.h	(working copy)
> > @@ -50,6 +50,8 @@ public:
> >      InlineTextBox* nextTextBox() const { return static_cast<InlineTextBox*>(nextLineBox()); }
> >      InlineTextBox* prevTextBox() const { return static_cast<InlineTextBox*>(prevLineBox()); }
> >  
> > +    virtual int height() const;
> 
> Same comment about private inline functions.
>

Can't be private.
 
> Same applies to other classes like RootInlineBox.
>

Can't be private.
 
> I'm going to say review- because I'd like to see another patch that calls
> virtual functions a bit less often.
> 

Unfortunately I can't really improve on this.  SVG subclasses RootInlineBox, InlineTextBox, and InlineFlowBox and supplies different heights.  SVG also subclasses RenderText and RenderInline.  The places that you are noticing that now use virtual height() are shared with SVG.
Comment 4 Dave Hyatt 2009-02-09 16:52:26 PST
Created attachment 27503 [details]
Patch addressing most of Darin's comments
Comment 5 Dave Hyatt 2009-02-09 17:19:48 PST
I built release and ran the PLT.  None of the height() functions even show up.  height() really is used more for event handling than anything else, and I don't think the virtual function calls are going to hurt at all there.


Comment 6 Darin Adler 2009-02-09 17:55:12 PST
Comment on attachment 27503 [details]
Patch addressing most of Darin's comments

r=me
Comment 7 Mark Rowe (bdash) 2009-02-09 21:27:23 PST
Did this get landed?
Comment 8 David Levin 2009-03-24 12:46:24 PDT
Committed as r40802.

Resolving to move out of the commit queue.