cast_off 0.2.1 → 0.2.3
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 +40 -19
- data/README.en +0 -1
- data/bin/CastOff +7 -6
- data/cast_off.gemspec +2 -2
- data/ext/cast_off/cast_off.c.rb +118 -21
- data/ext/cast_off/depend +68 -39
- data/ext/cast_off/generated_c_include/iter_api.h +1 -1
- data/ext/cast_off/generated_c_include/vm_api.h +90 -7
- data/ext/cast_off/ruby_source/1.9.2/debug.h +36 -0
- data/ext/cast_off/ruby_source/1.9.2/eval_intern.h +232 -0
- data/ext/cast_off/ruby_source/1.9.2/gc.h +77 -0
- data/ext/cast_off/ruby_source/1.9.2/id.h +170 -0
- data/ext/cast_off/ruby_source/{insns.inc → 1.9.2/insns.inc} +0 -0
- data/ext/cast_off/ruby_source/{insns_info.inc → 1.9.2/insns_info.inc} +0 -0
- data/ext/cast_off/ruby_source/1.9.2/iseq.h +104 -0
- data/ext/cast_off/ruby_source/{manual_update.h → 1.9.2/manual_update.h} +0 -0
- data/ext/cast_off/ruby_source/1.9.2/method.h +103 -0
- data/ext/cast_off/ruby_source/1.9.2/node.h +483 -0
- data/ext/cast_off/ruby_source/1.9.2/thread_pthread.h +27 -0
- data/ext/cast_off/ruby_source/1.9.2/thread_win32.h +33 -0
- data/ext/cast_off/ruby_source/1.9.2/vm_core.h +707 -0
- data/ext/cast_off/ruby_source/1.9.2/vm_exec.h +184 -0
- data/ext/cast_off/ruby_source/1.9.2/vm_insnhelper.c +1721 -0
- data/ext/cast_off/ruby_source/1.9.2/vm_insnhelper.h +208 -0
- data/ext/cast_off/ruby_source/1.9.2/vm_opts.h +51 -0
- data/ext/cast_off/ruby_source/{atomic.h → 1.9.3/atomic.h} +0 -0
- data/ext/cast_off/ruby_source/{constant.h → 1.9.3/constant.h} +0 -0
- data/ext/cast_off/ruby_source/{debug.h → 1.9.3/debug.h} +0 -0
- data/ext/cast_off/ruby_source/{eval_intern.h → 1.9.3/eval_intern.h} +0 -0
- data/ext/cast_off/ruby_source/{gc.h → 1.9.3/gc.h} +0 -0
- data/ext/cast_off/ruby_source/{id.h → 1.9.3/id.h} +0 -0
- data/ext/cast_off/ruby_source/1.9.3/insns.inc +179 -0
- data/ext/cast_off/ruby_source/1.9.3/insns_info.inc +695 -0
- data/ext/cast_off/ruby_source/{internal.h → 1.9.3/internal.h} +0 -0
- data/ext/cast_off/ruby_source/{iseq.h → 1.9.3/iseq.h} +0 -0
- data/ext/cast_off/ruby_source/1.9.3/manual_update.h +135 -0
- data/ext/cast_off/ruby_source/{method.h → 1.9.3/method.h} +0 -0
- data/ext/cast_off/ruby_source/{node.h → 1.9.3/node.h} +0 -0
- data/ext/cast_off/ruby_source/{thread_pthread.h → 1.9.3/thread_pthread.h} +0 -0
- data/ext/cast_off/ruby_source/{thread_win32.h → 1.9.3/thread_win32.h} +0 -0
- data/ext/cast_off/ruby_source/{vm_core.h → 1.9.3/vm_core.h} +0 -0
- data/ext/cast_off/ruby_source/{vm_exec.h → 1.9.3/vm_exec.h} +0 -0
- data/ext/cast_off/ruby_source/{vm_insnhelper.c → 1.9.3/vm_insnhelper.c} +0 -0
- data/ext/cast_off/ruby_source/{vm_insnhelper.h → 1.9.3/vm_insnhelper.h} +0 -0
- data/ext/cast_off/ruby_source/{vm_opts.h → 1.9.3/vm_opts.h} +0 -0
- data/lib/cast_off/compile.rb +118 -68
- data/lib/cast_off/compile/basicblock.rb +3 -1
- data/lib/cast_off/compile/cfg.rb +0 -2
- data/lib/cast_off/compile/code_manager.rb +36 -7
- data/lib/cast_off/compile/configuration.rb +18 -13
- data/lib/cast_off/compile/dependency.rb +32 -11
- data/lib/cast_off/compile/information.rb +10 -6
- data/lib/cast_off/compile/instruction.rb +0 -11
- data/lib/cast_off/compile/ir/call_ir.rb +27 -5
- data/lib/cast_off/compile/ir/operand.rb +54 -34
- data/lib/cast_off/compile/ir/simple_ir.rb +6 -8
- data/lib/cast_off/compile/translator.rb +9 -0
- metadata +41 -25
- data/ext/cast_off/cast_off.h +0 -24
File without changes
|
File without changes
|
@@ -0,0 +1,135 @@
|
|
1
|
+
/* ----- string.c ----- */
|
2
|
+
#define STR_TMPLOCK FL_USER7
|
3
|
+
#define STR_NOEMBED FL_USER1
|
4
|
+
#define STR_SHARED FL_USER2 /* = ELTS_SHARED */
|
5
|
+
#define STR_ASSOC FL_USER3
|
6
|
+
#define STR_SHARED_P(s) FL_ALL((s), STR_NOEMBED|ELTS_SHARED)
|
7
|
+
#define STR_ASSOC_P(s) FL_ALL((s), STR_NOEMBED|STR_ASSOC)
|
8
|
+
#define STR_NOCAPA (STR_NOEMBED|ELTS_SHARED|STR_ASSOC)
|
9
|
+
#define STR_NOCAPA_P(s) (FL_TEST((s),STR_NOEMBED) && FL_ANY((s),ELTS_SHARED|STR_ASSOC))
|
10
|
+
|
11
|
+
/* ----- vm.c ----- */
|
12
|
+
static rb_control_frame_t *
|
13
|
+
vm_get_ruby_level_caller_cfp(rb_thread_t *th, rb_control_frame_t *cfp)
|
14
|
+
{
|
15
|
+
if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
|
16
|
+
return cfp;
|
17
|
+
}
|
18
|
+
|
19
|
+
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
|
20
|
+
|
21
|
+
while (!RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)) {
|
22
|
+
if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
|
23
|
+
return cfp;
|
24
|
+
}
|
25
|
+
|
26
|
+
if ((cfp->flag & VM_FRAME_FLAG_PASSED) == 0) {
|
27
|
+
break;
|
28
|
+
}
|
29
|
+
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
|
30
|
+
}
|
31
|
+
return 0;
|
32
|
+
}
|
33
|
+
|
34
|
+
static VALUE
|
35
|
+
make_localjump_error(const char *mesg, VALUE value, int reason)
|
36
|
+
{
|
37
|
+
extern VALUE rb_eLocalJumpError;
|
38
|
+
VALUE exc = rb_exc_new2(rb_eLocalJumpError, mesg);
|
39
|
+
ID id;
|
40
|
+
|
41
|
+
switch (reason) {
|
42
|
+
case TAG_BREAK:
|
43
|
+
CONST_ID(id, "break");
|
44
|
+
break;
|
45
|
+
case TAG_REDO:
|
46
|
+
CONST_ID(id, "redo");
|
47
|
+
break;
|
48
|
+
case TAG_RETRY:
|
49
|
+
CONST_ID(id, "retry");
|
50
|
+
break;
|
51
|
+
case TAG_NEXT:
|
52
|
+
CONST_ID(id, "next");
|
53
|
+
break;
|
54
|
+
case TAG_RETURN:
|
55
|
+
CONST_ID(id, "return");
|
56
|
+
break;
|
57
|
+
default:
|
58
|
+
CONST_ID(id, "noreason");
|
59
|
+
break;
|
60
|
+
}
|
61
|
+
rb_iv_set(exc, "@exit_value", value);
|
62
|
+
rb_iv_set(exc, "@reason", ID2SYM(id));
|
63
|
+
return exc;
|
64
|
+
}
|
65
|
+
|
66
|
+
void
|
67
|
+
rb_vm_localjump_error(const char *mesg, VALUE value, int reason)
|
68
|
+
{
|
69
|
+
VALUE exc = make_localjump_error(mesg, value, reason);
|
70
|
+
rb_exc_raise(exc);
|
71
|
+
}
|
72
|
+
|
73
|
+
/* ----- vm_method.c ----- */
|
74
|
+
static rb_method_entry_t*
|
75
|
+
search_method(VALUE klass, ID id)
|
76
|
+
{
|
77
|
+
st_data_t body;
|
78
|
+
if (!klass) {
|
79
|
+
return 0;
|
80
|
+
}
|
81
|
+
|
82
|
+
while (!st_lookup(RCLASS_M_TBL(klass), id, &body)) {
|
83
|
+
klass = RCLASS_SUPER(klass);
|
84
|
+
if (!klass) {
|
85
|
+
return 0;
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
return (rb_method_entry_t *)body;
|
90
|
+
}
|
91
|
+
|
92
|
+
static int
|
93
|
+
rb_method_definition_eq(const rb_method_definition_t *d1, const rb_method_definition_t *d2)
|
94
|
+
{
|
95
|
+
if (d1 == d2) return 1;
|
96
|
+
if (!d1 || !d2) return 0;
|
97
|
+
if (d1->type != d2->type) {
|
98
|
+
return 0;
|
99
|
+
}
|
100
|
+
switch (d1->type) {
|
101
|
+
case VM_METHOD_TYPE_ISEQ:
|
102
|
+
return d1->body.iseq == d2->body.iseq;
|
103
|
+
case VM_METHOD_TYPE_CFUNC:
|
104
|
+
return
|
105
|
+
d1->body.cfunc.func == d2->body.cfunc.func &&
|
106
|
+
d1->body.cfunc.argc == d2->body.cfunc.argc;
|
107
|
+
case VM_METHOD_TYPE_ATTRSET:
|
108
|
+
case VM_METHOD_TYPE_IVAR:
|
109
|
+
return d1->body.attr.id == d2->body.attr.id;
|
110
|
+
case VM_METHOD_TYPE_BMETHOD:
|
111
|
+
return RTEST(rb_equal(d1->body.proc, d2->body.proc));
|
112
|
+
case VM_METHOD_TYPE_MISSING:
|
113
|
+
return d1->original_id == d2->original_id;
|
114
|
+
case VM_METHOD_TYPE_ZSUPER:
|
115
|
+
case VM_METHOD_TYPE_NOTIMPLEMENTED:
|
116
|
+
case VM_METHOD_TYPE_UNDEF:
|
117
|
+
return 1;
|
118
|
+
case VM_METHOD_TYPE_OPTIMIZED:
|
119
|
+
return d1->body.optimize_type == d2->body.optimize_type;
|
120
|
+
default:
|
121
|
+
rb_bug("rb_method_entry_eq: unsupported method type (%d)\n", d1->type);
|
122
|
+
return 0;
|
123
|
+
}
|
124
|
+
}
|
125
|
+
|
126
|
+
int
|
127
|
+
rb_method_entry_eq(const rb_method_entry_t *m1, const rb_method_entry_t *m2)
|
128
|
+
{
|
129
|
+
return rb_method_definition_eq(m1->def, m2->def);
|
130
|
+
}
|
131
|
+
|
132
|
+
/* ----- set noinline ----- */
|
133
|
+
NOINLINE(static rb_control_frame_t *vm_get_ruby_level_caller_cfp(rb_thread_t *th, rb_control_frame_t *cfp));
|
134
|
+
NOINLINE(static rb_method_entry_t* search_method(VALUE klass, ID id));
|
135
|
+
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/lib/cast_off/compile.rb
CHANGED
@@ -32,9 +32,10 @@ module CastOff
|
|
32
32
|
@@autoload_proc.call()
|
33
33
|
return true
|
34
34
|
end
|
35
|
-
return true if load()
|
36
35
|
|
37
|
-
|
36
|
+
# Marshal.load で定数を参照したときに、クラス定義が走る可能性があるので、
|
37
|
+
# @@autoload_proc を定義する前に、Marshal.load を呼び出しておく。
|
38
|
+
compiled = CodeManager.load_autocompiled()
|
38
39
|
@@autoload_proc = lambda {
|
39
40
|
compiled = CodeManager.load_autocompiled() unless compiled
|
40
41
|
return false unless compiled
|
@@ -42,7 +43,8 @@ module CastOff
|
|
42
43
|
hook_class_definition_end(nil) if fin
|
43
44
|
fin
|
44
45
|
}
|
45
|
-
hook_class_definition_end(@@autoload_proc)
|
46
|
+
hook_class_definition_end(@@autoload_proc) if RUBY_VERSION == "1.9.3"
|
47
|
+
@@autoload_proc.call()
|
46
48
|
true
|
47
49
|
end
|
48
50
|
|
@@ -61,7 +63,15 @@ module CastOff
|
|
61
63
|
end
|
62
64
|
|
63
65
|
@@autocompile_proc = nil
|
64
|
-
|
66
|
+
case RUBY_VERSION
|
67
|
+
when "1.9.3"
|
68
|
+
@@compile_auto_incremental = true
|
69
|
+
when "1.9.2"
|
70
|
+
@@compile_auto_incremental = false
|
71
|
+
else
|
72
|
+
bug()
|
73
|
+
end
|
74
|
+
|
65
75
|
def autocompile()
|
66
76
|
return false if autoload_running?
|
67
77
|
return true if autocompile_running?
|
@@ -145,24 +155,26 @@ module CastOff
|
|
145
155
|
end
|
146
156
|
|
147
157
|
def compile(target, mid, bind_or_typemap = nil, typemap = nil)
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
158
|
+
execute_no_hook() do
|
159
|
+
case target
|
160
|
+
when Class, Module
|
161
|
+
# ok
|
162
|
+
else
|
163
|
+
raise(ArgumentError.new("first argument should be Class or Module"))
|
164
|
+
end
|
165
|
+
mid, bind, typemap = parse_arguments(mid, bind_or_typemap, typemap)
|
166
|
+
t = override_target(target, mid)
|
167
|
+
iseq = @@original_instance_method_iseq[[t, mid]] || get_iseq(target, mid, false)
|
168
|
+
manager, configuration, suggestion = compile_iseq(iseq, mid, typemap, false, bind)
|
169
|
+
manager.compilation_target_is_a(t, mid, false)
|
170
|
+
set_direct_call(target, mid, target.instance_of?(Class) ? :class : :module, manager, configuration)
|
171
|
+
load_binary(manager, configuration, suggestion, iseq, bind)
|
172
|
+
t = override_target(target, mid)
|
173
|
+
dlog("override target of #{target}##{mid} is #{t}")
|
174
|
+
__send__("register_method_#{manager.signiture}", t)
|
175
|
+
@@original_instance_method_iseq[[t, mid]] = iseq
|
176
|
+
@@manager_table[manager.signiture] = manager
|
153
177
|
end
|
154
|
-
mid, bind, typemap = parse_arguments(mid, bind_or_typemap, typemap)
|
155
|
-
t = override_target(target, mid)
|
156
|
-
iseq = @@original_instance_method_iseq[[t, mid]] || get_iseq(target, mid, false)
|
157
|
-
manager, configuration, suggestion = compile_iseq(iseq, mid, typemap, false, bind)
|
158
|
-
manager.compilation_target_is_a(t, mid, false)
|
159
|
-
set_direct_call(target, mid, target.instance_of?(Class) ? :class : :module, manager, configuration)
|
160
|
-
load_binary(manager, configuration, suggestion, iseq, bind)
|
161
|
-
t = override_target(target, mid)
|
162
|
-
dlog("override target of #{target}##{mid} is #{t}")
|
163
|
-
__send__("register_method_#{manager.signiture}", t)
|
164
|
-
@@original_instance_method_iseq[[t, mid]] = iseq
|
165
|
-
@@manager_table[manager.signiture] = manager
|
166
178
|
true
|
167
179
|
end
|
168
180
|
|
@@ -172,15 +184,17 @@ module CastOff
|
|
172
184
|
end
|
173
185
|
|
174
186
|
def compile_singleton_method(obj, mid, bind_or_typemap = nil, typemap = nil)
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
187
|
+
execute_no_hook() do
|
188
|
+
mid, bind, typemap = parse_arguments(mid, bind_or_typemap, typemap)
|
189
|
+
iseq = @@original_singleton_method_iseq[[obj, mid]] || get_iseq(obj, mid, true)
|
190
|
+
manager, configuration, suggestion = compile_iseq(iseq, mid, typemap, false, bind)
|
191
|
+
manager.compilation_target_is_a(obj, mid, true)
|
192
|
+
set_direct_call(obj, mid, :singleton, manager, configuration)
|
193
|
+
load_binary(manager, configuration, suggestion, iseq, bind)
|
194
|
+
__send__("register_singleton_method_#{manager.signiture}", obj)
|
195
|
+
@@original_singleton_method_iseq[[obj, mid]] = iseq
|
196
|
+
@@manager_table[manager.signiture] = manager
|
197
|
+
end
|
184
198
|
true
|
185
199
|
end
|
186
200
|
|
@@ -190,25 +204,46 @@ module CastOff
|
|
190
204
|
iseq = get_iseq_from_block(block)
|
191
205
|
key = iseq.__id__
|
192
206
|
if !@@loaded_binary[key]
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
207
|
+
execute_no_hook() do
|
208
|
+
bind = block.binding
|
209
|
+
manager, configuration, suggestion = compile_iseq(iseq, nil, typemap, false, bind)
|
210
|
+
load_binary(manager, configuration, suggestion, iseq, bind)
|
211
|
+
@@loaded_binary[key] = manager.signiture
|
212
|
+
end
|
197
213
|
end
|
198
214
|
sign = @@loaded_binary[key]
|
199
215
|
recv = get_caller()
|
200
216
|
__send__(sign, recv)
|
201
217
|
end
|
202
218
|
|
219
|
+
def autocompile_running?
|
220
|
+
!!@@autocompile_proc
|
221
|
+
end
|
222
|
+
|
223
|
+
def autoload_running?
|
224
|
+
!!@@autoload_proc
|
225
|
+
end
|
226
|
+
|
227
|
+
def compiler_running?
|
228
|
+
!!Thread.current[COMPILER_RUNNING_KEY]
|
229
|
+
end
|
230
|
+
|
203
231
|
private
|
204
232
|
|
233
|
+
COMPILER_RUNNING_KEY = :CastOffCompilerRunning
|
234
|
+
def compiler_running(bool)
|
235
|
+
Thread.current[COMPILER_RUNNING_KEY] = bool
|
236
|
+
end
|
237
|
+
|
205
238
|
def execute_no_hook()
|
206
239
|
bug() unless block_given?
|
207
240
|
begin
|
241
|
+
compiler_running(true)
|
208
242
|
hook_m = hook_method_invocation(nil)
|
209
243
|
hook_c = hook_class_definition_end(nil)
|
210
244
|
yield
|
211
245
|
ensure
|
246
|
+
compiler_running(false)
|
212
247
|
if hook_m
|
213
248
|
bug() unless autocompile_running?
|
214
249
|
hook_method_invocation(@@autocompile_proc)
|
@@ -231,9 +266,7 @@ Currently, CastOff cannot compile method which source file is not exist.
|
|
231
266
|
suggestion = Suggestion.new(iseq, @@suggestion_io)
|
232
267
|
configuration = nil
|
233
268
|
manager.do_atomically() do
|
234
|
-
|
235
|
-
configuration = __compile(iseq, manager, typemap || {}, mid, is_proc, bind, suggestion)
|
236
|
-
end
|
269
|
+
configuration = __compile(iseq, manager, typemap || {}, mid, is_proc, bind, suggestion)
|
237
270
|
end
|
238
271
|
bug() unless configuration.instance_of?(Configuration)
|
239
272
|
[manager, configuration, suggestion]
|
@@ -295,8 +328,9 @@ Currently, CastOff cannot compile method which source file is not exist.
|
|
295
328
|
manager.version_up()
|
296
329
|
begin
|
297
330
|
__send__(singleton ? 'compile_singleton_method' : 'compile', target, mid, ann)
|
331
|
+
vlog("re-compilation success: #{target}#{singleton ? '.' : '#'}#{mid}")
|
298
332
|
rescue => e
|
299
|
-
vlog("re-compilation failed: #{target}#{singleton ? '.' : '#'}#{mid}")
|
333
|
+
vlog("re-compilation failed: #{target}#{singleton ? '.' : '#'}#{mid} => #{e}")
|
300
334
|
end
|
301
335
|
true
|
302
336
|
end
|
@@ -304,7 +338,7 @@ Currently, CastOff cannot compile method which source file is not exist.
|
|
304
338
|
class ReCompilation < StandardError; end
|
305
339
|
|
306
340
|
def __compile(iseq, manager, annotation, mid, is_proc, bind, suggestion)
|
307
|
-
if
|
341
|
+
if reuse_compiled_code? && !manager.target_file_updated?
|
308
342
|
# already compiled
|
309
343
|
if CastOff.development? || !CastOff.skip_configuration_check? || manager.last_configuration_enabled_development?
|
310
344
|
conf = Configuration.new(annotation, bind)
|
@@ -370,33 +404,46 @@ Currently, CastOff cannot compile method which source file is not exist.
|
|
370
404
|
conf
|
371
405
|
end
|
372
406
|
|
407
|
+
@@skipped = []
|
373
408
|
def __load(compiled)
|
374
409
|
begin
|
375
|
-
compiled.dup.each do |entry|
|
410
|
+
(@@skipped + compiled.dup).each do |entry|
|
376
411
|
klass, mid, singleton, file, line, bind = entry
|
377
412
|
if @@blacklist.include?(mid)
|
378
413
|
compiled.delete(entry)
|
379
414
|
next
|
380
415
|
end
|
381
416
|
bind = bind.bind if bind
|
382
|
-
|
417
|
+
skip = false
|
383
418
|
if singleton
|
384
419
|
iseq = @@original_singleton_method_iseq[[klass, mid]] || get_iseq(klass, mid, true)
|
385
420
|
else
|
386
|
-
|
387
|
-
|
421
|
+
begin
|
422
|
+
t = override_target(klass, mid)
|
423
|
+
iseq = @@original_instance_method_iseq[[t, mid]] || get_iseq(klass, mid, false)
|
424
|
+
rescue CompileError, UnsupportedError
|
425
|
+
@@skipped |= [entry]
|
426
|
+
dlog("skip: entry = #{entry}")
|
427
|
+
skip = true
|
428
|
+
end
|
388
429
|
end
|
389
|
-
f, l = *iseq.to_a.slice(7, 2)
|
390
|
-
if f == file && l == line
|
430
|
+
f, l = *iseq.to_a.slice(7, 2) unless skip
|
431
|
+
if !skip && f == file && l == line
|
391
432
|
begin
|
433
|
+
@@skipped.delete(entry)
|
392
434
|
if singleton
|
393
435
|
CastOff.compile_singleton_method(klass, mid, bind)
|
394
436
|
else
|
395
437
|
CastOff.compile(klass, mid, bind)
|
396
438
|
end
|
397
439
|
vlog("load #{klass}##{mid}")
|
398
|
-
rescue
|
399
|
-
|
440
|
+
rescue ArgumentError => e
|
441
|
+
# dependency の Marshal.load に失敗
|
442
|
+
vlog("skip: entry = #{entry[0]}#{entry[2] ? '.' : '#'}#{entry[1]}, #{e}")
|
443
|
+
CodeManager.delete_from_compiled(entry)
|
444
|
+
rescue UnsupportedError => e
|
445
|
+
vlog("unsupported #{klass}##{mid} => #{e}")
|
446
|
+
CodeManager.delete_from_compiled(entry)
|
400
447
|
end
|
401
448
|
else
|
402
449
|
dlog("iseq.filepath = #{f}, file = #{file}\niseq.line = #{l}, line = #{line}")
|
@@ -404,7 +451,7 @@ Currently, CastOff cannot compile method which source file is not exist.
|
|
404
451
|
compiled.delete(entry)
|
405
452
|
end
|
406
453
|
if compiled.empty?
|
407
|
-
vlog("---------- load finish ----------")
|
454
|
+
vlog("---------- load finish ----------") if @@skipped.empty?
|
408
455
|
true
|
409
456
|
else
|
410
457
|
false
|
@@ -415,12 +462,16 @@ Currently, CastOff cannot compile method which source file is not exist.
|
|
415
462
|
end
|
416
463
|
end
|
417
464
|
|
418
|
-
|
419
|
-
|
465
|
+
s = class << BasicObject
|
466
|
+
self
|
420
467
|
end
|
421
|
-
|
422
|
-
|
423
|
-
|
468
|
+
continue_load = RUBY_VERSION != "1.9.3"
|
469
|
+
s.class_eval do
|
470
|
+
define_method(:method_added) do |mid|
|
471
|
+
if CastOff.autoload_running? && (!@@skipped.empty? || continue_load) && !CastOff.compiler_running?
|
472
|
+
continue_load &= !@@autoload_proc.call()
|
473
|
+
end
|
474
|
+
end
|
424
475
|
end
|
425
476
|
|
426
477
|
def __autocompile(klass, mid, bind_table, location_table, index)
|
@@ -428,6 +479,7 @@ Currently, CastOff cannot compile method which source file is not exist.
|
|
428
479
|
return nil if klass.name =~ /CastOff/ # ここで弾いておかないと、__compile の require で __load が走る。
|
429
480
|
# Namespace のほうはあらかじめ require しておくことで回避。
|
430
481
|
# Namespace 以外は CastOff を含むので問題無し。
|
482
|
+
return nil if mid == :method_added || mid == :singleton_method_added
|
431
483
|
if klass.instance_methods(false).include?(mid) || klass.private_instance_methods(false).include?(mid)
|
432
484
|
singleton = false
|
433
485
|
else
|
@@ -529,7 +581,7 @@ Currently, CastOff cannot compile method which source file is not exist.
|
|
529
581
|
unless base_configuration
|
530
582
|
last = manager.load_last_configuration()
|
531
583
|
bind = last ? (last.bind ? last.bind.bind : nil) : nil
|
532
|
-
|
584
|
+
base_configuration = Configuration.new({}, bind)
|
533
585
|
end
|
534
586
|
bug() unless base_configuration.instance_of?(Configuration)
|
535
587
|
update_p = update_configuration(base_configuration, reciever_result, return_value_result)
|
@@ -604,20 +656,18 @@ Currently, CastOff cannot compile method which source file is not exist.
|
|
604
656
|
end
|
605
657
|
|
606
658
|
def load_binary(manager, configuration, suggestion, iseq, bind)
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
__send__("prefetch_constants_#{sign}", bind) if bind
|
620
|
-
end
|
659
|
+
so = manager.compiled_binary
|
660
|
+
sign = manager.signiture
|
661
|
+
bug("#{so} is not exist") unless File.exist?(so)
|
662
|
+
load_compiled_file(so)
|
663
|
+
function_pointer_initializer = "initialize_fptr_#{sign}".intern
|
664
|
+
hook_method_override(manager, configuration, function_pointer_initializer)
|
665
|
+
__send__("register_iseq_#{sign}", iseq)
|
666
|
+
__send__("register_ifunc_#{sign}")
|
667
|
+
set_sampling_table(suggestion, manager, configuration)
|
668
|
+
suggestion.dump_at_exit()
|
669
|
+
__send__(function_pointer_initializer)
|
670
|
+
__send__("prefetch_constants_#{sign}", bind) if bind
|
621
671
|
end
|
622
672
|
|
623
673
|
def capture_instruction()
|