stubRoutines.cpp revision 1668:3e8fbc61cee8
1/*
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * 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
34BufferBlob* StubRoutines::_code1                                = NULL;
35BufferBlob* StubRoutines::_code2                                = NULL;
36
37address StubRoutines::_call_stub_return_address                 = NULL;
38address StubRoutines::_call_stub_entry                          = NULL;
39
40address StubRoutines::_catch_exception_entry                    = NULL;
41address StubRoutines::_forward_exception_entry                  = NULL;
42address StubRoutines::_throw_AbstractMethodError_entry          = NULL;
43address StubRoutines::_throw_IncompatibleClassChangeError_entry = NULL;
44address StubRoutines::_throw_ArithmeticException_entry          = NULL;
45address StubRoutines::_throw_NullPointerException_entry         = NULL;
46address StubRoutines::_throw_NullPointerException_at_call_entry = NULL;
47address StubRoutines::_throw_StackOverflowError_entry           = NULL;
48address StubRoutines::_handler_for_unsafe_access_entry          = NULL;
49jint    StubRoutines::_verify_oop_count                         = 0;
50address StubRoutines::_verify_oop_subroutine_entry              = NULL;
51address StubRoutines::_atomic_xchg_entry                        = NULL;
52address StubRoutines::_atomic_xchg_ptr_entry                    = NULL;
53address StubRoutines::_atomic_store_entry                       = NULL;
54address StubRoutines::_atomic_store_ptr_entry                   = NULL;
55address StubRoutines::_atomic_cmpxchg_entry                     = NULL;
56address StubRoutines::_atomic_cmpxchg_ptr_entry                 = NULL;
57address StubRoutines::_atomic_cmpxchg_long_entry                = NULL;
58address StubRoutines::_atomic_add_entry                         = NULL;
59address StubRoutines::_atomic_add_ptr_entry                     = NULL;
60address StubRoutines::_fence_entry                              = NULL;
61address StubRoutines::_d2i_wrapper                              = NULL;
62address StubRoutines::_d2l_wrapper                              = NULL;
63
64jint    StubRoutines::_fpu_cntrl_wrd_std                        = 0;
65jint    StubRoutines::_fpu_cntrl_wrd_24                         = 0;
66jint    StubRoutines::_fpu_cntrl_wrd_64                         = 0;
67jint    StubRoutines::_fpu_cntrl_wrd_trunc                      = 0;
68jint    StubRoutines::_mxcsr_std                                = 0;
69jint    StubRoutines::_fpu_subnormal_bias1[3]                   = { 0, 0, 0 };
70jint    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.
74address StubRoutines::_jbyte_arraycopy          = CAST_FROM_FN_PTR(address, StubRoutines::jbyte_copy);
75address StubRoutines::_jshort_arraycopy         = CAST_FROM_FN_PTR(address, StubRoutines::jshort_copy);
76address StubRoutines::_jint_arraycopy           = CAST_FROM_FN_PTR(address, StubRoutines::jint_copy);
77address StubRoutines::_jlong_arraycopy          = CAST_FROM_FN_PTR(address, StubRoutines::jlong_copy);
78address StubRoutines::_oop_arraycopy            = CAST_FROM_FN_PTR(address, StubRoutines::oop_copy);
79address StubRoutines::_jbyte_disjoint_arraycopy          = CAST_FROM_FN_PTR(address, StubRoutines::jbyte_copy);
80address StubRoutines::_jshort_disjoint_arraycopy         = CAST_FROM_FN_PTR(address, StubRoutines::jshort_copy);
81address StubRoutines::_jint_disjoint_arraycopy           = CAST_FROM_FN_PTR(address, StubRoutines::jint_copy);
82address StubRoutines::_jlong_disjoint_arraycopy          = CAST_FROM_FN_PTR(address, StubRoutines::jlong_copy);
83address StubRoutines::_oop_disjoint_arraycopy            = CAST_FROM_FN_PTR(address, StubRoutines::oop_copy);
84
85address StubRoutines::_arrayof_jbyte_arraycopy  = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jbyte_copy);
86address StubRoutines::_arrayof_jshort_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jshort_copy);
87address StubRoutines::_arrayof_jint_arraycopy   = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jint_copy);
88address StubRoutines::_arrayof_jlong_arraycopy  = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jlong_copy);
89address StubRoutines::_arrayof_oop_arraycopy    = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_oop_copy);
90address StubRoutines::_arrayof_jbyte_disjoint_arraycopy  = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jbyte_copy);
91address StubRoutines::_arrayof_jshort_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jshort_copy);
92address StubRoutines::_arrayof_jint_disjoint_arraycopy   = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jint_copy);
93address StubRoutines::_arrayof_jlong_disjoint_arraycopy  = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jlong_copy);
94address StubRoutines::_arrayof_oop_disjoint_arraycopy  = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_oop_copy);
95
96address StubRoutines::_checkcast_arraycopy               = NULL;
97address StubRoutines::_unsafe_arraycopy                  = NULL;
98address StubRoutines::_generic_arraycopy                 = NULL;
99
100double (* StubRoutines::_intrinsic_log   )(double) = NULL;
101double (* StubRoutines::_intrinsic_log10 )(double) = NULL;
102double (* StubRoutines::_intrinsic_exp   )(double) = NULL;
103double (* StubRoutines::_intrinsic_pow   )(double, double) = NULL;
104double (* StubRoutines::_intrinsic_sin   )(double) = NULL;
105double (* StubRoutines::_intrinsic_cos   )(double) = NULL;
106double (* StubRoutines::_intrinsic_tan   )(double) = NULL;
107
108// Initialization
109//
110// Note: to break cycle with universe initialization, stubs are generated in two phases.
111// The first one generates stubs needed during universe init (e.g., _handle_must_compile_first_entry).
112// The second phase includes all other stubs (which may depend on universe being initialized.)
113
114extern void StubGenerator_generate(CodeBuffer* code, bool all); // only interface to generators
115
116void StubRoutines::initialize1() {
117  if (_code1 == NULL) {
118    ResourceMark rm;
119    TraceTime timer("StubRoutines generation 1", TraceStartupTime);
120    _code1 = BufferBlob::create("StubRoutines (1)", code_size1);
121    if (_code1 == NULL) {
122      vm_exit_out_of_memory(code_size1, "CodeCache: no room for StubRoutines (1)");
123    }
124    CodeBuffer buffer(_code1);
125    StubGenerator_generate(&buffer, false);
126  }
127}
128
129
130#ifdef ASSERT
131typedef void (*arraycopy_fn)(address src, address dst, int count);
132
133// simple tests of generated arraycopy functions
134static void test_arraycopy_func(address func, int alignment) {
135  int v = 0xcc;
136  int v2 = 0x11;
137  jlong lbuffer[8];
138  jlong lbuffer2[8];
139  address fbuffer  = (address) lbuffer;
140  address fbuffer2 = (address) lbuffer2;
141  unsigned int i;
142  for (i = 0; i < sizeof(lbuffer); i++) {
143    fbuffer[i] = v; fbuffer2[i] = v2;
144  }
145  // C++ does not guarantee jlong[] array alignment to 8 bytes.
146  // Use middle of array to check that memory before it is not modified.
147  address buffer  = (address) round_to((intptr_t)&lbuffer[4], BytesPerLong);
148  address buffer2 = (address) round_to((intptr_t)&lbuffer2[4], BytesPerLong);
149  // do an aligned copy
150  ((arraycopy_fn)func)(buffer, buffer2, 0);
151  for (i = 0; i < sizeof(lbuffer); i++) {
152    assert(fbuffer[i] == v && fbuffer2[i] == v2, "shouldn't have copied anything");
153  }
154  // adjust destination alignment
155  ((arraycopy_fn)func)(buffer, buffer2 + alignment, 0);
156  for (i = 0; i < sizeof(lbuffer); i++) {
157    assert(fbuffer[i] == v && fbuffer2[i] == v2, "shouldn't have copied anything");
158  }
159  // adjust source alignment
160  ((arraycopy_fn)func)(buffer + alignment, buffer2, 0);
161  for (i = 0; i < sizeof(lbuffer); i++) {
162    assert(fbuffer[i] == v && fbuffer2[i] == v2, "shouldn't have copied anything");
163  }
164}
165#endif
166
167
168void StubRoutines::initialize2() {
169  if (_code2 == NULL) {
170    ResourceMark rm;
171    TraceTime timer("StubRoutines generation 2", TraceStartupTime);
172    _code2 = BufferBlob::create("StubRoutines (2)", code_size2);
173    if (_code2 == NULL) {
174      vm_exit_out_of_memory(code_size2, "CodeCache: no room for StubRoutines (2)");
175    }
176    CodeBuffer buffer(_code2);
177    StubGenerator_generate(&buffer, true);
178  }
179
180#ifdef ASSERT
181
182#define TEST_ARRAYCOPY(type)                                                    \
183  test_arraycopy_func(          type##_arraycopy(),          sizeof(type));     \
184  test_arraycopy_func(          type##_disjoint_arraycopy(), sizeof(type));     \
185  test_arraycopy_func(arrayof_##type##_arraycopy(),          sizeof(HeapWord)); \
186  test_arraycopy_func(arrayof_##type##_disjoint_arraycopy(), sizeof(HeapWord))
187
188  // Make sure all the arraycopy stubs properly handle zero count
189  TEST_ARRAYCOPY(jbyte);
190  TEST_ARRAYCOPY(jshort);
191  TEST_ARRAYCOPY(jint);
192  TEST_ARRAYCOPY(jlong);
193
194#undef TEST_ARRAYCOPY
195
196#define TEST_COPYRTN(type) \
197  test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::conjoint_##type##s_atomic),  sizeof(type)); \
198  test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::arrayof_conjoint_##type##s), (int)MAX2(sizeof(HeapWord), sizeof(type)))
199
200  // Make sure all the copy runtime routines properly handle zero count
201  TEST_COPYRTN(jbyte);
202  TEST_COPYRTN(jshort);
203  TEST_COPYRTN(jint);
204  TEST_COPYRTN(jlong);
205
206#undef TEST_COPYRTN
207
208  test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::conjoint_words), sizeof(HeapWord));
209  test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::disjoint_words), sizeof(HeapWord));
210  test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::disjoint_words_atomic), sizeof(HeapWord));
211  // Aligned to BytesPerLong
212  test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::aligned_conjoint_words), sizeof(jlong));
213  test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::aligned_disjoint_words), sizeof(jlong));
214
215#endif
216}
217
218
219void stubRoutines_init1() { StubRoutines::initialize1(); }
220void stubRoutines_init2() { StubRoutines::initialize2(); }
221
222//
223// Default versions of arraycopy functions
224//
225
226static void gen_arraycopy_barrier_pre(oop* dest, size_t count) {
227    assert(count != 0, "count should be non-zero");
228    assert(count <= (size_t)max_intx, "count too large");
229    BarrierSet* bs = Universe::heap()->barrier_set();
230    assert(bs->has_write_ref_array_pre_opt(), "Must have pre-barrier opt");
231    bs->write_ref_array_pre(dest, (int)count);
232}
233
234static void gen_arraycopy_barrier(oop* dest, size_t count) {
235    assert(count != 0, "count should be non-zero");
236    BarrierSet* bs = Universe::heap()->barrier_set();
237    assert(bs->has_write_ref_array_opt(), "Barrier set must have ref array opt");
238    bs->write_ref_array((HeapWord*)dest, count);
239}
240
241JRT_LEAF(void, StubRoutines::jbyte_copy(jbyte* src, jbyte* dest, size_t count))
242#ifndef PRODUCT
243  SharedRuntime::_jbyte_array_copy_ctr++;      // Slow-path byte array copy
244#endif // !PRODUCT
245  Copy::conjoint_jbytes_atomic(src, dest, count);
246JRT_END
247
248JRT_LEAF(void, StubRoutines::jshort_copy(jshort* src, jshort* dest, size_t count))
249#ifndef PRODUCT
250  SharedRuntime::_jshort_array_copy_ctr++;     // Slow-path short/char array copy
251#endif // !PRODUCT
252  Copy::conjoint_jshorts_atomic(src, dest, count);
253JRT_END
254
255JRT_LEAF(void, StubRoutines::jint_copy(jint* src, jint* dest, size_t count))
256#ifndef PRODUCT
257  SharedRuntime::_jint_array_copy_ctr++;       // Slow-path int/float array copy
258#endif // !PRODUCT
259  Copy::conjoint_jints_atomic(src, dest, count);
260JRT_END
261
262JRT_LEAF(void, StubRoutines::jlong_copy(jlong* src, jlong* dest, size_t count))
263#ifndef PRODUCT
264  SharedRuntime::_jlong_array_copy_ctr++;      // Slow-path long/double array copy
265#endif // !PRODUCT
266  Copy::conjoint_jlongs_atomic(src, dest, count);
267JRT_END
268
269JRT_LEAF(void, StubRoutines::oop_copy(oop* src, oop* dest, size_t count))
270#ifndef PRODUCT
271  SharedRuntime::_oop_array_copy_ctr++;        // Slow-path oop array copy
272#endif // !PRODUCT
273  assert(count != 0, "count should be non-zero");
274  gen_arraycopy_barrier_pre(dest, count);
275  Copy::conjoint_oops_atomic(src, dest, count);
276  gen_arraycopy_barrier(dest, count);
277JRT_END
278
279JRT_LEAF(void, StubRoutines::arrayof_jbyte_copy(HeapWord* src, HeapWord* dest, size_t count))
280#ifndef PRODUCT
281  SharedRuntime::_jbyte_array_copy_ctr++;      // Slow-path byte array copy
282#endif // !PRODUCT
283  Copy::arrayof_conjoint_jbytes(src, dest, count);
284JRT_END
285
286JRT_LEAF(void, StubRoutines::arrayof_jshort_copy(HeapWord* src, HeapWord* dest, size_t count))
287#ifndef PRODUCT
288  SharedRuntime::_jshort_array_copy_ctr++;     // Slow-path short/char array copy
289#endif // !PRODUCT
290  Copy::arrayof_conjoint_jshorts(src, dest, count);
291JRT_END
292
293JRT_LEAF(void, StubRoutines::arrayof_jint_copy(HeapWord* src, HeapWord* dest, size_t count))
294#ifndef PRODUCT
295  SharedRuntime::_jint_array_copy_ctr++;       // Slow-path int/float array copy
296#endif // !PRODUCT
297  Copy::arrayof_conjoint_jints(src, dest, count);
298JRT_END
299
300JRT_LEAF(void, StubRoutines::arrayof_jlong_copy(HeapWord* src, HeapWord* dest, size_t count))
301#ifndef PRODUCT
302  SharedRuntime::_jlong_array_copy_ctr++;       // Slow-path int/float array copy
303#endif // !PRODUCT
304  Copy::arrayof_conjoint_jlongs(src, dest, count);
305JRT_END
306
307JRT_LEAF(void, StubRoutines::arrayof_oop_copy(HeapWord* src, HeapWord* dest, size_t count))
308#ifndef PRODUCT
309  SharedRuntime::_oop_array_copy_ctr++;        // Slow-path oop array copy
310#endif // !PRODUCT
311  assert(count != 0, "count should be non-zero");
312  gen_arraycopy_barrier_pre((oop *) dest, count);
313  Copy::arrayof_conjoint_oops(src, dest, count);
314  gen_arraycopy_barrier((oop *) dest, count);
315JRT_END
316