summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2020-06-15 17:20:03 -0700
committerKaz Kylheku <kaz@kylheku.com>2020-06-15 17:20:03 -0700
commit03db12abdf39b9c26ae28b28faaea933eb36aa2e (patch)
tree8cbfee8aaa28fc1645b33589cc7a6440f74207cc
parent09336076bd73d344f914504bab80f25528619f1c (diff)
downloadtxr-03db12abdf39b9c26ae28b28faaea933eb36aa2e.tar.gz
txr-03db12abdf39b9c26ae28b28faaea933eb36aa2e.tar.bz2
txr-03db12abdf39b9c26ae28b28faaea933eb36aa2e.zip
exceptions: avoid consing dyn env for package vars
* unwind.c (invoke_handler): Do not unconditionally bind *package* and *package-alist*. Allocate the new dynamic environment only if the current values of those variables are different from the ones stored in the frame. This is the excpected case since package and package list manipulations are rare.
-rw-r--r--unwind.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/unwind.c b/unwind.c
index 787dcd62..ac0f2d9f 100644
--- a/unwind.c
+++ b/unwind.c
@@ -637,15 +637,18 @@ val uw_exception_subtype_p(val sub, val sup)
static void invoke_handler(uw_frame_t *fr, struct args *args)
{
val saved_dyn_env = dyn_env;
+ val cur_pkg_alist = deref(cur_package_alist_loc);
+ val cur_pkg = cur_package;
fr->ha.visible = 0;
uw_simple_catch_begin;
- dyn_env = make_env(nil, nil, dyn_env);
-
- env_vbind(dyn_env, package_s, fr->ha.package);
- env_vbind(dyn_env, package_alist_s, fr->ha.package_alist);
+ if (cur_pkg_alist != fr->ha.package_alist || cur_pkg != fr->ha.package) {
+ dyn_env = make_env(nil, nil, dyn_env);
+ env_vbind(dyn_env, package_s, fr->ha.package);
+ env_vbind(dyn_env, package_alist_s, fr->ha.package_alist);
+ }
generic_funcall(fr->ha.fun, args);