Closed Bug 1353187 Opened 7 years ago Closed 7 years ago

guard access to the frame property table with a frame state bit

Categories

(Core :: Layout, enhancement)

enhancement
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla55
Tracking Status
firefox55 --- fixed

People

(Reporter: dbaron, Assigned: dbaron)

References

(Blocks 1 open bug)

Details

(Keywords: perf)

Attachments

(5 files)

Ehsan pointed out that reflow profiles show us spending a lot of time accessing the frame property table.

We should guard access to the frame property table with a frame state bit to optimize this away for frames that have no properties.  (I should also run some numbers for how frequent such frames are!)
I used this patch to get some quick measurements.

With this patch, I started Firefox ("./mach run") which loaded the start page, went to maps.google.com, and then went to www.mozilla.org and closed Firefox.  The printfs from this patch (run through "| sort | uniq -c") added up to:

  81945 proptable get bit=0
 236706 proptable get bit=1
  44679 proptable remove bit=0
  46948 proptable remove bit=1

I think that says this is worth doing, although I was hoping it would be a little more effective than that.
This makes it so that, given a |const nsIFrame*|, a caller can retrieve
properties but not set or remove them, but with an |nsIFrame*| all
operations are allowed.  I believe this is sensible since properties act
as extended member variables for things that are needed rarely, and
these are the const-ness semantics of member variables.

This also avoids the need for const_cast<nsIFrame*> to cast away const
in the following patch, which guards property access with a frame state
bit.

MozReview-Commit-ID: IJ9JnGzdH51
Attachment #8854196 - Flags: review?(dholbert)
This protects all accesses to the frame property table with a bit stored
on the frame.  This means we avoid hashtable operations when asking
about frame properties on frames that have no properties.

The changes to RestyleManager, and the new HasSkippingBitCheck API, are
needed because RestyleManager depended on being able to ask for
properties on a deleted frame (knowing that the property in question
could not have been set on any new frames since the deleted frame was
destroyed), in order to use the destruction of the properties that
happens at frame destruction as a mechanism for learning that the frame
was destroyed.  The changes there preserve the use of that mechanism,
although it becomes a bit uglier.  The ugliness is well-deserved.

MozReview-Commit-ID: BScmDUlWq65
Attachment #8854197 - Flags: review?(dholbert)
Comment on attachment 8854196 [details] [diff] [review]
Give frame properties the const-ness semantics of member variables

Review of attachment 8854196 [details] [diff] [review]:
-----------------------------------------------------------------

This is nice! r=me with typo fixed:

::: layout/base/FramePropertyTable.h
@@ +396,5 @@
> + * properties of a frame.
> + *
> + * However, since frame properties are like member variables, we have
> + * different versions for whether the frame is |const|, sharing a common
> + * a base class.

typo: drop the "a" at the start of the final line here.  (It's extra, after "a common..." on the previous line)

@@ +406,5 @@
>  public:
>    template<typename T> using Descriptor = FramePropertyTable::Descriptor<T>;
>    template<typename T> using PropertyType = FramePropertyTable::PropertyType<T>;
>  
> +  FramePropertiesBase(FramePropertyTable* aTable, CVnsIFrame* aFrame)

Perhaps the constructor should be protected, since you don't want to be able to create instances of this superclass directly, right?  (Only its subclasses should be able to invoke the constructor.)

(Probably nobody's ever actually going to try to do that, but it might be helpful from a reinforcing-the-documentation perspective. *shrug*.)
Attachment #8854196 - Flags: review?(dholbert) → review+
Comment on attachment 8854197 [details] [diff] [review]
Guard access to the frame property table with a frame state bit

Review of attachment 8854197 [details] [diff] [review]:
-----------------------------------------------------------------

I need to stare at the RestyleManager.cpp changes a bit more (I want to read + understand that better before I r+ this), but assuming that all checks out, this seems good.

Some minor review notes:

::: layout/base/FramePropertyTable.cpp
@@ +87,5 @@
>      mLastFrame = aFrame;
>      mLastEntry = entry;
>    }
>  
> +  MOZ_ASSERT(entry || aSkipBitCheck, "frame has NS_FRAME_HAS_PROPERTIES set");

Right now, it takes me a bit of reverse engineering to figure out (a) how the message follows from the asserted conditions, and (b) what the point of the assertion is, since "frame has [some state bit] set" doesn't seem especially abort-worthy.

Could you wrap the message to its own line, and broaden it slightly to something like:
  "frame has NS_FRAME_HAS_PROPERTIES set, but lacks entry"

(That's a more clearly assert-worthy thing, and it's easier to figure out how it maps to the conditions & the state-of-the-world at this point in the code.)

@@ +136,5 @@
>      mLastFrame = aFrame;
>      mLastEntry = mEntries.GetEntry(aFrame);
>    }
>    Entry* entry = mLastEntry;
> +  MOZ_ASSERT(entry, "frame has NS_FRAME_HAS_PROPERTIES set");

My assert-message nitpick applies here, too. (The condition is simpler here, but the message is still unclear about why it's something worth asserting over.)

Perhaps broaden slightly to the following same language suggested above, which will still fit on one line here & which IMO encapsulates the assert-worthy condition in a more human-readable way?

@@ +230,2 @@
>    Entry* entry = mEntries.GetEntry(aFrame);
> +  MOZ_ASSERT(entry, "frame has NS_FRAME_HAS_PROPERTIES set");

Here too.

::: layout/generic/nsFrameStateBits.h
@@ +269,5 @@
>  // Frame owns anonymous boxes whose style contexts it will need to update during
>  // a stylo tree traversal.
>  FRAME_STATE_BIT(Generic, 55, NS_FRAME_OWNS_ANON_BOXES)
>  
> +// Frame has properties in the properties hash.

Maybe slightly clearer:
  s/the properties hash/the Properties() hash table/

(For new people reading the code, there are way too many things called "properties" - JS/DOM properties, CSS properties, and then this thing. Good to be extra-clear which flavor we're referring to here.)
Comment on attachment 8854197 [details] [diff] [review]
Guard access to the frame property table with a frame state bit

Review of attachment 8854197 [details] [diff] [review]:
-----------------------------------------------------------------

(OK, the RestyleManager.cpp changes / HasSkippingBitCheck usage make sense to me now. r=me modulo the textual suggestions in comment 6.
Attachment #8854197 - Flags: review?(dholbert) → review+
See Also: → 1348469
This fixes the test failure in layout/style/test/test_initial_computation.html; the Delete call also needs to be made skipping the bit check, because we can destroy a frame *after* restyling it.  (This could happen, for example, if we restyle one of its siblings, requiring a frame reconstruct, and that reconstruct needs to propagate up to the parent.  I don't think that was the case in test_initial_computation, but it is definitely a case that can happen, which I should have realized.)

I'll merge these changes into the primary patch.
Attachment #8854601 - Flags: review?(dholbert)
Comment on attachment 8854601 [details] [diff] [review]
interdiff to fix test failure

Review of attachment 8854601 [details] [diff] [review]:
-----------------------------------------------------------------

r=me
Attachment #8854601 - Flags: review?(dholbert) → review+
Flags: needinfo?(dbaron)
Attachment #8854642 - Flags: review?(dholbert)
Comment on attachment 8854642 [details] [diff] [review]
second interdiff to fix test failure

Review of attachment 8854642 [details] [diff] [review]:
-----------------------------------------------------------------

r=me
Attachment #8854642 - Flags: review?(dholbert) → review+
https://hg.mozilla.org/mozilla-central/rev/c30756846670
https://hg.mozilla.org/mozilla-central/rev/63a14b2f3c74
Status: ASSIGNED → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla55
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: