< prev index next >

src/cpu/ppc/vm/methodHandles_ppc.cpp

Print this page




  43 #else
  44 #define BLOCK_COMMENT(str) __ block_comment(str)
  45 #endif
  46 
  47 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
  48 
  49 // Workaround for C++ overloading nastiness on '0' for RegisterOrConstant.
  50 inline static RegisterOrConstant constant(int value) {
  51   return RegisterOrConstant(value);
  52 }
  53 
  54 void MethodHandles::load_klass_from_Class(MacroAssembler* _masm, Register klass_reg, Register temp_reg, Register temp2_reg) {
  55   if (VerifyMethodHandles)
  56     verify_klass(_masm, klass_reg, SystemDictionary::WK_KLASS_ENUM_NAME(java_lang_Class), temp_reg, temp2_reg,
  57                  "MH argument is a Class");
  58   __ ld(klass_reg, java_lang_Class::klass_offset_in_bytes(), klass_reg);
  59 }
  60 
  61 #ifdef ASSERT
  62 static int check_nonzero(const char* xname, int x) {
  63   assert(x != 0, err_msg("%s should be nonzero", xname));
  64   return x;
  65 }
  66 #define NONZERO(x) check_nonzero(#x, x)
  67 #else //ASSERT
  68 #define NONZERO(x) (x)
  69 #endif //ASSERT
  70 
  71 #ifdef ASSERT
  72 void MethodHandles::verify_klass(MacroAssembler* _masm,
  73                                  Register obj_reg, SystemDictionary::WKID klass_id,
  74                                  Register temp_reg, Register temp2_reg,
  75                                  const char* error_message) {
  76   Klass** klass_addr = SystemDictionary::well_known_klass_addr(klass_id);
  77   KlassHandle klass = SystemDictionary::well_known_klass(klass_id);
  78   Label L_ok, L_bad;
  79   BLOCK_COMMENT("verify_klass {");
  80   __ verify_oop(obj_reg);
  81   __ cmpdi(CCR0, obj_reg, 0);
  82   __ beq(CCR0, L_bad);
  83   __ load_klass(temp_reg, obj_reg);


 417       Register vtable_index = R19_method;
 418       __ ld(vtable_index, NONZERO(java_lang_invoke_MemberName::vmindex_offset_in_bytes()), member_reg);
 419       if (VerifyMethodHandles) {
 420         Label L_index_ok;
 421         __ cmpdi(CCR1, vtable_index, 0);
 422         __ bge(CCR1, L_index_ok);
 423         __ stop("invalid vtable index for MH.invokeInterface");
 424         __ BIND(L_index_ok);
 425       }
 426 
 427       // given intf, index, and recv klass, dispatch to the implementation method
 428       __ lookup_interface_method(temp1_recv_klass, temp2_intf,
 429                                  // note: next two args must be the same:
 430                                  vtable_index, R19_method,
 431                                  temp3, temp4,
 432                                  L_incompatible_class_change_error);
 433       break;
 434     }
 435 
 436     default:
 437       fatal(err_msg_res("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid)));
 438       break;
 439     }
 440 
 441     // Live at this point:
 442     //   R19_method
 443     //   O5_savedSP (if interpreted)
 444 
 445     // After figuring out which concrete method to call, jump into it.
 446     // Note that this works in the interpreter with no data motion.
 447     // But the compiled version will require that rcx_recv be shifted out.
 448     __ verify_method_ptr(R19_method);
 449     jump_from_method_handle(_masm, R19_method, temp1, temp2, for_compiler_entry);
 450 
 451     if (iid == vmIntrinsics::_linkToInterface) {
 452       __ BIND(L_incompatible_class_change_error);
 453       __ load_const_optimized(temp1, StubRoutines::throw_IncompatibleClassChangeError_entry());
 454       __ mtctr(temp1);
 455       __ bctr();
 456     }
 457   }




  43 #else
  44 #define BLOCK_COMMENT(str) __ block_comment(str)
  45 #endif
  46 
  47 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
  48 
  49 // Workaround for C++ overloading nastiness on '0' for RegisterOrConstant.
  50 inline static RegisterOrConstant constant(int value) {
  51   return RegisterOrConstant(value);
  52 }
  53 
  54 void MethodHandles::load_klass_from_Class(MacroAssembler* _masm, Register klass_reg, Register temp_reg, Register temp2_reg) {
  55   if (VerifyMethodHandles)
  56     verify_klass(_masm, klass_reg, SystemDictionary::WK_KLASS_ENUM_NAME(java_lang_Class), temp_reg, temp2_reg,
  57                  "MH argument is a Class");
  58   __ ld(klass_reg, java_lang_Class::klass_offset_in_bytes(), klass_reg);
  59 }
  60 
  61 #ifdef ASSERT
  62 static int check_nonzero(const char* xname, int x) {
  63   assert(x != 0, "%s should be nonzero", xname);
  64   return x;
  65 }
  66 #define NONZERO(x) check_nonzero(#x, x)
  67 #else //ASSERT
  68 #define NONZERO(x) (x)
  69 #endif //ASSERT
  70 
  71 #ifdef ASSERT
  72 void MethodHandles::verify_klass(MacroAssembler* _masm,
  73                                  Register obj_reg, SystemDictionary::WKID klass_id,
  74                                  Register temp_reg, Register temp2_reg,
  75                                  const char* error_message) {
  76   Klass** klass_addr = SystemDictionary::well_known_klass_addr(klass_id);
  77   KlassHandle klass = SystemDictionary::well_known_klass(klass_id);
  78   Label L_ok, L_bad;
  79   BLOCK_COMMENT("verify_klass {");
  80   __ verify_oop(obj_reg);
  81   __ cmpdi(CCR0, obj_reg, 0);
  82   __ beq(CCR0, L_bad);
  83   __ load_klass(temp_reg, obj_reg);


 417       Register vtable_index = R19_method;
 418       __ ld(vtable_index, NONZERO(java_lang_invoke_MemberName::vmindex_offset_in_bytes()), member_reg);
 419       if (VerifyMethodHandles) {
 420         Label L_index_ok;
 421         __ cmpdi(CCR1, vtable_index, 0);
 422         __ bge(CCR1, L_index_ok);
 423         __ stop("invalid vtable index for MH.invokeInterface");
 424         __ BIND(L_index_ok);
 425       }
 426 
 427       // given intf, index, and recv klass, dispatch to the implementation method
 428       __ lookup_interface_method(temp1_recv_klass, temp2_intf,
 429                                  // note: next two args must be the same:
 430                                  vtable_index, R19_method,
 431                                  temp3, temp4,
 432                                  L_incompatible_class_change_error);
 433       break;
 434     }
 435 
 436     default:
 437       fatal("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid));
 438       break;
 439     }
 440 
 441     // Live at this point:
 442     //   R19_method
 443     //   O5_savedSP (if interpreted)
 444 
 445     // After figuring out which concrete method to call, jump into it.
 446     // Note that this works in the interpreter with no data motion.
 447     // But the compiled version will require that rcx_recv be shifted out.
 448     __ verify_method_ptr(R19_method);
 449     jump_from_method_handle(_masm, R19_method, temp1, temp2, for_compiler_entry);
 450 
 451     if (iid == vmIntrinsics::_linkToInterface) {
 452       __ BIND(L_incompatible_class_change_error);
 453       __ load_const_optimized(temp1, StubRoutines::throw_IncompatibleClassChangeError_entry());
 454       __ mtctr(temp1);
 455       __ bctr();
 456     }
 457   }


< prev index next >