Mercurial > hg > graal-compiler
annotate src/share/vm/runtime/stubRoutines.cpp @ 1091:6aa7255741f3
6906727: UseCompressedOops: some card-marking fixes related to object arrays
Summary: Introduced a new write_ref_array(HeapWords* start, size_t count) method that does the requisite MemRegion range calculation so (some of the) clients of the erstwhile write_ref_array(MemRegion mr) do not need to worry. This removed all external uses of array_size(), which was also simplified and made private. Asserts were added to catch other possible issues. Further, less essential, fixes stemming from this investigation are deferred to CR 6904516 (to follow shortly in hs17).
Reviewed-by: kvn, coleenp, jmasa
author | ysr |
---|---|
date | Thu, 03 Dec 2009 15:01:57 -0800 |
parents | f8236e79048a |
children | ddb7834449d0 |
rev | line source |
---|---|
0 | 1 /* |
2 * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. | |
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 * | |
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
20 * CA 95054 USA or visit www.sun.com if you need additional information or | |
21 * have any questions. | |
22 * | |
23 */ | |
24 | |
25 #include "incls/_precompiled.incl" | |
26 #include "incls/_stubRoutines.cpp.incl" | |
27 | |
28 | |
29 // Implementation of StubRoutines - for a description | |
30 // of how to extend it, see the header file. | |
31 | |
32 // Class Variables | |
33 | |
34 BufferBlob* StubRoutines::_code1 = NULL; | |
35 BufferBlob* StubRoutines::_code2 = NULL; | |
36 | |
37 address StubRoutines::_call_stub_return_address = NULL; | |
38 address StubRoutines::_call_stub_entry = NULL; | |
39 | |
40 address StubRoutines::_catch_exception_entry = NULL; | |
41 address StubRoutines::_forward_exception_entry = NULL; | |
42 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
|
43 address StubRoutines::_throw_IncompatibleClassChangeError_entry = NULL; |
0 | 44 address StubRoutines::_throw_ArithmeticException_entry = NULL; |
45 address StubRoutines::_throw_NullPointerException_entry = NULL; | |
46 address StubRoutines::_throw_NullPointerException_at_call_entry = NULL; | |
47 address StubRoutines::_throw_StackOverflowError_entry = NULL; | |
48 address StubRoutines::_handler_for_unsafe_access_entry = NULL; | |
49 jint StubRoutines::_verify_oop_count = 0; | |
50 address StubRoutines::_verify_oop_subroutine_entry = NULL; | |
51 address StubRoutines::_atomic_xchg_entry = NULL; | |
52 address StubRoutines::_atomic_xchg_ptr_entry = NULL; | |
53 address StubRoutines::_atomic_store_entry = NULL; | |
54 address StubRoutines::_atomic_store_ptr_entry = NULL; | |
55 address StubRoutines::_atomic_cmpxchg_entry = NULL; | |
56 address StubRoutines::_atomic_cmpxchg_ptr_entry = NULL; | |
57 address StubRoutines::_atomic_cmpxchg_long_entry = NULL; | |
58 address StubRoutines::_atomic_add_entry = NULL; | |
59 address StubRoutines::_atomic_add_ptr_entry = NULL; | |
60 address StubRoutines::_fence_entry = NULL; | |
61 address StubRoutines::_d2i_wrapper = NULL; | |
62 address StubRoutines::_d2l_wrapper = NULL; | |
63 | |
64 jint StubRoutines::_fpu_cntrl_wrd_std = 0; | |
65 jint StubRoutines::_fpu_cntrl_wrd_24 = 0; | |
66 jint StubRoutines::_fpu_cntrl_wrd_64 = 0; | |
67 jint StubRoutines::_fpu_cntrl_wrd_trunc = 0; | |
68 jint StubRoutines::_mxcsr_std = 0; | |
69 jint StubRoutines::_fpu_subnormal_bias1[3] = { 0, 0, 0 }; | |
70 jint StubRoutines::_fpu_subnormal_bias2[3] = { 0, 0, 0 }; | |
71 | |
72 // Compiled code entry points default values | |
73 // The dafault functions don't have separate disjoint versions. | |
74 address StubRoutines::_jbyte_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jbyte_copy); | |
75 address StubRoutines::_jshort_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jshort_copy); | |
76 address StubRoutines::_jint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jint_copy); | |
77 address StubRoutines::_jlong_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jlong_copy); | |
78 address StubRoutines::_oop_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::oop_copy); | |
79 address StubRoutines::_jbyte_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jbyte_copy); | |
80 address StubRoutines::_jshort_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jshort_copy); | |
81 address StubRoutines::_jint_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jint_copy); | |
82 address StubRoutines::_jlong_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jlong_copy); | |
83 address StubRoutines::_oop_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::oop_copy); | |
84 | |
85 address StubRoutines::_arrayof_jbyte_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jbyte_copy); | |
86 address StubRoutines::_arrayof_jshort_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jshort_copy); | |
87 address StubRoutines::_arrayof_jint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jint_copy); | |
88 address StubRoutines::_arrayof_jlong_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jlong_copy); | |
89 address StubRoutines::_arrayof_oop_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_oop_copy); | |
90 address StubRoutines::_arrayof_jbyte_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jbyte_copy); | |
91 address StubRoutines::_arrayof_jshort_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jshort_copy); | |
92 address StubRoutines::_arrayof_jint_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jint_copy); | |
93 address StubRoutines::_arrayof_jlong_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jlong_copy); | |
94 address StubRoutines::_arrayof_oop_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_oop_copy); | |
95 | |
96 address StubRoutines::_checkcast_arraycopy = NULL; | |
97 address StubRoutines::_unsafe_arraycopy = NULL; | |
98 address StubRoutines::_generic_arraycopy = NULL; | |
99 | |
100 // Initialization | |
101 // | |
102 // Note: to break cycle with universe initialization, stubs are generated in two phases. | |
103 // The first one generates stubs needed during universe init (e.g., _handle_must_compile_first_entry). | |
104 // The second phase includes all other stubs (which may depend on universe being initialized.) | |
105 | |
106 extern void StubGenerator_generate(CodeBuffer* code, bool all); // only interface to generators | |
107 | |
108 void StubRoutines::initialize1() { | |
109 if (_code1 == NULL) { | |
110 ResourceMark rm; | |
111 TraceTime timer("StubRoutines generation 1", TraceStartupTime); | |
112 _code1 = BufferBlob::create("StubRoutines (1)", code_size1); | |
113 if( _code1 == NULL) vm_exit_out_of_memory1(code_size1, "CodeCache: no room for %s", "StubRoutines (1)"); | |
114 CodeBuffer buffer(_code1->instructions_begin(), _code1->instructions_size()); | |
115 StubGenerator_generate(&buffer, false); | |
116 } | |
117 } | |
118 | |
119 | |
120 #ifdef ASSERT | |
121 typedef void (*arraycopy_fn)(address src, address dst, int count); | |
122 | |
123 // simple tests of generated arraycopy functions | |
124 static void test_arraycopy_func(address func, int alignment) { | |
125 int v = 0xcc; | |
126 int v2 = 0x11; | |
127 jlong lbuffer[2]; | |
128 jlong lbuffer2[2]; | |
129 address buffer = (address) lbuffer; | |
130 address buffer2 = (address) lbuffer2; | |
131 unsigned int i; | |
132 for (i = 0; i < sizeof(lbuffer); i++) { | |
133 buffer[i] = v; buffer2[i] = v2; | |
134 } | |
135 // do an aligned copy | |
136 ((arraycopy_fn)func)(buffer, buffer2, 0); | |
137 for (i = 0; i < sizeof(lbuffer); i++) { | |
138 assert(buffer[i] == v && buffer2[i] == v2, "shouldn't have copied anything"); | |
139 } | |
140 // adjust destination alignment | |
141 ((arraycopy_fn)func)(buffer, buffer2 + alignment, 0); | |
142 for (i = 0; i < sizeof(lbuffer); i++) { | |
143 assert(buffer[i] == v && buffer2[i] == v2, "shouldn't have copied anything"); | |
144 } | |
145 // adjust source alignment | |
146 ((arraycopy_fn)func)(buffer + alignment, buffer2, 0); | |
147 for (i = 0; i < sizeof(lbuffer); i++) { | |
148 assert(buffer[i] == v && buffer2[i] == v2, "shouldn't have copied anything"); | |
149 } | |
150 } | |
151 #endif | |
152 | |
153 | |
154 void StubRoutines::initialize2() { | |
155 if (_code2 == NULL) { | |
156 ResourceMark rm; | |
157 TraceTime timer("StubRoutines generation 2", TraceStartupTime); | |
158 _code2 = BufferBlob::create("StubRoutines (2)", code_size2); | |
159 if( _code2 == NULL) vm_exit_out_of_memory1(code_size2, "CodeCache: no room for %s", "StubRoutines (2)"); | |
160 CodeBuffer buffer(_code2->instructions_begin(), _code2->instructions_size()); | |
161 StubGenerator_generate(&buffer, true); | |
162 } | |
163 | |
164 #ifdef ASSERT | |
165 | |
166 #define TEST_ARRAYCOPY(type) \ | |
167 test_arraycopy_func( type##_arraycopy(), sizeof(type)); \ | |
168 test_arraycopy_func( type##_disjoint_arraycopy(), sizeof(type)); \ | |
169 test_arraycopy_func(arrayof_##type##_arraycopy(), sizeof(HeapWord)); \ | |
170 test_arraycopy_func(arrayof_##type##_disjoint_arraycopy(), sizeof(HeapWord)) | |
171 | |
172 // Make sure all the arraycopy stubs properly handle zeros | |
173 TEST_ARRAYCOPY(jbyte); | |
174 TEST_ARRAYCOPY(jshort); | |
175 TEST_ARRAYCOPY(jint); | |
176 TEST_ARRAYCOPY(jlong); | |
177 | |
178 #undef TEST_ARRAYCOPY | |
179 | |
180 #endif | |
181 } | |
182 | |
183 | |
184 void stubRoutines_init1() { StubRoutines::initialize1(); } | |
185 void stubRoutines_init2() { StubRoutines::initialize2(); } | |
186 | |
187 // | |
188 // Default versions of arraycopy functions | |
189 // | |
190 | |
191 static void gen_arraycopy_barrier(oop* dest, size_t count) { | |
192 assert(count != 0, "count should be non-zero"); | |
193 BarrierSet* bs = Universe::heap()->barrier_set(); | |
194 assert(bs->has_write_ref_array_opt(), "Barrier set must have ref array opt"); | |
195 bs->write_ref_array(MemRegion((HeapWord*)dest, (HeapWord*)(dest + count))); | |
196 } | |
197 | |
198 JRT_LEAF(void, StubRoutines::jbyte_copy(jbyte* src, jbyte* dest, size_t count)) | |
199 #ifndef PRODUCT | |
200 SharedRuntime::_jbyte_array_copy_ctr++; // Slow-path byte array copy | |
201 #endif // !PRODUCT | |
202 assert(count != 0, "count should be non-zero"); | |
203 Copy::conjoint_bytes_atomic(src, dest, count); | |
204 JRT_END | |
205 | |
206 JRT_LEAF(void, StubRoutines::jshort_copy(jshort* src, jshort* dest, size_t count)) | |
207 #ifndef PRODUCT | |
208 SharedRuntime::_jshort_array_copy_ctr++; // Slow-path short/char array copy | |
209 #endif // !PRODUCT | |
210 assert(count != 0, "count should be non-zero"); | |
211 Copy::conjoint_jshorts_atomic(src, dest, count); | |
212 JRT_END | |
213 | |
214 JRT_LEAF(void, StubRoutines::jint_copy(jint* src, jint* dest, size_t count)) | |
215 #ifndef PRODUCT | |
216 SharedRuntime::_jint_array_copy_ctr++; // Slow-path int/float array copy | |
217 #endif // !PRODUCT | |
218 assert(count != 0, "count should be non-zero"); | |
219 Copy::conjoint_jints_atomic(src, dest, count); | |
220 JRT_END | |
221 | |
222 JRT_LEAF(void, StubRoutines::jlong_copy(jlong* src, jlong* dest, size_t count)) | |
223 #ifndef PRODUCT | |
224 SharedRuntime::_jlong_array_copy_ctr++; // Slow-path long/double array copy | |
225 #endif // !PRODUCT | |
226 assert(count != 0, "count should be non-zero"); | |
227 Copy::conjoint_jlongs_atomic(src, dest, count); | |
228 JRT_END | |
229 | |
230 JRT_LEAF(void, StubRoutines::oop_copy(oop* src, oop* dest, size_t count)) | |
231 #ifndef PRODUCT | |
232 SharedRuntime::_oop_array_copy_ctr++; // Slow-path oop array copy | |
233 #endif // !PRODUCT | |
234 assert(count != 0, "count should be non-zero"); | |
235 Copy::conjoint_oops_atomic(src, dest, count); | |
236 gen_arraycopy_barrier(dest, count); | |
237 JRT_END | |
238 | |
239 JRT_LEAF(void, StubRoutines::arrayof_jbyte_copy(HeapWord* src, HeapWord* dest, size_t count)) | |
240 #ifndef PRODUCT | |
241 SharedRuntime::_jbyte_array_copy_ctr++; // Slow-path byte array copy | |
242 #endif // !PRODUCT | |
243 assert(count != 0, "count should be non-zero"); | |
244 Copy::arrayof_conjoint_bytes(src, dest, count); | |
245 JRT_END | |
246 | |
247 JRT_LEAF(void, StubRoutines::arrayof_jshort_copy(HeapWord* src, HeapWord* dest, size_t count)) | |
248 #ifndef PRODUCT | |
249 SharedRuntime::_jshort_array_copy_ctr++; // Slow-path short/char array copy | |
250 #endif // !PRODUCT | |
251 assert(count != 0, "count should be non-zero"); | |
252 Copy::arrayof_conjoint_jshorts(src, dest, count); | |
253 JRT_END | |
254 | |
255 JRT_LEAF(void, StubRoutines::arrayof_jint_copy(HeapWord* src, HeapWord* dest, size_t count)) | |
256 #ifndef PRODUCT | |
257 SharedRuntime::_jint_array_copy_ctr++; // Slow-path int/float array copy | |
258 #endif // !PRODUCT | |
259 assert(count != 0, "count should be non-zero"); | |
260 Copy::arrayof_conjoint_jints(src, dest, count); | |
261 JRT_END | |
262 | |
263 JRT_LEAF(void, StubRoutines::arrayof_jlong_copy(HeapWord* src, HeapWord* dest, size_t count)) | |
264 #ifndef PRODUCT | |
265 SharedRuntime::_jlong_array_copy_ctr++; // Slow-path int/float array copy | |
266 #endif // !PRODUCT | |
267 assert(count != 0, "count should be non-zero"); | |
268 Copy::arrayof_conjoint_jlongs(src, dest, count); | |
269 JRT_END | |
270 | |
271 JRT_LEAF(void, StubRoutines::arrayof_oop_copy(HeapWord* src, HeapWord* dest, size_t count)) | |
272 #ifndef PRODUCT | |
273 SharedRuntime::_oop_array_copy_ctr++; // Slow-path oop array copy | |
274 #endif // !PRODUCT | |
275 assert(count != 0, "count should be non-zero"); | |
276 Copy::arrayof_conjoint_oops(src, dest, count); | |
277 gen_arraycopy_barrier((oop *) dest, count); | |
278 JRT_END |