void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination, TRAPS) { address pc = (address) inst; if (inst->is_call()) { // NOTE: for call without a mov, the offset must fit a 32-bit immediate // see also CompilerToVM.getMaxCallTargetOffset() NativeCall* call = nativeCall_at(pc); call->set_destination((address) foreign_call_destination); _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand); } else if (inst->is_mov_literal64()) { NativeMovConstReg* mov = nativeMovConstReg_at(pc); mov->set_data((intptr_t) foreign_call_destination); _instructions->relocate(mov->instruction_address(), runtime_call_Relocation::spec(), Assembler::imm_operand); } else if (inst->is_jump()) { NativeJump* jump = nativeJump_at(pc); jump->set_jump_destination((address) foreign_call_destination); _instructions->relocate(jump->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand); } else if (inst->is_cond_jump()) { address old_dest = nativeGeneralJump_at(pc)->jump_destination(); address disp = Assembler::locate_operand(pc, Assembler::call32_operand); *(jint*) disp += ((address) foreign_call_destination) - old_dest; _instructions->relocate(pc, runtime_call_Relocation::spec(), Assembler::call32_operand); } else { JVMCI_ERROR("unsupported relocation for foreign call"); } TRACE_jvmci_3("relocating (foreign call) at " PTR_FORMAT, p2i(inst)); }
oop InlineCacheBuffer::ic_buffer_cached_oop(address code_begin) { // creation also verifies the object NativeMovConstReg* move = nativeMovConstReg_at(code_begin); // Verifies the jump NativeJump* jump = nativeJump_at(move->next_instruction_address()); return (oop)move->data(); }
// Release the CompiledICHolder* associated with this call site is there is one. void CompiledIC::cleanup_call_site(virtual_call_Relocation* call_site) { // This call site might have become stale so inspect it carefully. NativeCall* call = nativeCall_at(call_site->addr()); if (is_icholder_entry(call->destination())) { NativeMovConstReg* value = nativeMovConstReg_at(call_site->cached_value()); InlineCacheBuffer::queue_for_release((CompiledICHolder*)value->data()); } }
void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, Handle constant, TRAPS) { address pc = _instructions->start() + pc_offset; if (HotSpotMetaspaceConstantImpl::compressed(constant)) { #ifdef _LP64 NativeMovConstReg32* move = nativeMovConstReg32_at(pc); narrowKlass narrowOop = record_narrow_metadata_reference(constant, CHECK); move->set_data((intptr_t)narrowOop); TRACE_jvmci_3("relocating (narrow metaspace constant) at %p/%p", pc, narrowOop); #else JVMCI_ERROR("compressed Klass* on 32bit"); #endif } else { NativeMovConstReg* move = nativeMovConstReg_at(pc); Metadata* reference = record_metadata_reference(constant, CHECK); move->set_data((intptr_t)reference); TRACE_jvmci_3("relocating (metaspace constant) at %p/%p", pc, reference); } }
void CodeInstaller::pd_patch_OopConstant(int pc_offset, Handle constant, TRAPS) { address pc = _instructions->start() + pc_offset; Handle obj = HotSpotObjectConstantImpl::object(constant); jobject value = JNIHandles::make_local(obj()); if (HotSpotObjectConstantImpl::compressed(constant)) { #ifdef _LP64 int oop_index = _oop_recorder->find_index(value); RelocationHolder rspec = oop_Relocation::spec(oop_index); _instructions->relocate(pc, rspec, 1); #else JVMCI_ERROR("compressed oop on 32bit"); #endif } else { NativeMovConstReg* move = nativeMovConstReg_at(pc); move->set_data((intptr_t) value); // We need two relocations: one on the sethi and one on the add. int oop_index = _oop_recorder->find_index(value); RelocationHolder rspec = oop_Relocation::spec(oop_index); _instructions->relocate(pc + NativeMovConstReg::sethi_offset, rspec); _instructions->relocate(pc + NativeMovConstReg::add_offset, rspec); } }
// Code for unit testing implementation of NativeMovConstReg class void NativeMovConstReg::test() { #ifdef ASSERT ResourceMark rm; CodeBuffer cb("test", 100, 100); MacroAssembler* a = new MacroAssembler(&cb); NativeMovConstReg* nm; uint idx; int offsets[] = { 0x0, 0x7fffffff, 0x80000000, 0xffffffff, 0x20, 4096, 4097, }; VM_Version::allow_all(); AddressLiteral al1(0xaaaabbbb, relocInfo::external_word_type); a->sethi(al1, I3); a->add(I3, al1.low10(), I3); AddressLiteral al2(0xccccdddd, relocInfo::external_word_type); a->sethi(al2, O2); a->add(O2, al2.low10(), O2); nm = nativeMovConstReg_at( cb.insts_begin() ); nm->print(); nm = nativeMovConstReg_at( nm->next_instruction_address() ); for (idx = 0; idx < ARRAY_SIZE(offsets); idx++) { nm->set_data( offsets[idx] ); assert(nm->data() == offsets[idx], "check unit test"); } nm->print(); VM_Version::revert(); #endif }
address InlineCacheBuffer::ic_buffer_entry_point(address code_begin) { NativeMovConstReg* move = nativeMovConstReg_at(code_begin); // creation also verifies the object NativeJump* jump = nativeJump_at(move->next_instruction_address()); return jump->jump_destination(); }
void* InlineCacheBuffer::ic_buffer_cached_value(address code_begin) { NativeMovConstReg* move = nativeMovConstReg_at(code_begin); // creation also verifies the object NativeJump* jump = nativeJump_at(move->next_instruction_address()); void* o = (void*)move->data(); return o; }
void* InlineCacheBuffer::ic_buffer_cached_value(address code_begin) { NativeMovConstReg* move = nativeMovConstReg_at(code_begin); return (void*)move->data(); }
inline void CodeInstaller::pd_site_DataPatch(int pc_offset, oop site) { oop constant = CompilationResult_DataPatch::constant(site); int alignment = CompilationResult_DataPatch::alignment(site); bool inlined = CompilationResult_DataPatch::inlined(site) == JNI_TRUE; oop kind = Constant::kind(constant); char typeChar = Kind::typeChar(kind); address pc = _instructions->start() + pc_offset; switch (typeChar) { case 'z': case 'b': case 's': case 'c': case 'i': fatal("int-sized values not expected in DataPatch"); break; case 'f': case 'j': case 'd': { if (inlined) { NativeMovConstReg* move = nativeMovConstReg_at(pc); uint64_t value = Constant::primitive(constant); move->set_data(value); } else { int size = _constants->size(); if (alignment > 0) { guarantee(alignment <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin"); size = align_size_up(size, alignment); } // we don't care if this is a long/double/etc., the primitive field contains the right bits address dest = _constants->start() + size; _constants->set_end(dest); uint64_t value = Constant::primitive(constant); _constants->emit_int64(value); NativeMovRegMem* load = nativeMovRegMem_at(pc); int disp = _constants_size + pc_offset - size - BytesPerInstWord; load->set_offset(-disp); } break; } case 'a': { int size = _constants->size(); if (alignment > 0) { guarantee(alignment <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin"); size = align_size_up(size, alignment); } address dest = _constants->start() + size; _constants->set_end(dest); Handle obj = Constant::object(constant); jobject value = JNIHandles::make_local(obj()); _constants->emit_address((address) value); NativeMovRegMem* load = nativeMovRegMem_at(pc); int disp = _constants_size + pc_offset - size - BytesPerInstWord; load->set_offset(-disp); int oop_index = _oop_recorder->find_index(value); _constants->relocate(dest, oop_Relocation::spec(oop_index)); break; } default: fatal(err_msg("unexpected Kind (%d) in DataPatch", typeChar)); break; } }