Fix eql-specializer dispatch caching.

When the EQL specializer is a class it may clash with a class
specializer, since the class specializer is cached as a class object.
Use twice as much space for cache, the cache entry itself and a bit, 1
if it's an eql-specializer, 0 if it's a class specializer.

Fixes #295
This commit is contained in:
Stas Boukarev 2014-09-27 00:46:35 +04:00
parent 898a57818b
commit 85165d989a
2 changed files with 14 additions and 6 deletions

View file

@ -129,11 +129,17 @@ fill_spec_vector(cl_object vector, cl_object frame, cl_object gf)
FEwrong_num_arguments(gf);
unlikely_if (spec_no >= vector->vector.dim)
ecl_internal_error("Too many arguments to fill_spec_vector()");
argtype[spec_no++] =
(!ECL_LISTP(spec_type) ||
Null(ecl_memql(args[spec_position], spec_type))) ?
cl_class_of(args[spec_position]) :
args[spec_position];
/* Need to differentiate between EQL specializers and
class specializers, because the EQL value can be a
class, and may classh with a class specializer. */
if (ECL_LISTP(spec_type) && ecl_memql(args[spec_position], spec_type)) {
argtype[spec_no++] = args[spec_position];
argtype[spec_no++] = 1;
} else {
argtype[spec_no++] = cl_class_of(args[spec_position]);
argtype[spec_no++] = 0;
}
} end_loop_for_on_unsafe(spec_how_list);
vector->vector.fillp = spec_no;
return vector;

View file

@ -160,7 +160,9 @@ ecl_init_env(cl_env_ptr env)
#endif
#ifdef CLOS
env->method_cache = ecl_make_cache(64, 4096);
/* Needs 128 elements for 64 entries to differentiate between
EQL specializers and class specializers */
env->method_cache = ecl_make_cache(128, 4096);
env->slot_cache = ecl_make_cache(3, 4096);
#endif
env->pending_interrupt = ECL_NIL;