1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

YJIT: Fix unexpected truncation when outputing VALUE

Previously, YJIT incorrectly discarded the upper 32 bits of the object
pointer when writing out VALUEs to setup default keyword arguments.

In addition to incorrectly truncating, the output pointers were not
properly tracked for handling GC compaction moving the referenced
objects.

YJIT previously attempted to encode a mov instruction with a memory
destination and a 64 bit immediate when there is no such encoding
possible in the ISA. Add an assert to mitigate not being able to
catch this at build time.
This commit is contained in:
Alan Wu 2021-12-14 19:47:42 -05:00 committed by GitHub
parent 6eb500e2df
commit ac5d6faea8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
Notes: git 2021-12-15 09:48:15 +09:00
Merged: https://github.com/ruby/ruby/pull/5274

Merged-By: XrXr
3 changed files with 23 additions and 3 deletions

View file

@ -1,3 +1,18 @@
assert_equal '18374962167983112447', %q{
# regression test for incorrectly discarding 32 bits of a pointer when it
# comes to default values.
def large_literal_default(n: 0xff00_fabcafe0_00ff)
n
end
def call_graph_root
large_literal_default
end
call_graph_root
call_graph_root
}
assert_normal_exit %q{
# regression test for a leak caught by an asert on --yjit-call-threshold=2
Foo = 1

View file

@ -1343,7 +1343,10 @@ void mov(codeblock_t *cb, x86opnd_t dst, x86opnd_t src)
else
cb_write_rm(cb, dst.num_bits == 16, dst.num_bits == 64, NO_OPND, dst, 0, 1, 0xC7);
cb_write_int(cb, src.as.imm, (dst.num_bits > 32)? 32:dst.num_bits);
const uint32_t output_num_bits = (dst.num_bits > 32u) ? 32u : dst.num_bits;
// assert that we can write whole immediate without loss of infomation
assert (sig_imm_size(src.as.imm) <= output_num_bits);
cb_write_int(cb, src.as.imm, output_num_bits);
}
else

View file

@ -3698,7 +3698,7 @@ gen_send_iseq(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, const r
// This struct represents the metadata about the callee-specified
// keyword parameters.
const struct rb_iseq_param_keyword *keyword = iseq->body->param.keyword;
const struct rb_iseq_param_keyword *const keyword = iseq->body->param.keyword;
ADD_COMMENT(cb, "keyword args");
@ -3748,7 +3748,9 @@ gen_send_iseq(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, const r
default_value = Qnil;
}
mov(cb, default_arg, imm_opnd(default_value));
// GC might move default_value.
jit_mov_gc_ptr(jit, cb, REG0, default_value);
mov(cb, default_arg, REG0);
caller_kwargs[kwarg_idx++] = callee_kwarg;
}