Skip to content

Commit fec8b3b

Browse files
committed
local reasoning fix
1 parent 3f0e61f commit fec8b3b

File tree

2 files changed

+20
-21
lines changed

2 files changed

+20
-21
lines changed

yjit/src/codegen.rs

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -234,20 +234,21 @@ impl<'a> JITState<'a> {
234234
result
235235
}
236236

237-
/// Return true if the current ISEQ could escape an environment.
238-
///
239-
/// As of vm_push_frame(), EP is always equal to BP. However, after pushing
240-
/// a frame, some ISEQ setups call vm_bind_update_env(), which redirects EP.
241-
/// Also, some method calls escape the environment to the heap.
242-
fn escapes_ep(&self) -> bool {
243-
match unsafe { get_iseq_body_type(self.iseq) } {
244-
// <main> frame is always associated to TOPLEVEL_BINDING.
245-
ISEQ_TYPE_MAIN |
246-
// Kernel#eval uses a heap EP when a Binding argument is not nil.
247-
ISEQ_TYPE_EVAL => true,
248-
// If this ISEQ has previously escaped EP, give up the optimization.
249-
_ if iseq_escapes_ep(self.iseq) => true,
250-
_ => false,
237+
// TODO
238+
fn can_assume_on_stack_env(&self) -> bool {
239+
// In principle, all ISEQs can run with an escaped environment. But,
240+
// if we're compiling the currently running iseq, and the environment
241+
// is currently on-stack, we can say our code will run as such. The
242+
// compiler never causes an environment escape and maintains the
243+
// current state.
244+
if self.iseq == unsafe { get_cfp_iseq(self.get_cfp()) } {
245+
//
246+
if iseq_escapes_ep(self.iseq) {
247+
return false;
248+
}
249+
true
250+
} else {
251+
false
251252
}
252253
}
253254

@@ -370,14 +371,12 @@ impl<'a> JITState<'a> {
370371
true
371372
}
372373

373-
/// Assume that base pointer is equal to environment pointer in the current ISEQ.
374-
/// Return true if it's safe to assume so.
375374
fn assume_no_ep_escape(&mut self, asm: &mut Assembler) -> bool {
376375
if jit_ensure_block_entry_exit(self, asm).is_none() {
377376
return false; // out of space, give up
378377
}
379-
if self.escapes_ep() {
380-
return false; // EP has been escaped in this ISEQ. disable the optimization to avoid an invalidation loop.
378+
if !self.can_assume_on_stack_env() {
379+
return false; // Unsound to rely on TODO
381380
}
382381
self.no_ep_escape = true;
383382
true
@@ -2509,7 +2508,7 @@ fn gen_getlocal_generic(
25092508
level: u32,
25102509
) -> Option<CodegenStatus> {
25112510
// Split the block if we need to invalidate this instruction when EP escapes
2512-
if level == 0 && !jit.escapes_ep() && !jit.at_compile_target() {
2511+
if level == 0 && jit.can_assume_on_stack_env() && !jit.at_compile_target() {
25132512
return jit.defer_compilation(asm);
25142513
}
25152514

@@ -2610,7 +2609,7 @@ fn gen_setlocal_generic(
26102609
}
26112610

26122611
// Split the block if we need to invalidate this instruction when EP escapes
2613-
if level == 0 && !jit.escapes_ep() && !jit.at_compile_target() {
2612+
if level == 0 && jit.can_assume_on_stack_env() && !jit.at_compile_target() {
26142613
return jit.defer_compilation(asm);
26152614
}
26162615

yjit/src/cruby.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ pub use rb_iseq_encoded_size as get_iseq_encoded_size;
176176
pub use rb_get_iseq_body_local_iseq as get_iseq_body_local_iseq;
177177
pub use rb_get_iseq_body_iseq_encoded as get_iseq_body_iseq_encoded;
178178
pub use rb_get_iseq_body_stack_max as get_iseq_body_stack_max;
179-
pub use rb_get_iseq_body_type as get_iseq_body_type;
179+
//pub use rb_get_iseq_body_type as get_iseq_body_type;
180180
pub use rb_get_iseq_flags_has_lead as get_iseq_flags_has_lead;
181181
pub use rb_get_iseq_flags_has_opt as get_iseq_flags_has_opt;
182182
pub use rb_get_iseq_flags_has_kw as get_iseq_flags_has_kw;

0 commit comments

Comments
 (0)