src/cpu/ppc/vm/methodHandles_ppc.cpp

changeset 0
f90c822e73f8
child 6876
710a3c8b516e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/cpu/ppc/vm/methodHandles_ppc.cpp	Wed Apr 27 01:25:04 2016 +0800
     1.3 @@ -0,0 +1,558 @@
     1.4 +/*
     1.5 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright 2012, 2014 SAP AG. All rights reserved.
     1.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8 + *
     1.9 + * This code is free software; you can redistribute it and/or modify it
    1.10 + * under the terms of the GNU General Public License version 2 only, as
    1.11 + * published by the Free Software Foundation.
    1.12 + *
    1.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.15 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.16 + * version 2 for more details (a copy is included in the LICENSE file that
    1.17 + * accompanied this code).
    1.18 + *
    1.19 + * You should have received a copy of the GNU General Public License version
    1.20 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.22 + *
    1.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.24 + * or visit www.oracle.com if you need additional information or have any
    1.25 + * questions.
    1.26 + *
    1.27 + */
    1.28 +
    1.29 +#include "precompiled.hpp"
    1.30 +#include "asm/macroAssembler.inline.hpp"
    1.31 +#include "interpreter/interpreter.hpp"
    1.32 +#include "memory/allocation.inline.hpp"
    1.33 +#include "prims/methodHandles.hpp"
    1.34 +
    1.35 +#define __ _masm->
    1.36 +
    1.37 +#ifdef CC_INTERP
    1.38 +#define EXCEPTION_ENTRY StubRoutines::throw_NullPointerException_at_call_entry()
    1.39 +#else
    1.40 +#define EXCEPTION_ENTRY Interpreter::throw_NullPointerException_entry()
    1.41 +#endif
    1.42 +
    1.43 +#ifdef PRODUCT
    1.44 +#define BLOCK_COMMENT(str) // nothing
    1.45 +#else
    1.46 +#define BLOCK_COMMENT(str) __ block_comment(str)
    1.47 +#endif
    1.48 +
    1.49 +#define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
    1.50 +
    1.51 +// Workaround for C++ overloading nastiness on '0' for RegisterOrConstant.
    1.52 +inline static RegisterOrConstant constant(int value) {
    1.53 +  return RegisterOrConstant(value);
    1.54 +}
    1.55 +
    1.56 +void MethodHandles::load_klass_from_Class(MacroAssembler* _masm, Register klass_reg, Register temp_reg, Register temp2_reg) {
    1.57 +  if (VerifyMethodHandles)
    1.58 +    verify_klass(_masm, klass_reg, SystemDictionary::WK_KLASS_ENUM_NAME(java_lang_Class), temp_reg, temp2_reg,
    1.59 +                 "MH argument is a Class");
    1.60 +  __ ld(klass_reg, java_lang_Class::klass_offset_in_bytes(), klass_reg);
    1.61 +}
    1.62 +
    1.63 +#ifdef ASSERT
    1.64 +static int check_nonzero(const char* xname, int x) {
    1.65 +  assert(x != 0, err_msg("%s should be nonzero", xname));
    1.66 +  return x;
    1.67 +}
    1.68 +#define NONZERO(x) check_nonzero(#x, x)
    1.69 +#else //ASSERT
    1.70 +#define NONZERO(x) (x)
    1.71 +#endif //ASSERT
    1.72 +
    1.73 +#ifdef ASSERT
    1.74 +void MethodHandles::verify_klass(MacroAssembler* _masm,
    1.75 +                                 Register obj_reg, SystemDictionary::WKID klass_id,
    1.76 +                                 Register temp_reg, Register temp2_reg,
    1.77 +                                 const char* error_message) {
    1.78 +  Klass** klass_addr = SystemDictionary::well_known_klass_addr(klass_id);
    1.79 +  KlassHandle klass = SystemDictionary::well_known_klass(klass_id);
    1.80 +  Label L_ok, L_bad;
    1.81 +  BLOCK_COMMENT("verify_klass {");
    1.82 +  __ verify_oop(obj_reg);
    1.83 +  __ cmpdi(CCR0, obj_reg, 0);
    1.84 +  __ beq(CCR0, L_bad);
    1.85 +  __ load_klass(temp_reg, obj_reg);
    1.86 +  __ load_const_optimized(temp2_reg, (address) klass_addr);
    1.87 +  __ ld(temp2_reg, 0, temp2_reg);
    1.88 +  __ cmpd(CCR0, temp_reg, temp2_reg);
    1.89 +  __ beq(CCR0, L_ok);
    1.90 +  __ ld(temp_reg, klass->super_check_offset(), temp_reg);
    1.91 +  __ cmpd(CCR0, temp_reg, temp2_reg);
    1.92 +  __ beq(CCR0, L_ok);
    1.93 +  __ BIND(L_bad);
    1.94 +  __ stop(error_message);
    1.95 +  __ BIND(L_ok);
    1.96 +  BLOCK_COMMENT("} verify_klass");
    1.97 +}
    1.98 +
    1.99 +void MethodHandles::verify_ref_kind(MacroAssembler* _masm, int ref_kind, Register member_reg, Register temp) {
   1.100 +  Label L;
   1.101 +  BLOCK_COMMENT("verify_ref_kind {");
   1.102 +  __ load_sized_value(temp, NONZERO(java_lang_invoke_MemberName::flags_offset_in_bytes()), member_reg,
   1.103 +                      sizeof(u4), /*is_signed*/ false);
   1.104 +  // assert(sizeof(u4) == sizeof(java.lang.invoke.MemberName.flags), "");
   1.105 +  __ srwi( temp, temp, java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT);
   1.106 +  __ andi(temp, temp, java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK);
   1.107 +  __ cmpwi(CCR1, temp, ref_kind);
   1.108 +  __ beq(CCR1, L);
   1.109 +  { char* buf = NEW_C_HEAP_ARRAY(char, 100, mtInternal);
   1.110 +    jio_snprintf(buf, 100, "verify_ref_kind expected %x", ref_kind);
   1.111 +    if (ref_kind == JVM_REF_invokeVirtual ||
   1.112 +        ref_kind == JVM_REF_invokeSpecial)
   1.113 +      // could do this for all ref_kinds, but would explode assembly code size
   1.114 +      trace_method_handle(_masm, buf);
   1.115 +    __ stop(buf);
   1.116 +  }
   1.117 +  BLOCK_COMMENT("} verify_ref_kind");
   1.118 +  __ BIND(L);
   1.119 +}
   1.120 +
   1.121 +#endif // ASSERT
   1.122 +
   1.123 +void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register method, Register target, Register temp,
   1.124 +                                            bool for_compiler_entry) {
   1.125 +  Label L_no_such_method;
   1.126 +  assert(method == R19_method, "interpreter calling convention");
   1.127 +  assert_different_registers(method, target, temp);
   1.128 +
   1.129 +  if (!for_compiler_entry && JvmtiExport::can_post_interpreter_events()) {
   1.130 +    Label run_compiled_code;
   1.131 +    // JVMTI events, such as single-stepping, are implemented partly by avoiding running
   1.132 +    // compiled code in threads for which the event is enabled.  Check here for
   1.133 +    // interp_only_mode if these events CAN be enabled.
   1.134 +    __ verify_thread();
   1.135 +    __ lwz(temp, in_bytes(JavaThread::interp_only_mode_offset()), R16_thread);
   1.136 +    __ cmplwi(CCR0, temp, 0);
   1.137 +    __ beq(CCR0, run_compiled_code);
   1.138 +    // Null method test is replicated below in compiled case,
   1.139 +    // it might be able to address across the verify_thread()
   1.140 +    __ cmplwi(CCR0, R19_method, 0);
   1.141 +    __ beq(CCR0, L_no_such_method);
   1.142 +    __ ld(target, in_bytes(Method::interpreter_entry_offset()), R19_method);
   1.143 +    __ mtctr(target);
   1.144 +    __ bctr();
   1.145 +    __ BIND(run_compiled_code);
   1.146 +  }
   1.147 +
   1.148 +  // Compiled case, either static or fall-through from runtime conditional
   1.149 +  __ cmplwi(CCR0, R19_method, 0);
   1.150 +  __ beq(CCR0, L_no_such_method);
   1.151 +
   1.152 +  const ByteSize entry_offset = for_compiler_entry ? Method::from_compiled_offset() :
   1.153 +                                                     Method::from_interpreted_offset();
   1.154 +  __ ld(target, in_bytes(entry_offset), R19_method);
   1.155 +  __ mtctr(target);
   1.156 +  __ bctr();
   1.157 +
   1.158 +  __ bind(L_no_such_method);
   1.159 +  assert(StubRoutines::throw_AbstractMethodError_entry() != NULL, "not yet generated!");
   1.160 +  __ load_const_optimized(target, StubRoutines::throw_AbstractMethodError_entry());
   1.161 +  __ mtctr(target);
   1.162 +  __ bctr();
   1.163 +}
   1.164 +
   1.165 +
   1.166 +void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
   1.167 +                                        Register recv, Register method_temp,
   1.168 +                                        Register temp2, Register temp3,
   1.169 +                                        bool for_compiler_entry) {
   1.170 +  BLOCK_COMMENT("jump_to_lambda_form {");
   1.171 +  // This is the initial entry point of a lazy method handle.
   1.172 +  // After type checking, it picks up the invoker from the LambdaForm.
   1.173 +  assert_different_registers(recv, method_temp, temp2);  // temp3 is only passed on
   1.174 +  assert(method_temp == R19_method, "required register for loading method");
   1.175 +
   1.176 +  // Load the invoker, as MH -> MH.form -> LF.vmentry
   1.177 +  __ verify_oop(recv);
   1.178 +  __ load_heap_oop_not_null(method_temp, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes()), recv);
   1.179 +  __ verify_oop(method_temp);
   1.180 +  __ load_heap_oop_not_null(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes()), method_temp);
   1.181 +  __ verify_oop(method_temp);
   1.182 +  // the following assumes that a Method* is normally compressed in the vmtarget field:
   1.183 +  __ ld(method_temp, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes()), method_temp);
   1.184 +
   1.185 +  if (VerifyMethodHandles && !for_compiler_entry) {
   1.186 +    // make sure recv is already on stack
   1.187 +    __ ld(temp2, in_bytes(Method::const_offset()), method_temp);
   1.188 +    __ load_sized_value(temp2, in_bytes(ConstMethod::size_of_parameters_offset()), temp2,
   1.189 +                        sizeof(u2), /*is_signed*/ false);
   1.190 +    // assert(sizeof(u2) == sizeof(ConstMethod::_size_of_parameters), "");
   1.191 +    Label L;
   1.192 +    __ ld(temp2, __ argument_offset(temp2, temp2, 0), CC_INTERP_ONLY(R17_tos) NOT_CC_INTERP(R15_esp));
   1.193 +    __ cmpd(CCR1, temp2, recv);
   1.194 +    __ beq(CCR1, L);
   1.195 +    __ stop("receiver not on stack");
   1.196 +    __ BIND(L);
   1.197 +  }
   1.198 +
   1.199 +  jump_from_method_handle(_masm, method_temp, temp2, temp3, for_compiler_entry);
   1.200 +  BLOCK_COMMENT("} jump_to_lambda_form");
   1.201 +}
   1.202 +
   1.203 +
   1.204 +
   1.205 +// Code generation
   1.206 +address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* _masm,
   1.207 +                                                                vmIntrinsics::ID iid) {
   1.208 +  const bool not_for_compiler_entry = false;  // this is the interpreter entry
   1.209 +  assert(is_signature_polymorphic(iid), "expected invoke iid");
   1.210 +  if (iid == vmIntrinsics::_invokeGeneric ||
   1.211 +      iid == vmIntrinsics::_compiledLambdaForm) {
   1.212 +    // Perhaps surprisingly, the symbolic references visible to Java are not directly used.
   1.213 +    // They are linked to Java-generated adapters via MethodHandleNatives.linkMethod.
   1.214 +    // They all allow an appendix argument.
   1.215 +    __ stop("Should not reach here");           // empty stubs make SG sick
   1.216 +    return NULL;
   1.217 +  }
   1.218 +
   1.219 +  Register argbase    = CC_INTERP_ONLY(R17_tos) NOT_CC_INTERP(R15_esp); // parameter (preserved)
   1.220 +  Register argslot    = R3;
   1.221 +  Register temp1      = R6;
   1.222 +  Register param_size = R7;
   1.223 +
   1.224 +  // here's where control starts out:
   1.225 +  __ align(CodeEntryAlignment);
   1.226 +  address entry_point = __ pc();
   1.227 +
   1.228 +  if (VerifyMethodHandles) {
   1.229 +    Label L;
   1.230 +    BLOCK_COMMENT("verify_intrinsic_id {");
   1.231 +    __ load_sized_value(temp1, Method::intrinsic_id_offset_in_bytes(), R19_method,
   1.232 +                        sizeof(u1), /*is_signed*/ false);
   1.233 +    // assert(sizeof(u1) == sizeof(Method::_intrinsic_id), "");
   1.234 +    __ cmpwi(CCR1, temp1, (int) iid);
   1.235 +    __ beq(CCR1, L);
   1.236 +    if (iid == vmIntrinsics::_linkToVirtual ||
   1.237 +        iid == vmIntrinsics::_linkToSpecial) {
   1.238 +      // could do this for all kinds, but would explode assembly code size
   1.239 +      trace_method_handle(_masm, "bad Method*:intrinsic_id");
   1.240 +    }
   1.241 +    __ stop("bad Method*::intrinsic_id");
   1.242 +    __ BIND(L);
   1.243 +    BLOCK_COMMENT("} verify_intrinsic_id");
   1.244 +  }
   1.245 +
   1.246 +  // First task:  Find out how big the argument list is.
   1.247 +  int ref_kind = signature_polymorphic_intrinsic_ref_kind(iid);
   1.248 +  assert(ref_kind != 0 || iid == vmIntrinsics::_invokeBasic, "must be _invokeBasic or a linkTo intrinsic");
   1.249 +  if (ref_kind == 0 || MethodHandles::ref_kind_has_receiver(ref_kind)) {
   1.250 +    __ ld(param_size, in_bytes(Method::const_offset()), R19_method);
   1.251 +    __ load_sized_value(param_size, in_bytes(ConstMethod::size_of_parameters_offset()), param_size,
   1.252 +                        sizeof(u2), /*is_signed*/ false);
   1.253 +    // assert(sizeof(u2) == sizeof(ConstMethod::_size_of_parameters), "");
   1.254 +  } else {
   1.255 +    DEBUG_ONLY(param_size = noreg);
   1.256 +  }
   1.257 +
   1.258 +  Register tmp_mh = noreg;
   1.259 +  if (!is_signature_polymorphic_static(iid)) {
   1.260 +    __ ld(tmp_mh = temp1, __ argument_offset(param_size, param_size, 0), argbase);
   1.261 +    DEBUG_ONLY(param_size = noreg);
   1.262 +  }
   1.263 +
   1.264 +  if (TraceMethodHandles) {
   1.265 +    if (tmp_mh != noreg)
   1.266 +      __ mr(R23_method_handle, tmp_mh);  // make stub happy
   1.267 +    trace_method_handle_interpreter_entry(_masm, iid);
   1.268 +  }
   1.269 +
   1.270 +  if (iid == vmIntrinsics::_invokeBasic) {
   1.271 +    generate_method_handle_dispatch(_masm, iid, tmp_mh, noreg, not_for_compiler_entry);
   1.272 +
   1.273 +  } else {
   1.274 +    // Adjust argument list by popping the trailing MemberName argument.
   1.275 +    Register tmp_recv = noreg;
   1.276 +    if (MethodHandles::ref_kind_has_receiver(ref_kind)) {
   1.277 +      // Load the receiver (not the MH; the actual MemberName's receiver) up from the interpreter stack.
   1.278 +      __ ld(tmp_recv = temp1, __ argument_offset(param_size, param_size, 0), argbase);
   1.279 +      DEBUG_ONLY(param_size = noreg);
   1.280 +    }
   1.281 +    Register R19_member = R19_method;  // MemberName ptr; incoming method ptr is dead now
   1.282 +    __ ld(R19_member, RegisterOrConstant((intptr_t)8), argbase);
   1.283 +    __ add(argbase, Interpreter::stackElementSize, argbase);
   1.284 +    generate_method_handle_dispatch(_masm, iid, tmp_recv, R19_member, not_for_compiler_entry);
   1.285 +  }
   1.286 +
   1.287 +  return entry_point;
   1.288 +}
   1.289 +
   1.290 +void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
   1.291 +                                                    vmIntrinsics::ID iid,
   1.292 +                                                    Register receiver_reg,
   1.293 +                                                    Register member_reg,
   1.294 +                                                    bool for_compiler_entry) {
   1.295 +  assert(is_signature_polymorphic(iid), "expected invoke iid");
   1.296 +  Register temp1 = (for_compiler_entry ? R25_tmp5 : R7);
   1.297 +  Register temp2 = (for_compiler_entry ? R22_tmp2 : R8);
   1.298 +  Register temp3 = (for_compiler_entry ? R23_tmp3 : R9);
   1.299 +  Register temp4 = (for_compiler_entry ? R24_tmp4 : R10);
   1.300 +  if (receiver_reg != noreg)  assert_different_registers(temp1, temp2, temp3, temp4, receiver_reg);
   1.301 +  if (member_reg   != noreg)  assert_different_registers(temp1, temp2, temp3, temp4, member_reg);
   1.302 +
   1.303 +  if (iid == vmIntrinsics::_invokeBasic) {
   1.304 +    // indirect through MH.form.vmentry.vmtarget
   1.305 +    jump_to_lambda_form(_masm, receiver_reg, R19_method, temp1, temp2, for_compiler_entry);
   1.306 +  } else {
   1.307 +    // The method is a member invoker used by direct method handles.
   1.308 +    if (VerifyMethodHandles) {
   1.309 +      // make sure the trailing argument really is a MemberName (caller responsibility)
   1.310 +      verify_klass(_masm, member_reg, SystemDictionary::WK_KLASS_ENUM_NAME(MemberName_klass),
   1.311 +                   temp1, temp2,
   1.312 +                   "MemberName required for invokeVirtual etc.");
   1.313 +    }
   1.314 +
   1.315 +    Register temp1_recv_klass = temp1;
   1.316 +    if (iid != vmIntrinsics::_linkToStatic) {
   1.317 +      __ verify_oop(receiver_reg);
   1.318 +      if (iid == vmIntrinsics::_linkToSpecial) {
   1.319 +        // Don't actually load the klass; just null-check the receiver.
   1.320 +        __ null_check_throw(receiver_reg, -1, temp1, EXCEPTION_ENTRY);
   1.321 +      } else {
   1.322 +        // load receiver klass itself
   1.323 +        __ null_check_throw(receiver_reg, oopDesc::klass_offset_in_bytes(), temp1, EXCEPTION_ENTRY);
   1.324 +        __ load_klass(temp1_recv_klass, receiver_reg);
   1.325 +        __ verify_klass_ptr(temp1_recv_klass);
   1.326 +      }
   1.327 +      BLOCK_COMMENT("check_receiver {");
   1.328 +      // The receiver for the MemberName must be in receiver_reg.
   1.329 +      // Check the receiver against the MemberName.clazz
   1.330 +      if (VerifyMethodHandles && iid == vmIntrinsics::_linkToSpecial) {
   1.331 +        // Did not load it above...
   1.332 +        __ load_klass(temp1_recv_klass, receiver_reg);
   1.333 +        __ verify_klass_ptr(temp1_recv_klass);
   1.334 +      }
   1.335 +      if (VerifyMethodHandles && iid != vmIntrinsics::_linkToInterface) {
   1.336 +        Label L_ok;
   1.337 +        Register temp2_defc = temp2;
   1.338 +        __ load_heap_oop_not_null(temp2_defc, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes()), member_reg);
   1.339 +        load_klass_from_Class(_masm, temp2_defc, temp3, temp4);
   1.340 +        __ verify_klass_ptr(temp2_defc);
   1.341 +        __ check_klass_subtype(temp1_recv_klass, temp2_defc, temp3, temp4, L_ok);
   1.342 +        // If we get here, the type check failed!
   1.343 +        __ stop("receiver class disagrees with MemberName.clazz");
   1.344 +        __ BIND(L_ok);
   1.345 +      }
   1.346 +      BLOCK_COMMENT("} check_receiver");
   1.347 +    }
   1.348 +    if (iid == vmIntrinsics::_linkToSpecial ||
   1.349 +        iid == vmIntrinsics::_linkToStatic) {
   1.350 +      DEBUG_ONLY(temp1_recv_klass = noreg);  // these guys didn't load the recv_klass
   1.351 +    }
   1.352 +
   1.353 +    // Live registers at this point:
   1.354 +    //  member_reg - MemberName that was the trailing argument
   1.355 +    //  temp1_recv_klass - klass of stacked receiver, if needed
   1.356 +    //  O5_savedSP - interpreter linkage (if interpreted)
   1.357 +    //  O0..O5 - compiler arguments (if compiled)
   1.358 +
   1.359 +    Label L_incompatible_class_change_error;
   1.360 +    switch (iid) {
   1.361 +    case vmIntrinsics::_linkToSpecial:
   1.362 +      if (VerifyMethodHandles) {
   1.363 +        verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp2);
   1.364 +      }
   1.365 +      __ ld(R19_method, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes()), member_reg);
   1.366 +      break;
   1.367 +
   1.368 +    case vmIntrinsics::_linkToStatic:
   1.369 +      if (VerifyMethodHandles) {
   1.370 +        verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp2);
   1.371 +      }
   1.372 +      __ ld(R19_method, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes()), member_reg);
   1.373 +      break;
   1.374 +
   1.375 +    case vmIntrinsics::_linkToVirtual:
   1.376 +    {
   1.377 +      // same as TemplateTable::invokevirtual,
   1.378 +      // minus the CP setup and profiling:
   1.379 +
   1.380 +      if (VerifyMethodHandles) {
   1.381 +        verify_ref_kind(_masm, JVM_REF_invokeVirtual, member_reg, temp2);
   1.382 +      }
   1.383 +
   1.384 +      // pick out the vtable index from the MemberName, and then we can discard it:
   1.385 +      Register temp2_index = temp2;
   1.386 +      __ ld(temp2_index, NONZERO(java_lang_invoke_MemberName::vmindex_offset_in_bytes()), member_reg);
   1.387 +
   1.388 +      if (VerifyMethodHandles) {
   1.389 +        Label L_index_ok;
   1.390 +        __ cmpdi(CCR1, temp2_index, 0);
   1.391 +        __ bge(CCR1, L_index_ok);
   1.392 +        __ stop("no virtual index");
   1.393 +        __ BIND(L_index_ok);
   1.394 +      }
   1.395 +
   1.396 +      // Note:  The verifier invariants allow us to ignore MemberName.clazz and vmtarget
   1.397 +      // at this point.  And VerifyMethodHandles has already checked clazz, if needed.
   1.398 +
   1.399 +      // get target Method* & entry point
   1.400 +      __ lookup_virtual_method(temp1_recv_klass, temp2_index, R19_method);
   1.401 +      break;
   1.402 +    }
   1.403 +
   1.404 +    case vmIntrinsics::_linkToInterface:
   1.405 +    {
   1.406 +      // same as TemplateTable::invokeinterface
   1.407 +      // (minus the CP setup and profiling, with different argument motion)
   1.408 +      if (VerifyMethodHandles) {
   1.409 +        verify_ref_kind(_masm, JVM_REF_invokeInterface, member_reg, temp2);
   1.410 +      }
   1.411 +
   1.412 +      Register temp2_intf = temp2;
   1.413 +      __ load_heap_oop_not_null(temp2_intf, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes()), member_reg);
   1.414 +      load_klass_from_Class(_masm, temp2_intf, temp3, temp4);
   1.415 +      __ verify_klass_ptr(temp2_intf);
   1.416 +
   1.417 +      Register vtable_index = R19_method;
   1.418 +      __ ld(vtable_index, NONZERO(java_lang_invoke_MemberName::vmindex_offset_in_bytes()), member_reg);
   1.419 +      if (VerifyMethodHandles) {
   1.420 +        Label L_index_ok;
   1.421 +        __ cmpdi(CCR1, vtable_index, 0);
   1.422 +        __ bge(CCR1, L_index_ok);
   1.423 +        __ stop("invalid vtable index for MH.invokeInterface");
   1.424 +        __ BIND(L_index_ok);
   1.425 +      }
   1.426 +
   1.427 +      // given intf, index, and recv klass, dispatch to the implementation method
   1.428 +      __ lookup_interface_method(temp1_recv_klass, temp2_intf,
   1.429 +                                 // note: next two args must be the same:
   1.430 +                                 vtable_index, R19_method,
   1.431 +                                 temp3, temp4,
   1.432 +                                 L_incompatible_class_change_error);
   1.433 +      break;
   1.434 +    }
   1.435 +
   1.436 +    default:
   1.437 +      fatal(err_msg_res("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid)));
   1.438 +      break;
   1.439 +    }
   1.440 +
   1.441 +    // Live at this point:
   1.442 +    //   R19_method
   1.443 +    //   O5_savedSP (if interpreted)
   1.444 +
   1.445 +    // After figuring out which concrete method to call, jump into it.
   1.446 +    // Note that this works in the interpreter with no data motion.
   1.447 +    // But the compiled version will require that rcx_recv be shifted out.
   1.448 +    __ verify_method_ptr(R19_method);
   1.449 +    jump_from_method_handle(_masm, R19_method, temp1, temp2, for_compiler_entry);
   1.450 +
   1.451 +    if (iid == vmIntrinsics::_linkToInterface) {
   1.452 +      __ BIND(L_incompatible_class_change_error);
   1.453 +      __ load_const_optimized(temp1, StubRoutines::throw_IncompatibleClassChangeError_entry());
   1.454 +      __ mtctr(temp1);
   1.455 +      __ bctr();
   1.456 +    }
   1.457 +  }
   1.458 +}
   1.459 +
   1.460 +#ifndef PRODUCT
   1.461 +void trace_method_handle_stub(const char* adaptername,
   1.462 +                              oopDesc* mh,
   1.463 +                              intptr_t* entry_sp,
   1.464 +                              intptr_t* saved_regs) {
   1.465 +
   1.466 +  bool has_mh = (strstr(adaptername, "/static") == NULL &&
   1.467 +                 strstr(adaptername, "linkTo") == NULL);    // static linkers don't have MH
   1.468 +  const char* mh_reg_name = has_mh ? "R23_method_handle" : "G23";
   1.469 +  tty->print_cr("MH %s %s="INTPTR_FORMAT " sp=" INTPTR_FORMAT,
   1.470 +                adaptername, mh_reg_name, (intptr_t) mh, entry_sp);
   1.471 +
   1.472 +  if (Verbose) {
   1.473 +    tty->print_cr("Registers:");
   1.474 +    const int abi_offset = frame::abi_reg_args_size / 8;
   1.475 +    for (int i = R3->encoding(); i <= R12->encoding(); i++) {
   1.476 +      Register r = as_Register(i);
   1.477 +      int count = i - R3->encoding();
   1.478 +      // The registers are stored in reverse order on the stack (by save_volatile_gprs(R1_SP, abi_reg_args_size)).
   1.479 +      tty->print("%3s=" PTR_FORMAT, r->name(), saved_regs[abi_offset + count]);
   1.480 +      if ((count + 1) % 4 == 0) {
   1.481 +        tty->cr();
   1.482 +      } else {
   1.483 +        tty->print(", ");
   1.484 +      }
   1.485 +    }
   1.486 +    tty->cr();
   1.487 +
   1.488 +    {
   1.489 +      // dumping last frame with frame::describe
   1.490 +
   1.491 +      JavaThread* p = JavaThread::active();
   1.492 +
   1.493 +      ResourceMark rm;
   1.494 +      PRESERVE_EXCEPTION_MARK; // may not be needed by safer and unexpensive here
   1.495 +      FrameValues values;
   1.496 +
   1.497 +      // Note: We want to allow trace_method_handle from any call site.
   1.498 +      // While trace_method_handle creates a frame, it may be entered
   1.499 +      // without a PC on the stack top (e.g. not just after a call).
   1.500 +      // Walking that frame could lead to failures due to that invalid PC.
   1.501 +      // => carefully detect that frame when doing the stack walking
   1.502 +
   1.503 +      // Current C frame
   1.504 +      frame cur_frame = os::current_frame();
   1.505 +
   1.506 +      // Robust search of trace_calling_frame (independant of inlining).
   1.507 +      // Assumes saved_regs comes from a pusha in the trace_calling_frame.
   1.508 +      assert(cur_frame.sp() < saved_regs, "registers not saved on stack ?");
   1.509 +      frame trace_calling_frame = os::get_sender_for_C_frame(&cur_frame);
   1.510 +      while (trace_calling_frame.fp() < saved_regs) {
   1.511 +        trace_calling_frame = os::get_sender_for_C_frame(&trace_calling_frame);
   1.512 +      }
   1.513 +
   1.514 +      // Safely create a frame and call frame::describe.
   1.515 +      intptr_t *dump_sp = trace_calling_frame.sender_sp();
   1.516 +
   1.517 +      frame dump_frame = frame(dump_sp);
   1.518 +      dump_frame.describe(values, 1);
   1.519 +
   1.520 +      values.describe(-1, saved_regs, "raw top of stack");
   1.521 +
   1.522 +      tty->print_cr("Stack layout:");
   1.523 +      values.print(p);
   1.524 +    }
   1.525 +
   1.526 +    if (has_mh && mh->is_oop()) {
   1.527 +      mh->print();
   1.528 +      if (java_lang_invoke_MethodHandle::is_instance(mh)) {
   1.529 +        if (java_lang_invoke_MethodHandle::form_offset_in_bytes() != 0)
   1.530 +          java_lang_invoke_MethodHandle::form(mh)->print();
   1.531 +      }
   1.532 +    }
   1.533 +  }
   1.534 +}
   1.535 +
   1.536 +void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) {
   1.537 +  if (!TraceMethodHandles) return;
   1.538 +
   1.539 +  BLOCK_COMMENT("trace_method_handle {");
   1.540 +
   1.541 +  int nbytes_save = 10 * 8;             // 10 volatile gprs
   1.542 +  __ save_LR_CR(R0);
   1.543 +  __ mr(R0, R1_SP);                     // saved_sp
   1.544 +  assert(Assembler::is_simm(-nbytes_save, 16), "Overwriting R0");
   1.545 +  // Push_frame_reg_args only uses R0 if nbytes_save is wider than 16 bit.
   1.546 +  __ push_frame_reg_args(nbytes_save, R0);
   1.547 +  __ save_volatile_gprs(R1_SP, frame::abi_reg_args_size); // Except R0.
   1.548 +
   1.549 +  __ load_const(R3_ARG1, (address)adaptername);
   1.550 +  __ mr(R4_ARG2, R23_method_handle);
   1.551 +  __ mr(R5_ARG3, R0);        // saved_sp
   1.552 +  __ mr(R6_ARG4, R1_SP);
   1.553 +  __ call_VM_leaf(CAST_FROM_FN_PTR(address, trace_method_handle_stub));
   1.554 +
   1.555 +  __ restore_volatile_gprs(R1_SP, 112); // Except R0.
   1.556 +  __ pop_frame();
   1.557 +  __ restore_LR_CR(R0);
   1.558 +
   1.559 +  BLOCK_COMMENT("} trace_method_handle");
   1.560 +}
   1.561 +#endif // PRODUCT

mercurial