39 #define BLOCK_COMMENT(str) __ block_comment(str)
40 #define STOP(error) block_comment(error); __ stop(error)
41 #endif
42
43 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
44
45 // Workaround for C++ overloading nastiness on '0' for RegisterOrConstant.
46 static RegisterOrConstant constant(int value) {
47 return RegisterOrConstant(value);
48 }
49
50 void MethodHandles::load_klass_from_Class(MacroAssembler* _masm, Register klass_reg, Register temp_reg, Register temp2_reg) {
51 if (VerifyMethodHandles)
52 verify_klass(_masm, klass_reg, SystemDictionary::WK_KLASS_ENUM_NAME(java_lang_Class), temp_reg, temp2_reg,
53 "MH argument is a Class");
54 __ ld_ptr(Address(klass_reg, java_lang_Class::klass_offset_in_bytes()), klass_reg);
55 }
56
57 #ifdef ASSERT
58 static int check_nonzero(const char* xname, int x) {
59 assert(x != 0, err_msg("%s should be nonzero", xname));
60 return x;
61 }
62 #define NONZERO(x) check_nonzero(#x, x)
63 #else //ASSERT
64 #define NONZERO(x) (x)
65 #endif //ASSERT
66
67 #ifdef ASSERT
68 void MethodHandles::verify_klass(MacroAssembler* _masm,
69 Register obj_reg, SystemDictionary::WKID klass_id,
70 Register temp_reg, Register temp2_reg,
71 const char* error_message) {
72 Klass** klass_addr = SystemDictionary::well_known_klass_addr(klass_id);
73 KlassHandle klass = SystemDictionary::well_known_klass(klass_id);
74 bool did_save = false;
75 if (temp_reg == noreg || temp2_reg == noreg) {
76 temp_reg = L1;
77 temp2_reg = L2;
78 __ save_frame_and_mov(0, obj_reg, L0);
79 obj_reg = L0;
436
437 Register G5_index = G5_method;
438 __ ld_ptr(member_vmindex, G5_index);
439 if (VerifyMethodHandles) {
440 Label L;
441 __ cmp_and_br_short(G5_index, 0, Assembler::greaterEqual, Assembler::pt, L);
442 __ STOP("invalid vtable index for MH.invokeInterface");
443 __ bind(L);
444 }
445
446 // given intf, index, and recv klass, dispatch to the implementation method
447 __ lookup_interface_method(temp1_recv_klass, temp2_intf,
448 // note: next two args must be the same:
449 G5_index, G5_method,
450 temp3, temp4,
451 L_incompatible_class_change_error);
452 break;
453 }
454
455 default:
456 fatal(err_msg_res("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid)));
457 break;
458 }
459
460 // Live at this point:
461 // G5_method
462 // O5_savedSP (if interpreted)
463
464 // After figuring out which concrete method to call, jump into it.
465 // Note that this works in the interpreter with no data motion.
466 // But the compiled version will require that rcx_recv be shifted out.
467 __ verify_method_ptr(G5_method);
468 jump_from_method_handle(_masm, G5_method, temp1, temp2, for_compiler_entry);
469
470 if (iid == vmIntrinsics::_linkToInterface) {
471 __ BIND(L_incompatible_class_change_error);
472 AddressLiteral icce(StubRoutines::throw_IncompatibleClassChangeError_entry());
473 __ jump_to(icce, temp1);
474 __ delayed()->nop();
475 }
476 }
|
39 #define BLOCK_COMMENT(str) __ block_comment(str)
40 #define STOP(error) block_comment(error); __ stop(error)
41 #endif
42
43 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
44
45 // Workaround for C++ overloading nastiness on '0' for RegisterOrConstant.
46 static RegisterOrConstant constant(int value) {
47 return RegisterOrConstant(value);
48 }
49
50 void MethodHandles::load_klass_from_Class(MacroAssembler* _masm, Register klass_reg, Register temp_reg, Register temp2_reg) {
51 if (VerifyMethodHandles)
52 verify_klass(_masm, klass_reg, SystemDictionary::WK_KLASS_ENUM_NAME(java_lang_Class), temp_reg, temp2_reg,
53 "MH argument is a Class");
54 __ ld_ptr(Address(klass_reg, java_lang_Class::klass_offset_in_bytes()), klass_reg);
55 }
56
57 #ifdef ASSERT
58 static int check_nonzero(const char* xname, int x) {
59 assert(x != 0, "%s should be nonzero", xname);
60 return x;
61 }
62 #define NONZERO(x) check_nonzero(#x, x)
63 #else //ASSERT
64 #define NONZERO(x) (x)
65 #endif //ASSERT
66
67 #ifdef ASSERT
68 void MethodHandles::verify_klass(MacroAssembler* _masm,
69 Register obj_reg, SystemDictionary::WKID klass_id,
70 Register temp_reg, Register temp2_reg,
71 const char* error_message) {
72 Klass** klass_addr = SystemDictionary::well_known_klass_addr(klass_id);
73 KlassHandle klass = SystemDictionary::well_known_klass(klass_id);
74 bool did_save = false;
75 if (temp_reg == noreg || temp2_reg == noreg) {
76 temp_reg = L1;
77 temp2_reg = L2;
78 __ save_frame_and_mov(0, obj_reg, L0);
79 obj_reg = L0;
436
437 Register G5_index = G5_method;
438 __ ld_ptr(member_vmindex, G5_index);
439 if (VerifyMethodHandles) {
440 Label L;
441 __ cmp_and_br_short(G5_index, 0, Assembler::greaterEqual, Assembler::pt, L);
442 __ STOP("invalid vtable index for MH.invokeInterface");
443 __ bind(L);
444 }
445
446 // given intf, index, and recv klass, dispatch to the implementation method
447 __ lookup_interface_method(temp1_recv_klass, temp2_intf,
448 // note: next two args must be the same:
449 G5_index, G5_method,
450 temp3, temp4,
451 L_incompatible_class_change_error);
452 break;
453 }
454
455 default:
456 fatal("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid));
457 break;
458 }
459
460 // Live at this point:
461 // G5_method
462 // O5_savedSP (if interpreted)
463
464 // After figuring out which concrete method to call, jump into it.
465 // Note that this works in the interpreter with no data motion.
466 // But the compiled version will require that rcx_recv be shifted out.
467 __ verify_method_ptr(G5_method);
468 jump_from_method_handle(_masm, G5_method, temp1, temp2, for_compiler_entry);
469
470 if (iid == vmIntrinsics::_linkToInterface) {
471 __ BIND(L_incompatible_class_change_error);
472 AddressLiteral icce(StubRoutines::throw_IncompatibleClassChangeError_entry());
473 __ jump_to(icce, temp1);
474 __ delayed()->nop();
475 }
476 }
|