ytljit 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|