< prev index next >

src/cpu/ppc/vm/stubGenerator_ppc.cpp

Print this page
rev 9821 : 8146613: PPC64: C2 does no longer respect int to long conversion for stub calls
Reviewed-by: goetz

@@ -1,8 +1,8 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2015 SAP AG. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2012, 2016 SAP AG. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.

@@ -1075,10 +1075,16 @@
       __ blr();
     }
     return start;
   }
 
+  inline void assert_positive_int(Register count) {
+#ifdef ASSERT
+    __ srdi_(R0, count, 31);
+    __ asm_assert_eq("missing zero extend", 0xAFFE);
+#endif
+  }
 
   // Generate overlap test for array copy stubs.
   //
   // Input:
   //   R3_ARG1    -  from

@@ -1087,14 +1093,11 @@
   //
   void array_overlap_test(address no_overlap_target, int log2_elem_size) {
     Register tmp1 = R6_ARG4;
     Register tmp2 = R7_ARG5;
 
-#ifdef ASSERT
-    __ srdi_(tmp2, R5_ARG3, 31);
-    __ asm_assert_eq("missing zero extend", 0xAFFE);
-#endif
+    assert_positive_int(R5_ARG3);
 
     __ subf(tmp1, R3_ARG1, R4_ARG2); // distance in bytes
     __ sldi(tmp2, R5_ARG3, log2_elem_size); // size in bytes
     __ cmpld(CCR0, R3_ARG1, R4_ARG2); // Use unsigned comparison!
     __ cmpld(CCR1, tmp1, tmp2);

@@ -1130,18 +1133,19 @@
   //      count: R5_ARG3 treated as signed
   //
   address generate_disjoint_byte_copy(bool aligned, const char * name) {
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ function_entry();
+    assert_positive_int(R5_ARG3);
 
     Register tmp1 = R6_ARG4;
     Register tmp2 = R7_ARG5;
     Register tmp3 = R8_ARG6;
     Register tmp4 = R9_ARG7;
 
-
     Label l_1, l_2, l_3, l_4, l_5, l_6, l_7, l_8, l_9;
+
     // Don't try anything fancy if arrays don't have many elements.
     __ li(tmp3, 0);
     __ cmpwi(CCR0, R5_ARG3, 17);
     __ ble(CCR0, l_6); // copy 4 at a time
 

@@ -1262,10 +1266,11 @@
   //      count: R5_ARG3 treated as signed
   //
   address generate_conjoint_byte_copy(bool aligned, const char * name) {
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ function_entry();
+    assert_positive_int(R5_ARG3);
 
     Register tmp1 = R6_ARG4;
     Register tmp2 = R7_ARG5;
     Register tmp3 = R8_ARG6;
 

@@ -1354,12 +1359,14 @@
     Register tmp2 = R7_ARG5;
     Register tmp3 = R8_ARG6;
     Register tmp4 = R9_ARG7;
 
     address start = __ function_entry();
+    assert_positive_int(R5_ARG3);
 
       Label l_1, l_2, l_3, l_4, l_5, l_6, l_7, l_8;
+
     // don't try anything fancy if arrays don't have many elements
     __ li(tmp3, 0);
     __ cmpwi(CCR0, R5_ARG3, 9);
     __ ble(CCR0, l_6); // copy 2 at a time
 

@@ -1484,10 +1491,11 @@
   //      count: R5_ARG3 treated as signed
   //
   address generate_conjoint_short_copy(bool aligned, const char * name) {
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ function_entry();
+    assert_positive_int(R5_ARG3);
 
     Register tmp1 = R6_ARG4;
     Register tmp2 = R7_ARG5;
     Register tmp3 = R8_ARG6;
 

@@ -1526,10 +1534,11 @@
     Register tmp2 = R7_ARG5;
     Register tmp3 = R8_ARG6;
     Register tmp4 = R0;
 
     Label l_1, l_2, l_3, l_4, l_5, l_6;
+
     // for short arrays, just do single element copy
     __ li(tmp3, 0);
     __ cmpwi(CCR0, R5_ARG3, 5);
     __ ble(CCR0, l_2);
 

@@ -1608,10 +1617,11 @@
   //      count: R5_ARG3 treated as signed
   //
   address generate_disjoint_int_copy(bool aligned, const char * name) {
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ function_entry();
+    assert_positive_int(R5_ARG3);
     generate_disjoint_int_copy_core(aligned);
     __ li(R3_RET, 0); // return 0
     __ blr();
     return start;
   }

@@ -1693,11 +1703,11 @@
   //      count: R5_ARG3 treated as signed
   //
   address generate_conjoint_int_copy(bool aligned, const char * name) {
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ function_entry();
-
+    assert_positive_int(R5_ARG3);
     address nooverlap_target = aligned ?
       STUB_ENTRY(arrayof_jint_disjoint_arraycopy) :
       STUB_ENTRY(jint_disjoint_arraycopy);
 
     array_overlap_test(nooverlap_target, 2);

@@ -1780,10 +1790,11 @@
   //      count: R5_ARG3 treated as signed
   //
   address generate_disjoint_long_copy(bool aligned, const char * name) {
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ function_entry();
+    assert_positive_int(R5_ARG3);
     generate_disjoint_long_copy_core(aligned);
     __ li(R3_RET, 0); // return 0
     __ blr();
 
     return start;

@@ -1863,11 +1874,11 @@
   //      count: R5_ARG3 treated as signed
   //
   address generate_conjoint_long_copy(bool aligned, const char * name) {
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ function_entry();
-
+    assert_positive_int(R5_ARG3);
     address nooverlap_target = aligned ?
       STUB_ENTRY(arrayof_jlong_disjoint_arraycopy) :
       STUB_ENTRY(jlong_disjoint_arraycopy);
 
     array_overlap_test(nooverlap_target, 3);

@@ -1890,11 +1901,11 @@
   //
   address generate_conjoint_oop_copy(bool aligned, const char * name, bool dest_uninitialized) {
     StubCodeMark mark(this, "StubRoutines", name);
 
     address start = __ function_entry();
-
+    assert_positive_int(R5_ARG3);
     address nooverlap_target = aligned ?
       STUB_ENTRY(arrayof_oop_disjoint_arraycopy) :
       STUB_ENTRY(oop_disjoint_arraycopy);
 
     gen_write_ref_array_pre_barrier(R3_ARG1, R4_ARG2, R5_ARG3, dest_uninitialized, R9_ARG7);

@@ -1927,11 +1938,11 @@
   //      dest_uninitialized: G1 support
   //
   address generate_disjoint_oop_copy(bool aligned, const char * name, bool dest_uninitialized) {
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ function_entry();
-
+    assert_positive_int(R5_ARG3);
     gen_write_ref_array_pre_barrier(R3_ARG1, R4_ARG2, R5_ARG3, dest_uninitialized, R9_ARG7);
 
     // save some arguments, disjoint_long_copy_core destroys them.
     // needed for post barrier
     __ mr(R9_ARG7, R4_ARG2);

@@ -2001,11 +2012,28 @@
 
     //__ align(CodeEntryAlignment);
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ function_entry();
 
-    // TODO: Assert that int is 64 bit sign extended and arrays are not conjoint.
+    // Assert that int is 64 bit sign extended and arrays are not conjoint.
+#ifdef ASSERT
+    {
+    assert_positive_int(R5_ARG3);
+    const Register tmp1 = R11_scratch1, tmp2 = R12_scratch2;
+    Label no_overlap;
+    __ subf(tmp1, R3_ARG1, R4_ARG2); // distance in bytes
+    __ sldi(tmp2, R5_ARG3, LogBytesPerHeapOop); // size in bytes
+    __ cmpld(CCR0, R3_ARG1, R4_ARG2); // Use unsigned comparison!
+    __ cmpld(CCR1, tmp1, tmp2);
+    __ crnand(CCR0, Assembler::less, CCR1, Assembler::less);
+    // Overlaps if Src before dst and distance smaller than size.
+    // Branch to forward copy routine otherwise.
+    __ blt(CCR0, no_overlap);
+    __ stop("overlap in checkcast_copy", 0x9543);
+    __ bind(no_overlap);
+    }
+#endif
 
     gen_write_ref_array_pre_barrier(R3_from, R4_to, R5_count, dest_uninitialized, R12_tmp, /* preserve: */ R6_ckoff, R7_ckval);
 
     //inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr, R12_tmp, R3_RET);
 

@@ -2450,17 +2478,19 @@
                                                              STUB_ENTRY(oop_disjoint_arraycopy),
                                                              STUB_ENTRY(jlong_arraycopy),
                                                              STUB_ENTRY(checkcast_arraycopy));
 
     // fill routines
+    if (OptimizeFill) {
     StubRoutines::_jbyte_fill          = generate_fill(T_BYTE,  false, "jbyte_fill");
     StubRoutines::_jshort_fill         = generate_fill(T_SHORT, false, "jshort_fill");
     StubRoutines::_jint_fill           = generate_fill(T_INT,   false, "jint_fill");
     StubRoutines::_arrayof_jbyte_fill  = generate_fill(T_BYTE,  true, "arrayof_jbyte_fill");
     StubRoutines::_arrayof_jshort_fill = generate_fill(T_SHORT, true, "arrayof_jshort_fill");
     StubRoutines::_arrayof_jint_fill   = generate_fill(T_INT,   true, "arrayof_jint_fill");
   }
+  }
 
   // Safefetch stubs.
   void generate_safefetch(const char* name, int size, address* entry, address* fault_pc, address* continuation_pc) {
     // safefetch signatures:
     //   int      SafeFetch32(int*      adr, int      errValue);

@@ -2540,10 +2570,15 @@
     const Register tmp12 = R25;
     const Register tmp13 = R24;
 
     BLOCK_COMMENT("Entry:");
 
+    // C2 does not respect int to long conversion for stub calls.
+    __ clrldi(xlen, xlen, 32);
+    __ clrldi(ylen, ylen, 32);
+    __ clrldi(zlen, zlen, 32);
+
     // Save non-volatile regs (frameless).
     int current_offs = 8;
     __ std(R24, -current_offs, R1_SP); current_offs += 8;
     __ std(R25, -current_offs, R1_SP); current_offs += 8;
     __ std(R26, -current_offs, R1_SP); current_offs += 8;
< prev index next >