ytljit 0.0.4 → 0.0.5

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/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