24
#include "precompiled.hpp"
25
#include "compiler/disassembler.hpp"
26
#include "oops/compressedKlass.hpp"
27
#include "oops/oop.inline.hpp"
28
#include "runtime/handles.inline.hpp"
29
#include "runtime/javaCalls.hpp"
30
#include "runtime/jniHandles.hpp"
31
#include "runtime/sharedRuntime.hpp"
32
#include "jvmci/jvmci.hpp"
33
#include "jvmci/jvmciEnv.hpp"
34
#include "jvmci/jvmciCodeInstaller.hpp"
35
#include "jvmci/jvmciJavaClasses.hpp"
36
#include "jvmci/jvmciCompilerToVM.hpp"
37
#include "jvmci/jvmciRuntime.hpp"
38
#include "asm/register.hpp"
39
#include "classfile/vmSymbols.hpp"
40
#include "code/vmreg.hpp"
41
#include "vmreg_x86.inline.hpp"
43
#include "gc/z/zBarrierSetAssembler.hpp"
46
jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, JVMCI_TRAPS) {
47
if (inst->is_call() || inst->is_jump()) {
48
assert(NativeCall::instruction_size == (int)NativeJump::instruction_size, "unexpected size");
49
return (pc_offset + NativeCall::instruction_size);
50
} else if (inst->is_mov_literal64()) {
52
jint offset = pc_offset + ((NativeMovConstReg*)inst)->instruction_size();
53
u_char* call = (u_char*) (_instructions->start() + offset);
54
if (call[0] == Assembler::REX_B) {
58
if (call[0] == Assembler::REX2) {
63
assert(call[0] == 0xFF, "expected call");
66
} else if (inst->is_call_reg()) {
68
return (pc_offset + ((NativeCallReg *) inst)->next_instruction_offset());
69
} else if (inst->is_cond_jump()) {
70
address pc = (address) (inst);
71
return pc_offset + (jint) (Assembler::locate_next_instruction(pc) - pc);
73
JVMCI_ERROR_0("unsupported type of instruction for call site");
77
void CodeInstaller::pd_patch_OopConstant(int pc_offset, Handle& obj, bool compressed, JVMCI_TRAPS) {
78
address pc = _instructions->start() + pc_offset;
79
jobject value = JNIHandles::make_local(obj());
82
address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand);
83
int oop_index = _oop_recorder->find_index(value);
84
_instructions->relocate(pc, oop_Relocation::spec(oop_index), Assembler::narrow_oop_operand);
85
JVMCI_event_3("relocating (narrow oop constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(operand));
87
JVMCI_ERROR("compressed oop on 32bit");
90
address operand = Assembler::locate_operand(pc, Assembler::imm_operand);
91
*((jobject*) operand) = value;
92
_instructions->relocate(pc, oop_Relocation::spec_for_immediate(), Assembler::imm_operand);
93
JVMCI_event_3("relocating (oop constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(operand));
97
void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, HotSpotCompiledCodeStream* stream, u1 tag, JVMCI_TRAPS) {
98
address pc = _instructions->start() + pc_offset;
99
if (tag == PATCH_NARROW_KLASS) {
101
address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand);
102
*((narrowKlass*) operand) = record_narrow_metadata_reference(_instructions, operand, stream, tag, JVMCI_CHECK);
103
JVMCI_event_3("relocating (narrow metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(operand));
105
JVMCI_ERROR("compressed Klass* on 32bit");
108
address operand = Assembler::locate_operand(pc, Assembler::imm_operand);
109
*((void**) operand) = record_metadata_reference(_instructions, operand, stream, tag, JVMCI_CHECK);
110
JVMCI_event_3("relocating (metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(operand));
114
void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset, JVMCI_TRAPS) {
115
address pc = _instructions->start() + pc_offset;
117
address operand = Assembler::locate_operand(pc, Assembler::disp32_operand);
118
address next_instruction = Assembler::locate_next_instruction(pc);
119
address dest = _constants->start() + data_offset;
121
long disp = dest - next_instruction;
122
assert(disp == (jint) disp, "disp doesn't fit in 32 bits");
123
*((jint*) operand) = (jint) disp;
125
_instructions->relocate(pc, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand);
126
JVMCI_event_3("relocating at " PTR_FORMAT "/" PTR_FORMAT " with destination at " PTR_FORMAT " (%d)", p2i(pc), p2i(operand), p2i(dest), data_offset);
129
void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination, JVMCI_TRAPS) {
130
address pc = (address) inst;
131
if (inst->is_call()) {
134
NativeCall* call = nativeCall_at(pc);
135
call->set_destination((address) foreign_call_destination);
136
_instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand);
137
} else if (inst->is_mov_literal64()) {
138
NativeMovConstReg* mov = nativeMovConstReg_at(pc);
139
mov->set_data((intptr_t) foreign_call_destination);
140
_instructions->relocate(mov->instruction_address(), runtime_call_Relocation::spec(), Assembler::imm_operand);
141
} else if (inst->is_jump()) {
142
NativeJump* jump = nativeJump_at(pc);
143
jump->set_jump_destination((address) foreign_call_destination);
144
_instructions->relocate(jump->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand);
145
} else if (inst->is_cond_jump()) {
146
address old_dest = nativeGeneralJump_at(pc)->jump_destination();
147
address disp = Assembler::locate_operand(pc, Assembler::call32_operand);
148
*(jint*) disp += ((address) foreign_call_destination) - old_dest;
149
_instructions->relocate(pc, runtime_call_Relocation::spec(), Assembler::call32_operand);
151
JVMCI_ERROR("unsupported relocation for foreign call");
154
JVMCI_event_3("relocating (foreign call) at " PTR_FORMAT, p2i(inst));
157
void CodeInstaller::pd_relocate_JavaMethod(CodeBuffer &, methodHandle& method, jint pc_offset, JVMCI_TRAPS) {
158
NativeCall* call = nullptr;
159
switch (_next_call_type) {
163
case INVOKEINTERFACE: {
164
assert(!method->is_static(), "cannot call static method with invokeinterface");
166
call = nativeCall_at(_instructions->start() + pc_offset);
167
call->set_destination(SharedRuntime::get_resolve_virtual_call_stub());
168
_instructions->relocate(call->instruction_address(),
169
virtual_call_Relocation::spec(_invoke_mark_pc),
170
Assembler::call32_operand);
174
assert(method->is_static(), "cannot call non-static method with invokestatic");
176
call = nativeCall_at(_instructions->start() + pc_offset);
177
call->set_destination(SharedRuntime::get_resolve_static_call_stub());
178
_instructions->relocate(call->instruction_address(),
179
relocInfo::static_call_type, Assembler::call32_operand);
182
case INVOKESPECIAL: {
183
assert(!method->is_static(), "cannot call static method with invokespecial");
184
call = nativeCall_at(_instructions->start() + pc_offset);
185
call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub());
186
_instructions->relocate(call->instruction_address(),
187
relocInfo::opt_virtual_call_type, Assembler::call32_operand);
191
JVMCI_ERROR("invalid _next_call_type value: %d", _next_call_type);
194
if (!call->is_displacement_aligned()) {
195
JVMCI_ERROR("unaligned displacement for call at offset %d", pc_offset);
197
if (Continuations::enabled()) {
199
NativePostCallNop* nop = nativePostCallNop_at(call->next_instruction_address());
200
if (nop == nullptr) {
201
JVMCI_ERROR("missing post call nop at offset %d", pc_offset);
203
_instructions->relocate(call->next_instruction_address(), relocInfo::post_call_nop_type);
208
bool CodeInstaller::pd_relocate(address pc, jint mark) {
216
_instructions->relocate(pc, relocInfo::poll_type, Assembler::imm_operand);
218
case POLL_RETURN_NEAR:
219
case POLL_RETURN_FAR:
221
_instructions->relocate(pc, relocInfo::poll_return_type, Assembler::imm_operand);
224
case Z_BARRIER_RELOCATION_FORMAT_LOAD_GOOD_BEFORE_SHL:
225
_instructions->relocate(pc, barrier_Relocation::spec(), ZBarrierRelocationFormatLoadGoodBeforeShl);
227
case Z_BARRIER_RELOCATION_FORMAT_LOAD_BAD_AFTER_TEST:
228
_instructions->relocate(pc, barrier_Relocation::spec(), ZBarrierRelocationFormatLoadBadAfterTest);
230
case Z_BARRIER_RELOCATION_FORMAT_MARK_BAD_AFTER_TEST:
231
_instructions->relocate(pc, barrier_Relocation::spec(), ZBarrierRelocationFormatMarkBadAfterTest);
233
case Z_BARRIER_RELOCATION_FORMAT_STORE_GOOD_AFTER_CMP:
234
_instructions->relocate(pc, barrier_Relocation::spec(), ZBarrierRelocationFormatStoreGoodAfterCmp);
236
case Z_BARRIER_RELOCATION_FORMAT_STORE_BAD_AFTER_TEST:
237
_instructions->relocate(pc, barrier_Relocation::spec(), ZBarrierRelocationFormatStoreBadAfterTest);
239
case Z_BARRIER_RELOCATION_FORMAT_STORE_GOOD_AFTER_OR:
240
_instructions->relocate(pc, barrier_Relocation::spec(), ZBarrierRelocationFormatStoreGoodAfterOr);
242
case Z_BARRIER_RELOCATION_FORMAT_STORE_GOOD_AFTER_MOV:
243
_instructions->relocate(pc, barrier_Relocation::spec(), ZBarrierRelocationFormatStoreGoodAfterMov);
252
VMReg CodeInstaller::get_hotspot_reg(jint jvmci_reg, JVMCI_TRAPS) {
253
if (jvmci_reg < Register::number_of_registers) {
254
return as_Register(jvmci_reg)->as_VMReg();
256
jint floatRegisterNumber = jvmci_reg - Register::number_of_registers;
257
if (floatRegisterNumber < XMMRegister::number_of_registers) {
258
return as_XMMRegister(floatRegisterNumber)->as_VMReg();
260
JVMCI_ERROR_NULL("invalid register number: %d", jvmci_reg);
264
bool CodeInstaller::is_general_purpose_reg(VMReg hotspotRegister) {
265
return !(hotspotRegister->is_FloatRegister() || hotspotRegister->is_XMMRegister());