ytljit 0.0.3 → 0.0.4
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 +6 -0
- data/ext/memory.c +82 -0
- data/ext/ytljit.c +9 -0
- data/ext/ytljit.h +18 -0
- data/lib/runtime/gc.rb +41 -0
- data/lib/runtime/object.rb +18 -0
- data/lib/ytljit.rb +9 -0
- data/lib/ytljit/arena.rb +63 -0
- data/lib/ytljit/asm.rb +5 -1
- data/lib/ytljit/asmext.rb +42 -6
- data/lib/ytljit/asmutil.rb +26 -0
- data/lib/ytljit/instruction_ia.rb +28 -2
- data/lib/ytljit/type.rb +11 -5
- data/lib/ytljit/vm.rb +620 -173
- data/lib/ytljit/vm_codegen.rb +123 -26
- data/lib/ytljit/vm_cruby_obj.rb +91 -0
- data/lib/ytljit/vm_inline_method.rb +27 -19
- data/lib/ytljit/vm_sendnode.rb +416 -136
- data/lib/ytljit/vm_trans.rb +79 -19
- data/lib/ytljit/vm_type.rb +25 -19
- data/lib/ytljit/vm_type_gen.rb +55 -2
- data/test/test_arena.rb +60 -0
- data/test/test_assemble2.rb +25 -2
- metadata +10 -3
data/lib/ytljit/vm_trans.rb
CHANGED
@@ -43,6 +43,15 @@ module YTLJit
|
|
43
43
|
attr :local_label_tab
|
44
44
|
|
45
45
|
attr_accessor :not_reached_pos
|
46
|
+
|
47
|
+
def import_object(klass, name, value)
|
48
|
+
ctn = ClassTopNode.get_class_top_node(klass)
|
49
|
+
if ctn == nil then
|
50
|
+
ctn = ClassTopNode.new(@the_top, klass, klass.name)
|
51
|
+
end
|
52
|
+
valnode = LiteralNode.new(ctn, value)
|
53
|
+
ctn.get_constant_tab[name] = valnode
|
54
|
+
end
|
46
55
|
end
|
47
56
|
|
48
57
|
class YARVTranslatorBase
|
@@ -164,16 +173,30 @@ module YTLJit
|
|
164
173
|
|
165
174
|
def visit_getdynamic(code, ins, context)
|
166
175
|
# + 3 mean prtv_env/pointer to block function/self
|
167
|
-
|
168
|
-
|
176
|
+
dep = ins[2]
|
177
|
+
curcode = code
|
178
|
+
dep.times do
|
179
|
+
curcode = curcode.parent
|
180
|
+
end
|
181
|
+
offset = curcode.header['misc'][:local_size] + 3 - ins[1]
|
182
|
+
node = LocalVarRefNode.new(context.current_node, offset, dep)
|
169
183
|
context.expstack.push node
|
170
184
|
end
|
171
185
|
|
172
186
|
def visit_setdynamic(code, ins, context)
|
187
|
+
dep = ins[2]
|
188
|
+
curcode = code
|
189
|
+
dep.times do
|
190
|
+
curcode = curcode.parent
|
191
|
+
end
|
173
192
|
val = context.expstack.pop
|
174
193
|
curnode = context.current_node
|
175
|
-
offset =
|
176
|
-
node = LocalAssignNode.new(curnode, offset,
|
194
|
+
offset = curcode.header['misc'][:local_size] + 3 - ins[1]
|
195
|
+
node = LocalAssignNode.new(curnode, offset, dep, val)
|
196
|
+
if context.expstack[-1] == val then
|
197
|
+
varref = LocalVarRefNode.new(context.current_node, offset, dep)
|
198
|
+
context.expstack[-1] = varref
|
199
|
+
end
|
177
200
|
curnode.body = node
|
178
201
|
context.current_node = node
|
179
202
|
end
|
@@ -188,23 +211,35 @@ module YTLJit
|
|
188
211
|
|
189
212
|
# getclassvariable
|
190
213
|
# setclassvariable
|
191
|
-
|
192
|
-
def
|
214
|
+
|
215
|
+
def get_self_object(context)
|
193
216
|
klass = context.expstack.pop
|
194
217
|
case klass
|
195
218
|
when ConstantRefNode
|
196
219
|
klass = klass.value_node
|
197
220
|
|
198
|
-
|
199
221
|
when LiteralNode
|
200
222
|
klass = klass.value
|
201
223
|
if klass == nil then
|
202
224
|
klass = context.current_class_node
|
203
225
|
end
|
204
226
|
|
227
|
+
when SpecialObjectNode
|
228
|
+
if klass.kind == 3 then
|
229
|
+
klass = context.current_class_node
|
230
|
+
else
|
231
|
+
raise "Unkown special object kind = #{klass.kind}"
|
232
|
+
end
|
233
|
+
|
205
234
|
else
|
206
235
|
raise "Umkonwn node #{klass.class}"
|
207
236
|
end
|
237
|
+
|
238
|
+
klass
|
239
|
+
end
|
240
|
+
|
241
|
+
def visit_getconstant(code, ins, context)
|
242
|
+
klass = get_self_object(context)
|
208
243
|
name = ins[1]
|
209
244
|
curnode = context.current_node
|
210
245
|
node = ConstantRefNode.new(curnode, klass, name)
|
@@ -212,6 +247,13 @@ module YTLJit
|
|
212
247
|
end
|
213
248
|
|
214
249
|
def visit_setconstant(code, ins, context)
|
250
|
+
klass = get_self_object(context)
|
251
|
+
value = context.expstack.pop
|
252
|
+
name = ins[1]
|
253
|
+
curnode = context.current_node
|
254
|
+
node = ConstantAssignNode.new(curnode, klass, name, value)
|
255
|
+
curnode.body = node
|
256
|
+
context.current_node = node
|
215
257
|
end
|
216
258
|
|
217
259
|
# getglobal
|
@@ -246,9 +288,9 @@ module YTLJit
|
|
246
288
|
when :block
|
247
289
|
mtopnode = BlockTopNode.new(curnode)
|
248
290
|
when :method
|
249
|
-
mtopnode = MethodTopNode.new(curnode)
|
291
|
+
mtopnode = MethodTopNode.new(curnode, body.header['name'].to_sym)
|
250
292
|
when :class
|
251
|
-
mtopnode = ClassTopNode.new(curnode)
|
293
|
+
mtopnode = ClassTopNode.new(curnode, body.header['name'].to_sym)
|
252
294
|
when :top
|
253
295
|
raise "Maybe bug not appear top block."
|
254
296
|
end
|
@@ -289,10 +331,17 @@ module YTLJit
|
|
289
331
|
|
290
332
|
def visit_pop(code, ins, context)
|
291
333
|
node = context.expstack.pop
|
334
|
+
if node == nil then
|
335
|
+
# Maybe push instruction deleted by optimize
|
336
|
+
node = LiteralNode.new(nil, nil)
|
337
|
+
end
|
338
|
+
|
292
339
|
curnode = context.current_node
|
293
340
|
node.parent = curnode
|
294
341
|
curnode.body = node
|
295
|
-
|
342
|
+
if node.is_a?(HaveChildlenMixin) then
|
343
|
+
context.current_node = node
|
344
|
+
end
|
296
345
|
|
297
346
|
context
|
298
347
|
end
|
@@ -370,6 +419,7 @@ module YTLJit
|
|
370
419
|
end
|
371
420
|
RubyType::define_wraped_class(klassobj, RubyType::RubyTypeBoxed)
|
372
421
|
cnode = ClassTopNode.new(context.current_class_node, klassobj, name)
|
422
|
+
context.current_class_node.constant_tab[name] = cnode
|
373
423
|
|
374
424
|
body = VMLib::InstSeqTree.new(code, ins[2])
|
375
425
|
ncontext = YARVContext.new
|
@@ -381,7 +431,6 @@ module YTLJit
|
|
381
431
|
tr = self.class.new([body])
|
382
432
|
tr.translate(ncontext)
|
383
433
|
|
384
|
-
context.current_class_node.constant_tab[name] = cnode
|
385
434
|
curnode = context.current_node
|
386
435
|
cvnode = ClassValueNode.new(curnode, cnode)
|
387
436
|
context.expstack.push cvnode
|
@@ -393,6 +442,7 @@ module YTLJit
|
|
393
442
|
blk_iseq = ins[3]
|
394
443
|
curnode = context.current_node
|
395
444
|
numarg = ins[2]
|
445
|
+
seqno = ins[5]
|
396
446
|
|
397
447
|
# regular arguments
|
398
448
|
arg = []
|
@@ -409,7 +459,7 @@ module YTLJit
|
|
409
459
|
body = VMLib::InstSeqTree.new(code, blk_iseq)
|
410
460
|
ncontext = YARVContext.new
|
411
461
|
ncontext.current_file_name = context.current_file_name
|
412
|
-
ncontext.current_class_node =
|
462
|
+
ncontext.current_class_node = context.current_class_node
|
413
463
|
btn = ncontext.current_node = BlockTopNode.new(curnode)
|
414
464
|
ncontext.top_nodes.push btn
|
415
465
|
|
@@ -427,7 +477,7 @@ module YTLJit
|
|
427
477
|
|
428
478
|
func = MethodSelectNode.new(curnode, ins[1])
|
429
479
|
op_flag = ins[4]
|
430
|
-
sn = SendNode.make_send_node(curnode, func, arg, op_flag)
|
480
|
+
sn = SendNode.make_send_node(curnode, func, arg, op_flag, seqno)
|
431
481
|
func.set_reciever(sn)
|
432
482
|
context.expstack.push sn
|
433
483
|
|
@@ -442,6 +492,7 @@ module YTLJit
|
|
442
492
|
func = YieldNode.new(curnode)
|
443
493
|
numarg = ins[1]
|
444
494
|
op_flag = ins[2]
|
495
|
+
seqno = ins[3]
|
445
496
|
|
446
497
|
# regular arguments
|
447
498
|
args = []
|
@@ -455,17 +506,17 @@ module YTLJit
|
|
455
506
|
framelayout = frameinfo.frame_layout
|
456
507
|
|
457
508
|
# self
|
458
|
-
args.push
|
509
|
+
args.push LiteralNode.new(curnode, nil)
|
459
510
|
|
460
511
|
# block
|
461
|
-
args.push
|
512
|
+
args.push LiteralNode.new(curnode, nil)
|
462
513
|
|
463
514
|
# perv env
|
464
|
-
args.push
|
515
|
+
args.push LiteralNode.new(curnode, nil)
|
465
516
|
|
466
517
|
args = args.reverse
|
467
518
|
|
468
|
-
nnode = SendNode.new(curnode, func, args, op_flag)
|
519
|
+
nnode = SendNode.new(curnode, func, args, op_flag, seqno)
|
469
520
|
func.parent = nnode
|
470
521
|
context.expstack.push nnode
|
471
522
|
|
@@ -473,9 +524,17 @@ module YTLJit
|
|
473
524
|
end
|
474
525
|
|
475
526
|
def visit_leave(code, ins, context)
|
476
|
-
curnode =
|
527
|
+
curnode = nil
|
528
|
+
vnode = nil
|
529
|
+
if context.top_nodes.last.name == :initialize then
|
530
|
+
visit_pop(code, ins, context)
|
531
|
+
curnode = context.current_node
|
532
|
+
vnode = SelfRefNode.new(curnode)
|
533
|
+
else
|
534
|
+
curnode = context.current_node
|
535
|
+
vnode = context.expstack.pop
|
536
|
+
end
|
477
537
|
|
478
|
-
vnode = context.expstack.pop
|
479
538
|
srnode = SetResultNode.new(curnode, vnode)
|
480
539
|
curnode.body = srnode
|
481
540
|
|
@@ -504,6 +563,7 @@ module YTLJit
|
|
504
563
|
nllab = get_vmnode_from_label(context, ins[1])
|
505
564
|
|
506
565
|
jpnode = JumpNode.new(curnode, nllab)
|
566
|
+
jpnode.body = nllab
|
507
567
|
|
508
568
|
val = context.expstack.pop
|
509
569
|
nllab.come_from[jpnode] = val
|
data/lib/ytljit/vm_type.rb
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
module YTLJit
|
2
2
|
module TypeUtil
|
3
3
|
class KlassTree
|
4
|
-
def initialize(defkey = [], defval = [])
|
4
|
+
def initialize(defkey = [], defval = [[], []])
|
5
5
|
@node = KlassTreeNode.new(defkey, defval)
|
6
6
|
end
|
7
7
|
|
8
8
|
def add(key, value)
|
9
9
|
cnode = @node
|
10
|
-
snode = @node
|
11
10
|
ocnode = nil
|
12
11
|
while cnode
|
13
12
|
ocnode = cnode
|
@@ -15,13 +14,11 @@ module YTLJit
|
|
15
14
|
return cnode
|
16
15
|
end
|
17
16
|
|
18
|
-
if key.zip(cnode.key).all? {|k, n| k.is_a?(n.class)}
|
17
|
+
if key.zip(cnode.key).all? {|k, n| k.is_a?(n.class)} and false then
|
19
18
|
cnode = cnode.same_klass
|
20
19
|
if cnode == nil then
|
21
20
|
ocnode.same_klass = KlassTreeNode.new(key, value)
|
22
21
|
return ocnode.same_klass
|
23
|
-
else
|
24
|
-
snode = cnode
|
25
22
|
end
|
26
23
|
else
|
27
24
|
cnode = cnode.next_klass
|
@@ -35,13 +32,13 @@ module YTLJit
|
|
35
32
|
|
36
33
|
def search(key)
|
37
34
|
cnode = @node
|
38
|
-
|
35
|
+
|
39
36
|
while cnode
|
40
37
|
if key == cnode.key then
|
41
38
|
return cnode
|
42
39
|
end
|
43
40
|
|
44
|
-
if key.zip(cnode.key).all? {|a, b|
|
41
|
+
if key.zip(cnode.key).all? {|a, b|
|
45
42
|
if a then
|
46
43
|
atype = a.ruby_type
|
47
44
|
|
@@ -52,9 +49,10 @@ module YTLJit
|
|
52
49
|
nil
|
53
50
|
end
|
54
51
|
else
|
52
|
+
raise "foo"
|
55
53
|
return !b
|
56
54
|
end
|
57
|
-
} then
|
55
|
+
} and false then
|
58
56
|
cnode = cnode.same_klass
|
59
57
|
else
|
60
58
|
cnode = cnode.next_klass
|
@@ -77,7 +75,7 @@ module YTLJit
|
|
77
75
|
attr_accessor :same_klass
|
78
76
|
attr_accessor :next_klass
|
79
77
|
attr :key
|
80
|
-
|
78
|
+
attr :value
|
81
79
|
end
|
82
80
|
|
83
81
|
class TypeContainer
|
@@ -93,16 +91,16 @@ module YTLJit
|
|
93
91
|
@types_tree.search(key)
|
94
92
|
end
|
95
93
|
|
96
|
-
def add_type(key, type)
|
94
|
+
def add_type(key, type, pos)
|
97
95
|
tvs = @types_tree.search(key)
|
98
96
|
if tvs then
|
99
|
-
tvsv = tvs.value
|
97
|
+
tvsv = tvs.value[pos]
|
100
98
|
if !tvsv.include? type then
|
101
99
|
tvsv.push type
|
102
100
|
end
|
103
101
|
else
|
104
102
|
# inherit types of most similar signature
|
105
|
-
ival = []
|
103
|
+
ival = [[], []]
|
106
104
|
simnode = @types_tree.add(key, ival)
|
107
105
|
=begin
|
108
106
|
simnode.value.each do |ele|
|
@@ -111,14 +109,14 @@ module YTLJit
|
|
111
109
|
=end
|
112
110
|
|
113
111
|
if !ival.include? type then
|
114
|
-
ival.push type
|
112
|
+
ival[pos].push type
|
115
113
|
end
|
116
114
|
end
|
117
115
|
end
|
118
116
|
|
119
117
|
def add_node(key)
|
120
118
|
# inherit types of most similar signature
|
121
|
-
ival = []
|
119
|
+
ival = [[], []]
|
122
120
|
simnode = @types_tree.add(key, ival)
|
123
121
|
=begin
|
124
122
|
simnode.value.each do |ele|
|
@@ -134,7 +132,7 @@ module YTLJit
|
|
134
132
|
if res == nil then
|
135
133
|
res = add_node(key)
|
136
134
|
end
|
137
|
-
|
135
|
+
|
138
136
|
res
|
139
137
|
end
|
140
138
|
end
|
@@ -173,6 +171,11 @@ module YTLJit
|
|
173
171
|
end
|
174
172
|
|
175
173
|
def self.related_ruby_class(klass, base)
|
174
|
+
if @@base_type_tab[klass] then
|
175
|
+
return [@@base_type_tab[klass],
|
176
|
+
@@boxed_type_tab[klass],
|
177
|
+
@@unboxed_type_tab[klass]]
|
178
|
+
end
|
176
179
|
baseslf = base.new(klass)
|
177
180
|
boxslf = RubyTypeBoxed.new(klass)
|
178
181
|
unboxslf = RubyTypeUnboxed.new(klass)
|
@@ -205,7 +208,7 @@ module YTLJit
|
|
205
208
|
@@boxed_type_tab[klass] = boxslf
|
206
209
|
@@unboxed_type_tab[klass] = unboxslf
|
207
210
|
|
208
|
-
[boxslf, unboxslf]
|
211
|
+
[baseslf, boxslf, unboxslf]
|
209
212
|
end
|
210
213
|
|
211
214
|
def self.from_object(obj)
|
@@ -215,7 +218,9 @@ module YTLJit
|
|
215
218
|
def self.from_ruby_class(rcls)
|
216
219
|
tobj = @@base_type_tab[rcls]
|
217
220
|
if tobj == nil then
|
218
|
-
|
221
|
+
RubyType::define_wraped_class(rcls, RubyTypeBoxed)
|
222
|
+
tobj = @@base_type_tab[rcls]
|
223
|
+
tobj.instance
|
219
224
|
else
|
220
225
|
tobj.instance
|
221
226
|
end
|
@@ -242,11 +247,11 @@ module YTLJit
|
|
242
247
|
end
|
243
248
|
|
244
249
|
def to_unbox
|
245
|
-
|
250
|
+
@@unboxed_type_tab[@ruby_type].instance
|
246
251
|
end
|
247
252
|
|
248
253
|
def to_box
|
249
|
-
|
254
|
+
@@boxed_type_tab[@ruby_type].instance
|
250
255
|
end
|
251
256
|
|
252
257
|
def ==(other)
|
@@ -304,5 +309,6 @@ module YTLJit
|
|
304
309
|
define_wraped_class(Hash, RubyTypeBoxed)
|
305
310
|
define_wraped_class(Module, RubyTypeBoxed)
|
306
311
|
define_wraped_class(Class, RubyTypeBoxed)
|
312
|
+
define_wraped_class(Object, RubyTypeBoxed)
|
307
313
|
end
|
308
314
|
end
|
data/lib/ytljit/vm_type_gen.rb
CHANGED
@@ -86,7 +86,13 @@ module YTLJit
|
|
86
86
|
end
|
87
87
|
|
88
88
|
def gen_unboxing(context)
|
89
|
-
|
89
|
+
asm = context.assembler
|
90
|
+
fobj = TypedData.new(InternalRubyType::RFloat, context.ret_reg)
|
91
|
+
asm.with_retry do
|
92
|
+
asm.movsd(XMM0, fobj[:float_value])
|
93
|
+
end
|
94
|
+
|
95
|
+
context.ret_reg = XMM0
|
90
96
|
context
|
91
97
|
end
|
92
98
|
end
|
@@ -98,6 +104,8 @@ module YTLJit
|
|
98
104
|
asm = context.assembler
|
99
105
|
val = context.ret_reg
|
100
106
|
vnode = context.ret_node
|
107
|
+
context.start_using_reg(TMPR2)
|
108
|
+
context.start_using_reg(TMPR3)
|
101
109
|
context.start_using_reg(FUNC_FLOAT_ARG[0])
|
102
110
|
rbfloatnew = OpMemAddress.new(address_of("rb_float_new"))
|
103
111
|
asm.with_retry do
|
@@ -105,6 +113,8 @@ module YTLJit
|
|
105
113
|
asm.call_with_arg(rbfloatnew, 1)
|
106
114
|
end
|
107
115
|
context.end_using_reg(FUNC_FLOAT_ARG[0])
|
116
|
+
context.end_using_reg(TMPR3)
|
117
|
+
context.end_using_reg(TMPR2)
|
108
118
|
context.ret_reg = RETR
|
109
119
|
context
|
110
120
|
end
|
@@ -135,7 +145,21 @@ module YTLJit
|
|
135
145
|
end
|
136
146
|
|
137
147
|
def gen_copy(context)
|
138
|
-
|
148
|
+
asm = context.assembler
|
149
|
+
val = context.ret_reg
|
150
|
+
context.start_using_reg(TMPR2)
|
151
|
+
context.start_using_reg(TMPR3)
|
152
|
+
context.start_using_reg(FUNC_ARG[0])
|
153
|
+
rbarydup = OpMemAddress.new(address_of("rb_ary_dup"))
|
154
|
+
asm.with_retry do
|
155
|
+
asm.mov(FUNC_ARG[0], val)
|
156
|
+
asm.call_with_arg(rbarydup, 1)
|
157
|
+
end
|
158
|
+
context.end_using_reg(FUNC_ARG[0])
|
159
|
+
context.end_using_reg(TMPR3)
|
160
|
+
context.end_using_reg(TMPR2)
|
161
|
+
context.ret_reg = RETR
|
162
|
+
|
139
163
|
context
|
140
164
|
end
|
141
165
|
|
@@ -144,6 +168,35 @@ module YTLJit
|
|
144
168
|
self.class == other.class and
|
145
169
|
@element_type == other.element_type
|
146
170
|
end
|
171
|
+
|
172
|
+
def eql?(other)
|
173
|
+
other.is_a?(self.class) and
|
174
|
+
self.class == other.class and
|
175
|
+
@element_type == other.element_type
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
module StringTypeBoxedCodeGen
|
180
|
+
include AbsArch
|
181
|
+
|
182
|
+
def gen_copy(context)
|
183
|
+
asm = context.assembler
|
184
|
+
val = context.ret_reg
|
185
|
+
context.start_using_reg(TMPR2)
|
186
|
+
context.start_using_reg(TMPR3)
|
187
|
+
context.start_using_reg(FUNC_ARG[0])
|
188
|
+
rbstrresurrect = OpMemAddress.new(address_of("rb_str_resurrect"))
|
189
|
+
asm.with_retry do
|
190
|
+
asm.mov(FUNC_ARG[0], val)
|
191
|
+
asm.call_with_arg(rbstrresurrect, 1)
|
192
|
+
end
|
193
|
+
context.end_using_reg(FUNC_ARG[0])
|
194
|
+
context.end_using_reg(TMPR3)
|
195
|
+
context.end_using_reg(TMPR2)
|
196
|
+
context.ret_reg = RETR
|
197
|
+
|
198
|
+
context
|
199
|
+
end
|
147
200
|
end
|
148
201
|
|
149
202
|
module ArrayTypeUnboxedCodeGen
|