mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Delay and be selective about when to discard local types
jit_rb_obj_not() wants to access the type information of the receiver, but we were discarding type info of locals before jit_rb_obj_not() runs unncessarily. There are also cases we are unncessarily discarding local type info. For example, ivar reader and setter methods can never change local variables.
This commit is contained in:
parent
936ee55562
commit
8c68f112d8
1 changed files with 9 additions and 3 deletions
|
@ -2503,6 +2503,9 @@ gen_send_cfunc(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, const
|
||||||
imm_opnd(sizeof(rb_control_frame_t))
|
imm_opnd(sizeof(rb_control_frame_t))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// cfunc calls may corrupt types
|
||||||
|
ctx_clear_local_types(ctx);
|
||||||
|
|
||||||
// Note: gen_oswb_iseq() jumps to the next instruction with ctx->sp_offset == 0
|
// Note: gen_oswb_iseq() jumps to the next instruction with ctx->sp_offset == 0
|
||||||
// after the call, while this does not. This difference prevents
|
// after the call, while this does not. This difference prevents
|
||||||
// the two call types from sharing the same successor.
|
// the two call types from sharing the same successor.
|
||||||
|
@ -2670,6 +2673,9 @@ gen_send_iseq(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, const r
|
||||||
x86opnd_t stack_ret = ctx_stack_push(ctx, TYPE_UNKNOWN);
|
x86opnd_t stack_ret = ctx_stack_push(ctx, TYPE_UNKNOWN);
|
||||||
mov(cb, stack_ret, RAX);
|
mov(cb, stack_ret, RAX);
|
||||||
|
|
||||||
|
// Note: assuming that the leaf builtin doesn't change local variables here.
|
||||||
|
// Seems like a safe assumption.
|
||||||
|
|
||||||
return YJIT_KEEP_COMPILING;
|
return YJIT_KEEP_COMPILING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2770,6 +2776,9 @@ gen_send_iseq(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, const r
|
||||||
val_type_t recv_type = ctx_get_opnd_type(ctx, OPND_STACK(argc));
|
val_type_t recv_type = ctx_get_opnd_type(ctx, OPND_STACK(argc));
|
||||||
ctx_set_opnd_type(&callee_ctx, OPND_SELF, recv_type);
|
ctx_set_opnd_type(&callee_ctx, OPND_SELF, recv_type);
|
||||||
|
|
||||||
|
// The callee might change locals through Kernel#binding and other means.
|
||||||
|
ctx_clear_local_types(ctx);
|
||||||
|
|
||||||
// Pop arguments and receiver in return context, push the return value
|
// Pop arguments and receiver in return context, push the return value
|
||||||
// After the return, the JIT and interpreter SP will match up
|
// After the return, the JIT and interpreter SP will match up
|
||||||
ctx_t return_ctx = *ctx;
|
ctx_t return_ctx = *ctx;
|
||||||
|
@ -2889,9 +2898,6 @@ gen_send_general(jitstate_t *jit, ctx_t *ctx, struct rb_call_data *cd, rb_iseq_t
|
||||||
RUBY_ASSERT(cme->called_id == mid);
|
RUBY_ASSERT(cme->called_id == mid);
|
||||||
assume_method_lookup_stable(comptime_recv_klass, cme, jit->block);
|
assume_method_lookup_stable(comptime_recv_klass, cme, jit->block);
|
||||||
|
|
||||||
// Method calls may corrupt types
|
|
||||||
ctx_clear_local_types(ctx);
|
|
||||||
|
|
||||||
// To handle the aliased method case (VM_METHOD_TYPE_ALIAS)
|
// To handle the aliased method case (VM_METHOD_TYPE_ALIAS)
|
||||||
while (true) {
|
while (true) {
|
||||||
// switch on the method type
|
// switch on the method type
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue