< 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 **** /* ! * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. ! * Copyright 2012, 2015 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. --- 1,8 ---- /* ! * 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,1084 **** --- 1075,1090 ---- __ 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,1100 **** // 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 __ 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); --- 1093,1103 ---- // void array_overlap_test(address no_overlap_target, int log2_elem_size) { Register tmp1 = R6_ARG4; Register tmp2 = R7_ARG5; ! 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,1147 **** // 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(); 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 --- 1133,1151 ---- // 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,1271 **** --- 1266,1276 ---- // 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,1365 **** --- 1359,1372 ---- 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,1493 **** --- 1491,1501 ---- // 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,1535 **** --- 1534,1544 ---- 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,1617 **** --- 1617,1627 ---- // 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,1703 **** // 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(); ! address nooverlap_target = aligned ? STUB_ENTRY(arrayof_jint_disjoint_arraycopy) : STUB_ENTRY(jint_disjoint_arraycopy); array_overlap_test(nooverlap_target, 2); --- 1703,1713 ---- // 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,1789 **** --- 1790,1800 ---- // 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,1873 **** // 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(); ! address nooverlap_target = aligned ? STUB_ENTRY(arrayof_jlong_disjoint_arraycopy) : STUB_ENTRY(jlong_disjoint_arraycopy); array_overlap_test(nooverlap_target, 3); --- 1874,1884 ---- // 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,1900 **** // address generate_conjoint_oop_copy(bool aligned, const char * name, bool dest_uninitialized) { StubCodeMark mark(this, "StubRoutines", name); address start = __ function_entry(); ! 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); --- 1901,1911 ---- // 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,1937 **** // 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(); ! 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); --- 1938,1948 ---- // 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,2011 **** //__ 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. 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); --- 2012,2039 ---- //__ align(CodeEntryAlignment); StubCodeMark mark(this, "StubRoutines", name); address start = __ function_entry(); ! // 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,2466 **** --- 2478,2496 ---- 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,2549 **** --- 2570,2584 ---- 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 >