hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp
author johnc
Thu, 07 Apr 2011 09:53:20 -0700
changeset 9176 42d9d1010f38
parent 7889 02144432d0e1
child 9437 9981851b4b8c
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
#ifndef CC_INTERP
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
#ifndef FAST_DISPATCH
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
#define FAST_DISPATCH 1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
#undef FAST_DISPATCH
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
// Generation of Interpreter
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
// The InterpreterGenerator generates the interpreter into Interpreter::_code.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
#define __ _masm->
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
//----------------------------------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
void InterpreterGenerator::save_native_result(void) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
  // result potentially in O0/O1: save it across calls
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
  const Address& l_tmp = InterpreterMacroAssembler::l_tmp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
  // result potentially in F0/F1: save it across calls
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
  const Address& d_tmp = InterpreterMacroAssembler::d_tmp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
  // save and restore any potential method result value around the unlocking operation
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
  __ stf(FloatRegisterImpl::D, F0, d_tmp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
#ifdef _LP64
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
  __ stx(O0, l_tmp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
#else
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
  __ std(O0, l_tmp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
void InterpreterGenerator::restore_native_result(void) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
  const Address& l_tmp = InterpreterMacroAssembler::l_tmp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
  const Address& d_tmp = InterpreterMacroAssembler::d_tmp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
  // Restore any method result value
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
  __ ldf(FloatRegisterImpl::D, d_tmp, F0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
#ifdef _LP64
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
  __ ldx(l_tmp, O0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
#else
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
  __ ldd(l_tmp, O0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
address TemplateInterpreterGenerator::generate_exception_handler_common(const char* name, const char* message, bool pass_oop) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
  assert(!pass_oop || message == NULL, "either oop or message but not both");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
  address entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
  // expression stack must be empty before entering the VM if an exception happened
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
  __ empty_expression_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
  // load exception object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
  __ set((intptr_t)name, G3_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
  if (pass_oop) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
    __ call_VM(Oexception, CAST_FROM_FN_PTR(address, InterpreterRuntime::create_klass_exception), G3_scratch, Otos_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
    __ set((intptr_t)message, G4_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
    __ call_VM(Oexception, CAST_FROM_FN_PTR(address, InterpreterRuntime::create_exception), G3_scratch, G4_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
  // throw exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
  assert(Interpreter::throw_exception_entry() != NULL, "generate it first");
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   110
  AddressLiteral thrower(Interpreter::throw_exception_entry());
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   111
  __ jump_to(thrower, G3_scratch);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
  __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
  return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
address TemplateInterpreterGenerator::generate_ClassCastException_handler() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
  address entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
  // expression stack must be empty before entering the VM if an exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
  // happened
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
  __ empty_expression_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
  // load exception object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
  __ call_VM(Oexception,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
             CAST_FROM_FN_PTR(address,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
                              InterpreterRuntime::throw_ClassCastException),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
             Otos_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
  __ should_not_reach_here();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
  return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 670
diff changeset
   131
// Arguments are: required type in G5_method_type, and
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 670
diff changeset
   132
// failing object (or NULL) in G3_method_handle.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 670
diff changeset
   133
address TemplateInterpreterGenerator::generate_WrongMethodType_handler() {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 670
diff changeset
   134
  address entry = __ pc();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 670
diff changeset
   135
  // expression stack must be empty before entering the VM if an exception
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 670
diff changeset
   136
  // happened
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 670
diff changeset
   137
  __ empty_expression_stack();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 670
diff changeset
   138
  // load exception object
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 670
diff changeset
   139
  __ call_VM(Oexception,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 670
diff changeset
   140
             CAST_FROM_FN_PTR(address,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 670
diff changeset
   141
                              InterpreterRuntime::throw_WrongMethodTypeException),
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 670
diff changeset
   142
             G5_method_type,    // required
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 670
diff changeset
   143
             G3_method_handle); // actual
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 670
diff changeset
   144
  __ should_not_reach_here();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 670
diff changeset
   145
  return entry;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 670
diff changeset
   146
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 670
diff changeset
   147
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 670
diff changeset
   148
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
address TemplateInterpreterGenerator::generate_ArrayIndexOutOfBounds_handler(const char* name) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
  address entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
  // expression stack must be empty before entering the VM if an exception happened
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
  __ empty_expression_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
  // convention: expect aberrant index in register G3_scratch, then shuffle the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
  // index to G4_scratch for the VM call
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
  __ mov(G3_scratch, G4_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
  __ set((intptr_t)name, G3_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
  __ call_VM(Oexception, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_ArrayIndexOutOfBoundsException), G3_scratch, G4_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
  __ should_not_reach_here();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
  return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
address TemplateInterpreterGenerator::generate_StackOverflowError_handler() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
  address entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
  // expression stack must be empty before entering the VM if an exception happened
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
  __ empty_expression_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
  __ call_VM(Oexception, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_StackOverflowError));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
  __ should_not_reach_here();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
  return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
4429
d7eb4e2099aa 6858164: invokedynamic code needs some cleanup (post-6655638)
jrose
parents: 2572
diff changeset
   173
address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step) {
5416
5f6377fcfd3e 6829193: JSR 292 needs to support SPARC
twisti
parents: 5046
diff changeset
   174
  TosState incoming_state = state;
5f6377fcfd3e 6829193: JSR 292 needs to support SPARC
twisti
parents: 5046
diff changeset
   175
5f6377fcfd3e 6829193: JSR 292 needs to support SPARC
twisti
parents: 5046
diff changeset
   176
  Label cont;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
  address compiled_entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
  address entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
#if !defined(_LP64) && defined(COMPILER2)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
  // All return values are where we want them, except for Longs.  C2 returns
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
  // longs in G1 in the 32-bit build whereas the interpreter wants them in O0/O1.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
  // Since the interpreter will return longs in G1 and O0/O1 in the 32bit
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
  // build even if we are returning from interpreted we just do a little
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
  // stupid shuffing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
  // Note: I tried to make c2 return longs in O0/O1 and G1 so we wouldn't have to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
  // do this here. Unfortunately if we did a rethrow we'd see an machepilog node
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
  // first which would move g1 -> O0/O1 and destroy the exception we were throwing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
5416
5f6377fcfd3e 6829193: JSR 292 needs to support SPARC
twisti
parents: 5046
diff changeset
   190
  if (incoming_state == ltos) {
5f6377fcfd3e 6829193: JSR 292 needs to support SPARC
twisti
parents: 5046
diff changeset
   191
    __ srl (G1,  0, O1);
5f6377fcfd3e 6829193: JSR 292 needs to support SPARC
twisti
parents: 5046
diff changeset
   192
    __ srlx(G1, 32, O0);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
  }
5416
5f6377fcfd3e 6829193: JSR 292 needs to support SPARC
twisti
parents: 5046
diff changeset
   194
#endif // !_LP64 && COMPILER2
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
  __ bind(cont);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
  // The callee returns with the stack possibly adjusted by adapter transition
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
  // We remove that possible adjustment here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
  // All interpreter local registers are untouched. Any result is passed back
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
  // in the O0/O1 or float registers. Before continuing, the arguments must be
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
  // popped from the java expression stack; i.e., Lesp must be adjusted.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
  __ mov(Llast_SP, SP);   // Remove any adapter added stack space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
5416
5f6377fcfd3e 6829193: JSR 292 needs to support SPARC
twisti
parents: 5046
diff changeset
   206
  Label L_got_cache, L_giant_index;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
  const Register cache = G3_scratch;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
  const Register size  = G1_scratch;
5416
5f6377fcfd3e 6829193: JSR 292 needs to support SPARC
twisti
parents: 5046
diff changeset
   209
  if (EnableInvokeDynamic) {
5f6377fcfd3e 6829193: JSR 292 needs to support SPARC
twisti
parents: 5046
diff changeset
   210
    __ ldub(Address(Lbcp, 0), G1_scratch);  // Load current bytecode.
5f6377fcfd3e 6829193: JSR 292 needs to support SPARC
twisti
parents: 5046
diff changeset
   211
    __ cmp(G1_scratch, Bytecodes::_invokedynamic);
5f6377fcfd3e 6829193: JSR 292 needs to support SPARC
twisti
parents: 5046
diff changeset
   212
    __ br(Assembler::equal, false, Assembler::pn, L_giant_index);
5f6377fcfd3e 6829193: JSR 292 needs to support SPARC
twisti
parents: 5046
diff changeset
   213
    __ delayed()->nop();
5f6377fcfd3e 6829193: JSR 292 needs to support SPARC
twisti
parents: 5046
diff changeset
   214
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
  __ get_cache_and_index_at_bcp(cache, G1_scratch, 1);
5416
5f6377fcfd3e 6829193: JSR 292 needs to support SPARC
twisti
parents: 5046
diff changeset
   216
  __ bind(L_got_cache);
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   217
  __ ld_ptr(cache, constantPoolCacheOopDesc::base_offset() +
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   218
                   ConstantPoolCacheEntry::flags_offset(), size);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
  __ and3(size, 0xFF, size);                   // argument size in words
5419
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 5416
diff changeset
   220
  __ sll(size, Interpreter::logStackElementSize, size); // each argument size in bytes
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
  __ add(Lesp, size, Lesp);                    // pop arguments
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
  __ dispatch_next(state, step);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
5416
5f6377fcfd3e 6829193: JSR 292 needs to support SPARC
twisti
parents: 5046
diff changeset
   224
  // out of the main line of code...
5f6377fcfd3e 6829193: JSR 292 needs to support SPARC
twisti
parents: 5046
diff changeset
   225
  if (EnableInvokeDynamic) {
5f6377fcfd3e 6829193: JSR 292 needs to support SPARC
twisti
parents: 5046
diff changeset
   226
    __ bind(L_giant_index);
5688
9052dc91ea67 6939207: refactor constant pool index processing
jrose
parents: 5419
diff changeset
   227
    __ get_cache_and_index_at_bcp(cache, G1_scratch, 1, sizeof(u4));
5416
5f6377fcfd3e 6829193: JSR 292 needs to support SPARC
twisti
parents: 5046
diff changeset
   228
    __ ba(false, L_got_cache);
5f6377fcfd3e 6829193: JSR 292 needs to support SPARC
twisti
parents: 5046
diff changeset
   229
    __ delayed()->nop();
5f6377fcfd3e 6829193: JSR 292 needs to support SPARC
twisti
parents: 5046
diff changeset
   230
  }
5f6377fcfd3e 6829193: JSR 292 needs to support SPARC
twisti
parents: 5046
diff changeset
   231
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
  return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, int step) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
  address entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
  __ get_constant_pool_cache(LcpoolCache); // load LcpoolCache
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
  { Label L;
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   240
    Address exception_addr(G2_thread, Thread::pending_exception_offset());
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   241
    __ ld_ptr(exception_addr, Gtemp);  // Load pending exception.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
    __ tst(Gtemp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
    __ brx(Assembler::equal, false, Assembler::pt, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
    __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
    __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_pending_exception));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
    __ should_not_reach_here();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
    __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
  __ dispatch_next(state, step);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
  return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
// A result handler converts/unboxes a native call result into
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
// a java interpreter/compiler result. The current frame is an
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
// interpreter frame. The activation frame unwind code must be
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
// consistent with that of TemplateTable::_return(...). In the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
// case of native methods, the caller's SP was not modified.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
address TemplateInterpreterGenerator::generate_result_handler_for(BasicType type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
  address entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
  Register Itos_i  = Otos_i ->after_save();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
  Register Itos_l  = Otos_l ->after_save();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
  Register Itos_l1 = Otos_l1->after_save();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
  Register Itos_l2 = Otos_l2->after_save();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
  switch (type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
    case T_BOOLEAN: __ subcc(G0, O0, G0); __ addc(G0, 0, Itos_i); break; // !0 => true; 0 => false
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
    case T_CHAR   : __ sll(O0, 16, O0); __ srl(O0, 16, Itos_i);   break; // cannot use and3, 0xFFFF too big as immediate value!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
    case T_BYTE   : __ sll(O0, 24, O0); __ sra(O0, 24, Itos_i);   break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
    case T_SHORT  : __ sll(O0, 16, O0); __ sra(O0, 16, Itos_i);   break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
    case T_LONG   :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
#ifndef _LP64
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
                    __ mov(O1, Itos_l2);  // move other half of long
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
#endif              // ifdef or no ifdef, fall through to the T_INT case
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
    case T_INT    : __ mov(O0, Itos_i);                         break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
    case T_VOID   : /* nothing to do */                         break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
    case T_FLOAT  : assert(F0 == Ftos_f, "fix this code" );     break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
    case T_DOUBLE : assert(F0 == Ftos_d, "fix this code" );     break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
    case T_OBJECT :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
      __ ld_ptr(FP, (frame::interpreter_frame_oop_temp_offset*wordSize) + STACK_BIAS, Itos_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
      __ verify_oop(Itos_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
    default       : ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
  __ ret();                           // return from interpreter activation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
  __ delayed()->restore(I5_savedSP, G0, SP);  // remove interpreter frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
  NOT_PRODUCT(__ emit_long(0);)       // marker for disassembly
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
  return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
address TemplateInterpreterGenerator::generate_safept_entry_for(TosState state, address runtime_entry) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
  address entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
  __ push(state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
  __ call_VM(noreg, runtime_entry);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
  __ dispatch_via(vtos, Interpreter::normal_table(vtos));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
  return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
address TemplateInterpreterGenerator::generate_continuation_for(TosState state) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
  address entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
  __ dispatch_next(state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
  return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
// Helpers for commoning out cases in the various type of method entries.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
// increment invocation count & check for overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
// Note: checking for negative value instead of overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
//       so we have a 'sticky' overflow test
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
// Lmethod: method
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
// ??: invocation counter
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) {
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   317
  // 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
   318
  if (TieredCompilation) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   319
    const int increment = InvocationCounter::count_increment;
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   320
    const int mask = ((1 << Tier0InvokeNotifyFreqLog) - 1) << InvocationCounter::count_shift;
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   321
    Label no_mdo, done;
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   322
    if (ProfileInterpreter) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   323
      // If no method data exists, go to profile_continue.
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   324
      __ ld_ptr(Lmethod, methodOopDesc::method_data_offset(), G4_scratch);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   325
      __ br_null(G4_scratch, false, Assembler::pn, no_mdo);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   326
      __ delayed()->nop();
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   327
      // Increment counter
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   328
      Address mdo_invocation_counter(G4_scratch,
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   329
                                     in_bytes(methodDataOopDesc::invocation_counter_offset()) +
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   330
                                     in_bytes(InvocationCounter::counter_offset()));
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   331
      __ increment_mask_and_jump(mdo_invocation_counter, increment, mask,
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   332
                                 G3_scratch, Lscratch,
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   333
                                 Assembler::zero, overflow);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   334
      __ ba(false, done);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   335
      __ delayed()->nop();
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   336
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   338
    // Increment counter in methodOop
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   339
    __ bind(no_mdo);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   340
    Address invocation_counter(Lmethod,
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   341
                               in_bytes(methodOopDesc::invocation_counter_offset()) +
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   342
                               in_bytes(InvocationCounter::counter_offset()));
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   343
    __ increment_mask_and_jump(invocation_counter, increment, mask,
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   344
                               G3_scratch, Lscratch,
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   345
                               Assembler::zero, overflow);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   346
    __ bind(done);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   347
  } else {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   348
    // Update standard invocation counters
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   349
    __ increment_invocation_counter(O0, G3_scratch);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   350
    if (ProfileInterpreter) {  // %%% Merge this into methodDataOop
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   351
      Address interpreter_invocation_counter(Lmethod,in_bytes(methodOopDesc::interpreter_invocation_counter_offset()));
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   352
      __ ld(interpreter_invocation_counter, G3_scratch);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   353
      __ inc(G3_scratch);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   354
      __ st(G3_scratch, interpreter_invocation_counter);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   355
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   357
    if (ProfileInterpreter && profile_method != NULL) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   358
      // Test to see if we should create a method data oop
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   359
      AddressLiteral profile_limit((address)&InvocationCounter::InterpreterProfileLimit);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   360
      __ load_contents(profile_limit, G3_scratch);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   361
      __ cmp(O0, G3_scratch);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   362
      __ br(Assembler::lessUnsigned, false, Assembler::pn, *profile_method_continue);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   363
      __ delayed()->nop();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   365
      // if no method data exists, go to profile_method
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   366
      __ test_method_data_pointer(*profile_method);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   367
    }
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   368
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   369
    AddressLiteral invocation_limit((address)&InvocationCounter::InterpreterInvocationLimit);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   370
    __ load_contents(invocation_limit, G3_scratch);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   371
    __ cmp(O0, G3_scratch);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   372
    __ br(Assembler::greaterEqualUnsigned, false, Assembler::pn, *overflow);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   373
    __ delayed()->nop();
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5702
diff changeset
   374
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
// Allocate monitor and lock method (asm interpreter)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
// ebx - methodOop
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
void InterpreterGenerator::lock_method(void) {
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   382
  __ ld(Lmethod, in_bytes(methodOopDesc::access_flags_offset()), O0);  // Load access flags.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
 { Label ok;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
   __ btst(JVM_ACC_SYNCHRONIZED, O0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
   __ br( Assembler::notZero, false, Assembler::pt, ok);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
   __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
   __ stop("method doesn't need synchronization");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
   __ bind(ok);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
#endif // ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
  // get synchronization object to O0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
  { Label done;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
    const int mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
    __ btst(JVM_ACC_STATIC, O0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
    __ br( Assembler::zero, true, Assembler::pt, done);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
    __ delayed()->ld_ptr(Llocals, Interpreter::local_offset_in_bytes(0), O0); // get receiver for not-static case
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
    __ ld_ptr( Lmethod, in_bytes(methodOopDesc::constants_offset()), O0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
    __ ld_ptr( O0, constantPoolOopDesc::pool_holder_offset_in_bytes(), O0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
    // lock the mirror, not the klassOop
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
    __ ld_ptr( O0, mirror_offset, O0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
    __ tst(O0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
    __ breakpoint_trap(Assembler::zero);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
#endif // ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
    __ bind(done);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
  __ add_monitor_to_stack(true, noreg, noreg);  // allocate monitor elem
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
  __ st_ptr( O0, Lmonitors, BasicObjectLock::obj_offset_in_bytes());   // store object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
  // __ untested("lock_object from method entry");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
  __ lock_object(Lmonitors, O0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
void TemplateInterpreterGenerator::generate_stack_overflow_check(Register Rframe_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
                                                         Register Rscratch,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
                                                         Register Rscratch2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
  const int page_size = os::vm_page_size();
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   426
  Address saved_exception_pc(G2_thread, JavaThread::saved_exception_pc_offset());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
  Label after_frame_check;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
  assert_different_registers(Rframe_size, Rscratch, Rscratch2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
  __ set( page_size,   Rscratch );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
  __ cmp( Rframe_size, Rscratch );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
  __ br( Assembler::lessEqual, false, Assembler::pt, after_frame_check );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
  __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
  // get the stack base, and in debug, verify it is non-zero
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   438
  __ ld_ptr( G2_thread, Thread::stack_base_offset(), Rscratch );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
  Label base_not_zero;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
  __ cmp( Rscratch, G0 );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
  __ brx( Assembler::notEqual, false, Assembler::pn, base_not_zero );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
  __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
  __ stop("stack base is zero in generate_stack_overflow_check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
  __ bind(base_not_zero);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
  // get the stack size, and in debug, verify it is non-zero
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
  assert( sizeof(size_t) == sizeof(intptr_t), "wrong load size" );
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   450
  __ ld_ptr( G2_thread, Thread::stack_size_offset(), Rscratch2 );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
  Label size_not_zero;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
  __ cmp( Rscratch2, G0 );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
  __ brx( Assembler::notEqual, false, Assembler::pn, size_not_zero );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
  __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
  __ stop("stack size is zero in generate_stack_overflow_check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
  __ bind(size_not_zero);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
  // compute the beginning of the protected zone minus the requested frame size
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
  __ sub( Rscratch, Rscratch2,   Rscratch );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
  __ set( (StackRedPages+StackYellowPages) * page_size, Rscratch2 );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
  __ add( Rscratch, Rscratch2,   Rscratch );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
  // Add in the size of the frame (which is the same as subtracting it from the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
  // SP, which would take another register
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
  __ add( Rscratch, Rframe_size, Rscratch );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
  // the frame is greater than one page in size, so check against
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
  // the bottom of the stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
  __ cmp( SP, Rscratch );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
  __ brx( Assembler::greater, false, Assembler::pt, after_frame_check );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
  __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
  // Save the return address as the exception pc
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
  __ st_ptr(O7, saved_exception_pc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
  // the stack will overflow, throw an exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
  __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_StackOverflowError));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
  // if you get to here, then there is enough stack space
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
  __ bind( after_frame_check );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
// Generate a fixed interpreter frame. This is identical setup for interpreted
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
// methods and for native methods hence the shared code.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
  // The entry code sets up a new interpreter frame in 4 steps:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
  // 1) Increase caller's SP by for the extra local space needed:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
  //    (check for overflow)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
  //    Efficient implementation of xload/xstore bytecodes requires
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
  //    that arguments and non-argument locals are in a contigously
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
  //    addressable memory block => non-argument locals must be
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
  //    allocated in the caller's frame.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
  // 2) Create a new stack frame and register window:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
  //    The new stack frame must provide space for the standard
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
  //    register save area, the maximum java expression stack size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
  //    the monitor slots (0 slots initially), and some frame local
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
  //    scratch locations.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
  // 3) The following interpreter activation registers must be setup:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
  //    Lesp       : expression stack pointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
  //    Lbcp       : bytecode pointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
  //    Lmethod    : method
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
  //    Llocals    : locals pointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
  //    Lmonitors  : monitor pointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
  //    LcpoolCache: constant pool cache
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
  // 4) Initialize the non-argument locals if necessary:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
  //    Non-argument locals may need to be initialized to NULL
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
  //    for GC to work. If the oop-map information is accurate
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
  //    (in the absence of the JSR problem), no initialization
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
  //    is necessary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
  // (gri - 2/25/2000)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   525
  const Address size_of_parameters(G5_method, methodOopDesc::size_of_parameters_offset());
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   526
  const Address size_of_locals    (G5_method, methodOopDesc::size_of_locals_offset());
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   527
  const Address max_stack         (G5_method, methodOopDesc::max_stack_offset());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
  int rounded_vm_local_words = round_to( frame::interpreter_frame_vm_local_words, WordsPerLong );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
  const int extra_space =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
    rounded_vm_local_words +                   // frame local scratch space
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 670
diff changeset
   532
    //6815692//methodOopDesc::extra_stack_words() +       // extra push slots for MH adapters
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
    frame::memory_parameter_word_sp_offset +   // register save area
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
    (native_call ? frame::interpreter_frame_extra_outgoing_argument_words : 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
  const Register Glocals_size = G3;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
  const Register Otmp1 = O3;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
  const Register Otmp2 = O4;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
  // Lscratch can't be used as a temporary because the call_stub uses
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
  // it to assert that the stack frame was setup correctly.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
  __ lduh( size_of_parameters, Glocals_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
  // Gargs points to first local + BytesPerWord
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
  // Set the saved SP after the register window save
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
  assert_different_registers(Gargs, Glocals_size, Gframe_size, O5_savedSP);
5419
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 5416
diff changeset
   548
  __ sll(Glocals_size, Interpreter::logStackElementSize, Otmp1);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
  __ add(Gargs, Otmp1, Gargs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
  if (native_call) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
    __ calc_mem_param_words( Glocals_size, Gframe_size );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
    __ add( Gframe_size,  extra_space, Gframe_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
    __ round_to( Gframe_size, WordsPerLong );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
    __ sll( Gframe_size, LogBytesPerWord, Gframe_size );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
    // Compute number of locals in method apart from incoming parameters
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
    __ lduh( size_of_locals, Otmp1 );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
    __ sub( Otmp1, Glocals_size, Glocals_size );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
    __ round_to( Glocals_size, WordsPerLong );
5419
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 5416
diff changeset
   564
    __ sll( Glocals_size, Interpreter::logStackElementSize, Glocals_size );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
    // see if the frame is greater than one page in size. If so,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
    // then we need to verify there is enough stack space remaining
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
    // Frame_size = (max_stack + extra_space) * BytesPerWord;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
    __ lduh( max_stack, Gframe_size );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
    __ add( Gframe_size, extra_space, Gframe_size );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
    __ round_to( Gframe_size, WordsPerLong );
5419
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 5416
diff changeset
   572
    __ sll( Gframe_size, Interpreter::logStackElementSize, Gframe_size);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
    // Add in java locals size for stack overflow check only
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
    __ add( Gframe_size, Glocals_size, Gframe_size );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
    const Register Otmp2 = O4;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
    assert_different_registers(Otmp1, Otmp2, O5_savedSP);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
    generate_stack_overflow_check(Gframe_size, Otmp1, Otmp2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
    __ sub( Gframe_size, Glocals_size, Gframe_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
    // bump SP to accomodate the extra locals
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
    __ sub( SP, Glocals_size, SP );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
  // now set up a stack frame with the size computed above
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
  __ neg( Gframe_size );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
  __ save( SP, Gframe_size, SP );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
  // now set up all the local cache registers
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
  // NOTE: At this point, Lbyte_code/Lscratch has been modified. Note
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
  // that all present references to Lbyte_code initialize the register
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
  // immediately before use
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
  if (native_call) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
    __ mov(G0, Lbcp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
  } else {
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   604
    __ ld_ptr(G5_method, methodOopDesc::const_offset(), Lbcp);
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   605
    __ add(Lbcp, in_bytes(constMethodOopDesc::codes_offset()), Lbcp);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
  __ mov( G5_method, Lmethod);                 // set Lmethod
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
  __ get_constant_pool_cache( LcpoolCache );   // set LcpoolCache
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
  __ sub(FP, rounded_vm_local_words * BytesPerWord, Lmonitors ); // set Lmonitors
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
#ifdef _LP64
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
  __ add( Lmonitors, STACK_BIAS, Lmonitors );   // Account for 64 bit stack bias
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
  __ sub(Lmonitors, BytesPerWord, Lesp);       // set Lesp
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
  // setup interpreter activation registers
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
  __ sub(Gargs, BytesPerWord, Llocals);        // set Llocals
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
  if (ProfileInterpreter) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
#ifdef FAST_DISPATCH
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
    // FAST_DISPATCH and ProfileInterpreter are mutually exclusive since
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
    // they both use I2.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
    assert(0, "FAST_DISPATCH and +ProfileInterpreter are mutually exclusive");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
#endif // FAST_DISPATCH
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
    __ set_method_data_pointer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
// Empty method, generate a very fast return.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
address InterpreterGenerator::generate_empty_entry(void) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
  // A method that does nother but return...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
  address entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
  Label slow_path;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
  __ verify_oop(G5_method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
  // do nothing for empty methods (do not even increment invocation counter)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
  if ( UseFastEmptyMethods) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
    // If we need a safepoint check, generate full interpreter entry.
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   643
    AddressLiteral sync_state(SafepointSynchronize::address_of_state());
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   644
    __ set(sync_state, G3_scratch);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   645
    __ cmp(G3_scratch, SafepointSynchronize::_not_synchronized);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   646
    __ br(Assembler::notEqual, false, Assembler::pn, slow_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   647
    __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
    // Code: _return
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
    __ retl();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   651
    __ delayed()->mov(O5_savedSP, SP);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
    __ bind(slow_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
    (void) generate_normal_entry(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
    return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
// Call an accessor method (assuming it is resolved, otherwise drop into
489c9b5090e2 Initial load
duke
parents:
diff changeset
   662
// vanilla (slow path) entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
// Generates code to elide accessor methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
// Uses G3_scratch and G1_scratch as scratch
489c9b5090e2 Initial load
duke
parents:
diff changeset
   666
address InterpreterGenerator::generate_accessor_entry(void) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   667
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
  // Code: _aload_0, _(i|a)getfield, _(i|a)return or any rewrites thereof;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   669
  // 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
  address entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
  Label slow_path;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   676
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   677
  // XXX: for compressed oops pointer loading and decoding doesn't fit in
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   678
  // delay slot and damages G1
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   679
  if ( UseFastAccessorMethods && !UseCompressedOops ) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
    // Check if we need to reach a safepoint and generate full interpreter
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
    // frame if so.
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   682
    AddressLiteral sync_state(SafepointSynchronize::address_of_state());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   683
    __ load_contents(sync_state, G3_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   684
    __ cmp(G3_scratch, SafepointSynchronize::_not_synchronized);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   685
    __ br(Assembler::notEqual, false, Assembler::pn, slow_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
    __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   687
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
    // Check if local 0 != NULL
489c9b5090e2 Initial load
duke
parents:
diff changeset
   689
    __ ld_ptr(Gargs, G0, Otos_i ); // get local 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
    __ tst(Otos_i);  // check if local 0 == NULL and go the slow path
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
    __ brx(Assembler::zero, false, Assembler::pn, slow_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
    __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
    // read first instruction word and extract bytecode @ 1 and index @ 2
489c9b5090e2 Initial load
duke
parents:
diff changeset
   696
    // get first 4 bytes of the bytecodes (big endian!)
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   697
    __ ld_ptr(G5_method, methodOopDesc::const_offset(), G1_scratch);
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   698
    __ ld(G1_scratch, constMethodOopDesc::codes_offset(), G1_scratch);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   699
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
    // move index @ 2 far left then to the right most two bytes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   701
    __ sll(G1_scratch, 2*BitsPerByte, G1_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   702
    __ srl(G1_scratch, 2*BitsPerByte - exact_log2(in_words(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   703
                      ConstantPoolCacheEntry::size()) * BytesPerWord), G1_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   704
489c9b5090e2 Initial load
duke
parents:
diff changeset
   705
    // get constant pool cache
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   706
    __ ld_ptr(G5_method, methodOopDesc::constants_offset(), G3_scratch);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   707
    __ ld_ptr(G3_scratch, constantPoolOopDesc::cache_offset_in_bytes(), G3_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   708
489c9b5090e2 Initial load
duke
parents:
diff changeset
   709
    // get specific constant pool cache entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
   710
    __ add(G3_scratch, G1_scratch, G3_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   711
489c9b5090e2 Initial load
duke
parents:
diff changeset
   712
    // Check the constant Pool cache entry to see if it has been resolved.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   713
    // If not, need the slow path.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   714
    ByteSize cp_base_offset = constantPoolCacheOopDesc::base_offset();
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   715
    __ ld_ptr(G3_scratch, cp_base_offset + ConstantPoolCacheEntry::indices_offset(), G1_scratch);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   716
    __ srl(G1_scratch, 2*BitsPerByte, G1_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   717
    __ and3(G1_scratch, 0xFF, G1_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
    __ cmp(G1_scratch, Bytecodes::_getfield);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   719
    __ br(Assembler::notEqual, false, Assembler::pn, slow_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   720
    __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   721
489c9b5090e2 Initial load
duke
parents:
diff changeset
   722
    // Get the type and return field offset from the constant pool cache
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   723
    __ ld_ptr(G3_scratch, cp_base_offset + ConstantPoolCacheEntry::flags_offset(), G1_scratch);
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   724
    __ ld_ptr(G3_scratch, cp_base_offset + ConstantPoolCacheEntry::f2_offset(), G3_scratch);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   725
489c9b5090e2 Initial load
duke
parents:
diff changeset
   726
    Label xreturn_path;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   727
    // Need to differentiate between igetfield, agetfield, bgetfield etc.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   728
    // because they are different sizes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   729
    // Get the type from the constant pool cache
489c9b5090e2 Initial load
duke
parents:
diff changeset
   730
    __ srl(G1_scratch, ConstantPoolCacheEntry::tosBits, G1_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   731
    // Make sure we don't need to mask G1_scratch for tosBits after the above shift
489c9b5090e2 Initial load
duke
parents:
diff changeset
   732
    ConstantPoolCacheEntry::verify_tosBits();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   733
    __ cmp(G1_scratch, atos );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   734
    __ br(Assembler::equal, true, Assembler::pt, xreturn_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   735
    __ delayed()->ld_ptr(Otos_i, G3_scratch, Otos_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   736
    __ cmp(G1_scratch, itos);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   737
    __ br(Assembler::equal, true, Assembler::pt, xreturn_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   738
    __ delayed()->ld(Otos_i, G3_scratch, Otos_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   739
    __ cmp(G1_scratch, stos);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
    __ br(Assembler::equal, true, Assembler::pt, xreturn_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   741
    __ delayed()->ldsh(Otos_i, G3_scratch, Otos_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   742
    __ cmp(G1_scratch, ctos);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   743
    __ br(Assembler::equal, true, Assembler::pt, xreturn_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   744
    __ delayed()->lduh(Otos_i, G3_scratch, Otos_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   745
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   746
    __ cmp(G1_scratch, btos);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   747
    __ br(Assembler::equal, true, Assembler::pt, xreturn_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   748
    __ delayed()->ldsb(Otos_i, G3_scratch, Otos_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   749
    __ should_not_reach_here();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   750
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   751
    __ ldsb(Otos_i, G3_scratch, Otos_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   752
    __ bind(xreturn_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   753
489c9b5090e2 Initial load
duke
parents:
diff changeset
   754
    // _ireturn/_areturn
489c9b5090e2 Initial load
duke
parents:
diff changeset
   755
    __ retl();                      // return from leaf routine
489c9b5090e2 Initial load
duke
parents:
diff changeset
   756
    __ delayed()->mov(O5_savedSP, SP);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   757
489c9b5090e2 Initial load
duke
parents:
diff changeset
   758
    // Generate regular method entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
   759
    __ bind(slow_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   760
    (void) generate_normal_entry(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   761
    return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   762
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   763
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   764
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   765
9176
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   766
// Method entry for java.lang.ref.Reference.get.
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   767
address InterpreterGenerator::generate_Reference_get_entry(void) {
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   768
#ifndef SERIALGC
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   769
  // Code: _aload_0, _getfield, _areturn
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   770
  // parameter size = 1
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   771
  //
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   772
  // 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: 7889
diff changeset
   773
  //    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: 7889
diff changeset
   774
  //    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: 7889
diff changeset
   775
  //
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   776
  // Notes:-
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   777
  // * 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: 7889
diff changeset
   778
  //   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: 7889
diff changeset
   779
  //   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: 7889
diff changeset
   780
  //   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: 7889
diff changeset
   781
  //   update buffer.
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   782
  //   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: 7889
diff changeset
   783
  //   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: 7889
diff changeset
   784
  //   Reference.get() then going through the normal method entry
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   785
  //   will be fine.
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   786
  // * The G1 code can, however, check the receiver object (the instance
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   787
  //   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: 7889
diff changeset
   788
  //   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: 7889
diff changeset
   789
  //   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: 7889
diff changeset
   790
  //   regular method entry code to generate the NPE.
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   791
  //
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   792
  // This code is based on generate_accessor_enty.
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   793
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   794
  address entry = __ pc();
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   795
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   796
  const int referent_offset = java_lang_ref_Reference::referent_offset;
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   797
  guarantee(referent_offset > 0, "referent offset not initialized");
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   798
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   799
  if (UseG1GC) {
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   800
     Label slow_path;
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   801
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   802
    // In the G1 code we don't check if we need to reach a safepoint. We
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   803
    // continue and the thread will safepoint at the next bytecode dispatch.
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   804
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   805
    // Check if local 0 != NULL
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   806
    // 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: 7889
diff changeset
   807
    __ ld_ptr(Gargs, G0, Otos_i ); // get local 0
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   808
    __ tst(Otos_i);  // check if local 0 == NULL and go the slow path
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   809
    __ brx(Assembler::zero, false, Assembler::pn, slow_path);
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   810
    __ delayed()->nop();
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   811
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   812
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   813
    // Load the value of the referent field.
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   814
    if (Assembler::is_simm13(referent_offset)) {
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   815
      __ load_heap_oop(Otos_i, referent_offset, Otos_i);
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   816
    } else {
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   817
      __ set(referent_offset, G3_scratch);
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   818
      __ load_heap_oop(Otos_i, G3_scratch, Otos_i);
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   819
    }
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   820
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   821
    // 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: 7889
diff changeset
   822
    // the referent field in an SATB buffer. Note with
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   823
    // these parameters the pre-barrier does not generate
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   824
    // the load of the previous value
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   825
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   826
    __ g1_write_barrier_pre(noreg /* obj */, noreg /* index */, 0 /* offset */,
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   827
                            Otos_i /* pre_val */,
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   828
                            G3_scratch /* tmp */,
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   829
                            true /* preserve_o_regs */);
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   830
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   831
    // _areturn
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   832
    __ retl();                      // return from leaf routine
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   833
    __ delayed()->mov(O5_savedSP, SP);
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   834
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   835
    // Generate regular method entry
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   836
    __ bind(slow_path);
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   837
    (void) generate_normal_entry(false);
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   838
    return entry;
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   839
  }
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   840
#endif // SERIALGC
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   841
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   842
  // 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: 7889
diff changeset
   843
  // Reference.get is an accessor
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   844
  return generate_accessor_entry();
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   845
}
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 7889
diff changeset
   846
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   847
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   848
// Interpreter stub for calling a native method. (asm interpreter)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   849
// This sets up a somewhat different looking stack for calling the native method
489c9b5090e2 Initial load
duke
parents:
diff changeset
   850
// than the typical interpreter frame setup.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   851
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   852
489c9b5090e2 Initial load
duke
parents:
diff changeset
   853
address InterpreterGenerator::generate_native_entry(bool synchronized) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   854
  address entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   855
489c9b5090e2 Initial load
duke
parents:
diff changeset
   856
  // the following temporary registers are used during frame creation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   857
  const Register Gtmp1 = G3_scratch ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   858
  const Register Gtmp2 = G1_scratch;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   859
  bool inc_counter  = UseCompiler || CountCompiledCalls;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   860
489c9b5090e2 Initial load
duke
parents:
diff changeset
   861
  // make sure registers are different!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   862
  assert_different_registers(G2_thread, G5_method, Gargs, Gtmp1, Gtmp2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   863
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   864
  const Address Laccess_flags(Lmethod, methodOopDesc::access_flags_offset());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   865
489c9b5090e2 Initial load
duke
parents:
diff changeset
   866
  __ verify_oop(G5_method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   867
489c9b5090e2 Initial load
duke
parents:
diff changeset
   868
  const Register Glocals_size = G3;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   869
  assert_different_registers(Glocals_size, G4_scratch, Gframe_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   870
489c9b5090e2 Initial load
duke
parents:
diff changeset
   871
  // make sure method is native & not abstract
489c9b5090e2 Initial load
duke
parents:
diff changeset
   872
  // rethink these assertions - they can be simplified and shared (gri 2/25/2000)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   873
#ifdef ASSERT
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   874
  __ ld(G5_method, methodOopDesc::access_flags_offset(), Gtmp1);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   875
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   876
    Label L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   877
    __ btst(JVM_ACC_NATIVE, Gtmp1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   878
    __ br(Assembler::notZero, false, Assembler::pt, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   879
    __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   880
    __ stop("tried to execute non-native method as native");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   881
    __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   882
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   883
  { Label L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   884
    __ btst(JVM_ACC_ABSTRACT, Gtmp1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   885
    __ br(Assembler::zero, false, Assembler::pt, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   886
    __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   887
    __ stop("tried to execute abstract method as non-abstract");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   888
    __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   889
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   890
#endif // ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   891
489c9b5090e2 Initial load
duke
parents:
diff changeset
   892
 // generate the code to allocate the interpreter stack frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
   893
  generate_fixed_frame(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   894
489c9b5090e2 Initial load
duke
parents:
diff changeset
   895
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   896
  // No locals to initialize for native method
489c9b5090e2 Initial load
duke
parents:
diff changeset
   897
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   898
489c9b5090e2 Initial load
duke
parents:
diff changeset
   899
  // this slot will be set later, we initialize it to null here just in
489c9b5090e2 Initial load
duke
parents:
diff changeset
   900
  // case we get a GC before the actual value is stored later
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   901
  __ st_ptr(G0, FP, (frame::interpreter_frame_oop_temp_offset * wordSize) + STACK_BIAS);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   902
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   903
  const Address do_not_unlock_if_synchronized(G2_thread,
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   904
    JavaThread::do_not_unlock_if_synchronized_offset());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   905
  // Since at this point in the method invocation the exception handler
489c9b5090e2 Initial load
duke
parents:
diff changeset
   906
  // would try to exit the monitor of synchronized methods which hasn't
489c9b5090e2 Initial load
duke
parents:
diff changeset
   907
  // been entered yet, we set the thread local variable
489c9b5090e2 Initial load
duke
parents:
diff changeset
   908
  // _do_not_unlock_if_synchronized to true. If any exception was thrown by
489c9b5090e2 Initial load
duke
parents:
diff changeset
   909
  // runtime, exception handling i.e. unlock_if_synchronized_method will
489c9b5090e2 Initial load
duke
parents:
diff changeset
   910
  // check this thread local flag.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   911
  // This flag has two effects, one is to force an unwind in the topmost
489c9b5090e2 Initial load
duke
parents:
diff changeset
   912
  // interpreter frame and not perform an unlock while doing so.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   913
489c9b5090e2 Initial load
duke
parents:
diff changeset
   914
  __ movbool(true, G3_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   915
  __ stbool(G3_scratch, do_not_unlock_if_synchronized);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   916
489c9b5090e2 Initial load
duke
parents:
diff changeset
   917
  // increment invocation counter and check for overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
   918
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   919
  // Note: checking for negative value instead of overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
   920
  //       so we have a 'sticky' overflow test (may be of
489c9b5090e2 Initial load
duke
parents:
diff changeset
   921
  //       importance as soon as we have true MT/MP)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   922
  Label invocation_counter_overflow;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   923
  Label Lcontinue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   924
  if (inc_counter) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   925
    generate_counter_incr(&invocation_counter_overflow, NULL, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   926
489c9b5090e2 Initial load
duke
parents:
diff changeset
   927
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   928
  __ bind(Lcontinue);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   929
489c9b5090e2 Initial load
duke
parents:
diff changeset
   930
  bang_stack_shadow_pages(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   931
489c9b5090e2 Initial load
duke
parents:
diff changeset
   932
  // reset the _do_not_unlock_if_synchronized flag
489c9b5090e2 Initial load
duke
parents:
diff changeset
   933
  __ stbool(G0, do_not_unlock_if_synchronized);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   934
489c9b5090e2 Initial load
duke
parents:
diff changeset
   935
  // check for synchronized methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
   936
  // Must happen AFTER invocation_counter check and stack overflow check,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   937
  // so method is not locked if overflows.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   938
489c9b5090e2 Initial load
duke
parents:
diff changeset
   939
  if (synchronized) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   940
    lock_method();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   941
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   942
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   943
    { Label ok;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   944
      __ ld(Laccess_flags, O0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   945
      __ btst(JVM_ACC_SYNCHRONIZED, O0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   946
      __ br( Assembler::zero, false, Assembler::pt, ok);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   947
      __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   948
      __ stop("method needs synchronization");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   949
      __ bind(ok);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   950
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   951
#endif // ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   952
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   953
489c9b5090e2 Initial load
duke
parents:
diff changeset
   954
489c9b5090e2 Initial load
duke
parents:
diff changeset
   955
  // start execution
489c9b5090e2 Initial load
duke
parents:
diff changeset
   956
  __ verify_thread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   957
489c9b5090e2 Initial load
duke
parents:
diff changeset
   958
  // JVMTI support
489c9b5090e2 Initial load
duke
parents:
diff changeset
   959
  __ notify_method_entry();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   960
489c9b5090e2 Initial load
duke
parents:
diff changeset
   961
  // native call
489c9b5090e2 Initial load
duke
parents:
diff changeset
   962
489c9b5090e2 Initial load
duke
parents:
diff changeset
   963
  // (note that O0 is never an oop--at most it is a handle)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   964
  // It is important not to smash any handles created by this call,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   965
  // until any oop handle in O0 is dereferenced.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   966
489c9b5090e2 Initial load
duke
parents:
diff changeset
   967
  // (note that the space for outgoing params is preallocated)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   968
489c9b5090e2 Initial load
duke
parents:
diff changeset
   969
  // get signature handler
489c9b5090e2 Initial load
duke
parents:
diff changeset
   970
  { Label L;
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   971
    Address signature_handler(Lmethod, methodOopDesc::signature_handler_offset());
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   972
    __ ld_ptr(signature_handler, G3_scratch);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   973
    __ tst(G3_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   974
    __ brx(Assembler::notZero, false, Assembler::pt, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   975
    __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   976
    __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), Lmethod);
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   977
    __ ld_ptr(signature_handler, G3_scratch);
1
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
489c9b5090e2 Initial load
duke
parents:
diff changeset
   981
  // Push a new frame so that the args will really be stored in
489c9b5090e2 Initial load
duke
parents:
diff changeset
   982
  // Copy a few locals across so the new frame has the variables
489c9b5090e2 Initial load
duke
parents:
diff changeset
   983
  // we need but these values will be dead at the jni call and
489c9b5090e2 Initial load
duke
parents:
diff changeset
   984
  // therefore not gc volatile like the values in the current
489c9b5090e2 Initial load
duke
parents:
diff changeset
   985
  // frame (Lmethod in particular)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   986
489c9b5090e2 Initial load
duke
parents:
diff changeset
   987
  // Flush the method pointer to the register save area
489c9b5090e2 Initial load
duke
parents:
diff changeset
   988
  __ st_ptr(Lmethod, SP, (Lmethod->sp_offset_in_saved_window() * wordSize) + STACK_BIAS);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   989
  __ mov(Llocals, O1);
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   990
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   991
  // calculate where the mirror handle body is allocated in the interpreter frame:
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
   992
  __ add(FP, (frame::interpreter_frame_oop_temp_offset * wordSize) + STACK_BIAS, O2);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   993
489c9b5090e2 Initial load
duke
parents:
diff changeset
   994
  // Calculate current frame size
489c9b5090e2 Initial load
duke
parents:
diff changeset
   995
  __ sub(SP, FP, O3);         // Calculate negative of current frame size
489c9b5090e2 Initial load
duke
parents:
diff changeset
   996
  __ save(SP, O3, SP);        // Allocate an identical sized frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
   997
489c9b5090e2 Initial load
duke
parents:
diff changeset
   998
  // Note I7 has leftover trash. Slow signature handler will fill it in
489c9b5090e2 Initial load
duke
parents:
diff changeset
   999
  // should we get there. Normal jni call will set reasonable last_Java_pc
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1000
  // below (and fix I7 so the stack trace doesn't have a meaningless frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1001
  // in it).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1002
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1003
  // Load interpreter frame's Lmethod into same register here
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1004
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1005
  __ ld_ptr(FP, (Lmethod->sp_offset_in_saved_window() * wordSize) + STACK_BIAS, Lmethod);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1006
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1007
  __ mov(I1, Llocals);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1008
  __ mov(I2, Lscratch2);     // save the address of the mirror
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1009
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1010
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1011
  // ONLY Lmethod and Llocals are valid here!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1012
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1013
  // call signature handler, It will move the arg properly since Llocals in current frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1014
  // matches that in outer frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1015
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1016
  __ callr(G3_scratch, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1017
  __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1018
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1019
  // Result handler is in Lscratch
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1020
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1021
  // Reload interpreter frame's Lmethod since slow signature handler may block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1022
  __ ld_ptr(FP, (Lmethod->sp_offset_in_saved_window() * wordSize) + STACK_BIAS, Lmethod);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1023
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1024
  { Label not_static;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1025
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1026
    __ ld(Laccess_flags, O0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1027
    __ btst(JVM_ACC_STATIC, O0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1028
    __ br( Assembler::zero, false, Assembler::pt, not_static);
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  1029
    // get native function entry point(O0 is a good temp until the very end)
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  1030
    __ delayed()->ld_ptr(Lmethod, in_bytes(methodOopDesc::native_function_offset()), O0);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1031
    // for static methods insert the mirror argument
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1032
    const int mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1033
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  1034
    __ ld_ptr(Lmethod, methodOopDesc:: constants_offset(), O1);
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  1035
    __ ld_ptr(O1, constantPoolOopDesc::pool_holder_offset_in_bytes(), O1);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1036
    __ ld_ptr(O1, mirror_offset, O1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1037
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1038
    if (!PrintSignatureHandlers)  // do not dirty the output with this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1039
    { Label L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1040
      __ tst(O1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1041
      __ brx(Assembler::notZero, false, Assembler::pt, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1042
      __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1043
      __ stop("mirror is missing");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1044
      __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1045
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1046
#endif // ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1047
    __ st_ptr(O1, Lscratch2, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1048
    __ mov(Lscratch2, O1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1049
    __ bind(not_static);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1050
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1051
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1052
  // At this point, arguments have been copied off of stack into
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1053
  // their JNI positions, which are O1..O5 and SP[68..].
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1054
  // Oops are boxed in-place on the stack, with handles copied to arguments.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1055
  // The result handler is in Lscratch.  O0 will shortly hold the JNIEnv*.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1056
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1057
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1058
  { Label L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1059
    __ tst(O0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1060
    __ brx(Assembler::notZero, false, Assembler::pt, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1061
    __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1062
    __ stop("native entry point is missing");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1063
    __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1064
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1065
#endif // ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1066
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1067
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1068
  // setup the frame anchor
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1069
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1070
  // The scavenge function only needs to know that the PC of this frame is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1071
  // in the interpreter method entry code, it doesn't need to know the exact
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1072
  // PC and hence we can use O7 which points to the return address from the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1073
  // previous call in the code stream (signature handler function)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1074
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1075
  // The other trick is we set last_Java_sp to FP instead of the usual SP because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1076
  // we have pushed the extra frame in order to protect the volatile register(s)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1077
  // in that frame when we return from the jni call
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1078
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1079
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1080
  __ set_last_Java_frame(FP, O7);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1081
  __ mov(O7, I7);  // make dummy interpreter frame look like one above,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1082
                   // not meaningless information that'll confuse me.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1083
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1084
  // flush the windows now. We don't care about the current (protection) frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1085
  // only the outer frames
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1086
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1087
  __ flush_windows();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1088
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1089
  // mark windows as flushed
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  1090
  Address flags(G2_thread, JavaThread::frame_anchor_offset() + JavaFrameAnchor::flags_offset());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1091
  __ set(JavaFrameAnchor::flushed, G3_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1092
  __ st(G3_scratch, flags);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1093
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1094
  // Transition from _thread_in_Java to _thread_in_native. We are already safepoint ready.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1095
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  1096
  Address thread_state(G2_thread, JavaThread::thread_state_offset());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1097
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1098
  { Label L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1099
    __ ld(thread_state, G3_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1100
    __ cmp(G3_scratch, _thread_in_Java);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1101
    __ br(Assembler::equal, false, Assembler::pt, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1102
    __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1103
    __ stop("Wrong thread state in native stub");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1104
    __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1105
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1106
#endif // ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1107
  __ set(_thread_in_native, G3_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1108
  __ st(G3_scratch, thread_state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1109
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1110
  // Call the jni method, using the delay slot to set the JNIEnv* argument.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1111
  __ save_thread(L7_thread_cache); // save Gthread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1112
  __ callr(O0, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1113
  __ delayed()->
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1114
     add(L7_thread_cache, in_bytes(JavaThread::jni_environment_offset()), O0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1115
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1116
  // Back from jni method Lmethod in this frame is DEAD, DEAD, DEAD
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1117
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1118
  __ restore_thread(L7_thread_cache); // restore G2_thread
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
  1119
  __ reinit_heapbase();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1120
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1121
  // must we block?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1122
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1123
  // Block, if necessary, before resuming in _thread_in_Java state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1124
  // In order for GC to work, don't clear the last_Java_sp until after blocking.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1125
  { Label no_block;
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  1126
    AddressLiteral sync_state(SafepointSynchronize::address_of_state());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1127
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1128
    // Switch thread to "native transition" state before reading the synchronization state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1129
    // This additional state is necessary because reading and testing the synchronization
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1130
    // state is not atomic w.r.t. GC, as this scenario demonstrates:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1131
    //     Java thread A, in _thread_in_native state, loads _not_synchronized and is preempted.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1132
    //     VM thread changes sync state to synchronizing and suspends threads for GC.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1133
    //     Thread A is resumed to finish this native method, but doesn't block here since it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1134
    //     didn't see any synchronization is progress, and escapes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1135
    __ set(_thread_in_native_trans, G3_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1136
    __ st(G3_scratch, thread_state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1137
    if(os::is_MP()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1138
      if (UseMembar) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1139
        // Force this write out before the read below
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1140
        __ membar(Assembler::StoreLoad);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1141
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1142
        // Write serialization page so VM thread can do a pseudo remote membar.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1143
        // We use the current thread pointer to calculate a thread specific
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1144
        // offset to write to within the page. This minimizes bus traffic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1145
        // due to cache line collision.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1146
        __ serialize_memory(G2_thread, G1_scratch, G3_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1147
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1148
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1149
    __ load_contents(sync_state, G3_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1150
    __ cmp(G3_scratch, SafepointSynchronize::_not_synchronized);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1151
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1152
    Label L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1153
    __ br(Assembler::notEqual, false, Assembler::pn, L);
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  1154
    __ delayed()->ld(G2_thread, JavaThread::suspend_flags_offset(), G3_scratch);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1155
    __ cmp(G3_scratch, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1156
    __ br(Assembler::equal, false, Assembler::pt, no_block);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1157
    __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1158
    __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1159
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1160
    // Block.  Save any potential method result value before the operation and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1161
    // use a leaf call to leave the last_Java_frame setup undisturbed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1162
    save_native_result();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1163
    __ call_VM_leaf(L7_thread_cache,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1164
                    CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1165
                    G2_thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1166
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1167
    // Restore any method result value
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1168
    restore_native_result();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1169
    __ bind(no_block);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1170
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1171
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1172
  // Clear the frame anchor now
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1173
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1174
  __ reset_last_Java_frame();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1175
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1176
  // Move the result handler address
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1177
  __ mov(Lscratch, G3_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1178
  // return possible result to the outer frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1179
#ifndef __LP64
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1180
  __ mov(O0, I0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1181
  __ restore(O1, G0, O1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1182
#else
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1183
  __ restore(O0, G0, O0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1184
#endif /* __LP64 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1185
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1186
  // Move result handler to expected register
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1187
  __ mov(G3_scratch, Lscratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1188
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1189
  // Back in normal (native) interpreter frame. State is thread_in_native_trans
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1190
  // switch to thread_in_Java.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1191
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1192
  __ set(_thread_in_Java, G3_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1193
  __ st(G3_scratch, thread_state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1194
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1195
  // reset handle block
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  1196
  __ ld_ptr(G2_thread, JavaThread::active_handles_offset(), G3_scratch);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1197
  __ st_ptr(G0, G3_scratch, JNIHandleBlock::top_offset_in_bytes());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1198
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1199
  // If we have an oop result store it where it will be safe for any further gc
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1200
  // until we return now that we've released the handle it might be protected by
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1201
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1202
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1203
    Label no_oop, store_result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1204
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1205
    __ set((intptr_t)AbstractInterpreter::result_handler(T_OBJECT), G3_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1206
    __ cmp(G3_scratch, Lscratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1207
    __ brx(Assembler::notEqual, false, Assembler::pt, no_oop);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1208
    __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1209
    __ addcc(G0, O0, O0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1210
    __ brx(Assembler::notZero, true, Assembler::pt, store_result);     // if result is not NULL:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1211
    __ delayed()->ld_ptr(O0, 0, O0);                                   // unbox it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1212
    __ mov(G0, O0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1213
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1214
    __ bind(store_result);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1215
    // Store it where gc will look for it and result handler expects it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1216
    __ st_ptr(O0, FP, (frame::interpreter_frame_oop_temp_offset*wordSize) + STACK_BIAS);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1217
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1218
    __ bind(no_oop);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1219
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1220
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1221
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1222
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1223
  // handle exceptions (exception handling will handle unlocking!)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1224
  { Label L;
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  1225
    Address exception_addr(G2_thread, Thread::pending_exception_offset());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1226
    __ ld_ptr(exception_addr, Gtemp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1227
    __ tst(Gtemp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1228
    __ brx(Assembler::equal, false, Assembler::pt, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1229
    __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1230
    // Note: This could be handled more efficiently since we know that the native
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1231
    //       method doesn't have an exception handler. We could directly return
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1232
    //       to the exception handler for the caller.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1233
    __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_pending_exception));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1234
    __ should_not_reach_here();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1235
    __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1236
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1237
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1238
  // JVMTI support (preserves thread register)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1239
  __ notify_method_exit(true, ilgl, InterpreterMacroAssembler::NotifyJVMTI);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1240
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1241
  if (synchronized) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1242
    // save and restore any potential method result value around the unlocking operation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1243
    save_native_result();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1244
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1245
    __ add( __ top_most_monitor(), O1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1246
    __ unlock_object(O1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1247
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1248
    restore_native_result();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1249
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1250
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1251
#if defined(COMPILER2) && !defined(_LP64)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1252
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1253
  // C2 expects long results in G1 we can't tell if we're returning to interpreted
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1254
  // or compiled so just be safe.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1255
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1256
  __ sllx(O0, 32, G1);          // Shift bits into high G1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1257
  __ srl (O1, 0, O1);           // Zero extend O1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1258
  __ or3 (O1, G1, G1);          // OR 64 bits into G1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1259
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1260
#endif /* COMPILER2 && !_LP64 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1261
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1262
  // dispose of return address and remove activation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1263
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1264
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1265
    Label ok;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1266
    __ cmp(I5_savedSP, FP);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1267
    __ brx(Assembler::greaterEqualUnsigned, false, Assembler::pt, ok);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1268
    __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1269
    __ stop("bad I5_savedSP value");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1270
    __ should_not_reach_here();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1271
    __ bind(ok);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1272
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1273
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1274
  if (TraceJumps) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1275
    // Move target to register that is recordable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1276
    __ mov(Lscratch, G3_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1277
    __ JMP(G3_scratch, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1278
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1279
    __ jmp(Lscratch, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1280
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1281
  __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1282
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1283
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1284
  if (inc_counter) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1285
    // handle invocation counter overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1286
    __ bind(invocation_counter_overflow);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1287
    generate_counter_overflow(Lcontinue);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1288
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1289
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1290
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1291
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1292
  return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1293
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1294
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1295
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1296
// Generic method entry to (asm) interpreter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1297
//------------------------------------------------------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1298
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1299
address InterpreterGenerator::generate_normal_entry(bool synchronized) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1300
  address entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1301
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1302
  bool inc_counter  = UseCompiler || CountCompiledCalls;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1303
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1304
  // the following temporary registers are used during frame creation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1305
  const Register Gtmp1 = G3_scratch ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1306
  const Register Gtmp2 = G1_scratch;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1307
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1308
  // make sure registers are different!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1309
  assert_different_registers(G2_thread, G5_method, Gargs, Gtmp1, Gtmp2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1310
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  1311
  const Address size_of_parameters(G5_method, methodOopDesc::size_of_parameters_offset());
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  1312
  const Address size_of_locals    (G5_method, methodOopDesc::size_of_locals_offset());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1313
  // Seems like G5_method is live at the point this is used. So we could make this look consistent
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1314
  // and use in the asserts.
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  1315
  const Address access_flags      (Lmethod,   methodOopDesc::access_flags_offset());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1316
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1317
  __ verify_oop(G5_method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1318
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1319
  const Register Glocals_size = G3;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1320
  assert_different_registers(Glocals_size, G4_scratch, Gframe_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1321
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1322
  // make sure method is not native & not abstract
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1323
  // rethink these assertions - they can be simplified and shared (gri 2/25/2000)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1324
#ifdef ASSERT
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  1325
  __ ld(G5_method, methodOopDesc::access_flags_offset(), Gtmp1);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1326
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1327
    Label L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1328
    __ btst(JVM_ACC_NATIVE, Gtmp1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1329
    __ br(Assembler::zero, false, Assembler::pt, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1330
    __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1331
    __ stop("tried to execute native method as non-native");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1332
    __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1333
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1334
  { Label L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1335
    __ btst(JVM_ACC_ABSTRACT, Gtmp1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1336
    __ br(Assembler::zero, false, Assembler::pt, L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1337
    __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1338
    __ stop("tried to execute abstract method as non-abstract");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1339
    __ bind(L);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1340
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1341
#endif // ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1342
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1343
  // generate the code to allocate the interpreter stack frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1344
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1345
  generate_fixed_frame(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1346
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1347
#ifdef FAST_DISPATCH
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1348
  __ set((intptr_t)Interpreter::dispatch_table(), IdispatchTables);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1349
                                          // set bytecode dispatch table base
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1350
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1351
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1352
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1353
  // Code to initialize the extra (i.e. non-parm) locals
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1354
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1355
  Register init_value = noreg;    // will be G0 if we must clear locals
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1356
  // The way the code was setup before zerolocals was always true for vanilla java entries.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1357
  // It could only be false for the specialized entries like accessor or empty which have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1358
  // no extra locals so the testing was a waste of time and the extra locals were always
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1359
  // initialized. We removed this extra complication to already over complicated code.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1360
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1361
  init_value = G0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1362
  Label clear_loop;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1363
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1364
  // NOTE: If you change the frame layout, this code will need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1365
  // be updated!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1366
  __ lduh( size_of_locals, O2 );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1367
  __ lduh( size_of_parameters, O1 );
5419
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 5416
diff changeset
  1368
  __ sll( O2, Interpreter::logStackElementSize, O2);
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 5416
diff changeset
  1369
  __ sll( O1, Interpreter::logStackElementSize, O1 );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1370
  __ sub( Llocals, O2, O2 );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1371
  __ sub( Llocals, O1, O1 );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1372
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1373
  __ bind( clear_loop );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1374
  __ inc( O2, wordSize );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1375
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1376
  __ cmp( O2, O1 );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1377
  __ brx( Assembler::lessEqualUnsigned, true, Assembler::pt, clear_loop );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1378
  __ delayed()->st_ptr( init_value, O2, 0 );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1379
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  1380
  const Address do_not_unlock_if_synchronized(G2_thread,
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  1381
    JavaThread::do_not_unlock_if_synchronized_offset());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1382
  // Since at this point in the method invocation the exception handler
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1383
  // would try to exit the monitor of synchronized methods which hasn't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1384
  // been entered yet, we set the thread local variable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1385
  // _do_not_unlock_if_synchronized to true. If any exception was thrown by
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1386
  // runtime, exception handling i.e. unlock_if_synchronized_method will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1387
  // check this thread local flag.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1388
  __ movbool(true, G3_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1389
  __ stbool(G3_scratch, do_not_unlock_if_synchronized);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1390
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1391
  // increment invocation counter and check for overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1392
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1393
  // Note: checking for negative value instead of overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1394
  //       so we have a 'sticky' overflow test (may be of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1395
  //       importance as soon as we have true MT/MP)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1396
  Label invocation_counter_overflow;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1397
  Label profile_method;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1398
  Label profile_method_continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1399
  Label Lcontinue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1400
  if (inc_counter) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1401
    generate_counter_incr(&invocation_counter_overflow, &profile_method, &profile_method_continue);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1402
    if (ProfileInterpreter) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1403
      __ bind(profile_method_continue);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1404
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1405
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1406
  __ bind(Lcontinue);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1407
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1408
  bang_stack_shadow_pages(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1409
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1410
  // reset the _do_not_unlock_if_synchronized flag
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1411
  __ stbool(G0, do_not_unlock_if_synchronized);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1412
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1413
  // check for synchronized methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1414
  // Must happen AFTER invocation_counter check and stack overflow check,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1415
  // so method is not locked if overflows.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1416
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1417
  if (synchronized) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1418
    lock_method();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1419
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1420
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1421
    { Label ok;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1422
      __ ld(access_flags, O0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1423
      __ btst(JVM_ACC_SYNCHRONIZED, O0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1424
      __ br( Assembler::zero, false, Assembler::pt, ok);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1425
      __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1426
      __ stop("method needs synchronization");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1427
      __ bind(ok);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1428
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1429
#endif // ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1430
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1431
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1432
  // start execution
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1433
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1434
  __ verify_thread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1435
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1436
  // jvmti support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1437
  __ notify_method_entry();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1438
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1439
  // start executing instructions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1440
  __ dispatch_next(vtos);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1441
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1442
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1443
  if (inc_counter) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1444
    if (ProfileInterpreter) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1445
      // We have decided to profile this method in the interpreter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1446
      __ bind(profile_method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1447
7889
02144432d0e1 4930919: race condition in MDO creation at back branch locations
iveresov
parents: 7397
diff changeset
  1448
      __ 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
  1449
      __ set_method_data_pointer_for_bcp();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1450
      __ ba(false, profile_method_continue);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1451
      __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1452
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1453
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1454
    // handle invocation counter overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1455
    __ bind(invocation_counter_overflow);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1456
    generate_counter_overflow(Lcontinue);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1457
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1458
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1459
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1460
  return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1461
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1462
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1463
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1464
//----------------------------------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1465
// Entry points & stack frame layout
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1466
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1467
// Here we generate the various kind of entries into the interpreter.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1468
// The two main entry type are generic bytecode methods and native call method.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1469
// These both come in synchronized and non-synchronized versions but the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1470
// frame layout they create is very similar. The other method entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1471
// types are really just special purpose entries that are really entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1472
// and interpretation all in one. These are for trivial methods like
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1473
// accessor, empty, or special math methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1474
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1475
// When control flow reaches any of the entry types for the interpreter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1476
// the following holds ->
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1477
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1478
// C2 Calling Conventions:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1479
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1480
// The entry code below assumes that the following registers are set
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1481
// when coming in:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1482
//    G5_method: holds the methodOop of the method to call
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1483
//    Lesp:    points to the TOS of the callers expression stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1484
//             after having pushed all the parameters
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1485
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1486
// The entry code does the following to setup an interpreter frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1487
//   pop parameters from the callers stack by adjusting Lesp
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1488
//   set O0 to Lesp
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1489
//   compute X = (max_locals - num_parameters)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1490
//   bump SP up by X to accomadate the extra locals
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1491
//   compute X = max_expression_stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1492
//               + vm_local_words
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1493
//               + 16 words of register save area
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1494
//   save frame doing a save sp, -X, sp growing towards lower addresses
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1495
//   set Lbcp, Lmethod, LcpoolCache
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1496
//   set Llocals to i0
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1497
//   set Lmonitors to FP - rounded_vm_local_words
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1498
//   set Lesp to Lmonitors - 4
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1499
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1500
//  The frame has now been setup to do the rest of the entry code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1501
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1502
// Try this optimization:  Most method entries could live in a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1503
// "one size fits all" stack frame without all the dynamic size
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1504
// calculations.  It might be profitable to do all this calculation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1505
// statically and approximately for "small enough" methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1506
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1507
//-----------------------------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1508
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1509
// C1 Calling conventions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1510
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1511
// Upon method entry, the following registers are setup:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1512
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1513
// g2 G2_thread: current thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1514
// g5 G5_method: method to activate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1515
// g4 Gargs  : pointer to last argument
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1516
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1517
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1518
// Stack:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1519
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1520
// +---------------+ <--- sp
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1521
// |               |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1522
// : reg save area :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1523
// |               |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1524
// +---------------+ <--- sp + 0x40
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1525
// |               |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1526
// : extra 7 slots :      note: these slots are not really needed for the interpreter (fix later)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1527
// |               |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1528
// +---------------+ <--- sp + 0x5c
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1529
// |               |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1530
// :     free      :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1531
// |               |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1532
// +---------------+ <--- Gargs
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1533
// |               |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1534
// :   arguments   :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1535
// |               |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1536
// +---------------+
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1537
// |               |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1538
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1539
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1540
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1541
// AFTER FRAME HAS BEEN SETUP for method interpretation the stack looks like:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1542
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1543
// +---------------+ <--- sp
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1544
// |               |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1545
// : reg save area :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1546
// |               |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1547
// +---------------+ <--- sp + 0x40
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1548
// |               |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1549
// : extra 7 slots :      note: these slots are not really needed for the interpreter (fix later)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1550
// |               |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1551
// +---------------+ <--- sp + 0x5c
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1552
// |               |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1553
// :               :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1554
// |               | <--- Lesp
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1555
// +---------------+ <--- Lmonitors (fp - 0x18)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1556
// |   VM locals   |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1557
// +---------------+ <--- fp
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1558
// |               |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1559
// : reg save area :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1560
// |               |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1561
// +---------------+ <--- fp + 0x40
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1562
// |               |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1563
// : extra 7 slots :      note: these slots are not really needed for the interpreter (fix later)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1564
// |               |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1565
// +---------------+ <--- fp + 0x5c
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1566
// |               |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1567
// :     free      :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1568
// |               |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1569
// +---------------+
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1570
// |               |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1571
// : nonarg locals :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1572
// |               |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1573
// +---------------+
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1574
// |               |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1575
// :   arguments   :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1576
// |               | <--- Llocals
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1577
// +---------------+ <--- Gargs
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1578
// |               |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1579
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1580
static int size_activation_helper(int callee_extra_locals, int max_stack, int monitor_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1581
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1582
  // Figure out the size of an interpreter frame (in words) given that we have a fully allocated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1583
  // expression stack, the callee will have callee_extra_locals (so we can account for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1584
  // frame extension) and monitor_size for monitors. Basically we need to calculate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1585
  // this exactly like generate_fixed_frame/generate_compute_interpreter_state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1586
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1587
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1588
  // The big complicating thing here is that we must ensure that the stack stays properly
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1589
  // aligned. This would be even uglier if monitor size wasn't modulo what the stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1590
  // needs to be aligned for). We are given that the sp (fp) is already aligned by
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1591
  // the caller so we must ensure that it is properly aligned for our callee.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1592
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1593
  const int rounded_vm_local_words =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1594
       round_to(frame::interpreter_frame_vm_local_words,WordsPerLong);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1595
  // callee_locals and max_stack are counts, not the size in frame.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1596
  const int locals_size =
5419
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 5416
diff changeset
  1597
       round_to(callee_extra_locals * Interpreter::stackElementWords, WordsPerLong);
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 5416
diff changeset
  1598
  const int max_stack_words = max_stack * Interpreter::stackElementWords;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1599
  return (round_to((max_stack_words
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 670
diff changeset
  1600
                   //6815692//+ methodOopDesc::extra_stack_words()
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1601
                   + rounded_vm_local_words
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1602
                   + frame::memory_parameter_word_sp_offset), WordsPerLong)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1603
                   // already rounded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1604
                   + locals_size + monitor_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1605
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1606
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1607
// How much stack a method top interpreter activation needs in words.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1608
int AbstractInterpreter::size_top_interpreter_activation(methodOop method) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1609
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1610
  // See call_stub code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1611
  int call_stub_size  = round_to(7 + frame::memory_parameter_word_sp_offset,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1612
                                 WordsPerLong);    // 7 + register save area
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1613
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1614
  // Save space for one monitor to get into the interpreted method in case
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1615
  // the method is synchronized
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1616
  int monitor_size    = method->is_synchronized() ?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1617
                                1*frame::interpreter_frame_monitor_size() : 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1618
  return size_activation_helper(method->max_locals(), method->max_stack(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1619
                                 monitor_size) + call_stub_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1620
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1621
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1622
int AbstractInterpreter::layout_activation(methodOop method,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1623
                                           int tempcount,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1624
                                           int popframe_extra_args,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1625
                                           int moncount,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1626
                                           int callee_param_count,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1627
                                           int callee_local_count,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1628
                                           frame* caller,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1629
                                           frame* interpreter_frame,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1630
                                           bool is_top_frame) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1631
  // Note: This calculation must exactly parallel the frame setup
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1632
  // in InterpreterGenerator::generate_fixed_frame.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1633
  // If f!=NULL, set up the following variables:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1634
  //   - Lmethod
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1635
  //   - Llocals
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1636
  //   - Lmonitors (to the indicated number of monitors)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1637
  //   - Lesp (to the indicated number of temps)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1638
  // The frame f (if not NULL) on entry is a description of the caller of the frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1639
  // we are about to layout. We are guaranteed that we will be able to fill in a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1640
  // new interpreter frame as its callee (i.e. the stack space is allocated and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1641
  // the amount was determined by an earlier call to this method with f == NULL).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1642
  // On return f (if not NULL) while describe the interpreter frame we just layed out.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1643
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1644
  int monitor_size           = moncount * frame::interpreter_frame_monitor_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1645
  int rounded_vm_local_words = round_to(frame::interpreter_frame_vm_local_words,WordsPerLong);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1646
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1647
  assert(monitor_size == round_to(monitor_size, WordsPerLong), "must align");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1648
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1649
  // Note: if you look closely this appears to be doing something much different
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1650
  // than generate_fixed_frame. What is happening is this. On sparc we have to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1651
  // this dance with interpreter_sp_adjustment because the window save area would
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1652
  // appear just below the bottom (tos) of the caller's java expression stack. Because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1653
  // the interpreter want to have the locals completely contiguous generate_fixed_frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1654
  // will adjust the caller's sp for the "extra locals" (max_locals - parameter_size).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1655
  // Now in generate_fixed_frame the extension of the caller's sp happens in the callee.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1656
  // In this code the opposite occurs the caller adjusts it's own stack base on the callee.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1657
  // This is mostly ok but it does cause a problem when we get to the initial frame (the oldest)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1658
  // because the oldest frame would have adjust its callers frame and yet that frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1659
  // already exists and isn't part of this array of frames we are unpacking. So at first
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1660
  // glance this would seem to mess up that frame. However Deoptimization::fetch_unroll_info_helper()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1661
  // will after it calculates all of the frame's on_stack_size()'s will then figure out the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1662
  // amount to adjust the caller of the initial (oldest) frame and the calculation will all
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1663
  // add up. It does seem like it simpler to account for the adjustment here (and remove the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1664
  // callee... parameters here). However this would mean that this routine would have to take
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1665
  // the caller frame as input so we could adjust its sp (and set it's interpreter_sp_adjustment)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1666
  // and run the calling loop in the reverse order. This would also would appear to mean making
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1667
  // this code aware of what the interactions are when that initial caller fram was an osr or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1668
  // other adapter frame. deoptimization is complicated enough and  hard enough to debug that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1669
  // there is no sense in messing working code.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1670
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1671
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1672
  int rounded_cls = round_to((callee_local_count - callee_param_count), WordsPerLong);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1673
  assert(rounded_cls == round_to(rounded_cls, WordsPerLong), "must align");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1674
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1675
  int raw_frame_size = size_activation_helper(rounded_cls, method->max_stack(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1676
                                              monitor_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1677
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1678
  if (interpreter_frame != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1679
    // The skeleton frame must already look like an interpreter frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1680
    // even if not fully filled out.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1681
    assert(interpreter_frame->is_interpreted_frame(), "Must be interpreted frame");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1682
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1683
    intptr_t* fp = interpreter_frame->fp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1684
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1685
    JavaThread* thread = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1686
    RegisterMap map(thread, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1687
    // More verification that skeleton frame is properly walkable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1688
    assert(fp == caller->sp(), "fp must match");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1689
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1690
    intptr_t* montop     = fp - rounded_vm_local_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1691
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1692
    // preallocate monitors (cf. __ add_monitor_to_stack)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1693
    intptr_t* monitors = montop - monitor_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1694
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1695
    // preallocate stack space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1696
    intptr_t*  esp = monitors - 1 -
5419
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 5416
diff changeset
  1697
                     (tempcount * Interpreter::stackElementWords) -
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1698
                     popframe_extra_args;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1699
5419
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 5416
diff changeset
  1700
    int local_words = method->max_locals() * Interpreter::stackElementWords;
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 5416
diff changeset
  1701
    int parm_words  = method->size_of_parameters() * Interpreter::stackElementWords;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1702
    NEEDS_CLEANUP;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1703
    intptr_t* locals;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1704
    if (caller->is_interpreted_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1705
      // Can force the locals area to end up properly overlapping the top of the expression stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1706
      intptr_t* Lesp_ptr = caller->interpreter_frame_tos_address() - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1707
      // Note that this computation means we replace size_of_parameters() values from the caller
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1708
      // interpreter frame's expression stack with our argument locals
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1709
      locals = Lesp_ptr + parm_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1710
      int delta = local_words - parm_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1711
      int computed_sp_adjustment = (delta > 0) ? round_to(delta, WordsPerLong) : 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1712
      *interpreter_frame->register_addr(I5_savedSP)    = (intptr_t) (fp + computed_sp_adjustment) - STACK_BIAS;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1713
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1714
      assert(caller->is_compiled_frame() || caller->is_entry_frame(), "only possible cases");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1715
      // Don't have Lesp available; lay out locals block in the caller
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1716
      // adjacent to the register window save area.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1717
      //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1718
      // Compiled frames do not allocate a varargs area which is why this if
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1719
      // statement is needed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1720
      //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1721
      if (caller->is_compiled_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1722
        locals = fp + frame::register_save_words + local_words - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1723
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1724
        locals = fp + frame::memory_parameter_word_sp_offset + local_words - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1725
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1726
      if (!caller->is_entry_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1727
        // Caller wants his own SP back
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1728
        int caller_frame_size = caller->cb()->frame_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1729
        *interpreter_frame->register_addr(I5_savedSP) = (intptr_t)(caller->fp() - caller_frame_size) - STACK_BIAS;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1730
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1731
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1732
    if (TraceDeoptimization) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1733
      if (caller->is_entry_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1734
        // make sure I5_savedSP and the entry frames notion of saved SP
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1735
        // agree.  This assertion duplicate a check in entry frame code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1736
        // but catches the failure earlier.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1737
        assert(*caller->register_addr(Lscratch) == *interpreter_frame->register_addr(I5_savedSP),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1738
               "would change callers SP");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1739
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1740
      if (caller->is_entry_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1741
        tty->print("entry ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1742
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1743
      if (caller->is_compiled_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1744
        tty->print("compiled ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1745
        if (caller->is_deoptimized_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1746
          tty->print("(deopt) ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1747
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1748
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1749
      if (caller->is_interpreted_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1750
        tty->print("interpreted ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1751
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1752
      tty->print_cr("caller fp=0x%x sp=0x%x", caller->fp(), caller->sp());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1753
      tty->print_cr("save area = 0x%x, 0x%x", caller->sp(), caller->sp() + 16);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1754
      tty->print_cr("save area = 0x%x, 0x%x", caller->fp(), caller->fp() + 16);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1755
      tty->print_cr("interpreter fp=0x%x sp=0x%x", interpreter_frame->fp(), interpreter_frame->sp());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1756
      tty->print_cr("save area = 0x%x, 0x%x", interpreter_frame->sp(), interpreter_frame->sp() + 16);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1757
      tty->print_cr("save area = 0x%x, 0x%x", interpreter_frame->fp(), interpreter_frame->fp() + 16);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1758
      tty->print_cr("Llocals = 0x%x", locals);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1759
      tty->print_cr("Lesp = 0x%x", esp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1760
      tty->print_cr("Lmonitors = 0x%x", monitors);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1761
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1762
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1763
    if (method->max_locals() > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1764
      assert(locals < caller->sp() || locals >= (caller->sp() + 16), "locals in save area");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1765
      assert(locals < caller->fp() || locals > (caller->fp() + 16), "locals in save area");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1766
      assert(locals < interpreter_frame->sp() || locals > (interpreter_frame->sp() + 16), "locals in save area");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1767
      assert(locals < interpreter_frame->fp() || locals >= (interpreter_frame->fp() + 16), "locals in save area");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1768
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1769
#ifdef _LP64
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1770
    assert(*interpreter_frame->register_addr(I5_savedSP) & 1, "must be odd");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1771
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1772
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1773
    *interpreter_frame->register_addr(Lmethod)     = (intptr_t) method;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1774
    *interpreter_frame->register_addr(Llocals)     = (intptr_t) locals;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1775
    *interpreter_frame->register_addr(Lmonitors)   = (intptr_t) monitors;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1776
    *interpreter_frame->register_addr(Lesp)        = (intptr_t) esp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1777
    // Llast_SP will be same as SP as there is no adapter space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1778
    *interpreter_frame->register_addr(Llast_SP)    = (intptr_t) interpreter_frame->sp() - STACK_BIAS;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1779
    *interpreter_frame->register_addr(LcpoolCache) = (intptr_t) method->constants()->cache();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1780
#ifdef FAST_DISPATCH
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1781
    *interpreter_frame->register_addr(IdispatchTables) = (intptr_t) Interpreter::dispatch_table();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1782
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1783
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1784
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1785
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1786
    BasicObjectLock* mp = (BasicObjectLock*)monitors;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1787
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1788
    assert(interpreter_frame->interpreter_frame_method() == method, "method matches");
5419
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 5416
diff changeset
  1789
    assert(interpreter_frame->interpreter_frame_local_at(9) == (intptr_t *)((intptr_t)locals - (9 * Interpreter::stackElementSize)), "locals match");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1790
    assert(interpreter_frame->interpreter_frame_monitor_end()   == mp, "monitor_end matches");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1791
    assert(((intptr_t *)interpreter_frame->interpreter_frame_monitor_begin()) == ((intptr_t *)mp)+monitor_size, "monitor_begin matches");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1792
    assert(interpreter_frame->interpreter_frame_tos_address()-1 == esp, "esp matches");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1793
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1794
    // check bounds
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1795
    intptr_t* lo = interpreter_frame->sp() + (frame::memory_parameter_word_sp_offset - 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1796
    intptr_t* hi = interpreter_frame->fp() - rounded_vm_local_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1797
    assert(lo < monitors && montop <= hi, "monitors in bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1798
    assert(lo <= esp && esp < monitors, "esp in bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1799
#endif // ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1800
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1801
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1802
  return raw_frame_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1803
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1804
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1805
//----------------------------------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1806
// Exceptions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1807
void TemplateInterpreterGenerator::generate_throw_exception() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1808
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1809
  // Entry point in previous activation (i.e., if the caller was interpreted)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1810
  Interpreter::_rethrow_exception_entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1811
  // O0: exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1812
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1813
  // entry point for exceptions thrown within interpreter code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1814
  Interpreter::_throw_exception_entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1815
  __ verify_thread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1816
  // expression stack is undefined here
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1817
  // O0: exception, i.e. Oexception
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1818
  // Lbcp: exception bcx
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1819
  __ verify_oop(Oexception);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1820
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1821
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1822
  // expression stack must be empty before entering the VM in case of an exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1823
  __ empty_expression_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1824
  // find exception handler address and preserve exception oop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1825
  // call C routine to find handler and jump to it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1826
  __ call_VM(O1, CAST_FROM_FN_PTR(address, InterpreterRuntime::exception_handler_for_exception), Oexception);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1827
  __ push_ptr(O1); // push exception for exception handler bytecodes
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1828
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1829
  __ JMP(O0, 0); // jump to exception handler (may be remove activation entry!)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1830
  __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1831
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1832
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1833
  // if the exception is not handled in the current frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1834
  // the frame is removed and the exception is rethrown
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1835
  // (i.e. exception continuation is _rethrow_exception)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1836
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1837
  // Note: At this point the bci is still the bxi for the instruction which caused
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1838
  //       the exception and the expression stack is empty. Thus, for any VM calls
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1839
  //       at this point, GC will find a legal oop map (with empty expression stack).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1840
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1841
  // in current activation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1842
  // tos: exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1843
  // Lbcp: exception bcp
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1844
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1845
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1846
  // JVMTI PopFrame support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1847
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1848
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1849
  Interpreter::_remove_activation_preserving_args_entry = __ pc();
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  1850
  Address popframe_condition_addr(G2_thread, JavaThread::popframe_condition_offset());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1851
  // Set the popframe_processing bit in popframe_condition indicating that we are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1852
  // currently handling popframe, so that call_VMs that may happen later do not trigger new
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1853
  // popframe handling cycles.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1854
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1855
  __ ld(popframe_condition_addr, G3_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1856
  __ or3(G3_scratch, JavaThread::popframe_processing_bit, G3_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1857
  __ stw(G3_scratch, popframe_condition_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1858
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1859
  // Empty the expression stack, as in normal exception handling
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1860
  __ empty_expression_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1861
  __ unlock_if_synchronized_method(vtos, /* throw_monitor_exception */ false, /* install_monitor_exception */ false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1862
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1863
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1864
    // Check to see whether we are returning to a deoptimized frame.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1865
    // (The PopFrame call ensures that the caller of the popped frame is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1866
    // either interpreted or compiled and deoptimizes it if compiled.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1867
    // In this case, we can't call dispatch_next() after the frame is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1868
    // popped, but instead must save the incoming arguments and restore
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1869
    // them after deoptimization has occurred.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1870
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1871
    // Note that we don't compare the return PC against the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1872
    // deoptimization blob's unpack entry because of the presence of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1873
    // adapter frames in C2.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1874
    Label caller_not_deoptimized;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1875
    __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, InterpreterRuntime::interpreter_contains), I7);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1876
    __ tst(O0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1877
    __ brx(Assembler::notEqual, false, Assembler::pt, caller_not_deoptimized);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1878
    __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1879
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1880
    const Register Gtmp1 = G3_scratch;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1881
    const Register Gtmp2 = G1_scratch;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1882
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1883
    // Compute size of arguments for saving when returning to deoptimized caller
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1884
    __ lduh(Lmethod, in_bytes(methodOopDesc::size_of_parameters_offset()), Gtmp1);
5419
f2e8cc8c12ea 6943304: remove tagged stack interpreter
twisti
parents: 5416
diff changeset
  1885
    __ sll(Gtmp1, Interpreter::logStackElementSize, Gtmp1);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1886
    __ sub(Llocals, Gtmp1, Gtmp2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1887
    __ add(Gtmp2, wordSize, Gtmp2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1888
    // Save these arguments
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1889
    __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, Deoptimization::popframe_preserve_args), G2_thread, Gtmp1, Gtmp2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1890
    // Inform deoptimization that it is responsible for restoring these arguments
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1891
    __ set(JavaThread::popframe_force_deopt_reexecution_bit, Gtmp1);
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  1892
    Address popframe_condition_addr(G2_thread, JavaThread::popframe_condition_offset());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1893
    __ st(Gtmp1, popframe_condition_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1894
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1895
    // Return from the current method
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1896
    // The caller's SP was adjusted upon method entry to accomodate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1897
    // the callee's non-argument locals. Undo that adjustment.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1898
    __ ret();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1899
    __ delayed()->restore(I5_savedSP, G0, SP);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1900
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1901
    __ bind(caller_not_deoptimized);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1902
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1903
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1904
  // Clear the popframe condition flag
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1905
  __ stw(G0 /* popframe_inactive */, popframe_condition_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1906
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1907
  // Get out of the current method (how this is done depends on the particular compiler calling
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1908
  // convention that the interpreter currently follows)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1909
  // The caller's SP was adjusted upon method entry to accomodate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1910
  // the callee's non-argument locals. Undo that adjustment.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1911
  __ restore(I5_savedSP, G0, SP);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1912
  // The method data pointer was incremented already during
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1913
  // call profiling. We have to restore the mdp for the current bcp.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1914
  if (ProfileInterpreter) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1915
    __ set_method_data_pointer_for_bcp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1916
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1917
  // Resume bytecode interpretation at the current bcp
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1918
  __ dispatch_next(vtos);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1919
  // end of JVMTI PopFrame support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1920
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1921
  Interpreter::_remove_activation_entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1922
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1923
  // preserve exception over this code sequence (remove activation calls the vm, but oopmaps are not correct here)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1924
  __ pop_ptr(Oexception);                                  // get exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1925
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1926
  // Intel has the following comment:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1927
  //// remove the activation (without doing throws on illegalMonitorExceptions)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1928
  // They remove the activation without checking for bad monitor state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1929
  // %%% We should make sure this is the right semantics before implementing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1930
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1931
  // %%% changed set_vm_result_2 to set_vm_result and get_vm_result_2 to get_vm_result. Is there a bug here?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1932
  __ set_vm_result(Oexception);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1933
  __ unlock_if_synchronized_method(vtos, /* throw_monitor_exception */ false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1934
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1935
  __ notify_method_exit(false, vtos, InterpreterMacroAssembler::SkipNotifyJVMTI);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1936
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1937
  __ get_vm_result(Oexception);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1938
  __ verify_oop(Oexception);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1939
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1940
    const int return_reg_adjustment = frame::pc_return_offset;
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  1941
  Address issuing_pc_addr(I7, return_reg_adjustment);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1942
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1943
  // We are done with this activation frame; find out where to go next.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1944
  // The continuation point will be an exception handler, which expects
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1945
  // the following registers set up:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1946
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1947
  // Oexception: exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1948
  // Oissuing_pc: the local call that threw exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1949
  // Other On: garbage
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1950
  // In/Ln:  the contents of the caller's register window
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1951
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1952
  // We do the required restore at the last possible moment, because we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1953
  // need to preserve some state across a runtime call.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1954
  // (Remember that the caller activation is unknown--it might not be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1955
  // interpreted, so things like Lscratch are useless in the caller.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1956
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1957
  // Although the Intel version uses call_C, we can use the more
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1958
  // compact call_VM.  (The only real difference on SPARC is a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1959
  // harmlessly ignored [re]set_last_Java_frame, compared with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1960
  // the Intel code which lacks this.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1961
  __ mov(Oexception,      Oexception ->after_save());  // get exception in I0 so it will be on O0 after restore
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1962
  __ add(issuing_pc_addr, Oissuing_pc->after_save());  // likewise set I1 to a value local to the caller
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1963
  __ super_call_VM_leaf(L7_thread_cache,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1964
                        CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address),
5046
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4429
diff changeset
  1965
                        G2_thread, Oissuing_pc->after_save());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1966
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1967
  // The caller's SP was adjusted upon method entry to accomodate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1968
  // the callee's non-argument locals. Undo that adjustment.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1969
  __ JMP(O0, 0);                         // return exception handler in caller
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1970
  __ delayed()->restore(I5_savedSP, G0, SP);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1971
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1972
  // (same old exception object is already in Oexception; see above)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1973
  // Note that an "issuing PC" is actually the next PC after the call
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1974
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1975
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1976
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1977
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1978
// JVMTI ForceEarlyReturn support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1979
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1980
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1981
address TemplateInterpreterGenerator::generate_earlyret_entry_for(TosState state) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1982
  address entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1983
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1984
  __ empty_expression_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1985
  __ load_earlyret_value(state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1986
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  1987
  __ ld_ptr(G2_thread, JavaThread::jvmti_thread_state_offset(), G3_scratch);
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  1988
  Address cond_addr(G3_scratch, JvmtiThreadState::earlyret_state_offset());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1989
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1990
  // Clear the earlyret state
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1991
  __ stw(G0 /* JvmtiThreadState::earlyret_inactive */, cond_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1992
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1993
  __ remove_activation(state,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1994
                       /* throw_monitor_exception */ false,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1995
                       /* install_monitor_exception */ false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1996
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1997
  // The caller's SP was adjusted upon method entry to accomodate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1998
  // the callee's non-argument locals. Undo that adjustment.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1999
  __ ret();                             // return to caller
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2000
  __ delayed()->restore(I5_savedSP, G0, SP);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2001
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2002
  return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2003
} // end of JVMTI ForceEarlyReturn support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2004
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2005
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2006
//------------------------------------------------------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2007
// Helper for vtos entry point generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2008
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2009
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
  2010
  assert(t->is_valid() && t->tos_in() == vtos, "illegal template");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2011
  Label L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2012
  aep = __ pc(); __ push_ptr(); __ ba(false, L); __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2013
  fep = __ pc(); __ push_f();   __ ba(false, L); __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2014
  dep = __ pc(); __ push_d();   __ ba(false, L); __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2015
  lep = __ pc(); __ push_l();   __ ba(false, L); __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2016
  iep = __ pc(); __ push_i();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2017
  bep = cep = sep = iep;                        // there aren't any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2018
  vep = __ pc(); __ bind(L);                    // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2019
  generate_and_dispatch(t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2020
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2021
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2022
// --------------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2023
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2024
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2025
InterpreterGenerator::InterpreterGenerator(StubQueue* code)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2026
 : TemplateInterpreterGenerator(code) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2027
   generate_all(); // down here so it can be "virtual"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2028
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2029
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2030
// --------------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2031
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2032
// Non-product code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2033
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2034
address TemplateInterpreterGenerator::generate_trace_code(TosState state) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2035
  address entry = __ pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2036
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2037
  __ push(state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2038
  __ mov(O7, Lscratch); // protect return address within interpreter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2039
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2040
  // Pass a 0 (not used in sparc) and the top of stack to the bytecode tracer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2041
  __ mov( Otos_l2, G3_scratch );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2042
  __ call_VM(noreg, CAST_FROM_FN_PTR(address, SharedRuntime::trace_bytecode), G0, Otos_l1, G3_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2043
  __ mov(Lscratch, O7); // restore return address
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2044
  __ pop(state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2045
  __ retl();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2046
  __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2047
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2048
  return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2049
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2050
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2051
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2052
// helpers for generate_and_dispatch
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2053
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2054
void TemplateInterpreterGenerator::count_bytecode() {
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  2055
  __ inc_counter(&BytecodeCounter::_counter_value, G3_scratch, G4_scratch);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2056
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2057
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2058
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2059
void TemplateInterpreterGenerator::histogram_bytecode(Template* t) {
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  2060
  __ inc_counter(&BytecodeHistogram::_counters[t->bytecode()], G3_scratch, G4_scratch);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2061
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2062
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2063
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2064
void TemplateInterpreterGenerator::histogram_bytecode_pair(Template* t) {
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  2065
  AddressLiteral index   (&BytecodePairHistogram::_index);
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  2066
  AddressLiteral counters((address) &BytecodePairHistogram::_counters);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2067
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2068
  // get index, shift out old bytecode, bring in new bytecode, and store it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2069
  // _index = (_index >> log2_number_of_codes) |
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2070
  //          (bytecode << log2_number_of_codes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2071
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  2072
  __ load_contents(index, G4_scratch);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2073
  __ srl( G4_scratch, BytecodePairHistogram::log2_number_of_codes, G4_scratch );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2074
  __ set( ((int)t->bytecode()) << BytecodePairHistogram::log2_number_of_codes,  G3_scratch );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2075
  __ or3( G3_scratch,  G4_scratch, G4_scratch );
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  2076
  __ store_contents(G4_scratch, index, G3_scratch);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2077
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2078
  // bump bucket contents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2079
  // _counters[_index] ++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2080
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  2081
  __ set(counters, G3_scratch);                       // loads into G3_scratch
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2082
  __ sll( G4_scratch, LogBytesPerWord, G4_scratch );  // Index is word address
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2083
  __ add (G3_scratch, G4_scratch, G3_scratch);        // Add in index
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2084
  __ ld (G3_scratch, 0, G4_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2085
  __ inc (G4_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2086
  __ st (G4_scratch, 0, G3_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2087
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2088
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2089
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2090
void TemplateInterpreterGenerator::trace_bytecode(Template* t) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2091
  // Call a little run-time stub to avoid blow-up for each bytecode.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2092
  // The run-time runtime saves the right registers, depending on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2093
  // the tosca in-state for the given template.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2094
  address entry = Interpreter::trace_code(t->tos_in());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2095
  guarantee(entry != NULL, "entry must have been generated");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2096
  __ call(entry, relocInfo::none);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2097
  __ delayed()->nop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2098
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2099
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2100
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2101
void TemplateInterpreterGenerator::stop_interpreter_at() {
2571
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  2102
  AddressLiteral counter(&BytecodeCounter::_counter_value);
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  2103
  __ load_contents(counter, G3_scratch);
d602ad6538bd 6822110: Add AddressLiteral class on SPARC
twisti
parents: 2534
diff changeset
  2104
  AddressLiteral stop_at(&StopInterpreterAt);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2105
  __ load_ptr_contents(stop_at, G4_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2106
  __ cmp(G3_scratch, G4_scratch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2107
  __ breakpoint_trap(Assembler::equal);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2108
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2109
#endif // not PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2110
#endif // !CC_INTERP