cast_off 0.3.5 → 0.3.6

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/README CHANGED
@@ -212,9 +212,6 @@ cast_off [options] [programfile] [arguments]
212
212
  --run
213
213
  コンパイル済みコードを用いて、対象プログラム[programfile]を実行します。
214
214
 
215
- --deoptimize
216
- 脱最適化を有効にします。
217
-
218
215
  --clear
219
216
  プロファイル結果やコンパイル結果を削除します。
220
217
  name オプションによって foo と名づけたコンパイル結果を削除する場合、次のコマンドを使用してください。
@@ -464,7 +461,7 @@ CastOff.deoptimize(true) とすることで、脱最適化を有効にするこ
464
461
  ---指定方法
465
462
  CastOff.deoptimize(true or false)
466
463
  ---デフォルト値
467
- false
464
+ true
468
465
  ---備考
469
466
  ガードでの検査に失敗した場合に、脱最適化を行う(true)か、例外を発生させる(false)かを設定します。
470
467
  脱最適化を有効にすることで、ガードでの検査失敗時にも実行を継続させることができます。
data/README.en CHANGED
@@ -125,9 +125,6 @@ cast_off [options] PathOfTargetProgram ArgumentsOfTargetProgram
125
125
  --run
126
126
  Execute target program with compiled methods.
127
127
 
128
- --deoptimize
129
- Enable deoptimization.
130
-
131
128
  --clear
132
129
  Clear profile information and delete compiled methods.
133
130
  If you want to clear profile information and compiled methods of target name "foo",
data/bin/cast_off CHANGED
@@ -8,7 +8,6 @@ this = File.expand_path("#{Gem.bindir()}/#{File.basename(__FILE__)}")
8
8
  step = nil
9
9
  verbose = false
10
10
  clear = false
11
- deoptimize = false
12
11
  threshold = 100
13
12
  name = nil
14
13
 
@@ -22,9 +21,6 @@ opt.separator("\n Options:")
22
21
  opt.on('--run', <<-EOS.strip) {|v| step = 'run' }
23
22
  Execute [programfile] with compiled codes.
24
23
  EOS
25
- opt.on('--deoptimize', <<-EOS.strip) {|v| deoptimize = true }
26
- Enable deoptimization.
27
- EOS
28
24
  opt.on('--threshold=COUNT', <<-EOS.strip, Integer) {|v| threshold = v }
29
25
  Compile method which is executed more than COUNT.
30
26
  Default value is 100.
@@ -107,7 +103,6 @@ end
107
103
  configuration = <<-EOS
108
104
  CastOff.program_name = #{name.inspect}
109
105
  CastOff.skip_configuration_check(true)
110
- CastOff.deoptimize(#{deoptimize})
111
106
  CastOff.use_default_configuration()
112
107
  EOS
113
108
  eval(configuration, binding)
@@ -119,7 +114,7 @@ case step
119
114
  when nil
120
115
  STDERR.puts("-------------------------------- compilation start: threshold = #{threshold}, name = #{name}, profiling = ruby #{args} --------------------------------")
121
116
  2.times do |i|
122
- system("#{this} --step-#{i + 1} --threshold=#{threshold} --name=#{name} #{deoptimize ? '--deoptimize' : ''} #{verbose ? '--verbose' : ''} #{args}")
117
+ system("#{this} --step-#{i + 1} --threshold=#{threshold} --name=#{name} #{verbose ? '--verbose' : ''} #{args}")
123
118
  unless $? == 0
124
119
  STDERR.puts("Failed to execute 'ruby #{args}'")
125
120
  exit
@@ -161,7 +156,7 @@ CastOff.autoload()
161
156
  Compilation finished successfully.
162
157
  You can execute #{script} with compiled codes by use of following command.
163
158
 
164
- $cast_off --run --name=#{name}#{deoptimize ? ' --deoptimize ' : ' '}#{args}
159
+ $cast_off --run --name=#{name} #{args}
165
160
  ----------------------------------------------------------------------------------------
166
161
  EOS
167
162
  STDERR.puts(msg)
data/cast_off.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "cast_off"
3
- spec.version = "0.3.5"
3
+ spec.version = "0.3.6"
4
4
  spec.platform = Gem::Platform::RUBY
5
5
  spec.summary = "Compiler for Ruby1.9.3"
6
6
  spec.description = <<-EOS
@@ -833,7 +833,7 @@ static VALUE cast_off_class_wrapper_each_method_search_target(VALUE self, VALUE
833
833
  st_data_t body;
834
834
 
835
835
  if (!klass) {
836
- method_not_found(wrapper->klass, mid, 1);
836
+ break;
837
837
  }
838
838
  if (TYPE(klass) == T_ICLASS) {
839
839
  VALUE module = RBASIC(klass)->klass;
@@ -91,7 +91,7 @@ static inline VALUE MULT(long a, long b)
91
91
  % {'VALUE' => 'RFLOAT_VALUE', 'double' => ''},
92
92
  % {'VALUE' => 'DBL2NUM', 'double' => ''}],
93
93
  % ['float_float',
94
- % {'>' => 'gt', '>=' => 'ge', '<' => 'lt', '<=' => 'le', '==' => 'eq', '==' => 'eqq'},
94
+ % {'>' => 'gt', '>=' => 'ge', '<' => 'lt', '<=' => 'le', '==' => 'eq', '==' => 'eqq', '!=' => 'neq'},
95
95
  % 1,
96
96
  % :binary_operator,
97
97
  % {'VALUE' => 'RFLOAT_VALUE', 'double' => ''},
@@ -104,6 +104,13 @@ static inline VALUE MULT(long a, long b)
104
104
  % {'VALUE' => 'FIX2LONG', 'long' => ''},
105
105
  % {'VALUE' => 'FIX2LONG', 'long' => ''},
106
106
  % {'VALUE' => ''}],
107
+ % ['fixnum_fixnum',
108
+ % {'>' => 'gt', '>=' => 'ge', '<' => 'lt', '<=' => 'le', '==' => 'eq', '==' => 'eqq', '!=' => 'neq'},
109
+ % 1,
110
+ % :binary_operator,
111
+ % {'VALUE' => 'FIX2LONG', 'long' => ''},
112
+ % {'VALUE' => 'FIX2LONG', 'long' => ''},
113
+ % {'VALUE' => ''}],
107
114
  % ['fixnum_float',
108
115
  % {'+' => 'plus', '-' => 'minus', '*' => 'mult'},
109
116
  % 1,
@@ -112,7 +119,7 @@ static inline VALUE MULT(long a, long b)
112
119
  % {'VALUE' => 'RFLOAT_VALUE', 'double' => ''},
113
120
  % {'VALUE' => 'DBL2NUM', 'double' => ''}],
114
121
  % ['fixnum_float',
115
- % {'>' => 'gt', '>=' => 'ge', '<' => 'lt', '<=' => 'le', '==' => 'eq', '==' => 'eqq'},
122
+ % {'>' => 'gt', '>=' => 'ge', '<' => 'lt', '<=' => 'le', '==' => 'eq', '==' => 'eqq', '!=' => 'neq'},
116
123
  % 1,
117
124
  % :binary_operator,
118
125
  % {'VALUE' => '(double)FIX2LONG', 'long' => ''},
@@ -126,7 +133,7 @@ static inline VALUE MULT(long a, long b)
126
133
  % {'VALUE' => '(double)FIX2LONG', 'long' => ''},
127
134
  % {'VALUE' => 'DBL2NUM', 'double' => ''}],
128
135
  % ['float_fixnum',
129
- % {'>' => 'gt', '>=' => 'ge', '<' => 'lt', '<=' => 'le', '==' => 'eq', '==' => 'eqq'},
136
+ % {'>' => 'gt', '>=' => 'ge', '<' => 'lt', '<=' => 'le', '==' => 'eq', '==' => 'eqq', '!=' => 'neq'},
130
137
  % 1,
131
138
  % :binary_operator,
132
139
  % {'VALUE' => 'RFLOAT_VALUE', 'double' => ''},
@@ -1,3 +1,11 @@
1
+ static inline int empty_method_table_p(VALUE klass)
2
+ {
3
+ st_table *mtbl = RCLASS_M_TBL(klass);
4
+
5
+ if (!mtbl) rb_bug("empty_method_table_p: shoult not be reached");
6
+ return mtbl->num_entries == 0;
7
+ }
8
+
1
9
  static VALUE handle_blockarg(VALUE blockarg)
2
10
  {
3
11
  VALUE thval = rb_thread_current();
@@ -156,7 +156,7 @@ Max length of signiture is #{FILEPATH_LIMIT} in this environment.
156
156
  @annotation_path = "#{@dstdir}/#{@signiture}.ann"
157
157
  @development_mark_file = "development"
158
158
  @development_mark_path = "#{@dstdir}/#{@development_mark_file}"
159
- @dstbin = "#{@dstdir}/#{@signiture}.so"
159
+ @dstbin = "#{@dstdir}/#{@signiture}.#{CONFIG['DLEXT']}"
160
160
  @longpath = @base_configuration_path # FIXME
161
161
  check_length()
162
162
  end
@@ -229,8 +229,12 @@ Max length of signiture is #{FILEPATH_LIMIT} in this environment.
229
229
  log = `#{makecmd} 2>&1`
230
230
  if $? != 0
231
231
  dlog(c_source)
232
- dlog(log)
233
- bug("failed to compile c source: status = (#{$?})")
232
+ raise(CompileError.new(<<-EOS))
233
+
234
+ Failed to compile c source: status = (#{$?})
235
+ ---------- Error ----------
236
+ #{log}
237
+ EOS
234
238
  else
235
239
  dlog(c_source, 2)
236
240
  dlog(log, 2)
@@ -447,7 +447,7 @@ Currently, CastOff doesn't support object, which cannot marshal dump (e.g. STDIN
447
447
  def self.load(io)
448
448
  begin
449
449
  conf = Marshal.load(io)
450
- rescue NameError
450
+ rescue NameError, ArgumentError
451
451
  return nil
452
452
  end
453
453
  bug() unless conf.instance_of?(Configuration)
@@ -2333,7 +2333,7 @@ Currently, CastOff doesn't support object, which cannot marshal dump (e.g. STDIN
2333
2333
  :@@reuse_compiled_code => [true, false, true],
2334
2334
  :@@allow_builtin_variable_incompatibility => [false, true, false],
2335
2335
  :@@prefetch_constant => [true, true, false],
2336
- :@@deoptimize => [false, true, true],
2336
+ :@@deoptimize => [true, true, true],
2337
2337
  :@@development => [false, true, true],
2338
2338
  :@@alert_override => [true, true, false],
2339
2339
  :@@skip_configuration_check => [false, false, true],
@@ -690,11 +690,7 @@ module CastOff
690
690
  ret << " #{@return_value} = rb_reg_nth_match((int)(#{type >> 1}), rb_backref_get());"
691
691
  end
692
692
  else
693
- raise(UnsupportedError.new(<<-EOS))
694
-
695
- $&, $`, $\, $+, $0...$9 are incompatible.
696
- If you want to use these variables, use CastOff.allow_builtin_variable_incompatibility(true).
697
- EOS
693
+ bug()
698
694
  end
699
695
  end
700
696
  bug() unless param.empty?
@@ -1723,7 +1719,6 @@ You should not use #{@method_id} method in compilation target of CastOff.
1723
1719
  [MethodWrapper.new(FixnumWrapper, :>), 2] => [['gt', [Fixnum], nil, [TrueClass, FalseClass], false, false]],
1724
1720
  [MethodWrapper.new(FixnumWrapper, :==), 2] => [['eq', [Fixnum], nil, [TrueClass, FalseClass], false, false]],
1725
1721
  [MethodWrapper.new(FixnumWrapper, :===), 2] => [['eqq', [Fixnum], nil, [TrueClass, FalseClass], false, false]],
1726
- [MethodWrapper.new(FixnumWrapper, :!=), 2] => [['neq', [Fixnum], nil, [TrueClass, FalseClass], false, false]],
1727
1722
  [MethodWrapper.new(FixnumWrapper, :&), 2] => [['and', [Fixnum], Fixnum, nil, false, false]], # FIXME
1728
1723
  [MethodWrapper.new(FloatWrapper, :+), 2] => [['float_plus', [Float], nil, Float, true, true], ['fixnum_plus', [Fixnum], nil, Float, true, true]],
1729
1724
  [MethodWrapper.new(FloatWrapper, :-), 2] => [['float_minus', [Float], nil, Float, true, true], ['fixnum_minus', [Fixnum], nil, Float, true, true]],
@@ -1739,6 +1734,10 @@ You should not use #{@method_id} method in compilation target of CastOff.
1739
1734
  ['fixnum_gt', [Fixnum], nil, [TrueClass, FalseClass], false, true]],
1740
1735
  [MethodWrapper.new(FloatWrapper, :==), 2] => [['float_eq', [Float], nil, [TrueClass, FalseClass], false, true],
1741
1736
  ['fixnum_eq', [Fixnum], nil, [TrueClass, FalseClass], false, true]],
1737
+ [MethodWrapper.new(FixnumWrapper, :!=), 2] => [['fixnum_neq', [Fixnum], nil, [TrueClass, FalseClass], false, true],
1738
+ ['float_neq', [Float], nil, [TrueClass, FalseClass], false, true]],
1739
+ [MethodWrapper.new(FloatWrapper, :!=), 2] => [['float_neq', [Float], nil, [TrueClass, FalseClass], false, true],
1740
+ ['fixnum_neq', [Fixnum], nil, [TrueClass, FalseClass], false, true]],
1742
1741
  [MethodWrapper.new(FloatWrapper, :===), 2] => [['float_eqq', [Float], nil, [TrueClass, FalseClass], false, true],
1743
1742
  ['fixnum_eqq', [Fixnum], nil, [TrueClass, FalseClass], false, true]],
1744
1743
  [MethodWrapper.new(FixnumWrapper, :-@), 1] => [['uminus', [], nil, [Fixnum, Bignum], false, true]],
@@ -2034,8 +2033,8 @@ You should not use #{@method_id} method in compilation target of CastOff.
2034
2033
  } else {
2035
2034
  % if funcall
2036
2035
  <%= funcall_code(nil, id, recv, param, @argc) %>
2037
- % else
2038
- rb_bug("type mismatch: method name = <%= @method_id %>");
2036
+ % else # empty_method_table_p に通った特異クラスがくる可能性がある。
2037
+ <%= funcall_code(nil, id, recv, param, @argc) %>
2039
2038
  % end
2040
2039
  }
2041
2040
  %end
@@ -2117,7 +2116,7 @@ You should not use #{@method_id} method in compilation target of CastOff.
2117
2116
  else_class = types[else_index]
2118
2117
  else_code = not_funcall_code(else_class, @method_id, recv, param, @argc)
2119
2118
  if !else_code
2120
- @dependency.add(else_class, @method_id, false) if else_class.method_defined?
2119
+ @dependency.add(else_class, @method_id, false)
2121
2120
  else_code = funcall_code(else_class, id, recv, param, @argc)
2122
2121
  end
2123
2122
  if nil_code == else_code
@@ -379,6 +379,15 @@ Call site is (#{insn}).
379
379
  when :cast_off_setdvar
380
380
  irs << SubIR.new(TmpVariable.new(stack.pop()), DynamicVariable.new(*argv), insn, cfg)
381
381
  when :getspecial
382
+ type = insn.argv.last
383
+ bug() if type == 0
384
+ unless translator.configuration.allow_builtin_variable_incompatibility?
385
+ raise(UnsupportedError.new(<<-EOS))
386
+
387
+ $&, $`, $\, $+, $0...$9 are incompatible.
388
+ If you want to use these variables, use CastOff.allow_builtin_variable_incompatibility(true).
389
+ EOS
390
+ end
382
391
  param = []
383
392
  irs << Getspecial.new(param, 0, TmpVariable.new(stack.push()), insn, cfg)
384
393
  when :jump, :cast_off_enter_block, :cast_off_leave_block
@@ -64,10 +64,10 @@ module CastOff::Compiler
64
64
  ret = []
65
65
  case @src
66
66
  when Argument
67
- if @translator.inline_block?
68
- # nothing to do
69
- else
67
+ if !@translator.inline_block? && @insn.iseq.root?
70
68
  ret << " #{@dst} = #{@src.lvar};"
69
+ else
70
+ # nothing to do
71
71
  end
72
72
  when ConstWrapper
73
73
  @insn.iseq.reference_constant
@@ -101,7 +101,11 @@ static void sampling_variable(VALUE val, VALUE sym)
101
101
  klass = val;
102
102
  singleton_class_or_module_obj_p = Qtrue;
103
103
  } else {
104
- klass = rb_cCastOffSingletonClass;
104
+ if (empty_method_table_p(klass)) {
105
+ klass = rb_obj_class(val);
106
+ } else {
107
+ klass = rb_cCastOffSingletonClass;
108
+ }
105
109
  }
106
110
  }
107
111
 
@@ -122,9 +126,17 @@ static void __sampling_poscall(VALUE val, VALUE method_klass, VALUE method_id)
122
126
 
123
127
  if (FL_TEST(method_klass, FL_SINGLETON)) {
124
128
  VALUE recv = rb_ivar_get(method_klass, rb_intern("__attached__"));
125
- if ((rb_obj_class(recv) == rb_cClass || rb_obj_class(recv) == rb_cModule) && rb_class_of(recv) == method_klass) {
126
- method_klass = recv;
127
- class_method_or_module_function_p = Qtrue;
129
+ if (rb_class_of(recv) == method_klass) {
130
+ if ((rb_obj_class(recv) == rb_cClass || rb_obj_class(recv) == rb_cModule)) {
131
+ method_klass = recv;
132
+ class_method_or_module_function_p = Qtrue;
133
+ } else {
134
+ if (empty_method_table_p(method_klass)) {
135
+ method_klass = rb_obj_class(recv);
136
+ } else {
137
+ method_klass = rb_cCastOffSingletonClass;
138
+ }
139
+ }
128
140
  } else {
129
141
  method_klass = rb_cCastOffSingletonClass;
130
142
  }
@@ -153,7 +165,11 @@ static void __sampling_poscall(VALUE val, VALUE method_klass, VALUE method_id)
153
165
  klass = val;
154
166
  singleton_class_or_module_obj_p = Qtrue;
155
167
  } else {
156
- klass = rb_cCastOffSingletonClass;
168
+ if (empty_method_table_p(klass)) {
169
+ klass = rb_obj_class(val);
170
+ } else {
171
+ klass = rb_cCastOffSingletonClass;
172
+ }
157
173
  }
158
174
  }
159
175
 
@@ -393,14 +409,6 @@ static VALUE cast_off_initialize_fptr_<%= signiture() %>(VALUE dummy)
393
409
  return Qnil;
394
410
  }
395
411
 
396
- static inline int empty_method_table_p(VALUE klass)
397
- {
398
- st_table *mtbl = RCLASS_M_TBL(klass);
399
-
400
- if (!mtbl) rb_bug("empty_method_table_p: shoult not be reached");
401
- return mtbl->num_entries == 0;
402
- }
403
-
404
412
  %@throw_exception_functions.each do |(func, name)|
405
413
  <%= func.gsub(/<THROW_EXCEPTION_FUNCTION_NAME>/, name) %>
406
414
  %end
@@ -887,7 +895,8 @@ Source line is #{@root_iseq.source_line}.
887
895
 
888
896
  def allocate_function_pointer(klass, mid, convention, argc)
889
897
  bug() unless klass.is_a?(ClassWrapper)
890
- fptr = "fptr_#{klass}_#{@namespace.new(mid).name}"
898
+ suffix = klass.singleton? ? 'singleton' : 'instance'
899
+ fptr = "fptr_#{klass}_#{@namespace.new(mid).name}_#{suffix}"
891
900
  fptr.gsub!(/:/, '_')
892
901
  ids = klass.to_s.split("::")
893
902
  ids.each{|k| bug() if k == ''}
@@ -1136,6 +1145,10 @@ Source line is #{@root_iseq.source_line}.
1136
1145
  b << InsnInfo.new([:cast_off_enter_block, loop_label], insn.iseq, -1, -1, true, prep.depth + prep.stack_usage())
1137
1146
  b << cont_label
1138
1147
  bug() unless c_depth + 1 == prep.depth + prep.stack_usage()
1148
+ c_lvars.each_with_index do |l, index|
1149
+ op = (index < c_iseq.args.arg_size) ? :cast_off_decl_arg : :cast_off_decl_var
1150
+ b << InsnInfo.new([op] + l, c_iseq, -1, -1, true, c_depth)
1151
+ end
1139
1152
  b << InsnInfo.new([:cast_off_cont, loop_id, c_args, insn], c_iseq, -1, -1, true, c_depth)
1140
1153
  if c_iseq.args.opt?
1141
1154
  bug() if inline_block?
@@ -1565,8 +1578,9 @@ Currently, CastOff cannot handle this constant reference.
1565
1578
  body.unshift(InsnInfo.new([:cast_off_fetch_args, [must, opt, rest, post, block, lvars.slice(0, @arg_size)]], @root_iseq, -1, -1, true, 0))
1566
1579
  end
1567
1580
 
1581
+ bug() unless @root_iseq.args.arg_size == @arg_size
1568
1582
  decl = []
1569
- lvars.each_with_index do |l, index|
1583
+ @root_iseq.lvars.each_with_index do |l, index|
1570
1584
  if index < @arg_size
1571
1585
  bug() if execute?
1572
1586
  op = :cast_off_decl_arg
@@ -445,8 +445,9 @@ Currently, CastOff cannot compile method which source file is not exist.
445
445
  CastOff.compile(klass, mid, bind)
446
446
  end
447
447
  vlog("load #{klass}##{mid}")
448
- rescue ArgumentError => e
449
- # dependency の Marshal.load に失敗
448
+ rescue ArgumentError, NameError => e
449
+ # ArgumentError: dependency の Marshal.load に失敗
450
+ # NameError: prefetch constant での定数参照に失敗
450
451
  vlog("skip: entry = #{entry[0]}#{entry[2] ? '.' : '#'}#{entry[1]}, #{e}")
451
452
  CodeManager.delete_from_compiled(entry)
452
453
  rescue UnsupportedError => e
@@ -487,6 +488,16 @@ Currently, CastOff cannot compile method which source file is not exist.
487
488
  raise(ExecutionError.new("Currently, CastOff doesn't support Module#autoload"))
488
489
  end
489
490
  end
491
+ Kernel.module_eval do
492
+ def set_trace_func(*args, &p)
493
+ raise(ExecutionError.new("Currently, CastOff doesn't support set_trace_func"))
494
+ end
495
+ end
496
+ Thread.class_eval do
497
+ def set_trace_func(*args, &p)
498
+ raise(ExecutionError.new("Currently, CastOff doesn't support Thread#set_trace_func"))
499
+ end
500
+ end
490
501
 
491
502
  def contain_loop?(klass, mid)
492
503
  case compilation_target_type(klass, mid)
@@ -581,7 +592,7 @@ Currently, CastOff cannot compile method which source file is not exist.
581
592
  end
582
593
  vlog("#{index}: compile #{klass}#{singleton ? '.' : '#'}#{mid}")
583
594
  [klass, mid, singleton] + location + [Configuration::BindingWrapper.new(bind)] # klass, mid, file, line, binding
584
- rescue UnsupportedError => e
595
+ rescue UnsupportedError, CompileError => e
585
596
  vlog("#{index}: failed to compile #{klass}#{singleton ? '.' : '#'}#{mid} (#{e.message})")
586
597
  nil
587
598
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cast_off
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.5
4
+ version: 0.3.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-28 00:00:00.000000000 Z
12
+ date: 2011-11-30 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: ! 'CastOff is a compiler for Ruby1.9.3.
15
15