1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-30 03:40:34 +02:00

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.
This commit is contained in:
Andy Wingo 2017-02-16 10:38:15 +01:00
parent 4706d69824
commit cd3ff33a31
2 changed files with 22 additions and 14 deletions

View file

@ -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);
}