ytljit 0.0.8 → 0.0.9
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/code_alloc.c +2 -2
- data/ext/memory.c +2 -5
- data/ext/thread.c +144 -0
- data/ext/thread.h +24 -0
- data/ext/ytljit.c +33 -6
- data/ext/ytljit.h +33 -0
- data/lib/ytljit.rb +1 -1
- data/lib/ytljit/asm.rb +11 -4
- data/lib/ytljit/asmext_x64.rb +1 -1
- data/lib/ytljit/asmext_x86.rb +1 -1
- data/lib/ytljit/dyna_method.rb +136 -0
- data/lib/ytljit/marshal.rb +11 -0
- data/lib/ytljit/type.rb +2 -2
- data/lib/ytljit/vm.rb +781 -211
- data/lib/ytljit/vm_codegen.rb +73 -24
- data/lib/ytljit/vm_cruby_obj.rb +42 -30
- data/lib/ytljit/vm_inline_method.rb +40 -14
- data/lib/ytljit/vm_sendnode.rb +609 -190
- data/lib/ytljit/vm_trans.rb +60 -16
- data/lib/ytljit/vm_type.rb +29 -9
- data/lib/ytljit/vm_type_gen.rb +131 -56
- data/test/foo.rb +12 -0
- metadata +9 -16
data/lib/ytljit/vm_codegen.rb
CHANGED
@@ -131,7 +131,7 @@ LO | | | |
|
|
131
131
|
if @current_method[i] == offset then
|
132
132
|
offset = i
|
133
133
|
else
|
134
|
-
# This is legal this TopNode has only one signature
|
134
|
+
# This is legal if this TopNode has only one signature
|
135
135
|
sigc = offset.signature_cache
|
136
136
|
if sigc.size == 1 then
|
137
137
|
return sigc[0]
|
@@ -148,6 +148,14 @@ LO | | | |
|
|
148
148
|
|
149
149
|
cursignode = @current_method_signature_node[offset]
|
150
150
|
curmethod = @current_method[offset]
|
151
|
+
if curmethod == nil then
|
152
|
+
return nil
|
153
|
+
end
|
154
|
+
|
155
|
+
cursig = curmethod.current_signature
|
156
|
+
if cursig then
|
157
|
+
return cursig
|
158
|
+
end
|
151
159
|
|
152
160
|
sigc = curmethod.signature_cache
|
153
161
|
if sigc.size == 1 then
|
@@ -188,8 +196,9 @@ LO | | | |
|
|
188
196
|
end
|
189
197
|
|
190
198
|
def to_signature_aux(cursignode, offset, cache)
|
199
|
+
sig = to_signature(offset - 1, cache)
|
191
200
|
res = cursignode.map { |enode|
|
192
|
-
enode.decide_type_once(
|
201
|
+
enode.decide_type_once(sig)
|
193
202
|
}
|
194
203
|
|
195
204
|
res
|
@@ -198,20 +207,33 @@ LO | | | |
|
|
198
207
|
def to_signature_aux2(mt, args, cursig, offset, cache)
|
199
208
|
res = []
|
200
209
|
args.each do |ele|
|
201
|
-
ele.decide_type_once(cursig)
|
202
|
-
|
210
|
+
res.push ele.decide_type_once(cursig)
|
211
|
+
end
|
212
|
+
|
213
|
+
if !args[1].is_a?(Node::BlockTopNode) then
|
214
|
+
return res
|
203
215
|
end
|
204
216
|
|
205
217
|
ynode = mt.yield_node[0]
|
206
|
-
if ynode then
|
218
|
+
if ynode and false then
|
207
219
|
yargs = ynode.arguments
|
208
|
-
push_signature(yargs,
|
220
|
+
push_signature(yargs, mt)
|
209
221
|
ysig = to_signature_aux3(yargs, -1, cache)
|
222
|
+
# inherit self and block from caller node
|
223
|
+
ysig[1] = cursig[1]
|
224
|
+
ysig[2] = cursig[2]
|
225
|
+
|
210
226
|
args[1].type = nil
|
211
227
|
res[1] = args[1].decide_type_once(ysig)
|
212
|
-
#
|
213
|
-
#
|
228
|
+
#p res
|
229
|
+
#p res[1]
|
214
230
|
pop_signature
|
231
|
+
else
|
232
|
+
sig = args[1].search_valid_signature
|
233
|
+
if sig then
|
234
|
+
args[1].type = nil
|
235
|
+
res[1] = args[1].decide_type_once(sig)
|
236
|
+
end
|
215
237
|
end
|
216
238
|
|
217
239
|
res
|
@@ -231,6 +253,7 @@ LO | | | |
|
|
231
253
|
res = cursignode.map { |enode|
|
232
254
|
enode.decide_type_once(sig)
|
233
255
|
}
|
256
|
+
|
234
257
|
cache[cursignode] = res
|
235
258
|
res
|
236
259
|
end
|
@@ -248,6 +271,7 @@ LO | | | |
|
|
248
271
|
|
249
272
|
attr :top_node
|
250
273
|
attr :current_method_signature_node
|
274
|
+
attr :current_method
|
251
275
|
attr_accessor :convergent
|
252
276
|
attr_accessor :visited_top_node
|
253
277
|
attr_accessor :options
|
@@ -272,13 +296,16 @@ LO | | | |
|
|
272
296
|
@depth_reg = Hash.new(0)
|
273
297
|
@stack_content = []
|
274
298
|
@reg_content = Hash.new(true)
|
275
|
-
@reg_history = Hash.new
|
299
|
+
@reg_history = Hash.new
|
276
300
|
|
277
301
|
# Use only type inference compile mode
|
278
302
|
@slf = nil
|
279
303
|
|
280
304
|
# Options from user
|
281
305
|
@options = {}
|
306
|
+
|
307
|
+
# Comment of type inference
|
308
|
+
@comment = {}
|
282
309
|
end
|
283
310
|
|
284
311
|
attr :top_node
|
@@ -298,6 +325,7 @@ LO | | | |
|
|
298
325
|
attr_accessor :slf
|
299
326
|
|
300
327
|
attr_accessor :options
|
328
|
+
attr_accessor :comment
|
301
329
|
|
302
330
|
def set_reg_content(dst, val)
|
303
331
|
if dst.is_a?(FunctionArgument) then
|
@@ -313,13 +341,14 @@ LO | | | |
|
|
313
341
|
wsiz = AsmType::MACHINE_WORD.size
|
314
342
|
if dst.reg == SPR then
|
315
343
|
if val.is_a?(OpRegistor) and @reg_content[val] then
|
316
|
-
cpustack_setn(dst.disp.value / wsiz, @reg_content[val])
|
344
|
+
cpustack_setn(-dst.disp.value / wsiz - 1, @reg_content[val])
|
317
345
|
else
|
318
|
-
cpustack_setn(dst.disp.value / wsiz, val)
|
346
|
+
cpustack_setn(-dst.disp.value / wsiz - 1, val)
|
319
347
|
end
|
320
|
-
|
321
|
-
if dst.reg == BPR then
|
348
|
+
elsif dst.reg == BPR then
|
322
349
|
if val.is_a?(OpRegistor) and @reg_content[val] then
|
350
|
+
# 3 means difference of SP(constructed frame) and BP
|
351
|
+
# ref. gen_method_prologue
|
323
352
|
cpustack_setn(-dst.disp.value / wsiz + 3, @reg_content[val])
|
324
353
|
else
|
325
354
|
cpustack_setn(-dst.disp.value / wsiz + 3, val)
|
@@ -346,6 +375,8 @@ LO | | | |
|
|
346
375
|
cont = @stack_content.pop
|
347
376
|
if !cont.is_a?(OpRegistor) then
|
348
377
|
@reg_content[reg] = cont
|
378
|
+
else
|
379
|
+
@reg_content[reg] = @reg_content[cont]
|
349
380
|
end
|
350
381
|
end
|
351
382
|
|
@@ -403,6 +434,7 @@ LO | | | |
|
|
403
434
|
else
|
404
435
|
@depth_reg[reg] = 0
|
405
436
|
end
|
437
|
+
@reg_history[reg] ||= []
|
406
438
|
@reg_history[reg].push @reg_content[reg]
|
407
439
|
@reg_content[reg] = nil
|
408
440
|
@depth_reg[reg] += 1
|
@@ -529,10 +561,14 @@ LO | | | |
|
|
529
561
|
asm.push(BPR)
|
530
562
|
asm.mov(BPR, SPR)
|
531
563
|
end
|
564
|
+
context.set_reg_content(BPR, :old_ptr)
|
532
565
|
context.cpustack_push(BPR)
|
566
|
+
context.set_reg_content(TMPR, :num_of_args)
|
533
567
|
context.cpustack_push(TMPR)
|
568
|
+
context.set_reg_content(THEPR, :local_heap)
|
534
569
|
context.cpustack_push(THEPR)
|
535
|
-
context.
|
570
|
+
context.set_reg_content(BPR, :frame_ptr)
|
571
|
+
context.cpustack_push(BPR)
|
536
572
|
|
537
573
|
context
|
538
574
|
end
|
@@ -608,6 +644,7 @@ LO | | | |
|
|
608
644
|
asm.mov(TMPR, siz)
|
609
645
|
asm.mov(FUNC_ARG[1], TMPR)
|
610
646
|
end
|
647
|
+
context = gen_save_thepr(context)
|
611
648
|
context = gen_call(context, alloca, 2)
|
612
649
|
asm.with_retry do
|
613
650
|
asm.mov(THEPR, RETR)
|
@@ -646,6 +683,7 @@ LO | | | |
|
|
646
683
|
end
|
647
684
|
cpuinfo.push context.reg_content.dup
|
648
685
|
cpuinfo.push context.stack_content.dup
|
686
|
+
cpuinfo.push context.to_signature
|
649
687
|
context.top_node.frame_struct_array.push [vretadd, cpuinfo]
|
650
688
|
|
651
689
|
if context.options[:dump_context] then
|
@@ -661,18 +699,30 @@ LO | | | |
|
|
661
699
|
end
|
662
700
|
|
663
701
|
print "---- Stack map ----\n"
|
702
|
+
#=begin
|
703
|
+
if @frame_info then
|
704
|
+
start = @frame_info.argument_num + 1
|
705
|
+
ll = @frame_info.frame_layout.reverse[start..-1]
|
706
|
+
ll.each_with_index do |vinf, i|
|
707
|
+
ro = @frame_info.real_offset(i)
|
708
|
+
print " #{vinf.name}:#{vinf.size}\n"
|
664
709
|
=begin
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
710
|
+
if mlv = @modified_local_var.last[0][ro] then
|
711
|
+
print " #{mlv.class} \n"
|
712
|
+
else
|
713
|
+
print " #{vinf.class} \n"
|
714
|
+
end
|
715
|
+
=end
|
671
716
|
end
|
672
717
|
end
|
673
|
-
|
718
|
+
#=end
|
719
|
+
p "---"
|
674
720
|
context.stack_content.each do |value|
|
675
|
-
|
721
|
+
if value.is_a?(Symbol) then
|
722
|
+
print " #{value} \n"
|
723
|
+
else
|
724
|
+
print " #{value.class} \n"
|
725
|
+
end
|
676
726
|
end
|
677
727
|
end
|
678
728
|
end
|
@@ -701,8 +751,7 @@ LO | | | |
|
|
701
751
|
rtype = argcomphook.call(context, arg, i)
|
702
752
|
else
|
703
753
|
context = arg.compile(context)
|
704
|
-
context.ret_node.decide_type_once(cursig)
|
705
|
-
rtype = context.ret_node.type
|
754
|
+
rtype = context.ret_node.decide_type_once(cursig)
|
706
755
|
end
|
707
756
|
context = rtype.gen_boxing(context)
|
708
757
|
dst = OpIndirect.new(SPR, i * AsmType::MACHINE_WORD.size)
|
data/lib/ytljit/vm_cruby_obj.rb
CHANGED
@@ -12,16 +12,21 @@ module YTLJit
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def compile_main(context)
|
15
|
+
slfoff = @current_frame_info.offset_arg(2, BPR)
|
15
16
|
cursig = context.to_signature
|
16
|
-
|
17
|
+
compile_main_aux(context, slfoff, cursig[2])
|
18
|
+
end
|
19
|
+
|
20
|
+
def compile_main_aux(context, slfcont, slftype)
|
17
21
|
mivl = @class_top.end_nodes[0].modified_instance_var.keys
|
18
22
|
off = mivl.index(@name)
|
19
|
-
|
23
|
+
cursig = context.to_signature
|
24
|
+
asm = context.assembler
|
20
25
|
|
21
|
-
if !
|
26
|
+
if !slftype.boxed then
|
22
27
|
context.start_using_reg(TMPR2)
|
23
28
|
asm.with_retry do
|
24
|
-
asm.mov(TMPR2,
|
29
|
+
asm.mov(TMPR2, slfcont)
|
25
30
|
end
|
26
31
|
context = gen_ref_element(context, nil, off)
|
27
32
|
context.end_using_reg(TMPR2)
|
@@ -48,13 +53,11 @@ module YTLJit
|
|
48
53
|
ivarget = OpVarMemAddress.new(addr)
|
49
54
|
context.start_arg_reg
|
50
55
|
asm.with_retry do
|
51
|
-
asm.mov(FUNC_ARG[0],
|
56
|
+
asm.mov(FUNC_ARG[0], slfcont)
|
52
57
|
asm.mov(FUNC_ARG[1], off)
|
53
58
|
end
|
54
59
|
context = gen_save_thepr(context)
|
55
|
-
|
56
|
-
asm.call_with_arg(ivarget, 2)
|
57
|
-
end
|
60
|
+
context = gen_call(context, ivarget, 2)
|
58
61
|
|
59
62
|
context.end_arg_reg
|
60
63
|
context.ret_reg = RETR
|
@@ -78,19 +81,28 @@ module YTLJit
|
|
78
81
|
end
|
79
82
|
|
80
83
|
def compile_main(context)
|
81
|
-
cursig = context.to_signature
|
82
84
|
slfoff = @current_frame_info.offset_arg(2, BPR)
|
85
|
+
cursig = context.to_signature
|
86
|
+
compile_main_aux(context, slfoff, cursig[2], @val, @body)
|
87
|
+
end
|
88
|
+
|
89
|
+
def compile_main_aux(context, slfcont, slftype, val, body)
|
90
|
+
cursig = context.to_signature
|
83
91
|
mivl = @class_top.end_nodes[0].modified_instance_var.keys
|
84
92
|
off = mivl.index(@name)
|
85
|
-
rtype =
|
93
|
+
rtype = val.decide_type_once(cursig)
|
86
94
|
|
87
|
-
if !
|
95
|
+
if !slftype.boxed then
|
88
96
|
asm = context.assembler
|
89
97
|
asm.with_retry do
|
90
|
-
asm.mov(TMPR2,
|
98
|
+
asm.mov(TMPR2, slfcont)
|
99
|
+
end
|
100
|
+
context = gen_set_element(context, nil, off, val)
|
101
|
+
if body then
|
102
|
+
return body.compile(context)
|
103
|
+
else
|
104
|
+
return context
|
91
105
|
end
|
92
|
-
context = gen_set_element(context, nil, off, @val)
|
93
|
-
return @body.compile(context)
|
94
106
|
end
|
95
107
|
|
96
108
|
addr = lambda {
|
@@ -100,30 +112,34 @@ module YTLJit
|
|
100
112
|
}
|
101
113
|
ivarset = OpVarMemAddress.new(addr)
|
102
114
|
|
103
|
-
context
|
104
|
-
if @val.is_escape != :global_export then
|
105
|
-
context = rtype.gen_boxing(context)
|
106
|
-
end
|
107
|
-
|
115
|
+
context.start_using_reg(TMPR2)
|
108
116
|
context.start_arg_reg
|
109
117
|
asm = context.assembler
|
110
118
|
asm.with_retry do
|
111
|
-
asm.
|
119
|
+
asm.mov(FUNC_ARG[0], slfcont)
|
120
|
+
end
|
121
|
+
|
122
|
+
context = val.compile(context)
|
123
|
+
context = rtype.gen_boxing(context)
|
124
|
+
|
125
|
+
asm.with_retry do
|
112
126
|
asm.mov(TMPR2, context.ret_reg)
|
113
|
-
asm.mov(FUNC_ARG[0], slfoff)
|
114
127
|
asm.mov(FUNC_ARG[1], off)
|
115
128
|
asm.mov(FUNC_ARG[2], TMPR2)
|
116
129
|
end
|
117
130
|
context = gen_save_thepr(context)
|
118
|
-
|
119
|
-
|
120
|
-
asm.pop(TMPR2)
|
121
|
-
end
|
131
|
+
context = gen_call(context, ivarset, 3)
|
132
|
+
|
122
133
|
context.end_arg_reg
|
134
|
+
context.end_using_reg(TMPR2)
|
123
135
|
|
124
136
|
context.ret_reg = RETR
|
125
137
|
context.ret_node = self
|
126
|
-
|
138
|
+
if body then
|
139
|
+
body.compile(context)
|
140
|
+
else
|
141
|
+
context
|
142
|
+
end
|
127
143
|
end
|
128
144
|
end
|
129
145
|
end
|
@@ -147,10 +163,6 @@ module YTLJit
|
|
147
163
|
mnode = context.current_method_node
|
148
164
|
node = CRubyInstanceVarAssignNode.new(curnode, ins[1], mnode, val)
|
149
165
|
node.debug_info = context.debug_info
|
150
|
-
if context.expstack[-1] == val then
|
151
|
-
ivr = CRubyInstanceVarRefNode.new(curnode, ins[1], mnode)
|
152
|
-
context.expstack[-1] = ivr
|
153
|
-
end
|
154
166
|
curnode.body = node
|
155
167
|
context.current_node = node
|
156
168
|
end
|
@@ -153,11 +153,25 @@ module YTLJit
|
|
153
153
|
end
|
154
154
|
|
155
155
|
asm = context.assembler
|
156
|
-
|
157
|
-
if
|
158
|
-
|
156
|
+
if context.ret_reg != tempreg2 then
|
157
|
+
if tempreg2.is_a?(OpRegXMM) and
|
158
|
+
!context.ret_reg.is_a?(OpRegXMM) then
|
159
|
+
asm.with_retry do
|
160
|
+
asm.cvtsi2sd(tempreg2, context.ret_reg)
|
161
|
+
end
|
162
|
+
elsif !tempreg2.is_a?(OpRegXMM) and
|
163
|
+
context.ret_reg.is_a?(OpRegXMM) then
|
164
|
+
asm.with_retry do
|
165
|
+
asm.cvtsd2si(tempreg2, context.ret_reg)
|
166
|
+
end
|
167
|
+
else
|
168
|
+
asm.with_retry do
|
169
|
+
asm.mov(tempreg2, context.ret_reg)
|
170
|
+
end
|
159
171
|
end
|
160
|
-
|
172
|
+
end
|
173
|
+
context.set_reg_content(tempreg2, context.ret_node)
|
174
|
+
asm.with_retry do
|
161
175
|
asm.send(cinst, tempreg2, tempreg)
|
162
176
|
asm.send(sinst, resreg)
|
163
177
|
asm.add(resreg, resreg)
|
@@ -196,24 +210,30 @@ module YTLJit
|
|
196
210
|
include UnboxedObjectUtil
|
197
211
|
|
198
212
|
def compile_array_unboxed(context)
|
199
|
-
|
213
|
+
sizent = @element_node_list[1..-1].max_by {|a| a[3] ? a[3][0] : -1}
|
214
|
+
siz = sizent[3][0] + 1
|
200
215
|
compile_object_unboxed(context, siz)
|
201
216
|
end
|
202
217
|
|
203
218
|
def gen_ref_element(context, slf, idx)
|
219
|
+
context.start_using_reg(TMPR2)
|
204
220
|
asm = context.assembler
|
205
221
|
if slf then
|
206
|
-
context.start_using_reg(TMPR2)
|
207
222
|
context = slf.compile(context)
|
208
223
|
asm.with_retry do
|
209
224
|
asm.mov(TMPR2, context.ret_reg)
|
210
225
|
end
|
211
226
|
end
|
227
|
+
context.set_reg_content(TMPR2, context.ret_node)
|
212
228
|
|
213
229
|
if idx.is_a?(Fixnum) then
|
214
230
|
idxval = idx
|
215
231
|
else
|
216
232
|
context = idx.compile(context)
|
233
|
+
itype = idx.decide_type_once(context.to_signature)
|
234
|
+
if itype.boxed then
|
235
|
+
context = itype.gen_unboxing(context)
|
236
|
+
end
|
217
237
|
idxval = context.ret_reg
|
218
238
|
end
|
219
239
|
asm.with_retry do
|
@@ -232,9 +252,7 @@ module YTLJit
|
|
232
252
|
asm.add(TMPR, TMPR2)
|
233
253
|
end
|
234
254
|
|
235
|
-
|
236
|
-
context.end_using_reg(TMPR2)
|
237
|
-
end
|
255
|
+
context.end_using_reg(TMPR2)
|
238
256
|
context.ret_reg = INDIRECT_TMPR
|
239
257
|
context.ret_node = self
|
240
258
|
|
@@ -242,18 +260,23 @@ module YTLJit
|
|
242
260
|
end
|
243
261
|
|
244
262
|
def gen_set_element(context, slf, idx, val)
|
263
|
+
context.start_using_reg(TMPR2)
|
245
264
|
asm = context.assembler
|
246
265
|
if slf then
|
247
|
-
context.start_using_reg(TMPR2)
|
248
266
|
context = slf.compile(context)
|
249
267
|
asm.with_retry do
|
250
268
|
asm.mov(TMPR2, context.ret_reg)
|
251
269
|
end
|
252
270
|
end
|
271
|
+
idxval = nil
|
253
272
|
if idx.is_a?(Fixnum) then
|
254
273
|
idxval = idx
|
255
274
|
else
|
256
275
|
context = idx.compile(context)
|
276
|
+
itype = idx.decide_type_once(context.to_signature)
|
277
|
+
if itype.boxed then
|
278
|
+
context = itype.gen_unboxing(context)
|
279
|
+
end
|
257
280
|
idxval = context.ret_reg
|
258
281
|
end
|
259
282
|
|
@@ -263,17 +286,22 @@ module YTLJit
|
|
263
286
|
elsif idxval.is_a?(OpImmidiate)
|
264
287
|
asm.mov(TMPR, idxval.value * 8)
|
265
288
|
else
|
266
|
-
|
289
|
+
if idxval != TMPR then
|
290
|
+
asm.mov(TMPR, idxval)
|
291
|
+
end
|
267
292
|
asm.add(TMPR, TMPR) # * 2
|
268
293
|
asm.add(TMPR, TMPR) # * 4
|
269
294
|
asm.add(TMPR, TMPR) # * 8
|
270
295
|
end
|
271
296
|
asm.add(TMPR2, TMPR)
|
297
|
+
asm.push(TMPR2)
|
272
298
|
end
|
299
|
+
context.set_reg_content(TMPR2, :refer_of_static_heap)
|
273
300
|
context = val.compile(context)
|
274
301
|
|
275
302
|
valreg = context.ret_reg
|
276
303
|
asm.with_retry do
|
304
|
+
asm.pop(TMPR2)
|
277
305
|
if !valreg.is_a?(OpRegistor) then
|
278
306
|
asm.mov(RETR, valreg)
|
279
307
|
valreg = RETR
|
@@ -282,9 +310,7 @@ module YTLJit
|
|
282
310
|
asm.mov(INDIRECT_TMPR2, valreg)
|
283
311
|
end
|
284
312
|
|
285
|
-
|
286
|
-
context.end_using_reg(TMPR2)
|
287
|
-
end
|
313
|
+
context.end_using_reg(TMPR2)
|
288
314
|
context.ret_reg = valreg
|
289
315
|
context.ret_node = self
|
290
316
|
context
|