From e0f1048bbeb7dfff28d32edba4a7944a411f6299 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Thu, 6 Oct 2011 18:32:37 +0000 Subject: Avoid interning propstrings table for every stylesheet, style tag and style attribute. svn path=/trunk/libcss/; revision=12972 --- src/parse/language.c | 20 +++++---------- src/parse/language.h | 2 +- src/parse/propstrings.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++ src/parse/propstrings.h | 3 +++ 4 files changed, 76 insertions(+), 15 deletions(-) diff --git a/src/parse/language.c b/src/parse/language.c index 5e550b1..f541514 100644 --- a/src/parse/language.c +++ b/src/parse/language.c @@ -120,9 +120,7 @@ css_error css__language_create(css_stylesheet *sheet, css_parser *parser, css_language *c; css_parser_optparams params; parserutils_error perror; - lwc_error lerror; css_error error; - int i; if (sheet == NULL || parser == NULL || alloc == NULL || language == NULL) @@ -141,15 +139,11 @@ css_error css__language_create(css_stylesheet *sheet, css_parser *parser, } /* Intern all known strings */ - for (i = 0; i < LAST_KNOWN; i++) { - lerror = lwc_intern_string(stringmap[i].data, - stringmap[i].len, - &(c->strings[i])); - if (lerror != lwc_error_ok) { - parserutils_stack_destroy(c->context); - alloc(c, 0, pw); - return CSS_NOMEM; - } + error = css__propstrings_get(&c->strings); + if (error != CSS_OK) { + parserutils_stack_destroy(c->context); + alloc(c, 0, pw); + return error; } params.event_handler.handler = language_handle_event; @@ -201,9 +195,7 @@ css_error css__language_destroy(css_language *language) parserutils_stack_destroy(language->context); - for (i = 0; i < LAST_KNOWN; ++i) { - lwc_string_unref(language->strings[i]); - } + css__propstrings_unref(); language->alloc(language, 0, language->pw); diff --git a/src/parse/language.h b/src/parse/language.h index 0f1985c..522e981 100644 --- a/src/parse/language.h +++ b/src/parse/language.h @@ -44,7 +44,7 @@ typedef struct css_language { /** \todo These should be statically allocated */ /** Interned strings */ - lwc_string *strings[LAST_KNOWN]; + lwc_string **strings; lwc_string *default_namespace; /**< Default namespace URI */ css_namespace *namespaces; /**< Array of namespace mappings */ diff --git a/src/parse/propstrings.c b/src/parse/propstrings.c index 7e15e31..6973a54 100644 --- a/src/parse/propstrings.c +++ b/src/parse/propstrings.c @@ -6,6 +6,18 @@ */ #include "parse/propstrings.h" +#include "stylesheet.h" + +#include + +typedef struct css__propstrings_ctx { + uint32_t count; + lwc_string *strings[LAST_KNOWN]; +} css__propstings_ctx; + +css__propstings_ctx css__propstrings = { + .count = 0 +}; /* Must be synchronised with enum in propstrings.h */ const stringmap_entry stringmap[LAST_KNOWN] = { @@ -511,3 +523,57 @@ const stringmap_entry stringmap[LAST_KNOWN] = { }; +/** + * Obtain pointer to interned propstring list + * + * \param sheet Returns pointer to propstring table + * \return CSS_OK on success, + * CSS_NOMEM on memory exhaustion + * + * The propstring list is generated with the first call to this function and + * destroyed when it has no more users. Call css__propstrings_unref() when + * finished with the propstring list. + */ +css_error css__propstrings_get(lwc_string ***strings) +{ + if (css__propstrings.count > 0) { + css__propstrings.count++; + } else { + int i; + lwc_error lerror; + + /* Intern all known strings */ + for (i = 0; i < LAST_KNOWN; i++) { + lerror = lwc_intern_string(stringmap[i].data, + stringmap[i].len, + &css__propstrings.strings[i]); + + if (lerror != lwc_error_ok) + return CSS_NOMEM; + } + css__propstrings.count++; + } + + *strings = css__propstrings.strings; + + return CSS_OK; +} + +/** + * Reduce reference count for propstring list by one. + * + * When count hits zero, the list is destroyed. + */ +void css__propstrings_unref(void) +{ + css__propstrings.count--; + + if (css__propstrings.count == 0) { + int i; + + for (i = 0; i < LAST_KNOWN; i++) + lwc_string_unref(css__propstrings.strings[i]); + } +} + + diff --git a/src/parse/propstrings.h b/src/parse/propstrings.h index 25fe113..9ae3cf3 100644 --- a/src/parse/propstrings.h +++ b/src/parse/propstrings.h @@ -131,5 +131,8 @@ typedef struct stringmap_entry { extern const stringmap_entry stringmap[LAST_KNOWN]; +css_error css__propstrings_get(lwc_string ***strings); +void css__propstrings_unref(void); + #endif -- cgit v1.2.3