hotspot/src/cpu/ppc/vm/interpreter_ppc.cpp
changeset 35479 62c12ca7a45e
parent 35474 8333d76c7fee
child 35480 6ed8e1b70803
--- a/hotspot/src/cpu/ppc/vm/interpreter_ppc.cpp	Tue Jan 12 16:01:54 2016 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,555 +0,0 @@
-/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2015 SAP AG. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "asm/macroAssembler.inline.hpp"
-#include "interpreter/bytecodeHistogram.hpp"
-#include "interpreter/interpreter.hpp"
-#include "interpreter/interpreterRuntime.hpp"
-#include "interpreter/interp_masm.hpp"
-#include "interpreter/templateInterpreterGenerator.hpp"
-#include "interpreter/templateTable.hpp"
-#include "oops/arrayOop.hpp"
-#include "oops/methodData.hpp"
-#include "oops/method.hpp"
-#include "oops/oop.inline.hpp"
-#include "prims/jvmtiExport.hpp"
-#include "prims/jvmtiThreadState.hpp"
-#include "prims/methodHandles.hpp"
-#include "runtime/arguments.hpp"
-#include "runtime/frame.inline.hpp"
-#include "runtime/sharedRuntime.hpp"
-#include "runtime/stubRoutines.hpp"
-#include "runtime/synchronizer.hpp"
-#include "runtime/timer.hpp"
-#include "runtime/vframeArray.hpp"
-#include "utilities/debug.hpp"
-#ifdef COMPILER1
-#include "c1/c1_Runtime1.hpp"
-#endif
-
-#define __ _masm->
-
-#ifdef PRODUCT
-#define BLOCK_COMMENT(str) // nothing
-#else
-#define BLOCK_COMMENT(str) __ block_comment(str)
-#endif
-
-#define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
-
-address AbstractInterpreterGenerator::generate_slow_signature_handler() {
-  // Slow_signature handler that respects the PPC C calling conventions.
-  //
-  // We get called by the native entry code with our output register
-  // area == 8. First we call InterpreterRuntime::get_result_handler
-  // to copy the pointer to the signature string temporarily to the
-  // first C-argument and to return the result_handler in
-  // R3_RET. Since native_entry will copy the jni-pointer to the
-  // first C-argument slot later on, it is OK to occupy this slot
-  // temporarilly. Then we copy the argument list on the java
-  // expression stack into native varargs format on the native stack
-  // and load arguments into argument registers. Integer arguments in
-  // the varargs vector will be sign-extended to 8 bytes.
-  //
-  // On entry:
-  //   R3_ARG1        - intptr_t*     Address of java argument list in memory.
-  //   R15_prev_state - BytecodeInterpreter* Address of interpreter state for
-  //     this method
-  //   R19_method
-  //
-  // On exit (just before return instruction):
-  //   R3_RET            - contains the address of the result_handler.
-  //   R4_ARG2           - is not updated for static methods and contains "this" otherwise.
-  //   R5_ARG3-R10_ARG8: - When the (i-2)th Java argument is not of type float or double,
-  //                       ARGi contains this argument. Otherwise, ARGi is not updated.
-  //   F1_ARG1-F13_ARG13 - contain the first 13 arguments of type float or double.
-
-  const int LogSizeOfTwoInstructions = 3;
-
-  // FIXME: use Argument:: GL: Argument names different numbers!
-  const int max_fp_register_arguments  = 13;
-  const int max_int_register_arguments = 6;  // first 2 are reserved
-
-  const Register arg_java       = R21_tmp1;
-  const Register arg_c          = R22_tmp2;
-  const Register signature      = R23_tmp3;  // is string
-  const Register sig_byte       = R24_tmp4;
-  const Register fpcnt          = R25_tmp5;
-  const Register argcnt         = R26_tmp6;
-  const Register intSlot        = R27_tmp7;
-  const Register target_sp      = R28_tmp8;
-  const FloatRegister floatSlot = F0;
-
-  address entry = __ function_entry();
-
-  __ save_LR_CR(R0);
-  __ save_nonvolatile_gprs(R1_SP, _spill_nonvolatiles_neg(r14));
-  // We use target_sp for storing arguments in the C frame.
-  __ mr(target_sp, R1_SP);
-  __ push_frame_reg_args_nonvolatiles(0, R11_scratch1);
-
-  __ mr(arg_java, R3_ARG1);
-
-  __ call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::get_signature), R16_thread, R19_method);
-
-  // Signature is in R3_RET. Signature is callee saved.
-  __ mr(signature, R3_RET);
-
-  // Get the result handler.
-  __ call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::get_result_handler), R16_thread, R19_method);
-
-  {
-    Label L;
-    // test if static
-    // _access_flags._flags must be at offset 0.
-    // TODO PPC port: requires change in shared code.
-    //assert(in_bytes(AccessFlags::flags_offset()) == 0,
-    //       "MethodDesc._access_flags == MethodDesc._access_flags._flags");
-    // _access_flags must be a 32 bit value.
-    assert(sizeof(AccessFlags) == 4, "wrong size");
-    __ lwa(R11_scratch1/*access_flags*/, method_(access_flags));
-    // testbit with condition register.
-    __ testbitdi(CCR0, R0, R11_scratch1/*access_flags*/, JVM_ACC_STATIC_BIT);
-    __ btrue(CCR0, L);
-    // For non-static functions, pass "this" in R4_ARG2 and copy it
-    // to 2nd C-arg slot.
-    // We need to box the Java object here, so we use arg_java
-    // (address of current Java stack slot) as argument and don't
-    // dereference it as in case of ints, floats, etc.
-    __ mr(R4_ARG2, arg_java);
-    __ addi(arg_java, arg_java, -BytesPerWord);
-    __ std(R4_ARG2, _abi(carg_2), target_sp);
-    __ bind(L);
-  }
-
-  // Will be incremented directly after loop_start. argcnt=0
-  // corresponds to 3rd C argument.
-  __ li(argcnt, -1);
-  // arg_c points to 3rd C argument
-  __ addi(arg_c, target_sp, _abi(carg_3));
-  // no floating-point args parsed so far
-  __ li(fpcnt, 0);
-
-  Label move_intSlot_to_ARG, move_floatSlot_to_FARG;
-  Label loop_start, loop_end;
-  Label do_int, do_long, do_float, do_double, do_dontreachhere, do_object, do_array, do_boxed;
-
-  // signature points to '(' at entry
-#ifdef ASSERT
-  __ lbz(sig_byte, 0, signature);
-  __ cmplwi(CCR0, sig_byte, '(');
-  __ bne(CCR0, do_dontreachhere);
-#endif
-
-  __ bind(loop_start);
-
-  __ addi(argcnt, argcnt, 1);
-  __ lbzu(sig_byte, 1, signature);
-
-  __ cmplwi(CCR0, sig_byte, ')'); // end of signature
-  __ beq(CCR0, loop_end);
-
-  __ cmplwi(CCR0, sig_byte, 'B'); // byte
-  __ beq(CCR0, do_int);
-
-  __ cmplwi(CCR0, sig_byte, 'C'); // char
-  __ beq(CCR0, do_int);
-
-  __ cmplwi(CCR0, sig_byte, 'D'); // double
-  __ beq(CCR0, do_double);
-
-  __ cmplwi(CCR0, sig_byte, 'F'); // float
-  __ beq(CCR0, do_float);
-
-  __ cmplwi(CCR0, sig_byte, 'I'); // int
-  __ beq(CCR0, do_int);
-
-  __ cmplwi(CCR0, sig_byte, 'J'); // long
-  __ beq(CCR0, do_long);
-
-  __ cmplwi(CCR0, sig_byte, 'S'); // short
-  __ beq(CCR0, do_int);
-
-  __ cmplwi(CCR0, sig_byte, 'Z'); // boolean
-  __ beq(CCR0, do_int);
-
-  __ cmplwi(CCR0, sig_byte, 'L'); // object
-  __ beq(CCR0, do_object);
-
-  __ cmplwi(CCR0, sig_byte, '['); // array
-  __ beq(CCR0, do_array);
-
-  //  __ cmplwi(CCR0, sig_byte, 'V'); // void cannot appear since we do not parse the return type
-  //  __ beq(CCR0, do_void);
-
-  __ bind(do_dontreachhere);
-
-  __ unimplemented("ShouldNotReachHere in slow_signature_handler", 120);
-
-  __ bind(do_array);
-
-  {
-    Label start_skip, end_skip;
-
-    __ bind(start_skip);
-    __ lbzu(sig_byte, 1, signature);
-    __ cmplwi(CCR0, sig_byte, '[');
-    __ beq(CCR0, start_skip); // skip further brackets
-    __ cmplwi(CCR0, sig_byte, '9');
-    __ bgt(CCR0, end_skip);   // no optional size
-    __ cmplwi(CCR0, sig_byte, '0');
-    __ bge(CCR0, start_skip); // skip optional size
-    __ bind(end_skip);
-
-    __ cmplwi(CCR0, sig_byte, 'L');
-    __ beq(CCR0, do_object);  // for arrays of objects, the name of the object must be skipped
-    __ b(do_boxed);          // otherwise, go directly to do_boxed
-  }
-
-  __ bind(do_object);
-  {
-    Label L;
-    __ bind(L);
-    __ lbzu(sig_byte, 1, signature);
-    __ cmplwi(CCR0, sig_byte, ';');
-    __ bne(CCR0, L);
-   }
-  // Need to box the Java object here, so we use arg_java (address of
-  // current Java stack slot) as argument and don't dereference it as
-  // in case of ints, floats, etc.
-  Label do_null;
-  __ bind(do_boxed);
-  __ ld(R0,0, arg_java);
-  __ cmpdi(CCR0, R0, 0);
-  __ li(intSlot,0);
-  __ beq(CCR0, do_null);
-  __ mr(intSlot, arg_java);
-  __ bind(do_null);
-  __ std(intSlot, 0, arg_c);
-  __ addi(arg_java, arg_java, -BytesPerWord);
-  __ addi(arg_c, arg_c, BytesPerWord);
-  __ cmplwi(CCR0, argcnt, max_int_register_arguments);
-  __ blt(CCR0, move_intSlot_to_ARG);
-  __ b(loop_start);
-
-  __ bind(do_int);
-  __ lwa(intSlot, 0, arg_java);
-  __ std(intSlot, 0, arg_c);
-  __ addi(arg_java, arg_java, -BytesPerWord);
-  __ addi(arg_c, arg_c, BytesPerWord);
-  __ cmplwi(CCR0, argcnt, max_int_register_arguments);
-  __ blt(CCR0, move_intSlot_to_ARG);
-  __ b(loop_start);
-
-  __ bind(do_long);
-  __ ld(intSlot, -BytesPerWord, arg_java);
-  __ std(intSlot, 0, arg_c);
-  __ addi(arg_java, arg_java, - 2 * BytesPerWord);
-  __ addi(arg_c, arg_c, BytesPerWord);
-  __ cmplwi(CCR0, argcnt, max_int_register_arguments);
-  __ blt(CCR0, move_intSlot_to_ARG);
-  __ b(loop_start);
-
-  __ bind(do_float);
-  __ lfs(floatSlot, 0, arg_java);
-#if defined(LINUX)
-  // Linux uses ELF ABI. Both original ELF and ELFv2 ABIs have float
-  // in the least significant word of an argument slot.
-#if defined(VM_LITTLE_ENDIAN)
-  __ stfs(floatSlot, 0, arg_c);
-#else
-  __ stfs(floatSlot, 4, arg_c);
-#endif
-#elif defined(AIX)
-  // Although AIX runs on big endian CPU, float is in most significant
-  // word of an argument slot.
-  __ stfs(floatSlot, 0, arg_c);
-#else
-#error "unknown OS"
-#endif
-  __ addi(arg_java, arg_java, -BytesPerWord);
-  __ addi(arg_c, arg_c, BytesPerWord);
-  __ cmplwi(CCR0, fpcnt, max_fp_register_arguments);
-  __ blt(CCR0, move_floatSlot_to_FARG);
-  __ b(loop_start);
-
-  __ bind(do_double);
-  __ lfd(floatSlot, - BytesPerWord, arg_java);
-  __ stfd(floatSlot, 0, arg_c);
-  __ addi(arg_java, arg_java, - 2 * BytesPerWord);
-  __ addi(arg_c, arg_c, BytesPerWord);
-  __ cmplwi(CCR0, fpcnt, max_fp_register_arguments);
-  __ blt(CCR0, move_floatSlot_to_FARG);
-  __ b(loop_start);
-
-  __ bind(loop_end);
-
-  __ pop_frame();
-  __ restore_nonvolatile_gprs(R1_SP, _spill_nonvolatiles_neg(r14));
-  __ restore_LR_CR(R0);
-
-  __ blr();
-
-  Label move_int_arg, move_float_arg;
-  __ bind(move_int_arg); // each case must consist of 2 instructions (otherwise adapt LogSizeOfTwoInstructions)
-  __ mr(R5_ARG3, intSlot);  __ b(loop_start);
-  __ mr(R6_ARG4, intSlot);  __ b(loop_start);
-  __ mr(R7_ARG5, intSlot);  __ b(loop_start);
-  __ mr(R8_ARG6, intSlot);  __ b(loop_start);
-  __ mr(R9_ARG7, intSlot);  __ b(loop_start);
-  __ mr(R10_ARG8, intSlot); __ b(loop_start);
-
-  __ bind(move_float_arg); // each case must consist of 2 instructions (otherwise adapt LogSizeOfTwoInstructions)
-  __ fmr(F1_ARG1, floatSlot);   __ b(loop_start);
-  __ fmr(F2_ARG2, floatSlot);   __ b(loop_start);
-  __ fmr(F3_ARG3, floatSlot);   __ b(loop_start);
-  __ fmr(F4_ARG4, floatSlot);   __ b(loop_start);
-  __ fmr(F5_ARG5, floatSlot);   __ b(loop_start);
-  __ fmr(F6_ARG6, floatSlot);   __ b(loop_start);
-  __ fmr(F7_ARG7, floatSlot);   __ b(loop_start);
-  __ fmr(F8_ARG8, floatSlot);   __ b(loop_start);
-  __ fmr(F9_ARG9, floatSlot);   __ b(loop_start);
-  __ fmr(F10_ARG10, floatSlot); __ b(loop_start);
-  __ fmr(F11_ARG11, floatSlot); __ b(loop_start);
-  __ fmr(F12_ARG12, floatSlot); __ b(loop_start);
-  __ fmr(F13_ARG13, floatSlot); __ b(loop_start);
-
-  __ bind(move_intSlot_to_ARG);
-  __ sldi(R0, argcnt, LogSizeOfTwoInstructions);
-  __ load_const(R11_scratch1, move_int_arg); // Label must be bound here.
-  __ add(R11_scratch1, R0, R11_scratch1);
-  __ mtctr(R11_scratch1/*branch_target*/);
-  __ bctr();
-  __ bind(move_floatSlot_to_FARG);
-  __ sldi(R0, fpcnt, LogSizeOfTwoInstructions);
-  __ addi(fpcnt, fpcnt, 1);
-  __ load_const(R11_scratch1, move_float_arg); // Label must be bound here.
-  __ add(R11_scratch1, R0, R11_scratch1);
-  __ mtctr(R11_scratch1/*branch_target*/);
-  __ bctr();
-
-  return entry;
-}
-
-address AbstractInterpreterGenerator::generate_result_handler_for(BasicType type) {
-  //
-  // Registers alive
-  //   R3_RET
-  //   LR
-  //
-  // Registers updated
-  //   R3_RET
-  //
-
-  Label done;
-  address entry = __ pc();
-
-  switch (type) {
-  case T_BOOLEAN:
-    // convert !=0 to 1
-    __ neg(R0, R3_RET);
-    __ orr(R0, R3_RET, R0);
-    __ srwi(R3_RET, R0, 31);
-    break;
-  case T_BYTE:
-     // sign extend 8 bits
-     __ extsb(R3_RET, R3_RET);
-     break;
-  case T_CHAR:
-     // zero extend 16 bits
-     __ clrldi(R3_RET, R3_RET, 48);
-     break;
-  case T_SHORT:
-     // sign extend 16 bits
-     __ extsh(R3_RET, R3_RET);
-     break;
-  case T_INT:
-     // sign extend 32 bits
-     __ extsw(R3_RET, R3_RET);
-     break;
-  case T_LONG:
-     break;
-  case T_OBJECT:
-    // unbox result if not null
-    __ cmpdi(CCR0, R3_RET, 0);
-    __ beq(CCR0, done);
-    __ ld(R3_RET, 0, R3_RET);
-    __ verify_oop(R3_RET);
-    break;
-  case T_FLOAT:
-     break;
-  case T_DOUBLE:
-     break;
-  case T_VOID:
-     break;
-  default: ShouldNotReachHere();
-  }
-
-  __ BIND(done);
-  __ blr();
-
-  return entry;
-}
-
-// Abstract method entry.
-//
-address TemplateInterpreterGenerator::generate_abstract_entry(void) {
-  address entry = __ pc();
-
-  //
-  // Registers alive
-  //   R16_thread     - JavaThread*
-  //   R19_method     - callee's method (method to be invoked)
-  //   R1_SP          - SP prepared such that caller's outgoing args are near top
-  //   LR             - return address to caller
-  //
-  // Stack layout at this point:
-  //
-  //   0       [TOP_IJAVA_FRAME_ABI]         <-- R1_SP
-  //           alignment (optional)
-  //           [outgoing Java arguments]
-  //           ...
-  //   PARENT  [PARENT_IJAVA_FRAME_ABI]
-  //            ...
-  //
-
-  // Can't use call_VM here because we have not set up a new
-  // interpreter state. Make the call to the vm and make it look like
-  // our caller set up the JavaFrameAnchor.
-  __ set_top_ijava_frame_at_SP_as_last_Java_frame(R1_SP, R12_scratch2/*tmp*/);
-
-  // Push a new C frame and save LR.
-  __ save_LR_CR(R0);
-  __ push_frame_reg_args(0, R11_scratch1);
-
-  // This is not a leaf but we have a JavaFrameAnchor now and we will
-  // check (create) exceptions afterward so this is ok.
-  __ call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodError),
-                  R16_thread);
-
-  // Pop the C frame and restore LR.
-  __ pop_frame();
-  __ restore_LR_CR(R0);
-
-  // Reset JavaFrameAnchor from call_VM_leaf above.
-  __ reset_last_Java_frame();
-
-  // We don't know our caller, so jump to the general forward exception stub,
-  // which will also pop our full frame off. Satisfy the interface of
-  // SharedRuntime::generate_forward_exception()
-  __ load_const_optimized(R11_scratch1, StubRoutines::forward_exception_entry(), R0);
-  __ mtctr(R11_scratch1);
-  __ bctr();
-
-  return entry;
-}
-
-// Interpreter intrinsic for WeakReference.get().
-// 1. Don't push a full blown frame and go on dispatching, but fetch the value
-//    into R8 and return quickly
-// 2. If G1 is active we *must* execute this intrinsic for corrrectness:
-//    It contains a GC barrier which puts the reference into the satb buffer
-//    to indicate that someone holds a strong reference to the object the
-//    weak ref points to!
-address TemplateInterpreterGenerator::generate_Reference_get_entry(void) {
-  // Code: _aload_0, _getfield, _areturn
-  // parameter size = 1
-  //
-  // The code that gets generated by this routine is split into 2 parts:
-  //    1. the "intrinsified" code for G1 (or any SATB based GC),
-  //    2. the slow path - which is an expansion of the regular method entry.
-  //
-  // Notes:
-  // * In the G1 code we do not check whether we need to block for
-  //   a safepoint. If G1 is enabled then we must execute the specialized
-  //   code for Reference.get (except when the Reference object is null)
-  //   so that we can log the value in the referent field with an SATB
-  //   update buffer.
-  //   If the code for the getfield template is modified so that the
-  //   G1 pre-barrier code is executed when the current method is
-  //   Reference.get() then going through the normal method entry
-  //   will be fine.
-  // * The G1 code can, however, check the receiver object (the instance
-  //   of java.lang.Reference) and jump to the slow path if null. If the
-  //   Reference object is null then we obviously cannot fetch the referent
-  //   and so we don't need to call the G1 pre-barrier. Thus we can use the
-  //   regular method entry code to generate the NPE.
-  //
-
-  if (UseG1GC) {
-    address entry = __ pc();
-
-    const int referent_offset = java_lang_ref_Reference::referent_offset;
-    guarantee(referent_offset > 0, "referent offset not initialized");
-
-    Label slow_path;
-
-    // Debugging not possible, so can't use __ skip_if_jvmti_mode(slow_path, GR31_SCRATCH);
-
-    // In the G1 code we don't check if we need to reach a safepoint. We
-    // continue and the thread will safepoint at the next bytecode dispatch.
-
-    // If the receiver is null then it is OK to jump to the slow path.
-    __ ld(R3_RET, Interpreter::stackElementSize, R15_esp); // get receiver
-
-    // Check if receiver == NULL and go the slow path.
-    __ cmpdi(CCR0, R3_RET, 0);
-    __ beq(CCR0, slow_path);
-
-    // Load the value of the referent field.
-    __ load_heap_oop(R3_RET, referent_offset, R3_RET);
-
-    // Generate the G1 pre-barrier code to log the value of
-    // the referent field in an SATB buffer. Note with
-    // these parameters the pre-barrier does not generate
-    // the load of the previous value.
-
-    // Restore caller sp for c2i case.
-#ifdef ASSERT
-      __ ld(R9_ARG7, 0, R1_SP);
-      __ ld(R10_ARG8, 0, R21_sender_SP);
-      __ cmpd(CCR0, R9_ARG7, R10_ARG8);
-      __ asm_assert_eq("backlink", 0x544);
-#endif // ASSERT
-    __ mr(R1_SP, R21_sender_SP); // Cut the stack back to where the caller started.
-
-    __ g1_write_barrier_pre(noreg,         // obj
-                            noreg,         // offset
-                            R3_RET,        // pre_val
-                            R11_scratch1,  // tmp
-                            R12_scratch2,  // tmp
-                            true);         // needs_frame
-
-    __ blr();
-
-    // Generate regular method entry.
-    __ bind(slow_path);
-    __ jump_to_entry(Interpreter::entry_for_kind(Interpreter::zerolocals), R11_scratch1);
-    return entry;
-  }
-
-  return NULL;
-}