ytljit 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ext/extconf.rb +1 -1
- data/ext/memory.c +3 -3
- data/ext/ytljit.c +87 -48
- data/ext/ytljit.h +2 -0
- data/lib/ytljit/asm.rb +44 -8
- data/lib/ytljit/asmext.rb +1 -1
- data/lib/ytljit/asmext_x64.rb +18 -34
- data/lib/ytljit/asmext_x86.rb +15 -13
- data/lib/ytljit/asmutil.rb +4 -0
- data/lib/ytljit/instruction.rb +8 -1
- data/lib/ytljit/instruction_ia.rb +27 -16
- data/lib/ytljit/instruction_x64.rb +1 -3
- data/lib/ytljit/util.rb +29 -0
- data/lib/ytljit/vm.rb +464 -135
- data/lib/ytljit/vm_codegen.rb +111 -30
- data/lib/ytljit/vm_cruby_obj.rb +12 -10
- data/lib/ytljit/vm_inline_method.rb +32 -4
- data/lib/ytljit/vm_sendnode.rb +292 -38
- data/lib/ytljit/vm_trans.rb +221 -25
- data/lib/ytljit/vm_type.rb +6 -1
- data/lib/ytljit/vm_type_gen.rb +102 -20
- data/test/test_assemble2.rb +11 -8
- metadata +3 -3
data/lib/ytljit/vm_codegen.rb
CHANGED
@@ -233,6 +233,7 @@ LO | | | |
|
|
233
233
|
include AbsArch
|
234
234
|
def initialize(tnode)
|
235
235
|
@top_node = tnode
|
236
|
+
@prev_context = nil
|
236
237
|
@code_space = nil
|
237
238
|
|
238
239
|
# Signature of current compiling method
|
@@ -256,6 +257,7 @@ LO | | | |
|
|
256
257
|
end
|
257
258
|
|
258
259
|
attr :top_node
|
260
|
+
attr_accessor :prev_context
|
259
261
|
attr :code_space
|
260
262
|
|
261
263
|
attr :current_method_signature
|
@@ -266,7 +268,7 @@ LO | | | |
|
|
266
268
|
attr_accessor :ret_node
|
267
269
|
|
268
270
|
attr :reg_content
|
269
|
-
|
271
|
+
attr_accessor :stack_content
|
270
272
|
|
271
273
|
attr_accessor :slf
|
272
274
|
|
@@ -277,34 +279,57 @@ LO | | | |
|
|
277
279
|
dst = dst.dst_opecode
|
278
280
|
end
|
279
281
|
if dst.is_a?(OpRegistor) then
|
280
|
-
if val.is_a?(OpRegistor)
|
282
|
+
if val.is_a?(OpRegistor) and @reg_content[val] then
|
281
283
|
@reg_content[dst] = @reg_content[val]
|
282
284
|
else
|
283
285
|
@reg_content[dst] = val
|
284
286
|
end
|
285
|
-
elsif dst.is_a?(OpIndirect)
|
287
|
+
elsif dst.is_a?(OpIndirect) then
|
286
288
|
wsiz = AsmType::MACHINE_WORD.size
|
287
|
-
if
|
288
|
-
|
289
|
-
|
290
|
-
|
289
|
+
if dst.reg == SPR then
|
290
|
+
if val.is_a?(OpRegistor) and @reg_content[val] then
|
291
|
+
cpustack_setn(dst.disp.value / wsiz, @reg_content[val])
|
292
|
+
else
|
293
|
+
cpustack_setn(dst.disp.value / wsiz, val)
|
294
|
+
end
|
295
|
+
end
|
296
|
+
if dst.reg == BPR then
|
297
|
+
if val.is_a?(OpRegistor) and @reg_content[val] then
|
298
|
+
cpustack_setn(-dst.disp.value / wsiz + 3, @reg_content[val])
|
299
|
+
else
|
300
|
+
cpustack_setn(-dst.disp.value / wsiz + 3, val)
|
301
|
+
end
|
291
302
|
end
|
303
|
+
elsif dst.is_a?(OpImmidiate) then
|
304
|
+
# do nothing and legal
|
305
|
+
|
292
306
|
else
|
293
|
-
pp "foo"
|
294
|
-
pp dst
|
307
|
+
# pp "foo"
|
308
|
+
# pp dst
|
295
309
|
end
|
296
310
|
end
|
297
311
|
|
298
312
|
def cpustack_push(reg)
|
299
|
-
|
313
|
+
if @reg_content[reg] then
|
314
|
+
@stack_content.push @reg_content[reg]
|
315
|
+
else
|
316
|
+
@stack_content.push reg
|
317
|
+
end
|
300
318
|
end
|
301
319
|
|
302
320
|
def cpustack_pop(reg)
|
303
|
-
|
321
|
+
cont = @stack_content.pop
|
322
|
+
if !cont.is_a?(OpRegistor) then
|
323
|
+
@reg_content[reg] = cont
|
324
|
+
end
|
304
325
|
end
|
305
326
|
|
306
327
|
def cpustack_setn(offset, val)
|
307
|
-
|
328
|
+
if offset >= -@stack_content.size then
|
329
|
+
@stack_content[offset] = val
|
330
|
+
else
|
331
|
+
# Modify previous stack (maybe as arguments)
|
332
|
+
end
|
308
333
|
end
|
309
334
|
|
310
335
|
def cpustack_pushn(num)
|
@@ -338,7 +363,6 @@ LO | | | |
|
|
338
363
|
end
|
339
364
|
|
340
365
|
def reset_using_reg
|
341
|
-
# @depth_reg = {}
|
342
366
|
@depth_reg = Hash.new(0)
|
343
367
|
end
|
344
368
|
|
@@ -417,6 +441,29 @@ LO | | | |
|
|
417
441
|
end
|
418
442
|
end
|
419
443
|
|
444
|
+
def start_arg_reg(kind = FUNC_ARG)
|
445
|
+
asm = assembler
|
446
|
+
gen = asm.generator
|
447
|
+
used_arg_tab = gen.funcarg_info.used_arg_tab
|
448
|
+
if used_arg_tab.last then
|
449
|
+
# p "#{used_arg_tab.last.keys} #{caller[0]} #{@name}"
|
450
|
+
used_arg_tab.last.keys.each do |rno|
|
451
|
+
start_using_reg(kind[rno])
|
452
|
+
end
|
453
|
+
end
|
454
|
+
end
|
455
|
+
|
456
|
+
def end_arg_reg(kind = FUNC_ARG)
|
457
|
+
asm = assembler
|
458
|
+
gen = asm.generator
|
459
|
+
used_arg_tab = gen.funcarg_info.used_arg_tab
|
460
|
+
if used_arg_tab.last then
|
461
|
+
used_arg_tab.last.keys.reverse.each do |rno|
|
462
|
+
end_using_reg(kind[rno])
|
463
|
+
end
|
464
|
+
end
|
465
|
+
end
|
466
|
+
|
420
467
|
def to_signature(offset = -1)
|
421
468
|
@current_method_signature[offset]
|
422
469
|
end
|
@@ -445,9 +492,14 @@ LO | | | |
|
|
445
492
|
asm.push(BPR)
|
446
493
|
asm.mov(BPR, SPR)
|
447
494
|
asm.push(TMPR)
|
495
|
+
asm.push(THEPR)
|
448
496
|
asm.push(BPR)
|
449
497
|
asm.mov(BPR, SPR)
|
450
498
|
end
|
499
|
+
context.cpustack_push(BPR)
|
500
|
+
context.cpustack_push(TMPR)
|
501
|
+
context.cpustack_push(THEPR)
|
502
|
+
context.cpustack_push(SPR)
|
451
503
|
|
452
504
|
context
|
453
505
|
end
|
@@ -463,9 +515,11 @@ LO | | | |
|
|
463
515
|
asm.with_retry do
|
464
516
|
asm.mov(SPR, BPR)
|
465
517
|
asm.pop(BPR)
|
518
|
+
asm.pop(THEPR)
|
466
519
|
asm.mov(SPR, BPR)
|
467
520
|
asm.pop(BPR)
|
468
521
|
end
|
522
|
+
context.stack_content = []
|
469
523
|
|
470
524
|
context
|
471
525
|
end
|
@@ -500,9 +554,44 @@ LO | | | |
|
|
500
554
|
end
|
501
555
|
end
|
502
556
|
|
503
|
-
module
|
557
|
+
module CommonCodeGen
|
504
558
|
include AbsArch
|
505
559
|
|
560
|
+
def gen_alloca(context, siz)
|
561
|
+
asm = context.assembler
|
562
|
+
siz = siz * AsmType::MACHINE_WORD.size
|
563
|
+
asm.with_retry do
|
564
|
+
asm.sub(THEPR, siz)
|
565
|
+
end
|
566
|
+
context.ret_reg = THEPR
|
567
|
+
context
|
568
|
+
end
|
569
|
+
|
570
|
+
def gen_call(context, fnc, numarg, slf = nil)
|
571
|
+
casm = context.assembler
|
572
|
+
|
573
|
+
callpos = nil
|
574
|
+
casm.with_retry do
|
575
|
+
dmy, callpos = casm.call_with_arg(fnc, numarg)
|
576
|
+
end
|
577
|
+
context.end_using_reg(fnc)
|
578
|
+
vretadd = casm.output_stream.var_base_address(callpos)
|
579
|
+
cpuinfo = []
|
580
|
+
if slf then
|
581
|
+
cpuinfo.push slf
|
582
|
+
else
|
583
|
+
cpuinfo.push self
|
584
|
+
end
|
585
|
+
cpuinfo.push context.reg_content.dup
|
586
|
+
cpuinfo.push context.stack_content.dup
|
587
|
+
context.top_node.frame_struct_array.push [vretadd, cpuinfo]
|
588
|
+
|
589
|
+
if context.options[:dump_context] then
|
590
|
+
dump_context(context)
|
591
|
+
end
|
592
|
+
context
|
593
|
+
end
|
594
|
+
|
506
595
|
def dump_context(context)
|
507
596
|
print "---- Reg map ----\n"
|
508
597
|
context.reg_content.each do |key, value|
|
@@ -510,6 +599,7 @@ LO | | | |
|
|
510
599
|
end
|
511
600
|
|
512
601
|
print "---- Stack map ----\n"
|
602
|
+
=begin
|
513
603
|
@frame_info.frame_layout.each_with_index do |vinf, i|
|
514
604
|
ro = @frame_info.real_offset(i)
|
515
605
|
if mlv = @modified_local_var.last[0][ro] then
|
@@ -518,11 +608,17 @@ LO | | | |
|
|
518
608
|
print " #{vinf.class} \n"
|
519
609
|
end
|
520
610
|
end
|
611
|
+
=end
|
521
612
|
context.stack_content.each do |value|
|
522
613
|
print " #{value.class} \n"
|
523
614
|
end
|
524
615
|
end
|
525
|
-
|
616
|
+
end
|
617
|
+
|
618
|
+
module SendNodeCodeGen
|
619
|
+
include AbsArch
|
620
|
+
include CommonCodeGen
|
621
|
+
|
526
622
|
def gen_make_argv(context)
|
527
623
|
casm = context.assembler
|
528
624
|
rarg = @arguments[3..-1]
|
@@ -578,21 +674,6 @@ LO | | | |
|
|
578
674
|
|
579
675
|
context
|
580
676
|
end
|
581
|
-
|
582
|
-
def gen_call(context, fnc, numarg)
|
583
|
-
casm = context.assembler
|
584
|
-
|
585
|
-
callpos = nil
|
586
|
-
casm.with_retry do
|
587
|
-
dmy, callpos = casm.call_with_arg(fnc, numarg)
|
588
|
-
end
|
589
|
-
context.end_using_reg(fnc)
|
590
|
-
@var_return_address = casm.output_stream.var_base_address(callpos)
|
591
|
-
if context.options[:dump_context] then
|
592
|
-
dump_context(context)
|
593
|
-
end
|
594
|
-
context
|
595
|
-
end
|
596
677
|
end
|
597
678
|
end
|
598
679
|
end
|
data/lib/ytljit/vm_cruby_obj.rb
CHANGED
@@ -13,19 +13,21 @@ module YTLJit
|
|
13
13
|
slfoff = @current_frame_info.offset_arg(2, BPR)
|
14
14
|
ivid = ((@name.object_id << 1) / InternalRubyType::RObject.size)
|
15
15
|
ivarget = OpMemAddress.new(address_of("rb_ivar_get"))
|
16
|
-
context.
|
17
|
-
context.start_using_reg(FUNC_ARG[1])
|
16
|
+
context.start_arg_reg
|
18
17
|
asm = context.assembler
|
19
18
|
asm.with_retry do
|
20
19
|
asm.mov(FUNC_ARG[0], slfoff)
|
21
20
|
asm.mov(FUNC_ARG[1], ivid)
|
22
21
|
asm.call_with_arg(ivarget, 2)
|
23
22
|
end
|
24
|
-
context.
|
25
|
-
context.end_using_reg(FUNC_ARG[0])
|
23
|
+
context.end_arg_reg
|
26
24
|
|
27
25
|
context.ret_reg = RETR
|
28
26
|
context.ret_node = self
|
27
|
+
decide_type_once(context.to_signature)
|
28
|
+
if !@type.boxed then
|
29
|
+
context = @type.to_box.gen_unboxing(context)
|
30
|
+
end
|
29
31
|
context
|
30
32
|
end
|
31
33
|
end
|
@@ -46,9 +48,7 @@ module YTLJit
|
|
46
48
|
rtype = @val.decide_type_once(context.to_signature)
|
47
49
|
context = rtype.gen_boxing(context)
|
48
50
|
|
49
|
-
context.
|
50
|
-
context.start_using_reg(FUNC_ARG[1])
|
51
|
-
context.start_using_reg(FUNC_ARG[2])
|
51
|
+
context.start_arg_reg
|
52
52
|
asm = context.assembler
|
53
53
|
asm.with_retry do
|
54
54
|
asm.push(TMPR2)
|
@@ -59,9 +59,7 @@ module YTLJit
|
|
59
59
|
asm.call_with_arg(ivarset, 3)
|
60
60
|
asm.pop(TMPR2)
|
61
61
|
end
|
62
|
-
context.
|
63
|
-
context.end_using_reg(FUNC_ARG[1])
|
64
|
-
context.end_using_reg(FUNC_ARG[0])
|
62
|
+
context.end_arg_reg
|
65
63
|
|
66
64
|
context.ret_reg = RETR
|
67
65
|
context.ret_node = self
|
@@ -74,15 +72,19 @@ module YTLJit
|
|
74
72
|
include Node
|
75
73
|
|
76
74
|
def visit_getinstancevariable(code, ins, context)
|
75
|
+
context.macro_method = false
|
77
76
|
curnode = context.current_node
|
78
77
|
node = CRubyInstanceVarRefNode.new(curnode, ins[1])
|
78
|
+
node.debug_info = context.debug_info
|
79
79
|
context.expstack.push node
|
80
80
|
end
|
81
81
|
|
82
82
|
def visit_setinstancevariable(code, ins, context)
|
83
|
+
context.macro_method = false
|
83
84
|
val = context.expstack.pop
|
84
85
|
curnode = context.current_node
|
85
86
|
node = CRubyInstanceVarAssignNode.new(curnode, ins[1], val)
|
87
|
+
node.debug_info = context.debug_info
|
86
88
|
if context.expstack[-1] == val then
|
87
89
|
context.expstack[-1] = CRubyInstanceVarRefNode.new(curnode, ins[1])
|
88
90
|
end
|
@@ -2,6 +2,34 @@ module YTLJit
|
|
2
2
|
module VM
|
3
3
|
module ArithmeticOperationUtil
|
4
4
|
include AbsArch
|
5
|
+
def decide_type_core_local(tlist, sig, local_cache = {})
|
6
|
+
tlist = tlist.select {|e| e.class != RubyType::DefaultType0 }
|
7
|
+
if tlist.size < 2 then
|
8
|
+
return decide_type_core(tlist, local_cache)
|
9
|
+
end
|
10
|
+
aele = @arguments[3].decide_type_once(sig)
|
11
|
+
if tlist.include?(aele) then
|
12
|
+
aele
|
13
|
+
else
|
14
|
+
RubyType::DefaultType0.new
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def decide_type_once(sig, local_cache = {})
|
19
|
+
if local_cache[self] then
|
20
|
+
return local_cache[self]
|
21
|
+
end
|
22
|
+
|
23
|
+
if @type.equal?(nil) or @type.is_a?(RubyType::DefaultType0) then
|
24
|
+
tlist = type_list(sig).flatten.uniq
|
25
|
+
@type = decide_type_core_local(tlist, sig, local_cache)
|
26
|
+
else
|
27
|
+
@type
|
28
|
+
end
|
29
|
+
|
30
|
+
@type
|
31
|
+
end
|
32
|
+
|
5
33
|
def gen_arithmetic_operation(context, inst, tempreg, resreg)
|
6
34
|
context.start_using_reg(tempreg)
|
7
35
|
context = gen_eval_self(context)
|
@@ -58,9 +86,8 @@ module YTLJit
|
|
58
86
|
context.ret_reg = resreg
|
59
87
|
|
60
88
|
decide_type_once(context.to_signature)
|
61
|
-
|
62
89
|
if @type.boxed then
|
63
|
-
context = @type.
|
90
|
+
context = @type.gen_boxing(context)
|
64
91
|
end
|
65
92
|
|
66
93
|
context
|
@@ -76,6 +103,7 @@ module YTLJit
|
|
76
103
|
asm.mov(tempreg, context.ret_reg)
|
77
104
|
end
|
78
105
|
context.set_reg_content(tempreg, context.ret_node)
|
106
|
+
context.set_reg_content(tempreg, context.ret_node)
|
79
107
|
|
80
108
|
# @arguments[1] is block
|
81
109
|
# @arguments[2] is self
|
@@ -101,8 +129,8 @@ module YTLJit
|
|
101
129
|
context.ret_reg = resreg
|
102
130
|
|
103
131
|
decide_type_once(context.to_signature)
|
104
|
-
if type.boxed then
|
105
|
-
context = type.gen_boxing(context)
|
132
|
+
if @type.boxed then
|
133
|
+
context = @type.gen_boxing(context)
|
106
134
|
end
|
107
135
|
|
108
136
|
context
|