Tue, 10 Mar 2009 08:52:16 -0700
Merge
duke@435 | 1 | /* |
xdono@772 | 2 | * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. |
duke@435 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
duke@435 | 4 | * |
duke@435 | 5 | * This code is free software; you can redistribute it and/or modify it |
duke@435 | 6 | * under the terms of the GNU General Public License version 2 only, as |
duke@435 | 7 | * published by the Free Software Foundation. |
duke@435 | 8 | * |
duke@435 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
duke@435 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
duke@435 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
duke@435 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
duke@435 | 13 | * accompanied this code). |
duke@435 | 14 | * |
duke@435 | 15 | * You should have received a copy of the GNU General Public License version |
duke@435 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
duke@435 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
duke@435 | 18 | * |
duke@435 | 19 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
duke@435 | 20 | * CA 95054 USA or visit www.sun.com if you need additional information or |
duke@435 | 21 | * have any questions. |
duke@435 | 22 | * |
duke@435 | 23 | */ |
duke@435 | 24 | |
duke@435 | 25 | #include "incls/_precompiled.incl" |
duke@435 | 26 | #include "incls/_interpreter_x86_32.cpp.incl" |
duke@435 | 27 | |
duke@435 | 28 | #define __ _masm-> |
duke@435 | 29 | |
duke@435 | 30 | // Initialize the sentinel used to distinguish an interpreter return address. |
duke@435 | 31 | const int Interpreter::return_sentinel = 0xfeedbeed; |
duke@435 | 32 | |
duke@435 | 33 | //------------------------------------------------------------------------------------------------------------------------ |
duke@435 | 34 | |
duke@435 | 35 | address AbstractInterpreterGenerator::generate_slow_signature_handler() { |
duke@435 | 36 | address entry = __ pc(); |
duke@435 | 37 | // rbx,: method |
duke@435 | 38 | // rcx: temporary |
duke@435 | 39 | // rdi: pointer to locals |
duke@435 | 40 | // rsp: end of copied parameters area |
never@739 | 41 | __ mov(rcx, rsp); |
duke@435 | 42 | __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::slow_signature_handler), rbx, rdi, rcx); |
duke@435 | 43 | __ ret(0); |
duke@435 | 44 | return entry; |
duke@435 | 45 | } |
duke@435 | 46 | |
duke@435 | 47 | |
duke@435 | 48 | // |
duke@435 | 49 | // Various method entries (that c++ and asm interpreter agree upon) |
duke@435 | 50 | //------------------------------------------------------------------------------------------------------------------------ |
duke@435 | 51 | // |
duke@435 | 52 | // |
duke@435 | 53 | |
duke@435 | 54 | // Empty method, generate a very fast return. |
duke@435 | 55 | |
duke@435 | 56 | address InterpreterGenerator::generate_empty_entry(void) { |
duke@435 | 57 | |
duke@435 | 58 | // rbx,: methodOop |
duke@435 | 59 | // rcx: receiver (unused) |
duke@435 | 60 | // rsi: previous interpreter state (C++ interpreter) must preserve |
duke@435 | 61 | // rsi: sender sp must set sp to this value on return |
duke@435 | 62 | |
duke@435 | 63 | if (!UseFastEmptyMethods) return NULL; |
duke@435 | 64 | |
duke@435 | 65 | address entry_point = __ pc(); |
duke@435 | 66 | |
duke@435 | 67 | // If we need a safepoint check, generate full interpreter entry. |
duke@435 | 68 | Label slow_path; |
duke@435 | 69 | ExternalAddress state(SafepointSynchronize::address_of_state()); |
duke@435 | 70 | __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()), |
duke@435 | 71 | SafepointSynchronize::_not_synchronized); |
duke@435 | 72 | __ jcc(Assembler::notEqual, slow_path); |
duke@435 | 73 | |
duke@435 | 74 | // do nothing for empty methods (do not even increment invocation counter) |
duke@435 | 75 | // Code: _return |
duke@435 | 76 | // _return |
duke@435 | 77 | // return w/o popping parameters |
never@739 | 78 | __ pop(rax); |
never@739 | 79 | __ mov(rsp, rsi); |
duke@435 | 80 | __ jmp(rax); |
duke@435 | 81 | |
duke@435 | 82 | __ bind(slow_path); |
duke@435 | 83 | (void) generate_normal_entry(false); |
duke@435 | 84 | return entry_point; |
duke@435 | 85 | } |
duke@435 | 86 | |
duke@435 | 87 | address InterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) { |
duke@435 | 88 | |
duke@435 | 89 | // rbx,: methodOop |
duke@435 | 90 | // rcx: scratrch |
duke@435 | 91 | // rsi: sender sp |
duke@435 | 92 | |
duke@435 | 93 | if (!InlineIntrinsics) return NULL; // Generate a vanilla entry |
duke@435 | 94 | |
duke@435 | 95 | address entry_point = __ pc(); |
duke@435 | 96 | |
duke@435 | 97 | // These don't need a safepoint check because they aren't virtually |
duke@435 | 98 | // callable. We won't enter these intrinsics from compiled code. |
duke@435 | 99 | // If in the future we added an intrinsic which was virtually callable |
duke@435 | 100 | // we'd have to worry about how to safepoint so that this code is used. |
duke@435 | 101 | |
duke@435 | 102 | // mathematical functions inlined by compiler |
duke@435 | 103 | // (interpreter must provide identical implementation |
duke@435 | 104 | // in order to avoid monotonicity bugs when switching |
duke@435 | 105 | // from interpreter to compiler in the middle of some |
duke@435 | 106 | // computation) |
duke@435 | 107 | // |
duke@435 | 108 | // stack: [ ret adr ] <-- rsp |
duke@435 | 109 | // [ lo(arg) ] |
duke@435 | 110 | // [ hi(arg) ] |
duke@435 | 111 | // |
duke@435 | 112 | |
duke@435 | 113 | // Note: For JDK 1.2 StrictMath doesn't exist and Math.sin/cos/sqrt are |
duke@435 | 114 | // native methods. Interpreter::method_kind(...) does a check for |
duke@435 | 115 | // native methods first before checking for intrinsic methods and |
duke@435 | 116 | // thus will never select this entry point. Make sure it is not |
duke@435 | 117 | // called accidentally since the SharedRuntime entry points will |
duke@435 | 118 | // not work for JDK 1.2. |
duke@435 | 119 | // |
duke@435 | 120 | // We no longer need to check for JDK 1.2 since it's EOL'ed. |
duke@435 | 121 | // The following check existed in pre 1.6 implementation, |
duke@435 | 122 | // if (Universe::is_jdk12x_version()) { |
duke@435 | 123 | // __ should_not_reach_here(); |
duke@435 | 124 | // } |
duke@435 | 125 | // Universe::is_jdk12x_version() always returns false since |
duke@435 | 126 | // the JDK version is not yet determined when this method is called. |
duke@435 | 127 | // This method is called during interpreter_init() whereas |
duke@435 | 128 | // JDK version is only determined when universe2_init() is called. |
duke@435 | 129 | |
duke@435 | 130 | // Note: For JDK 1.3 StrictMath exists and Math.sin/cos/sqrt are |
duke@435 | 131 | // java methods. Interpreter::method_kind(...) will select |
duke@435 | 132 | // this entry point for the corresponding methods in JDK 1.3. |
duke@435 | 133 | // get argument |
duke@435 | 134 | if (TaggedStackInterpreter) { |
duke@435 | 135 | __ pushl(Address(rsp, 3*wordSize)); // push hi (and note rsp -= wordSize) |
duke@435 | 136 | __ pushl(Address(rsp, 2*wordSize)); // push lo |
duke@435 | 137 | __ fld_d(Address(rsp, 0)); // get double in ST0 |
never@739 | 138 | __ addptr(rsp, 2*wordSize); |
duke@435 | 139 | } else { |
duke@435 | 140 | __ fld_d(Address(rsp, 1*wordSize)); |
duke@435 | 141 | } |
duke@435 | 142 | switch (kind) { |
duke@435 | 143 | case Interpreter::java_lang_math_sin : |
duke@435 | 144 | __ trigfunc('s'); |
duke@435 | 145 | break; |
duke@435 | 146 | case Interpreter::java_lang_math_cos : |
duke@435 | 147 | __ trigfunc('c'); |
duke@435 | 148 | break; |
duke@435 | 149 | case Interpreter::java_lang_math_tan : |
duke@435 | 150 | __ trigfunc('t'); |
duke@435 | 151 | break; |
duke@435 | 152 | case Interpreter::java_lang_math_sqrt: |
duke@435 | 153 | __ fsqrt(); |
duke@435 | 154 | break; |
duke@435 | 155 | case Interpreter::java_lang_math_abs: |
duke@435 | 156 | __ fabs(); |
duke@435 | 157 | break; |
duke@435 | 158 | case Interpreter::java_lang_math_log: |
duke@435 | 159 | __ flog(); |
duke@435 | 160 | // Store to stack to convert 80bit precision back to 64bits |
duke@435 | 161 | __ push_fTOS(); |
duke@435 | 162 | __ pop_fTOS(); |
duke@435 | 163 | break; |
duke@435 | 164 | case Interpreter::java_lang_math_log10: |
duke@435 | 165 | __ flog10(); |
duke@435 | 166 | // Store to stack to convert 80bit precision back to 64bits |
duke@435 | 167 | __ push_fTOS(); |
duke@435 | 168 | __ pop_fTOS(); |
duke@435 | 169 | break; |
duke@435 | 170 | default : |
duke@435 | 171 | ShouldNotReachHere(); |
duke@435 | 172 | } |
duke@435 | 173 | |
duke@435 | 174 | // return double result in xmm0 for interpreter and compilers. |
duke@435 | 175 | if (UseSSE >= 2) { |
never@739 | 176 | __ subptr(rsp, 2*wordSize); |
duke@435 | 177 | __ fstp_d(Address(rsp, 0)); |
duke@435 | 178 | __ movdbl(xmm0, Address(rsp, 0)); |
never@739 | 179 | __ addptr(rsp, 2*wordSize); |
duke@435 | 180 | } |
duke@435 | 181 | |
duke@435 | 182 | // done, result in FPU ST(0) or XMM0 |
never@739 | 183 | __ pop(rdi); // get return address |
never@739 | 184 | __ mov(rsp, rsi); // set sp to sender sp |
duke@435 | 185 | __ jmp(rdi); |
duke@435 | 186 | |
duke@435 | 187 | return entry_point; |
duke@435 | 188 | } |
duke@435 | 189 | |
duke@435 | 190 | |
duke@435 | 191 | // Abstract method entry |
duke@435 | 192 | // Attempt to execute abstract method. Throw exception |
duke@435 | 193 | address InterpreterGenerator::generate_abstract_entry(void) { |
duke@435 | 194 | |
duke@435 | 195 | // rbx,: methodOop |
duke@435 | 196 | // rcx: receiver (unused) |
duke@435 | 197 | // rsi: previous interpreter state (C++ interpreter) must preserve |
duke@435 | 198 | |
duke@435 | 199 | // rsi: sender SP |
duke@435 | 200 | |
duke@435 | 201 | address entry_point = __ pc(); |
duke@435 | 202 | |
duke@435 | 203 | // abstract method entry |
duke@435 | 204 | // remove return address. Not really needed, since exception handling throws away expression stack |
never@739 | 205 | __ pop(rbx); |
duke@435 | 206 | |
duke@435 | 207 | // adjust stack to what a normal return would do |
never@739 | 208 | __ mov(rsp, rsi); |
duke@435 | 209 | // throw exception |
duke@435 | 210 | __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodError)); |
duke@435 | 211 | // the call_VM checks for exception, so we should never return here. |
duke@435 | 212 | __ should_not_reach_here(); |
duke@435 | 213 | |
duke@435 | 214 | return entry_point; |
duke@435 | 215 | } |
duke@435 | 216 | |
duke@435 | 217 | // This method tells the deoptimizer how big an interpreted frame must be: |
duke@435 | 218 | int AbstractInterpreter::size_activation(methodOop method, |
duke@435 | 219 | int tempcount, |
duke@435 | 220 | int popframe_extra_args, |
duke@435 | 221 | int moncount, |
duke@435 | 222 | int callee_param_count, |
duke@435 | 223 | int callee_locals, |
duke@435 | 224 | bool is_top_frame) { |
duke@435 | 225 | return layout_activation(method, |
duke@435 | 226 | tempcount, |
duke@435 | 227 | popframe_extra_args, |
duke@435 | 228 | moncount, |
duke@435 | 229 | callee_param_count, |
duke@435 | 230 | callee_locals, |
duke@435 | 231 | (frame*) NULL, |
duke@435 | 232 | (frame*) NULL, |
duke@435 | 233 | is_top_frame); |
duke@435 | 234 | } |
duke@435 | 235 | |
duke@435 | 236 | void Deoptimization::unwind_callee_save_values(frame* f, vframeArray* vframe_array) { |
duke@435 | 237 | |
duke@435 | 238 | // This code is sort of the equivalent of C2IAdapter::setup_stack_frame back in |
duke@435 | 239 | // the days we had adapter frames. When we deoptimize a situation where a |
duke@435 | 240 | // compiled caller calls a compiled caller will have registers it expects |
duke@435 | 241 | // to survive the call to the callee. If we deoptimize the callee the only |
duke@435 | 242 | // way we can restore these registers is to have the oldest interpreter |
duke@435 | 243 | // frame that we create restore these values. That is what this routine |
duke@435 | 244 | // will accomplish. |
duke@435 | 245 | |
duke@435 | 246 | // At the moment we have modified c2 to not have any callee save registers |
duke@435 | 247 | // so this problem does not exist and this routine is just a place holder. |
duke@435 | 248 | |
duke@435 | 249 | assert(f->is_interpreted_frame(), "must be interpreted"); |
duke@435 | 250 | } |