| Index: third_party/WebKit/Source/build/scripts/make_computed_style_base.py
|
| diff --git a/third_party/WebKit/Source/build/scripts/make_computed_style_base.py b/third_party/WebKit/Source/build/scripts/make_computed_style_base.py
|
| index 174941950ab6248421308683cec646ce9470580b..3da23abe6b2956a7042e19cdbd3bbba8d84cb579 100755
|
| --- a/third_party/WebKit/Source/build/scripts/make_computed_style_base.py
|
| +++ b/third_party/WebKit/Source/build/scripts/make_computed_style_base.py
|
| @@ -19,35 +19,35 @@ from name_utilities import (
|
| # TODO(shend): Put this into its own JSON5 file.
|
| NONPROPERTIES = [
|
| {'name': 'IsLink', 'field_template': 'monotonic_flag',
|
| - 'inherited': False, 'independent': False},
|
| - {'name': 'OriginalDisplay', 'field_template': 'keyword', 'initial_keyword': 'inline',
|
| + 'inherited': False, 'independent': False, 'default_value': False},
|
| + {'name': 'OriginalDisplay', 'field_template': 'keyword', 'default_value': 'inline',
|
| 'type_name': 'EDisplay', 'inherited': False, 'independent': False,
|
| 'keywords': [
|
| "inline", "block", "list-item", "inline-block", "table", "inline-table", "table-row-group", "table-header-group",
|
| "table-footer-group", "table-row", "table-column-group", "table-column", "table-cell", "table-caption", "-webkit-box",
|
| "-webkit-inline-box", "flex", "inline-flex", "grid", "inline-grid", "contents", "flow-root", "none"
|
| ]},
|
| - {'name': 'InsideLink', 'field_template': 'keyword', 'initial_keyword': 'not-inside-link',
|
| + {'name': 'InsideLink', 'field_template': 'keyword', 'default_value': 'not-inside-link',
|
| 'keywords': ['not-inside-link', 'inside-unvisited-link', 'inside-visited-link'],
|
| 'inherited': True, 'independent': False},
|
| # Style can not be shared.
|
| {'name': 'Unique', 'field_template': 'monotonic_flag',
|
| - 'inherited': False, 'independent': False},
|
| + 'inherited': False, 'independent': False, 'default_value': False},
|
| # Whether this style is affected by these pseudo-classes.
|
| {'name': 'AffectedByFocus', 'field_template': 'monotonic_flag',
|
| - 'inherited': False, 'independent': False},
|
| + 'inherited': False, 'independent': False, 'default_value': False},
|
| {'name': 'AffectedByHover', 'field_template': 'monotonic_flag',
|
| - 'inherited': False, 'independent': False},
|
| + 'inherited': False, 'independent': False, 'default_value': False},
|
| {'name': 'AffectedByActive', 'field_template': 'monotonic_flag',
|
| - 'inherited': False, 'independent': False},
|
| + 'inherited': False, 'independent': False, 'default_value': False},
|
| {'name': 'AffectedByDrag', 'field_template': 'monotonic_flag',
|
| - 'inherited': False, 'independent': False},
|
| + 'inherited': False, 'independent': False, 'default_value': False},
|
| # A non-inherited property references a variable or @apply is used
|
| {'name': 'HasVariableReferenceFromNonInheritedProperty', 'field_template': 'monotonic_flag',
|
| - 'inherited': False, 'independent': False},
|
| + 'inherited': False, 'independent': False, 'default_value': False},
|
| # Explicitly inherits a non-inherited property
|
| {'name': 'HasExplicitlyInheritedProperties', 'field_template': 'monotonic_flag',
|
| - 'inherited': False, 'independent': False},
|
| + 'inherited': False, 'independent': False, 'default_value': False},
|
| # These properties only have generated storage, and their methods are handwritten in ComputedStyle.
|
| # TODO(shend): Remove these fields and delete the 'storage_only' template.
|
| {'name': 'EmptyState', 'field_template': 'storage_only', 'size': 1, 'default_value': 'false',
|
| @@ -122,6 +122,9 @@ class Field(object):
|
| self.initial_method_name = method_name('Initial' + name_for_methods)
|
| self.resetter_method_name = method_name('Reset' + name_for_methods)
|
|
|
| + # If the size of the field is not None, it means it is a bit field
|
| + self.is_bit_field = self.size is not None
|
| +
|
| assert len(kwargs) == 0, 'Unexpected arguments provided to Field: ' + str(kwargs)
|
|
|
|
|
| @@ -167,18 +170,23 @@ def _create_field(field_role, property_):
|
|
|
| name_for_methods = property_['name_for_methods']
|
|
|
| + assert property_['default_value'] is not None, \
|
| + ('MakeComputedStyleBase requires an default value for all fields, none specified '
|
| + 'for property ' + property_['name'])
|
| +
|
| if property_['field_template'] == 'keyword':
|
| - assert property_['initial_keyword'] is not None, \
|
| - ('MakeComputedStyleBase requires an initial keyword for keyword fields, none specified '
|
| - 'for property ' + property_['name'])
|
| type_name = property_['type_name']
|
| - default_value = type_name + '::' + enum_value_name(property_['initial_keyword'])
|
| + default_value = type_name + '::' + enum_value_name(property_['default_value'])
|
| size = int(math.ceil(math.log(len(property_['keywords']), 2)))
|
| elif property_['field_template'] == 'storage_only':
|
| # 'storage_only' fields need to specify a size, type_name and default_value
|
| type_name = property_['type_name']
|
| default_value = property_['default_value']
|
| size = property_['size']
|
| + elif property_['field_template'] == 'external':
|
| + type_name = property_['type_name']
|
| + default_value = property_['default_value']
|
| + size = None
|
| else:
|
| assert property_['field_template'] in ('flag', 'monotonic_flag')
|
| type_name = 'bool'
|
| @@ -244,7 +252,7 @@ def _pack_fields(fields):
|
| # ensure ComputedStyleBase results in the expected size. If that
|
| # static_assert fails, this code is falling into the small number of
|
| # cases that are suboptimal, and may need to be rethought.
|
| - # For more details on packing bitfields to reduce padding, see:
|
| + # For more details on packing bit fields to reduce padding, see:
|
| # http://www.catb.org/esr/structure-packing/#_bitfields
|
| field_buckets = []
|
| # Consider fields in descending order of size to reduce fragmentation
|
| @@ -296,31 +304,37 @@ class ComputedStyleBaseWriter(make_style_builder.StyleBuilderWriter):
|
| all_fields = (_create_fields('property', property_values) +
|
| _create_fields('nonproperty', NONPROPERTIES))
|
|
|
| - # Group fields into buckets
|
| - field_buckets = _pack_fields(all_fields)
|
| + # Separate the normal fields from the bit fields
|
| + bit_fields = [field for field in all_fields if field.is_bit_field]
|
| + normal_fields = [field for field in all_fields if not field.is_bit_field]
|
| +
|
| + # Pack bit fields into buckets
|
| + field_buckets = _pack_fields(bit_fields)
|
|
|
| # The expected size of ComputedStyleBase is equivalent to as many words
|
| # as the total number of buckets.
|
| - self._expected_total_field_bytes = len(field_buckets)
|
| + self._expected_bit_field_bytes = len(field_buckets)
|
|
|
| # The most optimal size of ComputedStyleBase is the total sum of all the
|
| # field sizes, rounded up to the nearest word. If this produces the
|
| # incorrect value, either the packing algorithm is not optimal or there
|
| # is no way to pack the fields such that excess padding space is not
|
| # added.
|
| - # If this fails, increase padding_bytes by 1, but be aware that
|
| + # If this fails, increase extra_padding_bytes by 1, but be aware that
|
| # this also increases ComputedStyleBase by 1 word.
|
| - # We should be able to bring padding_bytes back to 0 from time to
|
| + # We should be able to bring extra_padding_bytes back to 0 from time to
|
| # time.
|
| - padding_bytes = 0
|
| - optimal_total_field_bytes = int(math.ceil(sum(f.size for f in all_fields) / 32.0))
|
| - real_total_field_bytes = optimal_total_field_bytes + padding_bytes
|
| - assert self._expected_total_field_bytes == real_total_field_bytes, \
|
| + extra_padding_bytes = 0
|
| + optimal_bit_field_bytes = int(math.ceil(sum(f.size for f in bit_fields) / 32.0))
|
| + real_bit_field_bytes = optimal_bit_field_bytes + extra_padding_bytes
|
| + assert self._expected_bit_field_bytes == real_bit_field_bytes, \
|
| ('The field packing algorithm produced %s bytes, optimal is %s bytes' %
|
| - (self._expected_total_field_bytes, real_total_field_bytes))
|
| + (self._expected_bit_field_bytes, real_bit_field_bytes))
|
| +
|
| + # Normal fields go first, then the bit fields.
|
| + self._fields = list(normal_fields)
|
|
|
| # Order the fields so fields in each bucket are adjacent.
|
| - self._fields = []
|
| for bucket in field_buckets:
|
| for field in bucket:
|
| self._fields.append(field)
|
| @@ -335,7 +349,6 @@ class ComputedStyleBaseWriter(make_style_builder.StyleBuilderWriter):
|
| 'enums': self._generated_enums,
|
| 'include_paths': self._include_paths,
|
| 'fields': self._fields,
|
| - 'expected_total_field_bytes': self._expected_total_field_bytes,
|
| }
|
|
|
| @template_expander.use_jinja('ComputedStyleBase.cpp.tmpl')
|
| @@ -344,7 +357,7 @@ class ComputedStyleBaseWriter(make_style_builder.StyleBuilderWriter):
|
| 'properties': self._properties,
|
| 'enums': self._generated_enums,
|
| 'fields': self._fields,
|
| - 'expected_total_field_bytes': self._expected_total_field_bytes,
|
| + 'expected_bit_field_bytes': self._expected_bit_field_bytes,
|
| }
|
|
|
| @template_expander.use_jinja('ComputedStyleBaseConstants.h.tmpl')
|
| @@ -353,7 +366,6 @@ class ComputedStyleBaseWriter(make_style_builder.StyleBuilderWriter):
|
| 'properties': self._properties,
|
| 'enums': self._generated_enums,
|
| 'fields': self._fields,
|
| - 'expected_total_field_bytes': self._expected_total_field_bytes,
|
| }
|
|
|
| @template_expander.use_jinja('CSSValueIDMappingsGenerated.h.tmpl')
|
| @@ -363,7 +375,7 @@ class ComputedStyleBaseWriter(make_style_builder.StyleBuilderWriter):
|
| for property_ in self._properties.values():
|
| if property_['field_template'] == 'keyword':
|
| mappings[property_['type_name']] = {
|
| - 'default_value': enum_value_name(property_['initial_keyword']),
|
| + 'default_value': enum_value_name(property_['default_value']),
|
| 'mapping': [(enum_value_name(k), enum_for_css_keyword(k)) for k in property_['keywords']],
|
| }
|
|
|
|
|