Skip to content

Commit ab966b7

Browse files
committed
perf: avoid blocking wait on kernel env on some interpreter entries
1 parent ac0b829 commit ab966b7

File tree

2 files changed

+22
-5
lines changed

2 files changed

+22
-5
lines changed

src/Lean/Compiler/IR/CompilerM.lean

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,22 @@ def findEnvDecl (env : Environment) (declName : Name) : Option Decl :=
165165
findAtSorted? (declMapExt.getModuleEntries env modIdx) declName
166166
| none => declMapExt.getState env |>.find? declName
167167

168+
/-- Like ``findEnvDecl env (declName ++ `_boxed)`` but with optimized negative lookup. -/
169+
@[export lean_ir_find_env_decl_boxed]
170+
private def findEnvDeclBoxed (env : Environment) (declName : Name) : Option Decl :=
171+
let boxed := declName ++ `_boxed
172+
-- Important: get module index of base name, not boxed version. Usually the interpreter never
173+
-- does negative lookups except in the case of `call_boxed` which must check whether a boxed
174+
-- version exists. If `declName` exists as an imported declaration but `declName'` doesn't, the
175+
-- latter's module index would be `none` and we may do an expensive blocking wait on the
176+
-- environment extension state even if in this situation we definitely know that `declName'` is
177+
-- not a local declaration.
178+
match env.getModuleIdxFor? declName with
179+
| some modIdx =>
180+
findAtSorted? (declMapExt.getModuleIREntries env modIdx) boxed <|>
181+
findAtSorted? (declMapExt.getModuleEntries env modIdx) boxed
182+
| none => declMapExt.getState env |>.find? boxed
183+
168184
def findDecl (n : Name) : CompilerM (Option Decl) :=
169185
return findEnvDecl (← getEnv) n
170186

src/library/ir_interpreter.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -186,11 +186,15 @@ option_ref<decl> find_ir_decl(elab_environment const & env, name const & n) {
186186
return option_ref<decl>(lean_ir_find_env_decl(env.to_obj_arg(), n.to_obj_arg()));
187187
}
188188

189+
extern "C" object * lean_ir_find_env_decl_boxed(object * env, object * n);
190+
option_ref<decl> find_ir_decl_boxed(elab_environment const & env, name const & n) {
191+
return option_ref<decl>(lean_ir_find_env_decl_boxed(env.to_obj_arg(), n.to_obj_arg()));
192+
}
193+
189194
extern "C" double lean_float_of_nat(lean_obj_arg a);
190195
extern "C" float lean_float32_of_nat(lean_obj_arg a);
191196

192197
static string_ref * g_mangle_prefix = nullptr;
193-
static string_ref * g_boxed_suffix = nullptr;
194198
static string_ref * g_boxed_mangled_suffix = nullptr;
195199
static name * g_interpreter_prefer_native = nullptr;
196200

@@ -1047,7 +1051,7 @@ class interpreter {
10471051
} else {
10481052
// `lookup_symbol` does not prefer the boxed version for interpreted functions, so check manually.
10491053
decl d = e.m_decl;
1050-
if (option_ref<decl> d_boxed = find_ir_decl(m_env, fn + *g_boxed_suffix)) {
1054+
if (option_ref<decl> d_boxed = find_ir_decl_boxed(m_env, fn)) {
10511055
d = *d_boxed.get();
10521056
}
10531057
r = mk_stub_closure(d, 0, nullptr);
@@ -1185,8 +1189,6 @@ extern "C" LEAN_EXPORT object * lean_run_init(object * env, object * opts, objec
11851189
void initialize_ir_interpreter() {
11861190
ir::g_mangle_prefix = new string_ref("l_");
11871191
mark_persistent(ir::g_mangle_prefix->raw());
1188-
ir::g_boxed_suffix = new string_ref("_boxed");
1189-
mark_persistent(ir::g_boxed_suffix->raw());
11901192
ir::g_boxed_mangled_suffix = new string_ref("___boxed");
11911193
mark_persistent(ir::g_boxed_mangled_suffix->raw());
11921194
ir::g_interpreter_prefer_native = new name({"interpreter", "prefer_native"});
@@ -1207,7 +1209,6 @@ void finalize_ir_interpreter() {
12071209
delete ir::g_init_globals;
12081210
delete ir::g_interpreter_prefer_native;
12091211
delete ir::g_boxed_mangled_suffix;
1210-
delete ir::g_boxed_suffix;
12111212
delete ir::g_mangle_prefix;
12121213
}
12131214
}

0 commit comments

Comments
 (0)