mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
test_jit.rb: verify tested insns
and fix some untested insns git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63323 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
853707123e
commit
d48efc4c83
1 changed files with 102 additions and 68 deletions
|
@ -7,7 +7,6 @@ require_relative '../lib/jit_support'
|
||||||
class TestJIT < Test::Unit::TestCase
|
class TestJIT < Test::Unit::TestCase
|
||||||
include JITSupport
|
include JITSupport
|
||||||
# Ensure all supported insns can be compiled. Only basic tests are included.
|
# Ensure all supported insns can be compiled. Only basic tests are included.
|
||||||
# TODO: ensure --dump=insns includes the expected insn
|
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
unless JITSupport.supported?
|
unless JITSupport.supported?
|
||||||
|
@ -16,11 +15,11 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_nop
|
def test_compile_insn_nop
|
||||||
assert_compile_once('nil rescue true', result_inspect: 'nil')
|
assert_compile_once('nil rescue true', result_inspect: 'nil', insns: %i[nop])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_local
|
def test_compile_insn_local
|
||||||
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '1')
|
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '1', insns: %i[setlocal_WC_0 getlocal_WC_0])
|
||||||
begin;
|
begin;
|
||||||
foo = 1
|
foo = 1
|
||||||
foo
|
foo
|
||||||
|
@ -28,7 +27,7 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_blockparam
|
def test_compile_insn_blockparam
|
||||||
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '3', success_count: 2)
|
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '3', success_count: 2, insns: %i[getblockparam setblockparam])
|
||||||
begin;
|
begin;
|
||||||
def foo(&b)
|
def foo(&b)
|
||||||
a = b
|
a = b
|
||||||
|
@ -45,18 +44,18 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_getspecial
|
def test_compile_insn_getspecial
|
||||||
assert_compile_once('$1', result_inspect: 'nil')
|
assert_compile_once('$1', result_inspect: 'nil', insns: %i[getspecial])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_setspecial
|
def test_compile_insn_setspecial
|
||||||
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: 'true')
|
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: 'true', insns: %i[setspecial])
|
||||||
begin;
|
begin;
|
||||||
true if nil.nil?..nil.nil?
|
true if nil.nil?..nil.nil?
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_instancevariable
|
def test_compile_insn_instancevariable
|
||||||
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '1')
|
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '1', insns: %i[getinstancevariable setinstancevariable])
|
||||||
begin;
|
begin;
|
||||||
@foo = 1
|
@foo = 1
|
||||||
@foo
|
@foo
|
||||||
|
@ -64,7 +63,7 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_classvariable
|
def test_compile_insn_classvariable
|
||||||
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '1')
|
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '1', insns: %i[getclassvariable setclassvariable])
|
||||||
begin;
|
begin;
|
||||||
@@foo = 1
|
@@foo = 1
|
||||||
@@foo
|
@@foo
|
||||||
|
@ -72,7 +71,7 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_constant
|
def test_compile_insn_constant
|
||||||
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '1')
|
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '1', insns: %i[getconstant setconstant])
|
||||||
begin;
|
begin;
|
||||||
FOO = 1
|
FOO = 1
|
||||||
FOO
|
FOO
|
||||||
|
@ -80,7 +79,7 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_global
|
def test_compile_insn_global
|
||||||
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '1')
|
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '1', insns: %i[getglobal setglobal])
|
||||||
begin;
|
begin;
|
||||||
$foo = 1
|
$foo = 1
|
||||||
$foo
|
$foo
|
||||||
|
@ -88,24 +87,24 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_putnil
|
def test_compile_insn_putnil
|
||||||
assert_compile_once('nil', result_inspect: 'nil')
|
assert_compile_once('nil', result_inspect: 'nil', insns: %i[putnil])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_putself
|
def test_compile_insn_putself
|
||||||
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: 'hello', success_count: 1)
|
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: 'hello', success_count: 1, insns: %i[putself])
|
||||||
begin;
|
begin;
|
||||||
proc { print "hello" }.call
|
proc { print "hello" }.call
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_putobject
|
def test_compile_insn_putobject
|
||||||
assert_compile_once('0', result_inspect: '0') # putobject_OP_INT2FIX_O_0_C_
|
assert_compile_once('0', result_inspect: '0', insns: %i[putobject_INT2FIX_0_])
|
||||||
assert_compile_once('1', result_inspect: '1') # putobject_OP_INT2FIX_O_1_C_
|
assert_compile_once('1', result_inspect: '1', insns: %i[putobject_INT2FIX_1_])
|
||||||
assert_compile_once('2', result_inspect: '2')
|
assert_compile_once('2', result_inspect: '2', insns: %i[putobject])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_putspecialobject_putiseq
|
def test_compile_insn_putspecialobject_putiseq
|
||||||
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: 'hello', success_count: 2)
|
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: 'hello', success_count: 2, insns: %i[putspecialobject putiseq])
|
||||||
begin;
|
begin;
|
||||||
print proc {
|
print proc {
|
||||||
def method_definition
|
def method_definition
|
||||||
|
@ -117,11 +116,11 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_putstring_concatstrings_tostring
|
def test_compile_insn_putstring_concatstrings_tostring
|
||||||
assert_compile_once('"a#{}b" + "c"', result_inspect: '"abc"')
|
assert_compile_once('"a#{}b" + "c"', result_inspect: '"abc"', insns: %i[tostring])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_freezestring
|
def test_compile_insn_freezestring
|
||||||
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~'end;'}", stdout: 'true', success_count: 1)
|
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~'end;'}", stdout: 'true', success_count: 1, insns: %i[freezestring])
|
||||||
begin;
|
begin;
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
print proc { "#{true}".frozen? }.call
|
print proc { "#{true}".frozen? }.call
|
||||||
|
@ -129,11 +128,11 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_toregexp
|
def test_compile_insn_toregexp
|
||||||
assert_compile_once('/#{true}/ =~ "true"', result_inspect: '0')
|
assert_compile_once('/#{true}/ =~ "true"', result_inspect: '0', insns: %i[toregexp])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_newarray
|
def test_compile_insn_newarray
|
||||||
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '[1, 2, 3]')
|
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '[1, 2, 3]', insns: %i[newarray])
|
||||||
begin;
|
begin;
|
||||||
a, b, c = 1, 2, 3
|
a, b, c = 1, 2, 3
|
||||||
[a, b, c]
|
[a, b, c]
|
||||||
|
@ -141,31 +140,31 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_intern_duparray
|
def test_compile_insn_intern_duparray
|
||||||
assert_compile_once('[:"#{0}"] + [1,2,3]', result_inspect: '[:"0", 1, 2, 3]')
|
assert_compile_once('[:"#{0}"] + [1,2,3]', result_inspect: '[:"0", 1, 2, 3]', insns: %i[duparray])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_expandarray
|
def test_compile_insn_expandarray
|
||||||
assert_compile_once('y = [ true, false, nil ]; x, = y; x', result_inspect: 'true')
|
assert_compile_once('y = [ true, false, nil ]; x, = y; x', result_inspect: 'true', insns: %i[expandarray])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_concatarray
|
def test_compile_insn_concatarray
|
||||||
assert_compile_once('["t", "r", *x = "u", "e"].join', result_inspect: '"true"')
|
assert_compile_once('["t", "r", *x = "u", "e"].join', result_inspect: '"true"', insns: %i[concatarray])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_splatarray
|
def test_compile_insn_splatarray
|
||||||
assert_compile_once('[*(1..2)]', result_inspect: '[1, 2]')
|
assert_compile_once('[*(1..2)]', result_inspect: '[1, 2]', insns: %i[splatarray])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_newhash
|
def test_compile_insn_newhash
|
||||||
assert_compile_once('a = 1; { a: a }', result_inspect: '{:a=>1}')
|
assert_compile_once('a = 1; { a: a }', result_inspect: '{:a=>1}', insns: %i[newhash])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_newrange
|
def test_compile_insn_newrange
|
||||||
assert_compile_once('a = 1; 0..a', result_inspect: '0..1')
|
assert_compile_once('a = 1; 0..a', result_inspect: '0..1', insns: %i[newrange])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_pop
|
def test_compile_insn_pop
|
||||||
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '1')
|
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '1', insns: %i[pop])
|
||||||
begin;
|
begin;
|
||||||
a = false
|
a = false
|
||||||
b = 1
|
b = 1
|
||||||
|
@ -174,7 +173,7 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_dup
|
def test_compile_insn_dup
|
||||||
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '3')
|
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '3', insns: %i[dup])
|
||||||
begin;
|
begin;
|
||||||
a = 1
|
a = 1
|
||||||
a&.+(2)
|
a&.+(2)
|
||||||
|
@ -182,7 +181,7 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_dupn
|
def test_compile_insn_dupn
|
||||||
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: 'true')
|
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: 'true', insns: %i[dupn])
|
||||||
begin;
|
begin;
|
||||||
klass = Class.new
|
klass = Class.new
|
||||||
klass::X ||= true
|
klass::X ||= true
|
||||||
|
@ -190,11 +189,11 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_swap_topn
|
def test_compile_insn_swap_topn
|
||||||
assert_compile_once('{}["true"] = true', result_inspect: 'true')
|
assert_compile_once('{}["true"] = true', result_inspect: 'true', insns: %i[swap topn])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_reverse
|
def test_compile_insn_reverse
|
||||||
assert_compile_once('q, (w, e), r = 1, [2, 3], 4; e == 3', result_inspect: 'true')
|
assert_compile_once('q, (w, e), r = 1, [2, 3], 4; e == 3', result_inspect: 'true', insns: %i[reverse])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_reput
|
def test_compile_insn_reput
|
||||||
|
@ -202,11 +201,11 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_setn
|
def test_compile_insn_setn
|
||||||
assert_compile_once('[nil][0] = 1', result_inspect: '1')
|
assert_compile_once('[nil][0] = 1', result_inspect: '1', insns: %i[setn])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_adjuststack
|
def test_compile_insn_adjuststack
|
||||||
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: 'true')
|
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: 'true', insns: %i[adjuststack])
|
||||||
begin;
|
begin;
|
||||||
x = [true]
|
x = [true]
|
||||||
x[0] ||= nil
|
x[0] ||= nil
|
||||||
|
@ -215,11 +214,11 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_defined
|
def test_compile_insn_defined
|
||||||
assert_compile_once('defined?(a)', result_inspect: 'nil')
|
assert_compile_once('defined?(a)', result_inspect: 'nil', insns: %i[defined])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_checkkeyword
|
def test_compile_insn_checkkeyword
|
||||||
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: 'true', success_count: 1)
|
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: 'true', success_count: 1, insns: %i[checkkeyword])
|
||||||
begin;
|
begin;
|
||||||
def test(x: rand)
|
def test(x: rand)
|
||||||
x
|
x
|
||||||
|
@ -237,28 +236,28 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_send
|
def test_compile_insn_send
|
||||||
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '1', success_count: 2)
|
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '1', success_count: 2, insns: %i[send])
|
||||||
begin;
|
begin;
|
||||||
print proc { yield_self { 1 } }.call
|
print proc { yield_self { 1 } }.call
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_opt_str_freeze
|
def test_compile_insn_opt_str_freeze
|
||||||
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '"foo"')
|
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '"foo"', insns: %i[opt_str_freeze])
|
||||||
begin;
|
begin;
|
||||||
'foo'.freeze
|
'foo'.freeze
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_opt_str_uminus
|
def test_compile_insn_opt_str_uminus
|
||||||
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '"bar"')
|
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '"bar"', insns: %i[opt_str_uminus])
|
||||||
begin;
|
begin;
|
||||||
-'bar'
|
-'bar'
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_opt_newarray_max
|
def test_compile_insn_opt_newarray_max
|
||||||
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '2')
|
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '2', insns: %i[opt_newarray_max])
|
||||||
begin;
|
begin;
|
||||||
a = 1
|
a = 1
|
||||||
b = 2
|
b = 2
|
||||||
|
@ -267,7 +266,7 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_opt_newarray_min
|
def test_compile_insn_opt_newarray_min
|
||||||
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '1')
|
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '1', insns: %i[opt_newarray_min])
|
||||||
begin;
|
begin;
|
||||||
a = 1
|
a = 1
|
||||||
b = 2
|
b = 2
|
||||||
|
@ -276,11 +275,11 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_opt_send_without_block
|
def test_compile_insn_opt_send_without_block
|
||||||
assert_compile_once('print', result_inspect: 'nil')
|
assert_compile_once('print', result_inspect: 'nil', insns: %i[opt_send_without_block])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_invokesuper
|
def test_compile_insn_invokesuper
|
||||||
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '3', success_count: 4)
|
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '3', success_count: 4, insns: %i[invokesuper])
|
||||||
begin;
|
begin;
|
||||||
mod = Module.new {
|
mod = Module.new {
|
||||||
def test
|
def test
|
||||||
|
@ -298,7 +297,7 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_invokeblock_leave
|
def test_compile_insn_invokeblock_leave
|
||||||
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '2', success_count: 2)
|
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '2', success_count: 2, insns: %i[invokeblock leave])
|
||||||
begin;
|
begin;
|
||||||
def foo
|
def foo
|
||||||
yield
|
yield
|
||||||
|
@ -308,7 +307,7 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_throw
|
def test_compile_insn_throw
|
||||||
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '4', success_count: 2)
|
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '4', success_count: 2, insns: %i[throw])
|
||||||
begin;
|
begin;
|
||||||
def test
|
def test
|
||||||
proc do
|
proc do
|
||||||
|
@ -325,15 +324,15 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_jump_branchif
|
def test_compile_insn_jump_branchif
|
||||||
assert_compile_once("#{<<~"begin;"}\n#{<<~'end;'}", result_inspect: 'nil')
|
assert_compile_once("#{<<~"begin;"}\n#{<<~'end;'}", result_inspect: 'nil', insns: %i[jump branchif])
|
||||||
begin;
|
begin;
|
||||||
a = false
|
a = false
|
||||||
1 + 1 while false
|
1 + 1 while a
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_branchunless
|
def test_compile_insn_branchunless
|
||||||
assert_compile_once("#{<<~"begin;"}\n#{<<~'end;'}", result_inspect: '1')
|
assert_compile_once("#{<<~"begin;"}\n#{<<~'end;'}", result_inspect: '1', insns: %i[branchunless])
|
||||||
begin;
|
begin;
|
||||||
a = true
|
a = true
|
||||||
if a
|
if a
|
||||||
|
@ -345,7 +344,7 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_branchnil
|
def test_compile_insn_branchnil
|
||||||
assert_compile_once("#{<<~"begin;"}\n#{<<~'end;'}", result_inspect: '3')
|
assert_compile_once("#{<<~"begin;"}\n#{<<~'end;'}", result_inspect: '3', insns: %i[branchnil])
|
||||||
begin;
|
begin;
|
||||||
a = 2
|
a = 2
|
||||||
a&.+(1)
|
a&.+(1)
|
||||||
|
@ -353,7 +352,7 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_checktype
|
def test_compile_insn_checktype
|
||||||
assert_compile_once("#{<<~"begin;"}\n#{<<~'end;'}", result_inspect: '"42"')
|
assert_compile_once("#{<<~"begin;"}\n#{<<~'end;'}", result_inspect: '"42"', insns: %i[checktype])
|
||||||
begin;
|
begin;
|
||||||
a = '2'
|
a = '2'
|
||||||
"4#{a}"
|
"4#{a}"
|
||||||
|
@ -361,43 +360,43 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_inlinecache
|
def test_compile_insn_inlinecache
|
||||||
assert_compile_once('Struct', result_inspect: 'Struct')
|
assert_compile_once('Struct', result_inspect: 'Struct', insns: %i[getinlinecache setinlinecache])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_once
|
def test_compile_insn_once
|
||||||
assert_compile_once('/#{true}/o =~ "true" && $~.to_a', result_inspect: '["true"]')
|
assert_compile_once('/#{true}/o =~ "true" && $~.to_a', result_inspect: '["true"]', insns: %i[once])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_checkmatch_opt_case_dispatch
|
def test_compile_insn_checkmatch_opt_case_dispatch
|
||||||
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '"world"')
|
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '"world"', insns: %i[opt_case_dispatch])
|
||||||
begin;
|
begin;
|
||||||
case 'hello'
|
case 'hello'
|
||||||
when /hello/
|
when 'hello'
|
||||||
'world'
|
'world'
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_opt_calc
|
def test_compile_insn_opt_calc
|
||||||
assert_compile_once('4 + 2 - ((2 * 3 / 2) % 2)', result_inspect: '5')
|
assert_compile_once('4 + 2 - ((2 * 3 / 2) % 2)', result_inspect: '5', insns: %i[opt_plus opt_minus opt_mult opt_div opt_mod])
|
||||||
assert_compile_once('4 + 2', result_inspect: '6')
|
assert_compile_once('4 + 2', result_inspect: '6')
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_opt_cmp
|
def test_compile_insn_opt_cmp
|
||||||
assert_compile_once('(1 == 1) && (1 != 2)', result_inspect: 'true')
|
assert_compile_once('(1 == 1) && (1 != 2)', result_inspect: 'true', insns: %i[opt_eq opt_neq])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_opt_rel
|
def test_compile_insn_opt_rel
|
||||||
assert_compile_once('1 < 2 && 1 <= 1 && 2 > 1 && 1 >= 1', result_inspect: 'true')
|
assert_compile_once('1 < 2 && 1 <= 1 && 2 > 1 && 1 >= 1', result_inspect: 'true', insns: %i[opt_lt opt_le opt_gt opt_ge])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_opt_ltlt
|
def test_compile_insn_opt_ltlt
|
||||||
assert_compile_once('[1] << 2', result_inspect: '[1, 2]')
|
assert_compile_once('[1] << 2', result_inspect: '[1, 2]', insns: %i[opt_ltlt])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_opt_aref
|
def test_compile_insn_opt_aref
|
||||||
# optimized call (optimized JIT) -> send call
|
# optimized call (optimized JIT) -> send call
|
||||||
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '21', success_count: 2, min_calls: 1)
|
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '21', success_count: 2, min_calls: 1, insns: %i[opt_aref])
|
||||||
begin;
|
begin;
|
||||||
obj = Object.new
|
obj = Object.new
|
||||||
def obj.[](h)
|
def obj.[](h)
|
||||||
|
@ -425,7 +424,7 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_opt_aset
|
def test_compile_insn_opt_aset
|
||||||
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '5')
|
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '5', insns: %i[opt_aset])
|
||||||
begin;
|
begin;
|
||||||
hash = { '1' => 2 }
|
hash = { '1' => 2 }
|
||||||
(hash['2'] = 2) + (hash[1.to_s] = 3)
|
(hash['2'] = 2) + (hash[1.to_s] = 3)
|
||||||
|
@ -433,7 +432,7 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_opt_length_size
|
def test_compile_insn_opt_length_size
|
||||||
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '4')
|
assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '4', insns: %i[opt_length])
|
||||||
begin;
|
begin;
|
||||||
array = [1, 2]
|
array = [1, 2]
|
||||||
array.length + array.size
|
array.length + array.size
|
||||||
|
@ -441,23 +440,23 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_opt_empty_p
|
def test_compile_insn_opt_empty_p
|
||||||
assert_compile_once('[].empty?', result_inspect: 'true')
|
assert_compile_once('[].empty?', result_inspect: 'true', insns: %i[opt_empty_p])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_opt_succ
|
def test_compile_insn_opt_succ
|
||||||
assert_compile_once('1.succ', result_inspect: '2')
|
assert_compile_once('1.succ', result_inspect: '2', insns: %i[opt_succ])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_opt_not
|
def test_compile_insn_opt_not
|
||||||
assert_compile_once('!!true', result_inspect: 'true')
|
assert_compile_once('!!true', result_inspect: 'true', insns: %i[opt_not])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_opt_regexpmatch1
|
def test_compile_insn_opt_regexpmatch1
|
||||||
assert_compile_once("/true/ =~ 'true'", result_inspect: '0')
|
assert_compile_once("/true/ =~ 'true'", result_inspect: '0', insns: %i[opt_regexpmatch1])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_opt_regexpmatch2
|
def test_compile_insn_opt_regexpmatch2
|
||||||
assert_compile_once("'true' =~ /true/", result_inspect: '0')
|
assert_compile_once("'true' =~ /true/", result_inspect: '0', insns: %i[opt_regexpmatch2])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_opt_call_c_function
|
def test_compile_insn_opt_call_c_function
|
||||||
|
@ -589,17 +588,17 @@ class TestJIT < Test::Unit::TestCase
|
||||||
private
|
private
|
||||||
|
|
||||||
# The shortest way to test one proc
|
# The shortest way to test one proc
|
||||||
def assert_compile_once(script, result_inspect:)
|
def assert_compile_once(script, result_inspect:, insns: [])
|
||||||
if script.match?(/\A\n.+\n\z/m)
|
if script.match?(/\A\n.+\n\z/m)
|
||||||
script = script.gsub(/^/, ' ')
|
script = script.gsub(/^/, ' ')
|
||||||
else
|
else
|
||||||
script = " #{script} "
|
script = " #{script} "
|
||||||
end
|
end
|
||||||
assert_eval_with_jit("p proc {#{script}}.call", stdout: "#{result_inspect}\n", success_count: 1)
|
assert_eval_with_jit("p proc {#{script}}.call", stdout: "#{result_inspect}\n", success_count: 1, insns: insns, uplevel: 4)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Shorthand for normal test cases
|
# Shorthand for normal test cases
|
||||||
def assert_eval_with_jit(script, stdout: nil, success_count:, min_calls: 1)
|
def assert_eval_with_jit(script, stdout: nil, success_count:, min_calls: 1, insns: [], uplevel: 3)
|
||||||
out, err = eval_with_jit(script, verbose: 1, min_calls: min_calls)
|
out, err = eval_with_jit(script, verbose: 1, min_calls: min_calls)
|
||||||
actual = err.scan(/^#{JIT_SUCCESS_PREFIX}:/).size
|
actual = err.scan(/^#{JIT_SUCCESS_PREFIX}:/).size
|
||||||
|
|
||||||
|
@ -616,6 +615,15 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Make sure that the script has insns expected to be tested
|
||||||
|
used_insns = method_insns(script)
|
||||||
|
insns.each do |insn|
|
||||||
|
unless used_insns.include?(insn)
|
||||||
|
$stderr.puts
|
||||||
|
warn "'#{insn}' insn is not included in the script. Actual insns are: #{used_insns.join(' ')}\n", uplevel: uplevel
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
assert_equal(
|
assert_equal(
|
||||||
success_count, actual,
|
success_count, actual,
|
||||||
"Expected #{success_count} times of JIT success, but succeeded #{actual} times.\n\n"\
|
"Expected #{success_count} times of JIT success, but succeeded #{actual} times.\n\n"\
|
||||||
|
@ -626,6 +634,32 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Collect block's insns or defined method's insns, which are expected to be JIT-ed.
|
||||||
|
def method_insns(script)
|
||||||
|
insns = []
|
||||||
|
RubyVM::InstructionSequence.compile(script).to_a.last.each do |(insn, *args)|
|
||||||
|
case insn
|
||||||
|
when :putiseq, :send
|
||||||
|
insns += collect_insns(args.last)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
insns.uniq
|
||||||
|
end
|
||||||
|
|
||||||
|
# Recursively collect insns in iseq_array
|
||||||
|
def collect_insns(iseq_array)
|
||||||
|
return [] if iseq_array.nil?
|
||||||
|
|
||||||
|
insns = iseq_array.last.select { |x| x.is_a?(Array) }.map(&:first)
|
||||||
|
iseq_array.last.each do |(insn, *args)|
|
||||||
|
case insn
|
||||||
|
when :putiseq, :send
|
||||||
|
insns += collect_insns(args.last)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
insns
|
||||||
|
end
|
||||||
|
|
||||||
# Run Ruby script with --jit-wait (Synchronous JIT compilation).
|
# Run Ruby script with --jit-wait (Synchronous JIT compilation).
|
||||||
# Returns [stdout, stderr]
|
# Returns [stdout, stderr]
|
||||||
def eval_with_jit(env = nil, script, **opts)
|
def eval_with_jit(env = nil, script, **opts)
|
||||||
|
|
Loading…
Add table
Reference in a new issue