mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2026-01-30 12:21:02 -08:00
bytevm: don't use ecl_fdefinition for OP_FUNCTION
The function ecl_fdefinition checks also for lamdbas and whatnot, while all we need is a lookup in the global namespace for the function name. This commit also changes how we store SETF function definition -- instead of maintaining them in a global environment, it is stored along with the symbol. That saves us from taking a global lock repeatedly.
This commit is contained in:
parent
9c1bcd0b7b
commit
1ff274bf08
8 changed files with 73 additions and 38 deletions
|
|
@ -236,6 +236,7 @@ make_this_symbol(int i, volatile cl_object s, int code,
|
|||
ECL_FMAKUNBOUND(s);
|
||||
s->symbol.undef_entry = ecl_undefined_function_entry;
|
||||
s->symbol.macfun = ECL_NIL;
|
||||
s->symbol.sfdef = ECL_NIL;
|
||||
s->symbol.plist = ECL_NIL;
|
||||
s->symbol.hpack = ECL_NIL;
|
||||
s->symbol.stype = stp;
|
||||
|
|
|
|||
|
|
@ -580,6 +580,7 @@ void init_type_info (void)
|
|||
to_bitmap(&o, &(o.symbol.value)) |
|
||||
to_bitmap(&o, &(o.symbol.gfdef)) |
|
||||
to_bitmap(&o, &(o.symbol.macfun)) |
|
||||
to_bitmap(&o, &(o.symbol.sfdef)) |
|
||||
to_bitmap(&o, &(o.symbol.plist)) |
|
||||
to_bitmap(&o, &(o.symbol.name)) |
|
||||
to_bitmap(&o, &(o.symbol.hpack));
|
||||
|
|
|
|||
|
|
@ -112,15 +112,12 @@ cl_object
|
|||
ecl_setf_definition(cl_object sym, cl_object createp)
|
||||
{
|
||||
cl_env_ptr the_env = ecl_process_env();
|
||||
cl_object pair;
|
||||
ECL_WITH_GLOBAL_ENV_RDLOCK_BEGIN(the_env) {
|
||||
pair = ecl_gethash_safe(sym, cl_core.setf_definitions, ECL_NIL);
|
||||
if (Null(pair) && !Null(createp)) {
|
||||
createp = make_setf_function_error(sym);
|
||||
pair = ecl_cons(createp, ECL_NIL);
|
||||
ecl_sethash(sym, cl_core.setf_definitions, pair);
|
||||
}
|
||||
} ECL_WITH_GLOBAL_ENV_RDLOCK_END;
|
||||
cl_object pair = sym->symbol.sfdef;
|
||||
if (Null(pair) && !Null(createp)) {
|
||||
createp = make_setf_function_error(sym);
|
||||
pair = ecl_cons(createp, ECL_NIL);
|
||||
sym->symbol.sfdef = pair;
|
||||
}
|
||||
return pair;
|
||||
}
|
||||
|
||||
|
|
@ -134,19 +131,11 @@ static void
|
|||
ecl_rem_setf_definition(cl_object sym)
|
||||
{
|
||||
cl_env_ptr the_env = ecl_process_env();
|
||||
ECL_WITH_GLOBAL_ENV_WRLOCK_BEGIN(the_env) {
|
||||
cl_object pair = ecl_gethash_safe(sym, cl_core.setf_definitions, ECL_NIL);
|
||||
if (!Null(pair)) {
|
||||
ECL_RPLACA(pair, make_setf_function_error(sym));
|
||||
ECL_RPLACD(pair, ECL_NIL);
|
||||
/*
|
||||
FIXME: This leaks resources
|
||||
We actually cannot remove it, because some compiled
|
||||
code might be using it!
|
||||
ecl_remhash(sym, cl_core.setf_definitions);
|
||||
*/
|
||||
}
|
||||
} ECL_WITH_GLOBAL_ENV_WRLOCK_END;
|
||||
cl_object pair = sym->symbol.sfdef;
|
||||
if (!Null(pair)) {
|
||||
ECL_RPLACA(pair, make_setf_function_error(sym));
|
||||
ECL_RPLACD(pair, ECL_NIL);
|
||||
}
|
||||
}
|
||||
|
||||
@(defun si::fset (fname def &optional macro pprint)
|
||||
|
|
|
|||
|
|
@ -87,6 +87,18 @@ VEwrong_num_arguments(cl_object fname)
|
|||
FEwrong_num_arguments(fname);
|
||||
}
|
||||
|
||||
static void
|
||||
VEundefined_function(cl_object fun)
|
||||
{
|
||||
FEundefined_function(fun);
|
||||
}
|
||||
|
||||
static void
|
||||
VEinvalid_function(cl_object fun)
|
||||
{
|
||||
FEinvalid_function(fun);
|
||||
}
|
||||
|
||||
static void
|
||||
VEclose_around_arg_type()
|
||||
{
|
||||
|
|
@ -150,6 +162,37 @@ _ecl_bclosure_dispatch_vararg(cl_narg narg, ...)
|
|||
return output;
|
||||
}
|
||||
|
||||
/* Find the global function definition associated with a name. This function is
|
||||
similar to ecl_fdefinition except thta it does not check for lambdas and
|
||||
assumes that the name is either SYMBOL or (SETF SYMBOL). -- jd 2024-12-12 */
|
||||
static cl_object
|
||||
_ecl_global_function_definition(cl_object name)
|
||||
{
|
||||
cl_object fun = ECL_NIL, sym, pair;
|
||||
switch (ecl_t_of(name)) {
|
||||
case t_symbol:
|
||||
unlikely_if (!ECL_FBOUNDP(name)
|
||||
|| name->symbol.stype & (ecl_stp_macro | ecl_stp_special_form))
|
||||
VEundefined_function(name);
|
||||
fun = ECL_SYM_FUN(name);
|
||||
break;
|
||||
case t_list:
|
||||
unlikely_if (Null(name))
|
||||
VEundefined_function(name);
|
||||
/* (setf fname) */
|
||||
sym = ECL_CONS_CAR(ECL_CONS_CDR(name));
|
||||
pair = sym->symbol.sfdef;
|
||||
unlikely_if (Null(pair) || Null(ECL_CONS_CDR(pair))) {
|
||||
VEundefined_function(name);
|
||||
}
|
||||
fun = ECL_CONS_CAR(pair);
|
||||
break;
|
||||
default:
|
||||
VEinvalid_function(name);
|
||||
}
|
||||
return fun;
|
||||
}
|
||||
|
||||
cl_object
|
||||
ecl_close_around(cl_object fun, cl_object lex) {
|
||||
cl_object v;
|
||||
|
|
@ -604,25 +647,27 @@ ecl_interpret(cl_object frame, cl_object env, cl_object bytecodes)
|
|||
}
|
||||
THREAD_NEXT;
|
||||
}
|
||||
/* OP_LFUNCTION n{arg}, function-name{symbol}
|
||||
Calls the local or global function with N arguments
|
||||
which have been deposited in the stack.
|
||||
/* OP_LFUNCTION index{fixnum}
|
||||
|
||||
Extracts a local function denoted by the index from the lexical
|
||||
environment.
|
||||
*/
|
||||
CASE(OP_LFUNCTION); { /* XXX: local function (fix comment) */
|
||||
CASE(OP_LFUNCTION); {
|
||||
int lex_env_index;
|
||||
GET_OPARG(lex_env_index, vector);
|
||||
reg0 = ecl_lex_env_get_fun(lex_env, lex_env_index);
|
||||
THREAD_NEXT;
|
||||
}
|
||||
|
||||
/* OP_FUNCTION name{symbol}
|
||||
Extracts the function associated to a symbol. The function
|
||||
may be defined in the global environment or in the local
|
||||
environment. This last value takes precedence.
|
||||
/* OP_FUNCTION name{function-name}
|
||||
|
||||
Extracts a function associated with the name. The function is defined in
|
||||
the global environment. Local function are handled by OP_LFUNCTION and
|
||||
lambdas are handled by OP_QUOTE and OP_CLOSE.
|
||||
*/
|
||||
CASE(OP_FUNCTION); { /* XXX: global function (fix comment) */
|
||||
CASE(OP_FUNCTION); {
|
||||
GET_DATA(reg0, vector, data);
|
||||
reg0 = ecl_fdefinition(reg0);
|
||||
reg0 = _ecl_global_function_definition(reg0);
|
||||
THREAD_NEXT;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -413,7 +413,6 @@ struct cl_core_struct cl_core = {
|
|||
.Jan1st1970UT = ECL_NIL,
|
||||
|
||||
.system_properties = ECL_NIL,
|
||||
.setf_definitions = ECL_NIL,
|
||||
|
||||
#ifdef ECL_THREADS
|
||||
.processes = ECL_NIL,
|
||||
|
|
@ -514,6 +513,7 @@ cl_boot(int argc, char **argv)
|
|||
ECL_NIL_SYMBOL->symbol.name = str_NIL;
|
||||
ECL_NIL_SYMBOL->symbol.cname = ECL_NIL;
|
||||
ECL_FMAKUNBOUND(ECL_NIL_SYMBOL);
|
||||
ECL_NIL_SYMBOL->symbol.sfdef = ECL_NIL;
|
||||
ECL_NIL_SYMBOL->symbol.plist = ECL_NIL;
|
||||
ECL_NIL_SYMBOL->symbol.hpack = ECL_NIL;
|
||||
ECL_NIL_SYMBOL->symbol.stype = ecl_stp_constant;
|
||||
|
|
@ -528,6 +528,7 @@ cl_boot(int argc, char **argv)
|
|||
ECL_T->symbol.name = str_T;
|
||||
ECL_T->symbol.cname = ECL_NIL;
|
||||
ECL_FMAKUNBOUND(ECL_T);
|
||||
ECL_T->symbol.sfdef = ECL_NIL;
|
||||
ECL_T->symbol.plist = ECL_NIL;
|
||||
ECL_T->symbol.hpack = ECL_NIL;
|
||||
ECL_T->symbol.stype = ecl_stp_constant;
|
||||
|
|
@ -678,10 +679,6 @@ cl_boot(int argc, char **argv)
|
|||
cl__make_hash_table(@'equal', ecl_make_fixnum(1024), /* size */
|
||||
cl_core.rehash_size,
|
||||
cl_core.rehash_threshold);
|
||||
cl_core.setf_definitions =
|
||||
cl__make_hash_table(@'eq', ecl_make_fixnum(256), /* size */
|
||||
cl_core.rehash_size,
|
||||
cl_core.rehash_threshold);
|
||||
|
||||
ECL_SET(@'*random-state*', ecl_make_random_state(ECL_T));
|
||||
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ cl_make_symbol(cl_object str)
|
|||
ECL_SET(x,OBJNULL);
|
||||
ECL_FMAKUNBOUND(x);
|
||||
x->symbol.undef_entry = ecl_undefined_function_entry;
|
||||
x->symbol.sfdef = ECL_NIL;
|
||||
x->symbol.plist = ECL_NIL;
|
||||
x->symbol.hpack = ECL_NIL;
|
||||
x->symbol.stype = ecl_stp_ordinary;
|
||||
|
|
@ -332,6 +333,7 @@ cl_symbol_name(cl_object x)
|
|||
x->symbol.value = sym->symbol.value;
|
||||
x->symbol.plist = cl_copy_list(sym->symbol.plist);
|
||||
x->symbol.undef_entry = sym->symbol.undef_entry;
|
||||
x->symbol.sfdef = sym->symbol.sfdef;
|
||||
x->symbol.macfun = sym->symbol.macfun;
|
||||
if (ECL_FBOUNDP(sym)) {
|
||||
x->symbol.gfdef = sym->symbol.gfdef;
|
||||
|
|
|
|||
|
|
@ -220,7 +220,6 @@ struct cl_core_struct {
|
|||
cl_object Jan1st1970UT;
|
||||
|
||||
cl_object system_properties;
|
||||
cl_object setf_definitions;
|
||||
|
||||
#ifdef ECL_THREADS
|
||||
cl_object processes;
|
||||
|
|
|
|||
|
|
@ -280,6 +280,7 @@ struct ecl_symbol {
|
|||
* of cfun.entry); see below for
|
||||
* more explanation */
|
||||
cl_object macfun; /* macro expansion function */
|
||||
cl_object sfdef; /* global (setf f) definition */
|
||||
cl_object plist; /* property list */
|
||||
cl_object name; /* print name */
|
||||
cl_object cname; /* associated C name for function
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue