Closed Bug 1353187 Opened 9 years ago Closed 9 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+
Status: ASSIGNED → RESOLVED
Closed: 9 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: