verify_no_recursion() checks whether all call sites of given subroutine all outside its body. It's a requirement for inlining to be possible.
Signed-off-by: Tomek Grabiec <tgrab...@gmail.com> --- jit/subroutine.c | 34 ++++++++++++++++++++++++++++++---- 1 files changed, 30 insertions(+), 4 deletions(-) diff --git a/jit/subroutine.c b/jit/subroutine.c index e831d17..4026104 100644 --- a/jit/subroutine.c +++ b/jit/subroutine.c @@ -843,6 +843,16 @@ update_and_copy_exception_handlers(struct inlining_context *ctx, return 0; } +static int verify_no_recursion(struct subroutine *sub) +{ + for (int i = 0; i < sub->nr_call_sites; i++) + if (sub->call_sites[i] > sub->start_pc && + sub->call_sites[i] < sub->end_pc) + return warn("subroutine recursion"), -EINVAL; + + return 0; +} + static int do_inline_subroutine(struct inlining_context *ctx, struct subroutine *sub) { @@ -866,6 +876,10 @@ static int do_inline_subroutine(struct inlining_context *ctx, if (err) goto error_update_bytecode_offsets; + err = verify_no_recursion(sub); + if (err) + goto error_update_bytecode_offsets; + unsigned long body_size = subroutine_get_body_size(sub); unsigned long sub_size = subroutine_get_size(sub); unsigned long new_code_length = ctx->code.code_length - sub_size + @@ -873,7 +887,7 @@ static int do_inline_subroutine(struct inlining_context *ctx, sub->call_sites_total_size; if (code_state_init_empty(&new_code, new_code_length)) - goto error_new_code; + goto error_update_bytecode_offsets; subroutine_sort_call_sites(sub); @@ -935,7 +949,6 @@ static int do_inline_subroutine(struct inlining_context *ctx, error: code_state_deinit(&new_code); - error_new_code: error_update_bytecode_offsets: pc_map_deinit(&pc_map); @@ -1088,13 +1101,26 @@ static int split_exception_handlers(struct inlining_context *ctx) static int verify_correct_nesting(struct inlining_context *ctx) { struct subroutine *this; + int *coverage; + + coverage = zalloc(ctx->code.code_length * sizeof(int)); + if (!coverage) + return -ENOMEM; list_for_each_entry(this, &ctx->subroutine_list, subroutine_list_node) { - for (int i = 0; i < this->nr_dependants; i++) - if (this->end_pc > this->dependants[i]->end_pc) + int color = coverage[this->start_pc]; + + for (unsigned long i = this->start_pc; i < this->end_pc; i++) { + if (coverage[i] != color) { + free(coverage); return warn("overlaping subroutines"), -EINVAL; + } + + coverage[i]++; + } } + free(coverage); return 0; } -- 1.6.0.6 ------------------------------------------------------------------------------ Enter the BlackBerry Developer Challenge This is your chance to win up to $100,000 in prizes! For a limited time, vendors submitting new applications to BlackBerry App World(TM) will have the opportunity to enter the BlackBerry Developer Challenge. See full prize details at: http://p.sf.net/sfu/Challenge _______________________________________________ Jatovm-devel mailing list Jatovm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jatovm-devel