stubRoutines.hpp 20.5 KB
Newer Older
D
duke 已提交
1
/*
2
 * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
D
duke 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
19 20 21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
D
duke 已提交
22 23 24
 *
 */

25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
#ifndef SHARE_VM_RUNTIME_STUBROUTINES_HPP
#define SHARE_VM_RUNTIME_STUBROUTINES_HPP

#include "code/codeBlob.hpp"
#include "memory/allocation.hpp"
#include "runtime/frame.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/stubCodeGenerator.hpp"
#include "utilities/top.hpp"
#ifdef TARGET_ARCH_x86
# include "nativeInst_x86.hpp"
#endif
#ifdef TARGET_ARCH_sparc
# include "nativeInst_sparc.hpp"
#endif
#ifdef TARGET_ARCH_zero
# include "nativeInst_zero.hpp"
#endif
43 44 45 46 47 48
#ifdef TARGET_ARCH_arm
# include "nativeInst_arm.hpp"
#endif
#ifdef TARGET_ARCH_ppc
# include "nativeInst_ppc.hpp"
#endif
49

D
duke 已提交
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
// StubRoutines provides entry points to assembly routines used by
// compiled code and the run-time system. Platform-specific entry
// points are defined in the platform-specific inner class.
//
// Class scheme:
//
//    platform-independent               platform-dependent
//
//    stubRoutines.hpp  <-- included --  stubRoutines_<arch>.hpp
//           ^                                  ^
//           |                                  |
//       implements                         implements
//           |                                  |
//           |                                  |
//    stubRoutines.cpp                   stubRoutines_<arch>.cpp
//    stubRoutines_<os_family>.cpp       stubGenerator_<arch>.cpp
//    stubRoutines_<os_arch>.cpp
//
// Note 1: The important thing is a clean decoupling between stub
//         entry points (interfacing to the whole vm; i.e., 1-to-n
//         relationship) and stub generators (interfacing only to
//         the entry points implementation; i.e., 1-to-1 relationship).
//         This significantly simplifies changes in the generator
//         structure since the rest of the vm is not affected.
//
// Note 2: stubGenerator_<arch>.cpp contains a minimal portion of
//         machine-independent code; namely the generator calls of
//         the generator functions that are used platform-independently.
//         However, it comes with the advantage of having a 1-file
//         implementation of the generator. It should be fairly easy
//         to change, should it become a problem later.
//
// Scheme for adding a new entry point:
//
// 1. determine if it's a platform-dependent or independent entry point
//    a) if platform independent: make subsequent changes in the independent files
//    b) if platform   dependent: make subsequent changes in the   dependent files
// 2. add a private instance variable holding the entry point address
// 3. add a public accessor function to the instance variable
// 4. implement the corresponding generator function in the platform-dependent
//    stubGenerator_<arch>.cpp file and call the function in generate_all() of that file


class StubRoutines: AllStatic {

 public:
  enum platform_independent_constants {
    max_size_of_parameters = 256                           // max. parameter size supported by megamorphic lookups
  };

  // Dependencies
  friend class StubGenerator;
102 103 104
#if defined STUBROUTINES_MD_HPP
# include STUBROUTINES_MD_HPP
#elif defined TARGET_ARCH_MODEL_x86_32
105
# include "stubRoutines_x86_32.hpp"
106
#elif defined TARGET_ARCH_MODEL_x86_64
107
# include "stubRoutines_x86_64.hpp"
108
#elif defined TARGET_ARCH_MODEL_sparc
109
# include "stubRoutines_sparc.hpp"
110
#elif defined TARGET_ARCH_MODEL_zero
111
# include "stubRoutines_zero.hpp"
112
#elif defined TARGET_ARCH_MODEL_ppc_64
113
# include "stubRoutines_ppc_64.hpp"
114 115
#endif

D
duke 已提交
116 117 118 119 120 121 122 123
  static jint    _verify_oop_count;
  static address _verify_oop_subroutine_entry;

  static address _call_stub_return_address;                // the return PC, when returning to a call stub
  static address _call_stub_entry;
  static address _forward_exception_entry;
  static address _catch_exception_entry;
  static address _throw_AbstractMethodError_entry;
124
  static address _throw_IncompatibleClassChangeError_entry;
D
duke 已提交
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
  static address _throw_NullPointerException_at_call_entry;
  static address _throw_StackOverflowError_entry;
  static address _handler_for_unsafe_access_entry;

  static address _atomic_xchg_entry;
  static address _atomic_xchg_ptr_entry;
  static address _atomic_store_entry;
  static address _atomic_store_ptr_entry;
  static address _atomic_cmpxchg_entry;
  static address _atomic_cmpxchg_ptr_entry;
  static address _atomic_cmpxchg_long_entry;
  static address _atomic_add_entry;
  static address _atomic_add_ptr_entry;
  static address _fence_entry;
  static address _d2i_wrapper;
  static address _d2l_wrapper;

  static jint    _fpu_cntrl_wrd_std;
  static jint    _fpu_cntrl_wrd_24;
  static jint    _fpu_cntrl_wrd_64;
  static jint    _fpu_cntrl_wrd_trunc;
  static jint    _mxcsr_std;
  static jint    _fpu_subnormal_bias1[3];
  static jint    _fpu_subnormal_bias2[3];

  static BufferBlob* _code1;                               // code buffer for initial routines
  static BufferBlob* _code2;                               // code buffer for all other routines

  // Leaf routines which implement arraycopy and their addresses
  // arraycopy operands aligned on element type boundary
  static address _jbyte_arraycopy;
  static address _jshort_arraycopy;
  static address _jint_arraycopy;
  static address _jlong_arraycopy;
159
  static address _oop_arraycopy, _oop_arraycopy_uninit;
D
duke 已提交
160 161 162 163
  static address _jbyte_disjoint_arraycopy;
  static address _jshort_disjoint_arraycopy;
  static address _jint_disjoint_arraycopy;
  static address _jlong_disjoint_arraycopy;
164
  static address _oop_disjoint_arraycopy, _oop_disjoint_arraycopy_uninit;
D
duke 已提交
165 166 167 168 169 170 171 172 173

  // arraycopy operands aligned on zero'th element boundary
  // These are identical to the ones aligned aligned on an
  // element type boundary, except that they assume that both
  // source and destination are HeapWord aligned.
  static address _arrayof_jbyte_arraycopy;
  static address _arrayof_jshort_arraycopy;
  static address _arrayof_jint_arraycopy;
  static address _arrayof_jlong_arraycopy;
174
  static address _arrayof_oop_arraycopy, _arrayof_oop_arraycopy_uninit;
D
duke 已提交
175 176 177 178
  static address _arrayof_jbyte_disjoint_arraycopy;
  static address _arrayof_jshort_disjoint_arraycopy;
  static address _arrayof_jint_disjoint_arraycopy;
  static address _arrayof_jlong_disjoint_arraycopy;
179
  static address _arrayof_oop_disjoint_arraycopy, _arrayof_oop_disjoint_arraycopy_uninit;
D
duke 已提交
180 181

  // these are recommended but optional:
182
  static address _checkcast_arraycopy, _checkcast_arraycopy_uninit;
D
duke 已提交
183 184 185
  static address _unsafe_arraycopy;
  static address _generic_arraycopy;

N
never 已提交
186 187 188 189 190 191 192
  static address _jbyte_fill;
  static address _jshort_fill;
  static address _jint_fill;
  static address _arrayof_jbyte_fill;
  static address _arrayof_jshort_fill;
  static address _arrayof_jint_fill;

K
kvn 已提交
193 194 195
  // zero heap space aligned to jlong (8 bytes)
  static address _zero_aligned_words;

196 197 198 199 200
  static address _aescrypt_encryptBlock;
  static address _aescrypt_decryptBlock;
  static address _cipherBlockChaining_encryptAESCrypt;
  static address _cipherBlockChaining_decryptAESCrypt;

201 202 203 204 205 206 207
  static address _sha1_implCompress;
  static address _sha1_implCompressMB;
  static address _sha256_implCompress;
  static address _sha256_implCompressMB;
  static address _sha512_implCompress;
  static address _sha512_implCompressMB;

208 209 210
  static address _updateBytesCRC32;
  static address _crc_table_adr;

211
  static address _multiplyToLen;
212 213
  static address _squareToLen;
  static address _mulAdd;
214

215 216 217 218 219 220 221 222 223 224 225 226 227 228
  // These are versions of the java.lang.Math methods which perform
  // the same operations as the intrinsic version.  They are used for
  // constant folding in the compiler to ensure equivalence.  If the
  // intrinsic version returns the same result as the strict version
  // then they can be set to the appropriate function from
  // SharedRuntime.
  static double (*_intrinsic_log)(double);
  static double (*_intrinsic_log10)(double);
  static double (*_intrinsic_exp)(double);
  static double (*_intrinsic_pow)(double, double);
  static double (*_intrinsic_sin)(double);
  static double (*_intrinsic_cos)(double);
  static double (*_intrinsic_tan)(double);

229 230 231 232 233 234 235 236
  // Safefetch stubs.
  static address _safefetch32_entry;
  static address _safefetch32_fault_pc;
  static address _safefetch32_continuation_pc;
  static address _safefetchN_entry;
  static address _safefetchN_fault_pc;
  static address _safefetchN_continuation_pc;

D
duke 已提交
237 238 239 240 241
 public:
  // Initialization/Testing
  static void    initialize1();                            // must happen before universe::genesis
  static void    initialize2();                            // must happen after  universe::genesis

S
sla 已提交
242 243
  static bool is_stub_code(address addr)                   { return contains(addr); }

D
duke 已提交
244 245 246 247 248 249
  static bool contains(address addr) {
    return
      (_code1 != NULL && _code1->blob_contains(addr)) ||
      (_code2 != NULL && _code2->blob_contains(addr)) ;
  }

250 251 252
  static CodeBlob* code1() { return _code1; }
  static CodeBlob* code2() { return _code2; }

D
duke 已提交
253 254 255 256 257 258 259 260 261 262 263 264 265
  // Debugging
  static jint    verify_oop_count()                        { return _verify_oop_count; }
  static jint*   verify_oop_count_addr()                   { return &_verify_oop_count; }
  // a subroutine for debugging the GC
  static address verify_oop_subroutine_entry_address()    { return (address)&_verify_oop_subroutine_entry; }

  static address catch_exception_entry()                   { return _catch_exception_entry; }

  // Calls to Java
  typedef void (*CallStub)(
    address   link,
    intptr_t* result,
    BasicType result_type,
266
    Method* method,
D
duke 已提交
267 268 269 270 271 272 273 274 275 276 277 278
    address   entry_point,
    intptr_t* parameters,
    int       size_of_parameters,
    TRAPS
  );

  static CallStub call_stub()                              { return CAST_TO_FN_PTR(CallStub, _call_stub_entry); }

  // Exceptions
  static address forward_exception_entry()                 { return _forward_exception_entry; }
  // Implicit exceptions
  static address throw_AbstractMethodError_entry()         { return _throw_AbstractMethodError_entry; }
279
  static address throw_IncompatibleClassChangeError_entry(){ return _throw_IncompatibleClassChangeError_entry; }
D
duke 已提交
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309
  static address throw_NullPointerException_at_call_entry(){ return _throw_NullPointerException_at_call_entry; }
  static address throw_StackOverflowError_entry()          { return _throw_StackOverflowError_entry; }

  // Exceptions during unsafe access - should throw Java exception rather
  // than crash.
  static address handler_for_unsafe_access()               { return _handler_for_unsafe_access_entry; }

  static address atomic_xchg_entry()                       { return _atomic_xchg_entry; }
  static address atomic_xchg_ptr_entry()                   { return _atomic_xchg_ptr_entry; }
  static address atomic_store_entry()                      { return _atomic_store_entry; }
  static address atomic_store_ptr_entry()                  { return _atomic_store_ptr_entry; }
  static address atomic_cmpxchg_entry()                    { return _atomic_cmpxchg_entry; }
  static address atomic_cmpxchg_ptr_entry()                { return _atomic_cmpxchg_ptr_entry; }
  static address atomic_cmpxchg_long_entry()               { return _atomic_cmpxchg_long_entry; }
  static address atomic_add_entry()                        { return _atomic_add_entry; }
  static address atomic_add_ptr_entry()                    { return _atomic_add_ptr_entry; }
  static address fence_entry()                             { return _fence_entry; }

  static address d2i_wrapper()                             { return _d2i_wrapper; }
  static address d2l_wrapper()                             { return _d2l_wrapper; }
  static jint    fpu_cntrl_wrd_std()                       { return _fpu_cntrl_wrd_std;   }
  static address addr_fpu_cntrl_wrd_std()                  { return (address)&_fpu_cntrl_wrd_std;   }
  static address addr_fpu_cntrl_wrd_24()                   { return (address)&_fpu_cntrl_wrd_24;   }
  static address addr_fpu_cntrl_wrd_64()                   { return (address)&_fpu_cntrl_wrd_64;   }
  static address addr_fpu_cntrl_wrd_trunc()                { return (address)&_fpu_cntrl_wrd_trunc; }
  static address addr_mxcsr_std()                          { return (address)&_mxcsr_std; }
  static address addr_fpu_subnormal_bias1()                { return (address)&_fpu_subnormal_bias1; }
  static address addr_fpu_subnormal_bias2()                { return (address)&_fpu_subnormal_bias2; }


310 311
  static address select_arraycopy_function(BasicType t, bool aligned, bool disjoint, const char* &name, bool dest_uninitialized);

D
duke 已提交
312 313 314 315
  static address jbyte_arraycopy()  { return _jbyte_arraycopy; }
  static address jshort_arraycopy() { return _jshort_arraycopy; }
  static address jint_arraycopy()   { return _jint_arraycopy; }
  static address jlong_arraycopy()  { return _jlong_arraycopy; }
316 317 318
  static address oop_arraycopy(bool dest_uninitialized = false) {
    return dest_uninitialized ? _oop_arraycopy_uninit : _oop_arraycopy;
  }
D
duke 已提交
319 320 321 322
  static address jbyte_disjoint_arraycopy()  { return _jbyte_disjoint_arraycopy; }
  static address jshort_disjoint_arraycopy() { return _jshort_disjoint_arraycopy; }
  static address jint_disjoint_arraycopy()   { return _jint_disjoint_arraycopy; }
  static address jlong_disjoint_arraycopy()  { return _jlong_disjoint_arraycopy; }
323 324 325
  static address oop_disjoint_arraycopy(bool dest_uninitialized = false) {
    return dest_uninitialized ?  _oop_disjoint_arraycopy_uninit : _oop_disjoint_arraycopy;
  }
D
duke 已提交
326 327 328 329 330

  static address arrayof_jbyte_arraycopy()  { return _arrayof_jbyte_arraycopy; }
  static address arrayof_jshort_arraycopy() { return _arrayof_jshort_arraycopy; }
  static address arrayof_jint_arraycopy()   { return _arrayof_jint_arraycopy; }
  static address arrayof_jlong_arraycopy()  { return _arrayof_jlong_arraycopy; }
331 332 333
  static address arrayof_oop_arraycopy(bool dest_uninitialized = false) {
    return dest_uninitialized ? _arrayof_oop_arraycopy_uninit : _arrayof_oop_arraycopy;
  }
D
duke 已提交
334 335 336 337 338

  static address arrayof_jbyte_disjoint_arraycopy()  { return _arrayof_jbyte_disjoint_arraycopy; }
  static address arrayof_jshort_disjoint_arraycopy() { return _arrayof_jshort_disjoint_arraycopy; }
  static address arrayof_jint_disjoint_arraycopy()   { return _arrayof_jint_disjoint_arraycopy; }
  static address arrayof_jlong_disjoint_arraycopy()  { return _arrayof_jlong_disjoint_arraycopy; }
339 340 341
  static address arrayof_oop_disjoint_arraycopy(bool dest_uninitialized = false) {
    return dest_uninitialized ? _arrayof_oop_disjoint_arraycopy_uninit : _arrayof_oop_disjoint_arraycopy;
  }
D
duke 已提交
342

343 344 345
  static address checkcast_arraycopy(bool dest_uninitialized = false) {
    return dest_uninitialized ? _checkcast_arraycopy_uninit : _checkcast_arraycopy;
  }
D
duke 已提交
346 347 348
  static address unsafe_arraycopy()        { return _unsafe_arraycopy; }
  static address generic_arraycopy()       { return _generic_arraycopy; }

N
never 已提交
349 350 351 352 353 354 355
  static address jbyte_fill()          { return _jbyte_fill; }
  static address jshort_fill()         { return _jshort_fill; }
  static address jint_fill()           { return _jint_fill; }
  static address arrayof_jbyte_fill()  { return _arrayof_jbyte_fill; }
  static address arrayof_jshort_fill() { return _arrayof_jshort_fill; }
  static address arrayof_jint_fill()   { return _arrayof_jint_fill; }

356 357 358 359 360
  static address aescrypt_encryptBlock()                { return _aescrypt_encryptBlock; }
  static address aescrypt_decryptBlock()                { return _aescrypt_decryptBlock; }
  static address cipherBlockChaining_encryptAESCrypt()  { return _cipherBlockChaining_encryptAESCrypt; }
  static address cipherBlockChaining_decryptAESCrypt()  { return _cipherBlockChaining_decryptAESCrypt; }

361 362 363 364 365 366 367
  static address sha1_implCompress()     { return _sha1_implCompress; }
  static address sha1_implCompressMB()   { return _sha1_implCompressMB; }
  static address sha256_implCompress()   { return _sha256_implCompress; }
  static address sha256_implCompressMB() { return _sha256_implCompressMB; }
  static address sha512_implCompress()   { return _sha512_implCompress; }
  static address sha512_implCompressMB() { return _sha512_implCompressMB; }

368 369 370
  static address updateBytesCRC32()    { return _updateBytesCRC32; }
  static address crc_table_addr()      { return _crc_table_adr; }

371
  static address multiplyToLen()       {return _multiplyToLen; }
372 373
  static address squareToLen()         {return _squareToLen; }
  static address mulAdd()              {return _mulAdd; }
374

N
never 已提交
375 376
  static address select_fill_function(BasicType t, bool aligned, const char* &name);

K
kvn 已提交
377
  static address zero_aligned_words()   { return _zero_aligned_words; }
N
never 已提交
378

379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407
  static double  intrinsic_log(double d) {
    assert(_intrinsic_log != NULL, "must be defined");
    return _intrinsic_log(d);
  }
  static double  intrinsic_log10(double d) {
    assert(_intrinsic_log != NULL, "must be defined");
    return _intrinsic_log10(d);
  }
  static double  intrinsic_exp(double d) {
    assert(_intrinsic_exp != NULL, "must be defined");
    return _intrinsic_exp(d);
  }
  static double  intrinsic_pow(double d, double d2) {
    assert(_intrinsic_pow != NULL, "must be defined");
    return _intrinsic_pow(d, d2);
  }
  static double  intrinsic_sin(double d) {
    assert(_intrinsic_sin != NULL, "must be defined");
    return _intrinsic_sin(d);
  }
  static double  intrinsic_cos(double d) {
    assert(_intrinsic_cos != NULL, "must be defined");
    return _intrinsic_cos(d);
  }
  static double  intrinsic_tan(double d) {
    assert(_intrinsic_tan != NULL, "must be defined");
    return _intrinsic_tan(d);
  }

408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435
  //
  // Safefetch stub support
  //

  typedef int      (*SafeFetch32Stub)(int*      adr, int      errValue);
  typedef intptr_t (*SafeFetchNStub) (intptr_t* adr, intptr_t errValue);

  static SafeFetch32Stub SafeFetch32_stub() { return CAST_TO_FN_PTR(SafeFetch32Stub, _safefetch32_entry); }
  static SafeFetchNStub  SafeFetchN_stub()  { return CAST_TO_FN_PTR(SafeFetchNStub,  _safefetchN_entry); }

  static bool is_safefetch_fault(address pc) {
    return pc != NULL &&
          (pc == _safefetch32_fault_pc ||
           pc == _safefetchN_fault_pc);
  }

  static address continuation_for_safefetch_fault(address pc) {
    assert(_safefetch32_continuation_pc != NULL &&
           _safefetchN_continuation_pc  != NULL,
           "not initialized");

    if (pc == _safefetch32_fault_pc) return _safefetch32_continuation_pc;
    if (pc == _safefetchN_fault_pc)  return _safefetchN_continuation_pc;

    ShouldNotReachHere();
    return NULL;
  }

D
duke 已提交
436 437 438 439
  //
  // Default versions of the above arraycopy functions for platforms which do
  // not have specialized versions
  //
440 441 442 443 444 445 446 447 448 449 450 451 452
  static void jbyte_copy     (jbyte*  src, jbyte*  dest, size_t count);
  static void jshort_copy    (jshort* src, jshort* dest, size_t count);
  static void jint_copy      (jint*   src, jint*   dest, size_t count);
  static void jlong_copy     (jlong*  src, jlong*  dest, size_t count);
  static void oop_copy       (oop*    src, oop*    dest, size_t count);
  static void oop_copy_uninit(oop*    src, oop*    dest, size_t count);

  static void arrayof_jbyte_copy     (HeapWord* src, HeapWord* dest, size_t count);
  static void arrayof_jshort_copy    (HeapWord* src, HeapWord* dest, size_t count);
  static void arrayof_jint_copy      (HeapWord* src, HeapWord* dest, size_t count);
  static void arrayof_jlong_copy     (HeapWord* src, HeapWord* dest, size_t count);
  static void arrayof_oop_copy       (HeapWord* src, HeapWord* dest, size_t count);
  static void arrayof_oop_copy_uninit(HeapWord* src, HeapWord* dest, size_t count);
D
duke 已提交
453
};
454

455 456 457 458 459 460 461 462 463 464 465
// Safefetch allows to load a value from a location that's not known
// to be valid. If the load causes a fault, the error value is returned.
inline int SafeFetch32(int* adr, int errValue) {
  assert(StubRoutines::SafeFetch32_stub(), "stub not yet generated");
  return StubRoutines::SafeFetch32_stub()(adr, errValue);
}
inline intptr_t SafeFetchN(intptr_t* adr, intptr_t errValue) {
  assert(StubRoutines::SafeFetchN_stub(), "stub not yet generated");
  return StubRoutines::SafeFetchN_stub()(adr, errValue);
}

466
#endif // SHARE_VM_RUNTIME_STUBROUTINES_HPP