2204N/A * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 0N/A * published by the Free Software Foundation. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1472N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 0N/A// Generation of Interpreter 0N/A// The InterpreterGenerator generates the interpreter into Interpreter::_code. 0N/A//---------------------------------------------------------------------------------------------------- 0N/A // We are in the jni transition frame. Save the last_java_frame corresponding to the 0N/A // outer interpreter frame 0N/A // make sure the interpreter frame we've pushed has a valid return pc 0N/A // load the register arguments (the C code packed them as varargs) 0N/A// LP64 passes floating point arguments in F1, F3, F5, etc. instead of 0N/A// Doubles are passed in D0, D2, D4 0N/A// We store the signature of the first 16 arguments in the first argument 0N/A// slot because it will be overwritten prior to calling the native 0N/A// function, with the pointer to the JNIEnv. 0N/A// If LP64 there can be up to 16 floating point arguments in registers 0N/A// or 6 integer registers. 0N/A // We are in the jni transition frame. Save the last_java_frame corresponding to the 0N/A // outer interpreter frame 0N/A // make sure the interpreter frame we've pushed has a valid return pc 0N/A // load the register arguments (the C code packed them as varargs) 0N/A // There are only 6 integer register arguments! 0N/A // Optimization, see if there are any more args and get out prior to checking 0N/A // all 16 float registers. My guess is that this is rare. 0N/A // If is_register is false, then we are done the first six integer args. 0N/A // Generate code to initiate compilation on the counter overflow. 0N/A // InterpreterRuntime::frequency_counter_overflow takes two arguments, 0N/A // the first indicates if the counter overflow occurs at a backwards branch (NULL bcp) 0N/A // and the second is only used when the first is true. We pass zero for both. 0N/A // The call returns the address of the verified entry point for the method or NULL 0N/A // if the compilation did not complete (either went background or bailed out). 0N/A // returns verified_entry_point or NULL 0N/A // we ignore it in any case 0N/A// Various method entries 0N/A// Abstract method entry 0N/A// Attempt to execute abstract method. Throw exception 0N/A // abstract method entry 0N/A // the call_VM checks for exception, so we should never return here. 0N/A//---------------------------------------------------------------------------------------------------- 0N/A// Entry points & stack frame layout 0N/A// Here we generate the various kind of entries into the interpreter. 0N/A// The two main entry type are generic bytecode methods and native call method. 0N/A// These both come in synchronized and non-synchronized versions but the 0N/A// frame layout they create is very similar. The other method entry 0N/A// types are really just special purpose entries that are really entry 0N/A// and interpretation all in one. These are for trivial methods like 0N/A// accessor, empty, or special math methods. 0N/A// When control flow reaches any of the entry types for the interpreter 0N/A// the following holds -> 0N/A// C2 Calling Conventions: 0N/A// The entry code below assumes that the following registers are set 0N/A// G5_method: holds the methodOop of the method to call 0N/A// Lesp: points to the TOS of the callers expression stack 0N/A// after having pushed all the parameters 0N/A// The entry code does the following to setup an interpreter frame 0N/A// pop parameters from the callers stack by adjusting Lesp 0N/A// compute X = (max_locals - num_parameters) 0N/A// bump SP up by X to accomadate the extra locals 0N/A// compute X = max_expression_stack 0N/A// + 16 words of register save area 0N/A// save frame doing a save sp, -X, sp growing towards lower addresses 0N/A// set Lbcp, Lmethod, LcpoolCache 0N/A// set Lmonitors to FP - rounded_vm_local_words 0N/A// set Lesp to Lmonitors - 4 0N/A// The frame has now been setup to do the rest of the entry code 0N/A// Try this optimization: Most method entries could live in a 0N/A// "one size fits all" stack frame without all the dynamic size 0N/A// calculations. It might be profitable to do all this calculation 0N/A// statically and approximately for "small enough" methods. 0N/A//----------------------------------------------------------------------------------------------- 0N/A// C1 Calling conventions 0N/A// Upon method entry, the following registers are setup: 0N/A// g2 G2_thread: current thread 0N/A// g5 G5_method: method to activate 0N/A// g4 Gargs : pointer to last argument 0N/A// +---------------+ <--- sp 0N/A// +---------------+ <--- sp + 0x40 0N/A// : extra 7 slots : note: these slots are not really needed for the interpreter (fix later) 0N/A// +---------------+ <--- sp + 0x5c 0N/A// +---------------+ <--- Gargs 0N/A// AFTER FRAME HAS BEEN SETUP for method interpretation the stack looks like: 0N/A// +---------------+ <--- sp 0N/A// +---------------+ <--- sp + 0x40 0N/A// : extra 7 slots : note: these slots are not really needed for the interpreter (fix later) 0N/A// +---------------+ <--- sp + 0x5c 0N/A// +---------------+ <--- Lmonitors (fp - 0x18) 0N/A// +---------------+ <--- fp 0N/A// +---------------+ <--- fp + 0x40 0N/A// : extra 7 slots : note: these slots are not really needed for the interpreter (fix later) 0N/A// +---------------+ <--- fp + 0x5c 0N/A// +---------------+ <--- Gargs 0N/A // determine code generation flags 1174N/A // No special entry points that preclude compilation 0N/A // This code is sort of the equivalent of C2IAdapter::setup_stack_frame back in 0N/A // the days we had adapter frames. When we deoptimize a situation where a 0N/A // compiled caller calls a compiled caller will have registers it expects 0N/A // to survive the call to the callee. If we deoptimize the callee the only 0N/A // way we can restore these registers is to have the oldest interpreter 0N/A // frame that we create restore these values. That is what this routine 0N/A // At the moment we have modified c2 to not have any callee save registers 0N/A // so this problem does not exist and this routine is just a place holder. 0N/A//----------------------------------------------------------------------------------------------------