hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
author johnc
Thu, 07 Apr 2011 09:53:20 -0700
changeset 9176 42d9d1010f38
parent 8315 1503f9d7681f
child 9179 6db9c9dffe1f
permissions -rw-r--r--
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error Summary: A referent object that is only weakly reachable at the start of concurrent marking but is re-attached to the strongly reachable object graph during marking may not be marked as live. This can cause the reference object to be processed prematurely and leave dangling pointers to the referent object. Implement a read barrier for the java.lang.ref.Reference::referent field by intrinsifying the Reference.get() method, and intercepting accesses though JNI, reflection, and Unsafe, so that when a non-null referent object is read it is also logged in an SATB buffer. Reviewed-by: kvn, iveresov, never, tonyp, dholmes
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
7889
02144432d0e1 4930919: race condition in MDO creation at back branch locations
iveresov
parents: 7397
diff changeset
     2
 * Copyright (c) 1997, 2011, 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: 6453
diff changeset
    25
#include "precompiled.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6453
diff changeset
    26
#include "asm/assembler.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6453
diff changeset
    27
#include "interpreter/bytecodeHistogram.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6453
diff changeset
    28
#include "interpreter/interpreter.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6453
diff changeset
    29
#include "interpreter/interpreterGenerator.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6453
diff changeset
    30
#include "interpreter/interpreterRuntime.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6453
diff changeset
    31
#include "interpreter/templateTable.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6453
diff changeset
    32
#include "oops/arrayOop.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6453
diff changeset
    33
#include "oops/methodDataOop.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6453
diff changeset
    34
#include "oops/methodOop.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6453
diff changeset
    35
#include "oops/oop.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6453
diff changeset
    36
#include "prims/jvmtiExport.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6453
diff changeset
    37
#include "prims/jvmtiThreadState.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6453
diff changeset
    38
#include "runtime/arguments.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6453
diff changeset
    39
#include "runtime/deoptimization.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6453
diff changeset
    40
#include "runtime/frame.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6453
diff changeset
    41
#include "runtime/sharedRuntime.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6453
diff changeset
    42
#include "runtime/stubRoutines.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6453
diff changeset
    43
#include "runtime/synchronizer.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6453
diff changeset
    44
#include "runtime/timer.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6453
diff changeset
    45
#include "runtime/vframeArray.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6453
diff changeset
    46
#include "utilities/debug.hpp"
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
#define __ _masm->
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
#ifndef CC_INTERP
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
const int method_offset = frame::interpreter_frame_method_offset * wordSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
const int bci_offset    = frame::interpreter_frame_bcx_offset    * wordSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
const int locals_offset = frame::interpreter_frame_locals_offset * wordSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
//------------------------------------------------------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
address TemplateInterpreterGenerator::generate_StackOverflowError_handler() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
  address entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
  // Note: There should be a minimal interpreter frame set up when stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
  // overflow occurs since we check explicitly for it now.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
  { Label L;
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
    66
    __ lea(rax, Address(rbp,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
                frame::interpreter_frame_monitor_block_top_offset * wordSize));
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
    68
    __ cmpptr(rax, rsp);  // rax, = maximal rsp for current rbp,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
                        //  (stack grows negative)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
    __ jcc(Assembler::aboveEqual, L); // check if frame is complete
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
    __ stop ("interpreter frame not set up");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
    __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
#endif // ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
  // Restore bcp under the assumption that the current frame is still
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
  // interpreted
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
  __ restore_bcp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
  // expression stack must be empty before entering the VM if an exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
  // happened
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
  __ empty_expression_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
  __ empty_FPU_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
  // throw exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
  __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_StackOverflowError));
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
  return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
address TemplateInterpreterGenerator::generate_ArrayIndexOutOfBounds_handler(const char* name) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
  address entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
  // expression stack must be empty before entering the VM if an exception happened
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
  __ empty_expression_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
  __ empty_FPU_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
  // setup parameters
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
  // ??? convention: expect aberrant index in register rbx,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
  __ lea(rax, ExternalAddress((address)name));
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
  __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_ArrayIndexOutOfBoundsException), rax, rbx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
  return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
address TemplateInterpreterGenerator::generate_ClassCastException_handler() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
  address entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
  // object is at TOS
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   103
  __ pop(rax);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
  // expression stack must be empty before entering the VM if an exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
  // happened
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
  __ empty_expression_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
  __ empty_FPU_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
  __ call_VM(noreg,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
             CAST_FROM_FN_PTR(address,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
                              InterpreterRuntime::throw_ClassCastException),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
             rax);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
  return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   115
// Arguments are: required type at TOS+4, failing object (or NULL) at TOS.
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 2154
diff changeset
   116
address TemplateInterpreterGenerator::generate_WrongMethodType_handler() {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 2154
diff changeset
   117
  address entry = __ pc();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 2154
diff changeset
   118
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 2154
diff changeset
   119
  __ pop(rbx);                  // actual failing object is at TOS
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 2154
diff changeset
   120
  __ pop(rax);                  // required type is at TOS+4
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 2154
diff changeset
   121
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 2154
diff changeset
   122
  __ verify_oop(rbx);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 2154
diff changeset
   123
  __ verify_oop(rax);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 2154
diff changeset
   124
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 2154
diff changeset
   125
  // Various method handle types use interpreter registers as temps.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 2154
diff changeset
   126
  __ restore_bcp();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 2154
diff changeset
   127
  __ restore_locals();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 2154
diff changeset
   128
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 2154
diff changeset
   129
  // Expression stack must be empty before entering the VM for an exception.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 2154
diff changeset
   130
  __ empty_expression_stack();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 2154
diff changeset
   131
  __ empty_FPU_stack();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 2154
diff changeset
   132
  __ call_VM(noreg,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 2154
diff changeset
   133
             CAST_FROM_FN_PTR(address,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 2154
diff changeset
   134
                              InterpreterRuntime::throw_WrongMethodTypeException),
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 2154
diff changeset
   135
             // pass required type, failing object (or NULL)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 2154
diff changeset
   136
             rax, rbx);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 2154
diff changeset
   137
  return entry;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 2154
diff changeset
   138
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 2154
diff changeset
   139
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 2154
diff changeset
   140
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
address TemplateInterpreterGenerator::generate_exception_handler_common(const char* name, const char* message, bool pass_oop) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
  assert(!pass_oop || message == NULL, "either oop or message but not both");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
  address entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
  if (pass_oop) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
    // object is at TOS
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   146
    __ pop(rbx);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
  // expression stack must be empty before entering the VM if an exception happened
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
  __ empty_expression_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
  __ empty_FPU_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
  // setup parameters
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
  __ lea(rax, ExternalAddress((address)name));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
  if (pass_oop) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
    __ call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::create_klass_exception), rax, rbx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
    if (message != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
      __ lea(rbx, ExternalAddress((address)message));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
    } else {
1888
bbf498fb4354 6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents: 1217
diff changeset
   159
      __ movptr(rbx, NULL_WORD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
    __ call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::create_exception), rax, rbx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
  // throw exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
  __ jump(ExternalAddress(Interpreter::throw_exception_entry()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
  return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
address TemplateInterpreterGenerator::generate_continuation_for(TosState state) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
  address entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
  // NULL last_sp until next java call
1888
bbf498fb4354 6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents: 1217
diff changeset
   172
  __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
  __ dispatch_next(state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
  return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
4429
d7eb4e2099aa 6858164: invokedynamic code needs some cleanup (post-6655638)
jrose
parents: 4094
diff changeset
   178
address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step) {
2570
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
   179
  TosState incoming_state = state;
8315
1503f9d7681f 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 7912
diff changeset
   180
  address entry = __ pc();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
#ifdef COMPILER2
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
  // The FPU stack is clean if UseSSE >= 2 but must be cleaned in other cases
2570
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
   184
  if ((incoming_state == ftos && UseSSE < 1) || (incoming_state == dtos && UseSSE < 2)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
    for (int i = 1; i < 8; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
        __ ffree(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
  } else if (UseSSE < 2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
    __ empty_FPU_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
#endif
2570
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
   192
  if ((incoming_state == ftos && UseSSE < 1) || (incoming_state == dtos && UseSSE < 2)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
    __ MacroAssembler::verify_FPU(1, "generate_return_entry_for compiled");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
    __ MacroAssembler::verify_FPU(0, "generate_return_entry_for compiled");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
  // In SSE mode, interpreter returns FP results in xmm0 but they need
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
  // to end up back on the FPU so it can operate on them.
2570
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
   200
  if (incoming_state == ftos && UseSSE >= 1) {
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   201
    __ subptr(rsp, wordSize);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
    __ movflt(Address(rsp, 0), xmm0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
    __ fld_s(Address(rsp, 0));
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   204
    __ addptr(rsp, wordSize);
2570
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
   205
  } else if (incoming_state == dtos && UseSSE >= 2) {
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   206
    __ subptr(rsp, 2*wordSize);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
    __ movdbl(Address(rsp, 0), xmm0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
    __ fld_d(Address(rsp, 0));
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   209
    __ addptr(rsp, 2*wordSize);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
  __ MacroAssembler::verify_FPU(state == ftos || state == dtos ? 1 : 0, "generate_return_entry_for in interpreter");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
  // Restore stack bottom in case i2c adjusted stack
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   215
  __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
  // and NULL it as marker that rsp is now tos until next java call
1888
bbf498fb4354 6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents: 1217
diff changeset
   217
  __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
  __ restore_bcp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
  __ restore_locals();
2570
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
   221
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
   222
  Label L_got_cache, L_giant_index;
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
   223
  if (EnableInvokeDynamic) {
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
   224
    __ cmpb(Address(rsi, 0), Bytecodes::_invokedynamic);
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
   225
    __ jcc(Assembler::equal, L_giant_index);
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
   226
  }
5688
9052dc91ea67 6939207: refactor constant pool index processing
jrose
parents: 5419
diff changeset
   227
  __ get_cache_and_index_at_bcp(rbx, rcx, 1, sizeof(u2));
2570
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
   228
  __ bind(L_got_cache);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
  __ movl(rbx, Address(rbx, rcx,
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   230
                    Address::times_ptr, constantPoolCacheOopDesc::base_offset() +
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
                    ConstantPoolCacheEntry::flags_offset()));
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   232
  __ andptr(rbx, 0xFF);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   233
  __ lea(rsp, Address(rsp, rbx, Interpreter::stackElementScale()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
  __ dispatch_next(state, step);
2570
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
   235
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
   236
  // out of the main line of code...
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
   237
  if (EnableInvokeDynamic) {
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
   238
    __ bind(L_giant_index);
5688
9052dc91ea67 6939207: refactor constant pool index processing
jrose
parents: 5419
diff changeset
   239
    __ get_cache_and_index_at_bcp(rbx, rcx, 1, sizeof(u4));
2570
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
   240
    __ jmp(L_got_cache);
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
   241
  }
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
   242
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
  return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, int step) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
  address entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
  // In SSE mode, FP results are in xmm0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
  if (state == ftos && UseSSE > 0) {
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   252
    __ subptr(rsp, wordSize);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
    __ movflt(Address(rsp, 0), xmm0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
    __ fld_s(Address(rsp, 0));
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   255
    __ addptr(rsp, wordSize);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
  } else if (state == dtos && UseSSE >= 2) {
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   257
    __ subptr(rsp, 2*wordSize);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
    __ movdbl(Address(rsp, 0), xmm0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
    __ fld_d(Address(rsp, 0));
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   260
    __ addptr(rsp, 2*wordSize);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
  __ MacroAssembler::verify_FPU(state == ftos || state == dtos ? 1 : 0, "generate_deopt_entry_for in interpreter");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
  // The stack is not extended by deopt but we must NULL last_sp as this
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
  // entry is like a "return".
1888
bbf498fb4354 6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents: 1217
diff changeset
   267
  __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
  __ restore_bcp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
  __ restore_locals();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
  // handle exceptions
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
  { Label L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
    const Register thread = rcx;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
    __ get_thread(thread);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   274
    __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
    __ jcc(Assembler::zero, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
    __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_pending_exception));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
    __ should_not_reach_here();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
    __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
  __ dispatch_next(state, step);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
  return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
int AbstractInterpreter::BasicType_as_index(BasicType type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
  int i = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
  switch (type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
    case T_BOOLEAN: i = 0; break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
    case T_CHAR   : i = 1; break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
    case T_BYTE   : i = 2; break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
    case T_SHORT  : i = 3; break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
    case T_INT    : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
    case T_LONG   : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
    case T_VOID   : i = 4; break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
    case T_FLOAT  : i = 5; break;  // have to treat float and double separately for SSE
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
    case T_DOUBLE : i = 6; break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
    case T_OBJECT : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
    case T_ARRAY  : i = 7; break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
    default       : ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
  assert(0 <= i && i < AbstractInterpreter::number_of_result_handlers, "index out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
  return i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
address TemplateInterpreterGenerator::generate_result_handler_for(BasicType type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
  address entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
  switch (type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
    case T_BOOLEAN: __ c2bool(rax);            break;
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   310
    case T_CHAR   : __ andptr(rax, 0xFFFF);    break;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
    case T_BYTE   : __ sign_extend_byte (rax); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
    case T_SHORT  : __ sign_extend_short(rax); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
    case T_INT    : /* nothing to do */        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
    case T_DOUBLE :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
    case T_FLOAT  :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
      { const Register t = InterpreterRuntime::SignatureHandlerGenerator::temp();
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   317
        __ pop(t);                            // remove return address first
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
        // Must return a result for interpreter or compiler. In SSE
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
        // mode, results are returned in xmm0 and the FPU stack must
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
        // be empty.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
        if (type == T_FLOAT && UseSSE >= 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
          // Load ST0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
          __ fld_d(Address(rsp, 0));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
          // Store as float and empty fpu stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
          __ fstp_s(Address(rsp, 0));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
          // and reload
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
          __ movflt(xmm0, Address(rsp, 0));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
        } else if (type == T_DOUBLE && UseSSE >= 2 ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
          __ movdbl(xmm0, Address(rsp, 0));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
          // restore ST0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
          __ fld_d(Address(rsp, 0));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
        // and pop the temp
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   335
        __ addptr(rsp, 2 * wordSize);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   336
        __ push(t);                           // restore return address
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
    case T_OBJECT :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
      // retrieve result from frame
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   341
      __ movptr(rax, Address(rbp, frame::interpreter_frame_oop_temp_offset*wordSize));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
      // and verify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
      __ verify_oop(rax);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
    default       : ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
  __ ret(0);                                   // return from result handler
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
  return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
address TemplateInterpreterGenerator::generate_safept_entry_for(TosState state, address runtime_entry) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
  address entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
  __ push(state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
  __ call_VM(noreg, runtime_entry);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
  __ dispatch_via(vtos, Interpreter::_normal_table.table_for(vtos));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
  return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
// Helpers for commoning out cases in the various type of method entries.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
// increment invocation count & check for overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
// Note: checking for negative value instead of overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
//       so we have a 'sticky' overflow test
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
// rbx,: method
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
// rcx: invocation counter
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) {
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   372
  const Address invocation_counter(rbx, in_bytes(methodOopDesc::invocation_counter_offset()) +
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   373
                                        in_bytes(InvocationCounter::counter_offset()));
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   374
  // Note: In tiered we increment either counters in methodOop or in MDO depending if we're profiling or not.
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   375
  if (TieredCompilation) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   376
    int increment = InvocationCounter::count_increment;
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   377
    int mask = ((1 << Tier0InvokeNotifyFreqLog)  - 1) << InvocationCounter::count_shift;
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   378
    Label no_mdo, done;
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   379
    if (ProfileInterpreter) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   380
      // Are we profiling?
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   381
      __ movptr(rax, Address(rbx, methodOopDesc::method_data_offset()));
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   382
      __ testptr(rax, rax);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   383
      __ jccb(Assembler::zero, no_mdo);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   384
      // Increment counter in the MDO
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   385
      const Address mdo_invocation_counter(rax, in_bytes(methodDataOopDesc::invocation_counter_offset()) +
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   386
                                                in_bytes(InvocationCounter::counter_offset()));
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   387
      __ increment_mask_and_jump(mdo_invocation_counter, increment, mask, rcx, false, Assembler::zero, overflow);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   388
      __ jmpb(done);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   389
    }
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   390
    __ bind(no_mdo);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   391
    // Increment counter in methodOop (we don't need to load it, it's in rcx).
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   392
    __ increment_mask_and_jump(invocation_counter, increment, mask, rcx, true, Assembler::zero, overflow);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   393
    __ bind(done);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   394
  } else {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   395
    const Address backedge_counter  (rbx, methodOopDesc::backedge_counter_offset() +
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   396
                                          InvocationCounter::counter_offset());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   398
    if (ProfileInterpreter) { // %%% Merge this into methodDataOop
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   399
      __ incrementl(Address(rbx,methodOopDesc::interpreter_invocation_counter_offset()));
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   400
    }
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   401
    // Update standard invocation counters
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   402
    __ movl(rax, backedge_counter);               // load backedge counter
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   403
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   404
    __ incrementl(rcx, InvocationCounter::count_increment);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   405
    __ andl(rax, InvocationCounter::count_mask_value);  // mask out the status bits
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   406
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   407
    __ movl(invocation_counter, rcx);             // save invocation count
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   408
    __ addl(rcx, rax);                            // add both counters
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   410
    // profile_method is non-null only for interpreted method so
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   411
    // profile_method != NULL == !native_call
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   412
    // BytecodeInterpreter only calls for native so code is elided.
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   413
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   414
    if (ProfileInterpreter && profile_method != NULL) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   415
      // Test to see if we should create a method data oop
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   416
      __ cmp32(rcx,
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   417
               ExternalAddress((address)&InvocationCounter::InterpreterProfileLimit));
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   418
      __ jcc(Assembler::less, *profile_method_continue);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   419
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   420
      // if no method data exists, go to profile_method
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   421
      __ test_method_data_pointer(rax, *profile_method);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   422
    }
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   423
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
    __ cmp32(rcx,
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   425
             ExternalAddress((address)&InvocationCounter::InterpreterInvocationLimit));
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   426
    __ jcc(Assembler::aboveEqual, *overflow);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
void InterpreterGenerator::generate_counter_overflow(Label* do_continue) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
  // Asm interpreter on entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
  // rdi - locals
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
  // rsi - bcp
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
  // rbx, - method
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
  // rdx - cpool
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
  // rbp, - interpreter frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
  // C++ interpreter on entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
  // rsi - new interpreter state pointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
  // rbp - interpreter frame pointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
  // rbx - method
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
  // On return (i.e. jump to entry_point) [ back to invocation of interpreter ]
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
  // rbx, - method
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
  // rcx - rcvr (assuming there is one)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
  // top of stack return address of interpreter caller
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
  // rsp - sender_sp
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
  // C++ interpreter only
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
  // rsi - previous interpreter state pointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
  const Address size_of_parameters(rbx, methodOopDesc::size_of_parameters_offset());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
  // InterpreterRuntime::frequency_counter_overflow takes one argument
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
  // indicating if the counter overflow occurs at a backwards branch (non-NULL bcp).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
  // The call returns the address of the verified entry point for the method or NULL
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
  // if the compilation did not complete (either went background or bailed out).
1909
952b42dad1fc 6795913: A few remaining wrong casts need to be fixed for building hotspot successfully on Mac OS.
xlu
parents: 1888
diff changeset
   459
  __ movptr(rax, (intptr_t)false);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
  __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), rax);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   462
  __ movptr(rbx, Address(rbp, method_offset));   // restore methodOop
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
  // Preserve invariant that rsi/rdi contain bcp/locals of sender frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
  // and jump to the interpreted entry.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
  __ jmp(*do_continue, relocInfo::none);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
void InterpreterGenerator::generate_stack_overflow_check(void) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
  // see if we've got enough room on the stack for locals plus overhead.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
  // the expression stack grows down incrementally, so the normal guard
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
  // page mechanism will work for that.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
  // Registers live on entry:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
  // Asm interpreter
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
  // rdx: number of additional locals this frame needs (what we must check)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
  // rbx,: methodOop
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
  // destroyed on exit
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
  // rax,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
  // NOTE:  since the additional locals are also always pushed (wasn't obvious in
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
  // generate_method_entry) so the guard should work for them too.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
  // monitor entry size: see picture of stack set (generate_method_entry) and frame_x86.hpp
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
  const int entry_size    = frame::interpreter_frame_monitor_size() * wordSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
  // total overhead size: entry_size + (saved rbp, thru expr stack bottom).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
  // be sure to change this if you add/subtract anything to/from the overhead area
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
  const int overhead_size = -(frame::interpreter_frame_initial_sp_offset*wordSize) + entry_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
  const int page_size = os::vm_page_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
  Label after_frame_check;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
  // see if the frame is greater than one page in size. If so,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
  // then we need to verify there is enough stack space remaining
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
  // for the additional locals.
5419
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 5046
diff changeset
   502
  __ cmpl(rdx, (page_size - overhead_size)/Interpreter::stackElementSize);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
  __ jcc(Assembler::belowEqual, after_frame_check);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
  // compute rsp as if this were going to be the last frame on
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
  // the stack before the red zone
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
  Label after_frame_check_pop;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   510
  __ push(rsi);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
  const Register thread = rsi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
  __ get_thread(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
  const Address stack_base(thread, Thread::stack_base_offset());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
  const Address stack_size(thread, Thread::stack_size_offset());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
  // locals + overhead, in bytes
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   520
  __ lea(rax, Address(noreg, rdx, Interpreter::stackElementScale(), overhead_size));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
  Label stack_base_okay, stack_size_okay;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
  // verify that thread stack base is non-zero
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   525
  __ cmpptr(stack_base, (int32_t)NULL_WORD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
  __ jcc(Assembler::notEqual, stack_base_okay);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
  __ stop("stack base is zero");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
  __ bind(stack_base_okay);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
  // verify that thread stack size is non-zero
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   530
  __ cmpptr(stack_size, 0);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
  __ jcc(Assembler::notEqual, stack_size_okay);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
  __ stop("stack size is zero");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
  __ bind(stack_size_okay);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
  // Add stack base to locals and subtract stack size
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   537
  __ addptr(rax, stack_base);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   538
  __ subptr(rax, stack_size);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
  // Use the maximum number of pages we might bang.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
  const int max_pages = StackShadowPages > (StackRedPages+StackYellowPages) ? StackShadowPages :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
                                                                              (StackRedPages+StackYellowPages);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   543
  __ addptr(rax, max_pages * page_size);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
  // check against the current stack bottom
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   546
  __ cmpptr(rsp, rax);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
  __ jcc(Assembler::above, after_frame_check_pop);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   549
  __ pop(rsi);  // get saved bcp / (c++ prev state ).
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   551
  __ pop(rax);  // get return address
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
  __ jump(ExternalAddress(Interpreter::throw_StackOverflowError_entry()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
  // all done with frame size check
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
  __ bind(after_frame_check_pop);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   556
  __ pop(rsi);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
  __ bind(after_frame_check);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
// Allocate monitor and lock method (asm interpreter)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
// rbx, - methodOop
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
void InterpreterGenerator::lock_method(void) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
  // synchronize method
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
  const Address access_flags      (rbx, methodOopDesc::access_flags_offset());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
  const Address monitor_block_top (rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
  const int entry_size            = frame::interpreter_frame_monitor_size() * wordSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
  #ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
    { Label L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
      __ movl(rax, access_flags);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
      __ testl(rax, JVM_ACC_SYNCHRONIZED);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
      __ jcc(Assembler::notZero, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
      __ stop("method doesn't need synchronization");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
      __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
  #endif // ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
  // get synchronization object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
  { Label done;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
    const int mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
    __ movl(rax, access_flags);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
    __ testl(rax, JVM_ACC_STATIC);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   584
    __ movptr(rax, Address(rdi, Interpreter::local_offset_in_bytes(0)));  // get receiver (assume this is frequent case)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
    __ jcc(Assembler::zero, done);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   586
    __ movptr(rax, Address(rbx, methodOopDesc::constants_offset()));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   587
    __ movptr(rax, Address(rax, constantPoolOopDesc::pool_holder_offset_in_bytes()));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   588
    __ movptr(rax, Address(rax, mirror_offset));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
    __ bind(done);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
  // add space for monitor & lock
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   592
  __ subptr(rsp, entry_size);                                           // add space for a monitor entry
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   593
  __ movptr(monitor_block_top, rsp);                                    // set new monitor block top
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   594
  __ movptr(Address(rsp, BasicObjectLock::obj_offset_in_bytes()), rax); // store object
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   595
  __ mov(rdx, rsp);                                                    // object address
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
  __ lock_object(rdx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
// Generate a fixed interpreter frame. This is identical setup for interpreted methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
// and for native methods hence the shared code.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
  // initialize fixed part of activation frame
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   605
  __ push(rax);                                       // save return address
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
  __ enter();                                         // save old & set new rbp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   609
  __ push(rsi);                                       // set sender sp
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   610
  __ push((int32_t)NULL_WORD);                        // leave last_sp as null
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   611
  __ movptr(rsi, Address(rbx,methodOopDesc::const_offset())); // get constMethodOop
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   612
  __ lea(rsi, Address(rsi,constMethodOopDesc::codes_offset())); // get codebase
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   613
  __ push(rbx);                                      // save methodOop
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
  if (ProfileInterpreter) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
    Label method_data_continue;
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   616
    __ movptr(rdx, Address(rbx, in_bytes(methodOopDesc::method_data_offset())));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   617
    __ testptr(rdx, rdx);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
    __ jcc(Assembler::zero, method_data_continue);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   619
    __ addptr(rdx, in_bytes(methodDataOopDesc::data_offset()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
    __ bind(method_data_continue);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   621
    __ push(rdx);                                       // set the mdp (method data pointer)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
  } else {
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   623
    __ push(0);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   626
  __ movptr(rdx, Address(rbx, methodOopDesc::constants_offset()));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   627
  __ movptr(rdx, Address(rdx, constantPoolOopDesc::cache_offset_in_bytes()));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   628
  __ push(rdx);                                       // set constant pool cache
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   629
  __ push(rdi);                                       // set locals pointer
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
  if (native_call) {
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   631
    __ push(0);                                       // no bcp
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
  } else {
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   633
    __ push(rsi);                                     // set bcp
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
    }
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   635
  __ push(0);                                         // reserve word for pointer to expression stack bottom
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   636
  __ movptr(Address(rsp, 0), rsp);                    // set expression stack bottom
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
// End of helpers
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
// Various method entries
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
//------------------------------------------------------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   645
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   646
489c9b5090e2 Initial load
duke
parents:
diff changeset
   647
// Call an accessor method (assuming it is resolved, otherwise drop into vanilla (slow path) entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
address InterpreterGenerator::generate_accessor_entry(void) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
489c9b5090e2 Initial load
duke
parents:
diff changeset
   651
  // rbx,: methodOop
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
  // rcx: receiver (preserve for slow entry into asm interpreter)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
  // rsi: senderSP must preserved for slow path, set SP to it on fast path
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
  address entry_point = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
  Label xreturn_path;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
  // do fastpath for resolved accessor methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
  if (UseFastAccessorMethods) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
    Label slow_path;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   662
    // If we need a safepoint check, generate full interpreter entry.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
    ExternalAddress state(SafepointSynchronize::address_of_state());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
    __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
             SafepointSynchronize::_not_synchronized);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   666
489c9b5090e2 Initial load
duke
parents:
diff changeset
   667
    __ jcc(Assembler::notEqual, slow_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
    // ASM/C++ Interpreter
489c9b5090e2 Initial load
duke
parents:
diff changeset
   669
    // Code: _aload_0, _(i|a)getfield, _(i|a)return or any rewrites thereof; parameter size = 1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   670
    // Note: We can only use this code if the getfield has been resolved
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
    //       and if we don't have a null-pointer exception => check for
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
    //       these conditions first and use slow path if necessary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
    // rbx,: method
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
    // rcx: receiver
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   675
    __ movptr(rax, Address(rsp, wordSize));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
    // check if local 0 != NULL and read field
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   678
    __ testptr(rax, rax);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
    __ jcc(Assembler::zero, slow_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   681
    __ movptr(rdi, Address(rbx, methodOopDesc::constants_offset()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
    // read first instruction word and extract bytecode @ 1 and index @ 2
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   683
    __ movptr(rdx, Address(rbx, methodOopDesc::const_offset()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   684
    __ movl(rdx, Address(rdx, constMethodOopDesc::codes_offset()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   685
    // Shift codes right to get the index on the right.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
    // The bytecode fetched looks like <index><0xb4><0x2a>
489c9b5090e2 Initial load
duke
parents:
diff changeset
   687
    __ shrl(rdx, 2*BitsPerByte);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
    __ shll(rdx, exact_log2(in_words(ConstantPoolCacheEntry::size())));
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   689
    __ movptr(rdi, Address(rdi, constantPoolOopDesc::cache_offset_in_bytes()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
    // rax,: local 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
    // rbx,: method
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
    // rcx: receiver - do not destroy since it is needed for slow path!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
    // rcx: scratch
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
    // rdx: constant pool cache index
489c9b5090e2 Initial load
duke
parents:
diff changeset
   696
    // rdi: constant pool cache
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
    // rsi: sender sp
489c9b5090e2 Initial load
duke
parents:
diff changeset
   698
489c9b5090e2 Initial load
duke
parents:
diff changeset
   699
    // check if getfield has been resolved and read constant pool cache entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
    // check the validity of the cache entry by testing whether _indices field
489c9b5090e2 Initial load
duke
parents:
diff changeset
   701
    // contains Bytecode::_getfield in b1 byte.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   702
    assert(in_words(ConstantPoolCacheEntry::size()) == 4, "adjust shift below");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   703
    __ movl(rcx,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   704
            Address(rdi,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   705
                    rdx,
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   706
                    Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   707
    __ shrl(rcx, 2*BitsPerByte);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   708
    __ andl(rcx, 0xFF);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   709
    __ cmpl(rcx, Bytecodes::_getfield);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   710
    __ jcc(Assembler::notEqual, slow_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   711
489c9b5090e2 Initial load
duke
parents:
diff changeset
   712
    // Note: constant pool entry is not valid before bytecode is resolved
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   713
    __ movptr(rcx,
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   714
              Address(rdi,
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   715
                      rdx,
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   716
                      Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f2_offset()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   717
    __ movl(rdx,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
            Address(rdi,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   719
                    rdx,
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   720
                    Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::flags_offset()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   721
489c9b5090e2 Initial load
duke
parents:
diff changeset
   722
    Label notByte, notShort, notChar;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   723
    const Address field_address (rax, rcx, Address::times_1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   724
489c9b5090e2 Initial load
duke
parents:
diff changeset
   725
    // Need to differentiate between igetfield, agetfield, bgetfield etc.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   726
    // because they are different sizes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   727
    // Use the type from the constant pool cache
489c9b5090e2 Initial load
duke
parents:
diff changeset
   728
    __ shrl(rdx, ConstantPoolCacheEntry::tosBits);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   729
    // Make sure we don't need to mask rdx for tosBits after the above shift
489c9b5090e2 Initial load
duke
parents:
diff changeset
   730
    ConstantPoolCacheEntry::verify_tosBits();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   731
    __ cmpl(rdx, btos);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   732
    __ jcc(Assembler::notEqual, notByte);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   733
    __ load_signed_byte(rax, field_address);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   734
    __ jmp(xreturn_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   735
489c9b5090e2 Initial load
duke
parents:
diff changeset
   736
    __ bind(notByte);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   737
    __ cmpl(rdx, stos);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   738
    __ jcc(Assembler::notEqual, notShort);
2148
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 1909
diff changeset
   739
    __ load_signed_short(rax, field_address);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
    __ jmp(xreturn_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   741
489c9b5090e2 Initial load
duke
parents:
diff changeset
   742
    __ bind(notShort);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   743
    __ cmpl(rdx, ctos);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   744
    __ jcc(Assembler::notEqual, notChar);
2148
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 1909
diff changeset
   745
    __ load_unsigned_short(rax, field_address);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   746
    __ jmp(xreturn_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   747
489c9b5090e2 Initial load
duke
parents:
diff changeset
   748
    __ bind(notChar);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   749
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   750
    Label okay;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   751
    __ cmpl(rdx, atos);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   752
    __ jcc(Assembler::equal, okay);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   753
    __ cmpl(rdx, itos);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   754
    __ jcc(Assembler::equal, okay);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   755
    __ stop("what type is this?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   756
    __ bind(okay);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   757
#endif // ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   758
    // All the rest are a 32 bit wordsize
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   759
    // This is ok for now. Since fast accessors should be going away
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   760
    __ movptr(rax, field_address);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   761
489c9b5090e2 Initial load
duke
parents:
diff changeset
   762
    __ bind(xreturn_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   763
489c9b5090e2 Initial load
duke
parents:
diff changeset
   764
    // _ireturn/_areturn
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   765
    __ pop(rdi);                               // get return address
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   766
    __ mov(rsp, rsi);                          // set sp to sender sp
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   767
    __ jmp(rdi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   768
489c9b5090e2 Initial load
duke
parents:
diff changeset
   769
    // generate a vanilla interpreter entry as the slow path
489c9b5090e2 Initial load
duke
parents:
diff changeset
   770
    __ bind(slow_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   771
489c9b5090e2 Initial load
duke
parents:
diff changeset
   772
    (void) generate_normal_entry(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   773
    return entry_point;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   774
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   775
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   776
489c9b5090e2 Initial load
duke
parents:
diff changeset
   777
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   778
9176
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   779
// Method entry for java.lang.ref.Reference.get.
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   780
address InterpreterGenerator::generate_Reference_get_entry(void) {
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   781
#ifndef SERIALGC
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   782
  // Code: _aload_0, _getfield, _areturn
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   783
  // parameter size = 1
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   784
  //
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   785
  // The code that gets generated by this routine is split into 2 parts:
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   786
  //    1. The "intrinsified" code for G1 (or any SATB based GC),
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   787
  //    2. The slow path - which is an expansion of the regular method entry.
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   788
  //
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   789
  // Notes:-
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   790
  // * In the G1 code we do not check whether we need to block for
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   791
  //   a safepoint. If G1 is enabled then we must execute the specialized
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   792
  //   code for Reference.get (except when the Reference object is null)
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   793
  //   so that we can log the value in the referent field with an SATB
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   794
  //   update buffer.
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   795
  //   If the code for the getfield template is modified so that the
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   796
  //   G1 pre-barrier code is executed when the current method is
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   797
  //   Reference.get() then going through the normal method entry
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   798
  //   will be fine.
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   799
  // * The G1 code below can, however, check the receiver object (the instance
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   800
  //   of java.lang.Reference) and jump to the slow path if null. If the
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   801
  //   Reference object is null then we obviously cannot fetch the referent
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   802
  //   and so we don't need to call the G1 pre-barrier. Thus we can use the
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   803
  //   regular method entry code to generate the NPE.
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   804
  //
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   805
  // This code is based on generate_accessor_enty.
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   806
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   807
  // rbx,: methodOop
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   808
  // rcx: receiver (preserve for slow entry into asm interpreter)
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   809
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   810
  // rsi: senderSP must preserved for slow path, set SP to it on fast path
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   811
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   812
  address entry = __ pc();
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   813
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   814
  const int referent_offset = java_lang_ref_Reference::referent_offset;
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   815
  guarantee(referent_offset > 0, "referent offset not initialized");
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   816
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   817
  if (UseG1GC) {
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   818
    Label slow_path;
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   819
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   820
    // Check if local 0 != NULL
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   821
    // If the receiver is null then it is OK to jump to the slow path.
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   822
    __ movptr(rax, Address(rsp, wordSize));
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   823
    __ testptr(rax, rax);
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   824
    __ jcc(Assembler::zero, slow_path);
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   825
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   826
    // rax: local 0 (must be preserved across the G1 barrier call)
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   827
    //
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   828
    // rbx: method (at this point it's scratch)
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   829
    // rcx: receiver (at this point it's scratch)
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   830
    // rdx: scratch
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   831
    // rdi: scratch
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   832
    //
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   833
    // rsi: sender sp
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   834
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   835
    // Preserve the sender sp in case the pre-barrier
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   836
    // calls the runtime
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   837
    __ push(rsi);
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   838
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   839
    // Load the value of the referent field.
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   840
    const Address field_address(rax, referent_offset);
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   841
    __ movptr(rax, field_address);
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   842
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   843
    // Generate the G1 pre-barrier code to log the value of
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   844
    // the referent field in an SATB buffer.
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   845
    __ get_thread(rcx);
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   846
    __ g1_write_barrier_pre(noreg /* obj */,
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   847
                            rax /* pre_val */,
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   848
                            rcx /* thread */,
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   849
                            rbx /* tmp */,
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   850
                            true /* tosca_save */,
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   851
                            true /* expand_call */);
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   852
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   853
    // _areturn
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   854
    __ pop(rsi);                // get sender sp
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   855
    __ pop(rdi);                // get return address
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   856
    __ mov(rsp, rsi);           // set sp to sender sp
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   857
    __ jmp(rdi);
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   858
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   859
    __ bind(slow_path);
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   860
    (void) generate_normal_entry(false);
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   861
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   862
    return entry;
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   863
  }
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   864
#endif // SERIALGC
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   865
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   866
  // If G1 is not enabled then attempt to go through the accessor entry point
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   867
  // Reference.get is an accessor
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   868
  return generate_accessor_entry();
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   869
}
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
   870
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   871
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   872
// Interpreter stub for calling a native method. (asm interpreter)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   873
// This sets up a somewhat different looking stack for calling the native method
489c9b5090e2 Initial load
duke
parents:
diff changeset
   874
// than the typical interpreter frame setup.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   875
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   876
489c9b5090e2 Initial load
duke
parents:
diff changeset
   877
address InterpreterGenerator::generate_native_entry(bool synchronized) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   878
  // determine code generation flags
489c9b5090e2 Initial load
duke
parents:
diff changeset
   879
  bool inc_counter  = UseCompiler || CountCompiledCalls;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   880
489c9b5090e2 Initial load
duke
parents:
diff changeset
   881
  // rbx,: methodOop
489c9b5090e2 Initial load
duke
parents:
diff changeset
   882
  // rsi: sender sp
489c9b5090e2 Initial load
duke
parents:
diff changeset
   883
  // rsi: previous interpreter state (C++ interpreter) must preserve
489c9b5090e2 Initial load
duke
parents:
diff changeset
   884
  address entry_point = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   885
489c9b5090e2 Initial load
duke
parents:
diff changeset
   886
489c9b5090e2 Initial load
duke
parents:
diff changeset
   887
  const Address size_of_parameters(rbx, methodOopDesc::size_of_parameters_offset());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   888
  const Address invocation_counter(rbx, methodOopDesc::invocation_counter_offset() + InvocationCounter::counter_offset());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   889
  const Address access_flags      (rbx, methodOopDesc::access_flags_offset());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   890
489c9b5090e2 Initial load
duke
parents:
diff changeset
   891
  // get parameter size (always needed)
2148
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 1909
diff changeset
   892
  __ load_unsigned_short(rcx, size_of_parameters);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   893
489c9b5090e2 Initial load
duke
parents:
diff changeset
   894
  // native calls don't need the stack size check since they have no expression stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
   895
  // and the arguments are already on the stack and we only add a handful of words
489c9b5090e2 Initial load
duke
parents:
diff changeset
   896
  // to the stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
   897
489c9b5090e2 Initial load
duke
parents:
diff changeset
   898
  // rbx,: methodOop
489c9b5090e2 Initial load
duke
parents:
diff changeset
   899
  // rcx: size of parameters
489c9b5090e2 Initial load
duke
parents:
diff changeset
   900
  // rsi: sender sp
489c9b5090e2 Initial load
duke
parents:
diff changeset
   901
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   902
  __ pop(rax);                                       // get return address
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   903
  // for natives the size of locals is zero
489c9b5090e2 Initial load
duke
parents:
diff changeset
   904
489c9b5090e2 Initial load
duke
parents:
diff changeset
   905
  // compute beginning of parameters (rdi)
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   906
  __ lea(rdi, Address(rsp, rcx, Interpreter::stackElementScale(), -wordSize));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   907
489c9b5090e2 Initial load
duke
parents:
diff changeset
   908
489c9b5090e2 Initial load
duke
parents:
diff changeset
   909
  // add 2 zero-initialized slots for native calls
489c9b5090e2 Initial load
duke
parents:
diff changeset
   910
  // NULL result handler
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   911
  __ push((int32_t)NULL_WORD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   912
  // NULL oop temp (mirror or jni oop result)
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   913
  __ push((int32_t)NULL_WORD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   914
489c9b5090e2 Initial load
duke
parents:
diff changeset
   915
  if (inc_counter) __ movl(rcx, invocation_counter);  // (pre-)fetch invocation count
489c9b5090e2 Initial load
duke
parents:
diff changeset
   916
  // initialize fixed part of activation frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
   917
489c9b5090e2 Initial load
duke
parents:
diff changeset
   918
  generate_fixed_frame(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   919
489c9b5090e2 Initial load
duke
parents:
diff changeset
   920
  // make sure method is native & not abstract
489c9b5090e2 Initial load
duke
parents:
diff changeset
   921
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   922
  __ movl(rax, access_flags);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   923
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   924
    Label L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   925
    __ testl(rax, JVM_ACC_NATIVE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   926
    __ jcc(Assembler::notZero, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   927
    __ stop("tried to execute non-native method as native");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   928
    __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   929
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   930
  { Label L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   931
    __ testl(rax, JVM_ACC_ABSTRACT);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   932
    __ jcc(Assembler::zero, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   933
    __ stop("tried to execute abstract method in interpreter");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   934
    __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   935
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   936
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   937
489c9b5090e2 Initial load
duke
parents:
diff changeset
   938
  // Since at this point in the method invocation the exception handler
489c9b5090e2 Initial load
duke
parents:
diff changeset
   939
  // would try to exit the monitor of synchronized methods which hasn't
489c9b5090e2 Initial load
duke
parents:
diff changeset
   940
  // been entered yet, we set the thread local variable
489c9b5090e2 Initial load
duke
parents:
diff changeset
   941
  // _do_not_unlock_if_synchronized to true. The remove_activation will
489c9b5090e2 Initial load
duke
parents:
diff changeset
   942
  // check this flag.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   943
489c9b5090e2 Initial load
duke
parents:
diff changeset
   944
  __ get_thread(rax);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   945
  const Address do_not_unlock_if_synchronized(rax,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   946
        in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   947
  __ movbool(do_not_unlock_if_synchronized, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   948
489c9b5090e2 Initial load
duke
parents:
diff changeset
   949
  // increment invocation count & check for overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
   950
  Label invocation_counter_overflow;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   951
  if (inc_counter) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   952
    generate_counter_incr(&invocation_counter_overflow, NULL, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   953
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   954
489c9b5090e2 Initial load
duke
parents:
diff changeset
   955
  Label continue_after_compile;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   956
  __ bind(continue_after_compile);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   957
489c9b5090e2 Initial load
duke
parents:
diff changeset
   958
  bang_stack_shadow_pages(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   959
489c9b5090e2 Initial load
duke
parents:
diff changeset
   960
  // reset the _do_not_unlock_if_synchronized flag
489c9b5090e2 Initial load
duke
parents:
diff changeset
   961
  __ get_thread(rax);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   962
  __ movbool(do_not_unlock_if_synchronized, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   963
489c9b5090e2 Initial load
duke
parents:
diff changeset
   964
  // check for synchronized methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
   965
  // Must happen AFTER invocation_counter check and stack overflow check,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   966
  // so method is not locked if overflows.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   967
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   968
  if (synchronized) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   969
    lock_method();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   970
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   971
    // no synchronization necessary
489c9b5090e2 Initial load
duke
parents:
diff changeset
   972
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   973
      { Label L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   974
        __ movl(rax, access_flags);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   975
        __ testl(rax, JVM_ACC_SYNCHRONIZED);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   976
        __ jcc(Assembler::zero, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   977
        __ stop("method needs synchronization");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   978
        __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   979
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   980
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   981
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   982
489c9b5090e2 Initial load
duke
parents:
diff changeset
   983
  // start execution
489c9b5090e2 Initial load
duke
parents:
diff changeset
   984
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   985
  { Label L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   986
    const Address monitor_block_top (rbp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   987
                 frame::interpreter_frame_monitor_block_top_offset * wordSize);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   988
    __ movptr(rax, monitor_block_top);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
   989
    __ cmpptr(rax, rsp);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   990
    __ jcc(Assembler::equal, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   991
    __ stop("broken stack frame setup in interpreter");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   992
    __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   993
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   994
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   995
489c9b5090e2 Initial load
duke
parents:
diff changeset
   996
  // jvmti/dtrace support
489c9b5090e2 Initial load
duke
parents:
diff changeset
   997
  __ notify_method_entry();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   998
489c9b5090e2 Initial load
duke
parents:
diff changeset
   999
  // work registers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1000
  const Register method = rbx;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1001
  const Register thread = rdi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1002
  const Register t      = rcx;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1003
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1004
  // allocate space for parameters
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1005
  __ get_method(method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1006
  __ verify_oop(method);
2148
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 1909
diff changeset
  1007
  __ load_unsigned_short(t, Address(method, methodOopDesc::size_of_parameters_offset()));
5419
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 5046
diff changeset
  1008
  __ shlptr(t, Interpreter::logStackElementSize);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1009
  __ addptr(t, 2*wordSize);     // allocate two more slots for JNIEnv and possible mirror
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1010
  __ subptr(rsp, t);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1011
  __ andptr(rsp, -(StackAlignmentInBytes)); // gcc needs 16 byte aligned stacks to do XMM intrinsics
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1012
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1013
  // get signature handler
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1014
  { Label L;
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1015
    __ movptr(t, Address(method, methodOopDesc::signature_handler_offset()));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1016
    __ testptr(t, t);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1017
    __ jcc(Assembler::notZero, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1018
    __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1019
    __ get_method(method);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1020
    __ movptr(t, Address(method, methodOopDesc::signature_handler_offset()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1021
    __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1022
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1023
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1024
  // call signature handler
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1025
  assert(InterpreterRuntime::SignatureHandlerGenerator::from() == rdi, "adjust this code");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1026
  assert(InterpreterRuntime::SignatureHandlerGenerator::to  () == rsp, "adjust this code");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1027
  assert(InterpreterRuntime::SignatureHandlerGenerator::temp() == t  , "adjust this code");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1028
  // The generated handlers do not touch RBX (the method oop).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1029
  // However, large signatures cannot be cached and are generated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1030
  // each time here.  The slow-path generator will blow RBX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1031
  // sometime, so we must reload it after the call.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1032
  __ call(t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1033
  __ get_method(method);        // slow path call blows RBX on DevStudio 5.0
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1034
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1035
  // result handler is in rax,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1036
  // set result handler
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1037
  __ movptr(Address(rbp, frame::interpreter_frame_result_handler_offset*wordSize), rax);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1038
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1039
  // pass mirror handle if static call
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1040
  { Label L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1041
    const int mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1042
    __ movl(t, Address(method, methodOopDesc::access_flags_offset()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1043
    __ testl(t, JVM_ACC_STATIC);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1044
    __ jcc(Assembler::zero, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1045
    // get mirror
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1046
    __ movptr(t, Address(method, methodOopDesc:: constants_offset()));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1047
    __ movptr(t, Address(t, constantPoolOopDesc::pool_holder_offset_in_bytes()));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1048
    __ movptr(t, Address(t, mirror_offset));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1049
    // copy mirror into activation frame
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1050
    __ movptr(Address(rbp, frame::interpreter_frame_oop_temp_offset * wordSize), t);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1051
    // pass handle to mirror
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1052
    __ lea(t, Address(rbp, frame::interpreter_frame_oop_temp_offset * wordSize));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1053
    __ movptr(Address(rsp, wordSize), t);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1054
    __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1055
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1056
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1057
  // get native function entry point
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1058
  { Label L;
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1059
    __ movptr(rax, Address(method, methodOopDesc::native_function_offset()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1060
    ExternalAddress unsatisfied(SharedRuntime::native_method_throw_unsatisfied_link_error_entry());
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1061
    __ cmpptr(rax, unsatisfied.addr());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1062
    __ jcc(Assembler::notEqual, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1063
    __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1064
    __ get_method(method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1065
    __ verify_oop(method);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1066
    __ movptr(rax, Address(method, methodOopDesc::native_function_offset()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1067
    __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1068
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1069
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1070
  // pass JNIEnv
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1071
  __ get_thread(thread);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1072
  __ lea(t, Address(thread, JavaThread::jni_environment_offset()));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1073
  __ movptr(Address(rsp, 0), t);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1074
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1075
  // set_last_Java_frame_before_call
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1076
  // It is enough that the pc()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1077
  // points into the right code segment. It does not have to be the correct return pc.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1078
  __ set_last_Java_frame(thread, noreg, rbp, __ pc());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1079
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1080
  // change thread state
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1081
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1082
  { Label L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1083
    __ movl(t, Address(thread, JavaThread::thread_state_offset()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1084
    __ cmpl(t, _thread_in_Java);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1085
    __ jcc(Assembler::equal, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1086
    __ stop("Wrong thread state in native stub");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1087
    __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1088
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1089
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1090
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1091
  // Change state to native
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1092
  __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_native);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1093
  __ call(rax);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1094
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1095
  // result potentially in rdx:rax or ST0
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1096
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1097
  // Either restore the MXCSR register after returning from the JNI Call
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1098
  // or verify that it wasn't changed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1099
  if (VM_Version::supports_sse()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1100
    if (RestoreMXCSROnJNICalls) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1101
      __ ldmxcsr(ExternalAddress(StubRoutines::addr_mxcsr_std()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1102
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1103
    else if (CheckJNICalls ) {
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1104
      __ call(RuntimeAddress(StubRoutines::x86::verify_mxcsr_entry()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1105
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1106
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1107
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1108
  // Either restore the x87 floating pointer control word after returning
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1109
  // from the JNI call or verify that it wasn't changed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1110
  if (CheckJNICalls) {
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1111
    __ call(RuntimeAddress(StubRoutines::x86::verify_fpu_cntrl_wrd_entry()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1112
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1113
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1114
  // save potential result in ST(0) & rdx:rax
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1115
  // (if result handler is the T_FLOAT or T_DOUBLE handler, result must be in ST0 -
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1116
  // the check is necessary to avoid potential Intel FPU overflow problems by saving/restoring 'empty' FPU registers)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1117
  // It is safe to do this push because state is _thread_in_native and return address will be found
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1118
  // via _last_native_pc and not via _last_jave_sp
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1119
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1120
  // NOTE: the order of theses push(es) is known to frame::interpreter_frame_result.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1121
  // If the order changes or anything else is added to the stack the code in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1122
  // interpreter_frame_result will have to be changed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1123
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1124
  { Label L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1125
    Label push_double;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1126
    ExternalAddress float_handler(AbstractInterpreter::result_handler(T_FLOAT));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1127
    ExternalAddress double_handler(AbstractInterpreter::result_handler(T_DOUBLE));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1128
    __ cmpptr(Address(rbp, (frame::interpreter_frame_oop_temp_offset + 1)*wordSize),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1129
              float_handler.addr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1130
    __ jcc(Assembler::equal, push_double);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1131
    __ cmpptr(Address(rbp, (frame::interpreter_frame_oop_temp_offset + 1)*wordSize),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1132
              double_handler.addr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1133
    __ jcc(Assembler::notEqual, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1134
    __ bind(push_double);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1135
    __ push(dtos);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1136
    __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1137
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1138
  __ push(ltos);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1139
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1140
  // change thread state
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1141
  __ get_thread(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1142
  __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_native_trans);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1143
  if(os::is_MP()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1144
    if (UseMembar) {
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1145
      // Force this write out before the read below
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1146
      __ membar(Assembler::Membar_mask_bits(
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1147
           Assembler::LoadLoad | Assembler::LoadStore |
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1148
           Assembler::StoreLoad | Assembler::StoreStore));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1149
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1150
      // Write serialization page so VM thread can do a pseudo remote membar.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1151
      // We use the current thread pointer to calculate a thread specific
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1152
      // offset to write to within the page. This minimizes bus traffic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1153
      // due to cache line collision.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1154
      __ serialize_memory(thread, rcx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1155
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1156
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1157
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1158
  if (AlwaysRestoreFPU) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1159
    //  Make sure the control word is correct.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1160
    __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1161
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1162
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1163
  // check for safepoint operation in progress and/or pending suspend requests
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1164
  { Label Continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1165
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1166
    __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1167
             SafepointSynchronize::_not_synchronized);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1168
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1169
    Label L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1170
    __ jcc(Assembler::notEqual, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1171
    __ cmpl(Address(thread, JavaThread::suspend_flags_offset()), 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1172
    __ jcc(Assembler::equal, Continue);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1173
    __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1174
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1175
    // Don't use call_VM as it will see a possible pending exception and forward it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1176
    // and never return here preventing us from clearing _last_native_pc down below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1177
    // 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
  1178
    // preserved and correspond to the bcp/locals pointers. So we do a runtime call
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1179
    // by hand.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1180
    //
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1181
    __ push(thread);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1182
    __ call(RuntimeAddress(CAST_FROM_FN_PTR(address,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1183
                                            JavaThread::check_special_condition_for_native_trans)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1184
    __ increment(rsp, wordSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1185
    __ get_thread(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1186
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1187
    __ bind(Continue);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1188
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1189
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1190
  // change thread state
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1191
  __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_Java);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1192
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1193
  __ reset_last_Java_frame(thread, true, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1194
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1195
  // reset handle block
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1196
  __ movptr(t, Address(thread, JavaThread::active_handles_offset()));
1888
bbf498fb4354 6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents: 1217
diff changeset
  1197
  __ movptr(Address(t, JNIHandleBlock::top_offset_in_bytes()), NULL_WORD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1198
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1199
  // If result was an oop then unbox and save it in the frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1200
  { Label L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1201
    Label no_oop, store_result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1202
    ExternalAddress handler(AbstractInterpreter::result_handler(T_OBJECT));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1203
    __ cmpptr(Address(rbp, frame::interpreter_frame_result_handler_offset*wordSize),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1204
              handler.addr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1205
    __ jcc(Assembler::notEqual, no_oop);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1206
    __ cmpptr(Address(rsp, 0), (int32_t)NULL_WORD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1207
    __ pop(ltos);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1208
    __ testptr(rax, rax);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1209
    __ jcc(Assembler::zero, store_result);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1210
    // unbox
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1211
    __ movptr(rax, Address(rax, 0));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1212
    __ bind(store_result);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1213
    __ movptr(Address(rbp, (frame::interpreter_frame_oop_temp_offset)*wordSize), rax);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1214
    // keep stack depth as expected by pushing oop which will eventually be discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1215
    __ push(ltos);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1216
    __ bind(no_oop);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1217
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1218
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1219
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1220
     Label no_reguard;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1221
     __ cmpl(Address(thread, JavaThread::stack_guard_state_offset()), JavaThread::stack_guard_yellow_disabled);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1222
     __ jcc(Assembler::notEqual, no_reguard);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1223
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1224
     __ pusha();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1225
     __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages)));
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1226
     __ popa();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1227
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1228
     __ bind(no_reguard);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1229
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1230
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1231
  // restore rsi to have legal interpreter frame,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1232
  // i.e., bci == 0 <=> rsi == code_base()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1233
  // Can't call_VM until bcp is within reasonable.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1234
  __ get_method(method);      // method is junk from thread_in_native to now.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1235
  __ verify_oop(method);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1236
  __ movptr(rsi, Address(method,methodOopDesc::const_offset()));   // get constMethodOop
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1237
  __ lea(rsi, Address(rsi,constMethodOopDesc::codes_offset()));    // get codebase
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1238
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1239
  // handle exceptions (exception handling will handle unlocking!)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1240
  { Label L;
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1241
    __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1242
    __ jcc(Assembler::zero, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1243
    // Note: At some point we may want to unify this with the code used in call_VM_base();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1244
    //       i.e., we should use the StubRoutines::forward_exception code. For now this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1245
    //       doesn't work here because the rsp is not correctly set at this point.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1246
    __ MacroAssembler::call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_pending_exception));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1247
    __ should_not_reach_here();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1248
    __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1249
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1250
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1251
  // do unlocking if necessary
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1252
  { Label L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1253
    __ movl(t, Address(method, methodOopDesc::access_flags_offset()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1254
    __ testl(t, JVM_ACC_SYNCHRONIZED);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1255
    __ jcc(Assembler::zero, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1256
    // the code below should be shared with interpreter macro assembler implementation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1257
    { Label unlock;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1258
      // BasicObjectLock will be first in list, since this is a synchronized method. However, need
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1259
      // to check that the object has not been unlocked by an explicit monitorexit bytecode.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1260
      const Address monitor(rbp, frame::interpreter_frame_initial_sp_offset * wordSize - (int)sizeof(BasicObjectLock));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1261
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1262
      __ lea(rdx, monitor);                   // address of first monitor
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1263
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1264
      __ movptr(t, Address(rdx, BasicObjectLock::obj_offset_in_bytes()));
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1265
      __ testptr(t, t);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1266
      __ jcc(Assembler::notZero, unlock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1267
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1268
      // Entry already unlocked, need to throw exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1269
      __ MacroAssembler::call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_illegal_monitor_state_exception));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1270
      __ should_not_reach_here();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1271
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1272
      __ bind(unlock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1273
      __ unlock_object(rdx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1274
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1275
    __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1276
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1277
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1278
  // jvmti/dtrace support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1279
  // Note: This must happen _after_ handling/throwing any exceptions since
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1280
  //       the exception handler code notifies the runtime of method exits
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1281
  //       too. If this happens before, method entry/exit notifications are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1282
  //       not properly paired (was bug - gri 11/22/99).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1283
  __ notify_method_exit(vtos, InterpreterMacroAssembler::NotifyJVMTI);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1284
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1285
  // restore potential result in rdx:rax, call result handler to restore potential result in ST0 & handle result
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1286
  __ pop(ltos);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1287
  __ movptr(t, Address(rbp, frame::interpreter_frame_result_handler_offset*wordSize));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1288
  __ call(t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1289
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1290
  // remove activation
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1291
  __ movptr(t, Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize)); // get sender sp
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1292
  __ leave();                                // remove frame anchor
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1293
  __ pop(rdi);                               // get return address
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1294
  __ mov(rsp, t);                            // set sp to sender sp
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1295
  __ jmp(rdi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1296
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1297
  if (inc_counter) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1298
    // Handle overflow of counter and compile method
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1299
    __ bind(invocation_counter_overflow);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1300
    generate_counter_overflow(&continue_after_compile);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1301
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1302
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1303
  return entry_point;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1304
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1305
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1306
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1307
// Generic interpreted method entry to (asm) interpreter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1308
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1309
address InterpreterGenerator::generate_normal_entry(bool synchronized) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1310
  // determine code generation flags
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1311
  bool inc_counter  = UseCompiler || CountCompiledCalls;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1312
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1313
  // rbx,: methodOop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1314
  // rsi: sender sp
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1315
  address entry_point = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1316
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1317
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1318
  const Address size_of_parameters(rbx, methodOopDesc::size_of_parameters_offset());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1319
  const Address size_of_locals    (rbx, methodOopDesc::size_of_locals_offset());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1320
  const Address invocation_counter(rbx, methodOopDesc::invocation_counter_offset() + InvocationCounter::counter_offset());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1321
  const Address access_flags      (rbx, methodOopDesc::access_flags_offset());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1322
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1323
  // get parameter size (always needed)
2148
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 1909
diff changeset
  1324
  __ load_unsigned_short(rcx, size_of_parameters);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1325
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1326
  // rbx,: methodOop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1327
  // rcx: size of parameters
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1328
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1329
  // rsi: sender_sp (could differ from sp+wordSize if we were called via c2i )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1330
2148
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 1909
diff changeset
  1331
  __ load_unsigned_short(rdx, size_of_locals);       // get size of locals in words
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1332
  __ subl(rdx, rcx);                                // rdx = no. of additional locals
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1333
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1334
  // see if we've got enough room on the stack for locals plus overhead.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1335
  generate_stack_overflow_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1336
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1337
  // get return address
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1338
  __ pop(rax);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1339
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1340
  // compute beginning of parameters (rdi)
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1341
  __ lea(rdi, Address(rsp, rcx, Interpreter::stackElementScale(), -wordSize));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1342
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1343
  // rdx - # of additional locals
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1344
  // allocate space for locals
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1345
  // explicitly initialize locals
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1346
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1347
    Label exit, loop;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1348
    __ testl(rdx, rdx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1349
    __ jcc(Assembler::lessEqual, exit);               // do nothing if rdx <= 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1350
    __ bind(loop);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1351
    __ push((int32_t)NULL_WORD);                      // initialize local variables
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1352
    __ decrement(rdx);                                // until everything initialized
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1353
    __ jcc(Assembler::greater, loop);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1354
    __ bind(exit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1355
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1356
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1357
  if (inc_counter) __ movl(rcx, invocation_counter);  // (pre-)fetch invocation count
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1358
  // initialize fixed part of activation frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1359
  generate_fixed_frame(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1360
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1361
  // make sure method is not native & not abstract
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1362
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1363
  __ movl(rax, access_flags);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1364
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1365
    Label L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1366
    __ testl(rax, JVM_ACC_NATIVE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1367
    __ jcc(Assembler::zero, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1368
    __ stop("tried to execute native method as non-native");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1369
    __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1370
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1371
  { Label L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1372
    __ testl(rax, JVM_ACC_ABSTRACT);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1373
    __ jcc(Assembler::zero, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1374
    __ stop("tried to execute abstract method in interpreter");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1375
    __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1376
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1377
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1378
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1379
  // Since at this point in the method invocation the exception handler
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1380
  // would try to exit the monitor of synchronized methods which hasn't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1381
  // been entered yet, we set the thread local variable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1382
  // _do_not_unlock_if_synchronized to true. The remove_activation will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1383
  // check this flag.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1384
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1385
  __ get_thread(rax);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1386
  const Address do_not_unlock_if_synchronized(rax,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1387
        in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1388
  __ movbool(do_not_unlock_if_synchronized, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1389
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1390
  // increment invocation count & check for overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1391
  Label invocation_counter_overflow;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1392
  Label profile_method;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1393
  Label profile_method_continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1394
  if (inc_counter) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1395
    generate_counter_incr(&invocation_counter_overflow, &profile_method, &profile_method_continue);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1396
    if (ProfileInterpreter) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1397
      __ bind(profile_method_continue);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1398
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1399
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1400
  Label continue_after_compile;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1401
  __ bind(continue_after_compile);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1402
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1403
  bang_stack_shadow_pages(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1404
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1405
  // reset the _do_not_unlock_if_synchronized flag
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1406
  __ get_thread(rax);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1407
  __ movbool(do_not_unlock_if_synchronized, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1408
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1409
  // check for synchronized methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1410
  // Must happen AFTER invocation_counter check and stack overflow check,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1411
  // so method is not locked if overflows.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1412
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1413
  if (synchronized) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1414
    // Allocate monitor and lock method
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1415
    lock_method();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1416
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1417
    // no synchronization necessary
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1418
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1419
      { Label L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1420
        __ movl(rax, access_flags);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1421
        __ testl(rax, JVM_ACC_SYNCHRONIZED);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1422
        __ jcc(Assembler::zero, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1423
        __ stop("method needs synchronization");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1424
        __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1425
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1426
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1427
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1428
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1429
  // start execution
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1430
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1431
  { Label L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1432
     const Address monitor_block_top (rbp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1433
                 frame::interpreter_frame_monitor_block_top_offset * wordSize);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1434
    __ movptr(rax, monitor_block_top);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1435
    __ cmpptr(rax, rsp);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1436
    __ jcc(Assembler::equal, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1437
    __ stop("broken stack frame setup in interpreter");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1438
    __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1439
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1440
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1441
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1442
  // jvmti support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1443
  __ notify_method_entry();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1444
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1445
  __ dispatch_next(vtos);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1446
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1447
  // invocation counter overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1448
  if (inc_counter) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1449
    if (ProfileInterpreter) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1450
      // We have decided to profile this method in the interpreter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1451
      __ bind(profile_method);
7889
02144432d0e1 4930919: race condition in MDO creation at back branch locations
iveresov
parents: 7397
diff changeset
  1452
      __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method));
02144432d0e1 4930919: race condition in MDO creation at back branch locations
iveresov
parents: 7397
diff changeset
  1453
      __ set_method_data_pointer_for_bcp();
7912
6d73dee171ea 7012766: assert(false) failed: DEBUG MESSAGE in MacroAssembler::debug32
iveresov
parents: 7889
diff changeset
  1454
      __ get_method(rbx);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1455
      __ jmp(profile_method_continue);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1456
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1457
    // Handle overflow of counter and compile method
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1458
    __ bind(invocation_counter_overflow);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1459
    generate_counter_overflow(&continue_after_compile);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1460
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1461
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1462
  return entry_point;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1463
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1464
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1465
//------------------------------------------------------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1466
// Entry points
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1467
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1468
// Here we generate the various kind of entries into the interpreter.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1469
// The two main entry type are generic bytecode methods and native call method.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1470
// These both come in synchronized and non-synchronized versions but the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1471
// frame layout they create is very similar. The other method entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1472
// types are really just special purpose entries that are really entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1473
// and interpretation all in one. These are for trivial methods like
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1474
// accessor, empty, or special math methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1475
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1476
// When control flow reaches any of the entry types for the interpreter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1477
// the following holds ->
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1478
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1479
// Arguments:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1480
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1481
// rbx,: methodOop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1482
// rcx: receiver
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1483
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1484
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1485
// Stack layout immediately at entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1486
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1487
// [ return address     ] <--- rsp
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1488
// [ parameter n        ]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1489
//   ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1490
// [ parameter 1        ]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1491
// [ expression stack   ] (caller's java expression stack)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1492
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1493
// Assuming that we don't go to one of the trivial specialized
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1494
// entries the stack will look like below when we are ready to execute
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1495
// the first bytecode (or call the native routine). The register usage
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1496
// will be as the template based interpreter expects (see interpreter_x86.hpp).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1497
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1498
// local variables follow incoming parameters immediately; i.e.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1499
// the return address is moved to the end of the locals).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1500
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1501
// [ monitor entry      ] <--- rsp
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1502
//   ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1503
// [ monitor entry      ]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1504
// [ expr. stack bottom ]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1505
// [ saved rsi          ]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1506
// [ current rdi        ]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1507
// [ methodOop          ]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1508
// [ saved rbp,          ] <--- rbp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1509
// [ return address     ]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1510
// [ local variable m   ]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1511
//   ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1512
// [ local variable 1   ]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1513
// [ parameter n        ]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1514
//   ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1515
// [ parameter 1        ] <--- rdi
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1516
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1517
address AbstractInterpreterGenerator::generate_method_entry(AbstractInterpreter::MethodKind kind) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1518
  // determine code generation flags
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1519
  bool synchronized = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1520
  address entry_point = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1521
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1522
  switch (kind) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1523
    case Interpreter::zerolocals             :                                                                             break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1524
    case Interpreter::zerolocals_synchronized: synchronized = true;                                                        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1525
    case Interpreter::native                 : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(false);  break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1526
    case Interpreter::native_synchronized    : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(true);   break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1527
    case Interpreter::empty                  : entry_point = ((InterpreterGenerator*)this)->generate_empty_entry();        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1528
    case Interpreter::accessor               : entry_point = ((InterpreterGenerator*)this)->generate_accessor_entry();     break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1529
    case Interpreter::abstract               : entry_point = ((InterpreterGenerator*)this)->generate_abstract_entry();     break;
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 2154
diff changeset
  1530
    case Interpreter::method_handle          : entry_point = ((InterpreterGenerator*)this)->generate_method_handle_entry(); break;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1531
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1532
    case Interpreter::java_lang_math_sin     : // fall thru
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1533
    case Interpreter::java_lang_math_cos     : // fall thru
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1534
    case Interpreter::java_lang_math_tan     : // fall thru
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1535
    case Interpreter::java_lang_math_abs     : // fall thru
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1536
    case Interpreter::java_lang_math_log     : // fall thru
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1537
    case Interpreter::java_lang_math_log10   : // fall thru
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1538
    case Interpreter::java_lang_math_sqrt    : entry_point = ((InterpreterGenerator*)this)->generate_math_entry(kind);     break;
9176
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
  1539
    case Interpreter::java_lang_ref_reference_get
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8315
diff changeset
  1540
                                             : entry_point = ((InterpreterGenerator*)this)->generate_Reference_get_entry(); break;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1541
    default                                  : ShouldNotReachHere();                                                       break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1542
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1543
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1544
  if (entry_point) return entry_point;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1545
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1546
  return ((InterpreterGenerator*)this)->generate_normal_entry(synchronized);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1547
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1548
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1549
4645
0c5f5b94e93a 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 4564
diff changeset
  1550
// These should never be compiled since the interpreter will prefer
0c5f5b94e93a 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 4564
diff changeset
  1551
// the compiled version to the intrinsic version.
0c5f5b94e93a 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 4564
diff changeset
  1552
bool AbstractInterpreter::can_be_compiled(methodHandle m) {
0c5f5b94e93a 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 4564
diff changeset
  1553
  switch (method_kind(m)) {
0c5f5b94e93a 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 4564
diff changeset
  1554
    case Interpreter::java_lang_math_sin     : // fall thru
0c5f5b94e93a 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 4564
diff changeset
  1555
    case Interpreter::java_lang_math_cos     : // fall thru
0c5f5b94e93a 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 4564
diff changeset
  1556
    case Interpreter::java_lang_math_tan     : // fall thru
0c5f5b94e93a 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 4564
diff changeset
  1557
    case Interpreter::java_lang_math_abs     : // fall thru
0c5f5b94e93a 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 4564
diff changeset
  1558
    case Interpreter::java_lang_math_log     : // fall thru
0c5f5b94e93a 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 4564
diff changeset
  1559
    case Interpreter::java_lang_math_log10   : // fall thru
0c5f5b94e93a 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 4564
diff changeset
  1560
    case Interpreter::java_lang_math_sqrt    :
0c5f5b94e93a 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 4564
diff changeset
  1561
      return false;
0c5f5b94e93a 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 4564
diff changeset
  1562
    default:
0c5f5b94e93a 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 4564
diff changeset
  1563
      return true;
0c5f5b94e93a 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 4564
diff changeset
  1564
  }
0c5f5b94e93a 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 4564
diff changeset
  1565
}
0c5f5b94e93a 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 4564
diff changeset
  1566
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1567
// How much stack a method activation needs in words.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1568
int AbstractInterpreter::size_top_interpreter_activation(methodOop method) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1569
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1570
  const int stub_code = 4;  // see generate_call_stub
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1571
  // Save space for one monitor to get into the interpreted method in case
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1572
  // the method is synchronized
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1573
  int monitor_size    = method->is_synchronized() ?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1574
                                1*frame::interpreter_frame_monitor_size() : 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1575
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1576
  // total overhead size: entry_size + (saved rbp, thru expr stack bottom).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1577
  // be sure to change this if you add/subtract anything to/from the overhead area
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1578
  const int overhead_size = -frame::interpreter_frame_initial_sp_offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1579
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 2154
diff changeset
  1580
  const int extra_stack = methodOopDesc::extra_stack_entries();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 2154
diff changeset
  1581
  const int method_stack = (method->max_locals() + method->max_stack() + extra_stack) *
5419
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 5046
diff changeset
  1582
                           Interpreter::stackElementWords;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1583
  return overhead_size + method_stack + stub_code;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1584
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1585
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1586
// asm based interpreter deoptimization helpers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1587
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1588
int AbstractInterpreter::layout_activation(methodOop method,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1589
                                           int tempcount,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1590
                                           int popframe_extra_args,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1591
                                           int moncount,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1592
                                           int callee_param_count,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1593
                                           int callee_locals,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1594
                                           frame* caller,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1595
                                           frame* interpreter_frame,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1596
                                           bool is_top_frame) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1597
  // Note: This calculation must exactly parallel the frame setup
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1598
  // in AbstractInterpreterGenerator::generate_method_entry.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1599
  // If interpreter_frame!=NULL, set up the method, locals, and monitors.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1600
  // The frame interpreter_frame, if not NULL, is guaranteed to be the right size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1601
  // as determined by a previous call to this method.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1602
  // It is also guaranteed to be walkable even though it is in a skeletal state
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1603
  // NOTE: return size is in words not bytes
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1604
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1605
  // fixed size of an interpreter frame:
5419
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 5046
diff changeset
  1606
  int max_locals = method->max_locals() * Interpreter::stackElementWords;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1607
  int extra_locals = (method->max_locals() - method->size_of_parameters()) *
5419
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 5046
diff changeset
  1608
                     Interpreter::stackElementWords;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1609
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1610
  int overhead = frame::sender_sp_offset - frame::interpreter_frame_initial_sp_offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1611
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1612
  // Our locals were accounted for by the caller (or last_frame_adjust on the transistion)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1613
  // Since the callee parameters already account for the callee's params we only need to account for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1614
  // the extra locals.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1615
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1616
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1617
  int size = overhead +
5419
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 5046
diff changeset
  1618
         ((callee_locals - callee_param_count)*Interpreter::stackElementWords) +
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1619
         (moncount*frame::interpreter_frame_monitor_size()) +
5419
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 5046
diff changeset
  1620
         tempcount*Interpreter::stackElementWords + popframe_extra_args;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1621
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1622
  if (interpreter_frame != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1623
#ifdef ASSERT
4564
55dfb20908d0 6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents: 4429
diff changeset
  1624
    if (!EnableMethodHandles)
55dfb20908d0 6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents: 4429
diff changeset
  1625
      // @@@ FIXME: Should we correct interpreter_frame_sender_sp in the calling sequences?
55dfb20908d0 6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents: 4429
diff changeset
  1626
      // Probably, since deoptimization doesn't work yet.
55dfb20908d0 6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents: 4429
diff changeset
  1627
      assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), "Frame not properly walkable");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1628
    assert(caller->sp() == interpreter_frame->sender_sp(), "Frame not properly walkable(2)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1629
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1630
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1631
    interpreter_frame->interpreter_frame_set_method(method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1632
    // NOTE the difference in using sender_sp and interpreter_frame_sender_sp
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1633
    // interpreter_frame_sender_sp is the original sp of the caller (the unextended_sp)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1634
    // and sender_sp is fp+8
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1635
    intptr_t* locals = interpreter_frame->sender_sp() + max_locals - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1636
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1637
    interpreter_frame->interpreter_frame_set_locals(locals);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1638
    BasicObjectLock* montop = interpreter_frame->interpreter_frame_monitor_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1639
    BasicObjectLock* monbot = montop - moncount;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1640
    interpreter_frame->interpreter_frame_set_monitor_end(monbot);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1641
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1642
    // Set last_sp
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1643
    intptr_t*  rsp = (intptr_t*) monbot  -
5419
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 5046
diff changeset
  1644
                     tempcount*Interpreter::stackElementWords -
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1645
                     popframe_extra_args;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1646
    interpreter_frame->interpreter_frame_set_last_sp(rsp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1647
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1648
    // All frames but the initial (oldest) interpreter frame we fill in have a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1649
    // value for sender_sp that allows walking the stack but isn't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1650
    // truly correct. Correct the value here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1651
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1652
    if (extra_locals != 0 &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1653
        interpreter_frame->sender_sp() == interpreter_frame->interpreter_frame_sender_sp() ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1654
      interpreter_frame->set_interpreter_frame_sender_sp(caller->sp() + extra_locals);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1655
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1656
    *interpreter_frame->interpreter_frame_cache_addr() =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1657
      method->constants()->cache();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1658
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1659
  return size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1660
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1661
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1662
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1663
//------------------------------------------------------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1664
// Exceptions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1665
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1666
void TemplateInterpreterGenerator::generate_throw_exception() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1667
  // Entry point in previous activation (i.e., if the caller was interpreted)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1668
  Interpreter::_rethrow_exception_entry = __ pc();
5046
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4645
diff changeset
  1669
  const Register thread = rcx;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1670
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1671
  // Restore sp to interpreter_frame_last_sp even though we are going
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1672
  // to empty the expression stack for the exception processing.
1888
bbf498fb4354 6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents: 1217
diff changeset
  1673
  __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1674
  // rax,: exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1675
  // rdx: return address/pc that threw exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1676
  __ restore_bcp();                              // rsi points to call/send
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1677
  __ restore_locals();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1678
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1679
  // Entry point for exceptions thrown within interpreter code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1680
  Interpreter::_throw_exception_entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1681
  // expression stack is undefined here
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1682
  // rax,: exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1683
  // rsi: exception bcp
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1684
  __ verify_oop(rax);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1685
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1686
  // expression stack must be empty before entering the VM in case of an exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1687
  __ empty_expression_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1688
  __ empty_FPU_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1689
  // find exception handler address and preserve exception oop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1690
  __ call_VM(rdx, CAST_FROM_FN_PTR(address, InterpreterRuntime::exception_handler_for_exception), rax);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1691
  // rax,: exception handler entry point
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1692
  // rdx: preserved exception oop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1693
  // rsi: bcp for exception handler
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1694
  __ push_ptr(rdx);                              // push exception which is now the only value on the stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1695
  __ jmp(rax);                                   // jump to exception handler (may be _remove_activation_entry!)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1696
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1697
  // If the exception is not handled in the current frame the frame is removed and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1698
  // the exception is rethrown (i.e. exception continuation is _rethrow_exception).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1699
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1700
  // Note: At this point the bci is still the bxi for the instruction which caused
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1701
  //       the exception and the expression stack is empty. Thus, for any VM calls
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1702
  //       at this point, GC will find a legal oop map (with empty expression stack).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1703
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1704
  // In current activation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1705
  // tos: exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1706
  // rsi: exception bcp
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1707
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1708
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1709
  // JVMTI PopFrame support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1710
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1711
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1712
   Interpreter::_remove_activation_preserving_args_entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1713
  __ empty_expression_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1714
  __ empty_FPU_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1715
  // Set the popframe_processing bit in pending_popframe_condition indicating that we are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1716
  // currently handling popframe, so that call_VMs that may happen later do not trigger new
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1717
  // popframe handling cycles.
5046
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4645
diff changeset
  1718
  __ get_thread(thread);
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4645
diff changeset
  1719
  __ movl(rdx, Address(thread, JavaThread::popframe_condition_offset()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1720
  __ orl(rdx, JavaThread::popframe_processing_bit);
5046
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4645
diff changeset
  1721
  __ movl(Address(thread, JavaThread::popframe_condition_offset()), rdx);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1722
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1723
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1724
    // Check to see whether we are returning to a deoptimized frame.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1725
    // (The PopFrame call ensures that the caller of the popped frame is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1726
    // either interpreted or compiled and deoptimizes it if compiled.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1727
    // In this case, we can't call dispatch_next() after the frame is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1728
    // popped, but instead must save the incoming arguments and restore
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1729
    // them after deoptimization has occurred.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1730
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1731
    // Note that we don't compare the return PC against the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1732
    // deoptimization blob's unpack entry because of the presence of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1733
    // adapter frames in C2.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1734
    Label caller_not_deoptimized;
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1735
    __ movptr(rdx, Address(rbp, frame::return_addr_offset * wordSize));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1736
    __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::interpreter_contains), rdx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1737
    __ testl(rax, rax);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1738
    __ jcc(Assembler::notZero, caller_not_deoptimized);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1739
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1740
    // Compute size of arguments for saving when returning to deoptimized caller
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1741
    __ get_method(rax);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1742
    __ verify_oop(rax);
2148
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 1909
diff changeset
  1743
    __ load_unsigned_short(rax, Address(rax, in_bytes(methodOopDesc::size_of_parameters_offset())));
5419
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 5046
diff changeset
  1744
    __ shlptr(rax, Interpreter::logStackElementSize);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1745
    __ restore_locals();
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1746
    __ subptr(rdi, rax);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1747
    __ addptr(rdi, wordSize);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1748
    // Save these arguments
5046
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4645
diff changeset
  1749
    __ get_thread(thread);
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4645
diff changeset
  1750
    __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, Deoptimization::popframe_preserve_args), thread, rax, rdi);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1751
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1752
    __ remove_activation(vtos, rdx,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1753
                         /* throw_monitor_exception */ false,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1754
                         /* install_monitor_exception */ false,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1755
                         /* notify_jvmdi */ false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1756
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1757
    // Inform deoptimization that it is responsible for restoring these arguments
5046
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4645
diff changeset
  1758
    __ get_thread(thread);
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4645
diff changeset
  1759
    __ movl(Address(thread, JavaThread::popframe_condition_offset()), JavaThread::popframe_force_deopt_reexecution_bit);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1760
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1761
    // Continue in deoptimization handler
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1762
    __ jmp(rdx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1763
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1764
    __ bind(caller_not_deoptimized);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1765
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1766
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1767
  __ remove_activation(vtos, rdx,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1768
                       /* throw_monitor_exception */ false,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1769
                       /* install_monitor_exception */ false,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1770
                       /* notify_jvmdi */ false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1771
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1772
  // Finish with popframe handling
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1773
  // A previous I2C followed by a deoptimization might have moved the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1774
  // outgoing arguments further up the stack. PopFrame expects the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1775
  // mutations to those outgoing arguments to be preserved and other
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1776
  // constraints basically require this frame to look exactly as
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1777
  // though it had previously invoked an interpreted activation with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1778
  // no space between the top of the expression stack (current
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1779
  // last_sp) and the top of stack. Rather than force deopt to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1780
  // maintain this kind of invariant all the time we call a small
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1781
  // fixup routine to move the mutated arguments onto the top of our
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1782
  // expression stack if necessary.
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1783
  __ mov(rax, rsp);
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1784
  __ movptr(rbx, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize));
5046
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4645
diff changeset
  1785
  __ get_thread(thread);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1786
  // PC must point into interpreter here
5046
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4645
diff changeset
  1787
  __ set_last_Java_frame(thread, noreg, rbp, __ pc());
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4645
diff changeset
  1788
  __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::popframe_move_outgoing_args), thread, rax, rbx);
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4645
diff changeset
  1789
  __ get_thread(thread);
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4645
diff changeset
  1790
  __ reset_last_Java_frame(thread, true, true);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1791
  // Restore the last_sp and null it out
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1792
  __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize));
1888
bbf498fb4354 6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents: 1217
diff changeset
  1793
  __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1794
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1795
  __ restore_bcp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1796
  __ restore_locals();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1797
  // The method data pointer was incremented already during
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1798
  // call profiling. We have to restore the mdp for the current bcp.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1799
  if (ProfileInterpreter) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1800
    __ set_method_data_pointer_for_bcp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1801
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1802
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1803
  // Clear the popframe condition flag
5046
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4645
diff changeset
  1804
  __ get_thread(thread);
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4645
diff changeset
  1805
  __ movl(Address(thread, JavaThread::popframe_condition_offset()), JavaThread::popframe_inactive);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1806
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1807
  __ dispatch_next(vtos);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1808
  // end of PopFrame support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1809
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1810
  Interpreter::_remove_activation_entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1811
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1812
  // preserve exception over this code sequence
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1813
  __ pop_ptr(rax);
5046
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4645
diff changeset
  1814
  __ get_thread(thread);
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4645
diff changeset
  1815
  __ movptr(Address(thread, JavaThread::vm_result_offset()), rax);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1816
  // remove the activation (without doing throws on illegalMonitorExceptions)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1817
  __ remove_activation(vtos, rdx, false, true, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1818
  // restore exception
5046
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4645
diff changeset
  1819
  __ get_thread(thread);
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4645
diff changeset
  1820
  __ movptr(rax, Address(thread, JavaThread::vm_result_offset()));
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4645
diff changeset
  1821
  __ movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1822
  __ verify_oop(rax);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1823
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1824
  // Inbetween activations - previous activation type unknown yet
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1825
  // compute continuation point - the continuation point expects
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1826
  // the following registers set up:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1827
  //
5046
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4645
diff changeset
  1828
  // rax: exception
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1829
  // rdx: return address/pc that threw exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1830
  // rsp: expression stack of caller
5046
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4645
diff changeset
  1831
  // rbp: rbp, of caller
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1832
  __ push(rax);                                  // save exception
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1833
  __ push(rdx);                                  // save return address
5046
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4645
diff changeset
  1834
  __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), thread, rdx);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1835
  __ mov(rbx, rax);                              // save exception handler
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1836
  __ pop(rdx);                                   // restore return address
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1837
  __ pop(rax);                                   // restore exception
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1838
  // Note that an "issuing PC" is actually the next PC after the call
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1839
  __ jmp(rbx);                                   // jump to exception handler of caller
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1840
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1841
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1842
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1843
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1844
// JVMTI ForceEarlyReturn support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1845
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1846
address TemplateInterpreterGenerator::generate_earlyret_entry_for(TosState state) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1847
  address entry = __ pc();
5046
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4645
diff changeset
  1848
  const Register thread = rcx;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1849
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1850
  __ restore_bcp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1851
  __ restore_locals();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1852
  __ empty_expression_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1853
  __ empty_FPU_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1854
  __ load_earlyret_value(state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1855
5046
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4645
diff changeset
  1856
  __ get_thread(thread);
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4645
diff changeset
  1857
  __ movptr(rcx, Address(thread, JavaThread::jvmti_thread_state_offset()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1858
  const Address cond_addr(rcx, JvmtiThreadState::earlyret_state_offset());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1859
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1860
  // Clear the earlyret state
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1861
  __ movl(cond_addr, JvmtiThreadState::earlyret_inactive);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1862
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1863
  __ remove_activation(state, rsi,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1864
                       false, /* throw_monitor_exception */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1865
                       false, /* install_monitor_exception */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1866
                       true); /* notify_jvmdi */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1867
  __ jmp(rsi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1868
  return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1869
} // end of ForceEarlyReturn support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1870
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1871
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1872
//------------------------------------------------------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1873
// Helper for vtos entry point generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1874
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1875
void TemplateInterpreterGenerator::set_vtos_entry_points (Template* t, address& bep, address& cep, address& sep, address& aep, address& iep, address& lep, address& fep, address& dep, address& vep) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1876
  assert(t->is_valid() && t->tos_in() == vtos, "illegal template");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1877
  Label L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1878
  fep = __ pc(); __ push(ftos); __ jmp(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1879
  dep = __ pc(); __ push(dtos); __ jmp(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1880
  lep = __ pc(); __ push(ltos); __ jmp(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1881
  aep = __ pc(); __ push(atos); __ jmp(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1882
  bep = cep = sep =             // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1883
  iep = __ pc(); __ push(itos); // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1884
  vep = __ pc(); __ bind(L);    // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1885
  generate_and_dispatch(t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1886
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1887
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1888
//------------------------------------------------------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1889
// Generation of individual instructions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1890
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1891
// helpers for generate_and_dispatch
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1892
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1893
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1894
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1895
InterpreterGenerator::InterpreterGenerator(StubQueue* code)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1896
 : TemplateInterpreterGenerator(code) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1897
   generate_all(); // down here so it can be "virtual"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1898
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1899
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1900
//------------------------------------------------------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1901
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1902
// Non-product code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1903
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1904
address TemplateInterpreterGenerator::generate_trace_code(TosState state) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1905
  address entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1906
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1907
  // prepare expression stack
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1908
  __ pop(rcx);          // pop return address so expression stack is 'pure'
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1909
  __ push(state);       // save tosca
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1910
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1911
  // pass tosca registers as arguments & call tracer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1912
  __ call_VM(noreg, CAST_FROM_FN_PTR(address, SharedRuntime::trace_bytecode), rcx, rax, rdx);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1913
  __ mov(rcx, rax);     // make sure return address is not destroyed by pop(state)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1914
  __ pop(state);        // restore tosca
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1915
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1916
  // return
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1917
  __ jmp(rcx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1918
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1919
  return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1920
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1921
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1922
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1923
void TemplateInterpreterGenerator::count_bytecode() {
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1924
  __ incrementl(ExternalAddress((address) &BytecodeCounter::_counter_value));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1925
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1926
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1927
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1928
void TemplateInterpreterGenerator::histogram_bytecode(Template* t) {
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1929
  __ incrementl(ExternalAddress((address) &BytecodeHistogram::_counters[t->bytecode()]));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1930
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1931
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1932
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1933
void TemplateInterpreterGenerator::histogram_bytecode_pair(Template* t) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1934
  __ mov32(ExternalAddress((address) &BytecodePairHistogram::_index), rbx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1935
  __ shrl(rbx, BytecodePairHistogram::log2_number_of_codes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1936
  __ orl(rbx, ((int)t->bytecode()) << BytecodePairHistogram::log2_number_of_codes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1937
  ExternalAddress table((address) BytecodePairHistogram::_counters);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1938
  Address index(noreg, rbx, Address::times_4);
1066
717c3345024f 5108146: Merge i486 and amd64 cpu directories
never
parents: 1
diff changeset
  1939
  __ incrementl(ArrayAddress(table, index));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1940
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1941
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1942
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1943
void TemplateInterpreterGenerator::trace_bytecode(Template* t) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1944
  // Call a little run-time stub to avoid blow-up for each bytecode.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1945
  // The run-time runtime saves the right registers, depending on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1946
  // the tosca in-state for the given template.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1947
  assert(Interpreter::trace_code(t->tos_in()) != NULL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1948
         "entry must have been generated");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1949
  __ call(RuntimeAddress(Interpreter::trace_code(t->tos_in())));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1950
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1951
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1952
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1953
void TemplateInterpreterGenerator::stop_interpreter_at() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1954
  Label L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1955
  __ cmp32(ExternalAddress((address) &BytecodeCounter::_counter_value),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1956
           StopInterpreterAt);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1957
  __ jcc(Assembler::notEqual, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1958
  __ int3();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1959
  __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1960
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1961
#endif // !PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1962
#endif // CC_INTERP