Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 14 additions & 11 deletions gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -4698,19 +4698,22 @@ rb_raw_obj_info_buitin_type(char *const buff, const size_t buff_size, const VALU
APPEND_S("shared -> ");
rb_raw_obj_info(BUFF_ARGS, ARY_SHARED_ROOT(obj));
}
else if (ARY_EMBED_P(obj)) {
APPEND_F("[%s%s] len: %ld (embed)",
C(ARY_EMBED_P(obj), "E"),
C(ARY_SHARED_P(obj), "S"),
RARRAY_LEN(obj));
}
else {
APPEND_F("[%s%s] len: %ld, capa:%ld ptr:%p",
C(ARY_EMBED_P(obj), "E"),
APPEND_F("[%s%s%s] ",
C(ARY_EMBED_P(obj), "E"),
C(ARY_SHARED_P(obj), "S"),
RARRAY_LEN(obj),
ARY_EMBED_P(obj) ? -1L : RARRAY(obj)->as.heap.aux.capa,
(void *)RARRAY_CONST_PTR(obj));
C(ARY_SHARED_ROOT_P(obj), "R"));

if (ARY_EMBED_P(obj)) {
APPEND_F("len: %ld (embed)",
RARRAY_LEN(obj));
}
else {
APPEND_F("len: %ld, capa:%ld ptr:%p",
RARRAY_LEN(obj),
RARRAY(obj)->as.heap.aux.capa,
(void *)RARRAY_CONST_PTR(obj));
}
}
break;
case T_STRING: {
Expand Down
15 changes: 4 additions & 11 deletions iseq.c
Original file line number Diff line number Diff line change
Expand Up @@ -1497,9 +1497,9 @@ rb_iseq_remove_coverage_all(void)
/* define wrapper class methods (RubyVM::InstructionSequence) */

static void
iseqw_mark(void *ptr)
iseqw_mark_and_move(void *ptr)
{
rb_gc_mark_movable(*(VALUE *)ptr);
rb_gc_mark_and_move((VALUE *)ptr);
}

static size_t
Expand All @@ -1508,20 +1508,13 @@ iseqw_memsize(const void *ptr)
return rb_iseq_memsize(*(const rb_iseq_t **)ptr);
}

static void
iseqw_ref_update(void *ptr)
{
VALUE *vptr = ptr;
*vptr = rb_gc_location(*vptr);
}

static const rb_data_type_t iseqw_data_type = {
"T_IMEMO/iseq",
{
iseqw_mark,
iseqw_mark_and_move,
RUBY_TYPED_DEFAULT_FREE,
iseqw_memsize,
iseqw_ref_update,
iseqw_mark_and_move,
},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY|RUBY_TYPED_WB_PROTECTED
};
Expand Down
1 change: 1 addition & 0 deletions test/.excludes-zjit/TestRubyOptimization.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
exclude(:test_side_effect_in_popped_splat, 'Test fails with ZJIT due to locals invalidation')
2 changes: 1 addition & 1 deletion test/ruby/test_gc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ def obj.bar() raise "obj.foo is called, but this is obj.bar" end
end

def test_singleton_method_added
assert_in_out_err([], <<-EOS, [], [], "[ruby-dev:44436]")
assert_in_out_err([], <<-EOS, [], [], "[ruby-dev:44436]", timeout: 30)
class BasicObject
undef singleton_method_added
def singleton_method_added(mid)
Expand Down
2 changes: 1 addition & 1 deletion test/ruby/test_keyword.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4033,7 +4033,7 @@ def m(a: [])
tap { m }
GC.start
tap { m }
}, bug8964
}, bug8964, timeout: 30
assert_normal_exit %q{
prc = Proc.new {|a: []|}
GC.stress = true
Expand Down
118 changes: 118 additions & 0 deletions test/ruby/test_zjit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,116 @@ def test(a, b) = a >= b
}, insns: [:opt_ge], call_threshold: 2
end

def test_new_hash_empty
assert_compiles '{}', %q{
def test = {}
test
}, insns: [:newhash]
end

def test_new_hash_nonempty
assert_compiles '{"key" => "value", 42 => 100}', %q{
def test
key = "key"
value = "value"
num = 42
result = 100
{key => value, num => result}
end
test
}, insns: [:newhash]
end

def test_new_hash_single_key_value
assert_compiles '{"key" => "value"}', %q{
def test = {"key" => "value"}
test
}, insns: [:newhash]
end

def test_new_hash_with_computation
assert_compiles '{"sum" => 5, "product" => 6}', %q{
def test(a, b)
{"sum" => a + b, "product" => a * b}
end
test(2, 3)
}, insns: [:newhash]
end

def test_new_hash_with_user_defined_hash_method
assert_runs 'true', %q{
class CustomKey
attr_reader :val

def initialize(val)
@val = val
end

def hash
@val.hash
end

def eql?(other)
other.is_a?(CustomKey) && @val == other.val
end
end

def test
key = CustomKey.new("key")
hash = {key => "value"}
hash[key] == "value"
end
test
}
end

def test_new_hash_with_user_hash_method_exception
assert_runs 'RuntimeError', %q{
class BadKey
def hash
raise "Hash method failed!"
end
end

def test
key = BadKey.new
{key => "value"}
end

begin
test
rescue => e
e.class
end
}
end

def test_new_hash_with_user_eql_method_exception
assert_runs 'RuntimeError', %q{
class BadKey
def hash
42
end

def eql?(other)
raise "Eql method failed!"
end
end

def test
key1 = BadKey.new
key2 = BadKey.new
{key1 => "value1", key2 => "value2"}
end

begin
test
rescue => e
e.class
end
}
end

def test_opt_hash_freeze
assert_compiles '{}', <<~RUBY, insns: [:opt_hash_freeze]
def test = {}.freeze
Expand Down Expand Up @@ -1135,6 +1245,14 @@ def test = return defined?(Foo), defined?(bar), defined?($ruby)
}, insns: [:defined]
end

def test_defined_with_method_call
assert_compiles '["method", nil]', %q{
def test = return defined?("x".reverse(1)), defined?("x".reverse(1).reverse)

test
}, insns: [:defined]
end

def test_defined_yield
assert_compiles "nil", "defined?(yield)"
assert_compiles '[nil, nil, "yield"]', %q{
Expand Down
6 changes: 5 additions & 1 deletion zjit/src/backend/lir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1684,6 +1684,7 @@ impl Assembler {
}

pub fn cpop_into(&mut self, opnd: Opnd) {
assert!(matches!(opnd, Opnd::Reg(_)), "Destination of cpop_into must be a register, got: {opnd:?}");
self.push_insn(Insn::CPopInto(opnd));
}

Expand Down Expand Up @@ -1831,6 +1832,7 @@ impl Assembler {
}

pub fn lea_into(&mut self, out: Opnd, opnd: Opnd) {
assert!(matches!(out, Opnd::Reg(_)), "Destination of lea_into must be a register, got: {out:?}");
self.push_insn(Insn::Lea { opnd, out });
}

Expand All @@ -1856,7 +1858,7 @@ impl Assembler {
}

pub fn load_into(&mut self, dest: Opnd, opnd: Opnd) {
assert!(matches!(dest, Opnd::Reg(_) | Opnd::VReg{..}), "Destination of load_into must be a register");
assert!(matches!(dest, Opnd::Reg(_)), "Destination of load_into must be a register, got: {dest:?}");
match (dest, opnd) {
(Opnd::Reg(dest), Opnd::Reg(opnd)) if dest == opnd => {}, // skip if noop
_ => self.push_insn(Insn::LoadInto { dest, opnd }),
Expand All @@ -1882,6 +1884,7 @@ impl Assembler {
}

pub fn mov(&mut self, dest: Opnd, src: Opnd) {
assert!(!matches!(dest, Opnd::VReg { .. }), "Destination of mov must not be Opnd::VReg, got: {dest:?}");
self.push_insn(Insn::Mov { dest, src });
}

Expand Down Expand Up @@ -1919,6 +1922,7 @@ impl Assembler {
}

pub fn store(&mut self, dest: Opnd, src: Opnd) {
assert!(!matches!(dest, Opnd::VReg { .. }), "Destination of store must not be Opnd::VReg, got: {dest:?}");
self.push_insn(Insn::Store { dest, src });
}

Expand Down
Loading