ytljit 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/ext/ytljit.c CHANGED
@@ -3,6 +3,7 @@
3
3
  #include <unistd.h>
4
4
  #include <stdlib.h>
5
5
  #include "ruby.h"
6
+ #include "ruby/st.h"
6
7
 
7
8
  #include "ytljit.h"
8
9
 
@@ -33,16 +34,34 @@ ytl_address_of(VALUE self, VALUE symstr)
33
34
  return Qnil;
34
35
  }
35
36
 
37
+ static rb_method_entry_t*
38
+ search_method(VALUE klass, ID id)
39
+ {
40
+ st_data_t body;
41
+ if (!klass) {
42
+ return 0;
43
+ }
44
+
45
+ while (!st_lookup(RCLASS_M_TBL(klass), id, &body)) {
46
+ klass = RCLASS_SUPER(klass);
47
+ if (!klass) {
48
+ return 0;
49
+ }
50
+ }
51
+
52
+ return (rb_method_entry_t *)body;
53
+ }
54
+
36
55
  VALUE
37
56
  ytl_method_address_of(VALUE klass, VALUE mname)
38
57
  {
39
58
  rb_method_entry_t *me;
40
59
  ID mid = SYM2ID(mname);
41
60
 
42
- me = rb_method_entry(klass, mid);
61
+ me = search_method(klass, mid);
43
62
 
44
63
  if (me && me->def && me->def->type == VM_METHOD_TYPE_CFUNC) {
45
- return ULONG2NUM((uintptr_t)me->def->body.cfunc.func);
64
+ return ULONG2NUM((uintptr_t)me->def->body.cfunc.func);
46
65
  }
47
66
  else {
48
67
  return Qnil;
@@ -74,7 +93,7 @@ ytl_method_address_of_raw(VALUE klass, VALUE mname)
74
93
  rb_method_entry_t *me;
75
94
  ID mid = SYM2ID(mname);
76
95
 
77
- me = rb_method_entry(klass, mid);
96
+ me = search_method(klass, mid);
78
97
 
79
98
  if (me && me->def && me->def->type == VM_METHOD_TYPE_CFUNC) {
80
99
  return (void *)me->def->body.cfunc.func;
@@ -130,6 +130,10 @@ module YTLJit
130
130
  def using(reg)
131
131
  @reg == reg
132
132
  end
133
+
134
+ def reg_no
135
+ @reg.reg_no
136
+ end
133
137
  end
134
138
 
135
139
  case $ruby_platform
@@ -713,14 +713,12 @@ module YTLJit
713
713
  when OpRegXMM
714
714
  case src
715
715
  when OpRegXMM
716
- rexseq, rexfmt = rex(dst, src)
717
716
  modseq, modfmt = modrm(inst, dst, src, dst, src)
718
- (rexseq + [op, 0x0F, 0x10] + modseq).pack("#{rexfmt}C3#{modfmt}")
717
+ ([op, 0x0F, 0x10] + modseq).pack("C3#{modfmt}")
719
718
 
720
719
  when OpIndirect
721
- rexseq, rexfmt = rex(dst, src)
722
720
  modseq, modfmt = modrm(inst, dst, src, dst, src)
723
- (rexseq + [op, 0x0F, 0x10] + modseq).pack("#{rexfmt}C3#{modfmt}")
721
+ ([op, 0x0F, 0x10] + modseq).pack("C3#{modfmt}")
724
722
 
725
723
  else
726
724
  return nosupported_addressing_mode(inst, dst, src)
@@ -729,9 +727,8 @@ module YTLJit
729
727
  when OpIndirect
730
728
  case src
731
729
  when OpRegXMM
732
- rexseq, rexfmt = rex(dst, src)
733
730
  modseq, modfmt = modrm(inst, src, dst, dst, src)
734
- (rexseq + [op, 0x0F, 0x11] + modseq).pack("#{rexfmt}C3#{modfmt}")
731
+ ([op, 0x0F, 0x11] + modseq).pack("C3#{modfmt}")
735
732
 
736
733
  else
737
734
  return nosupported_addressing_mode(inst, dst, src)
@@ -8,7 +8,14 @@ module YTLJit
8
8
  rrex |= 0b1
9
9
  end
10
10
  end
11
-
11
+
12
+ if dst.is_a?(OpIndirect) and dst.reg.is_a?(OpReg64) then
13
+ if dst.reg_no >= 8 then
14
+ rrex |= 0b1000
15
+ rrex |= 0b1
16
+ end
17
+ end
18
+
12
19
  if src.is_a?(OpReg64) then
13
20
  rrex |= 0b1000
14
21
  if src.reg_no >= 8 then
@@ -16,6 +23,13 @@ module YTLJit
16
23
  end
17
24
  end
18
25
 
26
+ if src.is_a?(OpIndirect) and src.reg.is_a?(OpReg64) then
27
+ if dst.reg_no >= 8 then
28
+ rrex |= 0b1000
29
+ rrex |= 0b1
30
+ end
31
+ end
32
+
19
33
  if src.is_a?(OpImmidiate64) then
20
34
  rrex |= 0b1000
21
35
  end
data/lib/ytljit/util.rb CHANGED
@@ -48,6 +48,41 @@ module YTLJit
48
48
  def boxing
49
49
  self
50
50
  end
51
+
52
+ # Singleton class can't be marshaled.
53
+ # So this class wrap to marshal singleton class
54
+ class ClassClassWrapper
55
+ def initialize(clsobj)
56
+ @klass_object = clsobj
57
+ @value = nil
58
+ end
59
+
60
+ def value
61
+ if @value then
62
+ @value
63
+ else
64
+ @value = class << @klass_object; self; end
65
+ @value
66
+ end
67
+ end
68
+
69
+ def name
70
+ value.name
71
+ end
72
+
73
+ def ancestors
74
+ value.ancestors
75
+ end
76
+
77
+ def marshal_dump
78
+ [@klass_object]
79
+ end
80
+
81
+ def marshal_load(obj)
82
+ @klass_object = obj
83
+ @value = nil
84
+ end
85
+ end
51
86
  end
52
87
 
53
88
  class Fixnum
@@ -62,3 +97,4 @@ class Float
62
97
  end
63
98
  end
64
99
 
100
+
data/lib/ytljit/vm.rb CHANGED
@@ -922,9 +922,10 @@ LocalVarNode
922
922
  @constant_tab = {}
923
923
  @method_tab = {}
924
924
  @klass_object = klassobj
925
- @klassclass = class << @klass_object; self; end
925
+ @klassclass = ClassClassWrapper.new(@klass_object)
926
926
  @klassclass_node = nil # Lazy
927
- RubyType::define_wraped_class(@klassclass, RubyType::RubyTypeBoxed)
927
+ RubyType::define_wraped_class(@klassclass,
928
+ RubyType::RubyTypeBoxed)
928
929
  unless @@class_top_tab[klassobj]
929
930
  @@class_top_tab[klassobj] = self
930
931
  end
@@ -932,26 +933,29 @@ LocalVarNode
932
933
 
933
934
  def collect_info(context)
934
935
  context.modified_local_var.push [{}]
935
- context.modified_instance_var = Hash.new {|hash, key| hash[key] = []}
936
+ context.modified_instance_var = Hash.new
936
937
  context = super
937
938
  context.modified_local_var.pop
938
939
  if @klassclass_node then
939
940
  @klassclass_node.collect_info(context)
941
+ else
942
+ context
940
943
  end
941
- context
942
944
  end
943
945
 
944
946
  def collect_candidate_type(context, signode, sig)
945
947
  super
946
948
  if @klassclass_node then
947
- context = @klassclass_node.collect_candidate_type(context,
948
- signode, sig)
949
+ @klassclass_node.collect_candidate_type(context, signode, sig)
950
+ else
951
+ context
949
952
  end
950
- context
951
953
  end
952
954
 
953
955
  def make_klassclass_node
954
- clsclsnode = ClassTopNode.new(self, @klassclass, @klassclass.name)
956
+ clsclsnode = ClassTopNode.new(self,
957
+ @klassclass,
958
+ @klassclass.name)
955
959
  clsclsnode.body = DummyNode.new
956
960
  @klassclass_node = clsclsnode
957
961
  end
@@ -1038,8 +1042,11 @@ LocalVarNode
1038
1042
  cs = self.find_cs_by_signature(context.to_signature)
1039
1043
  if cs then
1040
1044
  asm = context.assembler
1041
- add = lambda { @klassclass.address }
1045
+ add = lambda { @klassclass.value.address }
1042
1046
  var_klassclass = OpVarImmidiateAddress.new(add)
1047
+ context.start_using_reg(FUNC_ARG[0])
1048
+ context.start_using_reg(FUNC_ARG[1])
1049
+ context.start_using_reg(FUNC_ARG[2])
1043
1050
  asm.with_retry do
1044
1051
  asm.mov(FUNC_ARG_YTL[0], BPR)
1045
1052
  asm.mov(FUNC_ARG_YTL[1], 4)
@@ -1047,6 +1054,9 @@ LocalVarNode
1047
1054
  end
1048
1055
  add = cs.var_base_address
1049
1056
  context = gen_call(context, add, 3)
1057
+ context.end_using_reg(FUNC_ARG[2])
1058
+ context.end_using_reg(FUNC_ARG[1])
1059
+ context.end_using_reg(FUNC_ARG[0])
1050
1060
  end
1051
1061
 
1052
1062
  context
@@ -1068,10 +1078,22 @@ LocalVarNode
1068
1078
  @id.push 0
1069
1079
 
1070
1080
  @unwind_proc = CodeSpace.new
1081
+ @init_node = nil
1071
1082
  init_unwind_proc
1072
1083
  add_code_space(nil, @unwind_proc)
1073
1084
  end
1074
1085
 
1086
+ attr_accessor :init_node
1087
+ attr :code_space_tab
1088
+ attr :asm_tab
1089
+
1090
+ def traverse_childlen
1091
+ if @init_node then
1092
+ yield @init_node
1093
+ end
1094
+ yield @body
1095
+ end
1096
+
1075
1097
  def init_unwind_proc
1076
1098
  asm = Assembler.new(@unwind_proc)
1077
1099
  # Make linkage of frame pointer
@@ -1092,14 +1114,29 @@ LocalVarNode
1092
1114
  end
1093
1115
  end
1094
1116
 
1117
+ def collect_info(context)
1118
+ if @init_node then
1119
+ context = @init_node.collect_info(context)
1120
+ end
1121
+ super(context)
1122
+ end
1123
+
1095
1124
  def collect_candidate_type(context, signode, sig)
1096
1125
  context.convergent = true
1097
1126
  context.visited_top_node = {}
1098
- super
1127
+ if @init_node then
1128
+ context = @init_node.collect_candidate_type(context, signode, sig)
1129
+ end
1130
+ super(context, signode, sig)
1099
1131
  end
1100
1132
 
1101
- attr :code_space_tab
1102
- attr :asm_tab
1133
+ def compile(context)
1134
+ if @init_node then
1135
+ context = @init_node.compile(context)
1136
+ end
1137
+ context = super(context)
1138
+ context
1139
+ end
1103
1140
  end
1104
1141
 
1105
1142
  class LocalFrameInfoNode<BaseNode
@@ -1205,8 +1242,7 @@ LocalVarNode
1205
1242
  end
1206
1243
  context.cpustack_pushn(siz)
1207
1244
  end
1208
- context = @body.compile(context)
1209
- context
1245
+ @body.compile(context)
1210
1246
  end
1211
1247
  end
1212
1248
 
@@ -1355,8 +1391,7 @@ LocalVarNode
1355
1391
  cursig = context.to_signature
1356
1392
  same_type(self, @value_node, cursig, cursig, context)
1357
1393
  same_type(@value_node, self, cursig, cursig, context)
1358
- context = @body.collect_candidate_type(context)
1359
- context
1394
+ @body.collect_candidate_type(context)
1360
1395
  end
1361
1396
 
1362
1397
  def compile(context)
@@ -1390,9 +1425,7 @@ LocalVarNode
1390
1425
  context.ret_reg = RETR
1391
1426
  end
1392
1427
 
1393
- context = @body.compile(context)
1394
-
1395
- context
1428
+ @body.compile(context)
1396
1429
  end
1397
1430
  end
1398
1431
 
@@ -1516,10 +1549,10 @@ LocalVarNode
1516
1549
 
1517
1550
  def collect_candidate_type(context, sender = nil)
1518
1551
  if @come_from.keys[0] == sender then
1519
- context = @body.collect_candidate_type(context)
1552
+ @body.collect_candidate_type(context)
1553
+ else
1554
+ context
1520
1555
  end
1521
-
1522
- context
1523
1556
  end
1524
1557
 
1525
1558
  def compile(context)
@@ -1531,8 +1564,6 @@ LocalVarNode
1531
1564
  else
1532
1565
  context
1533
1566
  end
1534
-
1535
- context
1536
1567
  end
1537
1568
  end
1538
1569
 
@@ -1755,16 +1786,14 @@ LocalVarNode
1755
1786
  end
1756
1787
  context = @define.collect_candidate_type(context, arg, sig)
1757
1788
 
1758
- context = @body.collect_candidate_type(context)
1759
- context
1789
+ @body.collect_candidate_type(context)
1760
1790
  end
1761
1791
 
1762
1792
  def compile(context)
1763
1793
  # raise "Can't compile"
1764
1794
  context = super(context)
1765
1795
  context = @define.compile(context)
1766
- context = @body.compile(context)
1767
- context
1796
+ @body.compile(context)
1768
1797
  end
1769
1798
  end
1770
1799
 
@@ -1920,7 +1949,7 @@ LocalVarNode
1920
1949
  end
1921
1950
  if slfval == nil or mth == nil then
1922
1951
  mth = rklass.instance_method(@name)
1923
- @ruby_reciever = rklass
1952
+ @ruby_reciever = rtype.instance_eval {@ruby_type}
1924
1953
  end
1925
1954
 
1926
1955
  if variable_argument?(mth.parameters) then
@@ -2049,11 +2078,15 @@ LocalVarNode
2049
2078
  end
2050
2079
 
2051
2080
  addr = lambda {
2052
- if @ruby_reciever.class == Module then
2081
+ rrec = @ruby_reciever
2082
+ if rrec.is_a?(ClassClassWrapper) then
2083
+ rrec = rrec.value
2084
+ end
2085
+ if rrec.class == Module then
2053
2086
  name = @name
2054
- @ruby_reciever.send(:method_address_of, name)
2087
+ rrec.send(:method_address_of, name)
2055
2088
  else
2056
- @ruby_reciever.method_address_of(@name)
2089
+ rrec.method_address_of(@name)
2057
2090
  end
2058
2091
  }
2059
2092
  if addr.call then
@@ -2262,8 +2295,8 @@ LocalVarNode
2262
2295
  if base == TMPR2 then
2263
2296
  context.end_using_reg(base)
2264
2297
  end
2265
- context = @body.compile(context)
2266
- context
2298
+
2299
+ @body.compile(context)
2267
2300
  end
2268
2301
  end
2269
2302
 
@@ -2286,6 +2319,9 @@ LocalVarNode
2286
2319
 
2287
2320
  def collect_info(context)
2288
2321
  vti = context.modified_instance_var[@name]
2322
+ if vti == nil then
2323
+ vti = []
2324
+ end
2289
2325
  # Not dup so vti may update after.
2290
2326
  @var_type_info = vti
2291
2327
 
@@ -2355,8 +2391,28 @@ LocalVarNode
2355
2391
  def initialize(parent, klass, name)
2356
2392
  super(parent)
2357
2393
  @name = name
2394
+ rklass = nil
2395
+ case klass
2396
+ when LiteralNode, ConstantRefNode
2397
+ rklass = klass.get_constant_value[0]
2398
+ klass = ClassTopNode.get_class_top_node(rklass)
2399
+
2400
+ when ClassTopNode
2401
+ rklass = klass.get_constant_value[0]
2402
+
2403
+ else
2404
+ klass = search_class_top
2405
+ end
2406
+
2358
2407
  @class_top = klass # .search_class_top
2359
- @value_node, dummy = klass.search_constant_with_super(@name)
2408
+ @value_node = nil
2409
+ clsnode = nil
2410
+ if klass then
2411
+ @value_node, clsnode = klass.search_constant_with_super(@name)
2412
+ end
2413
+ if clsnode == nil and rklass then
2414
+ @value_node = LiteralNode.new(self, rklass.const_get(@name))
2415
+ end
2360
2416
  end
2361
2417
 
2362
2418
  attr :value_node
@@ -77,7 +77,7 @@ LO | | | |
77
77
  def initialize(tnode)
78
78
  @top_node = tnode
79
79
  @modified_local_var = []
80
- @modified_instance_var = Hash.new {|hash, key| hash[key] = []}
80
+ @modified_instance_var = Hash.new
81
81
  @yield_node = []
82
82
  end
83
83
 
@@ -357,7 +357,7 @@ LO | | | |
357
357
  def start_using_reg(reg)
358
358
  case reg
359
359
  when OpRegistor
360
- if reg != TMPR then
360
+ if reg != TMPR and reg != XMM0 then
361
361
  start_using_reg_aux(reg)
362
362
  end
363
363
 
@@ -11,14 +11,18 @@ module YTLJit
11
11
 
12
12
  def compile_main(context)
13
13
  slfoff = @current_frame_info.offset_arg(2, BPR)
14
- asm = context.assembler
15
14
  ivid = ((@name.object_id << 1) / InternalRubyType::RObject.size)
16
15
  ivarget = OpMemAddress.new(address_of("rb_ivar_get"))
16
+ context.start_using_reg(FUNC_ARG[0])
17
+ context.start_using_reg(FUNC_ARG[1])
18
+ asm = context.assembler
17
19
  asm.with_retry do
18
20
  asm.mov(FUNC_ARG[0], slfoff)
19
21
  asm.mov(FUNC_ARG[1], ivid)
20
22
  asm.call_with_arg(ivarget, 2)
21
23
  end
24
+ context.end_using_reg(FUNC_ARG[1])
25
+ context.end_using_reg(FUNC_ARG[0])
22
26
 
23
27
  context.ret_reg = RETR
24
28
  context.ret_node = self
@@ -42,6 +46,9 @@ module YTLJit
42
46
  rtype = @val.decide_type_once(context.to_signature)
43
47
  context = rtype.gen_boxing(context)
44
48
 
49
+ context.start_using_reg(FUNC_ARG[0])
50
+ context.start_using_reg(FUNC_ARG[1])
51
+ context.start_using_reg(FUNC_ARG[2])
45
52
  asm = context.assembler
46
53
  asm.with_retry do
47
54
  asm.push(TMPR2)
@@ -52,6 +59,9 @@ module YTLJit
52
59
  asm.call_with_arg(ivarset, 3)
53
60
  asm.pop(TMPR2)
54
61
  end
62
+ context.end_using_reg(FUNC_ARG[2])
63
+ context.end_using_reg(FUNC_ARG[1])
64
+ context.end_using_reg(FUNC_ARG[0])
55
65
 
56
66
  context.ret_reg = RETR
57
67
  context.ret_node = self
@@ -944,7 +944,8 @@ module YTLJit
944
944
  end
945
945
 
946
946
  def compile_call_func(context, fname)
947
- fadd = address_of(fname)
947
+ fadd = OpMemAddress.new(address_of(fname))
948
+ context.start_using_reg(FUNC_ARG[0])
948
949
  asm = context.assembler
949
950
  asm.with_retry do
950
951
  asm.mov(FUNC_FLOAT_ARG[0], context.ret_reg)
@@ -953,10 +954,11 @@ module YTLJit
953
954
  asm.fstpl(INDIRECT_SPR)
954
955
  asm.pop(XMM0)
955
956
  end
957
+ context.end_using_reg(FUNC_ARG[0])
956
958
  context
957
959
  end
958
960
 
959
- def compile(context)
961
+ def compile2(context)
960
962
  @arguments[2].decide_type_once(context.to_signature)
961
963
  rtype = @arguments[2].type
962
964
  rrtype = rtype.ruby_type
@@ -24,8 +24,8 @@ module YTLJit
24
24
  @not_reached_pos = false
25
25
  end
26
26
 
27
- attr :the_top
28
- attr :top_nodes
27
+ attr_accessor :the_top
28
+ attr :top_nodes
29
29
 
30
30
  attr_accessor :current_file_name
31
31
  attr_accessor :current_class_node
@@ -137,6 +137,13 @@ module YTLJit
137
137
 
138
138
  def visit_block_start(code, ins, context)
139
139
  mtopnode = context.current_node
140
+ if !mtopnode.is_a?(TopNode) then
141
+ oldtop = context.the_top
142
+ mtopnode = TopTopNode.new(nil, Object)
143
+ context.the_top = mtopnode
144
+ oldtop.parent = mtopnode
145
+ mtopnode.init_node = oldtop
146
+ end
140
147
 
141
148
  locals = code.header['locals']
142
149
  args = code.header['misc'][:arg_size]
@@ -232,7 +232,16 @@ module YTLJit
232
232
  end
233
233
 
234
234
  attr_accessor :asm_type
235
- attr_accessor :ruby_type
235
+
236
+ def ruby_type
237
+ if @ruby_type.is_a?(ClassClassWrapper) then
238
+ @ruby_type.value
239
+ else
240
+ @ruby_type
241
+ end
242
+ end
243
+
244
+ attr_writer :ruby_type
236
245
  end
237
246
 
238
247
  # Same as VALUE type in MRI
@@ -247,11 +256,11 @@ module YTLJit
247
256
  end
248
257
 
249
258
  def to_unbox
250
- @@unboxed_type_tab[@ruby_type].instance
259
+ @@unboxed_type_tab[ruby_type].instance
251
260
  end
252
261
 
253
262
  def to_box
254
- @@boxed_type_tab[@ruby_type].instance
263
+ @@boxed_type_tab[ruby_type].instance
255
264
  end
256
265
 
257
266
  def ==(other)
@@ -272,7 +281,7 @@ module YTLJit
272
281
  end
273
282
 
274
283
  def to_unbox
275
- @@unboxed_type_tab[@ruby_type].instance
284
+ @@unboxed_type_tab[ruby_type].instance
276
285
  end
277
286
 
278
287
  def to_box
@@ -288,7 +297,7 @@ module YTLJit
288
297
  end
289
298
 
290
299
  def to_box
291
- @@boxed_type_tab[@ruby_type].instance
300
+ @@boxed_type_tab[ruby_type].instance
292
301
  end
293
302
 
294
303
  def to_unbox
@@ -26,7 +26,7 @@ module YTLJit
26
26
  end
27
27
 
28
28
  def inspect
29
- "{ #{boxed ? "BOXED" : "UNBOXED"} #{@ruby_type}}"
29
+ "{ #{boxed ? "BOXED" : "UNBOXED"} #{ruby_type}}"
30
30
  end
31
31
  end
32
32
 
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 4
9
- version: 0.0.4
8
+ - 5
9
+ version: 0.0.5
10
10
  platform: ruby
11
11
  authors:
12
12
  - Hideki Miura
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-12-10 00:00:00 +09:00
17
+ date: 2010-12-17 00:00:00 +09:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency