Mercurial > hg > truffle
annotate src/cpu/x86/vm/relocInfo_x86.cpp @ 3096:8073f5ad1d87
IdealGraphVisualizer: Rename predecessors to "Nodes Above" and successors to "Nodes Below" and actions "Expand Predecessors" and "Expand Successors" to "Expand Above" and "Expand Below" to avoid ambiguity with the Graal concept of successors and predecessors
author | Peter Hofer <peter.hofer@jku.at> |
---|---|
date | Wed, 29 Jun 2011 18:27:14 +0200 |
parents | b40d4fa697bf |
children | da91efe96a93 |
rev | line source |
---|---|
0 | 1 /* |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
2 * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
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 | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
304
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
304
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
304
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "asm/assembler.inline.hpp" | |
27 #include "assembler_x86.inline.hpp" | |
28 #include "code/relocInfo.hpp" | |
29 #include "nativeInst_x86.hpp" | |
30 #include "oops/oop.inline.hpp" | |
31 #include "runtime/safepoint.hpp" | |
0 | 32 |
33 | |
2375
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
1972
diff
changeset
|
34 void Relocation::pd_set_data_value(address x, intptr_t o, bool verify_only) { |
0 | 35 #ifdef AMD64 |
36 x += o; | |
37 typedef Assembler::WhichOperand WhichOperand; | |
304 | 38 WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm, call32, narrow oop |
0 | 39 assert(which == Assembler::disp32_operand || |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
0
diff
changeset
|
40 which == Assembler::narrow_oop_operand || |
304 | 41 which == Assembler::imm_operand, "format unpacks ok"); |
42 if (which == Assembler::imm_operand) { | |
2375
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
1972
diff
changeset
|
43 if (verify_only) { |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
1972
diff
changeset
|
44 assert(*pd_address_in_code() == x, "instructions must match"); |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
1972
diff
changeset
|
45 } else { |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
1972
diff
changeset
|
46 *pd_address_in_code() = x; |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
1972
diff
changeset
|
47 } |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
0
diff
changeset
|
48 } else if (which == Assembler::narrow_oop_operand) { |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
0
diff
changeset
|
49 address disp = Assembler::locate_operand(addr(), which); |
2375
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
1972
diff
changeset
|
50 if (verify_only) { |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
1972
diff
changeset
|
51 assert(*(uint32_t*) disp == oopDesc::encode_heap_oop((oop)x), "instructions must match"); |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
1972
diff
changeset
|
52 } else { |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
1972
diff
changeset
|
53 *(int32_t*) disp = oopDesc::encode_heap_oop((oop)x); |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
1972
diff
changeset
|
54 } |
0 | 55 } else { |
56 // Note: Use runtime_call_type relocations for call32_operand. | |
57 address ip = addr(); | |
58 address disp = Assembler::locate_operand(ip, which); | |
59 address next_ip = Assembler::locate_next_instruction(ip); | |
2375
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
1972
diff
changeset
|
60 if (verify_only) { |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
1972
diff
changeset
|
61 assert(*(int32_t*) disp == (x - next_ip), "instructions must match"); |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
1972
diff
changeset
|
62 } else { |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
1972
diff
changeset
|
63 *(int32_t*) disp = x - next_ip; |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
1972
diff
changeset
|
64 } |
0 | 65 } |
66 #else | |
2375
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
1972
diff
changeset
|
67 if (verify_only) { |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
1972
diff
changeset
|
68 assert(*pd_address_in_code() == (x + o), "instructions must match"); |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
1972
diff
changeset
|
69 } else { |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
1972
diff
changeset
|
70 *pd_address_in_code() = x + o; |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
1972
diff
changeset
|
71 } |
0 | 72 #endif // AMD64 |
73 } | |
74 | |
75 | |
76 address Relocation::pd_call_destination(address orig_addr) { | |
77 intptr_t adj = 0; | |
78 if (orig_addr != NULL) { | |
79 // We just moved this call instruction from orig_addr to addr(). | |
80 // This means its target will appear to have grown by addr() - orig_addr. | |
81 adj = -( addr() - orig_addr ); | |
82 } | |
83 NativeInstruction* ni = nativeInstruction_at(addr()); | |
84 if (ni->is_call()) { | |
85 return nativeCall_at(addr())->destination() + adj; | |
86 } else if (ni->is_jump()) { | |
87 return nativeJump_at(addr())->jump_destination() + adj; | |
88 } else if (ni->is_cond_jump()) { | |
89 return nativeGeneralJump_at(addr())->jump_destination() + adj; | |
90 } else if (ni->is_mov_literal64()) { | |
91 return (address) ((NativeMovConstReg*)ni)->data(); | |
92 } else { | |
93 ShouldNotReachHere(); | |
94 return NULL; | |
95 } | |
96 } | |
97 | |
98 | |
99 void Relocation::pd_set_call_destination(address x) { | |
100 NativeInstruction* ni = nativeInstruction_at(addr()); | |
101 if (ni->is_call()) { | |
102 nativeCall_at(addr())->set_destination(x); | |
103 } else if (ni->is_jump()) { | |
104 NativeJump* nj = nativeJump_at(addr()); | |
304 | 105 |
106 // Unresolved jumps are recognized by a destination of -1 | |
107 // However 64bit can't actually produce such an address | |
108 // and encodes a jump to self but jump_destination will | |
109 // return a -1 as the signal. We must not relocate this | |
110 // jmp or the ic code will not see it as unresolved. | |
111 | |
0 | 112 if (nj->jump_destination() == (address) -1) { |
304 | 113 x = addr(); // jump to self |
0 | 114 } |
115 nj->set_jump_destination(x); | |
116 } else if (ni->is_cond_jump()) { | |
117 // %%%% kludge this, for now, until we get a jump_destination method | |
118 address old_dest = nativeGeneralJump_at(addr())->jump_destination(); | |
119 address disp = Assembler::locate_operand(addr(), Assembler::call32_operand); | |
120 *(jint*)disp += (x - old_dest); | |
121 } else if (ni->is_mov_literal64()) { | |
122 ((NativeMovConstReg*)ni)->set_data((intptr_t)x); | |
123 } else { | |
124 ShouldNotReachHere(); | |
125 } | |
126 } | |
127 | |
128 | |
129 address* Relocation::pd_address_in_code() { | |
130 // All embedded Intel addresses are stored in 32-bit words. | |
131 // Since the addr points at the start of the instruction, | |
132 // we must parse the instruction a bit to find the embedded word. | |
133 assert(is_data(), "must be a DataRelocation"); | |
134 typedef Assembler::WhichOperand WhichOperand; | |
304 | 135 WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm/imm32 |
0 | 136 #ifdef AMD64 |
137 assert(which == Assembler::disp32_operand || | |
138 which == Assembler::call32_operand || | |
304 | 139 which == Assembler::imm_operand, "format unpacks ok"); |
140 if (which != Assembler::imm_operand) { | |
0 | 141 // The "address" in the code is a displacement can't return it as |
142 // and address* since it is really a jint* | |
143 ShouldNotReachHere(); | |
144 return NULL; | |
145 } | |
146 #else | |
304 | 147 assert(which == Assembler::disp32_operand || which == Assembler::imm_operand, "format unpacks ok"); |
0 | 148 #endif // AMD64 |
149 return (address*) Assembler::locate_operand(addr(), which); | |
150 } | |
151 | |
152 | |
153 address Relocation::pd_get_address_from_code() { | |
154 #ifdef AMD64 | |
155 // All embedded Intel addresses are stored in 32-bit words. | |
156 // Since the addr points at the start of the instruction, | |
157 // we must parse the instruction a bit to find the embedded word. | |
158 assert(is_data(), "must be a DataRelocation"); | |
159 typedef Assembler::WhichOperand WhichOperand; | |
304 | 160 WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm/imm32 |
0 | 161 assert(which == Assembler::disp32_operand || |
162 which == Assembler::call32_operand || | |
304 | 163 which == Assembler::imm_operand, "format unpacks ok"); |
164 if (which != Assembler::imm_operand) { | |
0 | 165 address ip = addr(); |
166 address disp = Assembler::locate_operand(ip, which); | |
167 address next_ip = Assembler::locate_next_instruction(ip); | |
168 address a = next_ip + *(int32_t*) disp; | |
169 return a; | |
170 } | |
171 #endif // AMD64 | |
172 return *pd_address_in_code(); | |
173 } | |
174 | |
175 int Relocation::pd_breakpoint_size() { | |
176 // minimum breakpoint size, in short words | |
177 return NativeIllegalInstruction::instruction_size / sizeof(short); | |
178 } | |
179 | |
180 void Relocation::pd_swap_in_breakpoint(address x, short* instrs, int instrlen) { | |
181 Untested("pd_swap_in_breakpoint"); | |
182 if (instrs != NULL) { | |
183 assert(instrlen * sizeof(short) == NativeIllegalInstruction::instruction_size, "enough instrlen in reloc. data"); | |
184 for (int i = 0; i < instrlen; i++) { | |
185 instrs[i] = ((short*)x)[i]; | |
186 } | |
187 } | |
188 NativeIllegalInstruction::insert(x); | |
189 } | |
190 | |
191 | |
192 void Relocation::pd_swap_out_breakpoint(address x, short* instrs, int instrlen) { | |
193 Untested("pd_swap_out_breakpoint"); | |
194 assert(NativeIllegalInstruction::instruction_size == sizeof(short), "right address unit for update"); | |
195 NativeInstruction* ni = nativeInstruction_at(x); | |
196 *(short*)ni->addr_at(0) = instrs[0]; | |
197 } | |
304 | 198 |
199 void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { | |
200 #ifdef _LP64 | |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
201 if (!Assembler::is_polling_page_far()) { |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
202 typedef Assembler::WhichOperand WhichOperand; |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
203 WhichOperand which = (WhichOperand) format(); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
204 // This format is imm but it is really disp32 |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
205 which = Assembler::disp32_operand; |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
206 address orig_addr = old_addr_for(addr(), src, dest); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
207 NativeInstruction* oni = nativeInstruction_at(orig_addr); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
208 int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
209 // This poll_addr is incorrect by the size of the instruction it is irrelevant |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
210 intptr_t poll_addr = (intptr_t)oni + *orig_disp; |
304 | 211 |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
212 NativeInstruction* ni = nativeInstruction_at(addr()); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
213 intptr_t new_disp = poll_addr - (intptr_t) ni; |
304 | 214 |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
215 int32_t* disp = (int32_t*) Assembler::locate_operand(addr(), which); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
216 * disp = (int32_t)new_disp; |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
217 } |
304 | 218 #endif // _LP64 |
219 } | |
220 | |
221 void poll_return_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { | |
222 #ifdef _LP64 | |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
223 if (!Assembler::is_polling_page_far()) { |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
224 typedef Assembler::WhichOperand WhichOperand; |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
225 WhichOperand which = (WhichOperand) format(); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
226 // This format is imm but it is really disp32 |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
227 which = Assembler::disp32_operand; |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
228 address orig_addr = old_addr_for(addr(), src, dest); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
229 NativeInstruction* oni = nativeInstruction_at(orig_addr); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
230 int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
231 // This poll_addr is incorrect by the size of the instruction it is irrelevant |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
232 intptr_t poll_addr = (intptr_t)oni + *orig_disp; |
304 | 233 |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
234 NativeInstruction* ni = nativeInstruction_at(addr()); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
235 intptr_t new_disp = poll_addr - (intptr_t) ni; |
304 | 236 |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
237 int32_t* disp = (int32_t*) Assembler::locate_operand(addr(), which); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
238 * disp = (int32_t)new_disp; |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2375
diff
changeset
|
239 } |
304 | 240 #endif // _LP64 |
241 } |