Mercurial > hg > truffle
comparison src/share/vm/runtime/stubRoutines.cpp @ 2324:0ac769a57c64
6627983: G1: Bad oop deference during marking
Summary: Bulk zeroing reduction didn't work with G1, because arraycopy would call pre-barriers on uninitialized oops. The solution is to have version of arraycopy stubs that don't have pre-barriers. Also refactored arraycopy stubs generation on SPARC to be more readable and reduced the number of stubs necessary in some cases.
Reviewed-by: jrose, kvn, never
author | iveresov |
---|---|
date | Tue, 01 Mar 2011 14:56:48 -0800 |
parents | f95d63e2154a |
children | 13bc79b5c9c8 |
comparison
equal
deleted
inserted
replaced
2323:bc6b27fb3568 | 2324:0ac769a57c64 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
78 jint StubRoutines::_mxcsr_std = 0; | 78 jint StubRoutines::_mxcsr_std = 0; |
79 jint StubRoutines::_fpu_subnormal_bias1[3] = { 0, 0, 0 }; | 79 jint StubRoutines::_fpu_subnormal_bias1[3] = { 0, 0, 0 }; |
80 jint StubRoutines::_fpu_subnormal_bias2[3] = { 0, 0, 0 }; | 80 jint StubRoutines::_fpu_subnormal_bias2[3] = { 0, 0, 0 }; |
81 | 81 |
82 // Compiled code entry points default values | 82 // Compiled code entry points default values |
83 // The dafault functions don't have separate disjoint versions. | 83 // The default functions don't have separate disjoint versions. |
84 address StubRoutines::_jbyte_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jbyte_copy); | 84 address StubRoutines::_jbyte_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jbyte_copy); |
85 address StubRoutines::_jshort_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jshort_copy); | 85 address StubRoutines::_jshort_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jshort_copy); |
86 address StubRoutines::_jint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jint_copy); | 86 address StubRoutines::_jint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jint_copy); |
87 address StubRoutines::_jlong_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jlong_copy); | 87 address StubRoutines::_jlong_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jlong_copy); |
88 address StubRoutines::_oop_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::oop_copy); | 88 address StubRoutines::_oop_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::oop_copy); |
89 address StubRoutines::_oop_arraycopy_uninit = CAST_FROM_FN_PTR(address, StubRoutines::oop_copy_uninit); | |
89 address StubRoutines::_jbyte_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jbyte_copy); | 90 address StubRoutines::_jbyte_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jbyte_copy); |
90 address StubRoutines::_jshort_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jshort_copy); | 91 address StubRoutines::_jshort_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jshort_copy); |
91 address StubRoutines::_jint_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jint_copy); | 92 address StubRoutines::_jint_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jint_copy); |
92 address StubRoutines::_jlong_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jlong_copy); | 93 address StubRoutines::_jlong_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jlong_copy); |
93 address StubRoutines::_oop_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::oop_copy); | 94 address StubRoutines::_oop_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::oop_copy); |
95 address StubRoutines::_oop_disjoint_arraycopy_uninit = CAST_FROM_FN_PTR(address, StubRoutines::oop_copy_uninit); | |
94 | 96 |
95 address StubRoutines::_arrayof_jbyte_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jbyte_copy); | 97 address StubRoutines::_arrayof_jbyte_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jbyte_copy); |
96 address StubRoutines::_arrayof_jshort_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jshort_copy); | 98 address StubRoutines::_arrayof_jshort_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jshort_copy); |
97 address StubRoutines::_arrayof_jint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jint_copy); | 99 address StubRoutines::_arrayof_jint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jint_copy); |
98 address StubRoutines::_arrayof_jlong_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jlong_copy); | 100 address StubRoutines::_arrayof_jlong_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jlong_copy); |
99 address StubRoutines::_arrayof_oop_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_oop_copy); | 101 address StubRoutines::_arrayof_oop_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_oop_copy); |
102 address StubRoutines::_arrayof_oop_arraycopy_uninit = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_oop_copy_uninit); | |
100 address StubRoutines::_arrayof_jbyte_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jbyte_copy); | 103 address StubRoutines::_arrayof_jbyte_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jbyte_copy); |
101 address StubRoutines::_arrayof_jshort_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jshort_copy); | 104 address StubRoutines::_arrayof_jshort_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jshort_copy); |
102 address StubRoutines::_arrayof_jint_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jint_copy); | 105 address StubRoutines::_arrayof_jint_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jint_copy); |
103 address StubRoutines::_arrayof_jlong_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jlong_copy); | 106 address StubRoutines::_arrayof_jlong_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jlong_copy); |
104 address StubRoutines::_arrayof_oop_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_oop_copy); | 107 address StubRoutines::_arrayof_oop_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_oop_copy); |
108 address StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_oop_copy_uninit); | |
109 | |
105 | 110 |
106 address StubRoutines::_checkcast_arraycopy = NULL; | 111 address StubRoutines::_checkcast_arraycopy = NULL; |
112 address StubRoutines::_checkcast_arraycopy_uninit = NULL; | |
107 address StubRoutines::_unsafe_arraycopy = NULL; | 113 address StubRoutines::_unsafe_arraycopy = NULL; |
108 address StubRoutines::_generic_arraycopy = NULL; | 114 address StubRoutines::_generic_arraycopy = NULL; |
109 | 115 |
110 | 116 |
111 address StubRoutines::_jbyte_fill; | 117 address StubRoutines::_jbyte_fill; |
280 | 286 |
281 // | 287 // |
282 // Default versions of arraycopy functions | 288 // Default versions of arraycopy functions |
283 // | 289 // |
284 | 290 |
285 static void gen_arraycopy_barrier_pre(oop* dest, size_t count) { | 291 static void gen_arraycopy_barrier_pre(oop* dest, size_t count, bool dest_uninitialized) { |
286 assert(count != 0, "count should be non-zero"); | 292 assert(count != 0, "count should be non-zero"); |
287 assert(count <= (size_t)max_intx, "count too large"); | 293 assert(count <= (size_t)max_intx, "count too large"); |
288 BarrierSet* bs = Universe::heap()->barrier_set(); | 294 BarrierSet* bs = Universe::heap()->barrier_set(); |
289 assert(bs->has_write_ref_array_pre_opt(), "Must have pre-barrier opt"); | 295 assert(bs->has_write_ref_array_pre_opt(), "Must have pre-barrier opt"); |
290 bs->write_ref_array_pre(dest, (int)count); | 296 bs->write_ref_array_pre(dest, (int)count, dest_uninitialized); |
291 } | 297 } |
292 | 298 |
293 static void gen_arraycopy_barrier(oop* dest, size_t count) { | 299 static void gen_arraycopy_barrier(oop* dest, size_t count) { |
294 assert(count != 0, "count should be non-zero"); | 300 assert(count != 0, "count should be non-zero"); |
295 BarrierSet* bs = Universe::heap()->barrier_set(); | 301 BarrierSet* bs = Universe::heap()->barrier_set(); |
328 JRT_LEAF(void, StubRoutines::oop_copy(oop* src, oop* dest, size_t count)) | 334 JRT_LEAF(void, StubRoutines::oop_copy(oop* src, oop* dest, size_t count)) |
329 #ifndef PRODUCT | 335 #ifndef PRODUCT |
330 SharedRuntime::_oop_array_copy_ctr++; // Slow-path oop array copy | 336 SharedRuntime::_oop_array_copy_ctr++; // Slow-path oop array copy |
331 #endif // !PRODUCT | 337 #endif // !PRODUCT |
332 assert(count != 0, "count should be non-zero"); | 338 assert(count != 0, "count should be non-zero"); |
333 gen_arraycopy_barrier_pre(dest, count); | 339 gen_arraycopy_barrier_pre(dest, count, /*dest_uninitialized*/false); |
334 Copy::conjoint_oops_atomic(src, dest, count); | 340 Copy::conjoint_oops_atomic(src, dest, count); |
335 gen_arraycopy_barrier(dest, count); | 341 gen_arraycopy_barrier(dest, count); |
336 JRT_END | 342 JRT_END |
337 | 343 |
344 JRT_LEAF(void, StubRoutines::oop_copy_uninit(oop* src, oop* dest, size_t count)) | |
345 #ifndef PRODUCT | |
346 SharedRuntime::_oop_array_copy_ctr++; // Slow-path oop array copy | |
347 #endif // !PRODUCT | |
348 assert(count != 0, "count should be non-zero"); | |
349 gen_arraycopy_barrier_pre(dest, count, /*dest_uninitialized*/true); | |
350 Copy::conjoint_oops_atomic(src, dest, count); | |
351 gen_arraycopy_barrier(dest, count); | |
352 JRT_END | |
353 | |
338 JRT_LEAF(void, StubRoutines::arrayof_jbyte_copy(HeapWord* src, HeapWord* dest, size_t count)) | 354 JRT_LEAF(void, StubRoutines::arrayof_jbyte_copy(HeapWord* src, HeapWord* dest, size_t count)) |
339 #ifndef PRODUCT | 355 #ifndef PRODUCT |
340 SharedRuntime::_jbyte_array_copy_ctr++; // Slow-path byte array copy | 356 SharedRuntime::_jbyte_array_copy_ctr++; // Slow-path byte array copy |
341 #endif // !PRODUCT | 357 #endif // !PRODUCT |
342 Copy::arrayof_conjoint_jbytes(src, dest, count); | 358 Copy::arrayof_conjoint_jbytes(src, dest, count); |
366 JRT_LEAF(void, StubRoutines::arrayof_oop_copy(HeapWord* src, HeapWord* dest, size_t count)) | 382 JRT_LEAF(void, StubRoutines::arrayof_oop_copy(HeapWord* src, HeapWord* dest, size_t count)) |
367 #ifndef PRODUCT | 383 #ifndef PRODUCT |
368 SharedRuntime::_oop_array_copy_ctr++; // Slow-path oop array copy | 384 SharedRuntime::_oop_array_copy_ctr++; // Slow-path oop array copy |
369 #endif // !PRODUCT | 385 #endif // !PRODUCT |
370 assert(count != 0, "count should be non-zero"); | 386 assert(count != 0, "count should be non-zero"); |
371 gen_arraycopy_barrier_pre((oop *) dest, count); | 387 gen_arraycopy_barrier_pre((oop *) dest, count, /*dest_uninitialized*/false); |
372 Copy::arrayof_conjoint_oops(src, dest, count); | 388 Copy::arrayof_conjoint_oops(src, dest, count); |
373 gen_arraycopy_barrier((oop *) dest, count); | 389 gen_arraycopy_barrier((oop *) dest, count); |
374 JRT_END | 390 JRT_END |
375 | 391 |
392 JRT_LEAF(void, StubRoutines::arrayof_oop_copy_uninit(HeapWord* src, HeapWord* dest, size_t count)) | |
393 #ifndef PRODUCT | |
394 SharedRuntime::_oop_array_copy_ctr++; // Slow-path oop array copy | |
395 #endif // !PRODUCT | |
396 assert(count != 0, "count should be non-zero"); | |
397 gen_arraycopy_barrier_pre((oop *) dest, count, /*dest_uninitialized*/true); | |
398 Copy::arrayof_conjoint_oops(src, dest, count); | |
399 gen_arraycopy_barrier((oop *) dest, count); | |
400 JRT_END | |
376 | 401 |
377 address StubRoutines::select_fill_function(BasicType t, bool aligned, const char* &name) { | 402 address StubRoutines::select_fill_function(BasicType t, bool aligned, const char* &name) { |
378 #define RETURN_STUB(xxx_fill) { \ | 403 #define RETURN_STUB(xxx_fill) { \ |
379 name = #xxx_fill; \ | 404 name = #xxx_fill; \ |
380 return StubRoutines::xxx_fill(); } | 405 return StubRoutines::xxx_fill(); } |