cast_off 0.2.3 → 0.3.1

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.
@@ -93,19 +93,26 @@ expected <%= @guard_value.types %> but %s, %s\\n\\
93
93
  }
94
94
  EOS
95
95
 
96
- GUARD_TEMPLATE = ERB.new(<<-EOS, 0, '%-', 'g0')
97
- %bug() if @guard_value.undefined? || @guard_value.dynamic?
98
- <%= guard_begin() %>
96
+ GUARD_RECOMPILATION_FUNCTION_TEMPLATE = ERB.new(<<-EOS, 0, '%-', '__recompilation')
97
+ NOINLINE(static void <RECOMPILATION_FUNCTION_NAME>(VALUE obj));
98
+ static void <RECOMPILATION_FUNCTION_NAME>(VALUE obj)
99
+ {
99
100
  #if 1
100
- if(!sampling_table) register_sampling_table(rb_hash_new());
101
- % get_definition(@guard_value).each do |defn|
101
+ if(!sampling_table) register_sampling_table(rb_hash_new());
102
+ % count = 0
103
+ % defs = get_definition(@guard_value)
104
+ % defs.each do |defn|
102
105
  % case defn
103
106
  % when SubIR
104
107
  % case defn.src
105
108
  % when LocalVariable, DynamicVariable, InstanceVariable, ClassVariable, GlobalVariable, Self
106
- sampling_variable(<%= @guard_value %>, ID2SYM(rb_intern("<%= defn.src.source %>")));
107
- % when ConstWrapper, Literal
109
+ % count += 1
110
+ sampling_variable(obj, ID2SYM(rb_intern("<%= defn.src.source %>")));
111
+ % when ConstWrapper
108
112
  % # Fixme
113
+ /* <%= defn.src.path %> */
114
+ % when Literal
115
+ % # nothing to do
109
116
  % else
110
117
  % bug(defn.src)
111
118
  % end
@@ -115,12 +122,25 @@ expected <%= @guard_value.types %> but %s, %s\\n\\
115
122
  % recv.types.each do |k|
116
123
  % recv_class = @translator.get_c_classname(k)
117
124
  % bug() unless recv_class
118
- __sampling_poscall(<%= @guard_value %>, <%= recv_class %>, ID2SYM(rb_intern("<%= defn.method_id %>")));
125
+ % count += 1
126
+ __sampling_poscall(obj, <%= recv_class %>, ID2SYM(rb_intern("<%= defn.method_id %>")));
119
127
  % end
120
128
  % end
121
129
  % end
122
- rb_funcall(rb_mCastOff, rb_intern("re_compile"), 2, rb_str_new2("<%= @translator.signiture() %>"), sampling_table_val);
130
+ % if count > 0
131
+ rb_funcall(rb_mCastOff, rb_intern("re_compile"), 2, rb_str_new2("<%= @translator.signiture() %>"), sampling_table_val);
132
+ % else
133
+ % dlog("skip recompilation: defs = \#{defs.join("\\n")}")
134
+ % end
123
135
  #endif
136
+ }
137
+ EOS
138
+
139
+ GUARD_TEMPLATE = ERB.new(<<-EOS, 0, '%-', 'g0')
140
+ %bug() if @guard_value.undefined? || @guard_value.dynamic?
141
+ <%= guard_begin() %>
142
+ %func = @translator.declare_recompilation_function(GUARD_RECOMPILATION_FUNCTION_TEMPLATE.trigger(binding))
143
+ <%= func %>(<%= @guard_value %>);
124
144
  %if @configuration.deoptimize?
125
145
  goto <%= @insn.guard_label %>;
126
146
  % @insn.iseq.inject_guard(@insn, GUARD_DEOPTIMIZATION_TEMPLATE.trigger(binding))
@@ -670,7 +670,7 @@ Call site is (#{insn}).
670
670
  change = false
671
671
  @cfg.blocks.each do |b|
672
672
  foo = b.irs & irs
673
- bar = b.information.variable_definition & irs
673
+ bar = b.information.definition & irs
674
674
  if foo.size > 0 || bar.size > 0
675
675
  vars = []
676
676
  bar.each do |ir|
@@ -745,7 +745,7 @@ Call site is (#{insn}).
745
745
  when Literal
746
746
  return [target]
747
747
  when Variable
748
- ds = @information.variable_definition_of(target)
748
+ ds = @information.definition_of(target)
749
749
  bug() if ds.empty?
750
750
  ary = []
751
751
  ds.each do |d|
@@ -87,6 +87,7 @@ static void sampling_variable(VALUE val, VALUE sym)
87
87
  /* :variable => [klass0, klass1, ...] */
88
88
  VALUE klass = rb_class_of(val);
89
89
  VALUE hashval;
90
+ VALUE singleton_class_obj_p = Qfalse;
90
91
  st_table *hash;
91
92
 
92
93
  if (!st_lookup(sampling_table, (st_data_t)sym, (st_data_t*)&hashval)) {
@@ -96,11 +97,16 @@ static void sampling_variable(VALUE val, VALUE sym)
96
97
  hash = RHASH_TBL(hashval);
97
98
 
98
99
  if (FL_TEST(klass, FL_SINGLETON)) {
99
- klass = rb_cCastOffSingletonClass;
100
+ if (rb_obj_class(val) == rb_cClass) {
101
+ klass = val;
102
+ singleton_class_obj_p = Qtrue;
103
+ } else {
104
+ klass = rb_cCastOffSingletonClass;
105
+ }
100
106
  }
101
107
 
102
108
  if (!st_lookup(hash, (st_data_t)klass, 0)) {
103
- st_insert(hash, (st_data_t)klass, (st_data_t)Qtrue);
109
+ st_insert(hash, (st_data_t)klass, (st_data_t)singleton_class_obj_p);
104
110
  }
105
111
 
106
112
  return;
@@ -109,18 +115,30 @@ static void sampling_variable(VALUE val, VALUE sym)
109
115
  static void __sampling_poscall(VALUE val, VALUE method_klass, VALUE method_id)
110
116
  {
111
117
  VALUE klass;
112
- VALUE method_id_hashval, hashval;
113
- st_table *method_id_hash, *hash;
118
+ VALUE mtblval, method_id_hashval, hashval;
119
+ VALUE singleton_class_obj_p = Qfalse;
120
+ VALUE class_method_p = Qfalse;
121
+ st_table *mtbl, *method_id_hash, *hash;
114
122
 
115
123
  if (FL_TEST(method_klass, FL_SINGLETON)) {
116
- method_klass = rb_cCastOffSingletonClass;
124
+ VALUE recv = rb_ivar_get(method_klass, rb_intern("__attached__"));
125
+ if (rb_obj_class(recv) == rb_cClass && rb_class_of(recv) == method_klass) {
126
+ method_klass = recv;
127
+ class_method_p = Qtrue;
128
+ } else {
129
+ method_klass = rb_cCastOffSingletonClass;
130
+ }
117
131
  }
118
132
 
119
- klass = rb_class_of(val);
133
+ if (!st_lookup(sampling_table, (st_data_t)class_method_p, (st_data_t*)&mtblval)) {
134
+ mtblval = rb_hash_new();
135
+ st_insert(sampling_table, (st_data_t)class_method_p, (st_data_t)mtblval);
136
+ }
137
+ mtbl = RHASH_TBL(mtblval);
120
138
 
121
- if (!st_lookup(sampling_table, (st_data_t)method_klass, (st_data_t*)&method_id_hashval)) {
139
+ if (!st_lookup(mtbl, (st_data_t)method_klass, (st_data_t*)&method_id_hashval)) {
122
140
  method_id_hashval = rb_hash_new();
123
- st_insert(sampling_table, (st_data_t)method_klass, (st_data_t)method_id_hashval);
141
+ st_insert(mtbl, (st_data_t)method_klass, (st_data_t)method_id_hashval);
124
142
  }
125
143
  method_id_hash = RHASH_TBL(method_id_hashval);
126
144
  if (!st_lookup(method_id_hash, (st_data_t)method_id, (st_data_t*)&hashval)) {
@@ -129,12 +147,18 @@ static void __sampling_poscall(VALUE val, VALUE method_klass, VALUE method_id)
129
147
  }
130
148
  hash = RHASH_TBL(hashval);
131
149
 
150
+ klass = rb_class_of(val);
132
151
  if (FL_TEST(klass, FL_SINGLETON)) {
133
- klass = rb_cCastOffSingletonClass;
152
+ if (rb_obj_class(val) == rb_cClass) {
153
+ klass = val;
154
+ singleton_class_obj_p = Qtrue;
155
+ } else {
156
+ klass = rb_cCastOffSingletonClass;
157
+ }
134
158
  }
135
159
 
136
160
  if (!st_lookup(hash, (st_data_t)klass, 0)) {
137
- st_insert(hash, (st_data_t)klass, (st_data_t)Qtrue);
161
+ st_insert(hash, (st_data_t)klass, (st_data_t)singleton_class_obj_p);
138
162
  }
139
163
 
140
164
  return;
@@ -385,6 +409,10 @@ static inline int empty_method_table_p(VALUE klass)
385
409
  <%= func.gsub(/<CLASS_CHECK_FUNCTION_NAME>/, name) %>
386
410
  %end
387
411
 
412
+ %@recompilation_functions.each do |(func, name)|
413
+ <%= func.gsub(/<RECOMPILATION_FUNCTION_NAME>/, name) %>
414
+ %end
415
+
388
416
  %if !inline_block?
389
417
  static inline void expand_dframe(rb_thread_t *th, long size, rb_iseq_t *iseq, int root_p)
390
418
  {
@@ -769,6 +797,7 @@ void Init_<%= signiture() %>(void)
769
797
  @declare_constants = {}
770
798
  @class_check_functions = {}
771
799
  @throw_exception_functions = {}
800
+ @recompilation_functions = {}
772
801
  @prefetch_constants = {}
773
802
  @ivar_index = {}
774
803
  @loopkey = {}
@@ -912,6 +941,15 @@ Source line is #{@root_iseq.source_line}.
912
941
  name
913
942
  end
914
943
 
944
+ def declare_recompilation_function(func)
945
+ unless name = @recompilation_functions[func]
946
+ idx = @recompilation_functions.size()
947
+ name = "recompilation_#{idx}"
948
+ @recompilation_functions[func] = name
949
+ end
950
+ name
951
+ end
952
+
915
953
  def prefetch_constant(var, path, singleton_p)
916
954
  if @prefetch_constants[var]
917
955
  bug() unless @prefetch_constants[var] == [path, singleton_p]
@@ -546,26 +546,35 @@ Currently, CastOff cannot compile method which source file is not exist.
546
546
 
547
547
  def parse_sampling_table(sampling_table)
548
548
  reciever_result = {}
549
- return_value_result = {}
549
+ return_value_result = {:instance_methods => {}, :singleton_methods => {}}
550
550
  sampling_table.each do |(key0, val0)|
551
551
  case key0
552
552
  when Symbol
553
553
  bug() unless val0.is_a?(Hash)
554
- reciever_result[key0] = val0.keys
555
- when Class
554
+ reciever_result[key0] = val0.to_a
555
+ when TrueClass, FalseClass
556
+ mtbl = return_value_result[(key0 ? :singleton_methods : :instance_methods)]
557
+ bug() unless mtbl.is_a?(Hash)
556
558
  bug() unless val0.is_a?(Hash)
557
- newval = {}
558
- val0.each do |(key1, val1)|
559
- bug() unless key1.is_a?(Symbol)
560
- bug() unless val1.is_a?(Hash)
561
- newval[key1] = val1.keys
559
+ val0.each do |(klass, midtbl)|
560
+ bug() unless klass.is_a?(Class)
561
+ bug() unless midtbl.is_a?(Hash)
562
+ newval = {}
563
+ midtbl.each do |(key1, val1)|
564
+ bug() unless key1.is_a?(Symbol)
565
+ bug() unless val1.is_a?(Hash)
566
+ newval[key1] = val1.to_a
567
+ end
568
+ mtbl[klass] = newval
562
569
  end
563
- return_value_result[key0] = newval
564
570
  else
565
571
  bug("#{key0}, #{key0.class}")
566
572
  end
567
573
  end
568
- bug() unless (reciever_result.keys & return_value_result.keys).empty?
574
+ k0 = reciever_result.keys
575
+ k1 = return_value_result[:instance_methods].keys
576
+ k2 = return_value_result[:singleton_methods].keys
577
+ bug() unless (k0 & k1 & k2).empty?
569
578
  [reciever_result, return_value_result]
570
579
  end
571
580
 
@@ -603,8 +612,13 @@ Currently, CastOff cannot compile method which source file is not exist.
603
612
  reciever_result.each do |key0, val0|
604
613
  bug() unless key0.is_a?(Symbol)
605
614
  bug() unless val0.is_a?(Array)
606
- val0.each do |t|
607
- ary << [key0.to_s, t.to_s]
615
+ val0.each do |(klass, singleton_p)|
616
+ kstr = klass.to_s
617
+ if singleton_p
618
+ bug() unless klass.is_a?(Class)
619
+ kstr = "Class<#{kstr}>"
620
+ end
621
+ ary << [key0.to_s, kstr]
608
622
  end
609
623
  end
610
624
  suggestion.add_suggestion(msg, ["<Variable>", "<SamplingResultClass>"], ary)
@@ -612,11 +626,22 @@ Currently, CastOff cannot compile method which source file is not exist.
612
626
  if return_value_result.size > 0
613
627
  msg = "These are unresolved method return values sampling results."
614
628
  ary = []
615
- return_value_result.each do |key0, val0|
616
- bug() unless key0.is_a?(Class)
617
- bug() unless val0.is_a?(Hash)
618
- val0.each do |(mid, types)|
619
- types.each{|t| ary << ["#{key0}##{mid}", t.to_s]}
629
+ return_value_result.each do |sym, mtbl|
630
+ bug() unless sym == :singleton_methods || sym == :instance_methods
631
+ bug() unless mtbl.is_a?(Hash)
632
+ mtbl.each do |key0, val0|
633
+ bug() unless key0.is_a?(Class)
634
+ bug() unless val0.is_a?(Hash)
635
+ val0.each do |(mid, classes)|
636
+ classes.each do |(klass, singleton_p)|
637
+ kstr = klass.to_s
638
+ if singleton_p
639
+ bug() unless klass.is_a?(Class)
640
+ kstr = "Class<#{kstr}>"
641
+ end
642
+ ary << ["#{key0}#{sym == :singleton_methods ? '.' : '#'}#{mid}", kstr]
643
+ end
644
+ end
620
645
  end
621
646
  end
622
647
  suggestion.add_suggestion(msg, ["<Method>", "<SamplingResultClass>"], ary)
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.2.3
4
+ version: 0.3.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,14 +9,14 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-16 00:00:00.000000000 Z
12
+ date: 2011-11-18 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: ! 'CastOff is a performance improvement tool for Ruby1.9.3
15
15
 
16
16
  '
17
17
  email: shiba@rvm.jp
18
18
  executables:
19
- - CastOff
19
+ - cast_off
20
20
  extensions:
21
21
  - ext/cast_off/extconf.rb
22
22
  extra_rdoc_files:
@@ -95,7 +95,7 @@ files:
95
95
  - cast_off.gemspec
96
96
  - README
97
97
  - README.en
98
- - bin/CastOff
98
+ - bin/cast_off
99
99
  homepage: http://github.com/soba1104/CastOff
100
100
  licenses: []
101
101
  post_install_message: