< prev index next >

src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp

Print this page

        

*** 55,72 **** --- 55,285 ---- #ifdef BUILTIN_SIM #include "../../../../../../simulator/simulator.hpp" #endif + // Size of interpreter code. Increase if too small. Interpreter will + // fail with a guarantee ("not enough space for interpreter generation"); + // if too small. + // Run with +PrintInterpreter to get the VM to print out the size. + // Max size with JVMTI + int TemplateInterpreter::InterpreterCodeSize = 200 * 1024; + #define __ _masm-> //----------------------------------------------------------------------------- extern "C" void entry(CodeBuffer*); //----------------------------------------------------------------------------- + address TemplateInterpreterGenerator::generate_slow_signature_handler() { + address entry = __ pc(); + + __ andr(esp, esp, -16); + __ mov(c_rarg3, esp); + // rmethod + // rlocals + // c_rarg3: first stack arg - wordSize + + // adjust sp + __ sub(sp, c_rarg3, 18 * wordSize); + __ str(lr, Address(__ pre(sp, -2 * wordSize))); + __ call_VM(noreg, + CAST_FROM_FN_PTR(address, + InterpreterRuntime::slow_signature_handler), + rmethod, rlocals, c_rarg3); + + // r0: result handler + + // Stack layout: + // rsp: return address <- sp + // 1 garbage + // 8 integer args (if static first is unused) + // 1 float/double identifiers + // 8 double args + // stack args <- esp + // garbage + // expression stack bottom + // bcp (NULL) + // ... + + // Restore LR + __ ldr(lr, Address(__ post(sp, 2 * wordSize))); + + // Do FP first so we can use c_rarg3 as temp + __ ldrw(c_rarg3, Address(sp, 9 * wordSize)); // float/double identifiers + + for (int i = 0; i < Argument::n_float_register_parameters_c; i++) { + const FloatRegister r = as_FloatRegister(i); + + Label d, done; + + __ tbnz(c_rarg3, i, d); + __ ldrs(r, Address(sp, (10 + i) * wordSize)); + __ b(done); + __ bind(d); + __ ldrd(r, Address(sp, (10 + i) * wordSize)); + __ bind(done); + } + + // c_rarg0 contains the result from the call of + // InterpreterRuntime::slow_signature_handler so we don't touch it + // here. It will be loaded with the JNIEnv* later. + __ ldr(c_rarg1, Address(sp, 1 * wordSize)); + for (int i = c_rarg2->encoding(); i <= c_rarg7->encoding(); i += 2) { + Register rm = as_Register(i), rn = as_Register(i+1); + __ ldp(rm, rn, Address(sp, i * wordSize)); + } + + __ add(sp, sp, 18 * wordSize); + __ ret(lr); + + return entry; + } + + + // + // Various method entries + // + + address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) { + // rmethod: Method* + // r13: sender sp + // esp: args + + if (!InlineIntrinsics) return NULL; // Generate a vanilla entry + + // These don't need a safepoint check because they aren't virtually + // callable. We won't enter these intrinsics from compiled code. + // If in the future we added an intrinsic which was virtually callable + // we'd have to worry about how to safepoint so that this code is used. + + // mathematical functions inlined by compiler + // (interpreter must provide identical implementation + // in order to avoid monotonicity bugs when switching + // from interpreter to compiler in the middle of some + // computation) + // + // stack: + // [ arg ] <-- esp + // [ arg ] + // retaddr in lr + + address entry_point = NULL; + Register continuation = lr; + switch (kind) { + case Interpreter::java_lang_math_abs: + entry_point = __ pc(); + __ ldrd(v0, Address(esp)); + __ fabsd(v0, v0); + __ mov(sp, r13); // Restore caller's SP + break; + case Interpreter::java_lang_math_sqrt: + entry_point = __ pc(); + __ ldrd(v0, Address(esp)); + __ fsqrtd(v0, v0); + __ mov(sp, r13); + break; + case Interpreter::java_lang_math_sin : + case Interpreter::java_lang_math_cos : + case Interpreter::java_lang_math_tan : + case Interpreter::java_lang_math_log : + case Interpreter::java_lang_math_log10 : + case Interpreter::java_lang_math_exp : + entry_point = __ pc(); + __ ldrd(v0, Address(esp)); + __ mov(sp, r13); + __ mov(r19, lr); + continuation = r19; // The first callee-saved register + generate_transcendental_entry(kind, 1); + break; + case Interpreter::java_lang_math_pow : + entry_point = __ pc(); + __ mov(r19, lr); + continuation = r19; + __ ldrd(v0, Address(esp, 2 * Interpreter::stackElementSize)); + __ ldrd(v1, Address(esp)); + __ mov(sp, r13); + generate_transcendental_entry(kind, 2); + break; + default: + ; + } + if (entry_point) { + __ br(continuation); + } + + return entry_point; + } + + // double trigonometrics and transcendentals + // static jdouble dsin(jdouble x); + // static jdouble dcos(jdouble x); + // static jdouble dtan(jdouble x); + // static jdouble dlog(jdouble x); + // static jdouble dlog10(jdouble x); + // static jdouble dexp(jdouble x); + // static jdouble dpow(jdouble x, jdouble y); + + void TemplateInterpreterGenerator::generate_transcendental_entry(AbstractInterpreter::MethodKind kind, int fpargs) { + address fn; + switch (kind) { + case Interpreter::java_lang_math_sin : + fn = CAST_FROM_FN_PTR(address, SharedRuntime::dsin); + break; + case Interpreter::java_lang_math_cos : + fn = CAST_FROM_FN_PTR(address, SharedRuntime::dcos); + break; + case Interpreter::java_lang_math_tan : + fn = CAST_FROM_FN_PTR(address, SharedRuntime::dtan); + break; + case Interpreter::java_lang_math_log : + fn = CAST_FROM_FN_PTR(address, SharedRuntime::dlog); + break; + case Interpreter::java_lang_math_log10 : + fn = CAST_FROM_FN_PTR(address, SharedRuntime::dlog10); + break; + case Interpreter::java_lang_math_exp : + fn = CAST_FROM_FN_PTR(address, SharedRuntime::dexp); + break; + case Interpreter::java_lang_math_pow : + fpargs = 2; + fn = CAST_FROM_FN_PTR(address, SharedRuntime::dpow); + break; + default: + ShouldNotReachHere(); + } + const int gpargs = 0, rtype = 3; + __ mov(rscratch1, fn); + __ blrt(rscratch1, gpargs, fpargs, rtype); + } + + // Abstract method entry + // Attempt to execute abstract method. Throw exception + address TemplateInterpreterGenerator::generate_abstract_entry(void) { + // rmethod: Method* + // r13: sender SP + + address entry_point = __ pc(); + + // abstract method entry + + // pop return address, reset last_sp to NULL + __ empty_expression_stack(); + __ restore_bcp(); // bcp must be correct for exception handler (was destroyed) + __ restore_locals(); // make sure locals pointer is correct as well (was destroyed) + + // throw exception + __ call_VM(noreg, CAST_FROM_FN_PTR(address, + InterpreterRuntime::throw_AbstractMethodError)); + // the call_VM checks for exception, so we should never return here. + __ should_not_reach_here(); + + return entry_point; + } + address TemplateInterpreterGenerator::generate_StackOverflowError_handler() { address entry = __ pc(); #ifdef ASSERT {
< prev index next >