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