Liveness analysis can produce intervals with range not ending at a use position. When splitting such interval after last use position we get the new interval with non-zero range length and without use positions. We should not add such intervals to the "unhandled" list.
This bug led to incorrect compilation of java/lang/Thread.<init>(Ljava/lang/ThreadGroup;Ljava/lang/Runnable;)V because of splitting an interval with no use position. The bug didn't produce noticeable runtime effects when jato was compiled with -Os. When compiled with -O0 or -O2 it was failing in assertion: jit/spill-reload.c:51: last_insn: Assertion `ret != ((void *)0)' failed. Signed-off-by: Tomek Grabiec <tgrab...@gmail.com> --- include/jit/vars.h | 5 +++++ jit/linear-scan.c | 25 +++++++++++++++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/include/jit/vars.h b/include/jit/vars.h index a697b1c..1f73c48 100644 --- a/include/jit/vars.h +++ b/include/jit/vars.h @@ -88,6 +88,11 @@ struct live_interval { bool fixed_reg; }; +static inline bool has_use_positions(struct live_interval *it) +{ + return !list_is_empty(&it->use_positions); +} + static inline void mark_need_reload(struct live_interval *it, struct live_interval *parent) { diff --git a/jit/linear-scan.c b/jit/linear-scan.c index ca3053b..e67a733 100644 --- a/jit/linear-scan.c +++ b/jit/linear-scan.c @@ -149,8 +149,11 @@ static void __spill_interval_intersecting(struct live_interval *current, return; new = split_interval_at(new, next_pos); - mark_need_reload(new, it); + if (!has_use_positions(new)) + return; + + mark_need_reload(new, it); insert_to_list(new, unhandled); } @@ -238,8 +241,12 @@ static void allocate_blocked_reg(struct live_interval *current, */ pos = next_use_pos(current, current->range.start); new = split_interval_at(current, pos); - mark_need_reload(new, current); - insert_to_list(new, unhandled); + + if (has_use_positions(new)) { + mark_need_reload(new, current); + insert_to_list(new, unhandled); + } + current->need_spill = 1; } else if (block_pos[reg] > current->range.end) { /* Spilling made a register free for the whole current */ @@ -248,7 +255,9 @@ static void allocate_blocked_reg(struct live_interval *current, inactive, unhandled); } else { new = split_interval_at(current, block_pos[reg]); - insert_to_list(new, unhandled); + + if (has_use_positions(new)) + insert_to_list(new, unhandled); current->reg = reg; spill_all_intervals_intersecting(current, reg, active, @@ -300,8 +309,12 @@ static void try_to_allocate_free_reg(struct live_interval *current, * Register available for the first part of the interval. */ new = split_interval_at(current, free_until_pos[reg]); - mark_need_reload(new, current); - insert_to_list(new, unhandled); + + if (has_use_positions(new)) { + mark_need_reload(new, current); + insert_to_list(new, unhandled); + } + current->reg = reg; current->need_spill = 1; } -- 1.6.0.6 ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ Jatovm-devel mailing list Jatovm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jatovm-devel