From 19ece80529ccb8a8c6ec017eee5264b7ba62dcf8 Mon Sep 17 00:00:00 2001 From: John Mark Bell Date: Tue, 6 Sep 2011 08:15:29 +0000 Subject: A bunch more microoptimisations svn path=/trunk/libcss/; revision=12746 --- src/select/hash.c | 84 +++++++++++++------------------------------------- src/select/hash.h | 2 +- src/select/select.c | 89 ++++++++++++++++++++++++++++++----------------------- 3 files changed, 74 insertions(+), 101 deletions(-) (limited to 'src') diff --git a/src/select/hash.c b/src/select/hash.c index e6c6cf8..2cc6f4a 100644 --- a/src/select/hash.c +++ b/src/select/hash.c @@ -49,17 +49,13 @@ static css_error _insert_into_chain(css_selector_hash *ctx, hash_entry *head, static css_error _remove_from_chain(css_selector_hash *ctx, hash_entry *head, const css_selector *selector); -static css_error _iterate_elements(css_selector_hash *hash, - const css_selector **current, +static css_error _iterate_elements(const css_selector **current, const css_selector ***next); -static css_error _iterate_classes(css_selector_hash *hash, - const css_selector **current, +static css_error _iterate_classes(const css_selector **current, const css_selector ***next); -static css_error _iterate_ids(css_selector_hash *hash, - const css_selector **current, +static css_error _iterate_ids(const css_selector **current, const css_selector ***next); -static css_error _iterate_universal(css_selector_hash *hash, - const css_selector **current, +static css_error _iterate_universal(const css_selector **current, const css_selector ***next); /** @@ -510,16 +506,14 @@ css_error css__selector_hash_size(css_selector_hash *hash, size_t *size) uint32_t _hash_name(lwc_string *name) { uint32_t z = 0x811c9dc5; - size_t len = lwc_string_length(name); const char *data = lwc_string_data(name); + const char *end = data + lwc_string_length(name); - while (len > 0) { + while (data != end) { const char c = *data++; z *= 0x01000193; - z ^= ('A' <= c && c <= 'Z') ? (c + 'a' - 'A') : c; - - len--; + z ^= c & ~0x20; } return z; @@ -685,37 +679,28 @@ css_error _remove_from_chain(css_selector_hash *ctx, hash_entry *head, /** * Find the next selector that matches * - * \param hash Hash to search * \param current Current item * \param next Pointer to location to receive next item * \return CSS_OK on success, appropriate error otherwise * * If nothing further matches, CSS_OK will be returned and **next == NULL */ -css_error _iterate_elements(css_selector_hash *hash, - const css_selector **current, +css_error _iterate_elements(const css_selector **current, const css_selector ***next) { const hash_entry *head = (const hash_entry *) current; + bool match = false; + lwc_error lerror = lwc_error_ok; lwc_string *name; - if (hash == NULL || current == NULL || next == NULL) - return CSS_BADPARM; - name = head->sel->data.qname.name; /* Look for the next selector that matches the key */ - for (head = head->next; head != NULL; head = head->next) { - lwc_error lerror = lwc_error_ok; - bool match = false; - + while (match == false && (head = head->next) != NULL) { lerror = lwc_string_caseless_isequal( name, head->sel->data.qname.name, &match); if (lerror != lwc_error_ok) return css_error_from_lwc_error(lerror); - - if (match) - break; } if (head == NULL) @@ -729,31 +714,24 @@ css_error _iterate_elements(css_selector_hash *hash, /** * Find the next selector that matches * - * \param hash Hash to search * \param current Current item * \param next Pointer to location to receive next item * \return CSS_OK on success, appropriate error otherwise * * If nothing further matches, CSS_OK will be returned and **next == NULL */ -css_error _iterate_classes(css_selector_hash *hash, - const css_selector **current, +css_error _iterate_classes(const css_selector **current, const css_selector ***next) { const hash_entry *head = (const hash_entry *) current; - lwc_string *ref; - - if (hash == NULL || current == NULL || next == NULL) - return CSS_BADPARM; + bool match = false; + lwc_error lerror = lwc_error_ok; + lwc_string *name, *ref; ref = _class_name(head->sel); /* Look for the next selector that matches the key */ - for (head = head->next; head != NULL; head = head->next) { - lwc_error lerror = lwc_error_ok; - lwc_string *name; - bool match = false; - + while (match == false && (head = head->next) != NULL) { name = _class_name(head->sel); if (name == NULL) continue; @@ -762,9 +740,6 @@ css_error _iterate_classes(css_selector_hash *hash, ref, name, &match); if (lerror != lwc_error_ok) return css_error_from_lwc_error(lerror); - - if (match) - break; } if (head == NULL) @@ -778,31 +753,24 @@ css_error _iterate_classes(css_selector_hash *hash, /** * Find the next selector that matches * - * \param hash Hash to search * \param current Current item * \param next Pointer to location to receive next item * \return CSS_OK on success, appropriate error otherwise * * If nothing further matches, CSS_OK will be returned and **next == NULL */ -css_error _iterate_ids(css_selector_hash *hash, - const css_selector **current, +css_error _iterate_ids(const css_selector **current, const css_selector ***next) { const hash_entry *head = (const hash_entry *) current; - lwc_string *ref; - - if (hash == NULL || current == NULL || next == NULL) - return CSS_BADPARM; + bool match = false; + lwc_error lerror = lwc_error_ok; + lwc_string *name, *ref; ref = _id_name(head->sel); /* Look for the next selector that matches the key */ - for (head = head->next; head != NULL; head = head->next) { - lwc_error lerror = lwc_error_ok; - lwc_string *name; - bool match = false; - + while (match == false && (head = head->next) != NULL) { name = _id_name(head->sel); if (name == NULL) continue; @@ -811,9 +779,6 @@ css_error _iterate_ids(css_selector_hash *hash, ref, name, &match); if (lerror != lwc_error_ok) return css_error_from_lwc_error(lerror); - - if (match) - break; } if (head == NULL) @@ -827,22 +792,17 @@ css_error _iterate_ids(css_selector_hash *hash, /** * Find the next selector that matches * - * \param hash Hash to search * \param current Current item * \param next Pointer to location to receive next item * \return CSS_OK on success, appropriate error otherwise * * If nothing further matches, CSS_OK will be returned and **next == NULL */ -css_error _iterate_universal(css_selector_hash *hash, - const css_selector **current, +css_error _iterate_universal(const css_selector **current, const css_selector ***next) { const hash_entry *head = (const hash_entry *) current; - if (hash == NULL || current == NULL || next == NULL) - return CSS_BADPARM; - if (head->next == NULL) head = &empty_slot; else diff --git a/src/select/hash.h b/src/select/hash.h index 6b55950..06c27a9 100644 --- a/src/select/hash.h +++ b/src/select/hash.h @@ -18,7 +18,7 @@ struct css_selector; typedef struct css_selector_hash css_selector_hash; -typedef css_error (*css_selector_hash_iterator)(css_selector_hash *hash, +typedef css_error (*css_selector_hash_iterator)( const struct css_selector **current, const struct css_selector ***next); diff --git a/src/select/select.c b/src/select/select.c index d347814..72eba14 100644 --- a/src/select/select.c +++ b/src/select/select.c @@ -435,7 +435,40 @@ css_error css_select_style(css_select_ctx *ctx, void *node, /* Take account of presentational hints and fix up any remaining * unset properties. */ - for (j = 0; j < CSS_PSEUDO_ELEMENT_COUNT; j++) { + + /* Base element */ + state.current_pseudo = CSS_PSEUDO_ELEMENT_NONE; + state.computed = state.results->styles[CSS_PSEUDO_ELEMENT_NONE]; + for (i = 0; i < CSS_N_PROPERTIES; i++) { + const prop_state *prop = + &state.props[i][CSS_PSEUDO_ELEMENT_NONE]; + + /* Apply presentational hints if the property is unset or + * the existing property value did not come from an author + * stylesheet or a user sheet using !important. */ + if (prop->set == false || + (prop->origin != CSS_ORIGIN_AUTHOR && + prop->important == false)) { + error = set_hint(&state, i); + if (error != CSS_OK) + goto cleanup; + } + + /* If the property is still unset or it's set to inherit + * and we're the root element, then set it to its initial + * value. */ + if (prop->set == false || + (parent == NULL && + prop->inherit == true)) { + error = set_initial(&state, i, + CSS_PSEUDO_ELEMENT_NONE, parent); + if (error != CSS_OK) + goto cleanup; + } + } + + /* Pseudo elements, if any */ + for (j = CSS_PSEUDO_ELEMENT_NONE + 1; j < CSS_PSEUDO_ELEMENT_COUNT; j++) { state.current_pseudo = j; state.computed = state.results->styles[j]; @@ -444,29 +477,11 @@ css_error css_select_style(css_select_ctx *ctx, void *node, continue; for (i = 0; i < CSS_N_PROPERTIES; i++) { - prop_state *prop = &state.props[i][j]; - - /* Apply presentational hints if we're not selecting for - * a pseudo element, and the property is unset or the - * existing property value did not come from an author - * stylesheet or a user sheet using !important. */ - if (j == CSS_PSEUDO_ELEMENT_NONE && - (prop->set == false || - (prop->origin != CSS_ORIGIN_AUTHOR && - prop->important == false))) { - error = set_hint(&state, i); - if (error != CSS_OK) - goto cleanup; - } + const prop_state *prop = &state.props[i][j]; - /* If the property is still unset or we're not selecting - * for a pseudo element and it's set to inherit and - * we're the root element, then set it to its initial - * value. */ - if (prop->set == false || - (j == CSS_PSEUDO_ELEMENT_NONE && - parent == NULL && - prop->inherit == true)) { + /* If the property is still unset then set it + * to its initial value. */ + if (prop->set == false) { error = set_initial(&state, i, j, parent); if (error != CSS_OK) goto cleanup; @@ -816,6 +831,8 @@ css_error set_initial(css_select_state *state, */ if (prop_dispatch[prop].inherited == false || (pseudo == CSS_PSEUDO_ELEMENT_NONE && parent == NULL)) { + enum prop_group group = prop_dispatch[prop].group; + /* Remaining properties are neither inherited nor * already set. Thus, we set them to their initial * values here. Except, however, if the property in @@ -825,21 +842,21 @@ css_error set_initial(css_select_state *state, * accessors to return the initial values for the * property. */ - if (prop_dispatch[prop].group == GROUP_NORMAL) { + if (group == GROUP_NORMAL) { error = prop_dispatch[prop].initial(state); if (error != CSS_OK) return error; - } else if (prop_dispatch[prop].group == GROUP_UNCOMMON && + } else if (group == GROUP_UNCOMMON && state->computed->uncommon != NULL) { error = prop_dispatch[prop].initial(state); if (error != CSS_OK) return error; - } else if (prop_dispatch[prop].group == GROUP_PAGE && + } else if (group == GROUP_PAGE && state->computed->page != NULL) { error = prop_dispatch[prop].initial(state); if (error != CSS_OK) return error; - } else if (prop_dispatch[prop].group == GROUP_AURAL && + } else if (group == GROUP_AURAL && state->computed->aural != NULL) { error = prop_dispatch[prop].initial(state); if (error != CSS_OK) @@ -862,10 +879,8 @@ css_error select_from_sheet(css_select_ctx *ctx, const css_stylesheet *sheet, do { /* Find first non-charset rule, if we're at the list head */ if (rule == s->rule_list) { - for (; rule != NULL; rule = rule->next) { - if (rule->type != CSS_RULE_CHARSET) - break; - } + while (rule != NULL && rule->type == CSS_RULE_CHARSET) + rule = rule->next; } if (rule != NULL && rule->type == CSS_RULE_IMPORT) { @@ -912,7 +927,7 @@ css_error select_from_sheet(css_select_ctx *ctx, const css_stylesheet *sheet, return CSS_OK; } -static bool _selectors_pending(const css_selector **node, +static inline bool _selectors_pending(const css_selector **node, const css_selector **id, const css_selector ***classes, uint32_t n_classes, const css_selector **univ) { @@ -1082,18 +1097,18 @@ css_error match_selectors_in_sheet(css_select_ctx *ctx, /* Advance to next selector in whichever chain we extracted * the processed selector from. */ if (selector == *node_selectors) { - error = node_iterator(sheet->selectors, + error = node_iterator( node_selectors, &node_selectors); } else if (selector == *id_selectors) { - error = id_iterator(sheet->selectors, + error = id_iterator( id_selectors, &id_selectors); } else if (selector == *univ_selectors) { - error = univ_iterator(sheet->selectors, + error = univ_iterator( univ_selectors, &univ_selectors); } else { for (i = 0; i < n_classes; i++) { if (selector == *(class_selectors[i])) { - error = class_iterator(sheet->selectors, + error = class_iterator( class_selectors[i], &class_selectors[i]); break; @@ -1385,8 +1400,6 @@ css_error match_detail(css_select_ctx *ctx, void *node, bool is_root = false; css_error error = CSS_OK; - UNUSED(ctx); - switch (detail->type) { case CSS_SELECTOR_ELEMENT: error = state->handler->node_has_name(state->pw, node, -- cgit v1.2.3