RFR: Fix SEGV in checkcast_copy

Message ID 1386934003.26061.17.camel@localhost.localdomain
State New
Headers show

Commit Message

Edward Nevill Dec. 13, 2013, 11:26 a.m.
Hi,

The following patch fixes a problem in checkcast_copy where gen_write_ref_array_post_barrier was being called with start > end, gen_write_ref_array_post_barrier assumes there is always something to write, so this caused a SEGV.

This fix mirrors the code for X86. The alternative would be to fix gen_write_ref_array_post_barrier to just exit if start > end, but I have decided to just mirror the X86 code.

This fixes a number of SEGVs I am seeing at random places in jtreg/langtools.

OK to push?
Ed.


--- CUT HERE ---
exporting patch:
# HG changeset patch
# User Edward Nevill edward.nevill@linaro.org
# Date 1386933610 0
#      Fri Dec 13 11:20:10 2013 +0000
# Node ID 1f9222c232e0ef699034a48ce8bda49d76fedbe8
# Parent  390889cee20523b8bf400433ac171654893c3702
Fix SIGV in checkcast_copy

Comments

Andrew Haley Dec. 13, 2013, 11:41 a.m. | #1
On 12/13/2013 11:26 AM, Edward Nevill wrote:
> OK to push?

OK, thanks.

Andrew.

Patch

diff -r 390889cee205 -r 1f9222c232e0 src/cpu/aarch64/vm/stubGenerator_aarch64.cpp
--- a/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp	Thu Dec 12 17:58:29 2013 +0000
+++ b/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp	Fri Dec 13 11:20:10 2013 +0000
@@ -1590,7 +1590,7 @@ 
   address generate_checkcast_copy(const char *name, address *entry,
                                   bool dest_uninitialized = false) {
 
-    Label L_load_element, L_store_element, L_do_card_marks, L_done;
+    Label L_load_element, L_store_element, L_do_card_marks, L_done, L_done_pop;
 
     // Input registers (after setup_arg_regs)
     const Register from        = c_rarg0;   // source array address
@@ -1692,13 +1692,15 @@ 
     // Emit GC store barriers for the oops we have copied and report
     // their number to the caller.
 
-    __ sub(count, count_save, count);     // K = partially copied oop count
+    __ subs(count, count_save, count);     // K = partially copied oop count
     __ eon(count, count, zr);                   // report (-1^K) to caller
+    __ br(Assembler::EQ, L_done_pop);
 
     __ BIND(L_do_card_marks);
     __ add(to, to, -heapOopSize);         // make an inclusive end pointer
     gen_write_ref_array_post_barrier(start_to, to, rscratch1);
 
+    __ bind(L_done_pop);
     __ pop(r18->bit() | r19->bit() | r20->bit()| r21->bit(), sp);
     inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr);
 
--- CUT HERE ---