void InlineCacheBuffer::assemble_ic_buffer_code(address code_begin, void* cached_value, address entry_point) { ResourceMark rm; CodeBuffer code(code_begin, ic_stub_code_size()); MacroAssembler* masm = new MacroAssembler(&code); // note: even though the code contains an embedded value, we do not need reloc info // because // (1) the value is old (i.e., doesn't matter for scavenges) // (2) these ICStubs are removed *before* a GC happens, so the roots disappear // assert(cached_value == NULL || cached_oop->is_perm(), "must be perm oop"); masm->lea(rax, AddressLiteral((address) cached_value, relocInfo::metadata_type)); masm->jump(ExternalAddress(entry_point)); }
void NativeFarCall::set_destination(address dest) { // Address materialized in the instruction stream, so nothing to do. return; #if 0 // What we'd do if we really did want to change the destination if (destination() == dest) { return; } ResourceMark rm; CodeBuffer buf(addr_at(0), instruction_size + 1); MacroAssembler* _masm = new MacroAssembler(&buf); // Generate the new sequence AddressLiteral(dest); _masm->jumpl_to(dest, O7, O7); ICache::invalidate_range(addr_at(0), instruction_size ); #endif }
// Code generation address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* _masm) { // I5_savedSP: sender SP (must preserve) // G4 (Gargs): incoming argument list (must preserve) // G5_method: invoke methodOop; becomes method type. // G3_method_handle: receiver method handle (must load from sp[MethodTypeForm.vmslots]) // O0, O1: garbage temps, blown away Register O0_argslot = O0; Register O1_scratch = O1; // emit WrongMethodType path first, to enable back-branch from main path Label wrong_method_type; __ bind(wrong_method_type); __ jump_to(AddressLiteral(Interpreter::throw_WrongMethodType_entry()), O1_scratch); __ delayed()->nop(); // here's where control starts out: __ align(CodeEntryAlignment); address entry_point = __ pc(); // fetch the MethodType from the method handle into G5_method_type { Register tem = G5_method; assert(tem == G5_method_type, "yes, it's the same register"); for (jint* pchase = methodOopDesc::method_type_offsets_chain(); (*pchase) != -1; pchase++) { __ ld_ptr(Address(tem, *pchase), G5_method_type); } } // given the MethodType, find out where the MH argument is buried __ ld_ptr(Address(G5_method_type, __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, O1_scratch)), O0_argslot); __ ldsw( Address(O0_argslot, __ delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, O1_scratch)), O0_argslot); __ ld_ptr(__ argument_address(O0_argslot), G3_method_handle); __ check_method_handle_type(G5_method_type, G3_method_handle, O1_scratch, wrong_method_type); __ jump_to_method_handle_entry(G3_method_handle, O1_scratch); return entry_point; }
void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) { Label ic_miss, ic_hit; verify_oop(receiver); int klass_offset = oopDesc::klass_offset_in_bytes(); if (!ImplicitNullChecks || MacroAssembler::needs_explicit_null_check(klass_offset)) { if (VM_Version::has_CompareBranch()) { z_cgij(receiver, 0, Assembler::bcondEqual, ic_miss); } else { z_ltgr(receiver, receiver); z_bre(ic_miss); } } compare_klass_ptr(iCache, klass_offset, receiver, false); z_bre(ic_hit); // If icache check fails, then jump to runtime routine. // Note: RECEIVER must still contain the receiver! load_const_optimized(Z_R1_scratch, AddressLiteral(SharedRuntime::get_ic_miss_stub())); z_br(Z_R1_scratch); align(CodeEntryAlignment); bind(ic_hit); }