Tue, 22 Feb 2011 15:25:02 -0800
7020521: arraycopy stubs place prebarriers incorrectly
Summary: Rearranged the pre-barrier placement in arraycopy stubs so that they are properly called in case of chained calls. Also refactored the code a little bit so that it looks uniform across the platforms and is more readable.
Reviewed-by: never, kvn
1.1 --- a/src/cpu/sparc/vm/stubGenerator_sparc.cpp Wed Feb 09 15:02:23 2011 -0800 1.2 +++ b/src/cpu/sparc/vm/stubGenerator_sparc.cpp Tue Feb 22 15:25:02 2011 -0800 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -968,19 +968,6 @@ 1.11 return start; 1.12 } 1.13 1.14 - static address disjoint_byte_copy_entry; 1.15 - static address disjoint_short_copy_entry; 1.16 - static address disjoint_int_copy_entry; 1.17 - static address disjoint_long_copy_entry; 1.18 - static address disjoint_oop_copy_entry; 1.19 - 1.20 - static address byte_copy_entry; 1.21 - static address short_copy_entry; 1.22 - static address int_copy_entry; 1.23 - static address long_copy_entry; 1.24 - static address oop_copy_entry; 1.25 - 1.26 - static address checkcast_copy_entry; 1.27 1.28 // 1.29 // Verify that a register contains clean 32-bits positive value 1.30 @@ -1283,7 +1270,7 @@ 1.31 // to: O1 1.32 // count: O2 treated as signed 1.33 // 1.34 - address generate_disjoint_byte_copy(bool aligned, const char * name) { 1.35 + address generate_disjoint_byte_copy(bool aligned, address *entry, const char *name) { 1.36 __ align(CodeEntryAlignment); 1.37 StubCodeMark mark(this, "StubRoutines", name); 1.38 address start = __ pc(); 1.39 @@ -1299,9 +1286,11 @@ 1.40 1.41 assert_clean_int(count, O3); // Make sure 'count' is clean int. 1.42 1.43 - if (!aligned) disjoint_byte_copy_entry = __ pc(); 1.44 - // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.45 - if (!aligned) BLOCK_COMMENT("Entry:"); 1.46 + if (entry != NULL) { 1.47 + *entry = __ pc(); 1.48 + // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.49 + BLOCK_COMMENT("Entry:"); 1.50 + } 1.51 1.52 // for short arrays, just do single element copy 1.53 __ cmp(count, 23); // 16 + 7 1.54 @@ -1391,15 +1380,13 @@ 1.55 // to: O1 1.56 // count: O2 treated as signed 1.57 // 1.58 - address generate_conjoint_byte_copy(bool aligned, const char * name) { 1.59 + address generate_conjoint_byte_copy(bool aligned, address nooverlap_target, 1.60 + address *entry, const char *name) { 1.61 // Do reverse copy. 1.62 1.63 __ align(CodeEntryAlignment); 1.64 StubCodeMark mark(this, "StubRoutines", name); 1.65 address start = __ pc(); 1.66 - address nooverlap_target = aligned ? 1.67 - StubRoutines::arrayof_jbyte_disjoint_arraycopy() : 1.68 - disjoint_byte_copy_entry; 1.69 1.70 Label L_skip_alignment, L_align, L_aligned_copy; 1.71 Label L_copy_byte, L_copy_byte_loop, L_exit; 1.72 @@ -1412,9 +1399,11 @@ 1.73 1.74 assert_clean_int(count, O3); // Make sure 'count' is clean int. 1.75 1.76 - if (!aligned) byte_copy_entry = __ pc(); 1.77 - // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.78 - if (!aligned) BLOCK_COMMENT("Entry:"); 1.79 + if (entry != NULL) { 1.80 + *entry = __ pc(); 1.81 + // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.82 + BLOCK_COMMENT("Entry:"); 1.83 + } 1.84 1.85 array_overlap_test(nooverlap_target, 0); 1.86 1.87 @@ -1504,7 +1493,7 @@ 1.88 // to: O1 1.89 // count: O2 treated as signed 1.90 // 1.91 - address generate_disjoint_short_copy(bool aligned, const char * name) { 1.92 + address generate_disjoint_short_copy(bool aligned, address *entry, const char * name) { 1.93 __ align(CodeEntryAlignment); 1.94 StubCodeMark mark(this, "StubRoutines", name); 1.95 address start = __ pc(); 1.96 @@ -1520,9 +1509,11 @@ 1.97 1.98 assert_clean_int(count, O3); // Make sure 'count' is clean int. 1.99 1.100 - if (!aligned) disjoint_short_copy_entry = __ pc(); 1.101 - // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.102 - if (!aligned) BLOCK_COMMENT("Entry:"); 1.103 + if (entry != NULL) { 1.104 + *entry = __ pc(); 1.105 + // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.106 + BLOCK_COMMENT("Entry:"); 1.107 + } 1.108 1.109 // for short arrays, just do single element copy 1.110 __ cmp(count, 11); // 8 + 3 (22 bytes) 1.111 @@ -1842,15 +1833,13 @@ 1.112 // to: O1 1.113 // count: O2 treated as signed 1.114 // 1.115 - address generate_conjoint_short_copy(bool aligned, const char * name) { 1.116 + address generate_conjoint_short_copy(bool aligned, address nooverlap_target, 1.117 + address *entry, const char *name) { 1.118 // Do reverse copy. 1.119 1.120 __ align(CodeEntryAlignment); 1.121 StubCodeMark mark(this, "StubRoutines", name); 1.122 address start = __ pc(); 1.123 - address nooverlap_target = aligned ? 1.124 - StubRoutines::arrayof_jshort_disjoint_arraycopy() : 1.125 - disjoint_short_copy_entry; 1.126 1.127 Label L_skip_alignment, L_skip_alignment2, L_aligned_copy; 1.128 Label L_copy_2_bytes, L_copy_2_bytes_loop, L_exit; 1.129 @@ -1865,9 +1854,11 @@ 1.130 1.131 assert_clean_int(count, O3); // Make sure 'count' is clean int. 1.132 1.133 - if (!aligned) short_copy_entry = __ pc(); 1.134 - // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.135 - if (!aligned) BLOCK_COMMENT("Entry:"); 1.136 + if (entry != NULL) { 1.137 + *entry = __ pc(); 1.138 + // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.139 + BLOCK_COMMENT("Entry:"); 1.140 + } 1.141 1.142 array_overlap_test(nooverlap_target, 1); 1.143 1.144 @@ -2072,7 +2063,7 @@ 1.145 // to: O1 1.146 // count: O2 treated as signed 1.147 // 1.148 - address generate_disjoint_int_copy(bool aligned, const char * name) { 1.149 + address generate_disjoint_int_copy(bool aligned, address *entry, const char *name) { 1.150 __ align(CodeEntryAlignment); 1.151 StubCodeMark mark(this, "StubRoutines", name); 1.152 address start = __ pc(); 1.153 @@ -2080,9 +2071,11 @@ 1.154 const Register count = O2; 1.155 assert_clean_int(count, O3); // Make sure 'count' is clean int. 1.156 1.157 - if (!aligned) disjoint_int_copy_entry = __ pc(); 1.158 - // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.159 - if (!aligned) BLOCK_COMMENT("Entry:"); 1.160 + if (entry != NULL) { 1.161 + *entry = __ pc(); 1.162 + // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.163 + BLOCK_COMMENT("Entry:"); 1.164 + } 1.165 1.166 generate_disjoint_int_copy_core(aligned); 1.167 1.168 @@ -2204,20 +2197,19 @@ 1.169 // to: O1 1.170 // count: O2 treated as signed 1.171 // 1.172 - address generate_conjoint_int_copy(bool aligned, const char * name) { 1.173 + address generate_conjoint_int_copy(bool aligned, address nooverlap_target, 1.174 + address *entry, const char *name) { 1.175 __ align(CodeEntryAlignment); 1.176 StubCodeMark mark(this, "StubRoutines", name); 1.177 address start = __ pc(); 1.178 1.179 - address nooverlap_target = aligned ? 1.180 - StubRoutines::arrayof_jint_disjoint_arraycopy() : 1.181 - disjoint_int_copy_entry; 1.182 - 1.183 assert_clean_int(O2, O3); // Make sure 'count' is clean int. 1.184 1.185 - if (!aligned) int_copy_entry = __ pc(); 1.186 - // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.187 - if (!aligned) BLOCK_COMMENT("Entry:"); 1.188 + if (entry != NULL) { 1.189 + *entry = __ pc(); 1.190 + // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.191 + BLOCK_COMMENT("Entry:"); 1.192 + } 1.193 1.194 array_overlap_test(nooverlap_target, 2); 1.195 1.196 @@ -2336,16 +2328,18 @@ 1.197 // to: O1 1.198 // count: O2 treated as signed 1.199 // 1.200 - address generate_disjoint_long_copy(bool aligned, const char * name) { 1.201 + address generate_disjoint_long_copy(bool aligned, address *entry, const char *name) { 1.202 __ align(CodeEntryAlignment); 1.203 StubCodeMark mark(this, "StubRoutines", name); 1.204 address start = __ pc(); 1.205 1.206 assert_clean_int(O2, O3); // Make sure 'count' is clean int. 1.207 1.208 - if (!aligned) disjoint_long_copy_entry = __ pc(); 1.209 - // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.210 - if (!aligned) BLOCK_COMMENT("Entry:"); 1.211 + if (entry != NULL) { 1.212 + *entry = __ pc(); 1.213 + // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.214 + BLOCK_COMMENT("Entry:"); 1.215 + } 1.216 1.217 generate_disjoint_long_copy_core(aligned); 1.218 1.219 @@ -2406,19 +2400,21 @@ 1.220 // to: O1 1.221 // count: O2 treated as signed 1.222 // 1.223 - address generate_conjoint_long_copy(bool aligned, const char * name) { 1.224 + address generate_conjoint_long_copy(bool aligned, address nooverlap_target, 1.225 + address *entry, const char *name) { 1.226 __ align(CodeEntryAlignment); 1.227 StubCodeMark mark(this, "StubRoutines", name); 1.228 address start = __ pc(); 1.229 1.230 assert(!aligned, "usage"); 1.231 - address nooverlap_target = disjoint_long_copy_entry; 1.232 1.233 assert_clean_int(O2, O3); // Make sure 'count' is clean int. 1.234 1.235 - if (!aligned) long_copy_entry = __ pc(); 1.236 - // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.237 - if (!aligned) BLOCK_COMMENT("Entry:"); 1.238 + if (entry != NULL) { 1.239 + *entry = __ pc(); 1.240 + // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.241 + BLOCK_COMMENT("Entry:"); 1.242 + } 1.243 1.244 array_overlap_test(nooverlap_target, 3); 1.245 1.246 @@ -2439,7 +2435,7 @@ 1.247 // to: O1 1.248 // count: O2 treated as signed 1.249 // 1.250 - address generate_disjoint_oop_copy(bool aligned, const char * name) { 1.251 + address generate_disjoint_oop_copy(bool aligned, address *entry, const char *name) { 1.252 1.253 const Register from = O0; // source array address 1.254 const Register to = O1; // destination array address 1.255 @@ -2451,9 +2447,11 @@ 1.256 1.257 assert_clean_int(count, O3); // Make sure 'count' is clean int. 1.258 1.259 - if (!aligned) disjoint_oop_copy_entry = __ pc(); 1.260 - // caller can pass a 64-bit byte count here 1.261 - if (!aligned) BLOCK_COMMENT("Entry:"); 1.262 + if (entry != NULL) { 1.263 + *entry = __ pc(); 1.264 + // caller can pass a 64-bit byte count here 1.265 + BLOCK_COMMENT("Entry:"); 1.266 + } 1.267 1.268 // save arguments for barrier generation 1.269 __ mov(to, G1); 1.270 @@ -2487,7 +2485,8 @@ 1.271 // to: O1 1.272 // count: O2 treated as signed 1.273 // 1.274 - address generate_conjoint_oop_copy(bool aligned, const char * name) { 1.275 + address generate_conjoint_oop_copy(bool aligned, address nooverlap_target, 1.276 + address *entry, const char *name) { 1.277 1.278 const Register from = O0; // source array address 1.279 const Register to = O1; // destination array address 1.280 @@ -2499,22 +2498,19 @@ 1.281 1.282 assert_clean_int(count, O3); // Make sure 'count' is clean int. 1.283 1.284 - if (!aligned) oop_copy_entry = __ pc(); 1.285 - // caller can pass a 64-bit byte count here 1.286 - if (!aligned) BLOCK_COMMENT("Entry:"); 1.287 + if (entry != NULL) { 1.288 + *entry = __ pc(); 1.289 + // caller can pass a 64-bit byte count here 1.290 + BLOCK_COMMENT("Entry:"); 1.291 + } 1.292 + 1.293 + array_overlap_test(nooverlap_target, LogBytesPerHeapOop); 1.294 1.295 // save arguments for barrier generation 1.296 __ mov(to, G1); 1.297 __ mov(count, G5); 1.298 - 1.299 gen_write_ref_array_pre_barrier(G1, G5); 1.300 1.301 - address nooverlap_target = aligned ? 1.302 - StubRoutines::arrayof_oop_disjoint_arraycopy() : 1.303 - disjoint_oop_copy_entry; 1.304 - 1.305 - array_overlap_test(nooverlap_target, LogBytesPerHeapOop); 1.306 - 1.307 #ifdef _LP64 1.308 if (UseCompressedOops) { 1.309 generate_conjoint_int_copy_core(aligned); 1.310 @@ -2582,7 +2578,7 @@ 1.311 // ckval: O4 (super_klass) 1.312 // ret: O0 zero for success; (-1^K) where K is partial transfer count 1.313 // 1.314 - address generate_checkcast_copy(const char* name) { 1.315 + address generate_checkcast_copy(const char *name, address *entry) { 1.316 1.317 const Register O0_from = O0; // source array address 1.318 const Register O1_to = O1; // destination array address 1.319 @@ -2600,8 +2596,6 @@ 1.320 StubCodeMark mark(this, "StubRoutines", name); 1.321 address start = __ pc(); 1.322 1.323 - gen_write_ref_array_pre_barrier(O1, O2); 1.324 - 1.325 #ifdef ASSERT 1.326 // We sometimes save a frame (see generate_type_check below). 1.327 // If this will cause trouble, let's fail now instead of later. 1.328 @@ -2625,9 +2619,13 @@ 1.329 } 1.330 #endif //ASSERT 1.331 1.332 - checkcast_copy_entry = __ pc(); 1.333 - // caller can pass a 64-bit byte count here (from generic stub) 1.334 - BLOCK_COMMENT("Entry:"); 1.335 + if (entry != NULL) { 1.336 + *entry = __ pc(); 1.337 + // caller can pass a 64-bit byte count here (from generic stub) 1.338 + BLOCK_COMMENT("Entry:"); 1.339 + } 1.340 + 1.341 + gen_write_ref_array_pre_barrier(O1_to, O2_count); 1.342 1.343 Label load_element, store_element, do_card_marks, fail, done; 1.344 __ addcc(O2_count, 0, G1_remain); // initialize loop index, and test it 1.345 @@ -2700,7 +2698,11 @@ 1.346 // Examines the alignment of the operands and dispatches 1.347 // to a long, int, short, or byte copy loop. 1.348 // 1.349 - address generate_unsafe_copy(const char* name) { 1.350 + address generate_unsafe_copy(const char* name, 1.351 + address byte_copy_entry, 1.352 + address short_copy_entry, 1.353 + address int_copy_entry, 1.354 + address long_copy_entry) { 1.355 1.356 const Register O0_from = O0; // source array address 1.357 const Register O1_to = O1; // destination array address 1.358 @@ -2796,8 +2798,13 @@ 1.359 // O0 == 0 - success 1.360 // O0 == -1 - need to call System.arraycopy 1.361 // 1.362 - address generate_generic_copy(const char *name) { 1.363 - 1.364 + address generate_generic_copy(const char *name, 1.365 + address entry_jbyte_arraycopy, 1.366 + address entry_jshort_arraycopy, 1.367 + address entry_jint_arraycopy, 1.368 + address entry_oop_arraycopy, 1.369 + address entry_jlong_arraycopy, 1.370 + address entry_checkcast_arraycopy) { 1.371 Label L_failed, L_objArray; 1.372 1.373 // Input registers 1.374 @@ -2970,15 +2977,15 @@ 1.375 1.376 BLOCK_COMMENT("choose copy loop based on element size"); 1.377 __ cmp(G3_elsize, 0); 1.378 - __ br(Assembler::equal,true,Assembler::pt,StubRoutines::_jbyte_arraycopy); 1.379 + __ br(Assembler::equal, true, Assembler::pt, entry_jbyte_arraycopy); 1.380 __ delayed()->signx(length, count); // length 1.381 1.382 __ cmp(G3_elsize, LogBytesPerShort); 1.383 - __ br(Assembler::equal,true,Assembler::pt,StubRoutines::_jshort_arraycopy); 1.384 + __ br(Assembler::equal, true, Assembler::pt, entry_jshort_arraycopy); 1.385 __ delayed()->signx(length, count); // length 1.386 1.387 __ cmp(G3_elsize, LogBytesPerInt); 1.388 - __ br(Assembler::equal,true,Assembler::pt,StubRoutines::_jint_arraycopy); 1.389 + __ br(Assembler::equal, true, Assembler::pt, entry_jint_arraycopy); 1.390 __ delayed()->signx(length, count); // length 1.391 #ifdef ASSERT 1.392 { Label L; 1.393 @@ -2989,7 +2996,7 @@ 1.394 __ bind(L); 1.395 } 1.396 #endif 1.397 - __ br(Assembler::always,false,Assembler::pt,StubRoutines::_jlong_arraycopy); 1.398 + __ br(Assembler::always, false, Assembler::pt, entry_jlong_arraycopy); 1.399 __ delayed()->signx(length, count); // length 1.400 1.401 // objArrayKlass 1.402 @@ -3013,7 +3020,7 @@ 1.403 __ add(src, src_pos, from); // src_addr 1.404 __ add(dst, dst_pos, to); // dst_addr 1.405 __ BIND(L_plain_copy); 1.406 - __ br(Assembler::always, false, Assembler::pt,StubRoutines::_oop_arraycopy); 1.407 + __ br(Assembler::always, false, Assembler::pt, entry_oop_arraycopy); 1.408 __ delayed()->signx(length, count); // length 1.409 1.410 __ BIND(L_checkcast_copy); 1.411 @@ -3057,7 +3064,7 @@ 1.412 __ ld_ptr(G4_dst_klass, ek_offset, O4); // dest elem klass 1.413 // lduw(O4, sco_offset, O3); // sco of elem klass 1.414 1.415 - __ br(Assembler::always, false, Assembler::pt, checkcast_copy_entry); 1.416 + __ br(Assembler::always, false, Assembler::pt, entry_checkcast_arraycopy); 1.417 __ delayed()->lduw(O4, sco_offset, O3); 1.418 } 1.419 1.420 @@ -3068,39 +3075,76 @@ 1.421 } 1.422 1.423 void generate_arraycopy_stubs() { 1.424 - 1.425 - // Note: the disjoint stubs must be generated first, some of 1.426 - // the conjoint stubs use them. 1.427 - StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(false, "jbyte_disjoint_arraycopy"); 1.428 - StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(false, "jshort_disjoint_arraycopy"); 1.429 - StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_int_copy(false, "jint_disjoint_arraycopy"); 1.430 - StubRoutines::_jlong_disjoint_arraycopy = generate_disjoint_long_copy(false, "jlong_disjoint_arraycopy"); 1.431 - StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_oop_copy(false, "oop_disjoint_arraycopy"); 1.432 - StubRoutines::_arrayof_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(true, "arrayof_jbyte_disjoint_arraycopy"); 1.433 - StubRoutines::_arrayof_jshort_disjoint_arraycopy = generate_disjoint_short_copy(true, "arrayof_jshort_disjoint_arraycopy"); 1.434 - StubRoutines::_arrayof_jint_disjoint_arraycopy = generate_disjoint_int_copy(true, "arrayof_jint_disjoint_arraycopy"); 1.435 - StubRoutines::_arrayof_jlong_disjoint_arraycopy = generate_disjoint_long_copy(true, "arrayof_jlong_disjoint_arraycopy"); 1.436 - StubRoutines::_arrayof_oop_disjoint_arraycopy = generate_disjoint_oop_copy(true, "arrayof_oop_disjoint_arraycopy"); 1.437 - 1.438 - StubRoutines::_jbyte_arraycopy = generate_conjoint_byte_copy(false, "jbyte_arraycopy"); 1.439 - StubRoutines::_jshort_arraycopy = generate_conjoint_short_copy(false, "jshort_arraycopy"); 1.440 - StubRoutines::_jint_arraycopy = generate_conjoint_int_copy(false, "jint_arraycopy"); 1.441 - StubRoutines::_jlong_arraycopy = generate_conjoint_long_copy(false, "jlong_arraycopy"); 1.442 - StubRoutines::_oop_arraycopy = generate_conjoint_oop_copy(false, "oop_arraycopy"); 1.443 - StubRoutines::_arrayof_jbyte_arraycopy = generate_conjoint_byte_copy(true, "arrayof_jbyte_arraycopy"); 1.444 - StubRoutines::_arrayof_jshort_arraycopy = generate_conjoint_short_copy(true, "arrayof_jshort_arraycopy"); 1.445 + address entry; 1.446 + address entry_jbyte_arraycopy; 1.447 + address entry_jshort_arraycopy; 1.448 + address entry_jint_arraycopy; 1.449 + address entry_oop_arraycopy; 1.450 + address entry_jlong_arraycopy; 1.451 + address entry_checkcast_arraycopy; 1.452 + 1.453 + StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(false, &entry, 1.454 + "jbyte_disjoint_arraycopy"); 1.455 + StubRoutines::_jbyte_arraycopy = generate_conjoint_byte_copy(false, entry, &entry_jbyte_arraycopy, 1.456 + "jbyte_arraycopy"); 1.457 + StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(false, &entry, 1.458 + "jshort_disjoint_arraycopy"); 1.459 + StubRoutines::_jshort_arraycopy = generate_conjoint_short_copy(false, entry, &entry_jshort_arraycopy, 1.460 + "jshort_arraycopy"); 1.461 + StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_int_copy(false, &entry, 1.462 + "jint_disjoint_arraycopy"); 1.463 + StubRoutines::_jint_arraycopy = generate_conjoint_int_copy(false, entry, &entry_jint_arraycopy, 1.464 + "jint_arraycopy"); 1.465 + StubRoutines::_jlong_disjoint_arraycopy = generate_disjoint_long_copy(false, &entry, 1.466 + "jlong_disjoint_arraycopy"); 1.467 + StubRoutines::_jlong_arraycopy = generate_conjoint_long_copy(false, entry, &entry_jlong_arraycopy, 1.468 + "jlong_arraycopy"); 1.469 + StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_oop_copy(false, &entry, 1.470 + "oop_disjoint_arraycopy"); 1.471 + StubRoutines::_oop_arraycopy = generate_conjoint_oop_copy(false, entry, &entry_oop_arraycopy, 1.472 + "oop_arraycopy"); 1.473 + 1.474 + 1.475 + StubRoutines::_arrayof_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(true, &entry, 1.476 + "arrayof_jbyte_disjoint_arraycopy"); 1.477 + StubRoutines::_arrayof_jbyte_arraycopy = generate_conjoint_byte_copy(true, entry, NULL, 1.478 + "arrayof_jbyte_arraycopy"); 1.479 + 1.480 + StubRoutines::_arrayof_jshort_disjoint_arraycopy = generate_disjoint_short_copy(true, &entry, 1.481 + "arrayof_jshort_disjoint_arraycopy"); 1.482 + StubRoutines::_arrayof_jshort_arraycopy = generate_conjoint_short_copy(true, entry, NULL, 1.483 + "arrayof_jshort_arraycopy"); 1.484 + 1.485 + StubRoutines::_arrayof_jint_disjoint_arraycopy = generate_disjoint_int_copy(true, &entry, 1.486 + "arrayof_jint_disjoint_arraycopy"); 1.487 #ifdef _LP64 1.488 // since sizeof(jint) < sizeof(HeapWord), there's a different flavor: 1.489 - StubRoutines::_arrayof_jint_arraycopy = generate_conjoint_int_copy(true, "arrayof_jint_arraycopy"); 1.490 + StubRoutines::_arrayof_jint_arraycopy = generate_conjoint_int_copy(true, entry, NULL, "arrayof_jint_arraycopy"); 1.491 #else 1.492 StubRoutines::_arrayof_jint_arraycopy = StubRoutines::_jint_arraycopy; 1.493 #endif 1.494 + 1.495 + StubRoutines::_arrayof_jlong_disjoint_arraycopy = generate_disjoint_long_copy(true, NULL, 1.496 + "arrayof_jlong_disjoint_arraycopy"); 1.497 + StubRoutines::_arrayof_oop_disjoint_arraycopy = generate_disjoint_oop_copy(true, NULL, 1.498 + "arrayof_oop_disjoint_arraycopy"); 1.499 + 1.500 StubRoutines::_arrayof_jlong_arraycopy = StubRoutines::_jlong_arraycopy; 1.501 StubRoutines::_arrayof_oop_arraycopy = StubRoutines::_oop_arraycopy; 1.502 1.503 - StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy"); 1.504 - StubRoutines::_unsafe_arraycopy = generate_unsafe_copy("unsafe_arraycopy"); 1.505 - StubRoutines::_generic_arraycopy = generate_generic_copy("generic_arraycopy"); 1.506 + StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy", &entry_checkcast_arraycopy); 1.507 + StubRoutines::_unsafe_arraycopy = generate_unsafe_copy("unsafe_arraycopy", 1.508 + entry_jbyte_arraycopy, 1.509 + entry_jshort_arraycopy, 1.510 + entry_jint_arraycopy, 1.511 + entry_jlong_arraycopy); 1.512 + StubRoutines::_generic_arraycopy = generate_generic_copy("generic_arraycopy", 1.513 + entry_jbyte_arraycopy, 1.514 + entry_jshort_arraycopy, 1.515 + entry_jint_arraycopy, 1.516 + entry_oop_arraycopy, 1.517 + entry_jlong_arraycopy, 1.518 + entry_checkcast_arraycopy); 1.519 1.520 StubRoutines::_jbyte_fill = generate_fill(T_BYTE, false, "jbyte_fill"); 1.521 StubRoutines::_jshort_fill = generate_fill(T_SHORT, false, "jshort_fill"); 1.522 @@ -3224,21 +3268,6 @@ 1.523 1.524 }; // end class declaration 1.525 1.526 - 1.527 -address StubGenerator::disjoint_byte_copy_entry = NULL; 1.528 -address StubGenerator::disjoint_short_copy_entry = NULL; 1.529 -address StubGenerator::disjoint_int_copy_entry = NULL; 1.530 -address StubGenerator::disjoint_long_copy_entry = NULL; 1.531 -address StubGenerator::disjoint_oop_copy_entry = NULL; 1.532 - 1.533 -address StubGenerator::byte_copy_entry = NULL; 1.534 -address StubGenerator::short_copy_entry = NULL; 1.535 -address StubGenerator::int_copy_entry = NULL; 1.536 -address StubGenerator::long_copy_entry = NULL; 1.537 -address StubGenerator::oop_copy_entry = NULL; 1.538 - 1.539 -address StubGenerator::checkcast_copy_entry = NULL; 1.540 - 1.541 void StubGenerator_generate(CodeBuffer* code, bool all) { 1.542 StubGenerator g(code, all); 1.543 }
2.1 --- a/src/cpu/x86/vm/stubGenerator_x86_32.cpp Wed Feb 09 15:02:23 2011 -0800 2.2 +++ b/src/cpu/x86/vm/stubGenerator_x86_32.cpp Tue Feb 22 15:25:02 2011 -0800 2.3 @@ -945,6 +945,12 @@ 2.4 __ movptr(from , Address(rsp, 12+ 4)); 2.5 __ movptr(to , Address(rsp, 12+ 8)); 2.6 __ movl(count, Address(rsp, 12+ 12)); 2.7 + 2.8 + if (entry != NULL) { 2.9 + *entry = __ pc(); // Entry point from conjoint arraycopy stub. 2.10 + BLOCK_COMMENT("Entry:"); 2.11 + } 2.12 + 2.13 if (t == T_OBJECT) { 2.14 __ testl(count, count); 2.15 __ jcc(Assembler::zero, L_0_count); 2.16 @@ -952,9 +958,6 @@ 2.17 __ mov(saved_to, to); // save 'to' 2.18 } 2.19 2.20 - *entry = __ pc(); // Entry point from conjoint arraycopy stub. 2.21 - BLOCK_COMMENT("Entry:"); 2.22 - 2.23 __ subptr(to, from); // to --> to_from 2.24 __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element 2.25 __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp 2.26 @@ -1108,23 +1111,17 @@ 2.27 __ movptr(src , Address(rsp, 12+ 4)); // from 2.28 __ movptr(dst , Address(rsp, 12+ 8)); // to 2.29 __ movl2ptr(count, Address(rsp, 12+12)); // count 2.30 - if (t == T_OBJECT) { 2.31 - gen_write_ref_array_pre_barrier(dst, count); 2.32 - } 2.33 2.34 if (entry != NULL) { 2.35 *entry = __ pc(); // Entry point from generic arraycopy stub. 2.36 BLOCK_COMMENT("Entry:"); 2.37 } 2.38 2.39 - if (t == T_OBJECT) { 2.40 - __ testl(count, count); 2.41 - __ jcc(Assembler::zero, L_0_count); 2.42 - } 2.43 + // nooverlap_target expects arguments in rsi and rdi. 2.44 __ mov(from, src); 2.45 __ mov(to , dst); 2.46 2.47 - // arrays overlap test 2.48 + // arrays overlap test: dispatch to disjoint stub if necessary. 2.49 RuntimeAddress nooverlap(nooverlap_target); 2.50 __ cmpptr(dst, src); 2.51 __ lea(end, Address(src, count, sf, 0)); // src + count * elem_size 2.52 @@ -1132,6 +1129,12 @@ 2.53 __ cmpptr(dst, end); 2.54 __ jump_cc(Assembler::aboveEqual, nooverlap); 2.55 2.56 + if (t == T_OBJECT) { 2.57 + __ testl(count, count); 2.58 + __ jcc(Assembler::zero, L_0_count); 2.59 + gen_write_ref_array_pre_barrier(dst, count); 2.60 + } 2.61 + 2.62 // copy from high to low 2.63 __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element 2.64 __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp 2.65 @@ -1451,8 +1454,10 @@ 2.66 __ movptr(to, to_arg); 2.67 __ movl2ptr(length, length_arg); 2.68 2.69 - *entry = __ pc(); // Entry point from generic arraycopy stub. 2.70 - BLOCK_COMMENT("Entry:"); 2.71 + if (entry != NULL) { 2.72 + *entry = __ pc(); // Entry point from generic arraycopy stub. 2.73 + BLOCK_COMMENT("Entry:"); 2.74 + } 2.75 2.76 //--------------------------------------------------------------- 2.77 // Assembler stub will be used for this call to arraycopy
3.1 --- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp Wed Feb 09 15:02:23 2011 -0800 3.2 +++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp Tue Feb 22 15:25:02 2011 -0800 3.3 @@ -1,5 +1,5 @@ 3.4 /* 3.5 - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 3.6 + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. 3.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.8 * 3.9 * This code is free software; you can redistribute it and/or modify it 3.10 @@ -1057,20 +1057,6 @@ 3.11 return start; 3.12 } 3.13 3.14 - static address disjoint_byte_copy_entry; 3.15 - static address disjoint_short_copy_entry; 3.16 - static address disjoint_int_copy_entry; 3.17 - static address disjoint_long_copy_entry; 3.18 - static address disjoint_oop_copy_entry; 3.19 - 3.20 - static address byte_copy_entry; 3.21 - static address short_copy_entry; 3.22 - static address int_copy_entry; 3.23 - static address long_copy_entry; 3.24 - static address oop_copy_entry; 3.25 - 3.26 - static address checkcast_copy_entry; 3.27 - 3.28 // 3.29 // Verify that a register contains clean 32-bits positive value 3.30 // (high 32-bits are 0) so it could be used in 64-bits shifts. 3.31 @@ -1379,7 +1365,7 @@ 3.32 // disjoint_byte_copy_entry is set to the no-overlap entry point 3.33 // used by generate_conjoint_byte_copy(). 3.34 // 3.35 - address generate_disjoint_byte_copy(bool aligned, const char *name) { 3.36 + address generate_disjoint_byte_copy(bool aligned, address* entry, const char *name) { 3.37 __ align(CodeEntryAlignment); 3.38 StubCodeMark mark(this, "StubRoutines", name); 3.39 address start = __ pc(); 3.40 @@ -1399,9 +1385,11 @@ 3.41 __ enter(); // required for proper stackwalking of RuntimeStub frame 3.42 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int. 3.43 3.44 - disjoint_byte_copy_entry = __ pc(); 3.45 - BLOCK_COMMENT("Entry:"); 3.46 - // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 3.47 + if (entry != NULL) { 3.48 + *entry = __ pc(); 3.49 + // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 3.50 + BLOCK_COMMENT("Entry:"); 3.51 + } 3.52 3.53 setup_arg_regs(); // from => rdi, to => rsi, count => rdx 3.54 // r9 and r10 may be used to save non-volatile registers 3.55 @@ -1479,7 +1467,8 @@ 3.56 // dwords or qwords that span cache line boundaries will still be loaded 3.57 // and stored atomically. 3.58 // 3.59 - address generate_conjoint_byte_copy(bool aligned, const char *name) { 3.60 + address generate_conjoint_byte_copy(bool aligned, address nooverlap_target, 3.61 + address* entry, const char *name) { 3.62 __ align(CodeEntryAlignment); 3.63 StubCodeMark mark(this, "StubRoutines", name); 3.64 address start = __ pc(); 3.65 @@ -1494,11 +1483,13 @@ 3.66 __ enter(); // required for proper stackwalking of RuntimeStub frame 3.67 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int. 3.68 3.69 - byte_copy_entry = __ pc(); 3.70 - BLOCK_COMMENT("Entry:"); 3.71 - // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 3.72 - 3.73 - array_overlap_test(disjoint_byte_copy_entry, Address::times_1); 3.74 + if (entry != NULL) { 3.75 + *entry = __ pc(); 3.76 + // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 3.77 + BLOCK_COMMENT("Entry:"); 3.78 + } 3.79 + 3.80 + array_overlap_test(nooverlap_target, Address::times_1); 3.81 setup_arg_regs(); // from => rdi, to => rsi, count => rdx 3.82 // r9 and r10 may be used to save non-volatile registers 3.83 3.84 @@ -1574,7 +1565,7 @@ 3.85 // disjoint_short_copy_entry is set to the no-overlap entry point 3.86 // used by generate_conjoint_short_copy(). 3.87 // 3.88 - address generate_disjoint_short_copy(bool aligned, const char *name) { 3.89 + address generate_disjoint_short_copy(bool aligned, address *entry, const char *name) { 3.90 __ align(CodeEntryAlignment); 3.91 StubCodeMark mark(this, "StubRoutines", name); 3.92 address start = __ pc(); 3.93 @@ -1593,9 +1584,11 @@ 3.94 __ enter(); // required for proper stackwalking of RuntimeStub frame 3.95 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int. 3.96 3.97 - disjoint_short_copy_entry = __ pc(); 3.98 - BLOCK_COMMENT("Entry:"); 3.99 - // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 3.100 + if (entry != NULL) { 3.101 + *entry = __ pc(); 3.102 + // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 3.103 + BLOCK_COMMENT("Entry:"); 3.104 + } 3.105 3.106 setup_arg_regs(); // from => rdi, to => rsi, count => rdx 3.107 // r9 and r10 may be used to save non-volatile registers 3.108 @@ -1686,7 +1679,8 @@ 3.109 // or qwords that span cache line boundaries will still be loaded 3.110 // and stored atomically. 3.111 // 3.112 - address generate_conjoint_short_copy(bool aligned, const char *name) { 3.113 + address generate_conjoint_short_copy(bool aligned, address nooverlap_target, 3.114 + address *entry, const char *name) { 3.115 __ align(CodeEntryAlignment); 3.116 StubCodeMark mark(this, "StubRoutines", name); 3.117 address start = __ pc(); 3.118 @@ -1701,11 +1695,13 @@ 3.119 __ enter(); // required for proper stackwalking of RuntimeStub frame 3.120 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int. 3.121 3.122 - short_copy_entry = __ pc(); 3.123 - BLOCK_COMMENT("Entry:"); 3.124 - // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 3.125 - 3.126 - array_overlap_test(disjoint_short_copy_entry, Address::times_2); 3.127 + if (entry != NULL) { 3.128 + *entry = __ pc(); 3.129 + // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 3.130 + BLOCK_COMMENT("Entry:"); 3.131 + } 3.132 + 3.133 + array_overlap_test(nooverlap_target, Address::times_2); 3.134 setup_arg_regs(); // from => rdi, to => rsi, count => rdx 3.135 // r9 and r10 may be used to save non-volatile registers 3.136 3.137 @@ -1773,7 +1769,7 @@ 3.138 // disjoint_int_copy_entry is set to the no-overlap entry point 3.139 // used by generate_conjoint_int_oop_copy(). 3.140 // 3.141 - address generate_disjoint_int_oop_copy(bool aligned, bool is_oop, const char *name) { 3.142 + address generate_disjoint_int_oop_copy(bool aligned, bool is_oop, address* entry, const char *name) { 3.143 __ align(CodeEntryAlignment); 3.144 StubCodeMark mark(this, "StubRoutines", name); 3.145 address start = __ pc(); 3.146 @@ -1793,21 +1789,17 @@ 3.147 __ enter(); // required for proper stackwalking of RuntimeStub frame 3.148 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int. 3.149 3.150 - (is_oop ? disjoint_oop_copy_entry : disjoint_int_copy_entry) = __ pc(); 3.151 - 3.152 - if (is_oop) { 3.153 - // no registers are destroyed by this call 3.154 - gen_write_ref_array_pre_barrier(/* dest */ c_rarg1, /* count */ c_rarg2); 3.155 + if (entry != NULL) { 3.156 + *entry = __ pc(); 3.157 + // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 3.158 + BLOCK_COMMENT("Entry:"); 3.159 } 3.160 3.161 - BLOCK_COMMENT("Entry:"); 3.162 - // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 3.163 - 3.164 setup_arg_regs(); // from => rdi, to => rsi, count => rdx 3.165 // r9 and r10 may be used to save non-volatile registers 3.166 - 3.167 if (is_oop) { 3.168 __ movq(saved_to, to); 3.169 + gen_write_ref_array_pre_barrier(to, count); 3.170 } 3.171 3.172 // 'from', 'to' and 'count' are now valid 3.173 @@ -1867,7 +1859,8 @@ 3.174 // the hardware handle it. The two dwords within qwords that span 3.175 // cache line boundaries will still be loaded and stored atomicly. 3.176 // 3.177 - address generate_conjoint_int_oop_copy(bool aligned, bool is_oop, const char *name) { 3.178 + address generate_conjoint_int_oop_copy(bool aligned, bool is_oop, address nooverlap_target, 3.179 + address *entry, const char *name) { 3.180 __ align(CodeEntryAlignment); 3.181 StubCodeMark mark(this, "StubRoutines", name); 3.182 address start = __ pc(); 3.183 @@ -1882,20 +1875,21 @@ 3.184 __ enter(); // required for proper stackwalking of RuntimeStub frame 3.185 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int. 3.186 3.187 + if (entry != NULL) { 3.188 + *entry = __ pc(); 3.189 + // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 3.190 + BLOCK_COMMENT("Entry:"); 3.191 + } 3.192 + 3.193 + array_overlap_test(nooverlap_target, Address::times_4); 3.194 + setup_arg_regs(); // from => rdi, to => rsi, count => rdx 3.195 + // r9 and r10 may be used to save non-volatile registers 3.196 + 3.197 if (is_oop) { 3.198 // no registers are destroyed by this call 3.199 - gen_write_ref_array_pre_barrier(/* dest */ c_rarg1, /* count */ c_rarg2); 3.200 + gen_write_ref_array_pre_barrier(to, count); 3.201 } 3.202 3.203 - (is_oop ? oop_copy_entry : int_copy_entry) = __ pc(); 3.204 - BLOCK_COMMENT("Entry:"); 3.205 - // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 3.206 - 3.207 - array_overlap_test(is_oop ? disjoint_oop_copy_entry : disjoint_int_copy_entry, 3.208 - Address::times_4); 3.209 - setup_arg_regs(); // from => rdi, to => rsi, count => rdx 3.210 - // r9 and r10 may be used to save non-volatile registers 3.211 - 3.212 assert_clean_int(count, rax); // Make sure 'count' is clean int. 3.213 // 'from', 'to' and 'count' are now valid 3.214 __ movptr(dword_count, count); 3.215 @@ -1959,7 +1953,7 @@ 3.216 // disjoint_oop_copy_entry or disjoint_long_copy_entry is set to the 3.217 // no-overlap entry point used by generate_conjoint_long_oop_copy(). 3.218 // 3.219 - address generate_disjoint_long_oop_copy(bool aligned, bool is_oop, const char *name) { 3.220 + address generate_disjoint_long_oop_copy(bool aligned, bool is_oop, address *entry, const char *name) { 3.221 __ align(CodeEntryAlignment); 3.222 StubCodeMark mark(this, "StubRoutines", name); 3.223 address start = __ pc(); 3.224 @@ -1978,20 +1972,19 @@ 3.225 // Save no-overlap entry point for generate_conjoint_long_oop_copy() 3.226 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int. 3.227 3.228 - if (is_oop) { 3.229 - disjoint_oop_copy_entry = __ pc(); 3.230 - // no registers are destroyed by this call 3.231 - gen_write_ref_array_pre_barrier(/* dest */ c_rarg1, /* count */ c_rarg2); 3.232 - } else { 3.233 - disjoint_long_copy_entry = __ pc(); 3.234 + if (entry != NULL) { 3.235 + *entry = __ pc(); 3.236 + // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 3.237 + BLOCK_COMMENT("Entry:"); 3.238 } 3.239 - BLOCK_COMMENT("Entry:"); 3.240 - // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 3.241 3.242 setup_arg_regs(); // from => rdi, to => rsi, count => rdx 3.243 // r9 and r10 may be used to save non-volatile registers 3.244 - 3.245 // 'from', 'to' and 'qword_count' are now valid 3.246 + if (is_oop) { 3.247 + // no registers are destroyed by this call 3.248 + gen_write_ref_array_pre_barrier(to, qword_count); 3.249 + } 3.250 3.251 // Copy from low to high addresses. Use 'to' as scratch. 3.252 __ lea(end_from, Address(from, qword_count, Address::times_8, -8)); 3.253 @@ -2045,7 +2038,8 @@ 3.254 // c_rarg1 - destination array address 3.255 // c_rarg2 - element count, treated as ssize_t, can be zero 3.256 // 3.257 - address generate_conjoint_long_oop_copy(bool aligned, bool is_oop, const char *name) { 3.258 + address generate_conjoint_long_oop_copy(bool aligned, bool is_oop, address nooverlap_target, 3.259 + address *entry, const char *name) { 3.260 __ align(CodeEntryAlignment); 3.261 StubCodeMark mark(this, "StubRoutines", name); 3.262 address start = __ pc(); 3.263 @@ -2059,26 +2053,16 @@ 3.264 __ enter(); // required for proper stackwalking of RuntimeStub frame 3.265 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int. 3.266 3.267 - address disjoint_copy_entry = NULL; 3.268 - if (is_oop) { 3.269 - assert(!UseCompressedOops, "shouldn't be called for compressed oops"); 3.270 - disjoint_copy_entry = disjoint_oop_copy_entry; 3.271 - oop_copy_entry = __ pc(); 3.272 - array_overlap_test(disjoint_oop_copy_entry, Address::times_8); 3.273 - } else { 3.274 - disjoint_copy_entry = disjoint_long_copy_entry; 3.275 - long_copy_entry = __ pc(); 3.276 - array_overlap_test(disjoint_long_copy_entry, Address::times_8); 3.277 + if (entry != NULL) { 3.278 + *entry = __ pc(); 3.279 + // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 3.280 + BLOCK_COMMENT("Entry:"); 3.281 } 3.282 - BLOCK_COMMENT("Entry:"); 3.283 - // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 3.284 - 3.285 - array_overlap_test(disjoint_copy_entry, Address::times_8); 3.286 + 3.287 + array_overlap_test(nooverlap_target, Address::times_8); 3.288 setup_arg_regs(); // from => rdi, to => rsi, count => rdx 3.289 // r9 and r10 may be used to save non-volatile registers 3.290 - 3.291 // 'from', 'to' and 'qword_count' are now valid 3.292 - 3.293 if (is_oop) { 3.294 // Save to and count for store barrier 3.295 __ movptr(saved_count, qword_count); 3.296 @@ -2162,7 +2146,7 @@ 3.297 // rax == 0 - success 3.298 // rax == -1^K - failure, where K is partial transfer count 3.299 // 3.300 - address generate_checkcast_copy(const char *name) { 3.301 + address generate_checkcast_copy(const char *name, address *entry) { 3.302 3.303 Label L_load_element, L_store_element, L_do_card_marks, L_done; 3.304 3.305 @@ -2216,8 +2200,10 @@ 3.306 #endif 3.307 3.308 // Caller of this entry point must set up the argument registers. 3.309 - checkcast_copy_entry = __ pc(); 3.310 - BLOCK_COMMENT("Entry:"); 3.311 + if (entry != NULL) { 3.312 + *entry = __ pc(); 3.313 + BLOCK_COMMENT("Entry:"); 3.314 + } 3.315 3.316 // allocate spill slots for r13, r14 3.317 enum { 3.318 @@ -2334,7 +2320,9 @@ 3.319 // Examines the alignment of the operands and dispatches 3.320 // to a long, int, short, or byte copy loop. 3.321 // 3.322 - address generate_unsafe_copy(const char *name) { 3.323 + address generate_unsafe_copy(const char *name, 3.324 + address byte_copy_entry, address short_copy_entry, 3.325 + address int_copy_entry, address long_copy_entry) { 3.326 3.327 Label L_long_aligned, L_int_aligned, L_short_aligned; 3.328 3.329 @@ -2432,7 +2420,10 @@ 3.330 // rax == 0 - success 3.331 // rax == -1^K - failure, where K is partial transfer count 3.332 // 3.333 - address generate_generic_copy(const char *name) { 3.334 + address generate_generic_copy(const char *name, 3.335 + address byte_copy_entry, address short_copy_entry, 3.336 + address int_copy_entry, address long_copy_entry, 3.337 + address oop_copy_entry, address checkcast_copy_entry) { 3.338 3.339 Label L_failed, L_failed_0, L_objArray; 3.340 Label L_copy_bytes, L_copy_shorts, L_copy_ints, L_copy_longs; 3.341 @@ -2725,33 +2716,60 @@ 3.342 } 3.343 3.344 void generate_arraycopy_stubs() { 3.345 - // Call the conjoint generation methods immediately after 3.346 - // the disjoint ones so that short branches from the former 3.347 - // to the latter can be generated. 3.348 - StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(false, "jbyte_disjoint_arraycopy"); 3.349 - StubRoutines::_jbyte_arraycopy = generate_conjoint_byte_copy(false, "jbyte_arraycopy"); 3.350 - 3.351 - StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(false, "jshort_disjoint_arraycopy"); 3.352 - StubRoutines::_jshort_arraycopy = generate_conjoint_short_copy(false, "jshort_arraycopy"); 3.353 - 3.354 - StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_int_oop_copy(false, false, "jint_disjoint_arraycopy"); 3.355 - StubRoutines::_jint_arraycopy = generate_conjoint_int_oop_copy(false, false, "jint_arraycopy"); 3.356 - 3.357 - StubRoutines::_jlong_disjoint_arraycopy = generate_disjoint_long_oop_copy(false, false, "jlong_disjoint_arraycopy"); 3.358 - StubRoutines::_jlong_arraycopy = generate_conjoint_long_oop_copy(false, false, "jlong_arraycopy"); 3.359 + address entry; 3.360 + address entry_jbyte_arraycopy; 3.361 + address entry_jshort_arraycopy; 3.362 + address entry_jint_arraycopy; 3.363 + address entry_oop_arraycopy; 3.364 + address entry_jlong_arraycopy; 3.365 + address entry_checkcast_arraycopy; 3.366 + 3.367 + StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(false, &entry, 3.368 + "jbyte_disjoint_arraycopy"); 3.369 + StubRoutines::_jbyte_arraycopy = generate_conjoint_byte_copy(false, entry, &entry_jbyte_arraycopy, 3.370 + "jbyte_arraycopy"); 3.371 + 3.372 + StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(false, &entry, 3.373 + "jshort_disjoint_arraycopy"); 3.374 + StubRoutines::_jshort_arraycopy = generate_conjoint_short_copy(false, entry, &entry_jshort_arraycopy, 3.375 + "jshort_arraycopy"); 3.376 + 3.377 + StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_int_oop_copy(false, false, &entry, 3.378 + "jint_disjoint_arraycopy"); 3.379 + StubRoutines::_jint_arraycopy = generate_conjoint_int_oop_copy(false, false, entry, 3.380 + &entry_jint_arraycopy, "jint_arraycopy"); 3.381 + 3.382 + StubRoutines::_jlong_disjoint_arraycopy = generate_disjoint_long_oop_copy(false, false, &entry, 3.383 + "jlong_disjoint_arraycopy"); 3.384 + StubRoutines::_jlong_arraycopy = generate_conjoint_long_oop_copy(false, false, entry, 3.385 + &entry_jlong_arraycopy, "jlong_arraycopy"); 3.386 3.387 3.388 if (UseCompressedOops) { 3.389 - StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_int_oop_copy(false, true, "oop_disjoint_arraycopy"); 3.390 - StubRoutines::_oop_arraycopy = generate_conjoint_int_oop_copy(false, true, "oop_arraycopy"); 3.391 + StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_int_oop_copy(false, true, &entry, 3.392 + "oop_disjoint_arraycopy"); 3.393 + StubRoutines::_oop_arraycopy = generate_conjoint_int_oop_copy(false, true, entry, 3.394 + &entry_oop_arraycopy, "oop_arraycopy"); 3.395 } else { 3.396 - StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_long_oop_copy(false, true, "oop_disjoint_arraycopy"); 3.397 - StubRoutines::_oop_arraycopy = generate_conjoint_long_oop_copy(false, true, "oop_arraycopy"); 3.398 + StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_long_oop_copy(false, true, &entry, 3.399 + "oop_disjoint_arraycopy"); 3.400 + StubRoutines::_oop_arraycopy = generate_conjoint_long_oop_copy(false, true, entry, 3.401 + &entry_oop_arraycopy, "oop_arraycopy"); 3.402 } 3.403 3.404 - StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy"); 3.405 - StubRoutines::_unsafe_arraycopy = generate_unsafe_copy("unsafe_arraycopy"); 3.406 - StubRoutines::_generic_arraycopy = generate_generic_copy("generic_arraycopy"); 3.407 + StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy", &entry_checkcast_arraycopy); 3.408 + StubRoutines::_unsafe_arraycopy = generate_unsafe_copy("unsafe_arraycopy", 3.409 + entry_jbyte_arraycopy, 3.410 + entry_jshort_arraycopy, 3.411 + entry_jint_arraycopy, 3.412 + entry_jlong_arraycopy); 3.413 + StubRoutines::_generic_arraycopy = generate_generic_copy("generic_arraycopy", 3.414 + entry_jbyte_arraycopy, 3.415 + entry_jshort_arraycopy, 3.416 + entry_jint_arraycopy, 3.417 + entry_oop_arraycopy, 3.418 + entry_jlong_arraycopy, 3.419 + entry_checkcast_arraycopy); 3.420 3.421 StubRoutines::_jbyte_fill = generate_fill(T_BYTE, false, "jbyte_fill"); 3.422 StubRoutines::_jshort_fill = generate_fill(T_SHORT, false, "jshort_fill"); 3.423 @@ -3069,20 +3087,6 @@ 3.424 } 3.425 }; // end class declaration 3.426 3.427 -address StubGenerator::disjoint_byte_copy_entry = NULL; 3.428 -address StubGenerator::disjoint_short_copy_entry = NULL; 3.429 -address StubGenerator::disjoint_int_copy_entry = NULL; 3.430 -address StubGenerator::disjoint_long_copy_entry = NULL; 3.431 -address StubGenerator::disjoint_oop_copy_entry = NULL; 3.432 - 3.433 -address StubGenerator::byte_copy_entry = NULL; 3.434 -address StubGenerator::short_copy_entry = NULL; 3.435 -address StubGenerator::int_copy_entry = NULL; 3.436 -address StubGenerator::long_copy_entry = NULL; 3.437 -address StubGenerator::oop_copy_entry = NULL; 3.438 - 3.439 -address StubGenerator::checkcast_copy_entry = NULL; 3.440 - 3.441 void StubGenerator_generate(CodeBuffer* code, bool all) { 3.442 StubGenerator g(code, all); 3.443 }