stubRoutines.cpp revision 1410:f03d0a26bf83
1139749Simp/* 2116491Sharti * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. 3116491Sharti * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4116491Sharti * 5116491Sharti * This code is free software; you can redistribute it and/or modify it 6116491Sharti * under the terms of the GNU General Public License version 2 only, as 7116491Sharti * published by the Free Software Foundation. 8116491Sharti * 9116491Sharti * This code is distributed in the hope that it will be useful, but WITHOUT 10116491Sharti * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11116491Sharti * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12116491Sharti * version 2 for more details (a copy is included in the LICENSE file that 13116491Sharti * accompanied this code). 14116491Sharti * 15116491Sharti * You should have received a copy of the GNU General Public License version 16116491Sharti * 2 along with this work; if not, write to the Free Software Foundation, 17116491Sharti * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18116491Sharti * 19116491Sharti * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 20116491Sharti * CA 95054 USA or visit www.sun.com if you need additional information or 21116491Sharti * have any questions. 22116491Sharti * 23116491Sharti */ 24116491Sharti 25116491Sharti#include "incls/_precompiled.incl" 26116491Sharti#include "incls/_stubRoutines.cpp.incl" 27116491Sharti 28116491Sharti 29116491Sharti// Implementation of StubRoutines - for a description 30116491Sharti// of how to extend it, see the header file. 31116491Sharti 32116491Sharti// Class Variables 33116491Sharti 34116519ShartiBufferBlob* StubRoutines::_code1 = NULL; 35116519ShartiBufferBlob* StubRoutines::_code2 = NULL; 36116519Sharti 37116491Shartiaddress StubRoutines::_call_stub_return_address = NULL; 38116491Shartiaddress StubRoutines::_call_stub_entry = NULL; 39116491Sharti 40116491Shartiaddress StubRoutines::_catch_exception_entry = NULL; 41116491Shartiaddress StubRoutines::_forward_exception_entry = NULL; 42116491Shartiaddress StubRoutines::_throw_AbstractMethodError_entry = NULL; 43116491Shartiaddress StubRoutines::_throw_IncompatibleClassChangeError_entry = NULL; 44116491Shartiaddress StubRoutines::_throw_ArithmeticException_entry = NULL; 45116491Shartiaddress StubRoutines::_throw_NullPointerException_entry = NULL; 46116491Shartiaddress StubRoutines::_throw_NullPointerException_at_call_entry = NULL; 47116491Shartiaddress StubRoutines::_throw_StackOverflowError_entry = NULL; 48116491Shartiaddress StubRoutines::_handler_for_unsafe_access_entry = NULL; 49116491Shartijint StubRoutines::_verify_oop_count = 0; 50116491Shartiaddress StubRoutines::_verify_oop_subroutine_entry = NULL; 51116491Shartiaddress StubRoutines::_atomic_xchg_entry = NULL; 52116491Shartiaddress StubRoutines::_atomic_xchg_ptr_entry = NULL; 53116491Shartiaddress StubRoutines::_atomic_store_entry = NULL; 54116491Shartiaddress StubRoutines::_atomic_store_ptr_entry = NULL; 55116491Shartiaddress StubRoutines::_atomic_cmpxchg_entry = NULL; 56116491Shartiaddress StubRoutines::_atomic_cmpxchg_ptr_entry = NULL; 57116491Shartiaddress StubRoutines::_atomic_cmpxchg_long_entry = NULL; 58116491Shartiaddress StubRoutines::_atomic_add_entry = NULL; 59116491Shartiaddress StubRoutines::_atomic_add_ptr_entry = NULL; 60257176Sglebiusaddress StubRoutines::_fence_entry = NULL; 61116491Shartiaddress StubRoutines::_d2i_wrapper = NULL; 62116491Shartiaddress StubRoutines::_d2l_wrapper = NULL; 63116491Sharti 64116491Shartijint StubRoutines::_fpu_cntrl_wrd_std = 0; 65116491Shartijint StubRoutines::_fpu_cntrl_wrd_24 = 0; 66116491Shartijint StubRoutines::_fpu_cntrl_wrd_64 = 0; 67116491Shartijint StubRoutines::_fpu_cntrl_wrd_trunc = 0; 68116491Shartijint StubRoutines::_mxcsr_std = 0; 69116491Shartijint StubRoutines::_fpu_subnormal_bias1[3] = { 0, 0, 0 }; 70116491Shartijint StubRoutines::_fpu_subnormal_bias2[3] = { 0, 0, 0 }; 71119280Simp 72119280Simp// Compiled code entry points default values 73116491Sharti// The dafault functions don't have separate disjoint versions. 74116491Shartiaddress StubRoutines::_jbyte_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jbyte_copy); 75116491Shartiaddress StubRoutines::_jshort_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jshort_copy); 76116491Shartiaddress StubRoutines::_jint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jint_copy); 77116491Shartiaddress StubRoutines::_jlong_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jlong_copy); 78116491Shartiaddress StubRoutines::_oop_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::oop_copy); 79116491Shartiaddress StubRoutines::_jbyte_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jbyte_copy); 80116491Shartiaddress StubRoutines::_jshort_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jshort_copy); 81116491Shartiaddress StubRoutines::_jint_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jint_copy); 82116491Shartiaddress StubRoutines::_jlong_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jlong_copy); 83116491Shartiaddress StubRoutines::_oop_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::oop_copy); 84116491Sharti 85116491Shartiaddress StubRoutines::_arrayof_jbyte_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jbyte_copy); 86116491Shartiaddress StubRoutines::_arrayof_jshort_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jshort_copy); 87116491Shartiaddress StubRoutines::_arrayof_jint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jint_copy); 88116491Shartiaddress StubRoutines::_arrayof_jlong_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jlong_copy); 89116491Shartiaddress StubRoutines::_arrayof_oop_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_oop_copy); 90116491Shartiaddress StubRoutines::_arrayof_jbyte_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jbyte_copy); 91116491Shartiaddress StubRoutines::_arrayof_jshort_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jshort_copy); 92116491Shartiaddress StubRoutines::_arrayof_jint_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jint_copy); 93116491Shartiaddress StubRoutines::_arrayof_jlong_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jlong_copy); 94116491Shartiaddress StubRoutines::_arrayof_oop_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_oop_copy); 95116491Sharti 96116491Shartiaddress StubRoutines::_checkcast_arraycopy = NULL; 97116491Shartiaddress StubRoutines::_unsafe_arraycopy = NULL; 98116491Shartiaddress StubRoutines::_generic_arraycopy = NULL; 99116491Sharti 100116491Shartidouble (* StubRoutines::_intrinsic_log )(double) = NULL; 101116491Shartidouble (* StubRoutines::_intrinsic_log10 )(double) = NULL; 102116491Shartidouble (* StubRoutines::_intrinsic_exp )(double) = NULL; 103116491Shartidouble (* StubRoutines::_intrinsic_pow )(double, double) = NULL; 104116491Shartidouble (* StubRoutines::_intrinsic_sin )(double) = NULL; 105116491Shartidouble (* StubRoutines::_intrinsic_cos )(double) = NULL; 106116491Shartidouble (* StubRoutines::_intrinsic_tan )(double) = NULL; 107116491Sharti 108116491Sharti// Initialization 109116491Sharti// 110116491Sharti// Note: to break cycle with universe initialization, stubs are generated in two phases. 111116491Sharti// The first one generates stubs needed during universe init (e.g., _handle_must_compile_first_entry). 112116491Sharti// The second phase includes all other stubs (which may depend on universe being initialized.) 113116491Sharti 114116491Shartiextern void StubGenerator_generate(CodeBuffer* code, bool all); // only interface to generators 115116491Sharti 116116491Shartivoid StubRoutines::initialize1() { 117116491Sharti if (_code1 == NULL) { 118116491Sharti ResourceMark rm; 119116491Sharti TraceTime timer("StubRoutines generation 1", TraceStartupTime); 120148887Srwatson _code1 = BufferBlob::create("StubRoutines (1)", code_size1); 121116491Sharti if (_code1 == NULL) { 122116491Sharti vm_exit_out_of_memory(code_size1, 123116491Sharti "CodeCache: no room for StubRoutines (1)"); 124116491Sharti } 125116491Sharti CodeBuffer buffer(_code1->instructions_begin(), _code1->instructions_size()); 126116491Sharti StubGenerator_generate(&buffer, false); 127116491Sharti } 128116491Sharti} 129116491Sharti 130116491Sharti 131116491Sharti#ifdef ASSERT 132116491Shartitypedef void (*arraycopy_fn)(address src, address dst, int count); 133116491Sharti 134116491Sharti// simple tests of generated arraycopy functions 135116491Shartistatic void test_arraycopy_func(address func, int alignment) { 136116491Sharti int v = 0xcc; 137116491Sharti int v2 = 0x11; 138116491Sharti jlong lbuffer[2]; 139116491Sharti jlong lbuffer2[2]; 140116491Sharti address buffer = (address) lbuffer; 141116491Sharti address buffer2 = (address) lbuffer2; 142116491Sharti unsigned int i; 143116491Sharti for (i = 0; i < sizeof(lbuffer); i++) { 144116491Sharti buffer[i] = v; buffer2[i] = v2; 145116491Sharti } 146116491Sharti // do an aligned copy 147116491Sharti ((arraycopy_fn)func)(buffer, buffer2, 0); 148116491Sharti for (i = 0; i < sizeof(lbuffer); i++) { 149116491Sharti assert(buffer[i] == v && buffer2[i] == v2, "shouldn't have copied anything"); 150116491Sharti } 151116491Sharti // adjust destination alignment 152116491Sharti ((arraycopy_fn)func)(buffer, buffer2 + alignment, 0); 153116491Sharti for (i = 0; i < sizeof(lbuffer); i++) { 154116491Sharti assert(buffer[i] == v && buffer2[i] == v2, "shouldn't have copied anything"); 155116491Sharti } 156116491Sharti // adjust source alignment 157116491Sharti ((arraycopy_fn)func)(buffer + alignment, buffer2, 0); 158116491Sharti for (i = 0; i < sizeof(lbuffer); i++) { 159116491Sharti assert(buffer[i] == v && buffer2[i] == v2, "shouldn't have copied anything"); 160116491Sharti } 161116491Sharti} 162116491Sharti#endif 163118598Sharti 164116491Sharti 165116491Shartivoid StubRoutines::initialize2() { 166116491Sharti if (_code2 == NULL) { 167116491Sharti ResourceMark rm; 168116491Sharti TraceTime timer("StubRoutines generation 2", TraceStartupTime); 169116491Sharti _code2 = BufferBlob::create("StubRoutines (2)", code_size2); 170116491Sharti if (_code2 == NULL) { 171116491Sharti vm_exit_out_of_memory(code_size2, 172116491Sharti "CodeCache: no room for StubRoutines (2)"); 173116491Sharti } 174116491Sharti CodeBuffer buffer(_code2->instructions_begin(), _code2->instructions_size()); 175116491Sharti StubGenerator_generate(&buffer, true); 176118598Sharti } 177118598Sharti 178118598Sharti#ifdef ASSERT 179118598Sharti 180118598Sharti#define TEST_ARRAYCOPY(type) \ 181118598Sharti test_arraycopy_func( type##_arraycopy(), sizeof(type)); \ 182118598Sharti test_arraycopy_func( type##_disjoint_arraycopy(), sizeof(type)); \ 183118598Sharti test_arraycopy_func(arrayof_##type##_arraycopy(), sizeof(HeapWord)); \ 184118598Sharti test_arraycopy_func(arrayof_##type##_disjoint_arraycopy(), sizeof(HeapWord)) 185118598Sharti 186118598Sharti // Make sure all the arraycopy stubs properly handle zeros 187118598Sharti TEST_ARRAYCOPY(jbyte); 188118598Sharti TEST_ARRAYCOPY(jshort); 189118598Sharti TEST_ARRAYCOPY(jint); 190118598Sharti TEST_ARRAYCOPY(jlong); 191118598Sharti 192147256Sbrooks#undef TEST_ARRAYCOPY 193118598Sharti 194118598Sharti#endif 195118598Sharti} 196116491Sharti 197116491Sharti 198116491Shartivoid stubRoutines_init1() { StubRoutines::initialize1(); } 199116491Shartivoid stubRoutines_init2() { StubRoutines::initialize2(); } 200116491Sharti 201116491Sharti// 202116491Sharti// Default versions of arraycopy functions 203116491Sharti// 204116491Sharti 205116491Shartistatic void gen_arraycopy_barrier_pre(oop* dest, size_t count) { 206116491Sharti assert(count != 0, "count should be non-zero"); 207147256Sbrooks assert(count <= (size_t)max_intx, "count too large"); 208116491Sharti BarrierSet* bs = Universe::heap()->barrier_set(); 209116491Sharti assert(bs->has_write_ref_array_pre_opt(), "Must have pre-barrier opt"); 210116491Sharti bs->write_ref_array_pre(dest, (int)count); 211116491Sharti} 212116491Sharti 213116491Shartistatic void gen_arraycopy_barrier(oop* dest, size_t count) { 214116491Sharti assert(count != 0, "count should be non-zero"); 215116491Sharti BarrierSet* bs = Universe::heap()->barrier_set(); 216116491Sharti assert(bs->has_write_ref_array_opt(), "Barrier set must have ref array opt"); 217116491Sharti bs->write_ref_array((HeapWord*)dest, count); 218116491Sharti} 219116491Sharti 220116491ShartiJRT_LEAF(void, StubRoutines::jbyte_copy(jbyte* src, jbyte* dest, size_t count)) 221116491Sharti#ifndef PRODUCT 222116491Sharti SharedRuntime::_jbyte_array_copy_ctr++; // Slow-path byte array copy 223116491Sharti#endif // !PRODUCT 224116491Sharti assert(count != 0, "count should be non-zero"); 225116491Sharti Copy::conjoint_bytes_atomic(src, dest, count); 226116491ShartiJRT_END 227116491Sharti 228116491ShartiJRT_LEAF(void, StubRoutines::jshort_copy(jshort* src, jshort* dest, size_t count)) 229116491Sharti#ifndef PRODUCT 230116491Sharti SharedRuntime::_jshort_array_copy_ctr++; // Slow-path short/char array copy 231116491Sharti#endif // !PRODUCT 232116491Sharti assert(count != 0, "count should be non-zero"); 233116491Sharti Copy::conjoint_jshorts_atomic(src, dest, count); 234148887SrwatsonJRT_END 235116491Sharti 236116491ShartiJRT_LEAF(void, StubRoutines::jint_copy(jint* src, jint* dest, size_t count)) 237116491Sharti#ifndef PRODUCT 238116491Sharti SharedRuntime::_jint_array_copy_ctr++; // Slow-path int/float array copy 239116491Sharti#endif // !PRODUCT 240116491Sharti assert(count != 0, "count should be non-zero"); 241116491Sharti Copy::conjoint_jints_atomic(src, dest, count); 242116491ShartiJRT_END 243116491Sharti 244116491ShartiJRT_LEAF(void, StubRoutines::jlong_copy(jlong* src, jlong* dest, size_t count)) 245116491Sharti#ifndef PRODUCT 246116491Sharti SharedRuntime::_jlong_array_copy_ctr++; // Slow-path long/double array copy 247116491Sharti#endif // !PRODUCT 248116491Sharti assert(count != 0, "count should be non-zero"); 249118540Sharti Copy::conjoint_jlongs_atomic(src, dest, count); 250116491ShartiJRT_END 251116491Sharti 252148887SrwatsonJRT_LEAF(void, StubRoutines::oop_copy(oop* src, oop* dest, size_t count)) 253116491Sharti#ifndef PRODUCT 254116491Sharti SharedRuntime::_oop_array_copy_ctr++; // Slow-path oop array copy 255116491Sharti#endif // !PRODUCT 256148887Srwatson assert(count != 0, "count should be non-zero"); 257116491Sharti gen_arraycopy_barrier_pre(dest, count); 258116491Sharti Copy::conjoint_oops_atomic(src, dest, count); 259116491Sharti gen_arraycopy_barrier(dest, count); 260116491ShartiJRT_END 261116491Sharti 262116491ShartiJRT_LEAF(void, StubRoutines::arrayof_jbyte_copy(HeapWord* src, HeapWord* dest, size_t count)) 263116491Sharti#ifndef PRODUCT 264116491Sharti SharedRuntime::_jbyte_array_copy_ctr++; // Slow-path byte array copy 265116491Sharti#endif // !PRODUCT 266116491Sharti assert(count != 0, "count should be non-zero"); 267116491Sharti Copy::arrayof_conjoint_bytes(src, dest, count); 268116491ShartiJRT_END 269116491Sharti 270116491ShartiJRT_LEAF(void, StubRoutines::arrayof_jshort_copy(HeapWord* src, HeapWord* dest, size_t count)) 271116491Sharti#ifndef PRODUCT 272116491Sharti SharedRuntime::_jshort_array_copy_ctr++; // Slow-path short/char array copy 273116491Sharti#endif // !PRODUCT 274116491Sharti assert(count != 0, "count should be non-zero"); 275116491Sharti Copy::arrayof_conjoint_jshorts(src, dest, count); 276116491ShartiJRT_END 277116491Sharti 278116491ShartiJRT_LEAF(void, StubRoutines::arrayof_jint_copy(HeapWord* src, HeapWord* dest, size_t count)) 279147721Sharti#ifndef PRODUCT 280116491Sharti SharedRuntime::_jint_array_copy_ctr++; // Slow-path int/float array copy 281116491Sharti#endif // !PRODUCT 282116491Sharti assert(count != 0, "count should be non-zero"); 283116491Sharti Copy::arrayof_conjoint_jints(src, dest, count); 284116491ShartiJRT_END 285116491Sharti 286116491ShartiJRT_LEAF(void, StubRoutines::arrayof_jlong_copy(HeapWord* src, HeapWord* dest, size_t count)) 287116491Sharti#ifndef PRODUCT 288148887Srwatson SharedRuntime::_jlong_array_copy_ctr++; // Slow-path int/float array copy 289116491Sharti#endif // !PRODUCT 290116491Sharti assert(count != 0, "count should be non-zero"); 291116491Sharti Copy::arrayof_conjoint_jlongs(src, dest, count); 292116491ShartiJRT_END 293116491Sharti 294116491ShartiJRT_LEAF(void, StubRoutines::arrayof_oop_copy(HeapWord* src, HeapWord* dest, size_t count)) 295116491Sharti#ifndef PRODUCT 296116491Sharti SharedRuntime::_oop_array_copy_ctr++; // Slow-path oop array copy 297116491Sharti#endif // !PRODUCT 298116491Sharti assert(count != 0, "count should be non-zero"); 299116491Sharti gen_arraycopy_barrier_pre((oop *) dest, count); 300116491Sharti Copy::arrayof_conjoint_oops(src, dest, count); 301116491Sharti gen_arraycopy_barrier((oop *) dest, count); 302116491ShartiJRT_END 303116491Sharti