[css-grid] Refactor GridSpan to avoid pointers

Add new boolean to know if a GridSpan is definite or indefinite.
That way we don't need to use pointers and we can always have two
GridSpans in GridCoordinate, if the position is "auto" the GridSpan will
be marked as indefinite. This will allow in a follow-up patch to avoid
repeated calls to methods that resolve positions.

Most operations in GridSpan are restricted to definite GridSpans (access
to positions, iterator, etc.). For indefinite GridSpans we only need to
know that they're indefinite we shouldn't use the rest of the data.

No new tests, no change of behavior.

BUG=444011

Review URL: https://codereview.chromium.org/1459373002

Cr-Commit-Position: refs/heads/master@{#361119}
diff --git a/third_party/WebKit/Source/core/css/CSSGridTemplateAreasValue.cpp b/third_party/WebKit/Source/core/css/CSSGridTemplateAreasValue.cpp
index 42e0bad47..0fefa43 100644
--- a/third_party/WebKit/Source/core/css/CSSGridTemplateAreasValue.cpp
+++ b/third_party/WebKit/Source/core/css/CSSGridTemplateAreasValue.cpp
@@ -51,13 +51,13 @@
 
     for (const auto& item : gridAreaMap) {
         const GridCoordinate& coordinate = item.value;
-        if (row >= coordinate.rows.resolvedInitialPosition.toInt() && row < coordinate.rows.resolvedFinalPosition.toInt())
+        if (row >= coordinate.rows.resolvedInitialPosition().toInt() && row < coordinate.rows.resolvedFinalPosition().toInt())
             candidates.append(item.key);
     }
 
     for (const auto& item : gridAreaMap) {
         const GridCoordinate& coordinate = item.value;
-        if (column >= coordinate.columns.resolvedInitialPosition.toInt() && column < coordinate.columns.resolvedFinalPosition.toInt() && candidates.contains(item.key))
+        if (column >= coordinate.columns.resolvedInitialPosition().toInt() && column < coordinate.columns.resolvedFinalPosition().toInt() && candidates.contains(item.key))
             return item.key;
     }
 
diff --git a/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp
index fcecfbd8..8d184d6 100644
--- a/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp
@@ -2954,24 +2954,24 @@
 
         NamedGridAreaMap::iterator gridAreaIt = gridAreaMap.find(gridAreaName);
         if (gridAreaIt == gridAreaMap.end()) {
-            gridAreaMap.add(gridAreaName, GridCoordinate(GridSpan(rowCount, rowCount + 1), GridSpan(currentCol, lookAheadCol)));
+            gridAreaMap.add(gridAreaName, GridCoordinate(GridSpan::definiteGridSpan(rowCount, rowCount + 1), GridSpan::definiteGridSpan(currentCol, lookAheadCol)));
         } else {
             GridCoordinate& gridCoordinate = gridAreaIt->value;
 
             // The following checks test that the grid area is a single filled-in rectangle.
             // 1. The new row is adjacent to the previously parsed row.
-            if (rowCount != gridCoordinate.rows.resolvedFinalPosition.toInt())
+            if (rowCount != gridCoordinate.rows.resolvedFinalPosition().toInt())
                 return false;
 
             // 2. The new area starts at the same position as the previously parsed area.
-            if (currentCol != gridCoordinate.columns.resolvedInitialPosition.toInt())
+            if (currentCol != gridCoordinate.columns.resolvedInitialPosition().toInt())
                 return false;
 
             // 3. The new area ends at the same position as the previously parsed area.
-            if (lookAheadCol != gridCoordinate.columns.resolvedFinalPosition.toInt())
+            if (lookAheadCol != gridCoordinate.columns.resolvedFinalPosition().toInt())
                 return false;
 
-            ++gridCoordinate.rows.resolvedFinalPosition;
+            gridCoordinate.rows = GridSpan::definiteGridSpan(gridCoordinate.rows.resolvedInitialPosition(), gridCoordinate.rows.resolvedFinalPosition().next());
         }
         currentCol = lookAheadCol - 1;
     }
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp b/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp
index 4b0fbc2..42ecf49 100644
--- a/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp
@@ -521,12 +521,12 @@
         GridSpan areaSpan = direction == ForRows ? namedGridAreaEntry.value.rows : namedGridAreaEntry.value.columns;
         {
             NamedGridLinesMap::AddResult startResult = namedGridLines.add(namedGridAreaEntry.key + "-start", Vector<size_t>());
-            startResult.storedValue->value.append(areaSpan.resolvedInitialPosition.toInt());
+            startResult.storedValue->value.append(areaSpan.resolvedInitialPosition().toInt());
             std::sort(startResult.storedValue->value.begin(), startResult.storedValue->value.end());
         }
         {
             NamedGridLinesMap::AddResult endResult = namedGridLines.add(namedGridAreaEntry.key + "-end", Vector<size_t>());
-            endResult.storedValue->value.append(areaSpan.resolvedFinalPosition.toInt());
+            endResult.storedValue->value.append(areaSpan.resolvedFinalPosition().toInt());
             std::sort(endResult.storedValue->value.begin(), endResult.storedValue->value.end());
         }
     }
diff --git a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
index 1f24ae7..3b32e5d 100644
--- a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
@@ -209,7 +209,7 @@
         const size_t endOfVaryingTrackIndex = (m_direction == ForColumns) ? m_grid.size() : m_grid[0].size();
         for (; varyingTrackIndex < endOfVaryingTrackIndex; ++varyingTrackIndex) {
             if (checkEmptyCells(rowSpan, columnSpan)) {
-                OwnPtr<GridCoordinate> result = adoptPtr(new GridCoordinate(GridSpan(m_rowIndex, m_rowIndex + rowSpan), GridSpan(m_columnIndex, m_columnIndex + columnSpan)));
+                OwnPtr<GridCoordinate> result = adoptPtr(new GridCoordinate(GridSpan::definiteGridSpan(m_rowIndex, m_rowIndex + rowSpan), GridSpan::definiteGridSpan(m_columnIndex, m_columnIndex + columnSpan)));
                 // Advance the iterator to avoid an infinite loop where we would return the same grid area over and over.
                 ++varyingTrackIndex;
                 return result.release();
@@ -536,7 +536,7 @@
     // 4. Grow all Grid tracks having a fraction as the MaxTrackSizingFunction.
     double flexFraction = 0;
     if (hasDefiniteFreeSpace) {
-        flexFraction = findFlexFactorUnitSize(tracks, GridSpan(0, tracks.size()), direction, initialFreeSpace);
+        flexFraction = findFlexFactorUnitSize(tracks, GridSpan::definiteGridSpan(0, tracks.size()), direction, initialFreeSpace);
     } else {
         for (const auto& trackIndex : flexibleSizedTracksIndex)
             flexFraction = std::max(flexFraction, normalizedFlexFraction(tracks[trackIndex], gridTrackSize(direction, trackIndex).maxTrackBreadth().flex()));
@@ -547,7 +547,7 @@
                 const GridSpan span = cachedGridSpan(*gridItem, direction);
 
                 // Do not include already processed items.
-                if (i > 0 && span.resolvedInitialPosition.toInt() <= flexibleSizedTracksIndex[i - 1])
+                if (i > 0 && span.resolvedInitialPosition().toInt() <= flexibleSizedTracksIndex[i - 1])
                     continue;
 
                 flexFraction = std::max(flexFraction, findFlexFactorUnitSize(tracks, span, direction, maxContentForChild(*gridItem, direction, sizingData.columnTracks)));
@@ -834,7 +834,7 @@
 
 void LayoutGrid::resolveContentBasedTrackSizingFunctionsForNonSpanningItems(GridTrackSizingDirection direction, const GridSpan& span, LayoutBox& gridItem, GridTrack& track, Vector<GridTrack>& columnTracks)
 {
-    const GridResolvedPosition trackPosition = span.resolvedInitialPosition;
+    const GridResolvedPosition trackPosition = span.resolvedInitialPosition();
     GridTrackSize trackSize = gridTrackSize(direction, trackPosition.toInt());
 
     if (trackSize.hasMinContentMinTrackBreadth())
@@ -1105,7 +1105,7 @@
 
 void LayoutGrid::insertItemIntoGrid(LayoutBox& child, const GridCoordinate& coordinate)
 {
-    ensureGridSize(coordinate.rows.resolvedFinalPosition.toInt(), coordinate.columns.resolvedFinalPosition.toInt());
+    ensureGridSize(coordinate.rows.resolvedFinalPosition().toInt(), coordinate.columns.resolvedFinalPosition().toInt());
 
     for (GridSpan::iterator row = coordinate.rows.begin(); row != coordinate.rows.end(); ++row) {
         for (GridSpan::iterator column = coordinate.columns.begin(); column != coordinate.columns.end(); ++column)
@@ -1134,17 +1134,17 @@
         if (child->isOutOfFlowPositioned())
             continue;
 
-        OwnPtr<GridSpan> rowPositions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *child, ForRows);
-        OwnPtr<GridSpan> columnPositions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *child, ForColumns);
-        if (!rowPositions || !columnPositions) {
-            GridSpan* majorAxisPositions = (autoPlacementMajorAxisDirection() == ForColumns) ? columnPositions.get() : rowPositions.get();
-            if (!majorAxisPositions)
+        GridSpan rowPositions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *child, ForRows);
+        GridSpan columnPositions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *child, ForColumns);
+        if (!rowPositions.isDefinite() || !columnPositions.isDefinite()) {
+            GridSpan majorAxisPositions = (autoPlacementMajorAxisDirection() == ForColumns) ? columnPositions : rowPositions;
+            if (!majorAxisPositions.isDefinite())
                 autoMajorAxisAutoGridItems.append(child);
             else
                 specifiedMajorAxisAutoGridItems.append(child);
             continue;
         }
-        insertItemIntoGrid(*child, GridCoordinate(*rowPositions, *columnPositions));
+        insertItemIntoGrid(*child, GridCoordinate(rowPositions, columnPositions));
     }
 
     ASSERT(gridRowCount() >= GridResolvedPosition::explicitGridRowCount(*style()));
@@ -1173,24 +1173,24 @@
         m_gridItemsIndexesMap.set(child, childIndex++);
 
         // This function bypasses the cache (cachedGridCoordinate()) as it is used to build it.
-        OwnPtr<GridSpan> rowPositions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *child, ForRows);
-        OwnPtr<GridSpan> columnPositions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *child, ForColumns);
+        GridSpan rowPositions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *child, ForRows);
+        GridSpan columnPositions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *child, ForColumns);
 
         // |positions| is 0 if we need to run the auto-placement algorithm.
-        if (rowPositions) {
-            maximumRowIndex = std::max<size_t>(maximumRowIndex, rowPositions->resolvedFinalPosition.toInt());
+        if (rowPositions.isDefinite()) {
+            maximumRowIndex = std::max<size_t>(maximumRowIndex, rowPositions.resolvedFinalPosition().toInt());
         } else {
             // Grow the grid for items with a definite row span, getting the largest such span.
             GridSpan positions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(*style(), *child, ForRows, GridResolvedPosition(0));
-            maximumRowIndex = std::max<size_t>(maximumRowIndex, positions.resolvedFinalPosition.toInt());
+            maximumRowIndex = std::max<size_t>(maximumRowIndex, positions.resolvedFinalPosition().toInt());
         }
 
-        if (columnPositions) {
-            maximumColumnIndex = std::max<size_t>(maximumColumnIndex, columnPositions->resolvedFinalPosition.toInt());
+        if (columnPositions.isDefinite()) {
+            maximumColumnIndex = std::max<size_t>(maximumColumnIndex, columnPositions.resolvedFinalPosition().toInt());
         } else {
             // Grow the grid for items with a definite column span, getting the largest such span.
             GridSpan positions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(*style(), *child, ForColumns, GridResolvedPosition(0));
-            maximumColumnIndex = std::max<size_t>(maximumColumnIndex, positions.resolvedFinalPosition.toInt());
+            maximumColumnIndex = std::max<size_t>(maximumColumnIndex, positions.resolvedFinalPosition().toInt());
         }
     }
 
@@ -1218,18 +1218,18 @@
     HashMap<unsigned, unsigned, DefaultHash<unsigned>::Hash, WTF::UnsignedWithZeroKeyHashTraits<unsigned>> minorAxisCursors;
 
     for (const auto& autoGridItem : autoGridItems) {
-        OwnPtr<GridSpan> majorAxisPositions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *autoGridItem, autoPlacementMajorAxisDirection());
+        GridSpan majorAxisPositions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *autoGridItem, autoPlacementMajorAxisDirection());
         GridSpan minorAxisPositions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(*style(), *autoGridItem, autoPlacementMinorAxisDirection(), GridResolvedPosition(0));
-        unsigned majorAxisInitialPosition = majorAxisPositions->resolvedInitialPosition.toInt();
+        unsigned majorAxisInitialPosition = majorAxisPositions.resolvedInitialPosition().toInt();
 
-        GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), majorAxisPositions->resolvedInitialPosition.toInt(), isGridAutoFlowDense ? 0 : minorAxisCursors.get(majorAxisInitialPosition));
-        OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea(majorAxisPositions->integerSpan(), minorAxisPositions.integerSpan());
+        GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), majorAxisPositions.resolvedInitialPosition().toInt(), isGridAutoFlowDense ? 0 : minorAxisCursors.get(majorAxisInitialPosition));
+        OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea(majorAxisPositions.integerSpan(), minorAxisPositions.integerSpan());
         if (!emptyGridArea)
-            emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(*autoGridItem, autoPlacementMajorAxisDirection(), *majorAxisPositions);
+            emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(*autoGridItem, autoPlacementMajorAxisDirection(), majorAxisPositions);
         insertItemIntoGrid(*autoGridItem, *emptyGridArea);
 
         if (!isGridAutoFlowDense)
-            minorAxisCursors.set(majorAxisInitialPosition, isForColumns ? emptyGridArea->rows.resolvedInitialPosition.toInt() : emptyGridArea->columns.resolvedInitialPosition.toInt());
+            minorAxisCursors.set(majorAxisInitialPosition, isForColumns ? emptyGridArea->rows.resolvedInitialPosition().toInt() : emptyGridArea->columns.resolvedInitialPosition().toInt());
     }
 }
 
@@ -1251,8 +1251,8 @@
 
 void LayoutGrid::placeAutoMajorAxisItemOnGrid(LayoutBox& gridItem, std::pair<size_t, size_t>& autoPlacementCursor)
 {
-    OwnPtr<GridSpan> minorAxisPositions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), gridItem, autoPlacementMinorAxisDirection());
-    ASSERT(!GridResolvedPosition::resolveGridPositionsFromStyle(*style(), gridItem, autoPlacementMajorAxisDirection()));
+    GridSpan minorAxisPositions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), gridItem, autoPlacementMinorAxisDirection());
+    ASSERT(!GridResolvedPosition::resolveGridPositionsFromStyle(*style(), gridItem, autoPlacementMajorAxisDirection()).isDefinite());
     GridSpan majorAxisPositions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(*style(), gridItem, autoPlacementMajorAxisDirection(), GridResolvedPosition(0));
 
     const size_t endOfMajorAxis = (autoPlacementMajorAxisDirection() == ForColumns) ? gridColumnCount() : gridRowCount();
@@ -1260,18 +1260,18 @@
     size_t minorAxisAutoPlacementCursor = autoPlacementMajorAxisDirection() == ForColumns ? autoPlacementCursor.first : autoPlacementCursor.second;
 
     OwnPtr<GridCoordinate> emptyGridArea;
-    if (minorAxisPositions) {
+    if (minorAxisPositions.isDefinite()) {
         // Move to the next track in major axis if initial position in minor axis is before auto-placement cursor.
-        if (minorAxisPositions->resolvedInitialPosition.toInt() < minorAxisAutoPlacementCursor)
+        if (minorAxisPositions.resolvedInitialPosition().toInt() < minorAxisAutoPlacementCursor)
             majorAxisAutoPlacementCursor++;
 
         if (majorAxisAutoPlacementCursor < endOfMajorAxis) {
-            GridIterator iterator(m_grid, autoPlacementMinorAxisDirection(), minorAxisPositions->resolvedInitialPosition.toInt(), majorAxisAutoPlacementCursor);
-            emptyGridArea = iterator.nextEmptyGridArea(minorAxisPositions->integerSpan(), majorAxisPositions.integerSpan());
+            GridIterator iterator(m_grid, autoPlacementMinorAxisDirection(), minorAxisPositions.resolvedInitialPosition().toInt(), majorAxisAutoPlacementCursor);
+            emptyGridArea = iterator.nextEmptyGridArea(minorAxisPositions.integerSpan(), majorAxisPositions.integerSpan());
         }
 
         if (!emptyGridArea)
-            emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(gridItem, autoPlacementMinorAxisDirection(), *minorAxisPositions);
+            emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(gridItem, autoPlacementMinorAxisDirection(), minorAxisPositions);
     } else {
         GridSpan minorAxisPositions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(*style(), gridItem, autoPlacementMinorAxisDirection(), GridResolvedPosition(0));
 
@@ -1281,7 +1281,7 @@
 
             if (emptyGridArea) {
                 // Check that it fits in the minor axis direction, as we shouldn't grow in that direction here (it was already managed in populateExplicitGridAndOrderIterator()).
-                GridResolvedPosition minorAxisFinalPositionIndex = autoPlacementMinorAxisDirection() == ForColumns ? emptyGridArea->columns.resolvedFinalPosition : emptyGridArea->rows.resolvedFinalPosition;
+                GridResolvedPosition minorAxisFinalPositionIndex = autoPlacementMinorAxisDirection() == ForColumns ? emptyGridArea->columns.resolvedFinalPosition() : emptyGridArea->rows.resolvedFinalPosition();
                 const size_t endOfMinorAxis = autoPlacementMinorAxisDirection() == ForColumns ? gridColumnCount() : gridRowCount();
                 if (minorAxisFinalPositionIndex.toInt() <= endOfMinorAxis)
                     break;
@@ -1301,8 +1301,8 @@
 
     insertItemIntoGrid(gridItem, *emptyGridArea);
     // Move auto-placement cursor to the new position.
-    autoPlacementCursor.first = emptyGridArea->rows.resolvedInitialPosition.toInt();
-    autoPlacementCursor.second = emptyGridArea->columns.resolvedInitialPosition.toInt();
+    autoPlacementCursor.first = emptyGridArea->rows.resolvedInitialPosition().toInt();
+    autoPlacementCursor.second = emptyGridArea->columns.resolvedInitialPosition().toInt();
 }
 
 GridTrackSizingDirection LayoutGrid::autoPlacementMajorAxisDirection() const
@@ -1405,8 +1405,8 @@
 
 #if ENABLE(ASSERT)
         const GridCoordinate& coordinate = cachedGridCoordinate(*child);
-        ASSERT(coordinate.columns.resolvedInitialPosition.toInt() < sizingData.columnTracks.size());
-        ASSERT(coordinate.rows.resolvedInitialPosition.toInt() < sizingData.rowTracks.size());
+        ASSERT(coordinate.columns.resolvedInitialPosition().toInt() < sizingData.columnTracks.size());
+        ASSERT(coordinate.rows.resolvedInitialPosition().toInt() < sizingData.rowTracks.size());
 #endif
         child->setLogicalLocation(findChildLogicalPosition(*child, sizingData));
 
@@ -1462,8 +1462,8 @@
 {
     ASSERT(child.isHorizontalWritingMode() == isHorizontalWritingMode());
 
-    OwnPtr<GridSpan> positions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), child, direction);
-    if (!positions) {
+    GridSpan positions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), child, direction);
+    if (!positions.isDefinite()) {
         offset = LayoutUnit();
         breadth = (direction == ForColumns) ? clientLogicalWidth() : clientLogicalHeight();
         return;
@@ -1475,15 +1475,15 @@
 
     bool startIsAuto = startPosition.isAuto()
         || (startPosition.isNamedGridArea() && !GridResolvedPosition::isValidNamedLineOrArea(startPosition.namedGridLine(), styleRef(), GridResolvedPosition::initialPositionSide(direction)))
-        || (positions->resolvedInitialPosition.toInt() > lastTrackIndex);
+        || (positions.resolvedInitialPosition().toInt() > lastTrackIndex);
     bool endIsAuto = endPosition.isAuto()
         || (endPosition.isNamedGridArea() && !GridResolvedPosition::isValidNamedLineOrArea(endPosition.namedGridLine(), styleRef(), GridResolvedPosition::finalPositionSide(direction)))
-        || (positions->resolvedFinalPosition.prev().toInt() > lastTrackIndex);
+        || (positions.resolvedFinalPosition().prev().toInt() > lastTrackIndex);
 
     GridResolvedPosition firstPosition = GridResolvedPosition(0);
-    GridResolvedPosition initialPosition = startIsAuto ? firstPosition : positions->resolvedInitialPosition;
+    GridResolvedPosition initialPosition = startIsAuto ? firstPosition : positions.resolvedInitialPosition();
     GridResolvedPosition lastPosition = GridResolvedPosition(lastTrackIndex);
-    GridResolvedPosition finalPosition = endIsAuto ? lastPosition : positions->resolvedFinalPosition.prev();
+    GridResolvedPosition finalPosition = endIsAuto ? lastPosition : positions.resolvedFinalPosition().prev();
 
     // Positioned children do not grow the grid, so we need to clamp the positions to avoid ending up outside of it.
     initialPosition = std::min<GridResolvedPosition>(initialPosition, lastPosition);
@@ -1547,10 +1547,10 @@
     const Vector<GridTrack>& tracks = (direction == ForColumns) ? sizingData.columnTracks : sizingData.rowTracks;
     const GridSpan& span = cachedGridSpan(child, direction);
     const Vector<LayoutUnit>& linePositions = (direction == ForColumns) ? m_columnPositions : m_rowPositions;
-    LayoutUnit initialTrackPosition = linePositions[span.resolvedInitialPosition.toInt()];
-    LayoutUnit finalTrackPosition = linePositions[span.resolvedFinalPosition.prev().toInt()];
+    LayoutUnit initialTrackPosition = linePositions[span.resolvedInitialPosition().toInt()];
+    LayoutUnit finalTrackPosition = linePositions[span.resolvedFinalPosition().prev().toInt()];
     // Track Positions vector stores the 'start' grid line of each track, so w have to add last track's baseSize.
-    return finalTrackPosition - initialTrackPosition + tracks[span.resolvedFinalPosition.prev().toInt()].baseSize();
+    return finalTrackPosition - initialTrackPosition + tracks[span.resolvedFinalPosition().prev().toInt()].baseSize();
 }
 
 void LayoutGrid::populateGridPositions(GridSizingData& sizingData)
@@ -1857,7 +1857,7 @@
 LayoutUnit LayoutGrid::columnAxisOffsetForChild(const LayoutBox& child) const
 {
     const GridSpan& rowsSpan = cachedGridSpan(child, ForRows);
-    size_t childStartLine = rowsSpan.resolvedInitialPosition.toInt();
+    size_t childStartLine = rowsSpan.resolvedInitialPosition().toInt();
     LayoutUnit startOfRow = m_rowPositions[childStartLine];
     LayoutUnit startPosition = startOfRow + marginBeforeForChild(child);
     if (hasAutoMarginsInColumnAxis(child))
@@ -1868,7 +1868,7 @@
         return startPosition;
     case GridAxisEnd:
     case GridAxisCenter: {
-        size_t childEndLine = rowsSpan.resolvedFinalPosition.toInt();
+        size_t childEndLine = rowsSpan.resolvedFinalPosition().toInt();
         LayoutUnit endOfRow = m_rowPositions[childEndLine];
         // m_rowPositions include gutters so we need to substract them to get the actual end position for a given
         // row (this does not have to be done for the last track as there are no more m_rowPositions after it)
@@ -1889,7 +1889,7 @@
 LayoutUnit LayoutGrid::rowAxisOffsetForChild(const LayoutBox& child) const
 {
     const GridSpan& columnsSpan = cachedGridSpan(child, ForColumns);
-    size_t childStartLine = columnsSpan.resolvedInitialPosition.toInt();
+    size_t childStartLine = columnsSpan.resolvedInitialPosition().toInt();
     LayoutUnit startOfColumn = m_columnPositions[childStartLine];
     LayoutUnit startPosition = startOfColumn + marginStartForChild(child);
     if (hasAutoMarginsInRowAxis(child))
@@ -1900,7 +1900,7 @@
         return startPosition;
     case GridAxisEnd:
     case GridAxisCenter: {
-        size_t childEndLine = columnsSpan.resolvedFinalPosition.toInt();
+        size_t childEndLine = columnsSpan.resolvedFinalPosition().toInt();
         LayoutUnit endOfColumn = m_columnPositions[childEndLine];
         // m_columnPositions include gutters so we need to substract them to get the actual end position for a given
         // column (this does not have to be done for the last track as there are no more m_columnPositions after it)
diff --git a/third_party/WebKit/Source/core/paint/GridPainter.cpp b/third_party/WebKit/Source/core/paint/GridPainter.cpp
index c029941c..3fa13c8 100644
--- a/third_party/WebKit/Source/core/paint/GridPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/GridPainter.cpp
@@ -25,7 +25,7 @@
         --endGridAreaIndex;
 
     // GridSpan stores lines' indexes (not tracks' indexes).
-    return GridSpan(startGridAreaIndex, endGridAreaIndex + 1);
+    return GridSpan::definiteGridSpan(startGridAreaIndex, endGridAreaIndex + 1);
 }
 
 class GridItemsSorter {
diff --git a/third_party/WebKit/Source/core/style/GridCoordinate.h b/third_party/WebKit/Source/core/style/GridCoordinate.h
index 3a1e5b6..2573be6 100644
--- a/third_party/WebKit/Source/core/style/GridCoordinate.h
+++ b/third_party/WebKit/Source/core/style/GridCoordinate.h
@@ -49,37 +49,43 @@
 struct GridSpan {
     USING_FAST_MALLOC(GridSpan);
 public:
-    static PassOwnPtr<GridSpan> create(const GridResolvedPosition& resolvedInitialPosition, const GridResolvedPosition& resolvedFinalPosition)
+
+    static GridSpan definiteGridSpan(const GridResolvedPosition& resolvedInitialPosition, const GridResolvedPosition& resolvedFinalPosition)
     {
-        return adoptPtr(new GridSpan(resolvedInitialPosition, resolvedFinalPosition));
+        return GridSpan(resolvedInitialPosition, resolvedFinalPosition, Definite);
     }
 
-    static PassOwnPtr<GridSpan> createWithSpanAgainstOpposite(const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, GridPositionSide side)
+    static GridSpan indefiniteGridSpan()
+    {
+        return GridSpan(0, 1, Indefinite);
+    }
+
+    static GridSpan definiteGridSpanWithSpanAgainstOpposite(const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, GridPositionSide side)
     {
         size_t positionOffset = position.spanPosition();
         if (side == ColumnStartSide || side == RowStartSide) {
             if (resolvedOppositePosition == 0)
-                return GridSpan::create(resolvedOppositePosition, resolvedOppositePosition.next());
+                return GridSpan::definiteGridSpan(resolvedOppositePosition, resolvedOppositePosition.next());
 
             GridResolvedPosition initialResolvedPosition = GridResolvedPosition(std::max<int>(0, resolvedOppositePosition.toInt() - positionOffset));
-            return GridSpan::create(initialResolvedPosition, resolvedOppositePosition);
+            return GridSpan::definiteGridSpan(initialResolvedPosition, resolvedOppositePosition);
         }
 
-        return GridSpan::create(resolvedOppositePosition, GridResolvedPosition(resolvedOppositePosition.toInt() + positionOffset));
+        return GridSpan::definiteGridSpan(resolvedOppositePosition, GridResolvedPosition(resolvedOppositePosition.toInt() + positionOffset));
     }
 
-    static PassOwnPtr<GridSpan> createWithNamedSpanAgainstOpposite(const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, GridPositionSide side, const Vector<size_t>& gridLines)
+    static GridSpan definiteGridSpanWithNamedSpanAgainstOpposite(const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, GridPositionSide side, const Vector<size_t>& gridLines)
     {
         if (side == RowStartSide || side == ColumnStartSide)
-            return createWithInitialNamedSpanAgainstOpposite(resolvedOppositePosition, position, gridLines);
+            return definiteGridSpanWithInitialNamedSpanAgainstOpposite(resolvedOppositePosition, position, gridLines);
 
-        return createWithFinalNamedSpanAgainstOpposite(resolvedOppositePosition, position, gridLines);
+        return definiteGridSpanWithFinalNamedSpanAgainstOpposite(resolvedOppositePosition, position, gridLines);
     }
 
-    static PassOwnPtr<GridSpan> createWithInitialNamedSpanAgainstOpposite(const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, const Vector<size_t>& gridLines)
+    static GridSpan definiteGridSpanWithInitialNamedSpanAgainstOpposite(const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, const Vector<size_t>& gridLines)
     {
         if (resolvedOppositePosition == 0)
-            return GridSpan::create(resolvedOppositePosition, resolvedOppositePosition.next());
+            return GridSpan::definiteGridSpan(resolvedOppositePosition, resolvedOppositePosition.next());
 
         size_t firstLineBeforeOppositePositionIndex = 0;
         const size_t* firstLineBeforeOppositePosition = std::lower_bound(gridLines.begin(), gridLines.end(), resolvedOppositePosition.toInt());
@@ -89,10 +95,10 @@
         GridResolvedPosition resolvedGridLinePosition = GridResolvedPosition(gridLines[gridLineIndex]);
         if (resolvedGridLinePosition >= resolvedOppositePosition)
             resolvedGridLinePosition = resolvedOppositePosition.prev();
-        return GridSpan::create(resolvedGridLinePosition, resolvedOppositePosition);
+        return GridSpan::definiteGridSpan(resolvedGridLinePosition, resolvedOppositePosition);
     }
 
-    static PassOwnPtr<GridSpan> createWithFinalNamedSpanAgainstOpposite(const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, const Vector<size_t>& gridLines)
+    static GridSpan definiteGridSpanWithFinalNamedSpanAgainstOpposite(const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, const Vector<size_t>& gridLines)
     {
         size_t firstLineAfterOppositePositionIndex = gridLines.size() - 1;
         const size_t* firstLineAfterOppositePosition = std::upper_bound(gridLines.begin(), gridLines.end(), resolvedOppositePosition.toInt());
@@ -103,40 +109,66 @@
         if (resolvedGridLinePosition <= resolvedOppositePosition)
             resolvedGridLinePosition = resolvedOppositePosition.next();
 
-        return GridSpan::create(resolvedOppositePosition, resolvedGridLinePosition);
-    }
-
-    GridSpan(const GridResolvedPosition& resolvedInitialPosition, const GridResolvedPosition& resolvedFinalPosition)
-        : resolvedInitialPosition(std::min(resolvedInitialPosition.toInt(), kGridMaxTracks - 1))
-        , resolvedFinalPosition(std::min(resolvedFinalPosition.toInt(), kGridMaxTracks))
-    {
-        ASSERT(resolvedInitialPosition < resolvedFinalPosition);
+        return GridSpan::definiteGridSpan(resolvedOppositePosition, resolvedGridLinePosition);
     }
 
     bool operator==(const GridSpan& o) const
     {
-        return resolvedInitialPosition == o.resolvedInitialPosition && resolvedFinalPosition == o.resolvedFinalPosition;
+        return m_type == o.m_type && m_resolvedInitialPosition == o.m_resolvedInitialPosition && m_resolvedFinalPosition == o.m_resolvedFinalPosition;
     }
 
     size_t integerSpan() const
     {
-        return resolvedFinalPosition.toInt() - resolvedInitialPosition.toInt();
+        ASSERT(isDefinite());
+        return m_resolvedFinalPosition.toInt() - m_resolvedInitialPosition.toInt();
     }
 
-    GridResolvedPosition resolvedInitialPosition;
-    GridResolvedPosition resolvedFinalPosition;
+    const GridResolvedPosition& resolvedInitialPosition() const
+    {
+        ASSERT(isDefinite());
+        return m_resolvedInitialPosition;
+    }
+
+    const GridResolvedPosition& resolvedFinalPosition() const
+    {
+        ASSERT(isDefinite());
+        return m_resolvedFinalPosition;
+    }
 
     typedef GridResolvedPosition iterator;
 
     iterator begin() const
     {
-        return resolvedInitialPosition;
+        ASSERT(isDefinite());
+        return m_resolvedInitialPosition;
     }
 
     iterator end() const
     {
-        return resolvedFinalPosition;
+        ASSERT(isDefinite());
+        return m_resolvedFinalPosition;
     }
+
+    bool isDefinite() const
+    {
+        return m_type == Definite;
+    }
+
+private:
+
+    enum GridSpanType {Definite, Indefinite};
+
+    GridSpan(const GridResolvedPosition& resolvedInitialPosition, const GridResolvedPosition& resolvedFinalPosition, GridSpanType type)
+        : m_resolvedInitialPosition(std::min(resolvedInitialPosition.toInt(), kGridMaxTracks - 1))
+        , m_resolvedFinalPosition(std::min(resolvedFinalPosition.toInt(), kGridMaxTracks))
+        , m_type(type)
+    {
+        ASSERT(resolvedInitialPosition < resolvedFinalPosition);
+    }
+
+    GridResolvedPosition m_resolvedInitialPosition;
+    GridResolvedPosition m_resolvedFinalPosition;
+    GridSpanType m_type;
 };
 
 // This represents a grid area that spans in both rows' and columns' direction.
@@ -145,8 +177,8 @@
 public:
     // HashMap requires a default constuctor.
     GridCoordinate()
-        : columns(0, 1)
-        , rows(0, 1)
+        : columns(GridSpan::indefiniteGridSpan())
+        , rows(GridSpan::indefiniteGridSpan())
     {
     }
 
@@ -170,13 +202,13 @@
     {
         switch (side) {
         case ColumnStartSide:
-            return columns.resolvedInitialPosition;
+            return columns.resolvedInitialPosition();
         case ColumnEndSide:
-            return columns.resolvedFinalPosition;
+            return columns.resolvedFinalPosition();
         case RowStartSide:
-            return rows.resolvedInitialPosition;
+            return rows.resolvedInitialPosition();
         case RowEndSide:
-            return rows.resolvedFinalPosition;
+            return rows.resolvedFinalPosition();
         }
         ASSERT_NOT_REACHED();
         return 0;
diff --git a/third_party/WebKit/Source/core/style/GridResolvedPosition.cpp b/third_party/WebKit/Source/core/style/GridResolvedPosition.cpp
index a8d5b70..abad428 100644
--- a/third_party/WebKit/Source/core/style/GridResolvedPosition.cpp
+++ b/third_party/WebKit/Source/core/style/GridResolvedPosition.cpp
@@ -75,14 +75,14 @@
     GridResolvedPosition resolvedFinalPosition = resolvedInitialPosition.next();
 
     if (initialPosition.isSpan())
-        return *resolveGridPositionAgainstOppositePosition(gridContainerStyle, resolvedInitialPosition, initialPosition, finalSide);
+        return resolveGridPositionAgainstOppositePosition(gridContainerStyle, resolvedInitialPosition, initialPosition, finalSide);
     if (finalPosition.isSpan())
-        return *resolveGridPositionAgainstOppositePosition(gridContainerStyle, resolvedInitialPosition, finalPosition, finalSide);
+        return resolveGridPositionAgainstOppositePosition(gridContainerStyle, resolvedInitialPosition, finalPosition, finalSide);
 
-    return GridSpan(resolvedInitialPosition, resolvedFinalPosition);
+    return GridSpan::definiteGridSpan(resolvedInitialPosition, resolvedFinalPosition);
 }
 
-PassOwnPtr<GridSpan> GridResolvedPosition::resolveGridPositionsFromStyle(const ComputedStyle& gridContainerStyle, const LayoutBox& gridItem, GridTrackSizingDirection direction)
+GridSpan GridResolvedPosition::resolveGridPositionsFromStyle(const ComputedStyle& gridContainerStyle, const LayoutBox& gridItem, GridTrackSizingDirection direction)
 {
     GridPosition initialPosition, finalPosition;
     initialAndFinalPositionsFromStyle(gridContainerStyle, gridItem, direction, initialPosition, finalPosition);
@@ -92,7 +92,7 @@
 
     if (initialPosition.shouldBeResolvedAgainstOppositePosition() && finalPosition.shouldBeResolvedAgainstOppositePosition()) {
         // We can't get our grid positions without running the auto placement algorithm.
-        return nullptr;
+        return GridSpan::indefiniteGridSpan();
     }
 
     if (initialPosition.shouldBeResolvedAgainstOppositePosition()) {
@@ -114,7 +114,7 @@
     if (resolvedFinalPosition <= resolvedInitialPosition)
         resolvedFinalPosition = resolvedInitialPosition.next();
 
-    return adoptPtr(new GridSpan(resolvedInitialPosition, resolvedFinalPosition));
+    return GridSpan::definiteGridSpan(resolvedInitialPosition, resolvedFinalPosition);
 }
 
 size_t GridResolvedPosition::explicitGridColumnCount(const ComputedStyle& gridContainerStyle)
@@ -210,12 +210,12 @@
     return GridResolvedPosition(0);
 }
 
-PassOwnPtr<GridSpan> GridResolvedPosition::resolveGridPositionAgainstOppositePosition(const ComputedStyle& gridContainerStyle, const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, GridPositionSide side)
+GridSpan GridResolvedPosition::resolveGridPositionAgainstOppositePosition(const ComputedStyle& gridContainerStyle, const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, GridPositionSide side)
 {
     if (position.isAuto()) {
         if ((side == ColumnStartSide || side == RowStartSide) && resolvedOppositePosition.toInt())
-            return GridSpan::create(resolvedOppositePosition.prev(), resolvedOppositePosition);
-        return GridSpan::create(resolvedOppositePosition, resolvedOppositePosition.next());
+            return GridSpan::definiteGridSpan(resolvedOppositePosition.prev(), resolvedOppositePosition);
+        return GridSpan::definiteGridSpan(resolvedOppositePosition, resolvedOppositePosition.next());
     }
 
     ASSERT(position.isSpan());
@@ -226,10 +226,10 @@
         return resolveNamedGridLinePositionAgainstOppositePosition(gridContainerStyle, resolvedOppositePosition, position, side);
     }
 
-    return GridSpan::createWithSpanAgainstOpposite(resolvedOppositePosition, position, side);
+    return GridSpan::definiteGridSpanWithSpanAgainstOpposite(resolvedOppositePosition, position, side);
 }
 
-PassOwnPtr<GridSpan> GridResolvedPosition::resolveNamedGridLinePositionAgainstOppositePosition(const ComputedStyle& gridContainerStyle, const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, GridPositionSide side)
+GridSpan GridResolvedPosition::resolveNamedGridLinePositionAgainstOppositePosition(const ComputedStyle& gridContainerStyle, const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, GridPositionSide side)
 {
     ASSERT(position.isSpan());
     ASSERT(!position.namedGridLine().isNull());
@@ -243,11 +243,11 @@
     // See http://lists.w3.org/Archives/Public/www-style/2013Jun/0394.html.
     if (it == gridLinesNames.end()) {
         if ((side == ColumnStartSide || side == RowStartSide) && resolvedOppositePosition.toInt())
-            return GridSpan::create(resolvedOppositePosition.prev(), resolvedOppositePosition);
-        return GridSpan::create(resolvedOppositePosition, resolvedOppositePosition.next());
+            return GridSpan::definiteGridSpan(resolvedOppositePosition.prev(), resolvedOppositePosition);
+        return GridSpan::definiteGridSpan(resolvedOppositePosition, resolvedOppositePosition.next());
     }
 
-    return GridSpan::createWithNamedSpanAgainstOpposite(resolvedOppositePosition, position, side, it->value);
+    return GridSpan::definiteGridSpanWithNamedSpanAgainstOpposite(resolvedOppositePosition, position, side, it->value);
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/style/GridResolvedPosition.h b/third_party/WebKit/Source/core/style/GridResolvedPosition.h
index 4ac11e7..4fbcab09 100644
--- a/third_party/WebKit/Source/core/style/GridResolvedPosition.h
+++ b/third_party/WebKit/Source/core/style/GridResolvedPosition.h
@@ -37,11 +37,11 @@
     static GridPositionSide finalPositionSide(GridTrackSizingDirection);
     static void initialAndFinalPositionsFromStyle(const ComputedStyle&, const LayoutBox&, GridTrackSizingDirection, GridPosition &initialPosition, GridPosition &finalPosition);
     static GridSpan resolveGridPositionsFromAutoPlacementPosition(const ComputedStyle&, const LayoutBox&, GridTrackSizingDirection, const GridResolvedPosition&);
-    static PassOwnPtr<GridSpan> resolveGridPositionsFromStyle(const ComputedStyle&, const LayoutBox&, GridTrackSizingDirection);
+    static GridSpan resolveGridPositionsFromStyle(const ComputedStyle&, const LayoutBox&, GridTrackSizingDirection);
     static GridResolvedPosition resolveNamedGridLinePositionFromStyle(const ComputedStyle&, const GridPosition&, GridPositionSide);
     static GridResolvedPosition resolveGridPositionFromStyle(const ComputedStyle&, const GridPosition&, GridPositionSide);
-    static PassOwnPtr<GridSpan> resolveGridPositionAgainstOppositePosition(const ComputedStyle&, const GridResolvedPosition& resolvedOppositePosition, const GridPosition&, GridPositionSide);
-    static PassOwnPtr<GridSpan> resolveNamedGridLinePositionAgainstOppositePosition(const ComputedStyle&, const GridResolvedPosition& resolvedOppositePosition, const GridPosition&, GridPositionSide);
+    static GridSpan resolveGridPositionAgainstOppositePosition(const ComputedStyle&, const GridResolvedPosition& resolvedOppositePosition, const GridPosition&, GridPositionSide);
+    static GridSpan resolveNamedGridLinePositionAgainstOppositePosition(const ComputedStyle&, const GridResolvedPosition& resolvedOppositePosition, const GridPosition&, GridPositionSide);
 
     GridResolvedPosition(size_t position)
         : m_integerPosition(position)