aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gc.c3
-rw-r--r--insns.def116
-rw-r--r--tool/ruby_vm/views/_insn_entry.erb8
-rw-r--r--tool/ruby_vm/views/_mjit_compile_insn_body.erb2
-rw-r--r--vm_insnhelper.h18
5 files changed, 44 insertions, 103 deletions
diff --git a/gc.c b/gc.c
index ba1bbbfe08..c9965e02f4 100644
--- a/gc.c
+++ b/gc.c
@@ -1807,7 +1807,10 @@ rb_objspace_set_event_hook(const rb_event_flag_t event)
static void
gc_event_hook_body(rb_execution_context_t *ec, rb_objspace_t *objspace, const rb_event_flag_t event, VALUE data)
{
+ /* increment PC because source line is calculated with PC-1 */
+ const VALUE *pc = ec->cfp->pc++;
EXEC_EVENT_HOOK(ec, event, ec->cfp->self, 0, 0, 0, data);
+ ec->cfp->pc = pc;
}
#define gc_event_hook_available_p(objspace) ((objspace)->flags.has_hook)
diff --git a/insns.def b/insns.def
index df0cd26517..39c61a7f41 100644
--- a/insns.def
+++ b/insns.def
@@ -761,10 +761,7 @@ opt_str_freeze
if (val == Qundef) {
PUSH(rb_str_resurrect(str));
-#ifndef MJIT_HEADER
- ADD_PC(-WIDTH_OF_opt_send_without_block);
-#endif
- DISPATCH_ORIGINAL_INSN(opt_send_without_block);
+ CALL_SIMPLE_METHOD();
}
}
@@ -778,10 +775,7 @@ opt_str_uminus
if (val == Qundef) {
PUSH(rb_str_resurrect(str));
-#ifndef MJIT_HEADER
- ADD_PC(-WIDTH_OF_opt_send_without_block);
-#endif
- DISPATCH_ORIGINAL_INSN(opt_send_without_block);
+ CALL_SIMPLE_METHOD();
}
}
@@ -1058,10 +1052,7 @@ opt_plus
val = vm_opt_plus(recv, obj);
if (val == Qundef) {
-#ifndef MJIT_HEADER
- ADD_PC(-WIDTH_OF_opt_send_without_block);
-#endif
- DISPATCH_ORIGINAL_INSN(opt_send_without_block);
+ CALL_SIMPLE_METHOD();
}
}
@@ -1075,10 +1066,7 @@ opt_minus
val = vm_opt_minus(recv, obj);
if (val == Qundef) {
-#ifndef MJIT_HEADER
- ADD_PC(-WIDTH_OF_opt_send_without_block);
-#endif
- DISPATCH_ORIGINAL_INSN(opt_send_without_block);
+ CALL_SIMPLE_METHOD();
}
}
@@ -1092,10 +1080,7 @@ opt_mult
val = vm_opt_mult(recv, obj);
if (val == Qundef) {
-#ifndef MJIT_HEADER
- ADD_PC(-WIDTH_OF_opt_send_without_block);
-#endif
- DISPATCH_ORIGINAL_INSN(opt_send_without_block);
+ CALL_SIMPLE_METHOD();
}
}
@@ -1109,10 +1094,7 @@ opt_div
val = vm_opt_div(recv, obj);
if (val == Qundef) {
-#ifndef MJIT_HEADER
- ADD_PC(-WIDTH_OF_opt_send_without_block);
-#endif
- DISPATCH_ORIGINAL_INSN(opt_send_without_block);
+ CALL_SIMPLE_METHOD();
}
}
@@ -1126,10 +1108,7 @@ opt_mod
val = vm_opt_mod(recv, obj);
if (val == Qundef) {
-#ifndef MJIT_HEADER
- ADD_PC(-WIDTH_OF_opt_send_without_block);
-#endif
- DISPATCH_ORIGINAL_INSN(opt_send_without_block);
+ CALL_SIMPLE_METHOD();
}
}
@@ -1147,10 +1126,7 @@ opt_eq
val = opt_eq_func(recv, obj, ci, cc);
if (val == Qundef) {
-#ifndef MJIT_HEADER
- ADD_PC(-WIDTH_OF_opt_send_without_block);
-#endif
- DISPATCH_ORIGINAL_INSN(opt_send_without_block);
+ CALL_SIMPLE_METHOD();
}
}
@@ -1166,10 +1142,7 @@ opt_neq
val = vm_opt_neq(ci, cc, ci_eq, cc_eq, recv, obj);
if (val == Qundef) {
-#ifndef MJIT_HEADER
- ADD_PC(-WIDTH_OF_opt_send_without_block);
-#endif
- DISPATCH_ORIGINAL_INSN(opt_send_without_block);
+ CALL_SIMPLE_METHOD();
}
}
@@ -1183,10 +1156,7 @@ opt_lt
val = vm_opt_lt(recv, obj);
if (val == Qundef) {
-#ifndef MJIT_HEADER
- ADD_PC(-WIDTH_OF_opt_send_without_block);
-#endif
- DISPATCH_ORIGINAL_INSN(opt_send_without_block);
+ CALL_SIMPLE_METHOD();
}
}
@@ -1200,10 +1170,7 @@ opt_le
val = vm_opt_le(recv, obj);
if (val == Qundef) {
-#ifndef MJIT_HEADER
- ADD_PC(-WIDTH_OF_opt_send_without_block);
-#endif
- DISPATCH_ORIGINAL_INSN(opt_send_without_block);
+ CALL_SIMPLE_METHOD();
}
}
@@ -1217,10 +1184,7 @@ opt_gt
val = vm_opt_gt(recv, obj);
if (val == Qundef) {
-#ifndef MJIT_HEADER
- ADD_PC(-WIDTH_OF_opt_send_without_block);
-#endif
- DISPATCH_ORIGINAL_INSN(opt_send_without_block);
+ CALL_SIMPLE_METHOD();
}
}
@@ -1234,10 +1198,7 @@ opt_ge
val = vm_opt_ge(recv, obj);
if (val == Qundef) {
-#ifndef MJIT_HEADER
- ADD_PC(-WIDTH_OF_opt_send_without_block);
-#endif
- DISPATCH_ORIGINAL_INSN(opt_send_without_block);
+ CALL_SIMPLE_METHOD();
}
}
@@ -1251,10 +1212,7 @@ opt_ltlt
val = vm_opt_ltlt(recv, obj);
if (val == Qundef) {
-#ifndef MJIT_HEADER
- ADD_PC(-WIDTH_OF_opt_send_without_block);
-#endif
- DISPATCH_ORIGINAL_INSN(opt_send_without_block);
+ CALL_SIMPLE_METHOD();
}
}
@@ -1273,10 +1231,7 @@ opt_aref
val = vm_opt_aref(recv, obj);
if (val == Qundef) {
-#ifndef MJIT_HEADER
- ADD_PC(-WIDTH_OF_opt_send_without_block);
-#endif
- DISPATCH_ORIGINAL_INSN(opt_send_without_block);
+ CALL_SIMPLE_METHOD();
}
}
@@ -1293,10 +1248,7 @@ opt_aset
val = vm_opt_aset(recv, obj, set);
if (val == Qundef) {
-#ifndef MJIT_HEADER
- ADD_PC(-WIDTH_OF_opt_send_without_block);
-#endif
- DISPATCH_ORIGINAL_INSN(opt_send_without_block);
+ CALL_SIMPLE_METHOD();
}
}
@@ -1318,9 +1270,8 @@ opt_aset_with
#ifndef MJIT_HEADER
TOPN(0) = rb_str_resurrect(key);
PUSH(val);
- ADD_PC(-WIDTH_OF_opt_send_without_block);
#endif
- DISPATCH_ORIGINAL_INSN(opt_send_without_block);
+ CALL_SIMPLE_METHOD();
}
}
@@ -1338,9 +1289,8 @@ opt_aref_with
if (val == Qundef) {
#ifndef MJIT_HEADER
PUSH(rb_str_resurrect(key));
- ADD_PC(-WIDTH_OF_opt_send_without_block);
#endif
- DISPATCH_ORIGINAL_INSN(opt_send_without_block);
+ CALL_SIMPLE_METHOD();
}
}
@@ -1354,10 +1304,7 @@ opt_length
val = vm_opt_length(recv, BOP_LENGTH);
if (val == Qundef) {
-#ifndef MJIT_HEADER
- ADD_PC(-WIDTH_OF_opt_send_without_block);
-#endif
- DISPATCH_ORIGINAL_INSN(opt_send_without_block);
+ CALL_SIMPLE_METHOD();
}
}
@@ -1371,10 +1318,7 @@ opt_size
val = vm_opt_length(recv, BOP_SIZE);
if (val == Qundef) {
-#ifndef MJIT_HEADER
- ADD_PC(-WIDTH_OF_opt_send_without_block);
-#endif
- DISPATCH_ORIGINAL_INSN(opt_send_without_block);
+ CALL_SIMPLE_METHOD();
}
}
@@ -1388,10 +1332,7 @@ opt_empty_p
val = vm_opt_empty_p(recv);
if (val == Qundef) {
-#ifndef MJIT_HEADER
- ADD_PC(-WIDTH_OF_opt_send_without_block);
-#endif
- DISPATCH_ORIGINAL_INSN(opt_send_without_block);
+ CALL_SIMPLE_METHOD();
}
}
@@ -1405,10 +1346,7 @@ opt_succ
val = vm_opt_succ(recv);
if (val == Qundef) {
-#ifndef MJIT_HEADER
- ADD_PC(-WIDTH_OF_opt_send_without_block);
-#endif
- DISPATCH_ORIGINAL_INSN(opt_send_without_block);
+ CALL_SIMPLE_METHOD();
}
}
@@ -1422,10 +1360,7 @@ opt_not
val = vm_opt_not(ci, cc, recv);
if (val == Qundef) {
-#ifndef MJIT_HEADER
- ADD_PC(-WIDTH_OF_opt_send_without_block);
-#endif
- DISPATCH_ORIGINAL_INSN(opt_send_without_block);
+ CALL_SIMPLE_METHOD();
}
}
@@ -1450,10 +1385,7 @@ opt_regexpmatch2
val = vm_opt_regexpmatch2(obj2, obj1);
if (val == Qundef) {
-#ifndef MJIT_HEADER
- ADD_PC(-WIDTH_OF_opt_send_without_block);
-#endif
- DISPATCH_ORIGINAL_INSN(opt_send_without_block);
+ CALL_SIMPLE_METHOD();
}
}
diff --git a/tool/ruby_vm/views/_insn_entry.erb b/tool/ruby_vm/views/_insn_entry.erb
index d3c7b63582..05299d1006 100644
--- a/tool/ruby_vm/views/_insn_entry.erb
+++ b/tool/ruby_vm/views/_insn_entry.erb
@@ -13,11 +13,12 @@ INSN_ENTRY(<%= insn.name %>)
%# NAME_OF_CURRENT_INSN is used in vm_exec.h
# define NAME_OF_CURRENT_INSN <%= insn.name %>
# define INSN_ATTR(x) <%= insn.call_attribute(' ## x ## ') %>
+ bool leaf;
+ MAYBE_UNUSED(VALUE *) canary;
% unless insn.declarations.empty?
<%= insn.declarations.join(";\n ") %>;
% end
-<%= insn.handle_canary "DECLARE_CANARY" -%>
START_OF_ORIGINAL_INSN(<%= insn.name %>);
% insn.preamble.each do |konst|
<%= render_c_expr konst -%>
@@ -30,7 +31,7 @@ INSN_ENTRY(<%= insn.name %>)
<%= pop[:name] %> = <%= insn.cast_from_VALUE pop, "TOPN(#{i})"%>;
% end
DEBUG_ENTER_INSN(INSN_ATTR(name));
- ADD_PC(INSN_ATTR(width));
+ if (! (leaf = INSN_ATTR(leaf))) ADD_PC(INSN_ATTR(width));
% if insn.handles_sp?
POPN(INSN_ATTR(popn));
% end
@@ -47,11 +48,12 @@ INSN_ENTRY(<%= insn.name %>)
PUSH(<%= insn.cast_to_VALUE ret %>);
% end
% else
- ADJ_SP(INSN_ATTR(sp_inc));
+ INC_SP(INSN_ATTR(sp_inc));
% insn.rets.reverse_each.with_index do |ret, i|
TOPN(<%= i %>) = <%= insn.cast_to_VALUE ret %>;
% end
% end
+ if (leaf) ADD_PC(INSN_ATTR(width));
END_INSN(<%= insn.name %>);
# undef INSN_ATTR
# undef NAME_OF_CURRENT_INSN
diff --git a/tool/ruby_vm/views/_mjit_compile_insn_body.erb b/tool/ruby_vm/views/_mjit_compile_insn_body.erb
index f054059734..3b14c272b1 100644
--- a/tool/ruby_vm/views/_mjit_compile_insn_body.erb
+++ b/tool/ruby_vm/views/_mjit_compile_insn_body.erb
@@ -67,7 +67,7 @@
next_pos = pos + insn_len(insn) + (unsigned int)<%= dest %>;
fprintf(f, " goto label_%d;\n", next_pos);
% end
-% when /\A\s+DISPATCH_ORIGINAL_INSN\([^)]+\);\s+\z/
+% when /\A\s+CALL_SIMPLE_METHOD\(\);\s+\z/
% # For `opt_xxx`'s fallbacks.
if (status->local_stack_p) {
fprintf(f, " reg_cfp->sp = (VALUE *)reg_cfp->bp + %d;\n", b->stack_size + 1);
diff --git a/vm_insnhelper.h b/vm_insnhelper.h
index 6c1de01a62..56e63cd841 100644
--- a/vm_insnhelper.h
+++ b/vm_insnhelper.h
@@ -112,7 +112,6 @@ enum vm_regan_acttype {
#define DEC_SP(x) (VM_REG_SP -= (COLLECT_USAGE_REGISTER_HELPER(SP, SET, (x))))
#define SET_SV(x) (*GET_SP() = (x))
/* set current stack value as x */
-#define ADJ_SP(x) INC_SP(x)
/* instruction sequence C struct */
#define GET_ISEQ() (GET_CFP()->iseq)
@@ -184,9 +183,6 @@ enum vm_regan_acttype {
#define GET_BLOCK_HANDLER() (GET_LEP()[VM_ENV_DATA_INDEX_SPECVAL])
-#define WIDTH_OF_opt_send_without_block \
- ((rb_snum_t)attr_width_opt_send_without_block(0, 0))
-
/**********************************************************/
/* deal with control flow 3: exception */
/**********************************************************/
@@ -197,9 +193,8 @@ enum vm_regan_acttype {
/**********************************************************/
#if VM_CHECK_MODE > 0
-#define DECLARE_CANARY bool leaf; VALUE *canary
#define SETUP_CANARY() \
- if ((leaf = INSN_ATTR(leaf))) { \
+ if (leaf) { \
canary = GET_SP(); \
SET_SV(vm_stack_canary); \
}
@@ -208,7 +203,6 @@ enum vm_regan_acttype {
vm_canary_is_found_dead(INSN_ATTR(bin), *canary); \
}
#else
-#define DECLARE_CANARY /* void */
#define SETUP_CANARY() /* void */
#define CHECK_CANARY() /* void */
#endif
@@ -231,6 +225,16 @@ enum vm_regan_acttype {
#define USE_IC_FOR_SPECIALIZED_METHOD 1
#endif
+#ifndef MJIT_HEADER
+#define CALL_SIMPLE_METHOD() do { \
+ rb_snum_t x = leaf ? INSN_ATTR(width) : 0; \
+ rb_snum_t y = attr_width_opt_send_without_block(0, 0); \
+ rb_snum_t z = x - y; \
+ ADD_PC(z); \
+ DISPATCH_ORIGINAL_INSN(opt_send_without_block); \
+} while (0)
+#endif
+
#define NEXT_CLASS_SERIAL() (++ruby_vm_class_serial)
#define GET_GLOBAL_METHOD_STATE() (ruby_vm_global_method_state)
#define INC_GLOBAL_METHOD_STATE() (++ruby_vm_global_method_state)