Optimize relativePositionOffset() to avoid doing unnecessary work
authorhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 6 May 2015 18:37:51 +0000 (18:37 +0000)
committerhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 6 May 2015 18:37:51 +0000 (18:37 +0000)
https://bugs.webkit.org/show_bug.cgi?id=144698

Reviewed by Simon Fraser.

* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::relativePositionOffset):

Patch relativePositionOffset to avoid doing unnecessary work in the common case where
all values of top/left/right/bottom are either auto or fixed. We no longer fetch
containingBlock() into a local always, but instead just invoke the function only
when necessary.

Also avoid computing the percentage-relative maximum for the top/right/bottom/left lengths
when they are fixed values, since that maximum won't be examined at all.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@183879 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderBoxModelObject.cpp

index a82aeee..85afed2 100644 (file)
@@ -1,3 +1,21 @@
+2015-05-06  David Hyatt  <hyatt@apple.com>
+
+        Optimize relativePositionOffset() to avoid doing unnecessary work
+        https://bugs.webkit.org/show_bug.cgi?id=144698
+
+        Reviewed by Simon Fraser.
+
+        * rendering/RenderBoxModelObject.cpp:
+        (WebCore::RenderBoxModelObject::relativePositionOffset):
+
+        Patch relativePositionOffset to avoid doing unnecessary work in the common case where
+        all values of top/left/right/bottom are either auto or fixed. We no longer fetch
+        containingBlock() into a local always, but instead just invoke the function only
+        when necessary.
+
+        Also avoid computing the percentage-relative maximum for the top/right/bottom/left lengths
+        when they are fixed values, since that maximum won't be examined at all.
+
 2015-05-06  Martin Robinson  <mrobinson@igalia.com>
 
         [FreeType] Vertical CJK glyphs should not be rendered with synthetic oblique
index 9a3d074..ae0ef71 100644 (file)
@@ -274,21 +274,22 @@ bool RenderBoxModelObject::hasAutoHeightOrContainingBlockWithAutoHeight() const
 
 LayoutSize RenderBoxModelObject::relativePositionOffset() const
 {
-    LayoutSize offset = accumulateInFlowPositionOffsets(this);
+    // This function has been optimized to avoid calls to containingBlock() in the common case
+    // where all values are either auto or fixed.
 
-    RenderBlock* containingBlock = this->containingBlock();
+    LayoutSize offset = accumulateInFlowPositionOffsets(this);
 
     // Objects that shrink to avoid floats normally use available line width when computing containing block width.  However
     // in the case of relative positioning using percentages, we can't do this.  The offset should always be resolved using the
     // available width of the containing block.  Therefore we don't use containingBlockLogicalWidthForContent() here, but instead explicitly
     // call availableWidth on our containing block.
     if (!style().left().isAuto()) {
-        if (!style().right().isAuto() && !containingBlock->style().isLeftToRightDirection())
-            offset.setWidth(-valueForLength(style().right(), containingBlock->availableWidth()));
+        if (!style().right().isAuto() && !containingBlock()->style().isLeftToRightDirection())
+            offset.setWidth(-valueForLength(style().right(), !style().right().isFixed() ? containingBlock()->availableWidth() : LayoutUnit()));
         else
-            offset.expand(valueForLength(style().left(), containingBlock->availableWidth()), 0);
+            offset.expand(valueForLength(style().left(), !style().left().isFixed() ? containingBlock()->availableWidth() : LayoutUnit()), 0);
     } else if (!style().right().isAuto()) {
-        offset.expand(-valueForLength(style().right(), containingBlock->availableWidth()), 0);
+        offset.expand(-valueForLength(style().right(), !style().right().isFixed() ? containingBlock()->availableWidth() : LayoutUnit()), 0);
     }
 
     // If the containing block of a relatively positioned element does not
@@ -298,16 +299,16 @@ LayoutSize RenderBoxModelObject::relativePositionOffset() const
     // calculate the percent offset based on this height.
     // See <https://bugs.webkit.org/show_bug.cgi?id=26396>.
     if (!style().top().isAuto()
-        && (!containingBlock->hasAutoHeightOrContainingBlockWithAutoHeight()
-            || !style().top().isPercent()
-            || containingBlock->stretchesToViewport()))
-        offset.expand(0, valueForLength(style().top(), containingBlock->availableHeight()));
+        && (!style().top().isPercent()
+            || !containingBlock()->hasAutoHeightOrContainingBlockWithAutoHeight()
+            || containingBlock()->stretchesToViewport()))
+        offset.expand(0, valueForLength(style().top(), !style().top().isFixed() ? containingBlock()->availableHeight() : LayoutUnit()));
 
     else if (!style().bottom().isAuto()
-        && (!containingBlock->hasAutoHeightOrContainingBlockWithAutoHeight()
-            || !style().bottom().isPercent()
-            || containingBlock->stretchesToViewport()))
-        offset.expand(0, -valueForLength(style().bottom(), containingBlock->availableHeight()));
+        && (!style().bottom().isPercent()
+            || !containingBlock()->hasAutoHeightOrContainingBlockWithAutoHeight()
+            || containingBlock()->stretchesToViewport()))
+        offset.expand(0, -valueForLength(style().bottom(), !style().bottom().isFixed() ? containingBlock()->availableHeight() : LayoutUnit()));
 
     return offset;
 }