diff options
author | Andy Wingo <wingo@pobox.com> | 2017-02-16 10:38:15 +0100 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2017-02-16 10:38:15 +0100 |
commit | cd3ff33a31c51612f2247bdb15ecbe92d7da1310 (patch) | |
tree | 92f595464a9faabf2d2a4d075c359e7905ca8f3b /libguile | |
parent | 4706d6982457498c60e575a026229e03820381d3 (diff) |
Cheaper fluid-ref cache
* libguile/cache-internal.h (struct scm_cache_entry): Add needs_flush
member.
(scm_cache_evict_1): Clear needs_flush on newly evicted entry.
(scm_cache_insert): Propagate needs_flush to new entry.
* libguile/fluids.c (restore_dynamic_state): Mark all restored entries
as needing a flush.
(save_dynamic_state): Only cons on "needs_flush" entries to the
resulting dynamic state. The result is the same as before but
avoiding the refq on the weak table.
(fluid_set_x): Propagate needs_flush down to the cache.
(fluid_ref): When adding entry to cache, use needs_flush==0.
(scm_fluid_set_x, scm_fluid_unset_x, scm_swap_fluid, swap_fluid): Use
needs_flush==1.
Diffstat (limited to 'libguile')
-rw-r--r-- | libguile/cache-internal.h | 6 | ||||
-rw-r--r-- | libguile/fluids.c | 30 |
2 files changed, 22 insertions, 14 deletions
diff --git a/libguile/cache-internal.h b/libguile/cache-internal.h index fc1e3c139..88bb24af0 100644 --- a/libguile/cache-internal.h +++ b/libguile/cache-internal.h @@ -37,6 +37,7 @@ struct scm_cache_entry { scm_t_bits key; scm_t_bits value; + int needs_flush; }; #define SCM_CACHE_SIZE 8 @@ -73,6 +74,7 @@ scm_cache_evict_1 (struct scm_cache *cache, struct scm_cache_entry *evicted) sizeof (cache->entries[0]) * idx); cache->entries[0].key = 0; cache->entries[0].value = 0; + cache->entries[0].needs_flush = 0; } static inline struct scm_cache_entry* @@ -89,7 +91,7 @@ scm_cache_lookup (struct scm_cache *cache, SCM k) static inline void scm_cache_insert (struct scm_cache *cache, SCM k, SCM v, - struct scm_cache_entry *evicted) + struct scm_cache_entry *evicted, int needs_flush) { struct scm_cache_entry *entry; @@ -99,6 +101,7 @@ scm_cache_insert (struct scm_cache *cache, SCM k, SCM v, if (entry->key == SCM_UNPACK (k)) { entry->value = SCM_UNPACK (v); + entry->needs_flush = needs_flush; return; } memmove (cache->entries, @@ -106,6 +109,7 @@ scm_cache_insert (struct scm_cache *cache, SCM k, SCM v, (entry - cache->entries) * sizeof (*entry)); entry->key = SCM_UNPACK (k); entry->value = SCM_UNPACK (v); + entry->needs_flush = needs_flush; } #endif /* SCM_CACHE_INTERNAL_H */ diff --git a/libguile/fluids.c b/libguile/fluids.c index 7daad7781..5b42ccb6d 100644 --- a/libguile/fluids.c +++ b/libguile/fluids.c @@ -114,10 +114,11 @@ restore_dynamic_state (SCM saved, scm_t_dynamic_state *state) { entry->key = SCM_UNPACK (SCM_CAAR (saved)); entry->value = SCM_UNPACK (SCM_CDAR (saved)); + entry->needs_flush = 1; saved = scm_cdr (saved); } else - entry->key = entry->value = 0; + entry->key = entry->value = entry->needs_flush = 0; } state->values = saved; state->has_aliased_values = 1; @@ -133,9 +134,7 @@ save_dynamic_state (scm_t_dynamic_state *state) struct scm_cache_entry *entry = &state->cache.entries[slot]; SCM key = SCM_PACK (entry->key); SCM value = SCM_PACK (entry->value); - if (entry->key && - !scm_is_eq (scm_weak_table_refq (state->values, key, SCM_UNDEFINED), - value)) + if (entry->key && entry->needs_flush) { if (state->has_aliased_values) saved = scm_acons (key, value, saved); @@ -249,7 +248,8 @@ scm_is_fluid (SCM obj) } static void -fluid_set_x (scm_t_dynamic_state *dynamic_state, SCM fluid, SCM value) +fluid_set_x (scm_t_dynamic_state *dynamic_state, SCM fluid, SCM value, + int needs_flush) { struct scm_cache_entry *entry; struct scm_cache_entry evicted = { 0, 0 }; @@ -257,13 +257,17 @@ fluid_set_x (scm_t_dynamic_state *dynamic_state, SCM fluid, SCM value) entry = scm_cache_lookup (&dynamic_state->cache, fluid); if (scm_is_eq (SCM_PACK (entry->key), fluid)) { - entry->value = SCM_UNPACK (value); + if (SCM_UNPACK (value) != entry->value) + { + entry->needs_flush = 1; + entry->value = SCM_UNPACK (value); + } return; } - scm_cache_insert (&dynamic_state->cache, fluid, value, &evicted); + scm_cache_insert (&dynamic_state->cache, fluid, value, &evicted, 1); - if (evicted.key != 0) + if (evicted.key != 0 && evicted.needs_flush) { fluid = SCM_PACK (evicted.key); value = SCM_PACK (evicted.value); @@ -300,7 +304,7 @@ fluid_ref (scm_t_dynamic_state *dynamic_state, SCM fluid) val = SCM_I_FLUID_DEFAULT (fluid); /* Cache this lookup. */ - fluid_set_x (dynamic_state, fluid, val); + fluid_set_x (dynamic_state, fluid, val, 0); } return val; @@ -355,7 +359,7 @@ SCM_DEFINE (scm_fluid_set_x, "fluid-set!", 2, 0, 0, #define FUNC_NAME s_scm_fluid_set_x { SCM_VALIDATE_FLUID (1, fluid); - fluid_set_x (SCM_I_CURRENT_THREAD->dynamic_state, fluid, value); + fluid_set_x (SCM_I_CURRENT_THREAD->dynamic_state, fluid, value, 1); return SCM_UNSPECIFIED; } #undef FUNC_NAME @@ -369,7 +373,7 @@ SCM_DEFINE (scm_fluid_unset_x, "fluid-unset!", 1, 0, 0, suite demands it, but I would prefer not to. */ SCM_VALIDATE_FLUID (1, fluid); SCM_SET_CELL_OBJECT_1 (fluid, SCM_UNDEFINED); - fluid_set_x (SCM_I_CURRENT_THREAD->dynamic_state, fluid, SCM_UNDEFINED); + fluid_set_x (SCM_I_CURRENT_THREAD->dynamic_state, fluid, SCM_UNDEFINED, 1); return SCM_UNSPECIFIED; } #undef FUNC_NAME @@ -397,7 +401,7 @@ void scm_swap_fluid (SCM fluid, SCM value_box, scm_t_dynamic_state *dynstate) { SCM val = fluid_ref (dynstate, fluid); - fluid_set_x (dynstate, fluid, SCM_VARIABLE_REF (value_box)); + fluid_set_x (dynstate, fluid, SCM_VARIABLE_REF (value_box), 1); SCM_VARIABLE_SET (value_box, val); } @@ -474,7 +478,7 @@ swap_fluid (SCM data) scm_t_dynamic_state *dynstate = SCM_I_CURRENT_THREAD->dynamic_state; SCM f = SCM_CAR (data); SCM t = fluid_ref (dynstate, f); - fluid_set_x (dynstate, f, SCM_CDR (data)); + fluid_set_x (dynstate, f, SCM_CDR (data), 1); SCM_SETCDR (data, t); } |