hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp
author ccheung
Thu, 07 Apr 2016 22:03:04 -0700
changeset 37439 e8970711113b
parent 37248 11a660dbbb8e
child 38259 b495d1cfe673
permissions -rw-r--r--
8145221: Use trampolines for i2i and i2c entries in Methods that are stored in CDS archive Summary: This optimization reduces the size of the RW region of the CDS archive. It also reduces the amount of pages in the RW region that are actually written into during runtime. Reviewed-by: dlong, iklam, jiangli Contributed-by: ioi.lam@oracle.com, calvin.cheung@oracle.com, goetz.lindenmaier@sap.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
35757
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
     2
 * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5419
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5419
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5419
diff changeset
    21
 * questions.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    25
#include "precompiled.hpp"
14626
0cf4eccf130f 8003240: x86: move MacroAssembler into separate file
twisti
parents: 14391
diff changeset
    26
#include "asm/macroAssembler.hpp"
0cf4eccf130f 8003240: x86: move MacroAssembler into separate file
twisti
parents: 14391
diff changeset
    27
#include "asm/macroAssembler.inline.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    28
#include "code/debugInfoRec.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    29
#include "code/icBuffer.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    30
#include "code/vtableStubs.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    31
#include "interpreter/interpreter.hpp"
37248
11a660dbbb8e 8132524: Missing includes to resourceArea.hpp
jprovino
parents: 36561
diff changeset
    32
#include "memory/resourceArea.hpp"
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
    33
#include "oops/compiledICHolder.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    34
#include "prims/jvmtiRedefineClassesTrace.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    35
#include "runtime/sharedRuntime.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    36
#include "runtime/vframeArray.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    37
#include "vmreg_x86.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    38
#ifdef COMPILER1
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    39
#include "c1/c1_Runtime1.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    40
#endif
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    41
#ifdef COMPILER2
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    42
#include "opto/runtime.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    43
#endif
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
#define __ masm->
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
1900
68ea5d5fab8b 6792301: StackAlignmentInBytes not honored for compiled native methods
xlu
parents: 1888
diff changeset
    47
const int StackAlignmentInSlots = StackAlignmentInBytes / VMRegImpl::stack_slot_size;
68ea5d5fab8b 6792301: StackAlignmentInBytes not honored for compiled native methods
xlu
parents: 1888
diff changeset
    48
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
class RegisterSaver {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
  // Capture info about frame layout
13883
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
    51
#define DEF_XMM_OFFS(regnum) xmm ## regnum ## _off = xmm_off + (regnum)*16/BytesPerInt, xmm ## regnum ## H_off
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
  enum layout {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
                fpu_state_off = 0,
13883
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
    54
                fpu_state_end = fpu_state_off+FPUStateSizeInWords,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
                st0_off, st0H_off,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
                st1_off, st1H_off,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
                st2_off, st2H_off,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
                st3_off, st3H_off,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
                st4_off, st4H_off,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
                st5_off, st5H_off,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
                st6_off, st6H_off,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
                st7_off, st7H_off,
13883
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
    63
                xmm_off,
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
    64
                DEF_XMM_OFFS(0),
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
    65
                DEF_XMM_OFFS(1),
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
    66
                DEF_XMM_OFFS(2),
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
    67
                DEF_XMM_OFFS(3),
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
    68
                DEF_XMM_OFFS(4),
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
    69
                DEF_XMM_OFFS(5),
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
    70
                DEF_XMM_OFFS(6),
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
    71
                DEF_XMM_OFFS(7),
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
    72
                flags_off = xmm7_off + 16/BytesPerInt + 1, // 16-byte stack alignment fill word
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
                rdi_off,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
                rsi_off,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
                ignore_off,  // extra copy of rbp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
                rsp_off,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
                rbx_off,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
                rdx_off,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
                rcx_off,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
                rax_off,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
                // The frame sender code expects that rbp will be in the "natural" place and
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
                // will override any oopMap setting for it. We must therefore force the layout
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
                // so that it agrees with the frame sender code.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
                rbp_off,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
                return_off,      // slot for return address
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
                reg_save_size };
13883
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
    87
  enum { FPU_regs_live = flags_off - fpu_state_end };
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
  public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
  static OopMap* save_live_registers(MacroAssembler* masm, int additional_frame_words,
13883
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
    92
                                     int* total_frame_words, bool verify_fpu = true, bool save_vectors = false);
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
    93
  static void restore_live_registers(MacroAssembler* masm, bool restore_vectors = false);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
  static int rax_offset() { return rax_off; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
  static int rbx_offset() { return rbx_off; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
  // Offsets into the register save area
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
  // Used by deoptimization when it is managing result register
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
  // values on its own
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
  static int raxOffset(void) { return rax_off; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
  static int rdxOffset(void) { return rdx_off; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
  static int rbxOffset(void) { return rbx_off; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
  static int xmm0Offset(void) { return xmm0_off; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
  // This really returns a slot in the fp save area, which one is not important
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
  static int fpResultOffset(void) { return st0_off; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
  // During deoptimization only the result register need to be restored
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
  // all the other values have already been extracted.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
  static void restore_result_registers(MacroAssembler* masm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words,
13883
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
   117
                                           int* total_frame_words, bool verify_fpu, bool save_vectors) {
32727
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   118
  int num_xmm_regs = XMMRegisterImpl::number_of_registers;
35757
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   119
  int ymm_bytes = num_xmm_regs * 16;
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   120
  int zmm_bytes = num_xmm_regs * 32;
13883
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
   121
#ifdef COMPILER2
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
   122
  if (save_vectors) {
35757
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   123
    assert(UseAVX > 0, "up to 512bit vectors are supported with EVEX");
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   124
    assert(MaxVectorSize <= 64, "up to 512bit vectors are supported now");
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   125
    // Save upper half of YMM registers
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   126
    int vect_bytes = ymm_bytes;
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   127
    if (UseAVX > 2) {
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   128
      // Save upper half of ZMM registers as well
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   129
      vect_bytes += zmm_bytes;
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   130
    }
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   131
    additional_frame_words += vect_bytes / wordSize;
13883
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
   132
  }
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
   133
#else
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
   134
  assert(!save_vectors, "vectors are generated only by C2");
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
   135
#endif
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
   136
  int frame_size_in_bytes = (reg_save_size + additional_frame_words) * wordSize;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
  int frame_words = frame_size_in_bytes / wordSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
  *total_frame_words = frame_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
  assert(FPUStateSizeInWords == 27, "update stack layout");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
  // save registers, fpu state, and flags
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
  // We assume caller has already has return address slot on the stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
  // We push epb twice in this sequence because we want the real rbp,
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   145
  // to be under the return like a normal enter and we want to use pusha
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
  // We push by hand instead of pusing push
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
  __ enter();
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   148
  __ pusha();
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   149
  __ pushf();
13883
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
   150
  __ subptr(rsp,FPU_regs_live*wordSize); // Push FPU registers space
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
  __ push_FPU_state();          // Save FPU state & init
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
  if (verify_fpu) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
    // Some stubs may have non standard FPU control word settings so
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
    // only check and reset the value when it required to be the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
    // standard value.  The safepoint blob in particular can be used
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
    // in methods which are using the 24 bit control word for
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
    // optimized float math.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
    // Make sure the control word has the expected value
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
    Label ok;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
    __ cmpw(Address(rsp, 0), StubRoutines::fpu_cntrl_wrd_std());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
    __ jccb(Assembler::equal, ok);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
    __ stop("corrupted control word detected");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
    __ bind(ok);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
    // Reset the control word to guard against exceptions being unmasked
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
    // since fstp_d can cause FPU stack underflow exceptions.  Write it
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
    // into the on stack copy and then reload that to make sure that the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
    // current and future values are correct.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
    __ movw(Address(rsp, 0), StubRoutines::fpu_cntrl_wrd_std());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
  __ frstor(Address(rsp, 0));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
  if (!verify_fpu) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
    // Set the control word so that exceptions are masked for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
    // following code.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
    __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
32727
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   183
  int off = st0_off;
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   184
  int delta = st1_off - off;
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   185
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
  // Save the FPU registers in de-opt-able form
32727
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   187
  for (int n = 0; n < FloatRegisterImpl::number_of_registers; n++) {
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   188
    __ fstp_d(Address(rsp, off*wordSize));
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   189
    off += delta;
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   190
  }
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   191
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   192
  off = xmm0_off;
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   193
  delta = xmm1_off - off;
35757
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   194
  if(UseSSE == 1) {
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   195
    // Save the XMM state
32727
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   196
    for (int n = 0; n < num_xmm_regs; n++) {
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   197
      __ movflt(Address(rsp, off*wordSize), as_XMMRegister(n));
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   198
      off += delta;
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   199
    }
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   200
  } else if(UseSSE >= 2) {
35757
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   201
    // Save whole 128bit (16 bytes) XMM registers
34162
16b54851eaf6 8140779: Code generation fixes for avx512
iveresov
parents: 33198
diff changeset
   202
    for (int n = 0; n < num_xmm_regs; n++) {
16b54851eaf6 8140779: Code generation fixes for avx512
iveresov
parents: 33198
diff changeset
   203
      __ movdqu(Address(rsp, off*wordSize), as_XMMRegister(n));
16b54851eaf6 8140779: Code generation fixes for avx512
iveresov
parents: 33198
diff changeset
   204
      off += delta;
32727
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   205
    }
13883
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
   206
  }
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
   207
34203
6817dadf6c7e 8142980: SKX SpecJvm2008 - Derby
mcberg
parents: 34185
diff changeset
   208
  if (save_vectors) {
35757
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   209
    __ subptr(rsp, ymm_bytes);
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   210
    // Save upper half of YMM registers
32727
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   211
    for (int n = 0; n < num_xmm_regs; n++) {
36561
b18243f4d955 8151002: Make Assembler methods vextract and vinsert match actual instructions
mikael
parents: 36079
diff changeset
   212
      __ vextractf128_high(Address(rsp, n*16), as_XMMRegister(n));
32727
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   213
    }
30624
2e1803c8a26d 8076276: Add support for AVX512
kvn
parents: 30244
diff changeset
   214
    if (UseAVX > 2) {
35757
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   215
      __ subptr(rsp, zmm_bytes);
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   216
      // Save upper half of ZMM registers
32727
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   217
      for (int n = 0; n < num_xmm_regs; n++) {
36561
b18243f4d955 8151002: Make Assembler methods vextract and vinsert match actual instructions
mikael
parents: 36079
diff changeset
   218
        __ vextractf64x4_high(Address(rsp, n*32), as_XMMRegister(n));
32727
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   219
      }
30624
2e1803c8a26d 8076276: Add support for AVX512
kvn
parents: 30244
diff changeset
   220
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
  // Set an oopmap for the call site.  This oopmap will map all
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
  // oop-registers and debug-info registers as callee-saved.  This
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
  // will allow deoptimization at this safepoint to find all possible
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
  // debug-info recordings, as well as let GC find all oops.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
  OopMapSet *oop_maps = new OopMapSet();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
  OopMap* map =  new OopMap( frame_words, 0 );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
#define STACK_OFFSET(x) VMRegImpl::stack2reg((x) + additional_frame_words)
32727
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   232
#define NEXTREG(x) (x)->as_VMReg()->next()
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   233
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   234
  map->set_callee_saved(STACK_OFFSET(rax_off), rax->as_VMReg());
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   235
  map->set_callee_saved(STACK_OFFSET(rcx_off), rcx->as_VMReg());
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   236
  map->set_callee_saved(STACK_OFFSET(rdx_off), rdx->as_VMReg());
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   237
  map->set_callee_saved(STACK_OFFSET(rbx_off), rbx->as_VMReg());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
  // rbp, location is known implicitly, no oopMap
32727
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   239
  map->set_callee_saved(STACK_OFFSET(rsi_off), rsi->as_VMReg());
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   240
  map->set_callee_saved(STACK_OFFSET(rdi_off), rdi->as_VMReg());
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   241
  // %%% This is really a waste but we'll keep things as they were for now for the upper component
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   242
  off = st0_off;
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   243
  delta = st1_off - off;
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   244
  for (int n = 0; n < FloatRegisterImpl::number_of_registers; n++) {
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   245
    FloatRegister freg_name = as_FloatRegister(n);
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   246
    map->set_callee_saved(STACK_OFFSET(off), freg_name->as_VMReg());
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   247
    map->set_callee_saved(STACK_OFFSET(off+1), NEXTREG(freg_name));
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   248
    off += delta;
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   249
  }
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   250
  off = xmm0_off;
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   251
  delta = xmm1_off - off;
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   252
  for (int n = 0; n < num_xmm_regs; n++) {
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   253
    XMMRegister xmm_name = as_XMMRegister(n);
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   254
    map->set_callee_saved(STACK_OFFSET(off), xmm_name->as_VMReg());
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   255
    map->set_callee_saved(STACK_OFFSET(off+1), NEXTREG(xmm_name));
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   256
    off += delta;
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   257
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
#undef NEXTREG
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
#undef STACK_OFFSET
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
  return map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
13883
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
   264
void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_vectors) {
32727
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   265
  int num_xmm_regs = XMMRegisterImpl::number_of_registers;
35757
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   266
  int ymm_bytes = num_xmm_regs * 16;
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   267
  int zmm_bytes = num_xmm_regs * 32;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
  // Recover XMM & FPU state
13883
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
   269
  int additional_frame_bytes = 0;
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
   270
#ifdef COMPILER2
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
   271
  if (restore_vectors) {
35757
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   272
    assert(UseAVX > 0, "up to 512bit vectors are supported with EVEX");
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   273
    assert(MaxVectorSize <= 64, "up to 512bit vectors are supported now");
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   274
    // Save upper half of YMM registers
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   275
    additional_frame_bytes = ymm_bytes;
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   276
    if (UseAVX > 2) {
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   277
      // Save upper half of ZMM registers as well
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   278
      additional_frame_bytes += zmm_bytes;
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   279
    }
13883
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
   280
  }
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
   281
#else
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
   282
  assert(!restore_vectors, "vectors are generated only by C2");
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
   283
#endif
34203
6817dadf6c7e 8142980: SKX SpecJvm2008 - Derby
mcberg
parents: 34185
diff changeset
   284
35757
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   285
  int off = xmm0_off;
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   286
  int delta = xmm1_off - off;
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   287
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   288
  if (UseSSE == 1) {
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   289
    // Restore XMM registers
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   290
    assert(additional_frame_bytes == 0, "");
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   291
    for (int n = 0; n < num_xmm_regs; n++) {
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   292
      __ movflt(as_XMMRegister(n), Address(rsp, off*wordSize));
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   293
      off += delta;
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   294
    }
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   295
  } else if (UseSSE >= 2) {
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   296
    // Restore whole 128bit (16 bytes) XMM registers. Do this before restoring YMM and
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   297
    // ZMM because the movdqu instruction zeros the upper part of the XMM register.
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   298
    for (int n = 0; n < num_xmm_regs; n++) {
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   299
      __ movdqu(as_XMMRegister(n), Address(rsp, off*wordSize+additional_frame_bytes));
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   300
      off += delta;
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   301
    }
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   302
  }
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   303
13883
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
   304
  if (restore_vectors) {
32727
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   305
    if (UseAVX > 2) {
34162
16b54851eaf6 8140779: Code generation fixes for avx512
iveresov
parents: 33198
diff changeset
   306
      // Restore upper half of ZMM registers.
32727
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   307
      for (int n = 0; n < num_xmm_regs; n++) {
36561
b18243f4d955 8151002: Make Assembler methods vextract and vinsert match actual instructions
mikael
parents: 36079
diff changeset
   308
        __ vinsertf64x4_high(as_XMMRegister(n), Address(rsp, n*32));
32727
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   309
      }
35757
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   310
      __ addptr(rsp, zmm_bytes);
32727
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   311
    }
35757
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   312
    // Restore upper half of YMM registers.
32727
320855c2baef 8132160: support for AVX 512 call frames and stack management
mcberg
parents: 31786
diff changeset
   313
    for (int n = 0; n < num_xmm_regs; n++) {
36561
b18243f4d955 8151002: Make Assembler methods vextract and vinsert match actual instructions
mikael
parents: 36079
diff changeset
   314
      __ vinsertf128_high(as_XMMRegister(n), Address(rsp, n*16));
30624
2e1803c8a26d 8076276: Add support for AVX512
kvn
parents: 30244
diff changeset
   315
    }
35757
0eeda480b926 8148490: RegisterSaver::restore_live_registers() fails to restore xmm registers on 32 bit
thartmann
parents: 35492
diff changeset
   316
    __ addptr(rsp, ymm_bytes);
34203
6817dadf6c7e 8142980: SKX SpecJvm2008 - Derby
mcberg
parents: 34185
diff changeset
   317
  }
6817dadf6c7e 8142980: SKX SpecJvm2008 - Derby
mcberg
parents: 34185
diff changeset
   318
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
  __ pop_FPU_state();
13883
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
   320
  __ addptr(rsp, FPU_regs_live*wordSize); // Pop FPU registers
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   321
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   322
  __ popf();
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   323
  __ popa();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
  // Get the rbp, described implicitly by the frame sender code (no oopMap)
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   325
  __ pop(rbp);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
void RegisterSaver::restore_result_registers(MacroAssembler* masm) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
  // Just restore result register. Only used by deoptimization. By
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
  // now any callee save register that needs to be restore to a c2
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
  // caller of the deoptee has been extracted into the vframeArray
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
  // and will be stuffed into the c2i adapter we create for later
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
  // restoration so only result registers need to be restored here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
  __ frstor(Address(rsp, 0));      // Restore fpu state
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
  // Recover XMM & FPU state
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
  if( UseSSE == 1 ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
    __ movflt(xmm0, Address(rsp, xmm0_off*wordSize));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
  } else if( UseSSE >= 2 ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
    __ movdbl(xmm0, Address(rsp, xmm0_off*wordSize));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
  }
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   345
  __ movptr(rax, Address(rsp, rax_off*wordSize));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   346
  __ movptr(rdx, Address(rsp, rdx_off*wordSize));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
  // Pop all of the register save are off the stack except the return address
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   348
  __ addptr(rsp, return_off * wordSize);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
13883
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
   351
// Is vector's size (in bytes) bigger than a size saved by default?
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
   352
// 16 bytes XMM registers are saved by default using SSE2 movdqu instructions.
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
   353
// Note, MaxVectorSize == 0 with UseSSE < 2 and vectors are not generated.
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
   354
bool SharedRuntime::is_wide_vector(int size) {
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
   355
  return size > 16;
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
   356
}
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
   357
37439
e8970711113b 8145221: Use trampolines for i2i and i2c entries in Methods that are stored in CDS archive
ccheung
parents: 37248
diff changeset
   358
size_t SharedRuntime::trampoline_size() {
e8970711113b 8145221: Use trampolines for i2i and i2c entries in Methods that are stored in CDS archive
ccheung
parents: 37248
diff changeset
   359
  return 16;
e8970711113b 8145221: Use trampolines for i2i and i2c entries in Methods that are stored in CDS archive
ccheung
parents: 37248
diff changeset
   360
}
e8970711113b 8145221: Use trampolines for i2i and i2c entries in Methods that are stored in CDS archive
ccheung
parents: 37248
diff changeset
   361
e8970711113b 8145221: Use trampolines for i2i and i2c entries in Methods that are stored in CDS archive
ccheung
parents: 37248
diff changeset
   362
void SharedRuntime::generate_trampoline(MacroAssembler *masm, address destination) {
e8970711113b 8145221: Use trampolines for i2i and i2c entries in Methods that are stored in CDS archive
ccheung
parents: 37248
diff changeset
   363
  __ jump(RuntimeAddress(destination));
e8970711113b 8145221: Use trampolines for i2i and i2c entries in Methods that are stored in CDS archive
ccheung
parents: 37248
diff changeset
   364
}
e8970711113b 8145221: Use trampolines for i2i and i2c entries in Methods that are stored in CDS archive
ccheung
parents: 37248
diff changeset
   365
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
// The java_calling_convention describes stack locations as ideal slots on
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
// a frame with no abi restrictions. Since we must observe abi restrictions
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
// (like the placement of the register window) the slots must be biased by
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
// the following value.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
static int reg2offset_in(VMReg r) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
  // Account for saved rbp, and return address
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
  // This should really be in_preserve_stack_slots
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
  return (r->reg2stack() + 2) * VMRegImpl::stack_slot_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
static int reg2offset_out(VMReg r) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
  return (r->reg2stack() + SharedRuntime::out_preserve_stack_slots()) * VMRegImpl::stack_slot_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
// ---------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
// Read the array of BasicTypes from a signature, and compute where the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
// arguments should go.  Values in the VMRegPair regs array refer to 4-byte
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
// quantities.  Values less than SharedInfo::stack0 are registers, those above
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
// refer to 4-byte stack slots.  All stack slots are based off of the stack pointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
// as framesizes are fixed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
// VMRegImpl::stack0 refers to the first slot 0(sp).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
// and VMRegImpl::stack0+1 refers to the memory word 4-byes higher.  Register
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
// up to RegisterImpl::number_of_registers) are the 32-bit
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
// integer registers.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
// Pass first two oop/int args in registers ECX and EDX.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
// Pass first two float/double args in registers XMM0 and XMM1.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
// Doubles have precedence, so if you pass a mix of floats and doubles
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
// the doubles will grab the registers before the floats will.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
// Note: the INPUTS in sig_bt are in units of Java argument words, which are
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
// either 32-bit or 64-bit depending on the build.  The OUTPUTS are in 32-bit
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
// units regardless of build. Of course for i486 there is no 64 bit build
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
// ---------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
// The compiled Java calling convention.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
// Pass first two oop/int args in registers ECX and EDX.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
// Pass first two float/double args in registers XMM0 and XMM1.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
// Doubles have precedence, so if you pass a mix of floats and doubles
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
// the doubles will grab the registers before the floats will.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
                                           VMRegPair *regs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
                                           int total_args_passed,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
                                           int is_outgoing) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
  uint    stack = 0;          // Starting stack position for args on stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
  // Pass first two oop/int args in registers ECX and EDX.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
  uint reg_arg0 = 9999;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
  uint reg_arg1 = 9999;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
  // Pass first two float/double args in registers XMM0 and XMM1.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
  // Doubles have precedence, so if you pass a mix of floats and doubles
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
  // the doubles will grab the registers before the floats will.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
  // CNC - TURNED OFF FOR non-SSE.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
  //       On Intel we have to round all doubles (and most floats) at
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
  //       call sites by storing to the stack in any case.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
  // UseSSE=0 ==> Don't Use ==> 9999+0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
  // UseSSE=1 ==> Floats only ==> 9999+1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
  // UseSSE>=2 ==> Floats or doubles ==> 9999+2
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
  enum { fltarg_dontuse = 9999+0, fltarg_float_only = 9999+1, fltarg_flt_dbl = 9999+2 };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
  uint fargs = (UseSSE>=2) ? 2 : UseSSE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
  uint freg_arg0 = 9999+fargs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
  uint freg_arg1 = 9999+fargs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
  // Pass doubles & longs aligned on the stack.  First count stack slots for doubles
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
  int i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
  for( i = 0; i < total_args_passed; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
    if( sig_bt[i] == T_DOUBLE ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
      // first 2 doubles go in registers
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
      if( freg_arg0 == fltarg_flt_dbl ) freg_arg0 = i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
      else if( freg_arg1 == fltarg_flt_dbl ) freg_arg1 = i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
      else // Else double is passed low on the stack to be aligned.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
        stack += 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
    } else if( sig_bt[i] == T_LONG ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
      stack += 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
  int dstack = 0;             // Separate counter for placing doubles
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
  // Now pick where all else goes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
  for( i = 0; i < total_args_passed; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
    // From the type and the argument number (count) compute the location
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
    switch( sig_bt[i] ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
    case T_SHORT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
    case T_CHAR:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
    case T_BYTE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
    case T_BOOLEAN:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
    case T_INT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
    case T_ARRAY:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
    case T_OBJECT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
    case T_ADDRESS:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
      if( reg_arg0 == 9999 )  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
        reg_arg0 = i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
        regs[i].set1(rcx->as_VMReg());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
      } else if( reg_arg1 == 9999 )  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
        reg_arg1 = i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
        regs[i].set1(rdx->as_VMReg());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
        regs[i].set1(VMRegImpl::stack2reg(stack++));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
    case T_FLOAT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
      if( freg_arg0 == fltarg_flt_dbl || freg_arg0 == fltarg_float_only ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
        freg_arg0 = i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
        regs[i].set1(xmm0->as_VMReg());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
      } else if( freg_arg1 == fltarg_flt_dbl || freg_arg1 == fltarg_float_only ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
        freg_arg1 = i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
        regs[i].set1(xmm1->as_VMReg());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
        regs[i].set1(VMRegImpl::stack2reg(stack++));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
    case T_LONG:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
      assert(sig_bt[i+1] == T_VOID, "missing Half" );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
      regs[i].set2(VMRegImpl::stack2reg(dstack));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
      dstack += 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
    case T_DOUBLE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
      assert(sig_bt[i+1] == T_VOID, "missing Half" );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
      if( freg_arg0 == (uint)i ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
        regs[i].set2(xmm0->as_VMReg());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
      } else if( freg_arg1 == (uint)i ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
        regs[i].set2(xmm1->as_VMReg());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
        regs[i].set2(VMRegImpl::stack2reg(dstack));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
        dstack += 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
    case T_VOID: regs[i].set_bad(); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
    default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
      ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
  // return value can be odd number of VMRegImpl stack slots make multiple of 2
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
  return round_to(stack, 2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
// Patch the callers callsite with entry to compiled code if it exists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
static void patch_callers_callsite(MacroAssembler *masm) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
  Label L;
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   511
  __ cmpptr(Address(rbx, in_bytes(Method::code_offset())), (int32_t)NULL_WORD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
  __ jcc(Assembler::equal, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
  // Schedule the branch target address early.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
  // Call into the VM to patch the caller, then jump to compiled callee
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
  // rax, isn't live so capture return address while we easily can
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   516
  __ movptr(rax, Address(rsp, 0));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   517
  __ pusha();
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   518
  __ pushf();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
  if (UseSSE == 1) {
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   521
    __ subptr(rsp, 2*wordSize);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
    __ movflt(Address(rsp, 0), xmm0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
    __ movflt(Address(rsp, wordSize), xmm1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
  if (UseSSE >= 2) {
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   526
    __ subptr(rsp, 4*wordSize);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
    __ movdbl(Address(rsp, 0), xmm0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
    __ movdbl(Address(rsp, 2*wordSize), xmm1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
#ifdef COMPILER2
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
  // C2 may leave the stack dirty if not in SSE2+ mode
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
  if (UseSSE >= 2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
    __ verify_FPU(0, "c2i transition should have clean FPU stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
    __ empty_FPU_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
#endif /* COMPILER2 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
  // VM needs caller's callsite
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   540
  __ push(rax);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
  // VM needs target method
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   542
  __ push(rbx);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
  __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::fixup_callers_callsite)));
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   544
  __ addptr(rsp, 2*wordSize);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
  if (UseSSE == 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
    __ movflt(xmm0, Address(rsp, 0));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
    __ movflt(xmm1, Address(rsp, wordSize));
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   549
    __ addptr(rsp, 2*wordSize);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
  if (UseSSE >= 2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
    __ movdbl(xmm0, Address(rsp, 0));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
    __ movdbl(xmm1, Address(rsp, 2*wordSize));
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   554
    __ addptr(rsp, 4*wordSize);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   557
  __ popf();
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   558
  __ popa();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
  __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
static void move_c2i_double(MacroAssembler *masm, XMMRegister r, int st_off) {
5419
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 4735
diff changeset
   564
  int next_off = st_off - Interpreter::stackElementSize;
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 4735
diff changeset
   565
  __ movdbl(Address(rsp, next_off), r);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
static void gen_c2i_adapter(MacroAssembler *masm,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
                            int total_args_passed,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
                            int comp_args_on_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
                            const BasicType *sig_bt,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
                            const VMRegPair *regs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
                            Label& skip_fixup) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
  // Before we get into the guts of the C2I adapter, see if we should be here
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
  // at all.  We've come from compiled code and are attempting to jump to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
  // interpreter, which means the caller made a static call to get here
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
  // (vcalls always get a compiled target if there is one).  Check for a
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
  // compiled target.  If there is one, we need to patch the caller's call.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
  patch_callers_callsite(masm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
  __ bind(skip_fixup);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
#ifdef COMPILER2
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
  // C2 may leave the stack dirty if not in SSE2+ mode
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
  if (UseSSE >= 2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
    __ verify_FPU(0, "c2i transition should have clean FPU stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
    __ empty_FPU_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
#endif /* COMPILER2 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
  // Since all args are passed on the stack, total_args_passed * interpreter_
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
  // stack_element_size  is the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
  // space we need.
5419
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 4735
diff changeset
   595
  int extraspace = total_args_passed * Interpreter::stackElementSize;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
  // Get return address
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   598
  __ pop(rax);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
  // set senderSP value
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   601
  __ movptr(rsi, rsp);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   602
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   603
  __ subptr(rsp, extraspace);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
  // Now write the args into the outgoing interpreter space
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
  for (int i = 0; i < total_args_passed; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
    if (sig_bt[i] == T_VOID) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
      assert(i > 0 && (sig_bt[i-1] == T_LONG || sig_bt[i-1] == T_DOUBLE), "missing half");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
    // st_off points to lowest address on stack.
5419
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 4735
diff changeset
   613
    int st_off = ((total_args_passed - 1) - i) * Interpreter::stackElementSize;
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 4735
diff changeset
   614
    int next_off = st_off - Interpreter::stackElementSize;
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   615
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
    // Say 4 args:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
    // i   st_off
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
    // 0   12 T_LONG
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
    // 1    8 T_VOID
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
    // 2    4 T_OBJECT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
    // 3    0 T_BOOL
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
    VMReg r_1 = regs[i].first();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
    VMReg r_2 = regs[i].second();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
    if (!r_1->is_valid()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
      assert(!r_2->is_valid(), "");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
    if (r_1->is_stack()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
      // memory to memory use fpu stack top
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
      int ld_off = r_1->reg2stack() * VMRegImpl::stack_slot_size + extraspace;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
      if (!r_2->is_valid()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
        __ movl(rdi, Address(rsp, ld_off));
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   635
        __ movptr(Address(rsp, st_off), rdi);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
        // ld_off == LSW, ld_off+VMRegImpl::stack_slot_size == MSW
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
        // st_off == MSW, st_off-wordSize == LSW
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   641
        __ movptr(rdi, Address(rsp, ld_off));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   642
        __ movptr(Address(rsp, next_off), rdi);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   643
#ifndef _LP64
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   644
        __ movptr(rdi, Address(rsp, ld_off + wordSize));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   645
        __ movptr(Address(rsp, st_off), rdi);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   646
#else
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   647
#ifdef ASSERT
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   648
        // Overwrite the unused slot with known junk
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   649
        __ mov64(rax, CONST64(0xdeadffffdeadaaaa));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   650
        __ movptr(Address(rsp, st_off), rax);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   651
#endif /* ASSERT */
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   652
#endif // _LP64
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
    } else if (r_1->is_Register()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
      Register r = r_1->as_Register();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
      if (!r_2->is_valid()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
        __ movl(Address(rsp, st_off), r);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
        // long/double in gpr
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   660
        NOT_LP64(ShouldNotReachHere());
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   661
        // Two VMRegs can be T_OBJECT, T_ADDRESS, T_DOUBLE, T_LONG
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   662
        // T_DOUBLE and T_LONG use two slots in the interpreter
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   663
        if ( sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) {
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   664
          // long/double in gpr
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   665
#ifdef ASSERT
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   666
          // Overwrite the unused slot with known junk
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   667
          LP64_ONLY(__ mov64(rax, CONST64(0xdeadffffdeadaaab)));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   668
          __ movptr(Address(rsp, st_off), rax);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   669
#endif /* ASSERT */
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   670
          __ movptr(Address(rsp, next_off), r);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   671
        } else {
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   672
          __ movptr(Address(rsp, st_off), r);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   673
        }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
      assert(r_1->is_XMMRegister(), "");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
      if (!r_2->is_valid()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
        __ movflt(Address(rsp, st_off), r_1->as_XMMRegister());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
        assert(sig_bt[i] == T_DOUBLE || sig_bt[i] == T_LONG, "wrong type");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
        move_c2i_double(masm, r_1->as_XMMRegister(), st_off);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   683
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   684
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   685
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
  // Schedule the branch target address early.
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   687
  __ movptr(rcx, Address(rbx, in_bytes(Method::interpreter_entry_offset())));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
  // And repush original return address
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   689
  __ push(rax);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
  __ jmp(rcx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
static void move_i2c_double(MacroAssembler *masm, XMMRegister r, Register saved_sp, int ld_off) {
5419
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 4735
diff changeset
   695
  int next_val_off = ld_off - Interpreter::stackElementSize;
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 4735
diff changeset
   696
  __ movdbl(r, Address(saved_sp, next_val_off));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   698
13391
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   699
static void range_check(MacroAssembler* masm, Register pc_reg, Register temp_reg,
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   700
                        address code_start, address code_end,
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   701
                        Label& L_ok) {
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   702
  Label L_fail;
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   703
  __ lea(temp_reg, ExternalAddress(code_start));
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   704
  __ cmpptr(pc_reg, temp_reg);
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   705
  __ jcc(Assembler::belowEqual, L_fail);
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   706
  __ lea(temp_reg, ExternalAddress(code_end));
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   707
  __ cmpptr(pc_reg, temp_reg);
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   708
  __ jcc(Assembler::below, L_ok);
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   709
  __ bind(L_fail);
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   710
}
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   711
33160
c59f1676d27e 8136421: JEP 243: Java-Level JVM Compiler Interface
twisti
parents: 32727
diff changeset
   712
void SharedRuntime::gen_i2c_adapter(MacroAssembler *masm,
c59f1676d27e 8136421: JEP 243: Java-Level JVM Compiler Interface
twisti
parents: 32727
diff changeset
   713
                                    int total_args_passed,
c59f1676d27e 8136421: JEP 243: Java-Level JVM Compiler Interface
twisti
parents: 32727
diff changeset
   714
                                    int comp_args_on_stack,
c59f1676d27e 8136421: JEP 243: Java-Level JVM Compiler Interface
twisti
parents: 32727
diff changeset
   715
                                    const BasicType *sig_bt,
c59f1676d27e 8136421: JEP 243: Java-Level JVM Compiler Interface
twisti
parents: 32727
diff changeset
   716
                                    const VMRegPair *regs) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   717
  // Note: rsi contains the senderSP on entry. We must preserve it since
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
  // we may do a i2c -> c2i transition if we lose a race where compiled
489c9b5090e2 Initial load
duke
parents:
diff changeset
   719
  // code goes non-entrant while we get args ready.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   720
13391
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   721
  // Adapters can be frameless because they do not require the caller
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   722
  // to perform additional cleanup work, such as correcting the stack pointer.
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   723
  // An i2c adapter is frameless because the *caller* frame, which is interpreted,
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   724
  // routinely repairs its own stack pointer (from interpreter_frame_last_sp),
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   725
  // even if a callee has modified the stack pointer.
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   726
  // A c2i adapter is frameless because the *callee* frame, which is interpreted,
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   727
  // routinely repairs its caller's stack pointer (from sender_sp, which is set
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   728
  // up via the senderSP register).
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   729
  // In other words, if *either* the caller or callee is interpreted, we can
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   730
  // get the stack pointer repaired after a call.
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   731
  // This is why c2i and i2c adapters cannot be indefinitely composed.
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   732
  // In particular, if a c2i adapter were to somehow call an i2c adapter,
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   733
  // both caller and callee would be compiled methods, and neither would
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   734
  // clean up the stack pointer changes performed by the two adapters.
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   735
  // If this happens, control eventually transfers back to the compiled
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   736
  // caller, but with an uncorrected stack, causing delayed havoc.
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   737
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   738
  // Pick up the return address
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   739
  __ movptr(rax, Address(rsp, 0));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
13391
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   741
  if (VerifyAdapterCalls &&
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   742
      (Interpreter::code() != NULL || StubRoutines::code1() != NULL)) {
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   743
    // So, let's test for cascading c2i/i2c adapters right now.
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   744
    //  assert(Interpreter::contains($return_addr) ||
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   745
    //         StubRoutines::contains($return_addr),
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   746
    //         "i2c adapter must return to an interpreter frame");
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   747
    __ block_comment("verify_i2c { ");
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   748
    Label L_ok;
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   749
    if (Interpreter::code() != NULL)
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   750
      range_check(masm, rax, rdi,
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   751
                  Interpreter::code()->code_start(), Interpreter::code()->code_end(),
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   752
                  L_ok);
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   753
    if (StubRoutines::code1() != NULL)
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   754
      range_check(masm, rax, rdi,
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   755
                  StubRoutines::code1()->code_begin(), StubRoutines::code1()->code_end(),
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   756
                  L_ok);
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   757
    if (StubRoutines::code2() != NULL)
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   758
      range_check(masm, rax, rdi,
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   759
                  StubRoutines::code2()->code_begin(), StubRoutines::code2()->code_end(),
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   760
                  L_ok);
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   761
    const char* msg = "i2c adapter must return to an interpreter frame";
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   762
    __ block_comment(msg);
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   763
    __ stop(msg);
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   764
    __ bind(L_ok);
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   765
    __ block_comment("} verify_i2ce ");
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   766
  }
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
   767
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   768
  // Must preserve original SP for loading incoming arguments because
489c9b5090e2 Initial load
duke
parents:
diff changeset
   769
  // we need to align the outgoing SP for compiled code.
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   770
  __ movptr(rdi, rsp);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   771
489c9b5090e2 Initial load
duke
parents:
diff changeset
   772
  // Cut-out for having no stack args.  Since up to 2 int/oop args are passed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   773
  // in registers, we will occasionally have no stack args.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   774
  int comp_words_on_stack = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   775
  if (comp_args_on_stack) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   776
    // Sig words on the stack are greater-than VMRegImpl::stack0.  Those in
489c9b5090e2 Initial load
duke
parents:
diff changeset
   777
    // registers are below.  By subtracting stack0, we either get a negative
489c9b5090e2 Initial load
duke
parents:
diff changeset
   778
    // number (all values in registers) or the maximum stack slot accessed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   779
    // int comp_args_on_stack = VMRegImpl::reg2stack(max_arg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   780
    // Convert 4-byte stack slots to words.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   781
    comp_words_on_stack = round_to(comp_args_on_stack*4, wordSize)>>LogBytesPerWord;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   782
    // Round up to miminum stack alignment, in wordSize
489c9b5090e2 Initial load
duke
parents:
diff changeset
   783
    comp_words_on_stack = round_to(comp_words_on_stack, 2);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   784
    __ subptr(rsp, comp_words_on_stack * wordSize);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   785
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   786
489c9b5090e2 Initial load
duke
parents:
diff changeset
   787
  // Align the outgoing SP
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   788
  __ andptr(rsp, -(StackAlignmentInBytes));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   789
489c9b5090e2 Initial load
duke
parents:
diff changeset
   790
  // push the return address on the stack (note that pushing, rather
489c9b5090e2 Initial load
duke
parents:
diff changeset
   791
  // than storing it, yields the correct frame alignment for the callee)
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   792
  __ push(rax);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   793
489c9b5090e2 Initial load
duke
parents:
diff changeset
   794
  // Put saved SP in another register
489c9b5090e2 Initial load
duke
parents:
diff changeset
   795
  const Register saved_sp = rax;
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   796
  __ movptr(saved_sp, rdi);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   797
489c9b5090e2 Initial load
duke
parents:
diff changeset
   798
489c9b5090e2 Initial load
duke
parents:
diff changeset
   799
  // Will jump to the compiled code just as if compiled code was doing it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   800
  // Pre-load the register-jump target early, to schedule it better.
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   801
  __ movptr(rdi, Address(rbx, in_bytes(Method::from_compiled_offset())));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   802
489c9b5090e2 Initial load
duke
parents:
diff changeset
   803
  // Now generate the shuffle code.  Pick up all register args and move the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   804
  // rest through the floating point stack top.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   805
  for (int i = 0; i < total_args_passed; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   806
    if (sig_bt[i] == T_VOID) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   807
      // Longs and doubles are passed in native word order, but misaligned
489c9b5090e2 Initial load
duke
parents:
diff changeset
   808
      // in the 32-bit build.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   809
      assert(i > 0 && (sig_bt[i-1] == T_LONG || sig_bt[i-1] == T_DOUBLE), "missing half");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   810
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   811
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   812
489c9b5090e2 Initial load
duke
parents:
diff changeset
   813
    // Pick up 0, 1 or 2 words from SP+offset.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   814
489c9b5090e2 Initial load
duke
parents:
diff changeset
   815
    assert(!regs[i].second()->is_valid() || regs[i].first()->next() == regs[i].second(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   816
            "scrambled load targets?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   817
    // Load in argument order going down.
5419
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 4735
diff changeset
   818
    int ld_off = (total_args_passed - i) * Interpreter::stackElementSize;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   819
    // Point to interpreter value (vs. tag)
5419
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 4735
diff changeset
   820
    int next_off = ld_off - Interpreter::stackElementSize;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   821
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   822
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   823
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   824
    VMReg r_1 = regs[i].first();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   825
    VMReg r_2 = regs[i].second();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   826
    if (!r_1->is_valid()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   827
      assert(!r_2->is_valid(), "");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   828
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   829
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   830
    if (r_1->is_stack()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   831
      // Convert stack slot to an SP offset (+ wordSize to account for return address )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   832
      int st_off = regs[i].first()->reg2stack()*VMRegImpl::stack_slot_size + wordSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   833
489c9b5090e2 Initial load
duke
parents:
diff changeset
   834
      // We can use rsi as a temp here because compiled code doesn't need rsi as an input
489c9b5090e2 Initial load
duke
parents:
diff changeset
   835
      // and if we end up going thru a c2i because of a miss a reasonable value of rsi
489c9b5090e2 Initial load
duke
parents:
diff changeset
   836
      // we be generated.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   837
      if (!r_2->is_valid()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   838
        // __ fld_s(Address(saved_sp, ld_off));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   839
        // __ fstp_s(Address(rsp, st_off));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   840
        __ movl(rsi, Address(saved_sp, ld_off));
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   841
        __ movptr(Address(rsp, st_off), rsi);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   842
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   843
        // Interpreter local[n] == MSW, local[n+1] == LSW however locals
489c9b5090e2 Initial load
duke
parents:
diff changeset
   844
        // are accessed as negative so LSW is at LOW address
489c9b5090e2 Initial load
duke
parents:
diff changeset
   845
489c9b5090e2 Initial load
duke
parents:
diff changeset
   846
        // ld_off is MSW so get LSW
489c9b5090e2 Initial load
duke
parents:
diff changeset
   847
        // st_off is LSW (i.e. reg.first())
489c9b5090e2 Initial load
duke
parents:
diff changeset
   848
        // __ fld_d(Address(saved_sp, next_off));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   849
        // __ fstp_d(Address(rsp, st_off));
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   850
        //
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   851
        // We are using two VMRegs. This can be either T_OBJECT, T_ADDRESS, T_LONG, or T_DOUBLE
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   852
        // the interpreter allocates two slots but only uses one for thr T_LONG or T_DOUBLE case
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   853
        // So we must adjust where to pick up the data to match the interpreter.
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   854
        //
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   855
        // Interpreter local[n] == MSW, local[n+1] == LSW however locals
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   856
        // are accessed as negative so LSW is at LOW address
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   857
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   858
        // ld_off is MSW so get LSW
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   859
        const int offset = (NOT_LP64(true ||) sig_bt[i]==T_LONG||sig_bt[i]==T_DOUBLE)?
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   860
                           next_off : ld_off;
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   861
        __ movptr(rsi, Address(saved_sp, offset));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   862
        __ movptr(Address(rsp, st_off), rsi);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   863
#ifndef _LP64
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   864
        __ movptr(rsi, Address(saved_sp, ld_off));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   865
        __ movptr(Address(rsp, st_off + wordSize), rsi);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   866
#endif // _LP64
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   867
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   868
    } else if (r_1->is_Register()) {  // Register argument
489c9b5090e2 Initial load
duke
parents:
diff changeset
   869
      Register r = r_1->as_Register();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   870
      assert(r != rax, "must be different");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   871
      if (r_2->is_valid()) {
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   872
        //
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   873
        // We are using two VMRegs. This can be either T_OBJECT, T_ADDRESS, T_LONG, or T_DOUBLE
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   874
        // the interpreter allocates two slots but only uses one for thr T_LONG or T_DOUBLE case
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   875
        // So we must adjust where to pick up the data to match the interpreter.
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   876
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   877
        const int offset = (NOT_LP64(true ||) sig_bt[i]==T_LONG||sig_bt[i]==T_DOUBLE)?
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   878
                           next_off : ld_off;
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   879
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   880
        // this can be a misaligned move
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   881
        __ movptr(r, Address(saved_sp, offset));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   882
#ifndef _LP64
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   883
        assert(r_2->as_Register() != rax, "need another temporary register");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   884
        // Remember r_1 is low address (and LSB on x86)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   885
        // So r_2 gets loaded from high address regardless of the platform
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   886
        __ movptr(r_2->as_Register(), Address(saved_sp, ld_off));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   887
#endif // _LP64
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   888
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   889
        __ movl(r, Address(saved_sp, ld_off));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   890
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   891
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   892
      assert(r_1->is_XMMRegister(), "");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   893
      if (!r_2->is_valid()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   894
        __ movflt(r_1->as_XMMRegister(), Address(saved_sp, ld_off));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   895
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   896
        move_i2c_double(masm, r_1->as_XMMRegister(), saved_sp, ld_off);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   897
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   898
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   899
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   900
489c9b5090e2 Initial load
duke
parents:
diff changeset
   901
  // 6243940 We might end up in handle_wrong_method if
489c9b5090e2 Initial load
duke
parents:
diff changeset
   902
  // the callee is deoptimized as we race thru here. If that
489c9b5090e2 Initial load
duke
parents:
diff changeset
   903
  // happens we don't want to take a safepoint because the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   904
  // caller frame will look interpreted and arguments are now
489c9b5090e2 Initial load
duke
parents:
diff changeset
   905
  // "compiled" so it is much better to make this transition
489c9b5090e2 Initial load
duke
parents:
diff changeset
   906
  // invisible to the stack walking code. Unfortunately if
489c9b5090e2 Initial load
duke
parents:
diff changeset
   907
  // we try and find the callee by normal means a safepoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
   908
  // is possible. So we stash the desired callee in the thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   909
  // and the vm will find there should this case occur.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   910
489c9b5090e2 Initial load
duke
parents:
diff changeset
   911
  __ get_thread(rax);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   912
  __ movptr(Address(rax, JavaThread::callee_target_offset()), rbx);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   913
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   914
  // move Method* to rax, in case we end up in an c2i adapter.
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   915
  // the c2i adapters expect Method* in rax, (c2) because c2's
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   916
  // resolve stubs return the result (the method) in rax,.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   917
  // I'd love to fix this.
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   918
  __ mov(rax, rbx);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   919
489c9b5090e2 Initial load
duke
parents:
diff changeset
   920
  __ jmp(rdi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   921
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   922
489c9b5090e2 Initial load
duke
parents:
diff changeset
   923
// ---------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   924
AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   925
                                                            int total_args_passed,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   926
                                                            int comp_args_on_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   927
                                                            const BasicType *sig_bt,
4735
3d4e4ec0df67 6911204: generated adapters with large signatures can fill up the code cache
never
parents: 3681
diff changeset
   928
                                                            const VMRegPair *regs,
3d4e4ec0df67 6911204: generated adapters with large signatures can fill up the code cache
never
parents: 3681
diff changeset
   929
                                                            AdapterFingerPrint* fingerprint) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   930
  address i2c_entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   931
489c9b5090e2 Initial load
duke
parents:
diff changeset
   932
  gen_i2c_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   933
489c9b5090e2 Initial load
duke
parents:
diff changeset
   934
  // -------------------------------------------------------------------------
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   935
  // Generate a C2I adapter.  On entry we know rbx, holds the Method* during calls
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   936
  // to the interpreter.  The args start out packed in the compiled layout.  They
489c9b5090e2 Initial load
duke
parents:
diff changeset
   937
  // need to be unpacked into the interpreter layout.  This will almost always
489c9b5090e2 Initial load
duke
parents:
diff changeset
   938
  // require some stack space.  We grow the current (compiled) stack, then repack
489c9b5090e2 Initial load
duke
parents:
diff changeset
   939
  // the args.  We  finally end in a jump to the generic interpreter entry point.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   940
  // On exit from the interpreter, the interpreter will restore our SP (lest the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   941
  // compiled code, which relys solely on SP and not EBP, get sick).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   942
489c9b5090e2 Initial load
duke
parents:
diff changeset
   943
  address c2i_unverified_entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   944
  Label skip_fixup;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   945
489c9b5090e2 Initial load
duke
parents:
diff changeset
   946
  Register holder = rax;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   947
  Register receiver = rcx;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   948
  Register temp = rbx;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   949
489c9b5090e2 Initial load
duke
parents:
diff changeset
   950
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   951
489c9b5090e2 Initial load
duke
parents:
diff changeset
   952
    Label missed;
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
   953
    __ movptr(temp, Address(receiver, oopDesc::klass_offset_in_bytes()));
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   954
    __ cmpptr(temp, Address(holder, CompiledICHolder::holder_klass_offset()));
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   955
    __ movptr(rbx, Address(holder, CompiledICHolder::holder_method_offset()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   956
    __ jcc(Assembler::notEqual, missed);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   957
    // Method might have been compiled since the call site was patched to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   958
    // interpreted if that is the case treat it as a miss so we can get
489c9b5090e2 Initial load
duke
parents:
diff changeset
   959
    // the call site corrected.
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   960
    __ cmpptr(Address(rbx, in_bytes(Method::code_offset())), (int32_t)NULL_WORD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   961
    __ jcc(Assembler::equal, skip_fixup);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   962
489c9b5090e2 Initial load
duke
parents:
diff changeset
   963
    __ bind(missed);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   964
    __ jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   965
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   966
489c9b5090e2 Initial load
duke
parents:
diff changeset
   967
  address c2i_entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   968
489c9b5090e2 Initial load
duke
parents:
diff changeset
   969
  gen_c2i_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs, skip_fixup);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   970
489c9b5090e2 Initial load
duke
parents:
diff changeset
   971
  __ flush();
4735
3d4e4ec0df67 6911204: generated adapters with large signatures can fill up the code cache
never
parents: 3681
diff changeset
   972
  return AdapterHandlerLibrary::new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   973
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   974
489c9b5090e2 Initial load
duke
parents:
diff changeset
   975
int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   976
                                         VMRegPair *regs,
22832
03720a5b7595 8024344: PPC64 (part 112): C argument in register AND stack slot.
goetz
parents: 16624
diff changeset
   977
                                         VMRegPair *regs2,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   978
                                         int total_args_passed) {
22832
03720a5b7595 8024344: PPC64 (part 112): C argument in register AND stack slot.
goetz
parents: 16624
diff changeset
   979
  assert(regs2 == NULL, "not needed on x86");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   980
// We return the amount of VMRegImpl stack slots we need to reserve for all
489c9b5090e2 Initial load
duke
parents:
diff changeset
   981
// the arguments NOT counting out_preserve_stack_slots.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   982
489c9b5090e2 Initial load
duke
parents:
diff changeset
   983
  uint    stack = 0;        // All arguments on stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
   984
489c9b5090e2 Initial load
duke
parents:
diff changeset
   985
  for( int i = 0; i < total_args_passed; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   986
    // From the type and the argument number (count) compute the location
489c9b5090e2 Initial load
duke
parents:
diff changeset
   987
    switch( sig_bt[i] ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   988
    case T_BOOLEAN:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   989
    case T_CHAR:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   990
    case T_FLOAT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   991
    case T_BYTE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   992
    case T_SHORT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   993
    case T_INT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   994
    case T_OBJECT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   995
    case T_ARRAY:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   996
    case T_ADDRESS:
13742
9180987e305d 7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents: 13728
diff changeset
   997
    case T_METADATA:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   998
      regs[i].set1(VMRegImpl::stack2reg(stack++));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   999
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1000
    case T_LONG:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1001
    case T_DOUBLE: // The stack numbering is reversed from Java
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1002
      // Since C arguments do not get reversed, the ordering for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1003
      // doubles on the stack must be opposite the Java convention
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1004
      assert(sig_bt[i+1] == T_VOID, "missing Half" );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1005
      regs[i].set2(VMRegImpl::stack2reg(stack));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1006
      stack += 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1007
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1008
    case T_VOID: regs[i].set_bad(); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1009
    default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1010
      ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1011
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1012
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1013
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1014
  return stack;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1015
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1016
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1017
// A simple move of integer like type
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1018
static void simple_move32(MacroAssembler* masm, VMRegPair src, VMRegPair dst) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1019
  if (src.first()->is_stack()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1020
    if (dst.first()->is_stack()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1021
      // stack to stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1022
      // __ ld(FP, reg2offset(src.first()) + STACK_BIAS, L5);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1023
      // __ st(L5, SP, reg2offset(dst.first()) + STACK_BIAS);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1024
      __ movl2ptr(rax, Address(rbp, reg2offset_in(src.first())));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1025
      __ movptr(Address(rsp, reg2offset_out(dst.first())), rax);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1026
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1027
      // stack to reg
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1028
      __ movl2ptr(dst.first()->as_Register(),  Address(rbp, reg2offset_in(src.first())));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1029
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1030
  } else if (dst.first()->is_stack()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1031
    // reg to stack
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1032
    // no need to sign extend on 64bit
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1033
    __ movptr(Address(rsp, reg2offset_out(dst.first())), src.first()->as_Register());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1034
  } else {
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1035
    if (dst.first() != src.first()) {
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1036
      __ mov(dst.first()->as_Register(), src.first()->as_Register());
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1037
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1038
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1039
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1040
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1041
// An oop arg. Must pass a handle not the oop itself
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1042
static void object_move(MacroAssembler* masm,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1043
                        OopMap* map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1044
                        int oop_handle_offset,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1045
                        int framesize_in_slots,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1046
                        VMRegPair src,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1047
                        VMRegPair dst,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1048
                        bool is_receiver,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1049
                        int* receiver_offset) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1050
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1051
  // Because of the calling conventions we know that src can be a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1052
  // register or a stack location. dst can only be a stack location.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1053
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1054
  assert(dst.first()->is_stack(), "must be stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1055
  // must pass a handle. First figure out the location we use as a handle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1056
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1057
  if (src.first()->is_stack()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1058
    // Oop is already on the stack as an argument
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1059
    Register rHandle = rax;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1060
    Label nil;
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1061
    __ xorptr(rHandle, rHandle);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1062
    __ cmpptr(Address(rbp, reg2offset_in(src.first())), (int32_t)NULL_WORD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1063
    __ jcc(Assembler::equal, nil);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1064
    __ lea(rHandle, Address(rbp, reg2offset_in(src.first())));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1065
    __ bind(nil);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1066
    __ movptr(Address(rsp, reg2offset_out(dst.first())), rHandle);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1067
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1068
    int offset_in_older_frame = src.first()->reg2stack() + SharedRuntime::out_preserve_stack_slots();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1069
    map->set_oop(VMRegImpl::stack2reg(offset_in_older_frame + framesize_in_slots));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1070
    if (is_receiver) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1071
      *receiver_offset = (offset_in_older_frame + framesize_in_slots) * VMRegImpl::stack_slot_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1072
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1073
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1074
    // Oop is in an a register we must store it to the space we reserve
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1075
    // on the stack for oop_handles
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1076
    const Register rOop = src.first()->as_Register();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1077
    const Register rHandle = rax;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1078
    int oop_slot = (rOop == rcx ? 0 : 1) * VMRegImpl::slots_per_word + oop_handle_offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1079
    int offset = oop_slot*VMRegImpl::stack_slot_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1080
    Label skip;
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1081
    __ movptr(Address(rsp, offset), rOop);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1082
    map->set_oop(VMRegImpl::stack2reg(oop_slot));
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1083
    __ xorptr(rHandle, rHandle);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1084
    __ cmpptr(rOop, (int32_t)NULL_WORD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1085
    __ jcc(Assembler::equal, skip);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1086
    __ lea(rHandle, Address(rsp, offset));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1087
    __ bind(skip);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1088
    // Store the handle parameter
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1089
    __ movptr(Address(rsp, reg2offset_out(dst.first())), rHandle);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1090
    if (is_receiver) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1091
      *receiver_offset = offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1092
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1093
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1094
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1095
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1096
// A float arg may have to do float reg int reg conversion
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1097
static void float_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1098
  assert(!src.second()->is_valid() && !dst.second()->is_valid(), "bad float_move");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1099
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1100
  // Because of the calling convention we know that src is either a stack location
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1101
  // or an xmm register. dst can only be a stack location.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1102
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1103
  assert(dst.first()->is_stack() && ( src.first()->is_stack() || src.first()->is_XMMRegister()), "bad parameters");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1104
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1105
  if (src.first()->is_stack()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1106
    __ movl(rax, Address(rbp, reg2offset_in(src.first())));
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1107
    __ movptr(Address(rsp, reg2offset_out(dst.first())), rax);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1108
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1109
    // reg to stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1110
    __ movflt(Address(rsp, reg2offset_out(dst.first())), src.first()->as_XMMRegister());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1111
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1112
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1113
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1114
// A long move
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1115
static void long_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1116
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1117
  // The only legal possibility for a long_move VMRegPair is:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1118
  // 1: two stack slots (possibly unaligned)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1119
  // as neither the java  or C calling convention will use registers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1120
  // for longs.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1121
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1122
  if (src.first()->is_stack() && dst.first()->is_stack()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1123
    assert(src.second()->is_stack() && dst.second()->is_stack(), "must be all stack");
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1124
    __ movptr(rax, Address(rbp, reg2offset_in(src.first())));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1125
    NOT_LP64(__ movptr(rbx, Address(rbp, reg2offset_in(src.second()))));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1126
    __ movptr(Address(rsp, reg2offset_out(dst.first())), rax);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1127
    NOT_LP64(__ movptr(Address(rsp, reg2offset_out(dst.second())), rbx));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1128
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1129
    ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1130
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1131
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1132
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1133
// A double move
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1134
static void double_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1135
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1136
  // The only legal possibilities for a double_move VMRegPair are:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1137
  // The painful thing here is that like long_move a VMRegPair might be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1138
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1139
  // Because of the calling convention we know that src is either
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1140
  //   1: a single physical register (xmm registers only)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1141
  //   2: two stack slots (possibly unaligned)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1142
  // dst can only be a pair of stack slots.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1143
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1144
  assert(dst.first()->is_stack() && (src.first()->is_XMMRegister() || src.first()->is_stack()), "bad args");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1145
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1146
  if (src.first()->is_stack()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1147
    // source is all stack
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1148
    __ movptr(rax, Address(rbp, reg2offset_in(src.first())));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1149
    NOT_LP64(__ movptr(rbx, Address(rbp, reg2offset_in(src.second()))));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1150
    __ movptr(Address(rsp, reg2offset_out(dst.first())), rax);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1151
    NOT_LP64(__ movptr(Address(rsp, reg2offset_out(dst.second())), rbx));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1152
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1153
    // reg to stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1154
    // No worries about stack alignment
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1155
    __ movdbl(Address(rsp, reg2offset_out(dst.first())), src.first()->as_XMMRegister());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1156
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1157
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1158
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1159
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1160
void SharedRuntime::save_native_result(MacroAssembler *masm, BasicType ret_type, int frame_slots) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1161
  // We always ignore the frame_slots arg and just use the space just below frame pointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1162
  // which by this time is free to use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1163
  switch (ret_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1164
  case T_FLOAT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1165
    __ fstp_s(Address(rbp, -wordSize));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1166
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1167
  case T_DOUBLE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1168
    __ fstp_d(Address(rbp, -2*wordSize));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1169
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1170
  case T_VOID:  break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1171
  case T_LONG:
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1172
    __ movptr(Address(rbp, -wordSize), rax);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1173
    NOT_LP64(__ movptr(Address(rbp, -2*wordSize), rdx));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1174
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1175
  default: {
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1176
    __ movptr(Address(rbp, -wordSize), rax);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1177
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1178
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1179
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1180
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1181
void SharedRuntime::restore_native_result(MacroAssembler *masm, BasicType ret_type, int frame_slots) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1182
  // We always ignore the frame_slots arg and just use the space just below frame pointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1183
  // which by this time is free to use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1184
  switch (ret_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1185
  case T_FLOAT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1186
    __ fld_s(Address(rbp, -wordSize));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1187
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1188
  case T_DOUBLE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1189
    __ fld_d(Address(rbp, -2*wordSize));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1190
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1191
  case T_LONG:
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1192
    __ movptr(rax, Address(rbp, -wordSize));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1193
    NOT_LP64(__ movptr(rdx, Address(rbp, -2*wordSize)));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1194
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1195
  case T_VOID:  break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1196
  default: {
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1197
    __ movptr(rax, Address(rbp, -wordSize));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1198
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1199
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1200
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1201
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1202
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1203
static void save_or_restore_arguments(MacroAssembler* masm,
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1204
                                      const int stack_slots,
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1205
                                      const int total_in_args,
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1206
                                      const int arg_save_area,
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1207
                                      OopMap* map,
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1208
                                      VMRegPair* in_regs,
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1209
                                      BasicType* in_sig_bt) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1210
  // if map is non-NULL then the code should store the values,
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1211
  // otherwise it should load them.
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1212
  int handle_index = 0;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1213
  // Save down double word first
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1214
  for ( int i = 0; i < total_in_args; i++) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1215
    if (in_regs[i].first()->is_XMMRegister() && in_sig_bt[i] == T_DOUBLE) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1216
      int slot = handle_index * VMRegImpl::slots_per_word + arg_save_area;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1217
      int offset = slot * VMRegImpl::stack_slot_size;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1218
      handle_index += 2;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1219
      assert(handle_index <= stack_slots, "overflow");
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1220
      if (map != NULL) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1221
        __ movdbl(Address(rsp, offset), in_regs[i].first()->as_XMMRegister());
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1222
      } else {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1223
        __ movdbl(in_regs[i].first()->as_XMMRegister(), Address(rsp, offset));
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1224
      }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1225
    }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1226
    if (in_regs[i].first()->is_Register() && in_sig_bt[i] == T_LONG) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1227
      int slot = handle_index * VMRegImpl::slots_per_word + arg_save_area;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1228
      int offset = slot * VMRegImpl::stack_slot_size;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1229
      handle_index += 2;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1230
      assert(handle_index <= stack_slots, "overflow");
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1231
      if (map != NULL) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1232
        __ movl(Address(rsp, offset), in_regs[i].first()->as_Register());
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1233
        if (in_regs[i].second()->is_Register()) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1234
          __ movl(Address(rsp, offset + 4), in_regs[i].second()->as_Register());
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1235
        }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1236
      } else {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1237
        __ movl(in_regs[i].first()->as_Register(), Address(rsp, offset));
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1238
        if (in_regs[i].second()->is_Register()) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1239
          __ movl(in_regs[i].second()->as_Register(), Address(rsp, offset + 4));
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1240
        }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1241
      }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1242
    }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1243
  }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1244
  // Save or restore single word registers
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1245
  for ( int i = 0; i < total_in_args; i++) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1246
    if (in_regs[i].first()->is_Register()) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1247
      int slot = handle_index++ * VMRegImpl::slots_per_word + arg_save_area;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1248
      int offset = slot * VMRegImpl::stack_slot_size;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1249
      assert(handle_index <= stack_slots, "overflow");
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1250
      if (in_sig_bt[i] == T_ARRAY && map != NULL) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1251
        map->set_oop(VMRegImpl::stack2reg(slot));;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1252
      }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1253
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1254
      // Value is in an input register pass we must flush it to the stack
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1255
      const Register reg = in_regs[i].first()->as_Register();
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1256
      switch (in_sig_bt[i]) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1257
        case T_ARRAY:
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1258
          if (map != NULL) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1259
            __ movptr(Address(rsp, offset), reg);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1260
          } else {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1261
            __ movptr(reg, Address(rsp, offset));
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1262
          }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1263
          break;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1264
        case T_BOOLEAN:
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1265
        case T_CHAR:
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1266
        case T_BYTE:
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1267
        case T_SHORT:
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1268
        case T_INT:
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1269
          if (map != NULL) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1270
            __ movl(Address(rsp, offset), reg);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1271
          } else {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1272
            __ movl(reg, Address(rsp, offset));
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1273
          }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1274
          break;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1275
        case T_OBJECT:
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1276
        default: ShouldNotReachHere();
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1277
      }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1278
    } else if (in_regs[i].first()->is_XMMRegister()) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1279
      if (in_sig_bt[i] == T_FLOAT) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1280
        int slot = handle_index++ * VMRegImpl::slots_per_word + arg_save_area;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1281
        int offset = slot * VMRegImpl::stack_slot_size;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1282
        assert(handle_index <= stack_slots, "overflow");
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1283
        if (map != NULL) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1284
          __ movflt(Address(rsp, offset), in_regs[i].first()->as_XMMRegister());
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1285
        } else {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1286
          __ movflt(in_regs[i].first()->as_XMMRegister(), Address(rsp, offset));
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1287
        }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1288
      }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1289
    } else if (in_regs[i].first()->is_stack()) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1290
      if (in_sig_bt[i] == T_ARRAY && map != NULL) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1291
        int offset_in_older_frame = in_regs[i].first()->reg2stack() + SharedRuntime::out_preserve_stack_slots();
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1292
        map->set_oop(VMRegImpl::stack2reg(offset_in_older_frame + stack_slots));
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1293
      }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1294
    }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1295
  }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1296
}
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1297
35492
c8c0273e6b91 8146690: Make all classes in GC follow the naming convention.
david
parents: 35214
diff changeset
  1298
// Check GCLocker::needs_gc and enter the runtime if it's true.  This
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1299
// keeps a new JNI critical region from starting until a GC has been
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1300
// forced.  Save down any oops in registers and describe them in an
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1301
// OopMap.
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1302
static void check_needs_gc_for_critical_native(MacroAssembler* masm,
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1303
                                               Register thread,
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1304
                                               int stack_slots,
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1305
                                               int total_c_args,
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1306
                                               int total_in_args,
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1307
                                               int arg_save_area,
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1308
                                               OopMapSet* oop_maps,
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1309
                                               VMRegPair* in_regs,
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1310
                                               BasicType* in_sig_bt) {
35492
c8c0273e6b91 8146690: Make all classes in GC follow the naming convention.
david
parents: 35214
diff changeset
  1311
  __ block_comment("check GCLocker::needs_gc");
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1312
  Label cont;
35492
c8c0273e6b91 8146690: Make all classes in GC follow the naming convention.
david
parents: 35214
diff changeset
  1313
  __ cmp8(ExternalAddress((address)GCLocker::needs_gc_address()), false);
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1314
  __ jcc(Assembler::equal, cont);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1315
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1316
  // Save down any incoming oops and call into the runtime to halt for a GC
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1317
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1318
  OopMap* map = new OopMap(stack_slots * 2, 0 /* arg_slots*/);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1319
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1320
  save_or_restore_arguments(masm, stack_slots, total_in_args,
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1321
                            arg_save_area, map, in_regs, in_sig_bt);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1322
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1323
  address the_pc = __ pc();
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1324
  oop_maps->add_gc_map( __ offset(), map);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1325
  __ set_last_Java_frame(thread, rsp, noreg, the_pc);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1326
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1327
  __ block_comment("block_for_jni_critical");
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1328
  __ push(thread);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1329
  __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::block_for_jni_critical)));
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1330
  __ increment(rsp, wordSize);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1331
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1332
  __ get_thread(thread);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1333
  __ reset_last_Java_frame(thread, false, true);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1334
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1335
  save_or_restore_arguments(masm, stack_slots, total_in_args,
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1336
                            arg_save_area, NULL, in_regs, in_sig_bt);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1337
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1338
  __ bind(cont);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1339
#ifdef ASSERT
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1340
  if (StressCriticalJNINatives) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1341
    // Stress register saving
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1342
    OopMap* map = new OopMap(stack_slots * 2, 0 /* arg_slots*/);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1343
    save_or_restore_arguments(masm, stack_slots, total_in_args,
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1344
                              arg_save_area, map, in_regs, in_sig_bt);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1345
    // Destroy argument registers
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1346
    for (int i = 0; i < total_in_args - 1; i++) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1347
      if (in_regs[i].first()->is_Register()) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1348
        const Register reg = in_regs[i].first()->as_Register();
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1349
        __ xorptr(reg, reg);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1350
      } else if (in_regs[i].first()->is_XMMRegister()) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1351
        __ xorpd(in_regs[i].first()->as_XMMRegister(), in_regs[i].first()->as_XMMRegister());
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1352
      } else if (in_regs[i].first()->is_FloatRegister()) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1353
        ShouldNotReachHere();
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1354
      } else if (in_regs[i].first()->is_stack()) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1355
        // Nothing to do
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1356
      } else {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1357
        ShouldNotReachHere();
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1358
      }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1359
      if (in_sig_bt[i] == T_LONG || in_sig_bt[i] == T_DOUBLE) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1360
        i++;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1361
      }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1362
    }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1363
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1364
    save_or_restore_arguments(masm, stack_slots, total_in_args,
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1365
                              arg_save_area, NULL, in_regs, in_sig_bt);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1366
  }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1367
#endif
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1368
}
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1369
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1370
// Unpack an array argument into a pointer to the body and the length
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1371
// if the array is non-null, otherwise pass 0 for both.
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1372
static void unpack_array_argument(MacroAssembler* masm, VMRegPair reg, BasicType in_elem_type, VMRegPair body_arg, VMRegPair length_arg) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1373
  Register tmp_reg = rax;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1374
  assert(!body_arg.first()->is_Register() || body_arg.first()->as_Register() != tmp_reg,
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1375
         "possible collision");
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1376
  assert(!length_arg.first()->is_Register() || length_arg.first()->as_Register() != tmp_reg,
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1377
         "possible collision");
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1378
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1379
  // Pass the length, ptr pair
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1380
  Label is_null, done;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1381
  VMRegPair tmp(tmp_reg->as_VMReg());
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1382
  if (reg.first()->is_stack()) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1383
    // Load the arg up from the stack
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1384
    simple_move32(masm, reg, tmp);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1385
    reg = tmp;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1386
  }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1387
  __ testptr(reg.first()->as_Register(), reg.first()->as_Register());
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1388
  __ jccb(Assembler::equal, is_null);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1389
  __ lea(tmp_reg, Address(reg.first()->as_Register(), arrayOopDesc::base_offset_in_bytes(in_elem_type)));
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1390
  simple_move32(masm, tmp, body_arg);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1391
  // load the length relative to the body.
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1392
  __ movl(tmp_reg, Address(tmp_reg, arrayOopDesc::length_offset_in_bytes() -
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1393
                           arrayOopDesc::base_offset_in_bytes(in_elem_type)));
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1394
  simple_move32(masm, tmp, length_arg);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1395
  __ jmpb(done);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1396
  __ bind(is_null);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1397
  // Pass zeros
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1398
  __ xorptr(tmp_reg, tmp_reg);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1399
  simple_move32(masm, tmp, body_arg);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1400
  simple_move32(masm, tmp, length_arg);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1401
  __ bind(done);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1402
}
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1403
13391
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1404
static void verify_oop_args(MacroAssembler* masm,
13881
a326d528f3e1 7196262: JSR 292: java/lang/invoke/PrivateInvokeTest.java fails on solaris-sparc
twisti
parents: 13742
diff changeset
  1405
                            methodHandle method,
13391
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1406
                            const BasicType* sig_bt,
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1407
                            const VMRegPair* regs) {
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1408
  Register temp_reg = rbx;  // not part of any compiled calling seq
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1409
  if (VerifyOops) {
13881
a326d528f3e1 7196262: JSR 292: java/lang/invoke/PrivateInvokeTest.java fails on solaris-sparc
twisti
parents: 13742
diff changeset
  1410
    for (int i = 0; i < method->size_of_parameters(); i++) {
13391
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1411
      if (sig_bt[i] == T_OBJECT ||
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1412
          sig_bt[i] == T_ARRAY) {
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1413
        VMReg r = regs[i].first();
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1414
        assert(r->is_valid(), "bad oop arg");
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1415
        if (r->is_stack()) {
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1416
          __ movptr(temp_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize));
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1417
          __ verify_oop(temp_reg);
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1418
        } else {
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1419
          __ verify_oop(r->as_Register());
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1420
        }
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1421
      }
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1422
    }
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1423
  }
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1424
}
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1425
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1426
static void gen_special_dispatch(MacroAssembler* masm,
13881
a326d528f3e1 7196262: JSR 292: java/lang/invoke/PrivateInvokeTest.java fails on solaris-sparc
twisti
parents: 13742
diff changeset
  1427
                                 methodHandle method,
13391
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1428
                                 const BasicType* sig_bt,
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1429
                                 const VMRegPair* regs) {
13881
a326d528f3e1 7196262: JSR 292: java/lang/invoke/PrivateInvokeTest.java fails on solaris-sparc
twisti
parents: 13742
diff changeset
  1430
  verify_oop_args(masm, method, sig_bt, regs);
a326d528f3e1 7196262: JSR 292: java/lang/invoke/PrivateInvokeTest.java fails on solaris-sparc
twisti
parents: 13742
diff changeset
  1431
  vmIntrinsics::ID iid = method->intrinsic_id();
13391
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1432
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1433
  // Now write the args into the outgoing interpreter space
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1434
  bool     has_receiver   = false;
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1435
  Register receiver_reg   = noreg;
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1436
  int      member_arg_pos = -1;
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1437
  Register member_reg     = noreg;
13881
a326d528f3e1 7196262: JSR 292: java/lang/invoke/PrivateInvokeTest.java fails on solaris-sparc
twisti
parents: 13742
diff changeset
  1438
  int      ref_kind       = MethodHandles::signature_polymorphic_intrinsic_ref_kind(iid);
13391
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1439
  if (ref_kind != 0) {
13881
a326d528f3e1 7196262: JSR 292: java/lang/invoke/PrivateInvokeTest.java fails on solaris-sparc
twisti
parents: 13742
diff changeset
  1440
    member_arg_pos = method->size_of_parameters() - 1;  // trailing MemberName argument
13391
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1441
    member_reg = rbx;  // known to be free at this point
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1442
    has_receiver = MethodHandles::ref_kind_has_receiver(ref_kind);
13881
a326d528f3e1 7196262: JSR 292: java/lang/invoke/PrivateInvokeTest.java fails on solaris-sparc
twisti
parents: 13742
diff changeset
  1443
  } else if (iid == vmIntrinsics::_invokeBasic) {
13391
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1444
    has_receiver = true;
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1445
  } else {
33105
294e48b4f704 8080775: Better argument formatting for assert() and friends
david
parents: 32727
diff changeset
  1446
    fatal("unexpected intrinsic id %d", iid);
13391
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1447
  }
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1448
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1449
  if (member_reg != noreg) {
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1450
    // Load the member_arg into register, if necessary.
13881
a326d528f3e1 7196262: JSR 292: java/lang/invoke/PrivateInvokeTest.java fails on solaris-sparc
twisti
parents: 13742
diff changeset
  1451
    SharedRuntime::check_member_name_argument_is_last_argument(method, sig_bt, regs);
13391
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1452
    VMReg r = regs[member_arg_pos].first();
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1453
    if (r->is_stack()) {
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1454
      __ movptr(member_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize));
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1455
    } else {
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1456
      // no data motion is needed
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1457
      member_reg = r->as_Register();
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1458
    }
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1459
  }
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1460
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1461
  if (has_receiver) {
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1462
    // Make sure the receiver is loaded into a register.
13881
a326d528f3e1 7196262: JSR 292: java/lang/invoke/PrivateInvokeTest.java fails on solaris-sparc
twisti
parents: 13742
diff changeset
  1463
    assert(method->size_of_parameters() > 0, "oob");
13391
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1464
    assert(sig_bt[0] == T_OBJECT, "receiver argument must be an object");
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1465
    VMReg r = regs[0].first();
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1466
    assert(r->is_valid(), "bad receiver arg");
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1467
    if (r->is_stack()) {
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1468
      // Porting note:  This assumes that compiled calling conventions always
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1469
      // pass the receiver oop in a register.  If this is not true on some
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1470
      // platform, pick a temp and load the receiver from stack.
13881
a326d528f3e1 7196262: JSR 292: java/lang/invoke/PrivateInvokeTest.java fails on solaris-sparc
twisti
parents: 13742
diff changeset
  1471
      fatal("receiver always in a register");
13391
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1472
      receiver_reg = rcx;  // known to be free at this point
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1473
      __ movptr(receiver_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize));
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1474
    } else {
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1475
      // no data motion is needed
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1476
      receiver_reg = r->as_Register();
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1477
    }
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1478
  }
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1479
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1480
  // Figure out which address we are really jumping to:
13881
a326d528f3e1 7196262: JSR 292: java/lang/invoke/PrivateInvokeTest.java fails on solaris-sparc
twisti
parents: 13742
diff changeset
  1481
  MethodHandles::generate_method_handle_dispatch(masm, iid,
13391
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1482
                                                 receiver_reg, member_reg, /*for_compiler_entry:*/ true);
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1483
}
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1484
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1485
// ---------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1486
// Generate a native wrapper for a given method.  The method takes arguments
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1487
// in the Java compiled code convention, marshals them to the native
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1488
// convention (handlizes oops, etc), transitions to native, makes the call,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1489
// returns to java state (possibly blocking), unhandlizes any result and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1490
// returns.
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1491
//
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1492
// Critical native functions are a shorthand for the use of
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1493
// GetPrimtiveArrayCritical and disallow the use of any other JNI
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1494
// functions.  The wrapper is expected to unpack the arguments before
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1495
// passing them to the callee and perform checks before and after the
35492
c8c0273e6b91 8146690: Make all classes in GC follow the naming convention.
david
parents: 35214
diff changeset
  1496
// native call to ensure that they GCLocker
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1497
// lock_critical/unlock_critical semantics are followed.  Some other
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1498
// parts of JNI setup are skipped like the tear down of the JNI handle
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1499
// block and the check for pending exceptions it's impossible for them
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1500
// to be thrown.
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1501
//
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1502
// They are roughly structured like this:
35492
c8c0273e6b91 8146690: Make all classes in GC follow the naming convention.
david
parents: 35214
diff changeset
  1503
//    if (GCLocker::needs_gc())
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1504
//      SharedRuntime::block_for_jni_critical();
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1505
//    tranistion to thread_in_native
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1506
//    unpack arrray arguments and call native entry point
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1507
//    check for safepoint in progress
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1508
//    check if any thread suspend flags are set
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1509
//      call into JVM and possible unlock the JNI critical
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1510
//      if a GC was suppressed while in the critical native.
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1511
//    transition back to thread_in_Java
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1512
//    return to caller
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1513
//
13391
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1514
nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
33593
60764a78fa5c 8140274: methodHandles and constantPoolHandles should be passed as const references
coleenp
parents: 33198
diff changeset
  1515
                                                const methodHandle& method,
8872
36680c58660e 7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents: 8315
diff changeset
  1516
                                                int compile_id,
13391
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1517
                                                BasicType* in_sig_bt,
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1518
                                                VMRegPair* in_regs,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1519
                                                BasicType ret_type) {
13391
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1520
  if (method->is_method_handle_intrinsic()) {
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1521
    vmIntrinsics::ID iid = method->intrinsic_id();
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1522
    intptr_t start = (intptr_t)__ pc();
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1523
    int vep_offset = ((intptr_t)__ pc()) - start;
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1524
    gen_special_dispatch(masm,
13881
a326d528f3e1 7196262: JSR 292: java/lang/invoke/PrivateInvokeTest.java fails on solaris-sparc
twisti
parents: 13742
diff changeset
  1525
                         method,
13391
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1526
                         in_sig_bt,
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1527
                         in_regs);
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1528
    int frame_complete = ((intptr_t)__ pc()) - start;  // not complete, period
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1529
    __ flush();
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1530
    int stack_slots = SharedRuntime::out_preserve_stack_slots();  // no out slots at all, actually
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1531
    return nmethod::new_native_nmethod(method,
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1532
                                       compile_id,
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1533
                                       masm->code(),
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1534
                                       vep_offset,
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1535
                                       frame_complete,
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1536
                                       stack_slots / VMRegImpl::slots_per_word,
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1537
                                       in_ByteSize(-1),
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1538
                                       in_ByteSize(-1),
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1539
                                       (OopMapSet*)NULL);
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1540
  }
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1541
  bool is_critical_native = true;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1542
  address native_func = method->critical_native_function();
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1543
  if (native_func == NULL) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1544
    native_func = method->native_function();
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1545
    is_critical_native = false;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1546
  }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1547
  assert(native_func != NULL, "must have function");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1548
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1549
  // An OopMap for lock (and class if static)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1550
  OopMapSet *oop_maps = new OopMapSet();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1551
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1552
  // We have received a description of where all the java arg are located
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1553
  // on entry to the wrapper. We need to convert these args to where
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1554
  // the jni function will expect them. To figure out where they go
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1555
  // we convert the java signature to a C signature by inserting
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1556
  // the hidden arguments as arg[0] and possibly arg[1] (static method)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1557
13881
a326d528f3e1 7196262: JSR 292: java/lang/invoke/PrivateInvokeTest.java fails on solaris-sparc
twisti
parents: 13742
diff changeset
  1558
  const int total_in_args = method->size_of_parameters();
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1559
  int total_c_args = total_in_args;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1560
  if (!is_critical_native) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1561
    total_c_args += 1;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1562
    if (method->is_static()) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1563
      total_c_args++;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1564
    }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1565
  } else {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1566
    for (int i = 0; i < total_in_args; i++) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1567
      if (in_sig_bt[i] == T_ARRAY) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1568
        total_c_args++;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1569
      }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1570
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1571
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1572
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1573
  BasicType* out_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_c_args);
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1574
  VMRegPair* out_regs   = NEW_RESOURCE_ARRAY(VMRegPair, total_c_args);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1575
  BasicType* in_elem_bt = NULL;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1576
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1577
  int argc = 0;
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1578
  if (!is_critical_native) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1579
    out_sig_bt[argc++] = T_ADDRESS;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1580
    if (method->is_static()) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1581
      out_sig_bt[argc++] = T_OBJECT;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1582
    }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1583
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1584
    for (int i = 0; i < total_in_args ; i++ ) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1585
      out_sig_bt[argc++] = in_sig_bt[i];
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1586
    }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1587
  } else {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1588
    Thread* THREAD = Thread::current();
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1589
    in_elem_bt = NEW_RESOURCE_ARRAY(BasicType, total_in_args);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1590
    SignatureStream ss(method->signature());
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1591
    for (int i = 0; i < total_in_args ; i++ ) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1592
      if (in_sig_bt[i] == T_ARRAY) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1593
        // Arrays are passed as int, elem* pair
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1594
        out_sig_bt[argc++] = T_INT;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1595
        out_sig_bt[argc++] = T_ADDRESS;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1596
        Symbol* atype = ss.as_symbol(CHECK_NULL);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1597
        const char* at = atype->as_C_string();
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1598
        if (strlen(at) == 2) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1599
          assert(at[0] == '[', "must be");
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1600
          switch (at[1]) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1601
            case 'B': in_elem_bt[i]  = T_BYTE; break;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1602
            case 'C': in_elem_bt[i]  = T_CHAR; break;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1603
            case 'D': in_elem_bt[i]  = T_DOUBLE; break;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1604
            case 'F': in_elem_bt[i]  = T_FLOAT; break;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1605
            case 'I': in_elem_bt[i]  = T_INT; break;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1606
            case 'J': in_elem_bt[i]  = T_LONG; break;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1607
            case 'S': in_elem_bt[i]  = T_SHORT; break;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1608
            case 'Z': in_elem_bt[i]  = T_BOOLEAN; break;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1609
            default: ShouldNotReachHere();
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1610
          }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1611
        }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1612
      } else {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1613
        out_sig_bt[argc++] = in_sig_bt[i];
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1614
        in_elem_bt[i] = T_VOID;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1615
      }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1616
      if (in_sig_bt[i] != T_VOID) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1617
        assert(in_sig_bt[i] == ss.type(), "must match");
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1618
        ss.next();
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1619
      }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1620
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1621
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1622
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1623
  // Now figure out where the args must be stored and how much stack space
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1624
  // they require.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1625
  int out_arg_slots;
22832
03720a5b7595 8024344: PPC64 (part 112): C argument in register AND stack slot.
goetz
parents: 16624
diff changeset
  1626
  out_arg_slots = c_calling_convention(out_sig_bt, out_regs, NULL, total_c_args);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1627
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1628
  // Compute framesize for the wrapper.  We need to handlize all oops in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1629
  // registers a max of 2 on x86.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1630
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1631
  // Calculate the total number of stack slots we will need.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1632
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1633
  // First count the abi requirement plus all of the outgoing args
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1634
  int stack_slots = SharedRuntime::out_preserve_stack_slots() + out_arg_slots;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1635
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1636
  // Now the space for the inbound oop handle area
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1637
  int total_save_slots = 2 * VMRegImpl::slots_per_word; // 2 arguments passed in registers
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1638
  if (is_critical_native) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1639
    // Critical natives may have to call out so they need a save area
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1640
    // for register arguments.
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1641
    int double_slots = 0;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1642
    int single_slots = 0;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1643
    for ( int i = 0; i < total_in_args; i++) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1644
      if (in_regs[i].first()->is_Register()) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1645
        const Register reg = in_regs[i].first()->as_Register();
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1646
        switch (in_sig_bt[i]) {
13391
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11637
diff changeset
  1647
          case T_ARRAY:  // critical array (uses 2 slots on LP64)
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1648
          case T_BOOLEAN:
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1649
          case T_BYTE:
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1650
          case T_SHORT:
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1651
          case T_CHAR:
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1652
          case T_INT:  single_slots++; break;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1653
          case T_LONG: double_slots++; break;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1654
          default:  ShouldNotReachHere();
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1655
        }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1656
      } else if (in_regs[i].first()->is_XMMRegister()) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1657
        switch (in_sig_bt[i]) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1658
          case T_FLOAT:  single_slots++; break;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1659
          case T_DOUBLE: double_slots++; break;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1660
          default:  ShouldNotReachHere();
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1661
        }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1662
      } else if (in_regs[i].first()->is_FloatRegister()) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1663
        ShouldNotReachHere();
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1664
      }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1665
    }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1666
    total_save_slots = double_slots * 2 + single_slots;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1667
    // align the save area
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1668
    if (double_slots != 0) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1669
      stack_slots = round_to(stack_slots, 2);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1670
    }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1671
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1672
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1673
  int oop_handle_offset = stack_slots;
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1674
  stack_slots += total_save_slots;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1675
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1676
  // Now any space we need for handlizing a klass if static method
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1677
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1678
  int klass_slot_offset = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1679
  int klass_offset = -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1680
  int lock_slot_offset = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1681
  bool is_static = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1682
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1683
  if (method->is_static()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1684
    klass_slot_offset = stack_slots;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1685
    stack_slots += VMRegImpl::slots_per_word;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1686
    klass_offset = klass_slot_offset * VMRegImpl::stack_slot_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1687
    is_static = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1688
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1689
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1690
  // Plus a lock if needed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1691
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1692
  if (method->is_synchronized()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1693
    lock_slot_offset = stack_slots;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1694
    stack_slots += VMRegImpl::slots_per_word;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1695
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1696
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1697
  // Now a place (+2) to save return values or temp during shuffling
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1698
  // + 2 for return address (which we own) and saved rbp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1699
  stack_slots += 4;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1700
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1701
  // Ok The space we have allocated will look like:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1702
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1703
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1704
  // FP-> |                     |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1705
  //      |---------------------|
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1706
  //      | 2 slots for moves   |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1707
  //      |---------------------|
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1708
  //      | lock box (if sync)  |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1709
  //      |---------------------| <- lock_slot_offset  (-lock_slot_rbp_offset)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1710
  //      | klass (if static)   |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1711
  //      |---------------------| <- klass_slot_offset
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1712
  //      | oopHandle area      |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1713
  //      |---------------------| <- oop_handle_offset (a max of 2 registers)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1714
  //      | outbound memory     |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1715
  //      | based arguments     |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1716
  //      |                     |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1717
  //      |---------------------|
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1718
  //      |                     |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1719
  // SP-> | out_preserved_slots |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1720
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1721
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1722
  // ****************************************************************************
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1723
  // WARNING - on Windows Java Natives use pascal calling convention and pop the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1724
  // arguments off of the stack after the jni call. Before the call we can use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1725
  // instructions that are SP relative. After the jni call we switch to FP
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1726
  // relative instructions instead of re-adjusting the stack on windows.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1727
  // ****************************************************************************
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1728
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1729
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1730
  // Now compute actual number of stack words we need rounding to make
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1731
  // stack properly aligned.
1900
68ea5d5fab8b 6792301: StackAlignmentInBytes not honored for compiled native methods
xlu
parents: 1888
diff changeset
  1732
  stack_slots = round_to(stack_slots, StackAlignmentInSlots);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1733
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1734
  int stack_size = stack_slots * VMRegImpl::stack_slot_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1735
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1736
  intptr_t start = (intptr_t)__ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1737
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1738
  // First thing make an ic check to see if we should even be here
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1739
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1740
  // We are free to use all registers as temps without saving them and
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1741
  // restoring them except rbp. rbp is the only callee save register
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1742
  // as far as the interpreter and the compiler(s) are concerned.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1743
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1744
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1745
  const Register ic_reg = rax;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1746
  const Register receiver = rcx;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1747
  Label hit;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1748
  Label exception_pending;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1749
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1750
  __ verify_oop(receiver);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1751
  __ cmpptr(ic_reg, Address(receiver, oopDesc::klass_offset_in_bytes()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1752
  __ jcc(Assembler::equal, hit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1753
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1754
  __ jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1755
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1756
  // verified entry must be aligned for code patching.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1757
  // and the first 5 bytes must be in the same cache line
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1758
  // if we align at 8 then we will be sure 5 bytes are in the same line
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1759
  __ align(8);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1760
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1761
  __ bind(hit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1762
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1763
  int vep_offset = ((intptr_t)__ pc()) - start;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1764
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1765
#ifdef COMPILER1
36079
692adc3fa1b5 6378256: Performance problem with System.identityHashCode in client compiler
thartmann
parents: 35757
diff changeset
  1766
  // For Object.hashCode, System.identityHashCode try to pull hashCode from object header if available.
692adc3fa1b5 6378256: Performance problem with System.identityHashCode in client compiler
thartmann
parents: 35757
diff changeset
  1767
  if ((InlineObjectHash && method->intrinsic_id() == vmIntrinsics::_hashCode) || (method->intrinsic_id() == vmIntrinsics::_identityHashCode)) {
692adc3fa1b5 6378256: Performance problem with System.identityHashCode in client compiler
thartmann
parents: 35757
diff changeset
  1768
    inline_check_hashcode_from_object_header(masm, method, rcx /*obj_reg*/, rax /*result*/);
692adc3fa1b5 6378256: Performance problem with System.identityHashCode in client compiler
thartmann
parents: 35757
diff changeset
  1769
   }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1770
#endif // COMPILER1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1771
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1772
  // The instruction at the verified entry point must be 5 bytes or longer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1773
  // because it can be patched on the fly by make_non_entrant. The stack bang
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1774
  // instruction fits that requirement.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1775
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1776
  // Generate stack overflow check
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1777
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1778
  if (UseStackBanging) {
35201
996db89f378e 8139864: Improve handling of stack protection zones.
goetz
parents: 34203
diff changeset
  1779
    __ bang_stack_with_offset((int)JavaThread::stack_shadow_zone_size());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1780
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1781
    // need a 5 byte instruction to allow MT safe patching to non-entrant
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1782
    __ fat_nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1783
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1784
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1785
  // Generate a new frame for the wrapper.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1786
  __ enter();
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1787
  // -2 because return address is already present and so is saved rbp
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1788
  __ subptr(rsp, stack_size - 2*wordSize);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1789
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1790
  // Frame is now completed as far as size and linkage.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1791
  int frame_complete = ((intptr_t)__ pc()) - start;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1792
23491
f690330b10b9 8031320: Use Intel RTM instructions for locks
kvn
parents: 22872
diff changeset
  1793
  if (UseRTMLocking) {
f690330b10b9 8031320: Use Intel RTM instructions for locks
kvn
parents: 22872
diff changeset
  1794
    // Abort RTM transaction before calling JNI
f690330b10b9 8031320: Use Intel RTM instructions for locks
kvn
parents: 22872
diff changeset
  1795
    // because critical section will be large and will be
f690330b10b9 8031320: Use Intel RTM instructions for locks
kvn
parents: 22872
diff changeset
  1796
    // aborted anyway. Also nmethod could be deoptimized.
f690330b10b9 8031320: Use Intel RTM instructions for locks
kvn
parents: 22872
diff changeset
  1797
    __ xabort(0);
f690330b10b9 8031320: Use Intel RTM instructions for locks
kvn
parents: 22872
diff changeset
  1798
  }
f690330b10b9 8031320: Use Intel RTM instructions for locks
kvn
parents: 22872
diff changeset
  1799
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1800
  // Calculate the difference between rsp and rbp,. We need to know it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1801
  // after the native call because on windows Java Natives will pop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1802
  // the arguments and it is painful to do rsp relative addressing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1803
  // in a platform independent way. So after the call we switch to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1804
  // rbp, relative addressing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1805
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1806
  int fp_adjustment = stack_size - 2*wordSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1807
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1808
#ifdef COMPILER2
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1809
  // C2 may leave the stack dirty if not in SSE2+ mode
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1810
  if (UseSSE >= 2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1811
    __ verify_FPU(0, "c2i transition should have clean FPU stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1812
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1813
    __ empty_FPU_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1814
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1815
#endif /* COMPILER2 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1816
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1817
  // Compute the rbp, offset for any slots used after the jni call
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1818
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1819
  int lock_slot_rbp_offset = (lock_slot_offset*VMRegImpl::stack_slot_size) - fp_adjustment;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1820
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1821
  // We use rdi as a thread pointer because it is callee save and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1822
  // if we load it once it is usable thru the entire wrapper
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1823
  const Register thread = rdi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1824
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1825
  // We use rsi as the oop handle for the receiver/klass
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1826
  // It is callee save so it survives the call to native
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1827
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1828
  const Register oop_handle_reg = rsi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1829
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1830
  __ get_thread(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1831
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1832
  if (is_critical_native) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1833
    check_needs_gc_for_critical_native(masm, thread, stack_slots, total_c_args, total_in_args,
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1834
                                       oop_handle_offset, oop_maps, in_regs, in_sig_bt);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1835
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1836
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1837
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1838
  // We immediately shuffle the arguments so that any vm call we have to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1839
  // make from here on out (sync slow path, jvmti, etc.) we will have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1840
  // captured the oops from our caller and have a valid oopMap for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1841
  // them.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1842
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1843
  // -----------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1844
  // The Grand Shuffle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1845
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1846
  // Natives require 1 or 2 extra arguments over the normal ones: the JNIEnv*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1847
  // and, if static, the class mirror instead of a receiver.  This pretty much
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1848
  // guarantees that register layout will not match (and x86 doesn't use reg
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1849
  // parms though amd does).  Since the native abi doesn't use register args
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1850
  // and the java conventions does we don't have to worry about collisions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1851
  // All of our moved are reg->stack or stack->stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1852
  // We ignore the extra arguments during the shuffle and handle them at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1853
  // last moment. The shuffle is described by the two calling convention
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1854
  // vectors we have in our possession. We simply walk the java vector to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1855
  // get the source locations and the c vector to get the destinations.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1856
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1857
  int c_arg = is_critical_native ? 0 : (method->is_static() ? 2 : 1 );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1858
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1859
  // Record rsp-based slot for receiver on stack for non-static methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1860
  int receiver_offset = -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1861
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1862
  // This is a trick. We double the stack slots so we can claim
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1863
  // the oops in the caller's frame. Since we are sure to have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1864
  // more args than the caller doubling is enough to make
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1865
  // sure we can capture all the incoming oop args from the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1866
  // caller.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1867
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1868
  OopMap* map = new OopMap(stack_slots * 2, 0 /* arg_slots*/);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1869
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1870
  // Mark location of rbp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1871
  // map->set_callee_saved(VMRegImpl::stack2reg( stack_slots - 2), stack_slots * 2, 0, rbp->as_VMReg());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1872
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1873
  // We know that we only have args in at most two integer registers (rcx, rdx). So rax, rbx
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1874
  // Are free to temporaries if we have to do  stack to steck moves.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1875
  // All inbound args are referenced based on rbp, and all outbound args via rsp.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1876
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1877
  for (int i = 0; i < total_in_args ; i++, c_arg++ ) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1878
    switch (in_sig_bt[i]) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1879
      case T_ARRAY:
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1880
        if (is_critical_native) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1881
          unpack_array_argument(masm, in_regs[i], in_elem_bt[i], out_regs[c_arg + 1], out_regs[c_arg]);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1882
          c_arg++;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1883
          break;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1884
        }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1885
      case T_OBJECT:
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1886
        assert(!is_critical_native, "no oop arguments");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1887
        object_move(masm, map, oop_handle_offset, stack_slots, in_regs[i], out_regs[c_arg],
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1888
                    ((i == 0) && (!is_static)),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1889
                    &receiver_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1890
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1891
      case T_VOID:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1892
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1893
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1894
      case T_FLOAT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1895
        float_move(masm, in_regs[i], out_regs[c_arg]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1896
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1897
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1898
      case T_DOUBLE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1899
        assert( i + 1 < total_in_args &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1900
                in_sig_bt[i + 1] == T_VOID &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1901
                out_sig_bt[c_arg+1] == T_VOID, "bad arg list");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1902
        double_move(masm, in_regs[i], out_regs[c_arg]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1903
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1904
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1905
      case T_LONG :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1906
        long_move(masm, in_regs[i], out_regs[c_arg]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1907
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1908
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1909
      case T_ADDRESS: assert(false, "found T_ADDRESS in java args");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1910
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1911
      default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1912
        simple_move32(masm, in_regs[i], out_regs[c_arg]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1913
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1914
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1915
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1916
  // Pre-load a static method's oop into rsi.  Used both by locking code and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1917
  // the normal JNI call code.
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1918
  if (method->is_static() && !is_critical_native) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1919
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1920
    //  load opp into a register
14391
df0a1573d5bd 8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents: 13883
diff changeset
  1921
    __ movoop(oop_handle_reg, JNIHandles::make_local(method->method_holder()->java_mirror()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1922
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1923
    // Now handlize the static class mirror it's known not-null.
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1924
    __ movptr(Address(rsp, klass_offset), oop_handle_reg);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1925
    map->set_oop(VMRegImpl::stack2reg(klass_slot_offset));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1926
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1927
    // Now get the handle
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1928
    __ lea(oop_handle_reg, Address(rsp, klass_offset));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1929
    // store the klass handle as second argument
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1930
    __ movptr(Address(rsp, wordSize), oop_handle_reg);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1931
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1932
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1933
  // Change state to native (we save the return address in the thread, since it might not
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1934
  // be pushed on the stack when we do a a stack traversal). It is enough that the pc()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1935
  // points into the right code segment. It does not have to be the correct return pc.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1936
  // We use the same pc/oopMap repeatedly when we call out
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1937
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1938
  intptr_t the_pc = (intptr_t) __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1939
  oop_maps->add_gc_map(the_pc - start, map);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1940
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1941
  __ set_last_Java_frame(thread, rsp, noreg, (address)the_pc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1942
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1943
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1944
  // We have all of the arguments setup at this point. We must not touch any register
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1945
  // argument registers at this point (what if we save/restore them there are no oop?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1946
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1947
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1948
    SkipIfEqual skip_if(masm, &DTraceMethodProbes, 0);
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
  1949
    __ mov_metadata(rax, method());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1950
    __ call_VM_leaf(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1951
         CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1952
         thread, rax);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1953
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1954
2136
c55428da3cec 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 1066
diff changeset
  1955
  // RedefineClasses() tracing support for obsolete method entry
c55428da3cec 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 1066
diff changeset
  1956
  if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) {
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
  1957
    __ mov_metadata(rax, method());
2136
c55428da3cec 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 1066
diff changeset
  1958
    __ call_VM_leaf(
c55428da3cec 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 1066
diff changeset
  1959
         CAST_FROM_FN_PTR(address, SharedRuntime::rc_trace_method_entry),
c55428da3cec 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 1066
diff changeset
  1960
         thread, rax);
c55428da3cec 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 1066
diff changeset
  1961
  }
c55428da3cec 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 1066
diff changeset
  1962
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1963
  // These are register definitions we need for locking/unlocking
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1964
  const Register swap_reg = rax;  // Must use rax, for cmpxchg instruction
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1965
  const Register obj_reg  = rcx;  // Will contain the oop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1966
  const Register lock_reg = rdx;  // Address of compiler lock object (BasicLock)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1967
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1968
  Label slow_path_lock;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1969
  Label lock_done;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1970
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1971
  // Lock a synchronized method
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1972
  if (method->is_synchronized()) {
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  1973
    assert(!is_critical_native, "unhandled");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1974
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1975
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1976
    const int mark_word_offset = BasicLock::displaced_header_offset_in_bytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1977
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1978
    // Get the handle (the 2nd argument)
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1979
    __ movptr(oop_handle_reg, Address(rsp, wordSize));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1980
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1981
    // Get address of the box
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1982
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1983
    __ lea(lock_reg, Address(rbp, lock_slot_rbp_offset));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1984
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1985
    // Load the oop from the handle
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1986
    __ movptr(obj_reg, Address(oop_handle_reg, 0));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1987
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1988
    if (UseBiasedLocking) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1989
      // Note that oop_handle_reg is trashed during this call
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1990
      __ biased_locking_enter(lock_reg, obj_reg, swap_reg, oop_handle_reg, false, lock_done, &slow_path_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1991
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1992
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1993
    // Load immediate 1 into swap_reg %rax,
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1994
    __ movptr(swap_reg, 1);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1995
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1996
    // Load (object->mark() | 1) into swap_reg %rax,
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  1997
    __ orptr(swap_reg, Address(obj_reg, 0));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1998
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1999
    // Save (object->mark() | 1) into BasicLock's displaced header
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2000
    __ movptr(Address(lock_reg, mark_word_offset), swap_reg);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2001
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2002
    if (os::is_MP()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2003
      __ lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2004
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2005
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2006
    // src -> dest iff dest == rax, else rax, <- dest
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2007
    // *obj_reg = lock_reg iff *obj_reg == rax, else rax, = *(obj_reg)
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2008
    __ cmpxchgptr(lock_reg, Address(obj_reg, 0));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2009
    __ jcc(Assembler::equal, lock_done);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2010
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2011
    // Test if the oopMark is an obvious stack pointer, i.e.,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2012
    //  1) (mark & 3) == 0, and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2013
    //  2) rsp <= mark < mark + os::pagesize()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2014
    // These 3 tests can be done by evaluating the following
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2015
    // expression: ((mark - rsp) & (3 - os::vm_page_size())),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2016
    // assuming both stack pointer and pagesize have their
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2017
    // least significant 2 bits clear.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2018
    // NOTE: the oopMark is in swap_reg %rax, as the result of cmpxchg
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2019
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2020
    __ subptr(swap_reg, rsp);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2021
    __ andptr(swap_reg, 3 - os::vm_page_size());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2022
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2023
    // Save the test result, for recursive case, the result is zero
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2024
    __ movptr(Address(lock_reg, mark_word_offset), swap_reg);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2025
    __ jcc(Assembler::notEqual, slow_path_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2026
    // Slow path will re-enter here
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2027
    __ bind(lock_done);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2028
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2029
    if (UseBiasedLocking) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2030
      // Re-fetch oop_handle_reg as we trashed it above
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2031
      __ movptr(oop_handle_reg, Address(rsp, wordSize));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2032
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2033
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2034
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2035
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2036
  // Finally just about ready to make the JNI call
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2037
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2038
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2039
  // get JNIEnv* which is first argument to native
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2040
  if (!is_critical_native) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2041
    __ lea(rdx, Address(thread, in_bytes(JavaThread::jni_environment_offset())));
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2042
    __ movptr(Address(rsp, 0), rdx);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2043
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2044
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2045
  // Now set thread in native
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2046
  __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_native);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2047
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2048
  __ call(RuntimeAddress(native_func));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2049
16624
9dbd4b210bf9 8011102: Clear AVX registers after return from JNI call
kvn
parents: 14626
diff changeset
  2050
  // Verify or restore cpu control state after JNI call
9dbd4b210bf9 8011102: Clear AVX registers after return from JNI call
kvn
parents: 14626
diff changeset
  2051
  __ restore_cpu_control_state_after_jni();
9dbd4b210bf9 8011102: Clear AVX registers after return from JNI call
kvn
parents: 14626
diff changeset
  2052
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2053
  // WARNING - on Windows Java Natives use pascal calling convention and pop the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2054
  // arguments off of the stack. We could just re-adjust the stack pointer here
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2055
  // and continue to do SP relative addressing but we instead switch to FP
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2056
  // relative addressing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2057
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2058
  // Unpack native results.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2059
  switch (ret_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2060
  case T_BOOLEAN: __ c2bool(rax);            break;
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2061
  case T_CHAR   : __ andptr(rax, 0xFFFF);    break;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2062
  case T_BYTE   : __ sign_extend_byte (rax); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2063
  case T_SHORT  : __ sign_extend_short(rax); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2064
  case T_INT    : /* nothing to do */        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2065
  case T_DOUBLE :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2066
  case T_FLOAT  :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2067
    // Result is in st0 we'll save as needed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2068
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2069
  case T_ARRAY:                 // Really a handle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2070
  case T_OBJECT:                // Really a handle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2071
      break; // can't de-handlize until after safepoint check
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2072
  case T_VOID: break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2073
  case T_LONG: break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2074
  default       : ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2075
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2076
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2077
  // Switch thread to "native transition" state before reading the synchronization state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2078
  // This additional state is necessary because reading and testing the synchronization
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2079
  // state is not atomic w.r.t. GC, as this scenario demonstrates:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2080
  //     Java thread A, in _thread_in_native state, loads _not_synchronized and is preempted.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2081
  //     VM thread changes sync state to synchronizing and suspends threads for GC.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2082
  //     Thread A is resumed to finish this native method, but doesn't block here since it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2083
  //     didn't see any synchronization is progress, and escapes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2084
  __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_native_trans);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2085
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2086
  if(os::is_MP()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2087
    if (UseMembar) {
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2088
      // Force this write out before the read below
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2089
      __ membar(Assembler::Membar_mask_bits(
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2090
           Assembler::LoadLoad | Assembler::LoadStore |
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2091
           Assembler::StoreLoad | Assembler::StoreStore));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2092
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2093
      // Write serialization page so VM thread can do a pseudo remote membar.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2094
      // We use the current thread pointer to calculate a thread specific
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2095
      // offset to write to within the page. This minimizes bus traffic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2096
      // due to cache line collision.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2097
      __ serialize_memory(thread, rcx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2098
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2099
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2100
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2101
  if (AlwaysRestoreFPU) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2102
    // Make sure the control word is correct.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2103
    __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2104
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2105
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2106
  Label after_transition;
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2107
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2108
  // check for safepoint operation in progress and/or pending suspend requests
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2109
  { Label Continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2110
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2111
    __ cmp32(ExternalAddress((address)SafepointSynchronize::address_of_state()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2112
             SafepointSynchronize::_not_synchronized);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2113
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2114
    Label L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2115
    __ jcc(Assembler::notEqual, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2116
    __ cmpl(Address(thread, JavaThread::suspend_flags_offset()), 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2117
    __ jcc(Assembler::equal, Continue);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2118
    __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2119
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2120
    // Don't use call_VM as it will see a possible pending exception and forward it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2121
    // and never return here preventing us from clearing _last_native_pc down below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2122
    // Also can't use call_VM_leaf either as it will check to see if rsi & rdi are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2123
    // preserved and correspond to the bcp/locals pointers. So we do a runtime call
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2124
    // by hand.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2125
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2126
    save_native_result(masm, ret_type, stack_slots);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2127
    __ push(thread);
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2128
    if (!is_critical_native) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2129
      __ call(RuntimeAddress(CAST_FROM_FN_PTR(address,
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2130
                                              JavaThread::check_special_condition_for_native_trans)));
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2131
    } else {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2132
      __ call(RuntimeAddress(CAST_FROM_FN_PTR(address,
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2133
                                              JavaThread::check_special_condition_for_native_trans_and_transition)));
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2134
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2135
    __ increment(rsp, wordSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2136
    // Restore any method result value
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2137
    restore_native_result(masm, ret_type, stack_slots);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2138
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2139
    if (is_critical_native) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2140
      // The call above performed the transition to thread_in_Java so
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2141
      // skip the transition logic below.
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2142
      __ jmpb(after_transition);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2143
    }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2144
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2145
    __ bind(Continue);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2146
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2147
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2148
  // change thread state
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2149
  __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_Java);
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2150
  __ bind(after_transition);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2151
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2152
  Label reguard;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2153
  Label reguard_done;
35201
996db89f378e 8139864: Improve handling of stack protection zones.
goetz
parents: 34203
diff changeset
  2154
  __ cmpl(Address(thread, JavaThread::stack_guard_state_offset()), JavaThread::stack_guard_yellow_reserved_disabled);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2155
  __ jcc(Assembler::equal, reguard);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2156
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2157
  // slow path reguard  re-enters here
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2158
  __ bind(reguard_done);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2159
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2160
  // Handle possible exception (will unlock if necessary)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2161
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2162
  // native result if any is live
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2163
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2164
  // Unlock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2165
  Label slow_path_unlock;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2166
  Label unlock_done;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2167
  if (method->is_synchronized()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2168
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2169
    Label done;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2170
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2171
    // Get locked oop from the handle we passed to jni
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2172
    __ movptr(obj_reg, Address(oop_handle_reg, 0));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2173
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2174
    if (UseBiasedLocking) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2175
      __ biased_locking_exit(obj_reg, rbx, done);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2176
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2177
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2178
    // Simple recursive lock?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2179
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2180
    __ cmpptr(Address(rbp, lock_slot_rbp_offset), (int32_t)NULL_WORD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2181
    __ jcc(Assembler::equal, done);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2182
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2183
    // Must save rax, if if it is live now because cmpxchg must use it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2184
    if (ret_type != T_FLOAT && ret_type != T_DOUBLE && ret_type != T_VOID) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2185
      save_native_result(masm, ret_type, stack_slots);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2186
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2187
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2188
    //  get old displaced header
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2189
    __ movptr(rbx, Address(rbp, lock_slot_rbp_offset));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2190
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2191
    // get address of the stack lock
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2192
    __ lea(rax, Address(rbp, lock_slot_rbp_offset));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2193
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2194
    // Atomic swap old header if oop still contains the stack lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2195
    if (os::is_MP()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2196
    __ lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2197
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2198
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2199
    // src -> dest iff dest == rax, else rax, <- dest
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2200
    // *obj_reg = rbx, iff *obj_reg == rax, else rax, = *(obj_reg)
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2201
    __ cmpxchgptr(rbx, Address(obj_reg, 0));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2202
    __ jcc(Assembler::notEqual, slow_path_unlock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2203
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2204
    // slow path re-enters here
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2205
    __ bind(unlock_done);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2206
    if (ret_type != T_FLOAT && ret_type != T_DOUBLE && ret_type != T_VOID) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2207
      restore_native_result(masm, ret_type, stack_slots);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2208
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2209
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2210
    __ bind(done);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2211
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2212
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2213
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2214
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2215
    SkipIfEqual skip_if(masm, &DTraceMethodProbes, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2216
    // Tell dtrace about this method exit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2217
    save_native_result(masm, ret_type, stack_slots);
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
  2218
    __ mov_metadata(rax, method());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2219
    __ call_VM_leaf(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2220
         CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2221
         thread, rax);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2222
    restore_native_result(masm, ret_type, stack_slots);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2223
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2224
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2225
  // We can finally stop using that last_Java_frame we setup ages ago
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2226
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2227
  __ reset_last_Java_frame(thread, false, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2228
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2229
  // Unpack oop result
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2230
  if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2231
      Label L;
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2232
      __ cmpptr(rax, (int32_t)NULL_WORD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2233
      __ jcc(Assembler::equal, L);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2234
      __ movptr(rax, Address(rax, 0));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2235
      __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2236
      __ verify_oop(rax);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2237
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2238
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2239
  if (!is_critical_native) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2240
    // reset handle block
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2241
    __ movptr(rcx, Address(thread, JavaThread::active_handles_offset()));
23844
0c29a324ae14 8039146: Fix 64-bit store to int JNIHandleBlock::_top
goetz
parents: 23491
diff changeset
  2242
    __ movl(Address(rcx, JNIHandleBlock::top_offset_in_bytes()), NULL_WORD);
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2243
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2244
    // Any exception pending?
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2245
    __ cmpptr(Address(thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2246
    __ jcc(Assembler::notEqual, exception_pending);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2247
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2248
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2249
  // no exception, we're almost done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2250
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2251
  // check that only result value is on FPU stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2252
  __ verify_FPU(ret_type == T_FLOAT || ret_type == T_DOUBLE ? 1 : 0, "native_wrapper normal exit");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2253
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2254
  // Fixup floating pointer results so that result looks like a return from a compiled method
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2255
  if (ret_type == T_FLOAT) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2256
    if (UseSSE >= 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2257
      // Pop st0 and store as float and reload into xmm register
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2258
      __ fstp_s(Address(rbp, -4));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2259
      __ movflt(xmm0, Address(rbp, -4));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2260
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2261
  } else if (ret_type == T_DOUBLE) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2262
    if (UseSSE >= 2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2263
      // Pop st0 and store as double and reload into xmm register
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2264
      __ fstp_d(Address(rbp, -8));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2265
      __ movdbl(xmm0, Address(rbp, -8));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2266
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2267
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2268
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2269
  // Return
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2270
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2271
  __ leave();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2272
  __ ret(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2273
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2274
  // Unexpected paths are out of line and go here
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2275
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2276
  // Slow path locking & unlocking
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2277
  if (method->is_synchronized()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2278
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2279
    // BEGIN Slow path lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2280
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2281
    __ bind(slow_path_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2282
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2283
    // has last_Java_frame setup. No exceptions so do vanilla call not call_VM
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2284
    // args are (oop obj, BasicLock* lock, JavaThread* thread)
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2285
    __ push(thread);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2286
    __ push(lock_reg);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2287
    __ push(obj_reg);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2288
    __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_locking_C)));
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2289
    __ addptr(rsp, 3*wordSize);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2290
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2291
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2292
    { Label L;
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2293
    __ cmpptr(Address(thread, in_bytes(Thread::pending_exception_offset())), (int)NULL_WORD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2294
    __ jcc(Assembler::equal, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2295
    __ stop("no pending exception allowed on exit from monitorenter");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2296
    __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2297
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2298
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2299
    __ jmp(lock_done);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2300
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2301
    // END Slow path lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2302
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2303
    // BEGIN Slow path unlock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2304
    __ bind(slow_path_unlock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2305
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2306
    // Slow path unlock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2307
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2308
    if (ret_type == T_FLOAT || ret_type == T_DOUBLE ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2309
      save_native_result(masm, ret_type, stack_slots);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2310
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2311
    // Save pending exception around call to VM (which contains an EXCEPTION_MARK)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2312
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2313
    __ pushptr(Address(thread, in_bytes(Thread::pending_exception_offset())));
1888
bbf498fb4354 6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents: 1066
diff changeset
  2314
    __ movptr(Address(thread, in_bytes(Thread::pending_exception_offset())), NULL_WORD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2315
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2316
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2317
    // should be a peal
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2318
    // +wordSize because of the push above
30244
d4e471395ff5 8073165: Contended Locking fast exit bucket
dcubed
parents: 28947
diff changeset
  2319
    // args are (oop obj, BasicLock* lock, JavaThread* thread)
d4e471395ff5 8073165: Contended Locking fast exit bucket
dcubed
parents: 28947
diff changeset
  2320
    __ push(thread);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2321
    __ lea(rax, Address(rbp, lock_slot_rbp_offset));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2322
    __ push(rax);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2323
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2324
    __ push(obj_reg);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2325
    __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_unlocking_C)));
30244
d4e471395ff5 8073165: Contended Locking fast exit bucket
dcubed
parents: 28947
diff changeset
  2326
    __ addptr(rsp, 3*wordSize);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2327
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2328
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2329
      Label L;
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2330
      __ cmpptr(Address(thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2331
      __ jcc(Assembler::equal, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2332
      __ stop("no pending exception allowed on exit complete_monitor_unlocking_C");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2333
      __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2334
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2335
#endif /* ASSERT */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2336
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2337
    __ popptr(Address(thread, in_bytes(Thread::pending_exception_offset())));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2338
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2339
    if (ret_type == T_FLOAT || ret_type == T_DOUBLE ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2340
      restore_native_result(masm, ret_type, stack_slots);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2341
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2342
    __ jmp(unlock_done);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2343
    // END Slow path unlock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2344
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2345
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2346
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2347
  // SLOW PATH Reguard the stack if needed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2348
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2349
  __ bind(reguard);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2350
  save_native_result(masm, ret_type, stack_slots);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2351
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2352
    __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2353
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2354
  restore_native_result(masm, ret_type, stack_slots);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2355
  __ jmp(reguard_done);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2356
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2357
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2358
  // BEGIN EXCEPTION PROCESSING
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2359
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2360
  if (!is_critical_native) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2361
    // Forward  the exception
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2362
    __ bind(exception_pending);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2363
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2364
    // remove possible return value from FPU register stack
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2365
    __ empty_FPU_stack();
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2366
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2367
    // pop our frame
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2368
    __ leave();
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2369
    // and forward the exception
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2370
    __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2371
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2372
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2373
  __ flush();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2374
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2375
  nmethod *nm = nmethod::new_native_nmethod(method,
8872
36680c58660e 7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents: 8315
diff changeset
  2376
                                            compile_id,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2377
                                            masm->code(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2378
                                            vep_offset,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2379
                                            frame_complete,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2380
                                            stack_slots / VMRegImpl::slots_per_word,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2381
                                            (is_static ? in_ByteSize(klass_offset) : in_ByteSize(receiver_offset)),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2382
                                            in_ByteSize(lock_slot_offset*VMRegImpl::stack_slot_size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2383
                                            oop_maps);
11637
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2384
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2385
  if (is_critical_native) {
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2386
    nm->set_lazy_critical_native(true);
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2387
  }
030466036615 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 10539
diff changeset
  2388
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2389
  return nm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2390
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2391
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2392
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2393
// this function returns the adjust size (in number of words) to a c2i adapter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2394
// activation for use during deoptimization
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2395
int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals ) {
5419
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 4735
diff changeset
  2396
  return (callee_locals - callee_parameters) * Interpreter::stackElementWords;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2397
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2398
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2399
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2400
uint SharedRuntime::out_preserve_stack_slots() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2401
  return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2402
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2403
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2404
//------------------------------generate_deopt_blob----------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2405
void SharedRuntime::generate_deopt_blob() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2406
  // allocate space for the code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2407
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2408
  // setup code generation tools
31786
eb497c0e1ddc 8079156: [TESTBUG] 32 bit Java 9-fastdebug hit assertion in client mode with StackShadowPages flag value from 32 to 50.
gziemski
parents: 30624
diff changeset
  2409
  // note: the buffer code size must account for StackShadowPages=50
eb497c0e1ddc 8079156: [TESTBUG] 32 bit Java 9-fastdebug hit assertion in client mode with StackShadowPages flag value from 32 to 50.
gziemski
parents: 30624
diff changeset
  2410
  CodeBuffer   buffer("deopt_blob", 1536, 1024);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2411
  MacroAssembler* masm = new MacroAssembler(&buffer);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2412
  int frame_size_in_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2413
  OopMap* map = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2414
  // Account for the extra args we place on the stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2415
  // by the time we call fetch_unroll_info
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2416
  const int additional_words = 2; // deopt kind, thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2417
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2418
  OopMapSet *oop_maps = new OopMapSet();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2419
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2420
  // -------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2421
  // This code enters when returning to a de-optimized nmethod.  A return
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2422
  // address has been pushed on the the stack, and return values are in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2423
  // registers.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2424
  // If we are doing a normal deopt then we were called from the patched
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2425
  // nmethod from the point we returned to the nmethod. So the return
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2426
  // address on the stack is wrong by NativeCall::instruction_size
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2427
  // We will adjust the value to it looks like we have the original return
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2428
  // address on the stack (like when we eagerly deoptimized).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2429
  // In the case of an exception pending with deoptimized then we enter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2430
  // with a return address on the stack that points after the call we patched
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2431
  // into the exception handler. We have the following register state:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2432
  //    rax,: exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2433
  //    rbx,: exception handler
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2434
  //    rdx: throwing pc
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2435
  // So in this case we simply jam rdx into the useless return address and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2436
  // the stack looks just like we want.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2437
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2438
  // At this point we need to de-opt.  We save the argument return
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2439
  // registers.  We call the first C routine, fetch_unroll_info().  This
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2440
  // routine captures the return values and returns a structure which
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2441
  // describes the current frame size and the sizes of all replacement frames.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2442
  // The current frame is compiled code and may contain many inlined
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2443
  // functions, each with their own JVM state.  We pop the current frame, then
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2444
  // push all the new frames.  Then we call the C routine unpack_frames() to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2445
  // populate these frames.  Finally unpack_frames() returns us the new target
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2446
  // address.  Notice that callee-save registers are BLOWN here; they have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2447
  // already been captured in the vframeArray at the time the return PC was
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2448
  // patched.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2449
  address start = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2450
  Label cont;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2451
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2452
  // Prolog for non exception case!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2453
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2454
  // Save everything in sight.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2455
3681
8565da02ec7a 6829127: Deoptimization Failure on Specjvm98 _227_mtrt with -XX:+DeoptimizeALot since Hs11 b01
cfang
parents: 2154
diff changeset
  2456
  map = RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words, false);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2457
  // Normal deoptimization
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2458
  __ push(Deoptimization::Unpack_deopt);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2459
  __ jmp(cont);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2460
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2461
  int reexecute_offset = __ pc() - start;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2462
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2463
  // Reexecute case
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2464
  // return address is the pc describes what bci to do re-execute at
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2465
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2466
  // No need to update map as each call to save_live_registers will produce identical oopmap
3681
8565da02ec7a 6829127: Deoptimization Failure on Specjvm98 _227_mtrt with -XX:+DeoptimizeALot since Hs11 b01
cfang
parents: 2154
diff changeset
  2467
  (void) RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words, false);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2468
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2469
  __ push(Deoptimization::Unpack_reexecute);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2470
  __ jmp(cont);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2471
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2472
  int exception_offset = __ pc() - start;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2473
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2474
  // Prolog for exception case
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2475
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2476
  // all registers are dead at this entry point, except for rax, and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2477
  // rdx which contain the exception oop and exception pc
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2478
  // respectively.  Set them in TLS and fall thru to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2479
  // unpack_with_exception_in_tls entry point.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2480
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2481
  __ get_thread(rdi);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2482
  __ movptr(Address(rdi, JavaThread::exception_pc_offset()), rdx);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2483
  __ movptr(Address(rdi, JavaThread::exception_oop_offset()), rax);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2484
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2485
  int exception_in_tls_offset = __ pc() - start;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2486
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2487
  // new implementation because exception oop is now passed in JavaThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2488
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2489
  // Prolog for exception case
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2490
  // All registers must be preserved because they might be used by LinearScan
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2491
  // Exceptiop oop and throwing PC are passed in JavaThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2492
  // tos: stack at point of call to method that threw the exception (i.e. only
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2493
  // args are on the stack, no return address)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2494
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2495
  // make room on stack for the return address
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2496
  // It will be patched later with the throwing pc. The correct value is not
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2497
  // available now because loading it from memory would destroy registers.
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2498
  __ push(0);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2499
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2500
  // Save everything in sight.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2501
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2502
  // No need to update map as each call to save_live_registers will produce identical oopmap
3681
8565da02ec7a 6829127: Deoptimization Failure on Specjvm98 _227_mtrt with -XX:+DeoptimizeALot since Hs11 b01
cfang
parents: 2154
diff changeset
  2503
  (void) RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words, false);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2504
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2505
  // Now it is safe to overwrite any register
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2506
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2507
  // store the correct deoptimization type
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2508
  __ push(Deoptimization::Unpack_exception);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2509
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2510
  // load throwing pc from JavaThread and patch it as the return address
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2511
  // of the current frame. Then clear the field in JavaThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2512
  __ get_thread(rdi);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2513
  __ movptr(rdx, Address(rdi, JavaThread::exception_pc_offset()));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2514
  __ movptr(Address(rbp, wordSize), rdx);
1888
bbf498fb4354 6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents: 1066
diff changeset
  2515
  __ movptr(Address(rdi, JavaThread::exception_pc_offset()), NULL_WORD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2516
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2517
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2518
  // verify that there is really an exception oop in JavaThread
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2519
  __ movptr(rax, Address(rdi, JavaThread::exception_oop_offset()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2520
  __ verify_oop(rax);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2521
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2522
  // verify that there is no pending exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2523
  Label no_pending_exception;
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2524
  __ movptr(rax, Address(rdi, Thread::pending_exception_offset()));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2525
  __ testptr(rax, rax);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2526
  __ jcc(Assembler::zero, no_pending_exception);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2527
  __ stop("must not have pending exception here");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2528
  __ bind(no_pending_exception);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2529
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2530
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2531
  __ bind(cont);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2532
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2533
  // Compiled code leaves the floating point stack dirty, empty it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2534
  __ empty_FPU_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2535
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2536
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2537
  // Call C code.  Need thread and this frame, but NOT official VM entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2538
  // crud.  We cannot block on this call, no GC can happen.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2539
  __ get_thread(rcx);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2540
  __ push(rcx);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2541
  // fetch_unroll_info needs to call last_java_frame()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2542
  __ set_last_Java_frame(rcx, noreg, noreg, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2543
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2544
  __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::fetch_unroll_info)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2545
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2546
  // Need to have an oopmap that tells fetch_unroll_info where to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2547
  // find any register it might need.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2548
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2549
  oop_maps->add_gc_map( __ pc()-start, map);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2550
34173
01bb07d23a5b 8141133: [JVMCI] crash during safepoint deopt if rethrow_exception is set
twisti
parents: 34162
diff changeset
  2551
  // Discard args to fetch_unroll_info
01bb07d23a5b 8141133: [JVMCI] crash during safepoint deopt if rethrow_exception is set
twisti
parents: 34162
diff changeset
  2552
  __ pop(rcx);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2553
  __ pop(rcx);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2554
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2555
  __ get_thread(rcx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2556
  __ reset_last_Java_frame(rcx, false, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2557
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2558
  // Load UnrollBlock into EDI
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2559
  __ mov(rdi, rax);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2560
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2561
  // Move the unpack kind to a safe place in the UnrollBlock because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2562
  // we are very short of registers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2563
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2564
  Address unpack_kind(rdi, Deoptimization::UnrollBlock::unpack_kind_offset_in_bytes());
34173
01bb07d23a5b 8141133: [JVMCI] crash during safepoint deopt if rethrow_exception is set
twisti
parents: 34162
diff changeset
  2565
  // retrieve the deopt kind from the UnrollBlock.
01bb07d23a5b 8141133: [JVMCI] crash during safepoint deopt if rethrow_exception is set
twisti
parents: 34162
diff changeset
  2566
  __ movl(rax, unpack_kind);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2567
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2568
   Label noException;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2569
  __ cmpl(rax, Deoptimization::Unpack_exception);   // Was exception pending?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2570
  __ jcc(Assembler::notEqual, noException);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2571
  __ movptr(rax, Address(rcx, JavaThread::exception_oop_offset()));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2572
  __ movptr(rdx, Address(rcx, JavaThread::exception_pc_offset()));
1888
bbf498fb4354 6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents: 1066
diff changeset
  2573
  __ movptr(Address(rcx, JavaThread::exception_oop_offset()), NULL_WORD);
bbf498fb4354 6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents: 1066
diff changeset
  2574
  __ movptr(Address(rcx, JavaThread::exception_pc_offset()), NULL_WORD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2575
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2576
  __ verify_oop(rax);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2577
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2578
  // Overwrite the result registers with the exception results.
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2579
  __ movptr(Address(rsp, RegisterSaver::raxOffset()*wordSize), rax);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2580
  __ movptr(Address(rsp, RegisterSaver::rdxOffset()*wordSize), rdx);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2581
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2582
  __ bind(noException);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2583
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2584
  // Stack is back to only having register save data on the stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2585
  // Now restore the result registers. Everything else is either dead or captured
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2586
  // in the vframeArray.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2587
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2588
  RegisterSaver::restore_result_registers(masm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2589
3681
8565da02ec7a 6829127: Deoptimization Failure on Specjvm98 _227_mtrt with -XX:+DeoptimizeALot since Hs11 b01
cfang
parents: 2154
diff changeset
  2590
  // Non standard control word may be leaked out through a safepoint blob, and we can
8565da02ec7a 6829127: Deoptimization Failure on Specjvm98 _227_mtrt with -XX:+DeoptimizeALot since Hs11 b01
cfang
parents: 2154
diff changeset
  2591
  // deopt at a poll point with the non standard control word. However, we should make
8565da02ec7a 6829127: Deoptimization Failure on Specjvm98 _227_mtrt with -XX:+DeoptimizeALot since Hs11 b01
cfang
parents: 2154
diff changeset
  2592
  // sure the control word is correct after restore_result_registers.
8565da02ec7a 6829127: Deoptimization Failure on Specjvm98 _227_mtrt with -XX:+DeoptimizeALot since Hs11 b01
cfang
parents: 2154
diff changeset
  2593
  __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std()));
8565da02ec7a 6829127: Deoptimization Failure on Specjvm98 _227_mtrt with -XX:+DeoptimizeALot since Hs11 b01
cfang
parents: 2154
diff changeset
  2594
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2595
  // All of the register save area has been popped of the stack. Only the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2596
  // return address remains.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2597
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2598
  // Pop all the frames we must move/replace.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2599
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2600
  // Frame picture (youngest to oldest)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2601
  // 1: self-frame (no frame link)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2602
  // 2: deopting frame  (no frame link)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2603
  // 3: caller of deopting frame (could be compiled/interpreted).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2604
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2605
  // Note: by leaving the return address of self-frame on the stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2606
  // and using the size of frame 2 to adjust the stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2607
  // when we are done the return to frame 3 will still be on the stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2608
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2609
  // Pop deoptimized frame
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2610
  __ addptr(rsp, Address(rdi,Deoptimization::UnrollBlock::size_of_deoptimized_frame_offset_in_bytes()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2611
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2612
  // sp should be pointing at the return address to the caller (3)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2613
21728
0c36ed5f52f5 8028308: nsk regression, assert(obj->is_oop()) failed: not an oop
roland
parents: 16624
diff changeset
  2614
  // Pick up the initial fp we should save
0c36ed5f52f5 8028308: nsk regression, assert(obj->is_oop()) failed: not an oop
roland
parents: 16624
diff changeset
  2615
  // restore rbp before stack bang because if stack overflow is thrown it needs to be pushed (and preserved)
0c36ed5f52f5 8028308: nsk regression, assert(obj->is_oop()) failed: not an oop
roland
parents: 16624
diff changeset
  2616
  __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_info_offset_in_bytes()));
0c36ed5f52f5 8028308: nsk regression, assert(obj->is_oop()) failed: not an oop
roland
parents: 16624
diff changeset
  2617
24018
77b156916bab 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 23844
diff changeset
  2618
#ifdef ASSERT
77b156916bab 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 23844
diff changeset
  2619
  // Compilers generate code that bang the stack by as much as the
77b156916bab 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 23844
diff changeset
  2620
  // interpreter would need. So this stack banging should never
77b156916bab 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 23844
diff changeset
  2621
  // trigger a fault. Verify that it does not on non product builds.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2622
  if (UseStackBanging) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2623
    __ movl(rbx, Address(rdi ,Deoptimization::UnrollBlock::total_frame_sizes_offset_in_bytes()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2624
    __ bang_stack_size(rbx, rcx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2625
  }
24018
77b156916bab 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 23844
diff changeset
  2626
#endif
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2627
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2628
  // Load array of frame pcs into ECX
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2629
  __ movptr(rcx,Address(rdi,Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes()));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2630
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2631
  __ pop(rsi); // trash the old pc
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2632
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2633
  // Load array of frame sizes into ESI
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2634
  __ movptr(rsi,Address(rdi,Deoptimization::UnrollBlock::frame_sizes_offset_in_bytes()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2635
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2636
  Address counter(rdi, Deoptimization::UnrollBlock::counter_temp_offset_in_bytes());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2637
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2638
  __ movl(rbx, Address(rdi, Deoptimization::UnrollBlock::number_of_frames_offset_in_bytes()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2639
  __ movl(counter, rbx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2640
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2641
  // Now adjust the caller's stack to make up for the extra locals
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2642
  // but record the original sp so that we can save it in the skeletal interpreter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2643
  // frame and the stack walking of interpreter_sender will get the unextended sp
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2644
  // value and not the "real" sp value.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2645
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2646
  Address sp_temp(rdi, Deoptimization::UnrollBlock::sender_sp_temp_offset_in_bytes());
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2647
  __ movptr(sp_temp, rsp);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2648
  __ movl2ptr(rbx, Address(rdi, Deoptimization::UnrollBlock::caller_adjustment_offset_in_bytes()));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2649
  __ subptr(rsp, rbx);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2650
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2651
  // Push interpreter frames in a loop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2652
  Label loop;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2653
  __ bind(loop);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2654
  __ movptr(rbx, Address(rsi, 0));      // Load frame size
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2655
  __ subptr(rbx, 2*wordSize);           // we'll push pc and rbp, by hand
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2656
  __ pushptr(Address(rcx, 0));          // save return address
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2657
  __ enter();                           // save old & set new rbp,
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2658
  __ subptr(rsp, rbx);                  // Prolog!
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2659
  __ movptr(rbx, sp_temp);              // sender's sp
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2660
  // This value is corrected by layout_activation_impl
1888
bbf498fb4354 6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents: 1066
diff changeset
  2661
  __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2662
  __ movptr(Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize), rbx); // Make it walkable
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2663
  __ movptr(sp_temp, rsp);              // pass to next frame
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2664
  __ addptr(rsi, wordSize);             // Bump array pointer (sizes)
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2665
  __ addptr(rcx, wordSize);             // Bump array pointer (pcs)
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2666
  __ decrementl(counter);             // decrement counter
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2667
  __ jcc(Assembler::notZero, loop);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2668
  __ pushptr(Address(rcx, 0));          // save final return address
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2669
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2670
  // Re-push self-frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2671
  __ enter();                           // save old & set new rbp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2672
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2673
  //  Return address and rbp, are in place
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2674
  // We'll push additional args later. Just allocate a full sized
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2675
  // register save area
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2676
  __ subptr(rsp, (frame_size_in_words-additional_words - 2) * wordSize);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2677
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2678
  // Restore frame locals after moving the frame
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2679
  __ movptr(Address(rsp, RegisterSaver::raxOffset()*wordSize), rax);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2680
  __ movptr(Address(rsp, RegisterSaver::rdxOffset()*wordSize), rdx);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2681
  __ fstp_d(Address(rsp, RegisterSaver::fpResultOffset()*wordSize));   // Pop float stack and store in local
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2682
  if( UseSSE>=2 ) __ movdbl(Address(rsp, RegisterSaver::xmm0Offset()*wordSize), xmm0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2683
  if( UseSSE==1 ) __ movflt(Address(rsp, RegisterSaver::xmm0Offset()*wordSize), xmm0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2684
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2685
  // Set up the args to unpack_frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2686
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2687
  __ pushl(unpack_kind);                     // get the unpack_kind value
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2688
  __ get_thread(rcx);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2689
  __ push(rcx);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2690
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2691
  // set last_Java_sp, last_Java_fp
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2692
  __ set_last_Java_frame(rcx, noreg, rbp, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2693
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2694
  // Call C code.  Need thread but NOT official VM entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2695
  // crud.  We cannot block on this call, no GC can happen.  Call should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2696
  // restore return values to their stack-slots with the new SP.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2697
  __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2698
  // Set an oopmap for the call site
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2699
  oop_maps->add_gc_map( __ pc()-start, new OopMap( frame_size_in_words, 0 ));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2700
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2701
  // rax, contains the return result type
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2702
  __ push(rax);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2703
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2704
  __ get_thread(rcx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2705
  __ reset_last_Java_frame(rcx, false, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2706
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2707
  // Collect return values
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2708
  __ movptr(rax,Address(rsp, (RegisterSaver::raxOffset() + additional_words + 1)*wordSize));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2709
  __ movptr(rdx,Address(rsp, (RegisterSaver::rdxOffset() + additional_words + 1)*wordSize));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2710
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2711
  // Clear floating point stack before returning to interpreter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2712
  __ empty_FPU_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2713
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2714
  // Check if we should push the float or double return value.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2715
  Label results_done, yes_double_value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2716
  __ cmpl(Address(rsp, 0), T_DOUBLE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2717
  __ jcc (Assembler::zero, yes_double_value);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2718
  __ cmpl(Address(rsp, 0), T_FLOAT);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2719
  __ jcc (Assembler::notZero, results_done);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2720
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2721
  // return float value as expected by interpreter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2722
  if( UseSSE>=1 ) __ movflt(xmm0, Address(rsp, (RegisterSaver::xmm0Offset() + additional_words + 1)*wordSize));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2723
  else            __ fld_d(Address(rsp, (RegisterSaver::fpResultOffset() + additional_words + 1)*wordSize));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2724
  __ jmp(results_done);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2725
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2726
  // return double value as expected by interpreter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2727
  __ bind(yes_double_value);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2728
  if( UseSSE>=2 ) __ movdbl(xmm0, Address(rsp, (RegisterSaver::xmm0Offset() + additional_words + 1)*wordSize));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2729
  else            __ fld_d(Address(rsp, (RegisterSaver::fpResultOffset() + additional_words + 1)*wordSize));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2730
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2731
  __ bind(results_done);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2732
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2733
  // Pop self-frame.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2734
  __ leave();                              // Epilog!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2735
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2736
  // Jump to interpreter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2737
  __ ret(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2738
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2739
  // -------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2740
  // make sure all code is generated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2741
  masm->flush();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2742
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2743
  _deopt_blob = DeoptimizationBlob::create( &buffer, oop_maps, 0, exception_offset, reexecute_offset, frame_size_in_words);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2744
  _deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2745
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2746
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2747
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2748
#ifdef COMPILER2
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2749
//------------------------------generate_uncommon_trap_blob--------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2750
void SharedRuntime::generate_uncommon_trap_blob() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2751
  // allocate space for the code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2752
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2753
  // setup code generation tools
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2754
  CodeBuffer   buffer("uncommon_trap_blob", 512, 512);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2755
  MacroAssembler* masm = new MacroAssembler(&buffer);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2756
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2757
  enum frame_layout {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2758
    arg0_off,      // thread                     sp + 0 // Arg location for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2759
    arg1_off,      // unloaded_class_index       sp + 1 // calling C
34173
01bb07d23a5b 8141133: [JVMCI] crash during safepoint deopt if rethrow_exception is set
twisti
parents: 34162
diff changeset
  2760
    arg2_off,      // exec_mode                  sp + 2
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2761
    // The frame sender code expects that rbp will be in the "natural" place and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2762
    // will override any oopMap setting for it. We must therefore force the layout
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2763
    // so that it agrees with the frame sender code.
34173
01bb07d23a5b 8141133: [JVMCI] crash during safepoint deopt if rethrow_exception is set
twisti
parents: 34162
diff changeset
  2764
    rbp_off,       // callee saved register      sp + 3
01bb07d23a5b 8141133: [JVMCI] crash during safepoint deopt if rethrow_exception is set
twisti
parents: 34162
diff changeset
  2765
    return_off,    // slot for return address    sp + 4
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2766
    framesize
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2767
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2768
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2769
  address start = __ pc();
23491
f690330b10b9 8031320: Use Intel RTM instructions for locks
kvn
parents: 22872
diff changeset
  2770
f690330b10b9 8031320: Use Intel RTM instructions for locks
kvn
parents: 22872
diff changeset
  2771
  if (UseRTMLocking) {
f690330b10b9 8031320: Use Intel RTM instructions for locks
kvn
parents: 22872
diff changeset
  2772
    // Abort RTM transaction before possible nmethod deoptimization.
f690330b10b9 8031320: Use Intel RTM instructions for locks
kvn
parents: 22872
diff changeset
  2773
    __ xabort(0);
f690330b10b9 8031320: Use Intel RTM instructions for locks
kvn
parents: 22872
diff changeset
  2774
  }
f690330b10b9 8031320: Use Intel RTM instructions for locks
kvn
parents: 22872
diff changeset
  2775
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2776
  // Push self-frame.
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2777
  __ subptr(rsp, return_off*wordSize);     // Epilog!
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2778
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2779
  // rbp, is an implicitly saved callee saved register (i.e. the calling
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2780
  // convention will save restore it in prolog/epilog) Other than that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2781
  // there are no callee save registers no that adapter frames are gone.
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2782
  __ movptr(Address(rsp, rbp_off*wordSize), rbp);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2783
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2784
  // Clear the floating point exception stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2785
  __ empty_FPU_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2786
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2787
  // set last_Java_sp
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2788
  __ get_thread(rdx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2789
  __ set_last_Java_frame(rdx, noreg, noreg, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2790
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2791
  // Call C code.  Need thread but NOT official VM entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2792
  // crud.  We cannot block on this call, no GC can happen.  Call should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2793
  // capture callee-saved registers as well as return values.
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2794
  __ movptr(Address(rsp, arg0_off*wordSize), rdx);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2795
  // argument already in ECX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2796
  __ movl(Address(rsp, arg1_off*wordSize),rcx);
34173
01bb07d23a5b 8141133: [JVMCI] crash during safepoint deopt if rethrow_exception is set
twisti
parents: 34162
diff changeset
  2797
  __ movl(Address(rsp, arg2_off*wordSize), Deoptimization::Unpack_uncommon_trap);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2798
  __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2799
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2800
  // Set an oopmap for the call site
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2801
  OopMapSet *oop_maps = new OopMapSet();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2802
  OopMap* map =  new OopMap( framesize, 0 );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2803
  // No oopMap for rbp, it is known implicitly
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2804
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2805
  oop_maps->add_gc_map( __ pc()-start, map);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2806
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2807
  __ get_thread(rcx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2808
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2809
  __ reset_last_Java_frame(rcx, false, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2810
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2811
  // Load UnrollBlock into EDI
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2812
  __ movptr(rdi, rax);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2813
34173
01bb07d23a5b 8141133: [JVMCI] crash during safepoint deopt if rethrow_exception is set
twisti
parents: 34162
diff changeset
  2814
#ifdef ASSERT
01bb07d23a5b 8141133: [JVMCI] crash during safepoint deopt if rethrow_exception is set
twisti
parents: 34162
diff changeset
  2815
  { Label L;
01bb07d23a5b 8141133: [JVMCI] crash during safepoint deopt if rethrow_exception is set
twisti
parents: 34162
diff changeset
  2816
    __ cmpptr(Address(rdi, Deoptimization::UnrollBlock::unpack_kind_offset_in_bytes()),
01bb07d23a5b 8141133: [JVMCI] crash during safepoint deopt if rethrow_exception is set
twisti
parents: 34162
diff changeset
  2817
            (int32_t)Deoptimization::Unpack_uncommon_trap);
01bb07d23a5b 8141133: [JVMCI] crash during safepoint deopt if rethrow_exception is set
twisti
parents: 34162
diff changeset
  2818
    __ jcc(Assembler::equal, L);
01bb07d23a5b 8141133: [JVMCI] crash during safepoint deopt if rethrow_exception is set
twisti
parents: 34162
diff changeset
  2819
    __ stop("SharedRuntime::generate_deopt_blob: expected Unpack_uncommon_trap");
01bb07d23a5b 8141133: [JVMCI] crash during safepoint deopt if rethrow_exception is set
twisti
parents: 34162
diff changeset
  2820
    __ bind(L);
01bb07d23a5b 8141133: [JVMCI] crash during safepoint deopt if rethrow_exception is set
twisti
parents: 34162
diff changeset
  2821
  }
01bb07d23a5b 8141133: [JVMCI] crash during safepoint deopt if rethrow_exception is set
twisti
parents: 34162
diff changeset
  2822
#endif
01bb07d23a5b 8141133: [JVMCI] crash during safepoint deopt if rethrow_exception is set
twisti
parents: 34162
diff changeset
  2823
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2824
  // Pop all the frames we must move/replace.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2825
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2826
  // Frame picture (youngest to oldest)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2827
  // 1: self-frame (no frame link)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2828
  // 2: deopting frame  (no frame link)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2829
  // 3: caller of deopting frame (could be compiled/interpreted).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2830
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2831
  // Pop self-frame.  We have no frame, and must rely only on EAX and ESP.
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2832
  __ addptr(rsp,(framesize-1)*wordSize);     // Epilog!
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2833
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2834
  // Pop deoptimized frame
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2835
  __ movl2ptr(rcx, Address(rdi,Deoptimization::UnrollBlock::size_of_deoptimized_frame_offset_in_bytes()));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2836
  __ addptr(rsp, rcx);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2837
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2838
  // sp should be pointing at the return address to the caller (3)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2839
21728
0c36ed5f52f5 8028308: nsk regression, assert(obj->is_oop()) failed: not an oop
roland
parents: 16624
diff changeset
  2840
  // Pick up the initial fp we should save
0c36ed5f52f5 8028308: nsk regression, assert(obj->is_oop()) failed: not an oop
roland
parents: 16624
diff changeset
  2841
  // restore rbp before stack bang because if stack overflow is thrown it needs to be pushed (and preserved)
0c36ed5f52f5 8028308: nsk regression, assert(obj->is_oop()) failed: not an oop
roland
parents: 16624
diff changeset
  2842
  __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_info_offset_in_bytes()));
0c36ed5f52f5 8028308: nsk regression, assert(obj->is_oop()) failed: not an oop
roland
parents: 16624
diff changeset
  2843
24018
77b156916bab 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 23844
diff changeset
  2844
#ifdef ASSERT
77b156916bab 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 23844
diff changeset
  2845
  // Compilers generate code that bang the stack by as much as the
77b156916bab 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 23844
diff changeset
  2846
  // interpreter would need. So this stack banging should never
77b156916bab 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 23844
diff changeset
  2847
  // trigger a fault. Verify that it does not on non product builds.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2848
  if (UseStackBanging) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2849
    __ movl(rbx, Address(rdi ,Deoptimization::UnrollBlock::total_frame_sizes_offset_in_bytes()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2850
    __ bang_stack_size(rbx, rcx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2851
  }
24018
77b156916bab 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents: 23844
diff changeset
  2852
#endif
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2853
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2854
  // Load array of frame pcs into ECX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2855
  __ movl(rcx,Address(rdi,Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2856
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2857
  __ pop(rsi); // trash the pc
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2858
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2859
  // Load array of frame sizes into ESI
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2860
  __ movptr(rsi,Address(rdi,Deoptimization::UnrollBlock::frame_sizes_offset_in_bytes()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2861
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2862
  Address counter(rdi, Deoptimization::UnrollBlock::counter_temp_offset_in_bytes());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2863
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2864
  __ movl(rbx, Address(rdi, Deoptimization::UnrollBlock::number_of_frames_offset_in_bytes()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2865
  __ movl(counter, rbx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2866
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2867
  // Now adjust the caller's stack to make up for the extra locals
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2868
  // but record the original sp so that we can save it in the skeletal interpreter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2869
  // frame and the stack walking of interpreter_sender will get the unextended sp
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2870
  // value and not the "real" sp value.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2871
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2872
  Address sp_temp(rdi, Deoptimization::UnrollBlock::sender_sp_temp_offset_in_bytes());
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2873
  __ movptr(sp_temp, rsp);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2874
  __ movl(rbx, Address(rdi, Deoptimization::UnrollBlock::caller_adjustment_offset_in_bytes()));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2875
  __ subptr(rsp, rbx);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2876
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2877
  // Push interpreter frames in a loop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2878
  Label loop;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2879
  __ bind(loop);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2880
  __ movptr(rbx, Address(rsi, 0));      // Load frame size
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2881
  __ subptr(rbx, 2*wordSize);           // we'll push pc and rbp, by hand
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2882
  __ pushptr(Address(rcx, 0));          // save return address
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2883
  __ enter();                           // save old & set new rbp,
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2884
  __ subptr(rsp, rbx);                  // Prolog!
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2885
  __ movptr(rbx, sp_temp);              // sender's sp
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2886
  // This value is corrected by layout_activation_impl
1888
bbf498fb4354 6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents: 1066
diff changeset
  2887
  __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD );
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2888
  __ movptr(Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize), rbx); // Make it walkable
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2889
  __ movptr(sp_temp, rsp);              // pass to next frame
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2890
  __ addptr(rsi, wordSize);             // Bump array pointer (sizes)
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2891
  __ addptr(rcx, wordSize);             // Bump array pointer (pcs)
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2892
  __ decrementl(counter);             // decrement counter
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2893
  __ jcc(Assembler::notZero, loop);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2894
  __ pushptr(Address(rcx, 0));            // save final return address
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2895
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2896
  // Re-push self-frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2897
  __ enter();                           // save old & set new rbp,
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2898
  __ subptr(rsp, (framesize-2) * wordSize);   // Prolog!
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2899
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2900
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2901
  // set last_Java_sp, last_Java_fp
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2902
  __ get_thread(rdi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2903
  __ set_last_Java_frame(rdi, noreg, rbp, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2904
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2905
  // Call C code.  Need thread but NOT official VM entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2906
  // crud.  We cannot block on this call, no GC can happen.  Call should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2907
  // restore return values to their stack-slots with the new SP.
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2908
  __ movptr(Address(rsp,arg0_off*wordSize),rdi);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2909
  __ movl(Address(rsp,arg1_off*wordSize), Deoptimization::Unpack_uncommon_trap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2910
  __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2911
  // Set an oopmap for the call site
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2912
  oop_maps->add_gc_map( __ pc()-start, new OopMap( framesize, 0 ) );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2913
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2914
  __ get_thread(rdi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2915
  __ reset_last_Java_frame(rdi, true, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2916
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2917
  // Pop self-frame.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2918
  __ leave();     // Epilog!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2919
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2920
  // Jump to interpreter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2921
  __ ret(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2922
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2923
  // -------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2924
  // make sure all code is generated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2925
  masm->flush();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2926
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2927
   _uncommon_trap_blob = UncommonTrapBlob::create(&buffer, oop_maps, framesize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2928
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2929
#endif // COMPILER2
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2930
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2931
//------------------------------generate_handler_blob------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2932
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2933
// Generate a special Compile2Runtime blob that saves all registers,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2934
// setup oopmap, and calls safepoint code to stop the compiled code for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2935
// a safepoint.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2936
//
13883
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
  2937
SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_type) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2938
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2939
  // Account for thread arg in our frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2940
  const int additional_words = 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2941
  int frame_size_in_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2942
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2943
  assert (StubRoutines::forward_exception_entry() != NULL, "must be generated before");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2944
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2945
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2946
  OopMapSet *oop_maps = new OopMapSet();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2947
  OopMap* map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2948
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2949
  // allocate space for the code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2950
  // setup code generation tools
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2951
  CodeBuffer   buffer("handler_blob", 1024, 512);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2952
  MacroAssembler* masm = new MacroAssembler(&buffer);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2953
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2954
  const Register java_thread = rdi; // callee-saved for VC++
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2955
  address start   = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2956
  address call_pc = NULL;
13883
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
  2957
  bool cause_return = (poll_type == POLL_AT_RETURN);
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
  2958
  bool save_vectors = (poll_type == POLL_AT_VECTOR_LOOP);
23491
f690330b10b9 8031320: Use Intel RTM instructions for locks
kvn
parents: 22872
diff changeset
  2959
f690330b10b9 8031320: Use Intel RTM instructions for locks
kvn
parents: 22872
diff changeset
  2960
  if (UseRTMLocking) {
f690330b10b9 8031320: Use Intel RTM instructions for locks
kvn
parents: 22872
diff changeset
  2961
    // Abort RTM transaction before calling runtime
f690330b10b9 8031320: Use Intel RTM instructions for locks
kvn
parents: 22872
diff changeset
  2962
    // because critical section will be large and will be
f690330b10b9 8031320: Use Intel RTM instructions for locks
kvn
parents: 22872
diff changeset
  2963
    // aborted anyway. Also nmethod could be deoptimized.
f690330b10b9 8031320: Use Intel RTM instructions for locks
kvn
parents: 22872
diff changeset
  2964
    __ xabort(0);
f690330b10b9 8031320: Use Intel RTM instructions for locks
kvn
parents: 22872
diff changeset
  2965
  }
f690330b10b9 8031320: Use Intel RTM instructions for locks
kvn
parents: 22872
diff changeset
  2966
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2967
  // If cause_return is true we are at a poll_return and there is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2968
  // the return address on the stack to the caller on the nmethod
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2969
  // that is safepoint. We can leave this return on the stack and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2970
  // effectively complete the return and safepoint in the caller.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2971
  // Otherwise we push space for a return address that the safepoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2972
  // handler will install later to make the stack walking sensible.
13883
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
  2973
  if (!cause_return)
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
  2974
    __ push(rbx);  // Make room for return address (or push it again)
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
  2975
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
  2976
  map = RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words, false, save_vectors);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2977
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2978
  // The following is basically a call_VM. However, we need the precise
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2979
  // address of the call in order to generate an oopmap. Hence, we do all the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2980
  // work ourselves.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2981
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2982
  // Push thread argument and setup last_Java_sp
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2983
  __ get_thread(java_thread);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2984
  __ push(java_thread);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2985
  __ set_last_Java_frame(java_thread, noreg, noreg, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2986
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2987
  // if this was not a poll_return then we need to correct the return address now.
13883
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
  2988
  if (!cause_return) {
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2989
    __ movptr(rax, Address(java_thread, JavaThread::saved_exception_pc_offset()));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  2990
    __ movptr(Address(rbp, wordSize), rax);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2991
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2992
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2993
  // do the call
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2994
  __ call(RuntimeAddress(call_ptr));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2995
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2996
  // Set an oopmap for the call site.  This oopmap will map all
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2997
  // oop-registers and debug-info registers as callee-saved.  This
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2998
  // will allow deoptimization at this safepoint to find all possible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2999
  // debug-info recordings, as well as let GC find all oops.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3000
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3001
  oop_maps->add_gc_map( __ pc() - start, map);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3002
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3003
  // Discard arg
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  3004
  __ pop(rcx);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3005
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3006
  Label noException;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3007
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3008
  // Clear last_Java_sp again
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3009
  __ get_thread(java_thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3010
  __ reset_last_Java_frame(java_thread, false, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3011
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  3012
  __ cmpptr(Address(java_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3013
  __ jcc(Assembler::equal, noException);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3014
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3015
  // Exception pending
13883
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
  3016
  RegisterSaver::restore_live_registers(masm, save_vectors);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3017
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3018
  __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3019
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3020
  __ bind(noException);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3021
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3022
  // Normal exit, register restoring and exit
13883
6979b9850feb 7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents: 13881
diff changeset
  3023
  RegisterSaver::restore_live_registers(masm, save_vectors);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3024
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3025
  __ ret(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3026
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3027
  // make sure all code is generated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3028
  masm->flush();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3029
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3030
  // Fill-out other meta info
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3031
  return SafepointBlob::create(&buffer, oop_maps, frame_size_in_words);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3032
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3033
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3034
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3035
// generate_resolve_blob - call resolution (static/virtual/opt-virtual/ic-miss
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3036
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3037
// Generate a stub that calls into vm to find out the proper destination
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3038
// of a java call. All the argument registers are live at this point
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3039
// but since this is generic code we don't know what they are and the caller
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3040
// must do any gc of the args.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3041
//
9976
6fef34e63df1 7045514: SPARC assembly code for JSR 292 ricochet frames
never
parents: 9630
diff changeset
  3042
RuntimeStub* SharedRuntime::generate_resolve_blob(address destination, const char* name) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3043
  assert (StubRoutines::forward_exception_entry() != NULL, "must be generated before");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3044
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3045
  // allocate space for the code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3046
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3047
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3048
  CodeBuffer buffer(name, 1000, 512);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3049
  MacroAssembler* masm                = new MacroAssembler(&buffer);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3050
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3051
  int frame_size_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3052
  enum frame_layout {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3053
                thread_off,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3054
                extra_words };
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3055
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3056
  OopMapSet *oop_maps = new OopMapSet();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3057
  OopMap* map = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3058
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3059
  int start = __ offset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3060
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3061
  map = RegisterSaver::save_live_registers(masm, extra_words, &frame_size_words);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3062
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3063
  int frame_complete = __ offset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3064
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3065
  const Register thread = rdi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3066
  __ get_thread(rdi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3067
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  3068
  __ push(thread);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3069
  __ set_last_Java_frame(thread, noreg, rbp, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3070
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3071
  __ call(RuntimeAddress(destination));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3072
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3073
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3074
  // Set an oopmap for the call site.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3075
  // We need this not only for callee-saved registers, but also for volatile
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3076
  // registers that the compiler might be keeping live across a safepoint.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3077
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3078
  oop_maps->add_gc_map( __ offset() - start, map);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3079
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3080
  // rax, contains the address we are going to jump to assuming no exception got installed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3081
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  3082
  __ addptr(rsp, wordSize);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3083
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3084
  // clear last_Java_sp
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3085
  __ reset_last_Java_frame(thread, true, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3086
  // check for pending exceptions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3087
  Label pending;
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  3088
  __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3089
  __ jcc(Assembler::notEqual, pending);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3090
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
  3091
  // get the returned Method*
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
  3092
  __ get_vm_result_2(rbx, thread);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  3093
  __ movptr(Address(rsp, RegisterSaver::rbx_offset() * wordSize), rbx);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  3094
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  3095
  __ movptr(Address(rsp, RegisterSaver::rax_offset() * wordSize), rax);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3096
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3097
  RegisterSaver::restore_live_registers(masm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3098
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3099
  // We are back the the original state on entry and ready to go.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3100
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3101
  __ jmp(rax);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3102
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3103
  // Pending exception after the safepoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3104
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3105
  __ bind(pending);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3106
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3107
  RegisterSaver::restore_live_registers(masm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3108
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3109
  // exception pending => remove activation and forward to exception handler
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3110
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3111
  __ get_thread(thread);
1888
bbf498fb4354 6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents: 1066
diff changeset
  3112
  __ movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 670
diff changeset
  3113
  __ movptr(rax, Address(thread, Thread::pending_exception_offset()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3114
  __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3115
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3116
  // -------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3117
  // make sure all code is generated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3118
  masm->flush();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3119
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3120
  // return the  blob
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3121
  // frame_size_words or bytes??
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3122
  return RuntimeStub::new_runtime_stub(name, &buffer, frame_complete, frame_size_words, oop_maps, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3123
}