8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "asm/macroAssembler.inline.hpp"
27 #include "gc/shared/barrierSet.hpp"
28 #include "gc/shared/barrierSetCodeGen.hpp"
29 #include "interpreter/interpreter.hpp"
30 #include "nativeInst_ppc.hpp"
31 #include "oops/instanceOop.hpp"
32 #include "oops/method.hpp"
33 #include "oops/objArrayKlass.hpp"
34 #include "oops/oop.inline.hpp"
35 #include "prims/methodHandles.hpp"
36 #include "runtime/frame.inline.hpp"
37 #include "runtime/handles.inline.hpp"
38 #include "runtime/sharedRuntime.hpp"
39 #include "runtime/stubCodeGenerator.hpp"
40 #include "runtime/stubRoutines.hpp"
41 #include "runtime/thread.inline.hpp"
42 #include "utilities/align.hpp"
43
44 // Declaration and definition of StubGenerator (no .hpp file).
45 // For a more detailed description of the stub routine structure
46 // see the comment in stubRoutines.hpp.
47
|
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "asm/macroAssembler.inline.hpp"
27 #include "gc/shared/barrierSet.hpp"
28 #include "gc/shared/barrierSetAssembler.hpp"
29 #include "interpreter/interpreter.hpp"
30 #include "nativeInst_ppc.hpp"
31 #include "oops/instanceOop.hpp"
32 #include "oops/method.hpp"
33 #include "oops/objArrayKlass.hpp"
34 #include "oops/oop.inline.hpp"
35 #include "prims/methodHandles.hpp"
36 #include "runtime/frame.inline.hpp"
37 #include "runtime/handles.inline.hpp"
38 #include "runtime/sharedRuntime.hpp"
39 #include "runtime/stubCodeGenerator.hpp"
40 #include "runtime/stubRoutines.hpp"
41 #include "runtime/thread.inline.hpp"
42 #include "utilities/align.hpp"
43
44 // Declaration and definition of StubGenerator (no .hpp file).
45 // For a more detailed description of the stub routine structure
46 // see the comment in stubRoutines.hpp.
47
|
2014 // count: R5_ARG3 treated as signed
2015 // dest_uninitialized: G1 support
2016 //
2017 address generate_conjoint_oop_copy(bool aligned, const char * name, bool dest_uninitialized) {
2018 StubCodeMark mark(this, "StubRoutines", name);
2019
2020 address start = __ function_entry();
2021 assert_positive_int(R5_ARG3);
2022 address nooverlap_target = aligned ?
2023 STUB_ENTRY(arrayof_oop_disjoint_arraycopy) :
2024 STUB_ENTRY(oop_disjoint_arraycopy);
2025
2026 DecoratorSet decorators = 0;
2027 if (dest_uninitialized) {
2028 decorators |= AS_DEST_NOT_INITIALIZED;
2029 }
2030 if (aligned) {
2031 decorators |= ARRAYCOPY_ALIGNED;
2032 }
2033
2034 BarrierSetCodeGen *bs = Universe::heap()->barrier_set()->code_gen();
2035 bs->arraycopy_prologue(_masm, decorators, T_OBJECT, R3_ARG1, R4_ARG2, R5_ARG3, noreg, noreg);
2036
2037 if (UseCompressedOops) {
2038 array_overlap_test(nooverlap_target, 2);
2039 generate_conjoint_int_copy_core(aligned);
2040 } else {
2041 array_overlap_test(nooverlap_target, 3);
2042 generate_conjoint_long_copy_core(aligned);
2043 }
2044
2045 bs->arraycopy_epilogue(_masm, decorators, T_OBJECT, R4_ARG2, R5_ARG3, noreg);
2046 __ li(R3_RET, 0); // return 0
2047 __ blr();
2048 return start;
2049 }
2050
2051 // Generate stub for disjoint oop copy. If "aligned" is true, the
2052 // "from" and "to" addresses are assumed to be heapword aligned.
2053 //
2054 // Arguments for generated stub:
2055 // from: R3_ARG1
2056 // to: R4_ARG2
2057 // count: R5_ARG3 treated as signed
2058 // dest_uninitialized: G1 support
2059 //
2060 address generate_disjoint_oop_copy(bool aligned, const char * name, bool dest_uninitialized) {
2061 StubCodeMark mark(this, "StubRoutines", name);
2062 address start = __ function_entry();
2063 assert_positive_int(R5_ARG3);
2064
2065 DecoratorSet decorators = ARRAYCOPY_DISJOINT;
2066 if (dest_uninitialized) {
2067 decorators |= AS_DEST_NOT_INITIALIZED;
2068 }
2069 if (aligned) {
2070 decorators |= ARRAYCOPY_ALIGNED;
2071 }
2072
2073 BarrierSetCodeGen *bs = Universe::heap()->barrier_set()->code_gen();
2074 bs->arraycopy_prologue(_masm, decorators, T_OBJECT, R3_ARG1, R4_ARG2, R5_ARG3, noreg, noreg);
2075
2076 if (UseCompressedOops) {
2077 generate_disjoint_int_copy_core(aligned);
2078 } else {
2079 generate_disjoint_long_copy_core(aligned);
2080 }
2081
2082 bs->arraycopy_epilogue(_masm, decorators, T_OBJECT, R4_ARG2, R5_ARG3, noreg);
2083 __ li(R3_RET, 0); // return 0
2084 __ blr();
2085
2086 return start;
2087 }
2088
2089
2090 // Helper for generating a dynamic type check.
2091 // Smashes only the given temp registers.
2092 void generate_type_check(Register sub_klass,
|
2014 // count: R5_ARG3 treated as signed
2015 // dest_uninitialized: G1 support
2016 //
2017 address generate_conjoint_oop_copy(bool aligned, const char * name, bool dest_uninitialized) {
2018 StubCodeMark mark(this, "StubRoutines", name);
2019
2020 address start = __ function_entry();
2021 assert_positive_int(R5_ARG3);
2022 address nooverlap_target = aligned ?
2023 STUB_ENTRY(arrayof_oop_disjoint_arraycopy) :
2024 STUB_ENTRY(oop_disjoint_arraycopy);
2025
2026 DecoratorSet decorators = 0;
2027 if (dest_uninitialized) {
2028 decorators |= AS_DEST_NOT_INITIALIZED;
2029 }
2030 if (aligned) {
2031 decorators |= ARRAYCOPY_ALIGNED;
2032 }
2033
2034 BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
2035 bs->arraycopy_prologue(_masm, decorators, T_OBJECT, R3_ARG1, R4_ARG2, R5_ARG3, noreg, noreg);
2036
2037 if (UseCompressedOops) {
2038 array_overlap_test(nooverlap_target, 2);
2039 generate_conjoint_int_copy_core(aligned);
2040 } else {
2041 array_overlap_test(nooverlap_target, 3);
2042 generate_conjoint_long_copy_core(aligned);
2043 }
2044
2045 bs->arraycopy_epilogue(_masm, decorators, T_OBJECT, R4_ARG2, R5_ARG3, noreg);
2046 __ li(R3_RET, 0); // return 0
2047 __ blr();
2048 return start;
2049 }
2050
2051 // Generate stub for disjoint oop copy. If "aligned" is true, the
2052 // "from" and "to" addresses are assumed to be heapword aligned.
2053 //
2054 // Arguments for generated stub:
2055 // from: R3_ARG1
2056 // to: R4_ARG2
2057 // count: R5_ARG3 treated as signed
2058 // dest_uninitialized: G1 support
2059 //
2060 address generate_disjoint_oop_copy(bool aligned, const char * name, bool dest_uninitialized) {
2061 StubCodeMark mark(this, "StubRoutines", name);
2062 address start = __ function_entry();
2063 assert_positive_int(R5_ARG3);
2064
2065 DecoratorSet decorators = ARRAYCOPY_DISJOINT;
2066 if (dest_uninitialized) {
2067 decorators |= AS_DEST_NOT_INITIALIZED;
2068 }
2069 if (aligned) {
2070 decorators |= ARRAYCOPY_ALIGNED;
2071 }
2072
2073 BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
2074 bs->arraycopy_prologue(_masm, decorators, T_OBJECT, R3_ARG1, R4_ARG2, R5_ARG3, noreg, noreg);
2075
2076 if (UseCompressedOops) {
2077 generate_disjoint_int_copy_core(aligned);
2078 } else {
2079 generate_disjoint_long_copy_core(aligned);
2080 }
2081
2082 bs->arraycopy_epilogue(_masm, decorators, T_OBJECT, R4_ARG2, R5_ARG3, noreg);
2083 __ li(R3_RET, 0); // return 0
2084 __ blr();
2085
2086 return start;
2087 }
2088
2089
2090 // Helper for generating a dynamic type check.
2091 // Smashes only the given temp registers.
2092 void generate_type_check(Register sub_klass,
|
2146 const Register tmp1 = R11_scratch1, tmp2 = R12_scratch2;
2147 Label no_overlap;
2148 __ subf(tmp1, R3_ARG1, R4_ARG2); // distance in bytes
2149 __ sldi(tmp2, R5_ARG3, LogBytesPerHeapOop); // size in bytes
2150 __ cmpld(CCR0, R3_ARG1, R4_ARG2); // Use unsigned comparison!
2151 __ cmpld(CCR1, tmp1, tmp2);
2152 __ crnand(CCR0, Assembler::less, CCR1, Assembler::less);
2153 // Overlaps if Src before dst and distance smaller than size.
2154 // Branch to forward copy routine otherwise.
2155 __ blt(CCR0, no_overlap);
2156 __ stop("overlap in checkcast_copy", 0x9543);
2157 __ bind(no_overlap);
2158 }
2159 #endif
2160
2161 DecoratorSet decorators = ARRAYCOPY_CHECKCAST;
2162 if (dest_uninitialized) {
2163 decorators |= AS_DEST_NOT_INITIALIZED;
2164 }
2165
2166 BarrierSetCodeGen *bs = Universe::heap()->barrier_set()->code_gen();
2167 bs->arraycopy_prologue(_masm, decorators, T_OBJECT, R3_from, R4_to, R5_count, /* preserve: */ R6_ckoff, R7_ckval);
2168
2169 //inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr, R12_tmp, R3_RET);
2170
2171 Label load_element, store_element, store_null, success, do_epilogue;
2172 __ or_(R9_remain, R5_count, R5_count); // Initialize loop index, and test it.
2173 __ li(R8_offset, 0); // Offset from start of arrays.
2174 __ li(R2_minus1, -1);
2175 __ bne(CCR0, load_element);
2176
2177 // Empty array: Nothing to do.
2178 __ li(R3_RET, 0); // Return 0 on (trivial) success.
2179 __ blr();
2180
2181 // ======== begin loop ========
2182 // (Entry is load_element.)
2183 __ align(OptoLoopAlignment);
2184 __ bind(store_element);
2185 if (UseCompressedOops) {
|
2146 const Register tmp1 = R11_scratch1, tmp2 = R12_scratch2;
2147 Label no_overlap;
2148 __ subf(tmp1, R3_ARG1, R4_ARG2); // distance in bytes
2149 __ sldi(tmp2, R5_ARG3, LogBytesPerHeapOop); // size in bytes
2150 __ cmpld(CCR0, R3_ARG1, R4_ARG2); // Use unsigned comparison!
2151 __ cmpld(CCR1, tmp1, tmp2);
2152 __ crnand(CCR0, Assembler::less, CCR1, Assembler::less);
2153 // Overlaps if Src before dst and distance smaller than size.
2154 // Branch to forward copy routine otherwise.
2155 __ blt(CCR0, no_overlap);
2156 __ stop("overlap in checkcast_copy", 0x9543);
2157 __ bind(no_overlap);
2158 }
2159 #endif
2160
2161 DecoratorSet decorators = ARRAYCOPY_CHECKCAST;
2162 if (dest_uninitialized) {
2163 decorators |= AS_DEST_NOT_INITIALIZED;
2164 }
2165
2166 BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
2167 bs->arraycopy_prologue(_masm, decorators, T_OBJECT, R3_from, R4_to, R5_count, /* preserve: */ R6_ckoff, R7_ckval);
2168
2169 //inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr, R12_tmp, R3_RET);
2170
2171 Label load_element, store_element, store_null, success, do_epilogue;
2172 __ or_(R9_remain, R5_count, R5_count); // Initialize loop index, and test it.
2173 __ li(R8_offset, 0); // Offset from start of arrays.
2174 __ li(R2_minus1, -1);
2175 __ bne(CCR0, load_element);
2176
2177 // Empty array: Nothing to do.
2178 __ li(R3_RET, 0); // Return 0 on (trivial) success.
2179 __ blr();
2180
2181 // ======== begin loop ========
2182 // (Entry is load_element.)
2183 __ align(OptoLoopAlignment);
2184 __ bind(store_element);
2185 if (UseCompressedOops) {
|