annotate src/hotspot/cpu/x86/relocInfo_x86.cpp @ 55984:3a3e4e473622

8222637: Obsolete NeedsDeoptSuspend Reviewed-by: dlong, coleenp, dholmes
author rehn
date Fri, 26 Apr 2019 10:18:47 +0200
parents 0ce0ac68ace7
children f8d182aedc92
rev   line source
duke@1 1 /*
rehn@48069 2 * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
duke@1 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@1 4 *
duke@1 5 * This code is free software; you can redistribute it and/or modify it
duke@1 6 * under the terms of the GNU General Public License version 2 only, as
duke@1 7 * published by the Free Software Foundation.
duke@1 8 *
duke@1 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@1 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@1 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@1 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@1 13 * accompanied this code).
duke@1 14 *
duke@1 15 * You should have received a copy of the GNU General Public License version
duke@1 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@1 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@1 18 *
trims@5547 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@5547 20 * or visit www.oracle.com if you need additional information or have any
trims@5547 21 * questions.
duke@1 22 *
duke@1 23 */
duke@1 24
stefank@7397 25 #include "precompiled.hpp"
twisti@14626 26 #include "asm/macroAssembler.hpp"
stefank@7397 27 #include "code/relocInfo.hpp"
stefank@7397 28 #include "nativeInst_x86.hpp"
stefank@50087 29 #include "oops/compressedOops.inline.hpp"
tschatzl@31849 30 #include "oops/klass.inline.hpp"
stefank@7397 31 #include "oops/oop.inline.hpp"
stefank@7397 32 #include "runtime/safepoint.hpp"
rehn@48069 33 #include "runtime/safepointMechanism.hpp"
duke@1 34
duke@1 35
never@8724 36 void Relocation::pd_set_data_value(address x, intptr_t o, bool verify_only) {
duke@1 37 #ifdef AMD64
duke@1 38 x += o;
duke@1 39 typedef Assembler::WhichOperand WhichOperand;
never@1066 40 WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm, call32, narrow oop
duke@1 41 assert(which == Assembler::disp32_operand ||
kvn@590 42 which == Assembler::narrow_oop_operand ||
never@1066 43 which == Assembler::imm_operand, "format unpacks ok");
never@1066 44 if (which == Assembler::imm_operand) {
never@8724 45 if (verify_only) {
stefank@33807 46 guarantee(*pd_address_in_code() == x, "instructions must match");
never@8724 47 } else {
never@8724 48 *pd_address_in_code() = x;
never@8724 49 }
kvn@590 50 } else if (which == Assembler::narrow_oop_operand) {
kvn@590 51 address disp = Assembler::locate_operand(addr(), which);
coleenp@13728 52 // both compressed oops and compressed classes look the same
coleenp@13728 53 if (Universe::heap()->is_in_reserved((oop)x)) {
never@8724 54 if (verify_only) {
stefank@50087 55 guarantee(*(uint32_t*) disp == CompressedOops::encode((oop)x), "instructions must match");
never@8724 56 } else {
stefank@50087 57 *(int32_t*) disp = CompressedOops::encode((oop)x);
never@8724 58 }
duke@1 59 } else {
coleenp@13728 60 if (verify_only) {
stefank@33807 61 guarantee(*(uint32_t*) disp == Klass::encode_klass((Klass*)x), "instructions must match");
coleenp@13728 62 } else {
hseigel@19319 63 *(int32_t*) disp = Klass::encode_klass((Klass*)x);
coleenp@13728 64 }
coleenp@13728 65 }
coleenp@13728 66 } else {
duke@1 67 // Note: Use runtime_call_type relocations for call32_operand.
duke@1 68 address ip = addr();
duke@1 69 address disp = Assembler::locate_operand(ip, which);
duke@1 70 address next_ip = Assembler::locate_next_instruction(ip);
never@8724 71 if (verify_only) {
stefank@33807 72 guarantee(*(int32_t*) disp == (x - next_ip), "instructions must match");
never@8724 73 } else {
never@8724 74 *(int32_t*) disp = x - next_ip;
never@8724 75 }
duke@1 76 }
duke@1 77 #else
never@8724 78 if (verify_only) {
stefank@33807 79 guarantee(*pd_address_in_code() == (x + o), "instructions must match");
never@8724 80 } else {
never@8724 81 *pd_address_in_code() = x + o;
never@8724 82 }
duke@1 83 #endif // AMD64
duke@1 84 }
duke@1 85
duke@1 86
duke@1 87 address Relocation::pd_call_destination(address orig_addr) {
duke@1 88 intptr_t adj = 0;
duke@1 89 if (orig_addr != NULL) {
duke@1 90 // We just moved this call instruction from orig_addr to addr().
duke@1 91 // This means its target will appear to have grown by addr() - orig_addr.
duke@1 92 adj = -( addr() - orig_addr );
duke@1 93 }
duke@1 94 NativeInstruction* ni = nativeInstruction_at(addr());
duke@1 95 if (ni->is_call()) {
duke@1 96 return nativeCall_at(addr())->destination() + adj;
duke@1 97 } else if (ni->is_jump()) {
duke@1 98 return nativeJump_at(addr())->jump_destination() + adj;
duke@1 99 } else if (ni->is_cond_jump()) {
duke@1 100 return nativeGeneralJump_at(addr())->jump_destination() + adj;
duke@1 101 } else if (ni->is_mov_literal64()) {
duke@1 102 return (address) ((NativeMovConstReg*)ni)->data();
duke@1 103 } else {
duke@1 104 ShouldNotReachHere();
duke@1 105 return NULL;
duke@1 106 }
duke@1 107 }
duke@1 108
duke@1 109
duke@1 110 void Relocation::pd_set_call_destination(address x) {
duke@1 111 NativeInstruction* ni = nativeInstruction_at(addr());
duke@1 112 if (ni->is_call()) {
duke@1 113 nativeCall_at(addr())->set_destination(x);
duke@1 114 } else if (ni->is_jump()) {
duke@1 115 NativeJump* nj = nativeJump_at(addr());
never@1066 116
never@1066 117 // Unresolved jumps are recognized by a destination of -1
never@1066 118 // However 64bit can't actually produce such an address
never@1066 119 // and encodes a jump to self but jump_destination will
never@1066 120 // return a -1 as the signal. We must not relocate this
never@1066 121 // jmp or the ic code will not see it as unresolved.
never@1066 122
duke@1 123 if (nj->jump_destination() == (address) -1) {
never@1066 124 x = addr(); // jump to self
duke@1 125 }
duke@1 126 nj->set_jump_destination(x);
duke@1 127 } else if (ni->is_cond_jump()) {
duke@1 128 // %%%% kludge this, for now, until we get a jump_destination method
duke@1 129 address old_dest = nativeGeneralJump_at(addr())->jump_destination();
duke@1 130 address disp = Assembler::locate_operand(addr(), Assembler::call32_operand);
duke@1 131 *(jint*)disp += (x - old_dest);
duke@1 132 } else if (ni->is_mov_literal64()) {
duke@1 133 ((NativeMovConstReg*)ni)->set_data((intptr_t)x);
duke@1 134 } else {
duke@1 135 ShouldNotReachHere();
duke@1 136 }
duke@1 137 }
duke@1 138
duke@1 139
duke@1 140 address* Relocation::pd_address_in_code() {
duke@1 141 // All embedded Intel addresses are stored in 32-bit words.
duke@1 142 // Since the addr points at the start of the instruction,
duke@1 143 // we must parse the instruction a bit to find the embedded word.
duke@1 144 assert(is_data(), "must be a DataRelocation");
duke@1 145 typedef Assembler::WhichOperand WhichOperand;
never@1066 146 WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm/imm32
duke@1 147 #ifdef AMD64
duke@1 148 assert(which == Assembler::disp32_operand ||
duke@1 149 which == Assembler::call32_operand ||
never@1066 150 which == Assembler::imm_operand, "format unpacks ok");
morris@16382 151 // The "address" in the code is a displacement can't return it as
morris@16382 152 // and address* since it is really a jint*
morris@16382 153 guarantee(which == Assembler::imm_operand, "must be immediate operand");
duke@1 154 #else
never@1066 155 assert(which == Assembler::disp32_operand || which == Assembler::imm_operand, "format unpacks ok");
duke@1 156 #endif // AMD64
duke@1 157 return (address*) Assembler::locate_operand(addr(), which);
duke@1 158 }
duke@1 159
duke@1 160
duke@1 161 address Relocation::pd_get_address_from_code() {
duke@1 162 #ifdef AMD64
duke@1 163 // All embedded Intel addresses are stored in 32-bit words.
duke@1 164 // Since the addr points at the start of the instruction,
duke@1 165 // we must parse the instruction a bit to find the embedded word.
duke@1 166 assert(is_data(), "must be a DataRelocation");
duke@1 167 typedef Assembler::WhichOperand WhichOperand;
never@1066 168 WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm/imm32
duke@1 169 assert(which == Assembler::disp32_operand ||
duke@1 170 which == Assembler::call32_operand ||
never@1066 171 which == Assembler::imm_operand, "format unpacks ok");
never@1066 172 if (which != Assembler::imm_operand) {
duke@1 173 address ip = addr();
duke@1 174 address disp = Assembler::locate_operand(ip, which);
duke@1 175 address next_ip = Assembler::locate_next_instruction(ip);
duke@1 176 address a = next_ip + *(int32_t*) disp;
duke@1 177 return a;
duke@1 178 }
duke@1 179 #endif // AMD64
duke@1 180 return *pd_address_in_code();
duke@1 181 }
duke@1 182
never@1066 183 void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
never@1066 184 #ifdef _LP64
twisti@33160 185 typedef Assembler::WhichOperand WhichOperand;
twisti@33160 186 WhichOperand which = (WhichOperand) format();
twisti@33160 187 #if !INCLUDE_JVMCI
rehn@48069 188 if (SafepointMechanism::uses_global_page_poll()) {
rehn@48069 189 assert((which == Assembler::disp32_operand) == !Assembler::is_polling_page_far(), "format not set correctly");
rehn@48069 190 }
twisti@33160 191 #endif
twisti@33160 192 if (which == Assembler::disp32_operand) {
rehn@48069 193 assert(SafepointMechanism::uses_global_page_poll(), "should only have generated such a poll if global polling enabled");
iveresov@8871 194 address orig_addr = old_addr_for(addr(), src, dest);
iveresov@8871 195 NativeInstruction* oni = nativeInstruction_at(orig_addr);
iveresov@8871 196 int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which);
iveresov@8871 197 // This poll_addr is incorrect by the size of the instruction it is irrelevant
iveresov@8871 198 intptr_t poll_addr = (intptr_t)oni + *orig_disp;
iveresov@8871 199 NativeInstruction* ni = nativeInstruction_at(addr());
iveresov@8871 200 intptr_t new_disp = poll_addr - (intptr_t) ni;
never@1066 201
iveresov@8871 202 int32_t* disp = (int32_t*) Assembler::locate_operand(addr(), which);
iveresov@8871 203 * disp = (int32_t)new_disp;
iveresov@8871 204 }
never@1066 205 #endif // _LP64
never@1066 206 }
coleenp@13728 207
coleenp@13728 208 void metadata_Relocation::pd_fix_value(address x) {
coleenp@13728 209 }