From ce99e50ede4e4981d7b008bbe17f72fa351a5978 Mon Sep 17 00:00:00 2001 From: eileencodes Date: Tue, 4 Apr 2023 13:18:13 -0400 Subject: [PATCH] Move `catch_except_p` to `compile_data` The `catch_except_p` flag is used for communicating between parent and child iseq's that a throw instruction was emitted. So for example if a child iseq has a throw in it and the parent wants to catch the throw, we use this flag to communicate to the parent iseq that a throw instruction was emitted. This flag is only useful at compile time, it only impacts the compilation process so it seems to be fine to move it from the iseq body to the compile_data struct. Co-authored-by: Aaron Patterson --- compile.c | 29 ++++++++++++++++------------- iseq.c | 1 - iseq.h | 1 + rjit_c.rb | 9 ++++----- vm_core.h | 1 - 5 files changed, 21 insertions(+), 20 deletions(-) diff --git a/compile.c b/compile.c index 546c07cec5..819137006c 100644 --- a/compile.c +++ b/compile.c @@ -1355,11 +1355,14 @@ new_child_iseq_with_callback(rb_iseq_t *iseq, const struct rb_iseq_new_with_call } static void -set_catch_except_p(struct rb_iseq_constant_body *body) +set_catch_except_p(rb_iseq_t *iseq) { - body->catch_except_p = true; - if (body->parent_iseq != NULL) { - set_catch_except_p(ISEQ_BODY(body->parent_iseq)); + RUBY_ASSERT(ISEQ_COMPILE_DATA(iseq)); + ISEQ_COMPILE_DATA(iseq)->catch_except_p = true; + if (ISEQ_BODY(iseq)->parent_iseq != NULL) { + if (ISEQ_COMPILE_DATA(ISEQ_BODY(iseq)->parent_iseq)) { + set_catch_except_p((rb_iseq_t *) ISEQ_BODY(iseq)->parent_iseq); + } } } @@ -1371,7 +1374,7 @@ set_catch_except_p(struct rb_iseq_constant_body *body) So this function sets true for limited ISeqs with break/next/redo catch table entries whose child ISeq would really raise an exception. */ static void -update_catch_except_flags(struct rb_iseq_constant_body *body) +update_catch_except_flags(rb_iseq_t *iseq, struct rb_iseq_constant_body *body) { unsigned int pos; size_t i; @@ -1384,7 +1387,7 @@ update_catch_except_flags(struct rb_iseq_constant_body *body) while (pos < body->iseq_size) { insn = rb_vm_insn_decode(body->iseq_encoded[pos]); if (insn == BIN(throw)) { - set_catch_except_p(body); + set_catch_except_p(iseq); break; } pos += insn_len(insn); @@ -1399,7 +1402,8 @@ update_catch_except_flags(struct rb_iseq_constant_body *body) if (entry->type != CATCH_TYPE_BREAK && entry->type != CATCH_TYPE_NEXT && entry->type != CATCH_TYPE_REDO) { - body->catch_except_p = true; + RUBY_ASSERT(ISEQ_COMPILE_DATA(iseq)); + ISEQ_COMPILE_DATA(iseq)->catch_except_p = true; break; } } @@ -1496,10 +1500,12 @@ iseq_setup(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) if (!rb_iseq_translate_threaded_code(iseq)) return COMPILE_NG; debugs("[compile step 6 (update_catch_except_flags)] \n"); - update_catch_except_flags(ISEQ_BODY(iseq)); + RUBY_ASSERT(ISEQ_COMPILE_DATA(iseq)); + update_catch_except_flags(iseq, ISEQ_BODY(iseq)); debugs("[compile step 6.1 (remove unused catch tables)] \n"); - if (!ISEQ_BODY(iseq)->catch_except_p && ISEQ_BODY(iseq)->catch_table) { + RUBY_ASSERT(ISEQ_COMPILE_DATA(iseq)); + if (!ISEQ_COMPILE_DATA(iseq)->catch_except_p && ISEQ_BODY(iseq)->catch_table) { xfree(ISEQ_BODY(iseq)->catch_table); ISEQ_BODY(iseq)->catch_table = NULL; } @@ -3802,7 +3808,7 @@ iseq_optimize(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) int do_block_optimization = 0; - if (ISEQ_BODY(iseq)->type == ISEQ_TYPE_BLOCK && !ISEQ_BODY(iseq)->catch_except_p) { + if (ISEQ_BODY(iseq)->type == ISEQ_TYPE_BLOCK && !ISEQ_COMPILE_DATA(iseq)->catch_except_p) { do_block_optimization = 1; } @@ -12175,7 +12181,6 @@ ibf_dump_iseq_each(struct ibf_dump *dump, const rb_iseq_t *iseq) ibf_dump_write_small_value(dump, body->ic_size); ibf_dump_write_small_value(dump, body->ci_size); ibf_dump_write_small_value(dump, body->stack_max); - ibf_dump_write_small_value(dump, body->catch_except_p); ibf_dump_write_small_value(dump, body->builtin_attrs); #undef IBF_BODY_OFFSET @@ -12288,7 +12293,6 @@ ibf_load_iseq_each(struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t offset) const unsigned int ci_size = (unsigned int)ibf_load_small_value(load, &reading_pos); const unsigned int stack_max = (unsigned int)ibf_load_small_value(load, &reading_pos); - const char catch_except_p = (char)ibf_load_small_value(load, &reading_pos); const unsigned int builtin_attrs = (unsigned int)ibf_load_small_value(load, &reading_pos); // setup fname and dummy frame @@ -12361,7 +12365,6 @@ ibf_load_iseq_each(struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t offset) load_body->location.code_location.beg_pos.column = location_code_location_beg_pos_column; load_body->location.code_location.end_pos.lineno = location_code_location_end_pos_lineno; load_body->location.code_location.end_pos.column = location_code_location_end_pos_column; - load_body->catch_except_p = catch_except_p; load_body->builtin_attrs = builtin_attrs; load_body->ivc_size = ivc_size; diff --git a/iseq.c b/iseq.c index ccb6c152e5..81c60ae20e 100644 --- a/iseq.c +++ b/iseq.c @@ -2306,7 +2306,6 @@ rb_iseq_disasm_recursive(const rb_iseq_t *iseq, VALUE indent) rb_str_cat2(str, "== disasm: "); rb_str_append(str, iseq_inspect(iseq)); - rb_str_catf(str, " (catch: %s)", body->catch_except_p ? "true" : "false"); if ((l = RSTRING_LEN(str) - indent_len) < header_minlen) { rb_str_modify_expand(str, header_minlen - l); memset(RSTRING_END(str), '=', header_minlen - l); diff --git a/iseq.h b/iseq.h index 96d19029a1..b12228eed9 100644 --- a/iseq.h +++ b/iseq.h @@ -126,6 +126,7 @@ struct iseq_compile_data { struct rb_id_table *ivar_cache_table; const struct rb_builtin_function *builtin_function_table; const NODE *root_node; + bool catch_except_p; // If a frame of this ISeq may catch exception, set true. #if OPT_SUPPORT_JOKE st_table *labels_table; #endif diff --git a/rjit_c.rb b/rjit_c.rb index 917e0f8772..591b53b89c 100644 --- a/rjit_c.rb +++ b/rjit_c.rb @@ -1159,7 +1159,6 @@ module RubyVM::RJIT # :nodoc: all icvarc_size: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), icvarc_size)")], ci_size: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), ci_size)")], stack_max: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), stack_max)")], - catch_except_p: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), catch_except_p)")], builtin_attrs: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_constant_body *)NULL)), builtin_attrs)")], mark_bits: [CType::Union.new( "", Primitive.cexpr!("SIZEOF(((struct rb_iseq_constant_body *)NULL)->mark_bits)"), @@ -1599,10 +1598,6 @@ module RubyVM::RJIT # :nodoc: all CType::Stub.new(:rb_snum_t) end - def C._Bool - CType::Bool.new - end - def C.iseq_bits_t CType::Stub.new(:iseq_bits_t) end @@ -1631,6 +1626,10 @@ module RubyVM::RJIT # :nodoc: all CType::Stub.new(:rb_method_refined_t) end + def C._Bool + CType::Bool.new + end + def C.ccan_list_node CType::Stub.new(:ccan_list_node) end diff --git a/vm_core.h b/vm_core.h index d1640c9ab6..74824f48c6 100644 --- a/vm_core.h +++ b/vm_core.h @@ -496,7 +496,6 @@ struct rb_iseq_constant_body { unsigned int ci_size; unsigned int stack_max; /* for stack overflow check */ - bool catch_except_p; // If a frame of this ISeq may catch exception, set true. unsigned int builtin_attrs; // Union of rb_builtin_attr union {