       1 /*
       2  * Copyright (c) 1997, 2014, 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 "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
      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;
      53 address StubRoutines::_throw_IncompatibleClassChangeError_entry = NULL;
      54 address StubRoutines::_throw_NullPointerException_at_call_entry = NULL;
      55 address StubRoutines::_throw_StackOverflowError_entry           = NULL;
      56 address StubRoutines::_handler_for_unsafe_access_entry          = NULL;
      57 jint    StubRoutines::_verify_oop_count                         = 0;
      58 address StubRoutines::_verify_oop_subroutine_entry              = NULL;
      59 address StubRoutines::_atomic_xchg_entry                        = NULL;
      60 address StubRoutines::_atomic_xchg_ptr_entry                    = NULL;
      61 address StubRoutines::_atomic_store_entry                       = NULL;
      62 address StubRoutines::_atomic_store_ptr_entry                   = NULL;
      63 address StubRoutines::_atomic_cmpxchg_entry                     = NULL;
      64 address StubRoutines::_atomic_cmpxchg_ptr_entry                 = NULL;
      65 address StubRoutines::_atomic_cmpxchg_byte_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
      82 // The default functions don't have separate disjoint versions.
      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);
      88 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::_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);
      94 address StubRoutines::_oop_disjoint_arraycopy_uninit     = CAST_FROM_FN_PTR(address, StubRoutines::oop_copy_uninit);
      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);
     101 address StubRoutines::_arrayof_oop_arraycopy_uninit      = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_oop_copy_uninit);
     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);
     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
     109 address StubRoutines::_zero_aligned_words = CAST_FROM_FN_PTR(address, Copy::zero_to_words);
     110
     111 address StubRoutines::_checkcast_arraycopy               = NULL;
     112 address StubRoutines::_checkcast_arraycopy_uninit        = NULL;
     113 address StubRoutines::_unsafe_arraycopy                  = NULL;
     114 address StubRoutines::_generic_arraycopy                 = NULL;
     115
     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 address StubRoutines::_aescrypt_encryptBlock               = NULL;
     125 address StubRoutines::_aescrypt_decryptBlock               = NULL;
     126 address StubRoutines::_cipherBlockChaining_encryptAESCrypt = NULL;
     127 address StubRoutines::_cipherBlockChaining_decryptAESCrypt = NULL;
     128
     129 address StubRoutines::_sha1_implCompress     = NULL;
     130 address StubRoutines::_sha1_implCompressMB   = NULL;
     131 address StubRoutines::_sha256_implCompress   = NULL;
     132 address StubRoutines::_sha256_implCompressMB = NULL;
     133 address StubRoutines::_sha512_implCompress   = NULL;
     134 address StubRoutines::_sha512_implCompressMB = NULL;
     135
     136 address StubRoutines::_updateBytesCRC32 = NULL;
     137 address StubRoutines::_crc_table_adr = NULL;
     138
     139 address StubRoutines::_multiplyToLen = NULL;
     140 address StubRoutines::_squareToLen = NULL;
     141 address StubRoutines::_mulAdd = NULL;
     142
     143 double (* StubRoutines::_intrinsic_log   )(double) = NULL;
     144 double (* StubRoutines::_intrinsic_log10 )(double) = NULL;
     145 double (* StubRoutines::_intrinsic_exp   )(double) = NULL;
     146 double (* StubRoutines::_intrinsic_pow   )(double, double) = NULL;
     147 double (* StubRoutines::_intrinsic_sin   )(double) = NULL;
     148 double (* StubRoutines::_intrinsic_cos   )(double) = NULL;
     149 double (* StubRoutines::_intrinsic_tan   )(double) = NULL;
     150
     151 address StubRoutines::_safefetch32_entry                 = NULL;
     152 address StubRoutines::_safefetch32_fault_pc              = NULL;
     153 address StubRoutines::_safefetch32_continuation_pc       = NULL;
     154 address StubRoutines::_safefetchN_entry                  = NULL;
     155 address StubRoutines::_safefetchN_fault_pc               = NULL;
     156 address StubRoutines::_safefetchN_continuation_pc        = NULL;
     157
     158 // Initialization
     159 //
     160 // Note: to break cycle with universe initialization, stubs are generated in two phases.
     161 // The first one generates stubs needed during universe init (e.g., _handle_must_compile_first_entry).
     162 // The second phase includes all other stubs (which may depend on universe being initialized.)
     163
     164 extern void StubGenerator_generate(CodeBuffer* code, bool all); // only interface to generators
     165
     166 void StubRoutines::initialize1() {
     167   if (_code1 == NULL) {
     168     ResourceMark rm;
     169     TraceTime timer("StubRoutines generation 1", TraceStartupTime);
     170     _code1 = BufferBlob::create("StubRoutines (1)", code_size1);
     171     if (_code1 == NULL) {
     172       vm_exit_out_of_memory(code_size1, OOM_MALLOC_ERROR, "CodeCache: no room for StubRoutines (1)");
     173     }
     174     CodeBuffer buffer(_code1);
     175     StubGenerator_generate(&buffer, false);
     176   }
     177 }
     178
     179
     180 #ifdef ASSERT
     181 typedef void (*arraycopy_fn)(address src, address dst, int count);
     182
     183 // simple tests of generated arraycopy functions
     184 static void test_arraycopy_func(address func, int alignment) {
     185   int v = 0xcc;
     186   int v2 = 0x11;
     187   jlong lbuffer[8];
     188   jlong lbuffer2[8];
     189   address fbuffer  = (address) lbuffer;
     190   address fbuffer2 = (address) lbuffer2;
     191   unsigned int i;
     192   for (i = 0; i < sizeof(lbuffer); i++) {
     193     fbuffer[i] = v; fbuffer2[i] = v2;
     194   }
     195   // C++ does not guarantee jlong[] array alignment to 8 bytes.
     196   // Use middle of array to check that memory before it is not modified.
     197   address buffer  = (address) round_to((intptr_t)&lbuffer[4], BytesPerLong);
     198   address buffer2 = (address) round_to((intptr_t)&lbuffer2[4], BytesPerLong);
     199   // do an aligned copy
     200   ((arraycopy_fn)func)(buffer, buffer2, 0);
     201   for (i = 0; i < sizeof(lbuffer); i++) {
     202     assert(fbuffer[i] == v && fbuffer2[i] == v2, "shouldn't have copied anything");
     203   }
     204   // adjust destination alignment
     205   ((arraycopy_fn)func)(buffer, buffer2 + alignment, 0);
     206   for (i = 0; i < sizeof(lbuffer); i++) {
     207     assert(fbuffer[i] == v && fbuffer2[i] == v2, "shouldn't have copied anything");
     208   }
     209   // adjust source alignment
     210   ((arraycopy_fn)func)(buffer + alignment, buffer2, 0);
     211   for (i = 0; i < sizeof(lbuffer); i++) {
     212     assert(fbuffer[i] == v && fbuffer2[i] == v2, "shouldn't have copied anything");
     213   }
     214 }
     215 #endif
     216
     217
     218 void StubRoutines::initialize2() {
     219   if (_code2 == NULL) {
     220     ResourceMark rm;
     221     TraceTime timer("StubRoutines generation 2", TraceStartupTime);
     222     _code2 = BufferBlob::create("StubRoutines (2)", code_size2);
     223     if (_code2 == NULL) {
     224       vm_exit_out_of_memory(code_size2, OOM_MALLOC_ERROR, "CodeCache: no room for StubRoutines (2)");
     225     }
     226     CodeBuffer buffer(_code2);
     227     StubGenerator_generate(&buffer, true);
     228   }
     229
     230 #ifdef ASSERT
     231
     232 #define TEST_ARRAYCOPY(type)                                                    \
     233   test_arraycopy_func(          type##_arraycopy(),          sizeof(type));     \
     234   test_arraycopy_func(          type##_disjoint_arraycopy(), sizeof(type));     \
     235   test_arraycopy_func(arrayof_##type##_arraycopy(),          sizeof(HeapWord)); \
     236   test_arraycopy_func(arrayof_##type##_disjoint_arraycopy(), sizeof(HeapWord))
     237
     238   // Make sure all the arraycopy stubs properly handle zero count
     239   TEST_ARRAYCOPY(jbyte);
     240   TEST_ARRAYCOPY(jshort);
     241   TEST_ARRAYCOPY(jint);
     242   TEST_ARRAYCOPY(jlong);
     243
     244 #undef TEST_ARRAYCOPY
     245
     246 #define TEST_FILL(type)                                                                      \
     247   if (_##type##_fill != NULL) {                                                              \
     248     union {                                                                                  \
     249       double d;                                                                              \
     250       type body[96];                                                                         \
     251     } s;                                                                                     \
     252                                                                                              \
     253     int v = 32;                                                                              \
     254     for (int offset = -2; offset <= 2; offset++) {                                           \
     255       for (int i = 0; i < 96; i++) {                                                         \
     256         s.body[i] = 1;                                                                       \
     257       }                                                                                      \
     258       type* start = s.body + 8 + offset;                                                     \
     259       for (int aligned = 0; aligned < 2; aligned++) {                                        \
     260         if (aligned) {                                                                       \
     261           if (((intptr_t)start) % HeapWordSize == 0) {                                       \
     262             ((void (*)(type*, int, int))StubRoutines::_arrayof_##type##_fill)(start, v, 80); \
     263           } else {                                                                           \
     264             continue;                                                                        \
     265           }                                                                                  \
     266         } else {                                                                             \
     267           ((void (*)(type*, int, int))StubRoutines::_##type##_fill)(start, v, 80);           \
     268         }                                                                                    \
     269         for (int i = 0; i < 96; i++) {                                                       \
     270           if (i < (8 + offset) || i >= (88 + offset)) {                                      \
     271             assert(s.body[i] == 1, "what?");                                                 \
     272           } else {                                                                           \
     273             assert(s.body[i] == 32, "what?");                                                \
     274           }                                                                                  \
     275         }                                                                                    \
     276       }                                                                                      \
     277     }                                                                                        \
     278   }                                                                                          \
     279
     280   TEST_FILL(jbyte);
     281   TEST_FILL(jshort);
     282   TEST_FILL(jint);
     283
     284 #undef TEST_FILL
     285
     286 #define TEST_COPYRTN(type) \
     287   test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::conjoint_##type##s_atomic),  sizeof(type)); \
     288   test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::arrayof_conjoint_##type##s), (int)MAX2(sizeof(HeapWord), sizeof(type)))
     289
     290   // Make sure all the copy runtime routines properly handle zero count
     291   TEST_COPYRTN(jbyte);
     292   TEST_COPYRTN(jshort);
     293   TEST_COPYRTN(jint);
     294   TEST_COPYRTN(jlong);
     295
     296 #undef TEST_COPYRTN
     297
     298   test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::conjoint_words), sizeof(HeapWord));
     299   test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::disjoint_words), sizeof(HeapWord));
     300   test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::disjoint_words_atomic), sizeof(HeapWord));
     301   // Aligned to BytesPerLong
     302   test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::aligned_conjoint_words), sizeof(jlong));
     303   test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::aligned_disjoint_words), sizeof(jlong));
     304
     305 #endif
     306 }
     307
     308
     309 void stubRoutines_init1() { StubRoutines::initialize1(); }
     310 void stubRoutines_init2() { StubRoutines::initialize2(); }
     311
     312 //
     313 // Default versions of arraycopy functions
     314 //
     315
     316 static void gen_arraycopy_barrier_pre(oop* dest, size_t count, bool dest_uninitialized) {
     317     assert(count != 0, "count should be non-zero");
     318     assert(count <= (size_t)max_intx, "count too large");
     319     BarrierSet* bs = Universe::heap()->barrier_set();
     320     assert(bs->has_write_ref_array_pre_opt(), "Must have pre-barrier opt");
     321     bs->write_ref_array_pre(dest, (int)count, dest_uninitialized);
     322 }
     323
     324 static void gen_arraycopy_barrier(oop* dest, size_t count) {
     325     assert(count != 0, "count should be non-zero");
     326     BarrierSet* bs = Universe::heap()->barrier_set();
     327     assert(bs->has_write_ref_array_opt(), "Barrier set must have ref array opt");
     328     bs->write_ref_array((HeapWord*)dest, count);
     329 }
     330
     331 JRT_LEAF(void, StubRoutines::jbyte_copy(jbyte* src, jbyte* dest, size_t count))
     332 #ifndef PRODUCT
     333   SharedRuntime::_jbyte_array_copy_ctr++;      // Slow-path byte array copy
     334 #endif // !PRODUCT
     335   Copy::conjoint_jbytes_atomic(src, dest, count);
     336 JRT_END
     337
     338 JRT_LEAF(void, StubRoutines::jshort_copy(jshort* src, jshort* dest, size_t count))
     339 #ifndef PRODUCT
     340   SharedRuntime::_jshort_array_copy_ctr++;     // Slow-path short/char array copy
     341 #endif // !PRODUCT
     342   Copy::conjoint_jshorts_atomic(src, dest, count);
     343 JRT_END
     344
     345 JRT_LEAF(void, StubRoutines::jint_copy(jint* src, jint* dest, size_t count))
     346 #ifndef PRODUCT
     347   SharedRuntime::_jint_array_copy_ctr++;       // Slow-path int/float array copy
     348 #endif // !PRODUCT
     349   Copy::conjoint_jints_atomic(src, dest, count);
     350 JRT_END
     351
     352 JRT_LEAF(void, StubRoutines::jlong_copy(jlong* src, jlong* dest, size_t count))
     353 #ifndef PRODUCT
     354   SharedRuntime::_jlong_array_copy_ctr++;      // Slow-path long/double array copy
     355 #endif // !PRODUCT
     356   Copy::conjoint_jlongs_atomic(src, dest, count);
     357 JRT_END
     358
     359 JRT_LEAF(void, StubRoutines::oop_copy(oop* src, oop* dest, size_t count))
     360 #ifndef PRODUCT
     361   SharedRuntime::_oop_array_copy_ctr++;        // Slow-path oop array copy
     362 #endif // !PRODUCT
     363   assert(count != 0, "count should be non-zero");
     364   gen_arraycopy_barrier_pre(dest, count, /*dest_uninitialized*/false);
     365   Copy::conjoint_oops_atomic(src, dest, count);
     366   gen_arraycopy_barrier(dest, count);
     367 JRT_END
     368
     369 JRT_LEAF(void, StubRoutines::oop_copy_uninit(oop* src, oop* dest, size_t count))
     370 #ifndef PRODUCT
     371   SharedRuntime::_oop_array_copy_ctr++;        // Slow-path oop array copy
     372 #endif // !PRODUCT
     373   assert(count != 0, "count should be non-zero");
     374   gen_arraycopy_barrier_pre(dest, count, /*dest_uninitialized*/true);
     375   Copy::conjoint_oops_atomic(src, dest, count);
     376   gen_arraycopy_barrier(dest, count);
     377 JRT_END
     378
     379 JRT_LEAF(void, StubRoutines::arrayof_jbyte_copy(HeapWord* src, HeapWord* dest, size_t count))
     380 #ifndef PRODUCT
     381   SharedRuntime::_jbyte_array_copy_ctr++;      // Slow-path byte array copy
     382 #endif // !PRODUCT
     383   Copy::arrayof_conjoint_jbytes(src, dest, count);
     384 JRT_END
     385
     386 JRT_LEAF(void, StubRoutines::arrayof_jshort_copy(HeapWord* src, HeapWord* dest, size_t count))
     387 #ifndef PRODUCT
     388   SharedRuntime::_jshort_array_copy_ctr++;     // Slow-path short/char array copy
     389 #endif // !PRODUCT
     390   Copy::arrayof_conjoint_jshorts(src, dest, count);
     391 JRT_END
     392
     393 JRT_LEAF(void, StubRoutines::arrayof_jint_copy(HeapWord* src, HeapWord* dest, size_t count))
     394 #ifndef PRODUCT
     395   SharedRuntime::_jint_array_copy_ctr++;       // Slow-path int/float array copy
     396 #endif // !PRODUCT
     397   Copy::arrayof_conjoint_jints(src, dest, count);
     398 JRT_END
     399
     400 JRT_LEAF(void, StubRoutines::arrayof_jlong_copy(HeapWord* src, HeapWord* dest, size_t count))
     401 #ifndef PRODUCT
     402   SharedRuntime::_jlong_array_copy_ctr++;       // Slow-path int/float array copy
     403 #endif // !PRODUCT
     404   Copy::arrayof_conjoint_jlongs(src, dest, count);
     405 JRT_END
     406
     407 JRT_LEAF(void, StubRoutines::arrayof_oop_copy(HeapWord* src, HeapWord* dest, size_t count))
     408 #ifndef PRODUCT
     409   SharedRuntime::_oop_array_copy_ctr++;        // Slow-path oop array copy
     410 #endif // !PRODUCT
     411   assert(count != 0, "count should be non-zero");
     412   gen_arraycopy_barrier_pre((oop *) dest, count, /*dest_uninitialized*/false);
     413   Copy::arrayof_conjoint_oops(src, dest, count);
     414   gen_arraycopy_barrier((oop *) dest, count);
     415 JRT_END
     416
     417 JRT_LEAF(void, StubRoutines::arrayof_oop_copy_uninit(HeapWord* src, HeapWord* dest, size_t count))
     418 #ifndef PRODUCT
     419   SharedRuntime::_oop_array_copy_ctr++;        // Slow-path oop array copy
     420 #endif // !PRODUCT
     421   assert(count != 0, "count should be non-zero");
     422   gen_arraycopy_barrier_pre((oop *) dest, count, /*dest_uninitialized*/true);
     423   Copy::arrayof_conjoint_oops(src, dest, count);
     424   gen_arraycopy_barrier((oop *) dest, count);
     425 JRT_END
     426
     427 address StubRoutines::select_fill_function(BasicType t, bool aligned, const char* &name) {
     428 #define RETURN_STUB(xxx_fill) { \
     429   name = #xxx_fill; \
     430   return StubRoutines::xxx_fill(); }
     431
     432   switch (t) {
     433   case T_BYTE:
     434   case T_BOOLEAN:
     435     if (!aligned) RETURN_STUB(jbyte_fill);
     436     RETURN_STUB(arrayof_jbyte_fill);
     437   case T_CHAR:
     438   case T_SHORT:
     439     if (!aligned) RETURN_STUB(jshort_fill);
     440     RETURN_STUB(arrayof_jshort_fill);
     441   case T_INT:
     442   case T_FLOAT:
     443     if (!aligned) RETURN_STUB(jint_fill);
     444     RETURN_STUB(arrayof_jint_fill);
     445   case T_DOUBLE:
     446   case T_LONG:
     447   case T_ARRAY:
     448   case T_OBJECT:
     449   case T_NARROWOOP:
     450   case T_NARROWKLASS:
     451   case T_ADDRESS:
     452     // Currently unsupported
     453     return NULL;
     454
     455   default:
     456     ShouldNotReachHere();
     457     return NULL;
     458   }
     459
     460 #undef RETURN_STUB
     461 }
     462
     463 // constants for computing the copy function
     464 enum {
     465   COPYFUNC_UNALIGNED = 0,
     466   COPYFUNC_ALIGNED = 1,                 // src, dest aligned to HeapWordSize
     467   COPYFUNC_CONJOINT = 0,
     468   COPYFUNC_DISJOINT = 2                 // src != dest, or transfer can descend
     469 };
     470
     471 // Note:  The condition "disjoint" applies also for overlapping copies
     472 // where an descending copy is permitted (i.e., dest_offset <= src_offset).
     473 address
     474 StubRoutines::select_arraycopy_function(BasicType t, bool aligned, bool disjoint, const char* &name, bool dest_uninitialized) {
     475   int selector =
     476     (aligned  ? COPYFUNC_ALIGNED  : COPYFUNC_UNALIGNED) +
     477     (disjoint ? COPYFUNC_DISJOINT : COPYFUNC_CONJOINT);
     478
     479 #define RETURN_STUB(xxx_arraycopy) { \
     480   name = #xxx_arraycopy; \
     481   return StubRoutines::xxx_arraycopy(); }
     482
     483 #define RETURN_STUB_PARM(xxx_arraycopy, parm) {           \
     484   name = #xxx_arraycopy; \
     485   return StubRoutines::xxx_arraycopy(parm); }
     486
     487   switch (t) {
     488   case T_BYTE:
     489   case T_BOOLEAN:
     490     switch (selector) {
     491     case COPYFUNC_CONJOINT | COPYFUNC_UNALIGNED:  RETURN_STUB(jbyte_arraycopy);
     492     case COPYFUNC_CONJOINT | COPYFUNC_ALIGNED:    RETURN_STUB(arrayof_jbyte_arraycopy);
     493     case COPYFUNC_DISJOINT | COPYFUNC_UNALIGNED:  RETURN_STUB(jbyte_disjoint_arraycopy);
     494     case COPYFUNC_DISJOINT | COPYFUNC_ALIGNED:    RETURN_STUB(arrayof_jbyte_disjoint_arraycopy);
     495     }
     496   case T_CHAR:
     497   case T_SHORT:
     498     switch (selector) {
     499     case COPYFUNC_CONJOINT | COPYFUNC_UNALIGNED:  RETURN_STUB(jshort_arraycopy);
     500     case COPYFUNC_CONJOINT | COPYFUNC_ALIGNED:    RETURN_STUB(arrayof_jshort_arraycopy);
     501     case COPYFUNC_DISJOINT | COPYFUNC_UNALIGNED:  RETURN_STUB(jshort_disjoint_arraycopy);
     502     case COPYFUNC_DISJOINT | COPYFUNC_ALIGNED:    RETURN_STUB(arrayof_jshort_disjoint_arraycopy);
     503     }
     504   case T_INT:
     505   case T_FLOAT:
     506     switch (selector) {
     507     case COPYFUNC_CONJOINT | COPYFUNC_UNALIGNED:  RETURN_STUB(jint_arraycopy);
     508     case COPYFUNC_CONJOINT | COPYFUNC_ALIGNED:    RETURN_STUB(arrayof_jint_arraycopy);
     509     case COPYFUNC_DISJOINT | COPYFUNC_UNALIGNED:  RETURN_STUB(jint_disjoint_arraycopy);
     510     case COPYFUNC_DISJOINT | COPYFUNC_ALIGNED:    RETURN_STUB(arrayof_jint_disjoint_arraycopy);
     511     }
     512   case T_DOUBLE:
     513   case T_LONG:
     514     switch (selector) {
     515     case COPYFUNC_CONJOINT | COPYFUNC_UNALIGNED:  RETURN_STUB(jlong_arraycopy);
     516     case COPYFUNC_CONJOINT | COPYFUNC_ALIGNED:    RETURN_STUB(arrayof_jlong_arraycopy);
     517     case COPYFUNC_DISJOINT | COPYFUNC_UNALIGNED:  RETURN_STUB(jlong_disjoint_arraycopy);
     518     case COPYFUNC_DISJOINT | COPYFUNC_ALIGNED:    RETURN_STUB(arrayof_jlong_disjoint_arraycopy);
     519     }
     520   case T_ARRAY:
     521   case T_OBJECT:
     522     switch (selector) {
     523     case COPYFUNC_CONJOINT | COPYFUNC_UNALIGNED:  RETURN_STUB_PARM(oop_arraycopy, dest_uninitialized);
     524     case COPYFUNC_CONJOINT | COPYFUNC_ALIGNED:    RETURN_STUB_PARM(arrayof_oop_arraycopy, dest_uninitialized);
     525     case COPYFUNC_DISJOINT | COPYFUNC_UNALIGNED:  RETURN_STUB_PARM(oop_disjoint_arraycopy, dest_uninitialized);
     526     case COPYFUNC_DISJOINT | COPYFUNC_ALIGNED:    RETURN_STUB_PARM(arrayof_oop_disjoint_arraycopy, dest_uninitialized);
     527     }
     528   default:
     529     ShouldNotReachHere();
     530     return NULL;
     531   }
     532
     533 #undef RETURN_STUB
     534 #undef RETURN_STUB_PARM
     535 }