Mon, 11 Oct 2010 04:18:58 -0700
6829194: JSR 292 needs to support compressed oops
Reviewed-by: kvn, jrose
duke@435 | 1 | /* |
trims@1907 | 2 | * Copyright (c) 1997, 2010, Oracle and/or its affiliates. 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 | * |
trims@1907 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
trims@1907 | 20 | * or visit www.oracle.com if you need additional information or have any |
trims@1907 | 21 | * questions. |
duke@435 | 22 | * |
duke@435 | 23 | */ |
duke@435 | 24 | |
duke@435 | 25 | #include "incls/_precompiled.incl" |
duke@435 | 26 | #include "incls/_interpreter_sparc.cpp.incl" |
duke@435 | 27 | |
duke@435 | 28 | |
duke@435 | 29 | |
duke@435 | 30 | // Generation of Interpreter |
duke@435 | 31 | // |
duke@435 | 32 | // The InterpreterGenerator generates the interpreter into Interpreter::_code. |
duke@435 | 33 | |
duke@435 | 34 | |
duke@435 | 35 | #define __ _masm-> |
duke@435 | 36 | |
duke@435 | 37 | |
duke@435 | 38 | //---------------------------------------------------------------------------------------------------- |
duke@435 | 39 | |
duke@435 | 40 | |
duke@435 | 41 | |
duke@435 | 42 | |
duke@435 | 43 | int AbstractInterpreter::BasicType_as_index(BasicType type) { |
duke@435 | 44 | int i = 0; |
duke@435 | 45 | switch (type) { |
duke@435 | 46 | case T_BOOLEAN: i = 0; break; |
duke@435 | 47 | case T_CHAR : i = 1; break; |
duke@435 | 48 | case T_BYTE : i = 2; break; |
duke@435 | 49 | case T_SHORT : i = 3; break; |
duke@435 | 50 | case T_INT : i = 4; break; |
duke@435 | 51 | case T_LONG : i = 5; break; |
duke@435 | 52 | case T_VOID : i = 6; break; |
duke@435 | 53 | case T_FLOAT : i = 7; break; |
duke@435 | 54 | case T_DOUBLE : i = 8; break; |
duke@435 | 55 | case T_OBJECT : i = 9; break; |
duke@435 | 56 | case T_ARRAY : i = 9; break; |
duke@435 | 57 | default : ShouldNotReachHere(); |
duke@435 | 58 | } |
duke@435 | 59 | assert(0 <= i && i < AbstractInterpreter::number_of_result_handlers, "index out of bounds"); |
duke@435 | 60 | return i; |
duke@435 | 61 | } |
duke@435 | 62 | |
duke@435 | 63 | |
duke@435 | 64 | #ifndef _LP64 |
duke@435 | 65 | address AbstractInterpreterGenerator::generate_slow_signature_handler() { |
duke@435 | 66 | address entry = __ pc(); |
duke@435 | 67 | Argument argv(0, true); |
duke@435 | 68 | |
duke@435 | 69 | // We are in the jni transition frame. Save the last_java_frame corresponding to the |
duke@435 | 70 | // outer interpreter frame |
duke@435 | 71 | // |
duke@435 | 72 | __ set_last_Java_frame(FP, noreg); |
duke@435 | 73 | // make sure the interpreter frame we've pushed has a valid return pc |
duke@435 | 74 | __ mov(O7, I7); |
duke@435 | 75 | __ mov(Lmethod, G3_scratch); |
duke@435 | 76 | __ mov(Llocals, G4_scratch); |
duke@435 | 77 | __ save_frame(0); |
duke@435 | 78 | __ mov(G2_thread, L7_thread_cache); |
duke@435 | 79 | __ add(argv.address_in_frame(), O3); |
duke@435 | 80 | __ mov(G2_thread, O0); |
duke@435 | 81 | __ mov(G3_scratch, O1); |
duke@435 | 82 | __ call(CAST_FROM_FN_PTR(address, InterpreterRuntime::slow_signature_handler), relocInfo::runtime_call_type); |
duke@435 | 83 | __ delayed()->mov(G4_scratch, O2); |
duke@435 | 84 | __ mov(L7_thread_cache, G2_thread); |
duke@435 | 85 | __ reset_last_Java_frame(); |
duke@435 | 86 | |
duke@435 | 87 | // load the register arguments (the C code packed them as varargs) |
duke@435 | 88 | for (Argument ldarg = argv.successor(); ldarg.is_register(); ldarg = ldarg.successor()) { |
duke@435 | 89 | __ ld_ptr(ldarg.address_in_frame(), ldarg.as_register()); |
duke@435 | 90 | } |
duke@435 | 91 | __ ret(); |
duke@435 | 92 | __ delayed()-> |
duke@435 | 93 | restore(O0, 0, Lscratch); // caller's Lscratch gets the result handler |
duke@435 | 94 | return entry; |
duke@435 | 95 | } |
duke@435 | 96 | |
duke@435 | 97 | |
duke@435 | 98 | #else |
duke@435 | 99 | // LP64 passes floating point arguments in F1, F3, F5, etc. instead of |
duke@435 | 100 | // O0, O1, O2 etc.. |
duke@435 | 101 | // Doubles are passed in D0, D2, D4 |
duke@435 | 102 | // We store the signature of the first 16 arguments in the first argument |
duke@435 | 103 | // slot because it will be overwritten prior to calling the native |
duke@435 | 104 | // function, with the pointer to the JNIEnv. |
duke@435 | 105 | // If LP64 there can be up to 16 floating point arguments in registers |
duke@435 | 106 | // or 6 integer registers. |
duke@435 | 107 | address AbstractInterpreterGenerator::generate_slow_signature_handler() { |
duke@435 | 108 | |
duke@435 | 109 | enum { |
duke@435 | 110 | non_float = 0, |
duke@435 | 111 | float_sig = 1, |
duke@435 | 112 | double_sig = 2, |
duke@435 | 113 | sig_mask = 3 |
duke@435 | 114 | }; |
duke@435 | 115 | |
duke@435 | 116 | address entry = __ pc(); |
duke@435 | 117 | Argument argv(0, true); |
duke@435 | 118 | |
duke@435 | 119 | // We are in the jni transition frame. Save the last_java_frame corresponding to the |
duke@435 | 120 | // outer interpreter frame |
duke@435 | 121 | // |
duke@435 | 122 | __ set_last_Java_frame(FP, noreg); |
duke@435 | 123 | // make sure the interpreter frame we've pushed has a valid return pc |
duke@435 | 124 | __ mov(O7, I7); |
duke@435 | 125 | __ mov(Lmethod, G3_scratch); |
duke@435 | 126 | __ mov(Llocals, G4_scratch); |
duke@435 | 127 | __ save_frame(0); |
duke@435 | 128 | __ mov(G2_thread, L7_thread_cache); |
duke@435 | 129 | __ add(argv.address_in_frame(), O3); |
duke@435 | 130 | __ mov(G2_thread, O0); |
duke@435 | 131 | __ mov(G3_scratch, O1); |
duke@435 | 132 | __ call(CAST_FROM_FN_PTR(address, InterpreterRuntime::slow_signature_handler), relocInfo::runtime_call_type); |
duke@435 | 133 | __ delayed()->mov(G4_scratch, O2); |
duke@435 | 134 | __ mov(L7_thread_cache, G2_thread); |
duke@435 | 135 | __ reset_last_Java_frame(); |
duke@435 | 136 | |
duke@435 | 137 | |
duke@435 | 138 | // load the register arguments (the C code packed them as varargs) |
duke@435 | 139 | Address Sig = argv.address_in_frame(); // Argument 0 holds the signature |
duke@435 | 140 | __ ld_ptr( Sig, G3_scratch ); // Get register argument signature word into G3_scratch |
duke@435 | 141 | __ mov( G3_scratch, G4_scratch); |
duke@435 | 142 | __ srl( G4_scratch, 2, G4_scratch); // Skip Arg 0 |
duke@435 | 143 | Label done; |
duke@435 | 144 | for (Argument ldarg = argv.successor(); ldarg.is_float_register(); ldarg = ldarg.successor()) { |
duke@435 | 145 | Label NonFloatArg; |
duke@435 | 146 | Label LoadFloatArg; |
duke@435 | 147 | Label LoadDoubleArg; |
duke@435 | 148 | Label NextArg; |
duke@435 | 149 | Address a = ldarg.address_in_frame(); |
duke@435 | 150 | __ andcc(G4_scratch, sig_mask, G3_scratch); |
duke@435 | 151 | __ br(Assembler::zero, false, Assembler::pt, NonFloatArg); |
duke@435 | 152 | __ delayed()->nop(); |
duke@435 | 153 | |
duke@435 | 154 | __ cmp(G3_scratch, float_sig ); |
duke@435 | 155 | __ br(Assembler::equal, false, Assembler::pt, LoadFloatArg); |
duke@435 | 156 | __ delayed()->nop(); |
duke@435 | 157 | |
duke@435 | 158 | __ cmp(G3_scratch, double_sig ); |
duke@435 | 159 | __ br(Assembler::equal, false, Assembler::pt, LoadDoubleArg); |
duke@435 | 160 | __ delayed()->nop(); |
duke@435 | 161 | |
duke@435 | 162 | __ bind(NonFloatArg); |
duke@435 | 163 | // There are only 6 integer register arguments! |
duke@435 | 164 | if ( ldarg.is_register() ) |
duke@435 | 165 | __ ld_ptr(ldarg.address_in_frame(), ldarg.as_register()); |
duke@435 | 166 | else { |
duke@435 | 167 | // Optimization, see if there are any more args and get out prior to checking |
duke@435 | 168 | // all 16 float registers. My guess is that this is rare. |
duke@435 | 169 | // If is_register is false, then we are done the first six integer args. |
duke@435 | 170 | __ tst(G4_scratch); |
duke@435 | 171 | __ brx(Assembler::zero, false, Assembler::pt, done); |
duke@435 | 172 | __ delayed()->nop(); |
duke@435 | 173 | |
duke@435 | 174 | } |
duke@435 | 175 | __ ba(false, NextArg); |
duke@435 | 176 | __ delayed()->srl( G4_scratch, 2, G4_scratch ); |
duke@435 | 177 | |
duke@435 | 178 | __ bind(LoadFloatArg); |
duke@435 | 179 | __ ldf( FloatRegisterImpl::S, a, ldarg.as_float_register(), 4); |
duke@435 | 180 | __ ba(false, NextArg); |
duke@435 | 181 | __ delayed()->srl( G4_scratch, 2, G4_scratch ); |
duke@435 | 182 | |
duke@435 | 183 | __ bind(LoadDoubleArg); |
duke@435 | 184 | __ ldf( FloatRegisterImpl::D, a, ldarg.as_double_register() ); |
duke@435 | 185 | __ ba(false, NextArg); |
duke@435 | 186 | __ delayed()->srl( G4_scratch, 2, G4_scratch ); |
duke@435 | 187 | |
duke@435 | 188 | __ bind(NextArg); |
duke@435 | 189 | |
duke@435 | 190 | } |
duke@435 | 191 | |
duke@435 | 192 | __ bind(done); |
duke@435 | 193 | __ ret(); |
duke@435 | 194 | __ delayed()-> |
duke@435 | 195 | restore(O0, 0, Lscratch); // caller's Lscratch gets the result handler |
duke@435 | 196 | return entry; |
duke@435 | 197 | } |
duke@435 | 198 | #endif |
duke@435 | 199 | |
duke@435 | 200 | void InterpreterGenerator::generate_counter_overflow(Label& Lcontinue) { |
duke@435 | 201 | |
duke@435 | 202 | // Generate code to initiate compilation on the counter overflow. |
duke@435 | 203 | |
duke@435 | 204 | // InterpreterRuntime::frequency_counter_overflow takes two arguments, |
duke@435 | 205 | // the first indicates if the counter overflow occurs at a backwards branch (NULL bcp) |
duke@435 | 206 | // and the second is only used when the first is true. We pass zero for both. |
duke@435 | 207 | // The call returns the address of the verified entry point for the method or NULL |
duke@435 | 208 | // if the compilation did not complete (either went background or bailed out). |
duke@435 | 209 | __ set((int)false, O2); |
duke@435 | 210 | __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), O2, O2, true); |
duke@435 | 211 | // returns verified_entry_point or NULL |
duke@435 | 212 | // we ignore it in any case |
duke@435 | 213 | __ ba(false, Lcontinue); |
duke@435 | 214 | __ delayed()->nop(); |
duke@435 | 215 | |
duke@435 | 216 | } |
duke@435 | 217 | |
duke@435 | 218 | |
duke@435 | 219 | // End of helpers |
duke@435 | 220 | |
duke@435 | 221 | // Various method entries |
duke@435 | 222 | |
duke@435 | 223 | // Abstract method entry |
duke@435 | 224 | // Attempt to execute abstract method. Throw exception |
duke@435 | 225 | // |
duke@435 | 226 | address InterpreterGenerator::generate_abstract_entry(void) { |
duke@435 | 227 | address entry = __ pc(); |
duke@435 | 228 | // abstract method entry |
duke@435 | 229 | // throw exception |
duke@435 | 230 | __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodError)); |
duke@435 | 231 | // the call_VM checks for exception, so we should never return here. |
duke@435 | 232 | __ should_not_reach_here(); |
duke@435 | 233 | return entry; |
duke@435 | 234 | |
duke@435 | 235 | } |
duke@435 | 236 | |
duke@435 | 237 | |
jrose@1145 | 238 | // Method handle invoker |
jrose@1145 | 239 | // Dispatch a method of the form java.dyn.MethodHandles::invoke(...) |
jrose@1145 | 240 | address InterpreterGenerator::generate_method_handle_entry(void) { |
jrose@1145 | 241 | if (!EnableMethodHandles) { |
jrose@1145 | 242 | return generate_abstract_entry(); |
jrose@1145 | 243 | } |
twisti@1858 | 244 | |
twisti@1858 | 245 | return MethodHandles::generate_method_handle_interpreter_entry(_masm); |
jrose@1145 | 246 | } |
jrose@1145 | 247 | |
jrose@1145 | 248 | |
duke@435 | 249 | //---------------------------------------------------------------------------------------------------- |
duke@435 | 250 | // Entry points & stack frame layout |
duke@435 | 251 | // |
duke@435 | 252 | // Here we generate the various kind of entries into the interpreter. |
duke@435 | 253 | // The two main entry type are generic bytecode methods and native call method. |
duke@435 | 254 | // These both come in synchronized and non-synchronized versions but the |
duke@435 | 255 | // frame layout they create is very similar. The other method entry |
duke@435 | 256 | // types are really just special purpose entries that are really entry |
duke@435 | 257 | // and interpretation all in one. These are for trivial methods like |
duke@435 | 258 | // accessor, empty, or special math methods. |
duke@435 | 259 | // |
duke@435 | 260 | // When control flow reaches any of the entry types for the interpreter |
duke@435 | 261 | // the following holds -> |
duke@435 | 262 | // |
duke@435 | 263 | // C2 Calling Conventions: |
duke@435 | 264 | // |
duke@435 | 265 | // The entry code below assumes that the following registers are set |
duke@435 | 266 | // when coming in: |
duke@435 | 267 | // G5_method: holds the methodOop of the method to call |
duke@435 | 268 | // Lesp: points to the TOS of the callers expression stack |
duke@435 | 269 | // after having pushed all the parameters |
duke@435 | 270 | // |
duke@435 | 271 | // The entry code does the following to setup an interpreter frame |
duke@435 | 272 | // pop parameters from the callers stack by adjusting Lesp |
duke@435 | 273 | // set O0 to Lesp |
duke@435 | 274 | // compute X = (max_locals - num_parameters) |
duke@435 | 275 | // bump SP up by X to accomadate the extra locals |
duke@435 | 276 | // compute X = max_expression_stack |
duke@435 | 277 | // + vm_local_words |
duke@435 | 278 | // + 16 words of register save area |
duke@435 | 279 | // save frame doing a save sp, -X, sp growing towards lower addresses |
duke@435 | 280 | // set Lbcp, Lmethod, LcpoolCache |
duke@435 | 281 | // set Llocals to i0 |
duke@435 | 282 | // set Lmonitors to FP - rounded_vm_local_words |
duke@435 | 283 | // set Lesp to Lmonitors - 4 |
duke@435 | 284 | // |
duke@435 | 285 | // The frame has now been setup to do the rest of the entry code |
duke@435 | 286 | |
duke@435 | 287 | // Try this optimization: Most method entries could live in a |
duke@435 | 288 | // "one size fits all" stack frame without all the dynamic size |
duke@435 | 289 | // calculations. It might be profitable to do all this calculation |
duke@435 | 290 | // statically and approximately for "small enough" methods. |
duke@435 | 291 | |
duke@435 | 292 | //----------------------------------------------------------------------------------------------- |
duke@435 | 293 | |
duke@435 | 294 | // C1 Calling conventions |
duke@435 | 295 | // |
duke@435 | 296 | // Upon method entry, the following registers are setup: |
duke@435 | 297 | // |
duke@435 | 298 | // g2 G2_thread: current thread |
duke@435 | 299 | // g5 G5_method: method to activate |
duke@435 | 300 | // g4 Gargs : pointer to last argument |
duke@435 | 301 | // |
duke@435 | 302 | // |
duke@435 | 303 | // Stack: |
duke@435 | 304 | // |
duke@435 | 305 | // +---------------+ <--- sp |
duke@435 | 306 | // | | |
duke@435 | 307 | // : reg save area : |
duke@435 | 308 | // | | |
duke@435 | 309 | // +---------------+ <--- sp + 0x40 |
duke@435 | 310 | // | | |
duke@435 | 311 | // : extra 7 slots : note: these slots are not really needed for the interpreter (fix later) |
duke@435 | 312 | // | | |
duke@435 | 313 | // +---------------+ <--- sp + 0x5c |
duke@435 | 314 | // | | |
duke@435 | 315 | // : free : |
duke@435 | 316 | // | | |
duke@435 | 317 | // +---------------+ <--- Gargs |
duke@435 | 318 | // | | |
duke@435 | 319 | // : arguments : |
duke@435 | 320 | // | | |
duke@435 | 321 | // +---------------+ |
duke@435 | 322 | // | | |
duke@435 | 323 | // |
duke@435 | 324 | // |
duke@435 | 325 | // |
duke@435 | 326 | // AFTER FRAME HAS BEEN SETUP for method interpretation the stack looks like: |
duke@435 | 327 | // |
duke@435 | 328 | // +---------------+ <--- sp |
duke@435 | 329 | // | | |
duke@435 | 330 | // : reg save area : |
duke@435 | 331 | // | | |
duke@435 | 332 | // +---------------+ <--- sp + 0x40 |
duke@435 | 333 | // | | |
duke@435 | 334 | // : extra 7 slots : note: these slots are not really needed for the interpreter (fix later) |
duke@435 | 335 | // | | |
duke@435 | 336 | // +---------------+ <--- sp + 0x5c |
duke@435 | 337 | // | | |
duke@435 | 338 | // : : |
duke@435 | 339 | // | | <--- Lesp |
duke@435 | 340 | // +---------------+ <--- Lmonitors (fp - 0x18) |
duke@435 | 341 | // | VM locals | |
duke@435 | 342 | // +---------------+ <--- fp |
duke@435 | 343 | // | | |
duke@435 | 344 | // : reg save area : |
duke@435 | 345 | // | | |
duke@435 | 346 | // +---------------+ <--- fp + 0x40 |
duke@435 | 347 | // | | |
duke@435 | 348 | // : extra 7 slots : note: these slots are not really needed for the interpreter (fix later) |
duke@435 | 349 | // | | |
duke@435 | 350 | // +---------------+ <--- fp + 0x5c |
duke@435 | 351 | // | | |
duke@435 | 352 | // : free : |
duke@435 | 353 | // | | |
duke@435 | 354 | // +---------------+ |
duke@435 | 355 | // | | |
duke@435 | 356 | // : nonarg locals : |
duke@435 | 357 | // | | |
duke@435 | 358 | // +---------------+ |
duke@435 | 359 | // | | |
duke@435 | 360 | // : arguments : |
duke@435 | 361 | // | | <--- Llocals |
duke@435 | 362 | // +---------------+ <--- Gargs |
duke@435 | 363 | // | | |
duke@435 | 364 | |
duke@435 | 365 | address AbstractInterpreterGenerator::generate_method_entry(AbstractInterpreter::MethodKind kind) { |
duke@435 | 366 | // determine code generation flags |
duke@435 | 367 | bool synchronized = false; |
duke@435 | 368 | address entry_point = NULL; |
duke@435 | 369 | |
duke@435 | 370 | switch (kind) { |
duke@435 | 371 | case Interpreter::zerolocals : break; |
duke@435 | 372 | case Interpreter::zerolocals_synchronized: synchronized = true; break; |
duke@435 | 373 | case Interpreter::native : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(false); break; |
duke@435 | 374 | case Interpreter::native_synchronized : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(true); break; |
duke@435 | 375 | case Interpreter::empty : entry_point = ((InterpreterGenerator*)this)->generate_empty_entry(); break; |
duke@435 | 376 | case Interpreter::accessor : entry_point = ((InterpreterGenerator*)this)->generate_accessor_entry(); break; |
duke@435 | 377 | case Interpreter::abstract : entry_point = ((InterpreterGenerator*)this)->generate_abstract_entry(); break; |
jrose@1145 | 378 | case Interpreter::method_handle : entry_point = ((InterpreterGenerator*)this)->generate_method_handle_entry(); break; |
duke@435 | 379 | case Interpreter::java_lang_math_sin : break; |
duke@435 | 380 | case Interpreter::java_lang_math_cos : break; |
duke@435 | 381 | case Interpreter::java_lang_math_tan : break; |
duke@435 | 382 | case Interpreter::java_lang_math_sqrt : break; |
duke@435 | 383 | case Interpreter::java_lang_math_abs : break; |
duke@435 | 384 | case Interpreter::java_lang_math_log : break; |
duke@435 | 385 | case Interpreter::java_lang_math_log10 : break; |
duke@435 | 386 | default : ShouldNotReachHere(); break; |
duke@435 | 387 | } |
duke@435 | 388 | |
duke@435 | 389 | if (entry_point) return entry_point; |
duke@435 | 390 | |
duke@435 | 391 | return ((InterpreterGenerator*)this)->generate_normal_entry(synchronized); |
duke@435 | 392 | } |
duke@435 | 393 | |
duke@435 | 394 | |
never@1609 | 395 | bool AbstractInterpreter::can_be_compiled(methodHandle m) { |
never@1609 | 396 | // No special entry points that preclude compilation |
never@1609 | 397 | return true; |
never@1609 | 398 | } |
never@1609 | 399 | |
duke@435 | 400 | // This method tells the deoptimizer how big an interpreted frame must be: |
duke@435 | 401 | int AbstractInterpreter::size_activation(methodOop method, |
duke@435 | 402 | int tempcount, |
duke@435 | 403 | int popframe_extra_args, |
duke@435 | 404 | int moncount, |
duke@435 | 405 | int callee_param_count, |
duke@435 | 406 | int callee_locals, |
duke@435 | 407 | bool is_top_frame) { |
duke@435 | 408 | return layout_activation(method, |
duke@435 | 409 | tempcount, |
duke@435 | 410 | popframe_extra_args, |
duke@435 | 411 | moncount, |
duke@435 | 412 | callee_param_count, |
duke@435 | 413 | callee_locals, |
duke@435 | 414 | (frame*)NULL, |
duke@435 | 415 | (frame*)NULL, |
duke@435 | 416 | is_top_frame); |
duke@435 | 417 | } |
duke@435 | 418 | |
duke@435 | 419 | void Deoptimization::unwind_callee_save_values(frame* f, vframeArray* vframe_array) { |
duke@435 | 420 | |
duke@435 | 421 | // This code is sort of the equivalent of C2IAdapter::setup_stack_frame back in |
duke@435 | 422 | // the days we had adapter frames. When we deoptimize a situation where a |
duke@435 | 423 | // compiled caller calls a compiled caller will have registers it expects |
duke@435 | 424 | // to survive the call to the callee. If we deoptimize the callee the only |
duke@435 | 425 | // way we can restore these registers is to have the oldest interpreter |
duke@435 | 426 | // frame that we create restore these values. That is what this routine |
duke@435 | 427 | // will accomplish. |
duke@435 | 428 | |
duke@435 | 429 | // At the moment we have modified c2 to not have any callee save registers |
duke@435 | 430 | // so this problem does not exist and this routine is just a place holder. |
duke@435 | 431 | |
duke@435 | 432 | assert(f->is_interpreted_frame(), "must be interpreted"); |
duke@435 | 433 | } |
duke@435 | 434 | |
duke@435 | 435 | |
duke@435 | 436 | //---------------------------------------------------------------------------------------------------- |
duke@435 | 437 | // Exceptions |