Print this page
rev 4534 : 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
Summary: Changed gen_write_ref_array_post_barrier() code on x64 to pass start address and number of copied oop elements. In generate_checkcast_copy() skip post barrier code if no elements are copied.
Reviewed-by: roland

Split Split Close
Expand all
Collapse all
          --- old/src/cpu/x86/vm/stubGenerator_x86_32.cpp
          +++ new/src/cpu/x86/vm/stubGenerator_x86_32.cpp
↓ open down ↓ 1519 lines elided ↑ open up ↑
1520 1520      __ movptr(elem, from_element_addr);   // load the oop
1521 1521      __ testptr(elem, elem);
1522 1522      __ jccb(Assembler::zero, L_store_element);
1523 1523  
1524 1524      // (Could do a trick here:  Remember last successful non-null
1525 1525      // element stored and make a quick oop equality check on it.)
1526 1526  
1527 1527      __ movptr(elem_klass, elem_klass_addr); // query the object klass
1528 1528      generate_type_check(elem_klass, ckoff_arg, ckval_arg, temp,
1529 1529                          &L_store_element, NULL);
1530      -      // (On fall-through, we have failed the element type check.)
     1530 +    // (On fall-through, we have failed the element type check.)
1531 1531      // ======== end loop ========
1532 1532  
1533 1533      // It was a real error; we must depend on the caller to finish the job.
1534 1534      // Register "count" = -1 * number of *remaining* oops, length_arg = *total* oops.
1535 1535      // Emit GC store barriers for the oops we have copied (length_arg + count),
1536 1536      // and report their number to the caller.
     1537 +    assert_different_registers(to, count, rax);
     1538 +    Label L_post_barrier;
1537 1539      __ addl(count, length_arg);         // transfers = (length - remaining)
1538 1540      __ movl2ptr(rax, count);            // save the value
1539      -    __ notptr(rax);                     // report (-1^K) to caller
1540      -    __ movptr(to, to_arg);              // reload
1541      -    assert_different_registers(to, count, rax);
1542      -    gen_write_ref_array_post_barrier(to, count);
1543      -    __ jmpb(L_done);
     1541 +    __ notptr(rax);                     // report (-1^K) to caller (does not affect flags)
     1542 +    __ jccb(Assembler::notZero, L_post_barrier);
     1543 +    __ jmp(L_done); // K == 0, nothing was copied, skip post barrier
1544 1544  
1545 1545      // Come here on success only.
1546 1546      __ BIND(L_do_card_marks);
     1547 +    __ xorptr(rax, rax);                // return 0 on success
1547 1548      __ movl2ptr(count, length_arg);
1548      -    __ movptr(to, to_arg);                // reload
     1549 +
     1550 +    __ BIND(L_post_barrier);
     1551 +    __ movptr(to, to_arg);              // reload
1549 1552      gen_write_ref_array_post_barrier(to, count);
1550      -    __ xorptr(rax, rax);                  // return 0 on success
1551 1553  
1552 1554      // Common exit point (success or failure).
1553 1555      __ BIND(L_done);
1554 1556      __ pop(rbx);
1555 1557      __ pop(rdi);
1556 1558      __ pop(rsi);
1557 1559      inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr);
1558 1560      __ leave(); // required for proper stackwalking of RuntimeStub frame
1559 1561      __ ret(0);
1560 1562  
↓ open down ↓ 1405 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX