зеркало из https://github.com/github/ruby.git
merge revision(s) c178926fbe879045fa711444a1fd9e906af23e3b,a4b7ec12298c78392797e5ba7704076550e4f100: [Backport #19444]
YJIT: jit_prepare_routine_call() for String#+@ missing We saw SEGVs due to this when running with StackProf, which needs a correct PC for RUBY_INTERNAL_EVENT_NEWOBJ, the same event used for ObjectSpace allocation tracing. [Bug #19444] --- test/ruby/test_yjit.rb | 27 +++++++++++++++++++++++++++ yjit/src/codegen.rs | 5 ++++- 2 files changed, 31 insertions(+), 1 deletion(-) YJIT: Fix false assumption that String#+@ => ::String Could return a subclass. [Bug #19444] --- test/ruby/test_yjit.rb | 17 +++++++++++++++++ yjit/src/codegen.rs | 10 +++++++--- 2 files changed, 24 insertions(+), 3 deletions(-)
This commit is contained in:
Родитель
f1cde05d99
Коммит
4d75035e17
|
@ -1077,6 +1077,50 @@ class TestYJIT < Test::Unit::TestCase
|
|||
RUBY
|
||||
end
|
||||
|
||||
def test_tracing_str_uplus
|
||||
assert_compiles(<<~RUBY, frozen_string_literal: true, result: :ok)
|
||||
def str_uplus
|
||||
_ = 1
|
||||
_ = 2
|
||||
ret = [+"frfr", __LINE__]
|
||||
_ = 3
|
||||
_ = 4
|
||||
|
||||
ret
|
||||
end
|
||||
|
||||
str_uplus
|
||||
require 'objspace'
|
||||
ObjectSpace.trace_object_allocations_start
|
||||
|
||||
str, expected_line = str_uplus
|
||||
alloc_line = ObjectSpace.allocation_sourceline(str)
|
||||
|
||||
if expected_line == alloc_line
|
||||
:ok
|
||||
else
|
||||
[expected_line, alloc_line]
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
def test_str_uplus_subclass
|
||||
assert_compiles(<<~RUBY, frozen_string_literal: true, result: :subclass)
|
||||
class S < String
|
||||
def encoding
|
||||
:subclass
|
||||
end
|
||||
end
|
||||
|
||||
def test(str)
|
||||
(+str).encoding
|
||||
end
|
||||
|
||||
test ""
|
||||
test S.new
|
||||
RUBY
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def code_gc_helpers
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
|
||||
#define RUBY_VERSION_TEENY 1
|
||||
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
|
||||
#define RUBY_PATCHLEVEL 35
|
||||
#define RUBY_PATCHLEVEL 36
|
||||
|
||||
#include "ruby/version.h"
|
||||
#include "ruby/internal/abi.h"
|
||||
|
|
|
@ -4047,17 +4047,24 @@ fn jit_rb_int_equal(
|
|||
|
||||
/// If string is frozen, duplicate it to get a non-frozen string. Otherwise, return it.
|
||||
fn jit_rb_str_uplus(
|
||||
_jit: &mut JITState,
|
||||
jit: &mut JITState,
|
||||
ctx: &mut Context,
|
||||
asm: &mut Assembler,
|
||||
_ocb: &mut OutlinedCb,
|
||||
_ci: *const rb_callinfo,
|
||||
_cme: *const rb_callable_method_entry_t,
|
||||
_block: Option<IseqPtr>,
|
||||
_argc: i32,
|
||||
argc: i32,
|
||||
_known_recv_class: *const VALUE,
|
||||
) -> bool
|
||||
{
|
||||
if argc != 0 {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We allocate when we dup the string
|
||||
jit_prepare_routine_call(jit, ctx, asm);
|
||||
|
||||
asm.comment("Unary plus on string");
|
||||
let recv_opnd = asm.load(ctx.stack_pop(1));
|
||||
let flags_opnd = asm.load(Opnd::mem(64, recv_opnd, RUBY_OFFSET_RBASIC_FLAGS));
|
||||
|
@ -4065,8 +4072,8 @@ fn jit_rb_str_uplus(
|
|||
|
||||
let ret_label = asm.new_label("stack_ret");
|
||||
|
||||
// We guard for the receiver being a ::String, so the return value is too
|
||||
let stack_ret = ctx.stack_push(Type::CString);
|
||||
// String#+@ can only exist on T_STRING
|
||||
let stack_ret = ctx.stack_push(Type::TString);
|
||||
|
||||
// If the string isn't frozen, we just return it.
|
||||
asm.mov(stack_ret, recv_opnd);
|
||||
|
|
Загрузка…
Ссылка в новой задаче