1 /* |
1 /* |
2 * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
35 #include "asm/register.hpp" |
35 #include "asm/register.hpp" |
36 #include "classfile/vmSymbols.hpp" |
36 #include "classfile/vmSymbols.hpp" |
37 #include "code/vmreg.hpp" |
37 #include "code/vmreg.hpp" |
38 #include "vmreg_x86.inline.hpp" |
38 #include "vmreg_x86.inline.hpp" |
39 |
39 |
40 jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, Handle method, TRAPS) { |
40 jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, JVMCIObject method, JVMCI_TRAPS) { |
41 if (inst->is_call() || inst->is_jump()) { |
41 if (inst->is_call() || inst->is_jump()) { |
42 assert(NativeCall::instruction_size == (int)NativeJump::instruction_size, "unexpected size"); |
42 assert(NativeCall::instruction_size == (int)NativeJump::instruction_size, "unexpected size"); |
43 return (pc_offset + NativeCall::instruction_size); |
43 return (pc_offset + NativeCall::instruction_size); |
44 } else if (inst->is_mov_literal64()) { |
44 } else if (inst->is_mov_literal64()) { |
45 // mov+call instruction pair |
45 // mov+call instruction pair |
52 assert(call[0] == 0xFF, "expected call"); |
52 assert(call[0] == 0xFF, "expected call"); |
53 offset += 2; /* opcode byte + modrm byte */ |
53 offset += 2; /* opcode byte + modrm byte */ |
54 return (offset); |
54 return (offset); |
55 } else if (inst->is_call_reg()) { |
55 } else if (inst->is_call_reg()) { |
56 // the inlined vtable stub contains a "call register" instruction |
56 // the inlined vtable stub contains a "call register" instruction |
57 assert(method.not_null(), "only valid for virtual calls"); |
57 assert(method.is_non_null(), "only valid for virtual calls"); |
58 return (pc_offset + ((NativeCallReg *) inst)->next_instruction_offset()); |
58 return (pc_offset + ((NativeCallReg *) inst)->next_instruction_offset()); |
59 } else if (inst->is_cond_jump()) { |
59 } else if (inst->is_cond_jump()) { |
60 address pc = (address) (inst); |
60 address pc = (address) (inst); |
61 return pc_offset + (jint) (Assembler::locate_next_instruction(pc) - pc); |
61 return pc_offset + (jint) (Assembler::locate_next_instruction(pc) - pc); |
62 } else { |
62 } else { |
63 JVMCI_ERROR_0("unsupported type of instruction for call site"); |
63 JVMCI_ERROR_0("unsupported type of instruction for call site"); |
64 } |
64 } |
65 } |
65 } |
66 |
66 |
67 void CodeInstaller::pd_patch_OopConstant(int pc_offset, Handle constant, TRAPS) { |
67 void CodeInstaller::pd_patch_OopConstant(int pc_offset, JVMCIObject constant, JVMCI_TRAPS) { |
68 address pc = _instructions->start() + pc_offset; |
68 address pc = _instructions->start() + pc_offset; |
69 Handle obj(THREAD, HotSpotObjectConstantImpl::object(constant)); |
69 Handle obj = jvmci_env()->asConstant(constant, JVMCI_CHECK); |
|
70 Thread* THREAD = Thread::current(); |
70 jobject value = JNIHandles::make_local(obj()); |
71 jobject value = JNIHandles::make_local(obj()); |
71 if (HotSpotObjectConstantImpl::compressed(constant)) { |
72 if (jvmci_env()->get_HotSpotObjectConstantImpl_compressed(constant)) { |
72 #ifdef _LP64 |
73 #ifdef _LP64 |
73 address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand); |
74 address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand); |
74 int oop_index = _oop_recorder->find_index(value); |
75 int oop_index = _oop_recorder->find_index(value); |
75 _instructions->relocate(pc, oop_Relocation::spec(oop_index), Assembler::narrow_oop_operand); |
76 _instructions->relocate(pc, oop_Relocation::spec(oop_index), Assembler::narrow_oop_operand); |
76 TRACE_jvmci_3("relocating (narrow oop constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(operand)); |
77 TRACE_jvmci_3("relocating (narrow oop constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(operand)); |
83 _instructions->relocate(pc, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); |
84 _instructions->relocate(pc, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); |
84 TRACE_jvmci_3("relocating (oop constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(operand)); |
85 TRACE_jvmci_3("relocating (oop constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(operand)); |
85 } |
86 } |
86 } |
87 } |
87 |
88 |
88 void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, Handle constant, TRAPS) { |
89 void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, JVMCIObject constant, JVMCI_TRAPS) { |
89 address pc = _instructions->start() + pc_offset; |
90 address pc = _instructions->start() + pc_offset; |
90 if (HotSpotMetaspaceConstantImpl::compressed(constant)) { |
91 if (jvmci_env()->get_HotSpotMetaspaceConstantImpl_compressed(constant)) { |
91 #ifdef _LP64 |
92 #ifdef _LP64 |
92 address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand); |
93 address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand); |
93 *((narrowKlass*) operand) = record_narrow_metadata_reference(_instructions, operand, constant, CHECK); |
94 *((narrowKlass*) operand) = record_narrow_metadata_reference(_instructions, operand, constant, JVMCI_CHECK); |
94 TRACE_jvmci_3("relocating (narrow metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(operand)); |
95 TRACE_jvmci_3("relocating (narrow metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(operand)); |
95 #else |
96 #else |
96 JVMCI_ERROR("compressed Klass* on 32bit"); |
97 JVMCI_ERROR("compressed Klass* on 32bit"); |
97 #endif |
98 #endif |
98 } else { |
99 } else { |
99 address operand = Assembler::locate_operand(pc, Assembler::imm_operand); |
100 address operand = Assembler::locate_operand(pc, Assembler::imm_operand); |
100 *((void**) operand) = record_metadata_reference(_instructions, operand, constant, CHECK); |
101 *((void**) operand) = record_metadata_reference(_instructions, operand, constant, JVMCI_CHECK); |
101 TRACE_jvmci_3("relocating (metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(operand)); |
102 TRACE_jvmci_3("relocating (metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(operand)); |
102 } |
103 } |
103 } |
104 } |
104 |
105 |
105 void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset, TRAPS) { |
106 void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset, JVMCI_TRAPS) { |
106 address pc = _instructions->start() + pc_offset; |
107 address pc = _instructions->start() + pc_offset; |
107 |
108 |
108 address operand = Assembler::locate_operand(pc, Assembler::disp32_operand); |
109 address operand = Assembler::locate_operand(pc, Assembler::disp32_operand); |
109 address next_instruction = Assembler::locate_next_instruction(pc); |
110 address next_instruction = Assembler::locate_next_instruction(pc); |
110 address dest = _constants->start() + data_offset; |
111 address dest = _constants->start() + data_offset; |
115 |
116 |
116 _instructions->relocate(pc, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand); |
117 _instructions->relocate(pc, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand); |
117 TRACE_jvmci_3("relocating at " PTR_FORMAT "/" PTR_FORMAT " with destination at " PTR_FORMAT " (%d)", p2i(pc), p2i(operand), p2i(dest), data_offset); |
118 TRACE_jvmci_3("relocating at " PTR_FORMAT "/" PTR_FORMAT " with destination at " PTR_FORMAT " (%d)", p2i(pc), p2i(operand), p2i(dest), data_offset); |
118 } |
119 } |
119 |
120 |
120 void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination, TRAPS) { |
121 void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination, JVMCI_TRAPS) { |
121 address pc = (address) inst; |
122 address pc = (address) inst; |
122 if (inst->is_call()) { |
123 if (inst->is_call()) { |
123 // NOTE: for call without a mov, the offset must fit a 32-bit immediate |
124 // NOTE: for call without a mov, the offset must fit a 32-bit immediate |
124 // see also CompilerToVM.getMaxCallTargetOffset() |
125 // see also CompilerToVM.getMaxCallTargetOffset() |
125 NativeCall* call = nativeCall_at(pc); |
126 NativeCall* call = nativeCall_at(pc); |
143 } |
144 } |
144 |
145 |
145 TRACE_jvmci_3("relocating (foreign call) at " PTR_FORMAT, p2i(inst)); |
146 TRACE_jvmci_3("relocating (foreign call) at " PTR_FORMAT, p2i(inst)); |
146 } |
147 } |
147 |
148 |
148 void CodeInstaller::pd_relocate_JavaMethod(CodeBuffer &, Handle hotspot_method, jint pc_offset, TRAPS) { |
149 void CodeInstaller::pd_relocate_JavaMethod(CodeBuffer &, JVMCIObject hotspot_method, jint pc_offset, JVMCI_TRAPS) { |
149 #ifdef ASSERT |
150 #ifdef ASSERT |
150 Method* method = NULL; |
151 Method* method = NULL; |
151 // we need to check, this might also be an unresolved method |
152 // we need to check, this might also be an unresolved method |
152 if (hotspot_method->is_a(HotSpotResolvedJavaMethodImpl::klass())) { |
153 if (JVMCIENV->isa_HotSpotResolvedJavaMethodImpl(hotspot_method)) { |
153 method = getMethodFromHotSpotMethod(hotspot_method()); |
154 method = JVMCIENV->asMethod(hotspot_method); |
154 } |
155 } |
155 #endif |
156 #endif |
156 switch (_next_call_type) { |
157 switch (_next_call_type) { |
157 case INLINE_INVOKE: |
158 case INLINE_INVOKE: |
158 break; |
159 break; |
197 intptr_t new_disp = (intptr_t) (os::get_polling_page() + offset) - (intptr_t) ni; |
198 intptr_t new_disp = (intptr_t) (os::get_polling_page() + offset) - (intptr_t) ni; |
198 *disp = (int32_t)new_disp; |
199 *disp = (int32_t)new_disp; |
199 } |
200 } |
200 |
201 |
201 |
202 |
202 void CodeInstaller::pd_relocate_poll(address pc, jint mark, TRAPS) { |
203 void CodeInstaller::pd_relocate_poll(address pc, jint mark, JVMCI_TRAPS) { |
203 switch (mark) { |
204 switch (mark) { |
204 case POLL_NEAR: { |
205 case POLL_NEAR: { |
205 relocate_poll_near(pc); |
206 relocate_poll_near(pc); |
206 _instructions->relocate(pc, relocInfo::poll_type, Assembler::disp32_operand); |
207 _instructions->relocate(pc, relocInfo::poll_type, Assembler::disp32_operand); |
207 break; |
208 break; |
227 break; |
228 break; |
228 } |
229 } |
229 } |
230 } |
230 |
231 |
231 // convert JVMCI register indices (as used in oop maps) to HotSpot registers |
232 // convert JVMCI register indices (as used in oop maps) to HotSpot registers |
232 VMReg CodeInstaller::get_hotspot_reg(jint jvmci_reg, TRAPS) { |
233 VMReg CodeInstaller::get_hotspot_reg(jint jvmci_reg, JVMCI_TRAPS) { |
233 if (jvmci_reg < RegisterImpl::number_of_registers) { |
234 if (jvmci_reg < RegisterImpl::number_of_registers) { |
234 return as_Register(jvmci_reg)->as_VMReg(); |
235 return as_Register(jvmci_reg)->as_VMReg(); |
235 } else { |
236 } else { |
236 jint floatRegisterNumber = jvmci_reg - RegisterImpl::number_of_registers; |
237 jint floatRegisterNumber = jvmci_reg - RegisterImpl::number_of_registers; |
237 if (floatRegisterNumber < XMMRegisterImpl::number_of_registers) { |
238 if (floatRegisterNumber < XMMRegisterImpl::number_of_registers) { |