Mercurial > hg > graal-jvmci-8
annotate src/share/vm/runtime/stubRoutines.cpp @ 3979:4dfb2df418f2
6484982: G1: process references during evacuation pauses
Summary: G1 now uses two reference processors - one is used by concurrent marking and the other is used by STW GCs (both full and incremental evacuation pauses). In an evacuation pause, the reference processor is embedded into the closures used to scan objects. Doing so causes causes reference objects to be 'discovered' by the reference processor. At the end of the evacuation pause, these discovered reference objects are processed - preserving (and copying) referent objects (and their reachable graphs) as appropriate.
Reviewed-by: ysr, jwilhelm, brutisso, stefank, tonyp
author | johnc |
---|---|
date | Thu, 22 Sep 2011 10:57:37 -0700 |
parents | c565834fb592 |
children | 1d7922586cf6 |
rev | line source |
---|---|
0 | 1 /* |
2324 | 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
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 | |
7 * published by the Free Software Foundation. | |
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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1490
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1490
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1490
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "asm/codeBuffer.hpp" | |
27 #include "memory/resourceArea.hpp" | |
28 #include "oops/oop.inline.hpp" | |
29 #include "runtime/interfaceSupport.hpp" | |
30 #include "runtime/sharedRuntime.hpp" | |
31 #include "runtime/stubRoutines.hpp" | |
32 #include "runtime/timer.hpp" | |
33 #include "utilities/copy.hpp" | |
34 #ifdef COMPILER2 | |
35 #include "opto/runtime.hpp" | |
36 #endif | |
0 | 37 |
38 | |
39 // Implementation of StubRoutines - for a description | |
40 // of how to extend it, see the header file. | |
41 | |
42 // Class Variables | |
43 | |
44 BufferBlob* StubRoutines::_code1 = NULL; | |
45 BufferBlob* StubRoutines::_code2 = NULL; | |
46 | |
47 address StubRoutines::_call_stub_return_address = NULL; | |
48 address StubRoutines::_call_stub_entry = NULL; | |
49 | |
50 address StubRoutines::_catch_exception_entry = NULL; | |
51 address StubRoutines::_forward_exception_entry = NULL; | |
52 address StubRoutines::_throw_AbstractMethodError_entry = NULL; | |
16
f8236e79048a
6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents:
0
diff
changeset
|
53 address StubRoutines::_throw_IncompatibleClassChangeError_entry = NULL; |
0 | 54 address StubRoutines::_throw_NullPointerException_at_call_entry = NULL; |
55 address StubRoutines::_throw_StackOverflowError_entry = NULL; | |
3781
d83ac25d0304
7055355: JSR 292: crash while throwing WrongMethodTypeException
never
parents:
2446
diff
changeset
|
56 address StubRoutines::_throw_WrongMethodTypeException_entry = NULL; |
0 | 57 address StubRoutines::_handler_for_unsafe_access_entry = NULL; |
58 jint StubRoutines::_verify_oop_count = 0; | |
59 address StubRoutines::_verify_oop_subroutine_entry = NULL; | |
60 address StubRoutines::_atomic_xchg_entry = NULL; | |
61 address StubRoutines::_atomic_xchg_ptr_entry = NULL; | |
62 address StubRoutines::_atomic_store_entry = NULL; | |
63 address StubRoutines::_atomic_store_ptr_entry = NULL; | |
64 address StubRoutines::_atomic_cmpxchg_entry = NULL; | |
65 address StubRoutines::_atomic_cmpxchg_ptr_entry = NULL; | |
66 address StubRoutines::_atomic_cmpxchg_long_entry = NULL; | |
67 address StubRoutines::_atomic_add_entry = NULL; | |
68 address StubRoutines::_atomic_add_ptr_entry = NULL; | |
69 address StubRoutines::_fence_entry = NULL; | |
70 address StubRoutines::_d2i_wrapper = NULL; | |
71 address StubRoutines::_d2l_wrapper = NULL; | |
72 | |
73 jint StubRoutines::_fpu_cntrl_wrd_std = 0; | |
74 jint StubRoutines::_fpu_cntrl_wrd_24 = 0; | |
75 jint StubRoutines::_fpu_cntrl_wrd_64 = 0; | |
76 jint StubRoutines::_fpu_cntrl_wrd_trunc = 0; | |
77 jint StubRoutines::_mxcsr_std = 0; | |
78 jint StubRoutines::_fpu_subnormal_bias1[3] = { 0, 0, 0 }; | |
79 jint StubRoutines::_fpu_subnormal_bias2[3] = { 0, 0, 0 }; | |
80 | |
81 // Compiled code entry points default values | |
2324 | 82 // The default functions don't have separate disjoint versions. |
0 | 83 address StubRoutines::_jbyte_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jbyte_copy); |
84 address StubRoutines::_jshort_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jshort_copy); | |
85 address StubRoutines::_jint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jint_copy); | |
86 address StubRoutines::_jlong_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jlong_copy); | |
87 address StubRoutines::_oop_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::oop_copy); | |
2324 | 88 address StubRoutines::_oop_arraycopy_uninit = CAST_FROM_FN_PTR(address, StubRoutines::oop_copy_uninit); |
0 | 89 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::_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::_oop_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::oop_copy); | |
2324 | 94 address StubRoutines::_oop_disjoint_arraycopy_uninit = CAST_FROM_FN_PTR(address, StubRoutines::oop_copy_uninit); |
0 | 95 |
96 address StubRoutines::_arrayof_jbyte_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jbyte_copy); | |
97 address StubRoutines::_arrayof_jshort_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jshort_copy); | |
98 address StubRoutines::_arrayof_jint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jint_copy); | |
99 address StubRoutines::_arrayof_jlong_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jlong_copy); | |
100 address StubRoutines::_arrayof_oop_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_oop_copy); | |
2324 | 101 address StubRoutines::_arrayof_oop_arraycopy_uninit = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_oop_copy_uninit); |
0 | 102 address StubRoutines::_arrayof_jbyte_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jbyte_copy); |
103 address StubRoutines::_arrayof_jshort_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jshort_copy); | |
104 address StubRoutines::_arrayof_jint_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jint_copy); | |
105 address StubRoutines::_arrayof_jlong_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jlong_copy); | |
2324 | 106 address StubRoutines::_arrayof_oop_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_oop_copy); |
107 address StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_oop_copy_uninit); | |
108 | |
3892 | 109 address StubRoutines::_zero_aligned_words = CAST_FROM_FN_PTR(address, Copy::zero_to_words); |
0 | 110 |
111 address StubRoutines::_checkcast_arraycopy = NULL; | |
2324 | 112 address StubRoutines::_checkcast_arraycopy_uninit = NULL; |
0 | 113 address StubRoutines::_unsafe_arraycopy = NULL; |
114 address StubRoutines::_generic_arraycopy = NULL; | |
115 | |
1763 | 116 |
117 address StubRoutines::_jbyte_fill; | |
118 address StubRoutines::_jshort_fill; | |
119 address StubRoutines::_jint_fill; | |
120 address StubRoutines::_arrayof_jbyte_fill; | |
121 address StubRoutines::_arrayof_jshort_fill; | |
122 address StubRoutines::_arrayof_jint_fill; | |
123 | |
124 | |
1174
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
16
diff
changeset
|
125 double (* StubRoutines::_intrinsic_log )(double) = NULL; |
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
16
diff
changeset
|
126 double (* StubRoutines::_intrinsic_log10 )(double) = NULL; |
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
16
diff
changeset
|
127 double (* StubRoutines::_intrinsic_exp )(double) = NULL; |
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
16
diff
changeset
|
128 double (* StubRoutines::_intrinsic_pow )(double, double) = NULL; |
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
16
diff
changeset
|
129 double (* StubRoutines::_intrinsic_sin )(double) = NULL; |
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
16
diff
changeset
|
130 double (* StubRoutines::_intrinsic_cos )(double) = NULL; |
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
16
diff
changeset
|
131 double (* StubRoutines::_intrinsic_tan )(double) = NULL; |
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
16
diff
changeset
|
132 |
0 | 133 // Initialization |
134 // | |
135 // Note: to break cycle with universe initialization, stubs are generated in two phases. | |
136 // The first one generates stubs needed during universe init (e.g., _handle_must_compile_first_entry). | |
137 // The second phase includes all other stubs (which may depend on universe being initialized.) | |
138 | |
139 extern void StubGenerator_generate(CodeBuffer* code, bool all); // only interface to generators | |
140 | |
141 void StubRoutines::initialize1() { | |
142 if (_code1 == NULL) { | |
143 ResourceMark rm; | |
144 TraceTime timer("StubRoutines generation 1", TraceStartupTime); | |
145 _code1 = BufferBlob::create("StubRoutines (1)", code_size1); | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1245
diff
changeset
|
146 if (_code1 == NULL) { |
1748 | 147 vm_exit_out_of_memory(code_size1, "CodeCache: no room for StubRoutines (1)"); |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1245
diff
changeset
|
148 } |
1748 | 149 CodeBuffer buffer(_code1); |
0 | 150 StubGenerator_generate(&buffer, false); |
151 } | |
152 } | |
153 | |
154 | |
155 #ifdef ASSERT | |
156 typedef void (*arraycopy_fn)(address src, address dst, int count); | |
157 | |
158 // simple tests of generated arraycopy functions | |
159 static void test_arraycopy_func(address func, int alignment) { | |
160 int v = 0xcc; | |
161 int v2 = 0x11; | |
1603
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
162 jlong lbuffer[8]; |
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
163 jlong lbuffer2[8]; |
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
164 address fbuffer = (address) lbuffer; |
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
165 address fbuffer2 = (address) lbuffer2; |
0 | 166 unsigned int i; |
167 for (i = 0; i < sizeof(lbuffer); i++) { | |
1603
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
168 fbuffer[i] = v; fbuffer2[i] = v2; |
0 | 169 } |
1603
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
170 // C++ does not guarantee jlong[] array alignment to 8 bytes. |
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
171 // Use middle of array to check that memory before it is not modified. |
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
172 address buffer = (address) round_to((intptr_t)&lbuffer[4], BytesPerLong); |
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
173 address buffer2 = (address) round_to((intptr_t)&lbuffer2[4], BytesPerLong); |
0 | 174 // do an aligned copy |
175 ((arraycopy_fn)func)(buffer, buffer2, 0); | |
176 for (i = 0; i < sizeof(lbuffer); i++) { | |
1603
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
177 assert(fbuffer[i] == v && fbuffer2[i] == v2, "shouldn't have copied anything"); |
0 | 178 } |
179 // adjust destination alignment | |
180 ((arraycopy_fn)func)(buffer, buffer2 + alignment, 0); | |
181 for (i = 0; i < sizeof(lbuffer); i++) { | |
1603
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
182 assert(fbuffer[i] == v && fbuffer2[i] == v2, "shouldn't have copied anything"); |
0 | 183 } |
184 // adjust source alignment | |
185 ((arraycopy_fn)func)(buffer + alignment, buffer2, 0); | |
186 for (i = 0; i < sizeof(lbuffer); i++) { | |
1603
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
187 assert(fbuffer[i] == v && fbuffer2[i] == v2, "shouldn't have copied anything"); |
0 | 188 } |
189 } | |
190 #endif | |
191 | |
192 | |
193 void StubRoutines::initialize2() { | |
194 if (_code2 == NULL) { | |
195 ResourceMark rm; | |
196 TraceTime timer("StubRoutines generation 2", TraceStartupTime); | |
197 _code2 = BufferBlob::create("StubRoutines (2)", code_size2); | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1245
diff
changeset
|
198 if (_code2 == NULL) { |
1748 | 199 vm_exit_out_of_memory(code_size2, "CodeCache: no room for StubRoutines (2)"); |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1245
diff
changeset
|
200 } |
1748 | 201 CodeBuffer buffer(_code2); |
0 | 202 StubGenerator_generate(&buffer, true); |
203 } | |
204 | |
205 #ifdef ASSERT | |
206 | |
207 #define TEST_ARRAYCOPY(type) \ | |
208 test_arraycopy_func( type##_arraycopy(), sizeof(type)); \ | |
209 test_arraycopy_func( type##_disjoint_arraycopy(), sizeof(type)); \ | |
210 test_arraycopy_func(arrayof_##type##_arraycopy(), sizeof(HeapWord)); \ | |
211 test_arraycopy_func(arrayof_##type##_disjoint_arraycopy(), sizeof(HeapWord)) | |
212 | |
1603
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
213 // Make sure all the arraycopy stubs properly handle zero count |
0 | 214 TEST_ARRAYCOPY(jbyte); |
215 TEST_ARRAYCOPY(jshort); | |
216 TEST_ARRAYCOPY(jint); | |
217 TEST_ARRAYCOPY(jlong); | |
218 | |
219 #undef TEST_ARRAYCOPY | |
220 | |
1763 | 221 #define TEST_FILL(type) \ |
222 if (_##type##_fill != NULL) { \ | |
223 union { \ | |
224 double d; \ | |
225 type body[96]; \ | |
226 } s; \ | |
227 \ | |
228 int v = 32; \ | |
229 for (int offset = -2; offset <= 2; offset++) { \ | |
230 for (int i = 0; i < 96; i++) { \ | |
231 s.body[i] = 1; \ | |
232 } \ | |
233 type* start = s.body + 8 + offset; \ | |
234 for (int aligned = 0; aligned < 2; aligned++) { \ | |
235 if (aligned) { \ | |
236 if (((intptr_t)start) % HeapWordSize == 0) { \ | |
237 ((void (*)(type*, int, int))StubRoutines::_arrayof_##type##_fill)(start, v, 80); \ | |
238 } else { \ | |
239 continue; \ | |
240 } \ | |
241 } else { \ | |
242 ((void (*)(type*, int, int))StubRoutines::_##type##_fill)(start, v, 80); \ | |
243 } \ | |
244 for (int i = 0; i < 96; i++) { \ | |
245 if (i < (8 + offset) || i >= (88 + offset)) { \ | |
246 assert(s.body[i] == 1, "what?"); \ | |
247 } else { \ | |
248 assert(s.body[i] == 32, "what?"); \ | |
249 } \ | |
250 } \ | |
251 } \ | |
252 } \ | |
253 } \ | |
254 | |
255 TEST_FILL(jbyte); | |
256 TEST_FILL(jshort); | |
257 TEST_FILL(jint); | |
258 | |
259 #undef TEST_FILL | |
260 | |
1603
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
261 #define TEST_COPYRTN(type) \ |
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
262 test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::conjoint_##type##s_atomic), sizeof(type)); \ |
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
263 test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::arrayof_conjoint_##type##s), (int)MAX2(sizeof(HeapWord), sizeof(type))) |
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
264 |
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
265 // Make sure all the copy runtime routines properly handle zero count |
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
266 TEST_COPYRTN(jbyte); |
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
267 TEST_COPYRTN(jshort); |
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
268 TEST_COPYRTN(jint); |
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
269 TEST_COPYRTN(jlong); |
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
270 |
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
271 #undef TEST_COPYRTN |
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
272 |
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
273 test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::conjoint_words), sizeof(HeapWord)); |
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
274 test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::disjoint_words), sizeof(HeapWord)); |
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
275 test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::disjoint_words_atomic), sizeof(HeapWord)); |
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
276 // Aligned to BytesPerLong |
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
277 test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::aligned_conjoint_words), sizeof(jlong)); |
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
278 test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::aligned_disjoint_words), sizeof(jlong)); |
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
279 |
0 | 280 #endif |
281 } | |
282 | |
283 | |
284 void stubRoutines_init1() { StubRoutines::initialize1(); } | |
285 void stubRoutines_init2() { StubRoutines::initialize2(); } | |
286 | |
287 // | |
288 // Default versions of arraycopy functions | |
289 // | |
290 | |
2324 | 291 static void gen_arraycopy_barrier_pre(oop* dest, size_t count, bool dest_uninitialized) { |
1245
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1174
diff
changeset
|
292 assert(count != 0, "count should be non-zero"); |
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1174
diff
changeset
|
293 assert(count <= (size_t)max_intx, "count too large"); |
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1174
diff
changeset
|
294 BarrierSet* bs = Universe::heap()->barrier_set(); |
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1174
diff
changeset
|
295 assert(bs->has_write_ref_array_pre_opt(), "Must have pre-barrier opt"); |
2324 | 296 bs->write_ref_array_pre(dest, (int)count, dest_uninitialized); |
1245
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1174
diff
changeset
|
297 } |
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1174
diff
changeset
|
298 |
0 | 299 static void gen_arraycopy_barrier(oop* dest, size_t count) { |
300 assert(count != 0, "count should be non-zero"); | |
301 BarrierSet* bs = Universe::heap()->barrier_set(); | |
302 assert(bs->has_write_ref_array_opt(), "Barrier set must have ref array opt"); | |
1245
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1174
diff
changeset
|
303 bs->write_ref_array((HeapWord*)dest, count); |
0 | 304 } |
305 | |
306 JRT_LEAF(void, StubRoutines::jbyte_copy(jbyte* src, jbyte* dest, size_t count)) | |
307 #ifndef PRODUCT | |
308 SharedRuntime::_jbyte_array_copy_ctr++; // Slow-path byte array copy | |
309 #endif // !PRODUCT | |
1603
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
310 Copy::conjoint_jbytes_atomic(src, dest, count); |
0 | 311 JRT_END |
312 | |
313 JRT_LEAF(void, StubRoutines::jshort_copy(jshort* src, jshort* dest, size_t count)) | |
314 #ifndef PRODUCT | |
315 SharedRuntime::_jshort_array_copy_ctr++; // Slow-path short/char array copy | |
316 #endif // !PRODUCT | |
317 Copy::conjoint_jshorts_atomic(src, dest, count); | |
318 JRT_END | |
319 | |
320 JRT_LEAF(void, StubRoutines::jint_copy(jint* src, jint* dest, size_t count)) | |
321 #ifndef PRODUCT | |
322 SharedRuntime::_jint_array_copy_ctr++; // Slow-path int/float array copy | |
323 #endif // !PRODUCT | |
324 Copy::conjoint_jints_atomic(src, dest, count); | |
325 JRT_END | |
326 | |
327 JRT_LEAF(void, StubRoutines::jlong_copy(jlong* src, jlong* dest, size_t count)) | |
328 #ifndef PRODUCT | |
329 SharedRuntime::_jlong_array_copy_ctr++; // Slow-path long/double array copy | |
330 #endif // !PRODUCT | |
331 Copy::conjoint_jlongs_atomic(src, dest, count); | |
332 JRT_END | |
333 | |
334 JRT_LEAF(void, StubRoutines::oop_copy(oop* src, oop* dest, size_t count)) | |
335 #ifndef PRODUCT | |
336 SharedRuntime::_oop_array_copy_ctr++; // Slow-path oop array copy | |
337 #endif // !PRODUCT | |
338 assert(count != 0, "count should be non-zero"); | |
2324 | 339 gen_arraycopy_barrier_pre(dest, count, /*dest_uninitialized*/false); |
340 Copy::conjoint_oops_atomic(src, dest, count); | |
341 gen_arraycopy_barrier(dest, count); | |
342 JRT_END | |
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); | |
0 | 350 Copy::conjoint_oops_atomic(src, dest, count); |
351 gen_arraycopy_barrier(dest, count); | |
352 JRT_END | |
353 | |
354 JRT_LEAF(void, StubRoutines::arrayof_jbyte_copy(HeapWord* src, HeapWord* dest, size_t count)) | |
355 #ifndef PRODUCT | |
356 SharedRuntime::_jbyte_array_copy_ctr++; // Slow-path byte array copy | |
357 #endif // !PRODUCT | |
1603
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
358 Copy::arrayof_conjoint_jbytes(src, dest, count); |
0 | 359 JRT_END |
360 | |
361 JRT_LEAF(void, StubRoutines::arrayof_jshort_copy(HeapWord* src, HeapWord* dest, size_t count)) | |
362 #ifndef PRODUCT | |
363 SharedRuntime::_jshort_array_copy_ctr++; // Slow-path short/char array copy | |
364 #endif // !PRODUCT | |
365 Copy::arrayof_conjoint_jshorts(src, dest, count); | |
366 JRT_END | |
367 | |
368 JRT_LEAF(void, StubRoutines::arrayof_jint_copy(HeapWord* src, HeapWord* dest, size_t count)) | |
369 #ifndef PRODUCT | |
370 SharedRuntime::_jint_array_copy_ctr++; // Slow-path int/float array copy | |
371 #endif // !PRODUCT | |
372 Copy::arrayof_conjoint_jints(src, dest, count); | |
373 JRT_END | |
374 | |
375 JRT_LEAF(void, StubRoutines::arrayof_jlong_copy(HeapWord* src, HeapWord* dest, size_t count)) | |
376 #ifndef PRODUCT | |
377 SharedRuntime::_jlong_array_copy_ctr++; // Slow-path int/float array copy | |
378 #endif // !PRODUCT | |
379 Copy::arrayof_conjoint_jlongs(src, dest, count); | |
380 JRT_END | |
381 | |
382 JRT_LEAF(void, StubRoutines::arrayof_oop_copy(HeapWord* src, HeapWord* dest, size_t count)) | |
383 #ifndef PRODUCT | |
384 SharedRuntime::_oop_array_copy_ctr++; // Slow-path oop array copy | |
385 #endif // !PRODUCT | |
386 assert(count != 0, "count should be non-zero"); | |
2324 | 387 gen_arraycopy_barrier_pre((oop *) dest, count, /*dest_uninitialized*/false); |
0 | 388 Copy::arrayof_conjoint_oops(src, dest, count); |
389 gen_arraycopy_barrier((oop *) dest, count); | |
390 JRT_END | |
1763 | 391 |
2324 | 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 | |
1763 | 401 |
402 address StubRoutines::select_fill_function(BasicType t, bool aligned, const char* &name) { | |
403 #define RETURN_STUB(xxx_fill) { \ | |
404 name = #xxx_fill; \ | |
405 return StubRoutines::xxx_fill(); } | |
406 | |
407 switch (t) { | |
408 case T_BYTE: | |
409 case T_BOOLEAN: | |
410 if (!aligned) RETURN_STUB(jbyte_fill); | |
411 RETURN_STUB(arrayof_jbyte_fill); | |
412 case T_CHAR: | |
413 case T_SHORT: | |
414 if (!aligned) RETURN_STUB(jshort_fill); | |
415 RETURN_STUB(arrayof_jshort_fill); | |
416 case T_INT: | |
417 case T_FLOAT: | |
418 if (!aligned) RETURN_STUB(jint_fill); | |
419 RETURN_STUB(arrayof_jint_fill); | |
420 case T_DOUBLE: | |
421 case T_LONG: | |
422 case T_ARRAY: | |
423 case T_OBJECT: | |
424 case T_NARROWOOP: | |
425 case T_ADDRESS: | |
426 // Currently unsupported | |
427 return NULL; | |
428 | |
429 default: | |
430 ShouldNotReachHere(); | |
431 return NULL; | |
432 } | |
433 | |
434 #undef RETURN_STUB | |
435 } | |
2446 | 436 |
437 // constants for computing the copy function | |
438 enum { | |
439 COPYFUNC_UNALIGNED = 0, | |
440 COPYFUNC_ALIGNED = 1, // src, dest aligned to HeapWordSize | |
441 COPYFUNC_CONJOINT = 0, | |
442 COPYFUNC_DISJOINT = 2 // src != dest, or transfer can descend | |
443 }; | |
444 | |
445 // Note: The condition "disjoint" applies also for overlapping copies | |
446 // where an descending copy is permitted (i.e., dest_offset <= src_offset). | |
447 address | |
448 StubRoutines::select_arraycopy_function(BasicType t, bool aligned, bool disjoint, const char* &name, bool dest_uninitialized) { | |
449 int selector = | |
450 (aligned ? COPYFUNC_ALIGNED : COPYFUNC_UNALIGNED) + | |
451 (disjoint ? COPYFUNC_DISJOINT : COPYFUNC_CONJOINT); | |
452 | |
453 #define RETURN_STUB(xxx_arraycopy) { \ | |
454 name = #xxx_arraycopy; \ | |
455 return StubRoutines::xxx_arraycopy(); } | |
456 | |
457 #define RETURN_STUB_PARM(xxx_arraycopy, parm) { \ | |
458 name = #xxx_arraycopy; \ | |
459 return StubRoutines::xxx_arraycopy(parm); } | |
460 | |
461 switch (t) { | |
462 case T_BYTE: | |
463 case T_BOOLEAN: | |
464 switch (selector) { | |
465 case COPYFUNC_CONJOINT | COPYFUNC_UNALIGNED: RETURN_STUB(jbyte_arraycopy); | |
466 case COPYFUNC_CONJOINT | COPYFUNC_ALIGNED: RETURN_STUB(arrayof_jbyte_arraycopy); | |
467 case COPYFUNC_DISJOINT | COPYFUNC_UNALIGNED: RETURN_STUB(jbyte_disjoint_arraycopy); | |
468 case COPYFUNC_DISJOINT | COPYFUNC_ALIGNED: RETURN_STUB(arrayof_jbyte_disjoint_arraycopy); | |
469 } | |
470 case T_CHAR: | |
471 case T_SHORT: | |
472 switch (selector) { | |
473 case COPYFUNC_CONJOINT | COPYFUNC_UNALIGNED: RETURN_STUB(jshort_arraycopy); | |
474 case COPYFUNC_CONJOINT | COPYFUNC_ALIGNED: RETURN_STUB(arrayof_jshort_arraycopy); | |
475 case COPYFUNC_DISJOINT | COPYFUNC_UNALIGNED: RETURN_STUB(jshort_disjoint_arraycopy); | |
476 case COPYFUNC_DISJOINT | COPYFUNC_ALIGNED: RETURN_STUB(arrayof_jshort_disjoint_arraycopy); | |
477 } | |
478 case T_INT: | |
479 case T_FLOAT: | |
480 switch (selector) { | |
481 case COPYFUNC_CONJOINT | COPYFUNC_UNALIGNED: RETURN_STUB(jint_arraycopy); | |
482 case COPYFUNC_CONJOINT | COPYFUNC_ALIGNED: RETURN_STUB(arrayof_jint_arraycopy); | |
483 case COPYFUNC_DISJOINT | COPYFUNC_UNALIGNED: RETURN_STUB(jint_disjoint_arraycopy); | |
484 case COPYFUNC_DISJOINT | COPYFUNC_ALIGNED: RETURN_STUB(arrayof_jint_disjoint_arraycopy); | |
485 } | |
486 case T_DOUBLE: | |
487 case T_LONG: | |
488 switch (selector) { | |
489 case COPYFUNC_CONJOINT | COPYFUNC_UNALIGNED: RETURN_STUB(jlong_arraycopy); | |
490 case COPYFUNC_CONJOINT | COPYFUNC_ALIGNED: RETURN_STUB(arrayof_jlong_arraycopy); | |
491 case COPYFUNC_DISJOINT | COPYFUNC_UNALIGNED: RETURN_STUB(jlong_disjoint_arraycopy); | |
492 case COPYFUNC_DISJOINT | COPYFUNC_ALIGNED: RETURN_STUB(arrayof_jlong_disjoint_arraycopy); | |
493 } | |
494 case T_ARRAY: | |
495 case T_OBJECT: | |
496 switch (selector) { | |
497 case COPYFUNC_CONJOINT | COPYFUNC_UNALIGNED: RETURN_STUB_PARM(oop_arraycopy, dest_uninitialized); | |
498 case COPYFUNC_CONJOINT | COPYFUNC_ALIGNED: RETURN_STUB_PARM(arrayof_oop_arraycopy, dest_uninitialized); | |
499 case COPYFUNC_DISJOINT | COPYFUNC_UNALIGNED: RETURN_STUB_PARM(oop_disjoint_arraycopy, dest_uninitialized); | |
500 case COPYFUNC_DISJOINT | COPYFUNC_ALIGNED: RETURN_STUB_PARM(arrayof_oop_disjoint_arraycopy, dest_uninitialized); | |
501 } | |
502 default: | |
503 ShouldNotReachHere(); | |
504 return NULL; | |
505 } | |
506 | |
507 #undef RETURN_STUB | |
508 #undef RETURN_STUB_PARM | |
509 } |