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 }
|