1.1 --- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp Wed Feb 09 15:02:23 2011 -0800 1.2 +++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp Tue Feb 22 15:25:02 2011 -0800 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2003, 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 @@ -1057,20 +1057,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 // (high 32-bits are 0) so it could be used in 64-bits shifts. 1.31 @@ -1379,7 +1365,7 @@ 1.32 // disjoint_byte_copy_entry is set to the no-overlap entry point 1.33 // used by generate_conjoint_byte_copy(). 1.34 // 1.35 - address generate_disjoint_byte_copy(bool aligned, const char *name) { 1.36 + address generate_disjoint_byte_copy(bool aligned, address* entry, const char *name) { 1.37 __ align(CodeEntryAlignment); 1.38 StubCodeMark mark(this, "StubRoutines", name); 1.39 address start = __ pc(); 1.40 @@ -1399,9 +1385,11 @@ 1.41 __ enter(); // required for proper stackwalking of RuntimeStub frame 1.42 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int. 1.43 1.44 - disjoint_byte_copy_entry = __ pc(); 1.45 - BLOCK_COMMENT("Entry:"); 1.46 - // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.47 + if (entry != NULL) { 1.48 + *entry = __ pc(); 1.49 + // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.50 + BLOCK_COMMENT("Entry:"); 1.51 + } 1.52 1.53 setup_arg_regs(); // from => rdi, to => rsi, count => rdx 1.54 // r9 and r10 may be used to save non-volatile registers 1.55 @@ -1479,7 +1467,8 @@ 1.56 // dwords or qwords that span cache line boundaries will still be loaded 1.57 // and stored atomically. 1.58 // 1.59 - address generate_conjoint_byte_copy(bool aligned, const char *name) { 1.60 + address generate_conjoint_byte_copy(bool aligned, address nooverlap_target, 1.61 + address* entry, const char *name) { 1.62 __ align(CodeEntryAlignment); 1.63 StubCodeMark mark(this, "StubRoutines", name); 1.64 address start = __ pc(); 1.65 @@ -1494,11 +1483,13 @@ 1.66 __ enter(); // required for proper stackwalking of RuntimeStub frame 1.67 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int. 1.68 1.69 - byte_copy_entry = __ pc(); 1.70 - BLOCK_COMMENT("Entry:"); 1.71 - // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.72 - 1.73 - array_overlap_test(disjoint_byte_copy_entry, Address::times_1); 1.74 + if (entry != NULL) { 1.75 + *entry = __ pc(); 1.76 + // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.77 + BLOCK_COMMENT("Entry:"); 1.78 + } 1.79 + 1.80 + array_overlap_test(nooverlap_target, Address::times_1); 1.81 setup_arg_regs(); // from => rdi, to => rsi, count => rdx 1.82 // r9 and r10 may be used to save non-volatile registers 1.83 1.84 @@ -1574,7 +1565,7 @@ 1.85 // disjoint_short_copy_entry is set to the no-overlap entry point 1.86 // used by generate_conjoint_short_copy(). 1.87 // 1.88 - address generate_disjoint_short_copy(bool aligned, const char *name) { 1.89 + address generate_disjoint_short_copy(bool aligned, address *entry, const char *name) { 1.90 __ align(CodeEntryAlignment); 1.91 StubCodeMark mark(this, "StubRoutines", name); 1.92 address start = __ pc(); 1.93 @@ -1593,9 +1584,11 @@ 1.94 __ enter(); // required for proper stackwalking of RuntimeStub frame 1.95 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int. 1.96 1.97 - disjoint_short_copy_entry = __ pc(); 1.98 - BLOCK_COMMENT("Entry:"); 1.99 - // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.100 + if (entry != NULL) { 1.101 + *entry = __ pc(); 1.102 + // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.103 + BLOCK_COMMENT("Entry:"); 1.104 + } 1.105 1.106 setup_arg_regs(); // from => rdi, to => rsi, count => rdx 1.107 // r9 and r10 may be used to save non-volatile registers 1.108 @@ -1686,7 +1679,8 @@ 1.109 // or qwords that span cache line boundaries will still be loaded 1.110 // and stored atomically. 1.111 // 1.112 - address generate_conjoint_short_copy(bool aligned, const char *name) { 1.113 + address generate_conjoint_short_copy(bool aligned, address nooverlap_target, 1.114 + address *entry, const char *name) { 1.115 __ align(CodeEntryAlignment); 1.116 StubCodeMark mark(this, "StubRoutines", name); 1.117 address start = __ pc(); 1.118 @@ -1701,11 +1695,13 @@ 1.119 __ enter(); // required for proper stackwalking of RuntimeStub frame 1.120 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int. 1.121 1.122 - short_copy_entry = __ pc(); 1.123 - BLOCK_COMMENT("Entry:"); 1.124 - // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.125 - 1.126 - array_overlap_test(disjoint_short_copy_entry, Address::times_2); 1.127 + if (entry != NULL) { 1.128 + *entry = __ pc(); 1.129 + // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.130 + BLOCK_COMMENT("Entry:"); 1.131 + } 1.132 + 1.133 + array_overlap_test(nooverlap_target, Address::times_2); 1.134 setup_arg_regs(); // from => rdi, to => rsi, count => rdx 1.135 // r9 and r10 may be used to save non-volatile registers 1.136 1.137 @@ -1773,7 +1769,7 @@ 1.138 // disjoint_int_copy_entry is set to the no-overlap entry point 1.139 // used by generate_conjoint_int_oop_copy(). 1.140 // 1.141 - address generate_disjoint_int_oop_copy(bool aligned, bool is_oop, const char *name) { 1.142 + address generate_disjoint_int_oop_copy(bool aligned, bool is_oop, address* entry, const char *name) { 1.143 __ align(CodeEntryAlignment); 1.144 StubCodeMark mark(this, "StubRoutines", name); 1.145 address start = __ pc(); 1.146 @@ -1793,21 +1789,17 @@ 1.147 __ enter(); // required for proper stackwalking of RuntimeStub frame 1.148 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int. 1.149 1.150 - (is_oop ? disjoint_oop_copy_entry : disjoint_int_copy_entry) = __ pc(); 1.151 - 1.152 - if (is_oop) { 1.153 - // no registers are destroyed by this call 1.154 - gen_write_ref_array_pre_barrier(/* dest */ c_rarg1, /* count */ c_rarg2); 1.155 + if (entry != NULL) { 1.156 + *entry = __ pc(); 1.157 + // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.158 + BLOCK_COMMENT("Entry:"); 1.159 } 1.160 1.161 - BLOCK_COMMENT("Entry:"); 1.162 - // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.163 - 1.164 setup_arg_regs(); // from => rdi, to => rsi, count => rdx 1.165 // r9 and r10 may be used to save non-volatile registers 1.166 - 1.167 if (is_oop) { 1.168 __ movq(saved_to, to); 1.169 + gen_write_ref_array_pre_barrier(to, count); 1.170 } 1.171 1.172 // 'from', 'to' and 'count' are now valid 1.173 @@ -1867,7 +1859,8 @@ 1.174 // the hardware handle it. The two dwords within qwords that span 1.175 // cache line boundaries will still be loaded and stored atomicly. 1.176 // 1.177 - address generate_conjoint_int_oop_copy(bool aligned, bool is_oop, const char *name) { 1.178 + address generate_conjoint_int_oop_copy(bool aligned, bool is_oop, address nooverlap_target, 1.179 + address *entry, const char *name) { 1.180 __ align(CodeEntryAlignment); 1.181 StubCodeMark mark(this, "StubRoutines", name); 1.182 address start = __ pc(); 1.183 @@ -1882,20 +1875,21 @@ 1.184 __ enter(); // required for proper stackwalking of RuntimeStub frame 1.185 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int. 1.186 1.187 + if (entry != NULL) { 1.188 + *entry = __ pc(); 1.189 + // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.190 + BLOCK_COMMENT("Entry:"); 1.191 + } 1.192 + 1.193 + array_overlap_test(nooverlap_target, Address::times_4); 1.194 + setup_arg_regs(); // from => rdi, to => rsi, count => rdx 1.195 + // r9 and r10 may be used to save non-volatile registers 1.196 + 1.197 if (is_oop) { 1.198 // no registers are destroyed by this call 1.199 - gen_write_ref_array_pre_barrier(/* dest */ c_rarg1, /* count */ c_rarg2); 1.200 + gen_write_ref_array_pre_barrier(to, count); 1.201 } 1.202 1.203 - (is_oop ? oop_copy_entry : int_copy_entry) = __ pc(); 1.204 - BLOCK_COMMENT("Entry:"); 1.205 - // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.206 - 1.207 - array_overlap_test(is_oop ? disjoint_oop_copy_entry : disjoint_int_copy_entry, 1.208 - Address::times_4); 1.209 - setup_arg_regs(); // from => rdi, to => rsi, count => rdx 1.210 - // r9 and r10 may be used to save non-volatile registers 1.211 - 1.212 assert_clean_int(count, rax); // Make sure 'count' is clean int. 1.213 // 'from', 'to' and 'count' are now valid 1.214 __ movptr(dword_count, count); 1.215 @@ -1959,7 +1953,7 @@ 1.216 // disjoint_oop_copy_entry or disjoint_long_copy_entry is set to the 1.217 // no-overlap entry point used by generate_conjoint_long_oop_copy(). 1.218 // 1.219 - address generate_disjoint_long_oop_copy(bool aligned, bool is_oop, const char *name) { 1.220 + address generate_disjoint_long_oop_copy(bool aligned, bool is_oop, address *entry, const char *name) { 1.221 __ align(CodeEntryAlignment); 1.222 StubCodeMark mark(this, "StubRoutines", name); 1.223 address start = __ pc(); 1.224 @@ -1978,20 +1972,19 @@ 1.225 // Save no-overlap entry point for generate_conjoint_long_oop_copy() 1.226 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int. 1.227 1.228 - if (is_oop) { 1.229 - disjoint_oop_copy_entry = __ pc(); 1.230 - // no registers are destroyed by this call 1.231 - gen_write_ref_array_pre_barrier(/* dest */ c_rarg1, /* count */ c_rarg2); 1.232 - } else { 1.233 - disjoint_long_copy_entry = __ pc(); 1.234 + if (entry != NULL) { 1.235 + *entry = __ pc(); 1.236 + // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.237 + BLOCK_COMMENT("Entry:"); 1.238 } 1.239 - BLOCK_COMMENT("Entry:"); 1.240 - // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.241 1.242 setup_arg_regs(); // from => rdi, to => rsi, count => rdx 1.243 // r9 and r10 may be used to save non-volatile registers 1.244 - 1.245 // 'from', 'to' and 'qword_count' are now valid 1.246 + if (is_oop) { 1.247 + // no registers are destroyed by this call 1.248 + gen_write_ref_array_pre_barrier(to, qword_count); 1.249 + } 1.250 1.251 // Copy from low to high addresses. Use 'to' as scratch. 1.252 __ lea(end_from, Address(from, qword_count, Address::times_8, -8)); 1.253 @@ -2045,7 +2038,8 @@ 1.254 // c_rarg1 - destination array address 1.255 // c_rarg2 - element count, treated as ssize_t, can be zero 1.256 // 1.257 - address generate_conjoint_long_oop_copy(bool aligned, bool is_oop, const char *name) { 1.258 + address generate_conjoint_long_oop_copy(bool aligned, bool is_oop, address nooverlap_target, 1.259 + address *entry, const char *name) { 1.260 __ align(CodeEntryAlignment); 1.261 StubCodeMark mark(this, "StubRoutines", name); 1.262 address start = __ pc(); 1.263 @@ -2059,26 +2053,16 @@ 1.264 __ enter(); // required for proper stackwalking of RuntimeStub frame 1.265 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int. 1.266 1.267 - address disjoint_copy_entry = NULL; 1.268 - if (is_oop) { 1.269 - assert(!UseCompressedOops, "shouldn't be called for compressed oops"); 1.270 - disjoint_copy_entry = disjoint_oop_copy_entry; 1.271 - oop_copy_entry = __ pc(); 1.272 - array_overlap_test(disjoint_oop_copy_entry, Address::times_8); 1.273 - } else { 1.274 - disjoint_copy_entry = disjoint_long_copy_entry; 1.275 - long_copy_entry = __ pc(); 1.276 - array_overlap_test(disjoint_long_copy_entry, Address::times_8); 1.277 + if (entry != NULL) { 1.278 + *entry = __ pc(); 1.279 + // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.280 + BLOCK_COMMENT("Entry:"); 1.281 } 1.282 - BLOCK_COMMENT("Entry:"); 1.283 - // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) 1.284 - 1.285 - array_overlap_test(disjoint_copy_entry, Address::times_8); 1.286 + 1.287 + array_overlap_test(nooverlap_target, Address::times_8); 1.288 setup_arg_regs(); // from => rdi, to => rsi, count => rdx 1.289 // r9 and r10 may be used to save non-volatile registers 1.290 - 1.291 // 'from', 'to' and 'qword_count' are now valid 1.292 - 1.293 if (is_oop) { 1.294 // Save to and count for store barrier 1.295 __ movptr(saved_count, qword_count); 1.296 @@ -2162,7 +2146,7 @@ 1.297 // rax == 0 - success 1.298 // rax == -1^K - failure, where K is partial transfer count 1.299 // 1.300 - address generate_checkcast_copy(const char *name) { 1.301 + address generate_checkcast_copy(const char *name, address *entry) { 1.302 1.303 Label L_load_element, L_store_element, L_do_card_marks, L_done; 1.304 1.305 @@ -2216,8 +2200,10 @@ 1.306 #endif 1.307 1.308 // Caller of this entry point must set up the argument registers. 1.309 - checkcast_copy_entry = __ pc(); 1.310 - BLOCK_COMMENT("Entry:"); 1.311 + if (entry != NULL) { 1.312 + *entry = __ pc(); 1.313 + BLOCK_COMMENT("Entry:"); 1.314 + } 1.315 1.316 // allocate spill slots for r13, r14 1.317 enum { 1.318 @@ -2334,7 +2320,9 @@ 1.319 // Examines the alignment of the operands and dispatches 1.320 // to a long, int, short, or byte copy loop. 1.321 // 1.322 - address generate_unsafe_copy(const char *name) { 1.323 + address generate_unsafe_copy(const char *name, 1.324 + address byte_copy_entry, address short_copy_entry, 1.325 + address int_copy_entry, address long_copy_entry) { 1.326 1.327 Label L_long_aligned, L_int_aligned, L_short_aligned; 1.328 1.329 @@ -2432,7 +2420,10 @@ 1.330 // rax == 0 - success 1.331 // rax == -1^K - failure, where K is partial transfer count 1.332 // 1.333 - address generate_generic_copy(const char *name) { 1.334 + address generate_generic_copy(const char *name, 1.335 + address byte_copy_entry, address short_copy_entry, 1.336 + address int_copy_entry, address long_copy_entry, 1.337 + address oop_copy_entry, address checkcast_copy_entry) { 1.338 1.339 Label L_failed, L_failed_0, L_objArray; 1.340 Label L_copy_bytes, L_copy_shorts, L_copy_ints, L_copy_longs; 1.341 @@ -2725,33 +2716,60 @@ 1.342 } 1.343 1.344 void generate_arraycopy_stubs() { 1.345 - // Call the conjoint generation methods immediately after 1.346 - // the disjoint ones so that short branches from the former 1.347 - // to the latter can be generated. 1.348 - StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(false, "jbyte_disjoint_arraycopy"); 1.349 - StubRoutines::_jbyte_arraycopy = generate_conjoint_byte_copy(false, "jbyte_arraycopy"); 1.350 - 1.351 - StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(false, "jshort_disjoint_arraycopy"); 1.352 - StubRoutines::_jshort_arraycopy = generate_conjoint_short_copy(false, "jshort_arraycopy"); 1.353 - 1.354 - StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_int_oop_copy(false, false, "jint_disjoint_arraycopy"); 1.355 - StubRoutines::_jint_arraycopy = generate_conjoint_int_oop_copy(false, false, "jint_arraycopy"); 1.356 - 1.357 - StubRoutines::_jlong_disjoint_arraycopy = generate_disjoint_long_oop_copy(false, false, "jlong_disjoint_arraycopy"); 1.358 - StubRoutines::_jlong_arraycopy = generate_conjoint_long_oop_copy(false, false, "jlong_arraycopy"); 1.359 + address entry; 1.360 + address entry_jbyte_arraycopy; 1.361 + address entry_jshort_arraycopy; 1.362 + address entry_jint_arraycopy; 1.363 + address entry_oop_arraycopy; 1.364 + address entry_jlong_arraycopy; 1.365 + address entry_checkcast_arraycopy; 1.366 + 1.367 + StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(false, &entry, 1.368 + "jbyte_disjoint_arraycopy"); 1.369 + StubRoutines::_jbyte_arraycopy = generate_conjoint_byte_copy(false, entry, &entry_jbyte_arraycopy, 1.370 + "jbyte_arraycopy"); 1.371 + 1.372 + StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(false, &entry, 1.373 + "jshort_disjoint_arraycopy"); 1.374 + StubRoutines::_jshort_arraycopy = generate_conjoint_short_copy(false, entry, &entry_jshort_arraycopy, 1.375 + "jshort_arraycopy"); 1.376 + 1.377 + StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_int_oop_copy(false, false, &entry, 1.378 + "jint_disjoint_arraycopy"); 1.379 + StubRoutines::_jint_arraycopy = generate_conjoint_int_oop_copy(false, false, entry, 1.380 + &entry_jint_arraycopy, "jint_arraycopy"); 1.381 + 1.382 + StubRoutines::_jlong_disjoint_arraycopy = generate_disjoint_long_oop_copy(false, false, &entry, 1.383 + "jlong_disjoint_arraycopy"); 1.384 + StubRoutines::_jlong_arraycopy = generate_conjoint_long_oop_copy(false, false, entry, 1.385 + &entry_jlong_arraycopy, "jlong_arraycopy"); 1.386 1.387 1.388 if (UseCompressedOops) { 1.389 - StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_int_oop_copy(false, true, "oop_disjoint_arraycopy"); 1.390 - StubRoutines::_oop_arraycopy = generate_conjoint_int_oop_copy(false, true, "oop_arraycopy"); 1.391 + StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_int_oop_copy(false, true, &entry, 1.392 + "oop_disjoint_arraycopy"); 1.393 + StubRoutines::_oop_arraycopy = generate_conjoint_int_oop_copy(false, true, entry, 1.394 + &entry_oop_arraycopy, "oop_arraycopy"); 1.395 } else { 1.396 - StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_long_oop_copy(false, true, "oop_disjoint_arraycopy"); 1.397 - StubRoutines::_oop_arraycopy = generate_conjoint_long_oop_copy(false, true, "oop_arraycopy"); 1.398 + StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_long_oop_copy(false, true, &entry, 1.399 + "oop_disjoint_arraycopy"); 1.400 + StubRoutines::_oop_arraycopy = generate_conjoint_long_oop_copy(false, true, entry, 1.401 + &entry_oop_arraycopy, "oop_arraycopy"); 1.402 } 1.403 1.404 - StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy"); 1.405 - StubRoutines::_unsafe_arraycopy = generate_unsafe_copy("unsafe_arraycopy"); 1.406 - StubRoutines::_generic_arraycopy = generate_generic_copy("generic_arraycopy"); 1.407 + StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy", &entry_checkcast_arraycopy); 1.408 + StubRoutines::_unsafe_arraycopy = generate_unsafe_copy("unsafe_arraycopy", 1.409 + entry_jbyte_arraycopy, 1.410 + entry_jshort_arraycopy, 1.411 + entry_jint_arraycopy, 1.412 + entry_jlong_arraycopy); 1.413 + StubRoutines::_generic_arraycopy = generate_generic_copy("generic_arraycopy", 1.414 + entry_jbyte_arraycopy, 1.415 + entry_jshort_arraycopy, 1.416 + entry_jint_arraycopy, 1.417 + entry_oop_arraycopy, 1.418 + entry_jlong_arraycopy, 1.419 + entry_checkcast_arraycopy); 1.420 1.421 StubRoutines::_jbyte_fill = generate_fill(T_BYTE, false, "jbyte_fill"); 1.422 StubRoutines::_jshort_fill = generate_fill(T_SHORT, false, "jshort_fill"); 1.423 @@ -3069,20 +3087,6 @@ 1.424 } 1.425 }; // end class declaration 1.426 1.427 -address StubGenerator::disjoint_byte_copy_entry = NULL; 1.428 -address StubGenerator::disjoint_short_copy_entry = NULL; 1.429 -address StubGenerator::disjoint_int_copy_entry = NULL; 1.430 -address StubGenerator::disjoint_long_copy_entry = NULL; 1.431 -address StubGenerator::disjoint_oop_copy_entry = NULL; 1.432 - 1.433 -address StubGenerator::byte_copy_entry = NULL; 1.434 -address StubGenerator::short_copy_entry = NULL; 1.435 -address StubGenerator::int_copy_entry = NULL; 1.436 -address StubGenerator::long_copy_entry = NULL; 1.437 -address StubGenerator::oop_copy_entry = NULL; 1.438 - 1.439 -address StubGenerator::checkcast_copy_entry = NULL; 1.440 - 1.441 void StubGenerator_generate(CodeBuffer* code, bool all) { 1.442 StubGenerator g(code, all); 1.443 }