Mercurial > hg > graal-compiler
annotate src/share/vm/code/relocInfo.hpp @ 3992:d1bdeef3e3e2
7098282: G1: assert(interval >= 0) failed: Sanity check, referencePolicy.cpp: 76
Summary: There is a race between one thread successfully forwarding and copying the klass mirror for the SoftReference class (including the static master clock) and another thread attempting to use the master clock while attempting to discover a soft reference object. Maintain a shadow copy of the soft reference master clock and use the shadow during reference discovery and reference processing.
Reviewed-by: tonyp, brutisso, ysr
author | johnc |
---|---|
date | Wed, 12 Oct 2011 10:25:51 -0700 |
parents | 6c97c830fb6f |
children | da91efe96a93 |
rev | line source |
---|---|
0 | 1 /* |
2426
1d1603768966
7010070: Update all 2010 Oracle-changed OpenJDK files to have the proper copyright dates - second pass
trims
parents:
2375
diff
changeset
|
2 * Copyright (c) 1997, 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:
337
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
337
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:
337
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_CODE_RELOCINFO_HPP |
26 #define SHARE_VM_CODE_RELOCINFO_HPP | |
27 | |
28 #include "memory/allocation.hpp" | |
29 #include "utilities/top.hpp" | |
30 | |
0 | 31 // Types in this file: |
32 // relocInfo | |
33 // One element of an array of halfwords encoding compressed relocations. | |
34 // Also, the source of relocation types (relocInfo::oop_type, ...). | |
35 // Relocation | |
36 // A flyweight object representing a single relocation. | |
37 // It is fully unpacked from the compressed relocation array. | |
38 // oop_Relocation, ... (subclasses of Relocation) | |
39 // The location of some type-specific operations (oop_addr, ...). | |
40 // Also, the source of relocation specs (oop_Relocation::spec, ...). | |
41 // RelocationHolder | |
42 // A ValueObj type which acts as a union holding a Relocation object. | |
43 // Represents a relocation spec passed into a CodeBuffer during assembly. | |
44 // RelocIterator | |
45 // A StackObj which iterates over the relocations associated with | |
46 // a range of code addresses. Can be used to operate a copy of code. | |
47 // PatchingRelocIterator | |
48 // Specialized subtype of RelocIterator which removes breakpoints | |
49 // temporarily during iteration, then restores them. | |
50 // BoundRelocation | |
51 // An _internal_ type shared by packers and unpackers of relocations. | |
52 // It pastes together a RelocationHolder with some pointers into | |
53 // code and relocInfo streams. | |
54 | |
55 | |
56 // Notes on relocType: | |
57 // | |
58 // These hold enough information to read or write a value embedded in | |
59 // the instructions of an CodeBlob. They're used to update: | |
60 // | |
61 // 1) embedded oops (isOop() == true) | |
62 // 2) inline caches (isIC() == true) | |
63 // 3) runtime calls (isRuntimeCall() == true) | |
64 // 4) internal word ref (isInternalWord() == true) | |
65 // 5) external word ref (isExternalWord() == true) | |
66 // | |
67 // when objects move (GC) or if code moves (compacting the code heap). | |
68 // They are also used to patch the code (if a call site must change) | |
69 // | |
70 // A relocInfo is represented in 16 bits: | |
71 // 4 bits indicating the relocation type | |
72 // 12 bits indicating the offset from the previous relocInfo address | |
73 // | |
74 // The offsets accumulate along the relocInfo stream to encode the | |
75 // address within the CodeBlob, which is named RelocIterator::addr(). | |
76 // The address of a particular relocInfo always points to the first | |
77 // byte of the relevant instruction (and not to any of its subfields | |
78 // or embedded immediate constants). | |
79 // | |
80 // The offset value is scaled appropriately for the target machine. | |
81 // (See relocInfo_<arch>.hpp for the offset scaling.) | |
82 // | |
83 // On some machines, there may also be a "format" field which may provide | |
84 // additional information about the format of the instruction stream | |
85 // at the corresponding code address. The format value is usually zero. | |
86 // Any machine (such as Intel) whose instructions can sometimes contain | |
87 // more than one relocatable constant needs format codes to distinguish | |
88 // which operand goes with a given relocation. | |
89 // | |
90 // If the target machine needs N format bits, the offset has 12-N bits, | |
91 // the format is encoded between the offset and the type, and the | |
92 // relocInfo_<arch>.hpp file has manifest constants for the format codes. | |
93 // | |
94 // If the type is "data_prefix_tag" then the offset bits are further encoded, | |
95 // and in fact represent not a code-stream offset but some inline data. | |
96 // The data takes the form of a counted sequence of halfwords, which | |
97 // precedes the actual relocation record. (Clients never see it directly.) | |
98 // The interpetation of this extra data depends on the relocation type. | |
99 // | |
100 // On machines that have 32-bit immediate fields, there is usually | |
101 // little need for relocation "prefix" data, because the instruction stream | |
102 // is a perfectly reasonable place to store the value. On machines in | |
103 // which 32-bit values must be "split" across instructions, the relocation | |
104 // data is the "true" specification of the value, which is then applied | |
105 // to some field of the instruction (22 or 13 bits, on SPARC). | |
106 // | |
107 // Whenever the location of the CodeBlob changes, any PC-relative | |
108 // relocations, and any internal_word_type relocations, must be reapplied. | |
109 // After the GC runs, oop_type relocations must be reapplied. | |
110 // | |
111 // | |
112 // Here are meanings of the types: | |
113 // | |
114 // relocInfo::none -- a filler record | |
115 // Value: none | |
116 // Instruction: The corresponding code address is ignored | |
117 // Data: Any data prefix and format code are ignored | |
118 // (This means that any relocInfo can be disabled by setting | |
119 // its type to none. See relocInfo::remove.) | |
120 // | |
121 // relocInfo::oop_type -- a reference to an oop | |
122 // Value: an oop, or else the address (handle) of an oop | |
123 // Instruction types: memory (load), set (load address) | |
124 // Data: [] an oop stored in 4 bytes of instruction | |
125 // [n] n is the index of an oop in the CodeBlob's oop pool | |
126 // [[N]n l] and l is a byte offset to be applied to the oop | |
127 // [Nn Ll] both index and offset may be 32 bits if necessary | |
128 // Here is a special hack, used only by the old compiler: | |
129 // [[N]n 00] the value is the __address__ of the nth oop in the pool | |
130 // (Note that the offset allows optimal references to class variables.) | |
131 // | |
132 // relocInfo::internal_word_type -- an address within the same CodeBlob | |
133 // relocInfo::section_word_type -- same, but can refer to another section | |
134 // Value: an address in the CodeBlob's code or constants section | |
135 // Instruction types: memory (load), set (load address) | |
136 // Data: [] stored in 4 bytes of instruction | |
137 // [[L]l] a relative offset (see [About Offsets] below) | |
138 // In the case of section_word_type, the offset is relative to a section | |
139 // base address, and the section number (e.g., SECT_INSTS) is encoded | |
140 // into the low two bits of the offset L. | |
141 // | |
142 // relocInfo::external_word_type -- a fixed address in the runtime system | |
143 // Value: an address | |
144 // Instruction types: memory (load), set (load address) | |
145 // Data: [] stored in 4 bytes of instruction | |
146 // [n] the index of a "well-known" stub (usual case on RISC) | |
147 // [Ll] a 32-bit address | |
148 // | |
149 // relocInfo::runtime_call_type -- a fixed subroutine in the runtime system | |
150 // Value: an address | |
151 // Instruction types: PC-relative call (or a PC-relative branch) | |
152 // Data: [] stored in 4 bytes of instruction | |
153 // | |
154 // relocInfo::static_call_type -- a static call | |
155 // Value: an CodeBlob, a stub, or a fixup routine | |
156 // Instruction types: a call | |
157 // Data: [] | |
158 // The identity of the callee is extracted from debugging information. | |
159 // //%note reloc_3 | |
160 // | |
161 // relocInfo::virtual_call_type -- a virtual call site (which includes an inline | |
162 // cache) | |
163 // Value: an CodeBlob, a stub, the interpreter, or a fixup routine | |
164 // Instruction types: a call, plus some associated set-oop instructions | |
165 // Data: [] the associated set-oops are adjacent to the call | |
166 // [n] n is a relative offset to the first set-oop | |
167 // [[N]n l] and l is a limit within which the set-oops occur | |
168 // [Nn Ll] both n and l may be 32 bits if necessary | |
169 // The identity of the callee is extracted from debugging information. | |
170 // | |
171 // relocInfo::opt_virtual_call_type -- a virtual call site that is statically bound | |
172 // | |
173 // Same info as a static_call_type. We use a special type, so the handling of | |
174 // virtuals and statics are separated. | |
175 // | |
176 // | |
177 // The offset n points to the first set-oop. (See [About Offsets] below.) | |
178 // In turn, the set-oop instruction specifies or contains an oop cell devoted | |
179 // exclusively to the IC call, which can be patched along with the call. | |
180 // | |
181 // The locations of any other set-oops are found by searching the relocation | |
182 // information starting at the first set-oop, and continuing until all | |
183 // relocations up through l have been inspected. The value l is another | |
184 // relative offset. (Both n and l are relative to the call's first byte.) | |
185 // | |
186 // The limit l of the search is exclusive. However, if it points within | |
187 // the call (e.g., offset zero), it is adjusted to point after the call and | |
188 // any associated machine-specific delay slot. | |
189 // | |
190 // Since the offsets could be as wide as 32-bits, these conventions | |
191 // put no restrictions whatever upon code reorganization. | |
192 // | |
193 // The compiler is responsible for ensuring that transition from a clean | |
194 // state to a monomorphic compiled state is MP-safe. This implies that | |
195 // the system must respond well to intermediate states where a random | |
196 // subset of the set-oops has been correctly from the clean state | |
197 // upon entry to the VEP of the compiled method. In the case of a | |
198 // machine (Intel) with a single set-oop instruction, the 32-bit | |
199 // immediate field must not straddle a unit of memory coherence. | |
200 // //%note reloc_3 | |
201 // | |
202 // relocInfo::breakpoint_type -- a conditional breakpoint in the code | |
203 // Value: none | |
204 // Instruction types: any whatsoever | |
205 // Data: [b [T]t i...] | |
206 // The b is a bit-packed word representing the breakpoint's attributes. | |
207 // The t is a target address which the breakpoint calls (when it is enabled). | |
208 // The i... is a place to store one or two instruction words overwritten | |
209 // by a trap, so that the breakpoint may be subsequently removed. | |
210 // | |
211 // relocInfo::static_stub_type -- an extra stub for each static_call_type | |
212 // Value: none | |
213 // Instruction types: a virtual call: { set_oop; jump; } | |
214 // Data: [[N]n] the offset of the associated static_call reloc | |
215 // This stub becomes the target of a static call which must be upgraded | |
216 // to a virtual call (because the callee is interpreted). | |
217 // See [About Offsets] below. | |
218 // //%note reloc_2 | |
219 // | |
220 // For example: | |
221 // | |
222 // INSTRUCTIONS RELOC: TYPE PREFIX DATA | |
223 // ------------ ---- ----------- | |
224 // sethi %hi(myObject), R oop_type [n(myObject)] | |
225 // ld [R+%lo(myObject)+fldOffset], R2 oop_type [n(myObject) fldOffset] | |
226 // add R2, 1, R2 | |
227 // st R2, [R+%lo(myObject)+fldOffset] oop_type [n(myObject) fldOffset] | |
228 //%note reloc_1 | |
229 // | |
230 // This uses 4 instruction words, 8 relocation halfwords, | |
231 // and an entry (which is sharable) in the CodeBlob's oop pool, | |
232 // for a total of 36 bytes. | |
233 // | |
234 // Note that the compiler is responsible for ensuring the "fldOffset" when | |
235 // added to "%lo(myObject)" does not overflow the immediate fields of the | |
236 // memory instructions. | |
237 // | |
238 // | |
239 // [About Offsets] Relative offsets are supplied to this module as | |
240 // positive byte offsets, but they may be internally stored scaled | |
241 // and/or negated, depending on what is most compact for the target | |
242 // system. Since the object pointed to by the offset typically | |
243 // precedes the relocation address, it is profitable to store | |
244 // these negative offsets as positive numbers, but this decision | |
245 // is internal to the relocation information abstractions. | |
246 // | |
247 | |
248 class Relocation; | |
249 class CodeBuffer; | |
250 class CodeSection; | |
251 class RelocIterator; | |
252 | |
253 class relocInfo VALUE_OBJ_CLASS_SPEC { | |
254 friend class RelocIterator; | |
255 public: | |
256 enum relocType { | |
257 none = 0, // Used when no relocation should be generated | |
258 oop_type = 1, // embedded oop | |
259 virtual_call_type = 2, // a standard inline cache call for a virtual send | |
260 opt_virtual_call_type = 3, // a virtual call that has been statically bound (i.e., no IC cache) | |
261 static_call_type = 4, // a static send | |
262 static_stub_type = 5, // stub-entry for static send (takes care of interpreter case) | |
263 runtime_call_type = 6, // call to fixed external routine | |
264 external_word_type = 7, // reference to fixed external address | |
265 internal_word_type = 8, // reference within the current code blob | |
266 section_word_type = 9, // internal, but a cross-section reference | |
267 poll_type = 10, // polling instruction for safepoints | |
268 poll_return_type = 11, // polling instruction for safepoints at return | |
269 breakpoint_type = 12, // an initialization barrier or safepoint | |
270 yet_unused_type = 13, // Still unused | |
271 yet_unused_type_2 = 14, // Still unused | |
272 data_prefix_tag = 15, // tag for a prefix (carries data arguments) | |
273 type_mask = 15 // A mask which selects only the above values | |
274 }; | |
275 | |
276 protected: | |
277 unsigned short _value; | |
278 | |
279 enum RawBitsToken { RAW_BITS }; | |
280 relocInfo(relocType type, RawBitsToken ignore, int bits) | |
281 : _value((type << nontype_width) + bits) { } | |
282 | |
283 relocInfo(relocType type, RawBitsToken ignore, int off, int f) | |
284 : _value((type << nontype_width) + (off / (unsigned)offset_unit) + (f << offset_width)) { } | |
285 | |
286 public: | |
287 // constructor | |
288 relocInfo(relocType type, int offset, int format = 0) | |
289 #ifndef ASSERT | |
290 { | |
291 (*this) = relocInfo(type, RAW_BITS, offset, format); | |
292 } | |
293 #else | |
294 // Put a bunch of assertions out-of-line. | |
295 ; | |
296 #endif | |
297 | |
298 #define APPLY_TO_RELOCATIONS(visitor) \ | |
299 visitor(oop) \ | |
300 visitor(virtual_call) \ | |
301 visitor(opt_virtual_call) \ | |
302 visitor(static_call) \ | |
303 visitor(static_stub) \ | |
304 visitor(runtime_call) \ | |
305 visitor(external_word) \ | |
306 visitor(internal_word) \ | |
307 visitor(poll) \ | |
308 visitor(poll_return) \ | |
309 visitor(breakpoint) \ | |
310 visitor(section_word) \ | |
311 | |
312 | |
313 public: | |
314 enum { | |
315 value_width = sizeof(unsigned short) * BitsPerByte, | |
316 type_width = 4, // == log2(type_mask+1) | |
317 nontype_width = value_width - type_width, | |
318 datalen_width = nontype_width-1, | |
319 datalen_tag = 1 << datalen_width, // or-ed into _value | |
320 datalen_limit = 1 << datalen_width, | |
321 datalen_mask = (1 << datalen_width)-1 | |
322 }; | |
323 | |
324 // accessors | |
325 public: | |
326 relocType type() const { return (relocType)((unsigned)_value >> nontype_width); } | |
327 int format() const { return format_mask==0? 0: format_mask & | |
328 ((unsigned)_value >> offset_width); } | |
329 int addr_offset() const { assert(!is_prefix(), "must have offset"); | |
330 return (_value & offset_mask)*offset_unit; } | |
331 | |
332 protected: | |
333 const short* data() const { assert(is_datalen(), "must have data"); | |
334 return (const short*)(this + 1); } | |
335 int datalen() const { assert(is_datalen(), "must have data"); | |
336 return (_value & datalen_mask); } | |
337 int immediate() const { assert(is_immediate(), "must have immed"); | |
338 return (_value & datalen_mask); } | |
339 public: | |
340 static int addr_unit() { return offset_unit; } | |
341 static int offset_limit() { return (1 << offset_width) * offset_unit; } | |
342 | |
343 void set_type(relocType type); | |
344 void set_format(int format); | |
345 | |
346 void remove() { set_type(none); } | |
347 | |
348 protected: | |
349 bool is_none() const { return type() == none; } | |
350 bool is_prefix() const { return type() == data_prefix_tag; } | |
351 bool is_datalen() const { assert(is_prefix(), "must be prefix"); | |
352 return (_value & datalen_tag) != 0; } | |
353 bool is_immediate() const { assert(is_prefix(), "must be prefix"); | |
354 return (_value & datalen_tag) == 0; } | |
355 | |
356 public: | |
357 // Occasionally records of type relocInfo::none will appear in the stream. | |
358 // We do not bother to filter these out, but clients should ignore them. | |
359 // These records serve as "filler" in three ways: | |
360 // - to skip large spans of unrelocated code (this is rare) | |
361 // - to pad out the relocInfo array to the required oop alignment | |
362 // - to disable old relocation information which is no longer applicable | |
363 | |
364 inline friend relocInfo filler_relocInfo(); | |
365 | |
366 // Every non-prefix relocation may be preceded by at most one prefix, | |
367 // which supplies 1 or more halfwords of associated data. Conventionally, | |
368 // an int is represented by 0, 1, or 2 halfwords, depending on how | |
369 // many bits are required to represent the value. (In addition, | |
370 // if the sole halfword is a 10-bit unsigned number, it is made | |
371 // "immediate" in the prefix header word itself. This optimization | |
372 // is invisible outside this module.) | |
373 | |
374 inline friend relocInfo prefix_relocInfo(int datalen = 0); | |
375 | |
376 protected: | |
377 // an immediate relocInfo optimizes a prefix with one 10-bit unsigned value | |
378 static relocInfo immediate_relocInfo(int data0) { | |
379 assert(fits_into_immediate(data0), "data0 in limits"); | |
380 return relocInfo(relocInfo::data_prefix_tag, RAW_BITS, data0); | |
381 } | |
382 static bool fits_into_immediate(int data0) { | |
383 return (data0 >= 0 && data0 < datalen_limit); | |
384 } | |
385 | |
386 public: | |
387 // Support routines for compilers. | |
388 | |
389 // This routine takes an infant relocInfo (unprefixed) and | |
390 // edits in its prefix, if any. It also updates dest.locs_end. | |
391 void initialize(CodeSection* dest, Relocation* reloc); | |
392 | |
393 // This routine updates a prefix and returns the limit pointer. | |
394 // It tries to compress the prefix from 32 to 16 bits, and if | |
395 // successful returns a reduced "prefix_limit" pointer. | |
396 relocInfo* finish_prefix(short* prefix_limit); | |
397 | |
398 // bit-packers for the data array: | |
399 | |
400 // As it happens, the bytes within the shorts are ordered natively, | |
401 // but the shorts within the word are ordered big-endian. | |
402 // This is an arbitrary choice, made this way mainly to ease debugging. | |
403 static int data0_from_int(jint x) { return x >> value_width; } | |
404 static int data1_from_int(jint x) { return (short)x; } | |
405 static jint jint_from_data(short* data) { | |
406 return (data[0] << value_width) + (unsigned short)data[1]; | |
407 } | |
408 | |
409 static jint short_data_at(int n, short* data, int datalen) { | |
410 return datalen > n ? data[n] : 0; | |
411 } | |
412 | |
413 static jint jint_data_at(int n, short* data, int datalen) { | |
414 return datalen > n+1 ? jint_from_data(&data[n]) : short_data_at(n, data, datalen); | |
415 } | |
416 | |
417 // Update methods for relocation information | |
418 // (since code is dynamically patched, we also need to dynamically update the relocation info) | |
419 // Both methods takes old_type, so it is able to performe sanity checks on the information removed. | |
420 static void change_reloc_info_for_address(RelocIterator *itr, address pc, relocType old_type, relocType new_type); | |
421 static void remove_reloc_info_for_address(RelocIterator *itr, address pc, relocType old_type); | |
422 | |
423 // Machine dependent stuff | |
1972 | 424 #ifdef TARGET_ARCH_x86 |
425 # include "relocInfo_x86.hpp" | |
426 #endif | |
427 #ifdef TARGET_ARCH_sparc | |
428 # include "relocInfo_sparc.hpp" | |
429 #endif | |
430 #ifdef TARGET_ARCH_zero | |
431 # include "relocInfo_zero.hpp" | |
432 #endif | |
2192
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
1972
diff
changeset
|
433 #ifdef TARGET_ARCH_arm |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
1972
diff
changeset
|
434 # include "relocInfo_arm.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
1972
diff
changeset
|
435 #endif |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
1972
diff
changeset
|
436 #ifdef TARGET_ARCH_ppc |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
1972
diff
changeset
|
437 # include "relocInfo_ppc.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
1972
diff
changeset
|
438 #endif |
1972 | 439 |
0 | 440 |
441 protected: | |
442 // Derived constant, based on format_width which is PD: | |
443 enum { | |
444 offset_width = nontype_width - format_width, | |
445 offset_mask = (1<<offset_width) - 1, | |
446 format_mask = (1<<format_width) - 1 | |
447 }; | |
448 public: | |
449 enum { | |
450 // Conservatively large estimate of maximum length (in shorts) | |
451 // of any relocation record (probably breakpoints are largest). | |
452 // Extended format is length prefix, data words, and tag/offset suffix. | |
453 length_limit = 1 + 1 + (3*BytesPerWord/BytesPerShort) + 1, | |
454 have_format = format_width > 0 | |
455 }; | |
456 }; | |
457 | |
458 #define FORWARD_DECLARE_EACH_CLASS(name) \ | |
459 class name##_Relocation; | |
460 APPLY_TO_RELOCATIONS(FORWARD_DECLARE_EACH_CLASS) | |
461 #undef FORWARD_DECLARE_EACH_CLASS | |
462 | |
463 | |
464 | |
465 inline relocInfo filler_relocInfo() { | |
466 return relocInfo(relocInfo::none, relocInfo::offset_limit() - relocInfo::offset_unit); | |
467 } | |
468 | |
469 inline relocInfo prefix_relocInfo(int datalen) { | |
470 assert(relocInfo::fits_into_immediate(datalen), "datalen in limits"); | |
471 return relocInfo(relocInfo::data_prefix_tag, relocInfo::RAW_BITS, relocInfo::datalen_tag | datalen); | |
472 } | |
473 | |
474 | |
475 // Holder for flyweight relocation objects. | |
476 // Although the flyweight subclasses are of varying sizes, | |
477 // the holder is "one size fits all". | |
478 class RelocationHolder VALUE_OBJ_CLASS_SPEC { | |
479 friend class Relocation; | |
480 friend class CodeSection; | |
481 | |
482 private: | |
483 // this preallocated memory must accommodate all subclasses of Relocation | |
484 // (this number is assertion-checked in Relocation::operator new) | |
485 enum { _relocbuf_size = 5 }; | |
486 void* _relocbuf[ _relocbuf_size ]; | |
487 | |
488 public: | |
489 Relocation* reloc() const { return (Relocation*) &_relocbuf[0]; } | |
490 inline relocInfo::relocType type() const; | |
491 | |
492 // Add a constant offset to a relocation. Helper for class Address. | |
493 RelocationHolder plus(int offset) const; | |
494 | |
495 inline RelocationHolder(); // initializes type to none | |
496 | |
497 inline RelocationHolder(Relocation* r); // make a copy | |
498 | |
499 static const RelocationHolder none; | |
500 }; | |
501 | |
502 // A RelocIterator iterates through the relocation information of a CodeBlob. | |
503 // It is a variable BoundRelocation which is able to take on successive | |
504 // values as it is advanced through a code stream. | |
505 // Usage: | |
506 // RelocIterator iter(nm); | |
507 // while (iter.next()) { | |
508 // iter.reloc()->some_operation(); | |
509 // } | |
510 // or: | |
511 // RelocIterator iter(nm); | |
512 // while (iter.next()) { | |
513 // switch (iter.type()) { | |
514 // case relocInfo::oop_type : | |
515 // case relocInfo::ic_type : | |
516 // case relocInfo::prim_type : | |
517 // case relocInfo::uncommon_type : | |
518 // case relocInfo::runtime_call_type : | |
519 // case relocInfo::internal_word_type: | |
520 // case relocInfo::external_word_type: | |
521 // ... | |
522 // } | |
523 // } | |
524 | |
525 class RelocIterator : public StackObj { | |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1579
diff
changeset
|
526 enum { SECT_LIMIT = 3 }; // must be equal to CodeBuffer::SECT_LIMIT, checked in ctor |
0 | 527 friend class Relocation; |
528 friend class relocInfo; // for change_reloc_info_for_address only | |
529 typedef relocInfo::relocType relocType; | |
530 | |
531 private: | |
532 address _limit; // stop producing relocations after this _addr | |
533 relocInfo* _current; // the current relocation information | |
534 relocInfo* _end; // end marker; we're done iterating when _current == _end | |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
337
diff
changeset
|
535 nmethod* _code; // compiled method containing _addr |
0 | 536 address _addr; // instruction to which the relocation applies |
537 short _databuf; // spare buffer for compressed data | |
538 short* _data; // pointer to the relocation's data | |
539 short _datalen; // number of halfwords in _data | |
540 char _format; // position within the instruction | |
541 | |
542 // Base addresses needed to compute targets of section_word_type relocs. | |
543 address _section_start[SECT_LIMIT]; | |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1579
diff
changeset
|
544 address _section_end [SECT_LIMIT]; |
0 | 545 |
546 void set_has_current(bool b) { | |
547 _datalen = !b ? -1 : 0; | |
548 debug_only(_data = NULL); | |
549 } | |
550 void set_current(relocInfo& ri) { | |
551 _current = &ri; | |
552 set_has_current(true); | |
553 } | |
554 | |
555 RelocationHolder _rh; // where the current relocation is allocated | |
556 | |
557 relocInfo* current() const { assert(has_current(), "must have current"); | |
558 return _current; } | |
559 | |
560 void set_limits(address begin, address limit); | |
561 | |
562 void advance_over_prefix(); // helper method | |
563 | |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1579
diff
changeset
|
564 void initialize_misc(); |
0 | 565 |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
337
diff
changeset
|
566 void initialize(nmethod* nm, address begin, address limit); |
0 | 567 |
568 friend class PatchingRelocIterator; | |
569 // make an uninitialized one, for PatchingRelocIterator: | |
570 RelocIterator() { initialize_misc(); } | |
571 | |
572 public: | |
573 // constructor | |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
337
diff
changeset
|
574 RelocIterator(nmethod* nm, address begin = NULL, address limit = NULL); |
0 | 575 RelocIterator(CodeSection* cb, address begin = NULL, address limit = NULL); |
576 | |
577 // get next reloc info, return !eos | |
578 bool next() { | |
579 _current++; | |
580 assert(_current <= _end, "must not overrun relocInfo"); | |
581 if (_current == _end) { | |
582 set_has_current(false); | |
583 return false; | |
584 } | |
585 set_has_current(true); | |
586 | |
587 if (_current->is_prefix()) { | |
588 advance_over_prefix(); | |
589 assert(!current()->is_prefix(), "only one prefix at a time"); | |
590 } | |
591 | |
592 _addr += _current->addr_offset(); | |
593 | |
594 if (_limit != NULL && _addr >= _limit) { | |
595 set_has_current(false); | |
596 return false; | |
597 } | |
598 | |
599 if (relocInfo::have_format) _format = current()->format(); | |
600 return true; | |
601 } | |
602 | |
603 // accessors | |
604 address limit() const { return _limit; } | |
605 void set_limit(address x); | |
606 relocType type() const { return current()->type(); } | |
607 int format() const { return (relocInfo::have_format) ? current()->format() : 0; } | |
608 address addr() const { return _addr; } | |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
337
diff
changeset
|
609 nmethod* code() const { return _code; } |
0 | 610 short* data() const { return _data; } |
611 int datalen() const { return _datalen; } | |
612 bool has_current() const { return _datalen >= 0; } | |
613 | |
614 void set_addr(address addr) { _addr = addr; } | |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1579
diff
changeset
|
615 bool addr_in_const() const; |
0 | 616 |
617 address section_start(int n) const { | |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1579
diff
changeset
|
618 assert(_section_start[n], "must be initialized"); |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1579
diff
changeset
|
619 return _section_start[n]; |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1579
diff
changeset
|
620 } |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1579
diff
changeset
|
621 address section_end(int n) const { |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1579
diff
changeset
|
622 assert(_section_end[n], "must be initialized"); |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1579
diff
changeset
|
623 return _section_end[n]; |
0 | 624 } |
625 | |
626 // The address points to the affected displacement part of the instruction. | |
627 // For RISC, this is just the whole instruction. | |
628 // For Intel, this is an unaligned 32-bit word. | |
629 | |
630 // type-specific relocation accessors: oop_Relocation* oop_reloc(), etc. | |
631 #define EACH_TYPE(name) \ | |
632 inline name##_Relocation* name##_reloc(); | |
633 APPLY_TO_RELOCATIONS(EACH_TYPE) | |
634 #undef EACH_TYPE | |
635 // generic relocation accessor; switches on type to call the above | |
636 Relocation* reloc(); | |
637 | |
638 // CodeBlob's have relocation indexes for faster random access: | |
639 static int locs_and_index_size(int code_size, int locs_size); | |
640 // Store an index into [dest_start+dest_count..dest_end). | |
641 // At dest_start[0..dest_count] is the actual relocation information. | |
642 // Everything else up to dest_end is free space for the index. | |
643 static void create_index(relocInfo* dest_begin, int dest_count, relocInfo* dest_end); | |
644 | |
645 #ifndef PRODUCT | |
646 public: | |
647 void print(); | |
648 void print_current(); | |
649 #endif | |
650 }; | |
651 | |
652 | |
653 // A Relocation is a flyweight object allocated within a RelocationHolder. | |
654 // It represents the relocation data of relocation record. | |
655 // So, the RelocIterator unpacks relocInfos into Relocations. | |
656 | |
657 class Relocation VALUE_OBJ_CLASS_SPEC { | |
658 friend class RelocationHolder; | |
659 friend class RelocIterator; | |
660 | |
661 private: | |
662 static void guarantee_size(); | |
663 | |
664 // When a relocation has been created by a RelocIterator, | |
665 // this field is non-null. It allows the relocation to know | |
666 // its context, such as the address to which it applies. | |
667 RelocIterator* _binding; | |
668 | |
669 protected: | |
670 RelocIterator* binding() const { | |
671 assert(_binding != NULL, "must be bound"); | |
672 return _binding; | |
673 } | |
674 void set_binding(RelocIterator* b) { | |
675 assert(_binding == NULL, "must be unbound"); | |
676 _binding = b; | |
677 assert(_binding != NULL, "must now be bound"); | |
678 } | |
679 | |
680 Relocation() { | |
681 _binding = NULL; | |
682 } | |
683 | |
684 static RelocationHolder newHolder() { | |
685 return RelocationHolder(); | |
686 } | |
687 | |
688 public: | |
689 void* operator new(size_t size, const RelocationHolder& holder) { | |
690 if (size > sizeof(holder._relocbuf)) guarantee_size(); | |
691 assert((void* const *)holder.reloc() == &holder._relocbuf[0], "ptrs must agree"); | |
692 return holder.reloc(); | |
693 } | |
694 | |
695 // make a generic relocation for a given type (if possible) | |
696 static RelocationHolder spec_simple(relocInfo::relocType rtype); | |
697 | |
698 // here is the type-specific hook which writes relocation data: | |
699 virtual void pack_data_to(CodeSection* dest) { } | |
700 | |
701 // here is the type-specific hook which reads (unpacks) relocation data: | |
702 virtual void unpack_data() { | |
703 assert(datalen()==0 || type()==relocInfo::none, "no data here"); | |
704 } | |
705 | |
2455
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2375
diff
changeset
|
706 static bool is_reloc_index(intptr_t index) { |
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2375
diff
changeset
|
707 return 0 < index && index < os::vm_page_size(); |
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2375
diff
changeset
|
708 } |
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2375
diff
changeset
|
709 |
0 | 710 protected: |
711 // Helper functions for pack_data_to() and unpack_data(). | |
712 | |
713 // Most of the compression logic is confined here. | |
714 // (The "immediate data" mechanism of relocInfo works independently | |
715 // of this stuff, and acts to further compress most 1-word data prefixes.) | |
716 | |
717 // A variable-width int is encoded as a short if it will fit in 16 bits. | |
718 // The decoder looks at datalen to decide whether to unpack short or jint. | |
719 // Most relocation records are quite simple, containing at most two ints. | |
720 | |
721 static bool is_short(jint x) { return x == (short)x; } | |
722 static short* add_short(short* p, int x) { *p++ = x; return p; } | |
723 static short* add_jint (short* p, jint x) { | |
724 *p++ = relocInfo::data0_from_int(x); *p++ = relocInfo::data1_from_int(x); | |
725 return p; | |
726 } | |
727 static short* add_var_int(short* p, jint x) { // add a variable-width int | |
728 if (is_short(x)) p = add_short(p, x); | |
729 else p = add_jint (p, x); | |
730 return p; | |
731 } | |
732 | |
733 static short* pack_1_int_to(short* p, jint x0) { | |
734 // Format is one of: [] [x] [Xx] | |
735 if (x0 != 0) p = add_var_int(p, x0); | |
736 return p; | |
737 } | |
738 int unpack_1_int() { | |
739 assert(datalen() <= 2, "too much data"); | |
740 return relocInfo::jint_data_at(0, data(), datalen()); | |
741 } | |
742 | |
743 // With two ints, the short form is used only if both ints are short. | |
744 short* pack_2_ints_to(short* p, jint x0, jint x1) { | |
745 // Format is one of: [] [x y?] [Xx Y?y] | |
746 if (x0 == 0 && x1 == 0) { | |
747 // no halfwords needed to store zeroes | |
748 } else if (is_short(x0) && is_short(x1)) { | |
749 // 1-2 halfwords needed to store shorts | |
750 p = add_short(p, x0); if (x1!=0) p = add_short(p, x1); | |
751 } else { | |
752 // 3-4 halfwords needed to store jints | |
753 p = add_jint(p, x0); p = add_var_int(p, x1); | |
754 } | |
755 return p; | |
756 } | |
757 void unpack_2_ints(jint& x0, jint& x1) { | |
758 int dlen = datalen(); | |
759 short* dp = data(); | |
760 if (dlen <= 2) { | |
761 x0 = relocInfo::short_data_at(0, dp, dlen); | |
762 x1 = relocInfo::short_data_at(1, dp, dlen); | |
763 } else { | |
764 assert(dlen <= 4, "too much data"); | |
765 x0 = relocInfo::jint_data_at(0, dp, dlen); | |
766 x1 = relocInfo::jint_data_at(2, dp, dlen); | |
767 } | |
768 } | |
769 | |
770 protected: | |
771 // platform-dependent utilities for decoding and patching instructions | |
2375
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2192
diff
changeset
|
772 void pd_set_data_value (address x, intptr_t off, bool verify_only = false); // a set or mem-ref |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2192
diff
changeset
|
773 void pd_verify_data_value (address x, intptr_t off) { pd_set_data_value(x, off, true); } |
0 | 774 address pd_call_destination (address orig_addr = NULL); |
775 void pd_set_call_destination (address x); | |
776 void pd_swap_in_breakpoint (address x, short* instrs, int instrlen); | |
777 void pd_swap_out_breakpoint (address x, short* instrs, int instrlen); | |
778 static int pd_breakpoint_size (); | |
779 | |
780 // this extracts the address of an address in the code stream instead of the reloc data | |
781 address* pd_address_in_code (); | |
782 | |
783 // this extracts an address from the code stream instead of the reloc data | |
784 address pd_get_address_from_code (); | |
785 | |
786 // these convert from byte offsets, to scaled offsets, to addresses | |
787 static jint scaled_offset(address x, address base) { | |
788 int byte_offset = x - base; | |
789 int offset = -byte_offset / relocInfo::addr_unit(); | |
790 assert(address_from_scaled_offset(offset, base) == x, "just checkin'"); | |
791 return offset; | |
792 } | |
793 static jint scaled_offset_null_special(address x, address base) { | |
794 // Some relocations treat offset=0 as meaning NULL. | |
795 // Handle this extra convention carefully. | |
796 if (x == NULL) return 0; | |
797 assert(x != base, "offset must not be zero"); | |
798 return scaled_offset(x, base); | |
799 } | |
800 static address address_from_scaled_offset(jint offset, address base) { | |
801 int byte_offset = -( offset * relocInfo::addr_unit() ); | |
802 return base + byte_offset; | |
803 } | |
804 | |
805 // these convert between indexes and addresses in the runtime system | |
806 static int32_t runtime_address_to_index(address runtime_address); | |
807 static address index_to_runtime_address(int32_t index); | |
808 | |
809 // helpers for mapping between old and new addresses after a move or resize | |
810 address old_addr_for(address newa, const CodeBuffer* src, CodeBuffer* dest); | |
811 address new_addr_for(address olda, const CodeBuffer* src, CodeBuffer* dest); | |
812 void normalize_address(address& addr, const CodeSection* dest, bool allow_other_sections = false); | |
813 | |
814 public: | |
815 // accessors which only make sense for a bound Relocation | |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
337
diff
changeset
|
816 address addr() const { return binding()->addr(); } |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
337
diff
changeset
|
817 nmethod* code() const { return binding()->code(); } |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
337
diff
changeset
|
818 bool addr_in_const() const { return binding()->addr_in_const(); } |
0 | 819 protected: |
820 short* data() const { return binding()->data(); } | |
821 int datalen() const { return binding()->datalen(); } | |
822 int format() const { return binding()->format(); } | |
823 | |
824 public: | |
825 virtual relocInfo::relocType type() { return relocInfo::none; } | |
826 | |
827 // is it a call instruction? | |
828 virtual bool is_call() { return false; } | |
829 | |
830 // is it a data movement instruction? | |
831 virtual bool is_data() { return false; } | |
832 | |
833 // some relocations can compute their own values | |
834 virtual address value(); | |
835 | |
836 // all relocations are able to reassert their values | |
837 virtual void set_value(address x); | |
838 | |
839 virtual void clear_inline_cache() { } | |
840 | |
841 // This method assumes that all virtual/static (inline) caches are cleared (since for static_call_type and | |
842 // ic_call_type is not always posisition dependent (depending on the state of the cache)). However, this is | |
843 // probably a reasonable assumption, since empty caches simplifies code reloacation. | |
844 virtual void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { } | |
845 | |
846 void print(); | |
847 }; | |
848 | |
849 | |
850 // certain inlines must be deferred until class Relocation is defined: | |
851 | |
852 inline RelocationHolder::RelocationHolder() { | |
853 // initialize the vtbl, just to keep things type-safe | |
854 new(*this) Relocation(); | |
855 } | |
856 | |
857 | |
858 inline RelocationHolder::RelocationHolder(Relocation* r) { | |
859 // wordwise copy from r (ok if it copies garbage after r) | |
860 for (int i = 0; i < _relocbuf_size; i++) { | |
861 _relocbuf[i] = ((void**)r)[i]; | |
862 } | |
863 } | |
864 | |
865 | |
866 relocInfo::relocType RelocationHolder::type() const { | |
867 return reloc()->type(); | |
868 } | |
869 | |
870 // A DataRelocation always points at a memory or load-constant instruction.. | |
871 // It is absolute on most machines, and the constant is split on RISCs. | |
872 // The specific subtypes are oop, external_word, and internal_word. | |
873 // By convention, the "value" does not include a separately reckoned "offset". | |
874 class DataRelocation : public Relocation { | |
875 public: | |
876 bool is_data() { return true; } | |
877 | |
878 // both target and offset must be computed somehow from relocation data | |
879 virtual int offset() { return 0; } | |
880 address value() = 0; | |
881 void set_value(address x) { set_value(x, offset()); } | |
882 void set_value(address x, intptr_t o) { | |
883 if (addr_in_const()) | |
884 *(address*)addr() = x; | |
885 else | |
886 pd_set_data_value(x, o); | |
887 } | |
2375
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2192
diff
changeset
|
888 void verify_value(address x) { |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2192
diff
changeset
|
889 if (addr_in_const()) |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2192
diff
changeset
|
890 assert(*(address*)addr() == x, "must agree"); |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2192
diff
changeset
|
891 else |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2192
diff
changeset
|
892 pd_verify_data_value(x, offset()); |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2192
diff
changeset
|
893 } |
0 | 894 |
895 // The "o" (displacement) argument is relevant only to split relocations | |
896 // on RISC machines. In some CPUs (SPARC), the set-hi and set-lo ins'ns | |
897 // can encode more than 32 bits between them. This allows compilers to | |
898 // share set-hi instructions between addresses that differ by a small | |
899 // offset (e.g., different static variables in the same class). | |
900 // On such machines, the "x" argument to set_value on all set-lo | |
901 // instructions must be the same as the "x" argument for the | |
902 // corresponding set-hi instructions. The "o" arguments for the | |
903 // set-hi instructions are ignored, and must not affect the high-half | |
904 // immediate constant. The "o" arguments for the set-lo instructions are | |
905 // added into the low-half immediate constant, and must not overflow it. | |
906 }; | |
907 | |
908 // A CallRelocation always points at a call instruction. | |
909 // It is PC-relative on most machines. | |
910 class CallRelocation : public Relocation { | |
911 public: | |
912 bool is_call() { return true; } | |
913 | |
914 address destination() { return pd_call_destination(); } | |
915 void set_destination(address x); // pd_set_call_destination | |
916 | |
917 void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest); | |
918 address value() { return destination(); } | |
919 void set_value(address x) { set_destination(x); } | |
920 }; | |
921 | |
922 class oop_Relocation : public DataRelocation { | |
923 relocInfo::relocType type() { return relocInfo::oop_type; } | |
924 | |
925 public: | |
926 // encode in one of these formats: [] [n] [n l] [Nn l] [Nn Ll] | |
927 // an oop in the CodeBlob's oop pool | |
928 static RelocationHolder spec(int oop_index, int offset = 0) { | |
929 assert(oop_index > 0, "must be a pool-resident oop"); | |
930 RelocationHolder rh = newHolder(); | |
931 new(rh) oop_Relocation(oop_index, offset); | |
932 return rh; | |
933 } | |
934 // an oop in the instruction stream | |
935 static RelocationHolder spec_for_immediate() { | |
936 const int oop_index = 0; | |
937 const int offset = 0; // if you want an offset, use the oop pool | |
938 RelocationHolder rh = newHolder(); | |
939 new(rh) oop_Relocation(oop_index, offset); | |
940 return rh; | |
941 } | |
942 | |
943 private: | |
944 jint _oop_index; // if > 0, index into CodeBlob::oop_at | |
945 jint _offset; // byte offset to apply to the oop itself | |
946 | |
947 oop_Relocation(int oop_index, int offset) { | |
948 _oop_index = oop_index; _offset = offset; | |
949 } | |
950 | |
951 friend class RelocIterator; | |
952 oop_Relocation() { } | |
953 | |
954 public: | |
955 int oop_index() { return _oop_index; } | |
956 int offset() { return _offset; } | |
957 | |
958 // data is packed in "2_ints" format: [i o] or [Ii Oo] | |
959 void pack_data_to(CodeSection* dest); | |
960 void unpack_data(); | |
961 | |
962 void fix_oop_relocation(); // reasserts oop value | |
963 | |
2375
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2192
diff
changeset
|
964 void verify_oop_relocation(); |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2192
diff
changeset
|
965 |
0 | 966 address value() { return (address) *oop_addr(); } |
967 | |
968 bool oop_is_immediate() { return oop_index() == 0; } | |
969 | |
970 oop* oop_addr(); // addr or &pool[jint_data] | |
971 oop oop_value(); // *oop_addr | |
972 // Note: oop_value transparently converts Universe::non_oop_word to NULL. | |
973 }; | |
974 | |
975 class virtual_call_Relocation : public CallRelocation { | |
976 relocInfo::relocType type() { return relocInfo::virtual_call_type; } | |
977 | |
978 public: | |
979 // "first_oop" points to the first associated set-oop. | |
980 // The oop_limit helps find the last associated set-oop. | |
981 // (See comments at the top of this file.) | |
982 static RelocationHolder spec(address first_oop, address oop_limit = NULL) { | |
983 RelocationHolder rh = newHolder(); | |
984 new(rh) virtual_call_Relocation(first_oop, oop_limit); | |
985 return rh; | |
986 } | |
987 | |
988 virtual_call_Relocation(address first_oop, address oop_limit) { | |
989 _first_oop = first_oop; _oop_limit = oop_limit; | |
990 assert(first_oop != NULL, "first oop address must be specified"); | |
991 } | |
992 | |
993 private: | |
994 address _first_oop; // location of first set-oop instruction | |
995 address _oop_limit; // search limit for set-oop instructions | |
996 | |
997 friend class RelocIterator; | |
998 virtual_call_Relocation() { } | |
999 | |
1000 | |
1001 public: | |
1002 address first_oop(); | |
1003 address oop_limit(); | |
1004 | |
1005 // data is packed as scaled offsets in "2_ints" format: [f l] or [Ff Ll] | |
1006 // oop_limit is set to 0 if the limit falls somewhere within the call. | |
1007 // When unpacking, a zero oop_limit is taken to refer to the end of the call. | |
1008 // (This has the effect of bringing in the call's delay slot on SPARC.) | |
1009 void pack_data_to(CodeSection* dest); | |
1010 void unpack_data(); | |
1011 | |
1012 void clear_inline_cache(); | |
1013 | |
1014 // Figure out where an ic_call is hiding, given a set-oop or call. | |
1015 // Either ic_call or first_oop must be non-null; the other is deduced. | |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
337
diff
changeset
|
1016 // Code if non-NULL must be the nmethod, else it is deduced. |
0 | 1017 // The address of the patchable oop is also deduced. |
1018 // The returned iterator will enumerate over the oops and the ic_call, | |
1019 // as well as any other relocations that happen to be in that span of code. | |
1020 // Recognize relevant set_oops with: oop_reloc()->oop_addr() == oop_addr. | |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
337
diff
changeset
|
1021 static RelocIterator parse_ic(nmethod* &nm, address &ic_call, address &first_oop, oop* &oop_addr, bool *is_optimized); |
0 | 1022 }; |
1023 | |
1024 | |
1025 class opt_virtual_call_Relocation : public CallRelocation { | |
1026 relocInfo::relocType type() { return relocInfo::opt_virtual_call_type; } | |
1027 | |
1028 public: | |
1029 static RelocationHolder spec() { | |
1030 RelocationHolder rh = newHolder(); | |
1031 new(rh) opt_virtual_call_Relocation(); | |
1032 return rh; | |
1033 } | |
1034 | |
1035 private: | |
1036 friend class RelocIterator; | |
1037 opt_virtual_call_Relocation() { } | |
1038 | |
1039 public: | |
1040 void clear_inline_cache(); | |
1041 | |
1042 // find the matching static_stub | |
1043 address static_stub(); | |
1044 }; | |
1045 | |
1046 | |
1047 class static_call_Relocation : public CallRelocation { | |
1048 relocInfo::relocType type() { return relocInfo::static_call_type; } | |
1049 | |
1050 public: | |
1051 static RelocationHolder spec() { | |
1052 RelocationHolder rh = newHolder(); | |
1053 new(rh) static_call_Relocation(); | |
1054 return rh; | |
1055 } | |
1056 | |
1057 private: | |
1058 friend class RelocIterator; | |
1059 static_call_Relocation() { } | |
1060 | |
1061 public: | |
1062 void clear_inline_cache(); | |
1063 | |
1064 // find the matching static_stub | |
1065 address static_stub(); | |
1066 }; | |
1067 | |
1068 class static_stub_Relocation : public Relocation { | |
1069 relocInfo::relocType type() { return relocInfo::static_stub_type; } | |
1070 | |
1071 public: | |
1072 static RelocationHolder spec(address static_call) { | |
1073 RelocationHolder rh = newHolder(); | |
1074 new(rh) static_stub_Relocation(static_call); | |
1075 return rh; | |
1076 } | |
1077 | |
1078 private: | |
1079 address _static_call; // location of corresponding static_call | |
1080 | |
1081 static_stub_Relocation(address static_call) { | |
1082 _static_call = static_call; | |
1083 } | |
1084 | |
1085 friend class RelocIterator; | |
1086 static_stub_Relocation() { } | |
1087 | |
1088 public: | |
1089 void clear_inline_cache(); | |
1090 | |
1091 address static_call() { return _static_call; } | |
1092 | |
1093 // data is packed as a scaled offset in "1_int" format: [c] or [Cc] | |
1094 void pack_data_to(CodeSection* dest); | |
1095 void unpack_data(); | |
1096 }; | |
1097 | |
1098 class runtime_call_Relocation : public CallRelocation { | |
1099 relocInfo::relocType type() { return relocInfo::runtime_call_type; } | |
1100 | |
1101 public: | |
1102 static RelocationHolder spec() { | |
1103 RelocationHolder rh = newHolder(); | |
1104 new(rh) runtime_call_Relocation(); | |
1105 return rh; | |
1106 } | |
1107 | |
1108 private: | |
1109 friend class RelocIterator; | |
1110 runtime_call_Relocation() { } | |
1111 | |
1112 public: | |
1113 }; | |
1114 | |
1115 class external_word_Relocation : public DataRelocation { | |
1116 relocInfo::relocType type() { return relocInfo::external_word_type; } | |
1117 | |
1118 public: | |
1119 static RelocationHolder spec(address target) { | |
1120 assert(target != NULL, "must not be null"); | |
1121 RelocationHolder rh = newHolder(); | |
1122 new(rh) external_word_Relocation(target); | |
1123 return rh; | |
1124 } | |
1125 | |
1126 // Use this one where all 32/64 bits of the target live in the code stream. | |
1127 // The target must be an intptr_t, and must be absolute (not relative). | |
1128 static RelocationHolder spec_for_immediate() { | |
1129 RelocationHolder rh = newHolder(); | |
1130 new(rh) external_word_Relocation(NULL); | |
1131 return rh; | |
1132 } | |
1133 | |
2455
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2375
diff
changeset
|
1134 // Some address looking values aren't safe to treat as relocations |
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2375
diff
changeset
|
1135 // and should just be treated as constants. |
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2375
diff
changeset
|
1136 static bool can_be_relocated(address target) { |
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2375
diff
changeset
|
1137 return target != NULL && !is_reloc_index((intptr_t)target); |
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2375
diff
changeset
|
1138 } |
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2375
diff
changeset
|
1139 |
0 | 1140 private: |
1141 address _target; // address in runtime | |
1142 | |
1143 external_word_Relocation(address target) { | |
1144 _target = target; | |
1145 } | |
1146 | |
1147 friend class RelocIterator; | |
1148 external_word_Relocation() { } | |
1149 | |
1150 public: | |
1151 // data is packed as a well-known address in "1_int" format: [a] or [Aa] | |
1152 // The function runtime_address_to_index is used to turn full addresses | |
1153 // to short indexes, if they are pre-registered by the stub mechanism. | |
1154 // If the "a" value is 0 (i.e., _target is NULL), the address is stored | |
1155 // in the code stream. See external_word_Relocation::target(). | |
1156 void pack_data_to(CodeSection* dest); | |
1157 void unpack_data(); | |
1158 | |
1159 void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest); | |
1160 address target(); // if _target==NULL, fetch addr from code stream | |
1161 address value() { return target(); } | |
1162 }; | |
1163 | |
1164 class internal_word_Relocation : public DataRelocation { | |
1165 relocInfo::relocType type() { return relocInfo::internal_word_type; } | |
1166 | |
1167 public: | |
1168 static RelocationHolder spec(address target) { | |
1169 assert(target != NULL, "must not be null"); | |
1170 RelocationHolder rh = newHolder(); | |
1171 new(rh) internal_word_Relocation(target); | |
1172 return rh; | |
1173 } | |
1174 | |
1175 // use this one where all the bits of the target can fit in the code stream: | |
1176 static RelocationHolder spec_for_immediate() { | |
1177 RelocationHolder rh = newHolder(); | |
1178 new(rh) internal_word_Relocation(NULL); | |
1179 return rh; | |
1180 } | |
1181 | |
1182 internal_word_Relocation(address target) { | |
1183 _target = target; | |
1184 _section = -1; // self-relative | |
1185 } | |
1186 | |
1187 protected: | |
1188 address _target; // address in CodeBlob | |
1189 int _section; // section providing base address, if any | |
1190 | |
1191 friend class RelocIterator; | |
1192 internal_word_Relocation() { } | |
1193 | |
1194 // bit-width of LSB field in packed offset, if section >= 0 | |
1195 enum { section_width = 2 }; // must equal CodeBuffer::sect_bits | |
1196 | |
1197 public: | |
1198 // data is packed as a scaled offset in "1_int" format: [o] or [Oo] | |
1199 // If the "o" value is 0 (i.e., _target is NULL), the offset is stored | |
1200 // in the code stream. See internal_word_Relocation::target(). | |
1201 // If _section is not -1, it is appended to the low bits of the offset. | |
1202 void pack_data_to(CodeSection* dest); | |
1203 void unpack_data(); | |
1204 | |
1205 void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest); | |
1206 address target(); // if _target==NULL, fetch addr from code stream | |
1207 int section() { return _section; } | |
1208 address value() { return target(); } | |
1209 }; | |
1210 | |
1211 class section_word_Relocation : public internal_word_Relocation { | |
1212 relocInfo::relocType type() { return relocInfo::section_word_type; } | |
1213 | |
1214 public: | |
1215 static RelocationHolder spec(address target, int section) { | |
1216 RelocationHolder rh = newHolder(); | |
1217 new(rh) section_word_Relocation(target, section); | |
1218 return rh; | |
1219 } | |
1220 | |
1221 section_word_Relocation(address target, int section) { | |
1222 assert(target != NULL, "must not be null"); | |
1223 assert(section >= 0, "must be a valid section"); | |
1224 _target = target; | |
1225 _section = section; | |
1226 } | |
1227 | |
1228 //void pack_data_to -- inherited | |
1229 void unpack_data(); | |
1230 | |
1231 private: | |
1232 friend class RelocIterator; | |
1233 section_word_Relocation() { } | |
1234 }; | |
1235 | |
1236 | |
1237 class poll_Relocation : public Relocation { | |
1238 bool is_data() { return true; } | |
1239 relocInfo::relocType type() { return relocInfo::poll_type; } | |
304 | 1240 void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest); |
0 | 1241 }; |
1242 | |
1243 class poll_return_Relocation : public Relocation { | |
1244 bool is_data() { return true; } | |
1245 relocInfo::relocType type() { return relocInfo::poll_return_type; } | |
304 | 1246 void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest); |
0 | 1247 }; |
1248 | |
1249 | |
1250 class breakpoint_Relocation : public Relocation { | |
1251 relocInfo::relocType type() { return relocInfo::breakpoint_type; } | |
1252 | |
1253 enum { | |
1254 // attributes which affect the interpretation of the data: | |
1255 removable_attr = 0x0010, // buffer [i...] allows for undoing the trap | |
1256 internal_attr = 0x0020, // the target is an internal addr (local stub) | |
1257 settable_attr = 0x0040, // the target is settable | |
1258 | |
1259 // states which can change over time: | |
1260 enabled_state = 0x0100, // breakpoint must be active in running code | |
1261 active_state = 0x0200, // breakpoint instruction actually in code | |
1262 | |
1263 kind_mask = 0x000F, // mask for extracting kind | |
1264 high_bit = 0x4000 // extra bit which is always set | |
1265 }; | |
1266 | |
1267 public: | |
1268 enum { | |
1269 // kinds: | |
1270 initialization = 1, | |
1271 safepoint = 2 | |
1272 }; | |
1273 | |
1274 // If target is NULL, 32 bits are reserved for a later set_target(). | |
1275 static RelocationHolder spec(int kind, address target = NULL, bool internal_target = false) { | |
1276 RelocationHolder rh = newHolder(); | |
1277 new(rh) breakpoint_Relocation(kind, target, internal_target); | |
1278 return rh; | |
1279 } | |
1280 | |
1281 private: | |
1282 // We require every bits value to NOT to fit into relocInfo::datalen_width, | |
1283 // because we are going to actually store state in the reloc, and so | |
1284 // cannot allow it to be compressed (and hence copied by the iterator). | |
1285 | |
1286 short _bits; // bit-encoded kind, attrs, & state | |
1287 address _target; | |
1288 | |
1289 breakpoint_Relocation(int kind, address target, bool internal_target); | |
1290 | |
1291 friend class RelocIterator; | |
1292 breakpoint_Relocation() { } | |
1293 | |
1294 short bits() const { return _bits; } | |
1295 short& live_bits() const { return data()[0]; } | |
1296 short* instrs() const { return data() + datalen() - instrlen(); } | |
1297 int instrlen() const { return removable() ? pd_breakpoint_size() : 0; } | |
1298 | |
1299 void set_bits(short x) { | |
1300 assert(live_bits() == _bits, "must be the only mutator of reloc info"); | |
1301 live_bits() = _bits = x; | |
1302 } | |
1303 | |
1304 public: | |
1305 address target() const; | |
1306 void set_target(address x); | |
1307 | |
1308 int kind() const { return bits() & kind_mask; } | |
1309 bool enabled() const { return (bits() & enabled_state) != 0; } | |
1310 bool active() const { return (bits() & active_state) != 0; } | |
1311 bool internal() const { return (bits() & internal_attr) != 0; } | |
1312 bool removable() const { return (bits() & removable_attr) != 0; } | |
1313 bool settable() const { return (bits() & settable_attr) != 0; } | |
1314 | |
1315 void set_enabled(bool b); // to activate, you must also say set_active | |
1316 void set_active(bool b); // actually inserts bpt (must be enabled 1st) | |
1317 | |
1318 // data is packed as 16 bits, followed by the target (1 or 2 words), followed | |
1319 // if necessary by empty storage for saving away original instruction bytes. | |
1320 void pack_data_to(CodeSection* dest); | |
1321 void unpack_data(); | |
1322 | |
1323 // during certain operations, breakpoints must be out of the way: | |
1324 void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { | |
1325 assert(!active(), "cannot perform relocation on enabled breakpoints"); | |
1326 } | |
1327 }; | |
1328 | |
1329 | |
1330 // We know all the xxx_Relocation classes, so now we can define these: | |
1331 #define EACH_CASE(name) \ | |
1332 inline name##_Relocation* RelocIterator::name##_reloc() { \ | |
1333 assert(type() == relocInfo::name##_type, "type must agree"); \ | |
1334 /* The purpose of the placed "new" is to re-use the same */ \ | |
1335 /* stack storage for each new iteration. */ \ | |
1336 name##_Relocation* r = new(_rh) name##_Relocation(); \ | |
1337 r->set_binding(this); \ | |
1338 r->name##_Relocation::unpack_data(); \ | |
1339 return r; \ | |
1340 } | |
1341 APPLY_TO_RELOCATIONS(EACH_CASE); | |
1342 #undef EACH_CASE | |
1343 | |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
337
diff
changeset
|
1344 inline RelocIterator::RelocIterator(nmethod* nm, address begin, address limit) { |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
337
diff
changeset
|
1345 initialize(nm, begin, limit); |
0 | 1346 } |
1347 | |
1348 // if you are going to patch code, you should use this subclass of | |
1349 // RelocIterator | |
1350 class PatchingRelocIterator : public RelocIterator { | |
1351 private: | |
1352 RelocIterator _init_state; | |
1353 | |
1354 void prepass(); // deactivates all breakpoints | |
1355 void postpass(); // reactivates all enabled breakpoints | |
1356 | |
1357 // do not copy these puppies; it would have unpredictable side effects | |
1358 // these are private and have no bodies defined because they should not be called | |
1359 PatchingRelocIterator(const RelocIterator&); | |
1360 void operator=(const RelocIterator&); | |
1361 | |
1362 public: | |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
337
diff
changeset
|
1363 PatchingRelocIterator(nmethod* nm, address begin = NULL, address limit = NULL) |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
337
diff
changeset
|
1364 : RelocIterator(nm, begin, limit) { prepass(); } |
0 | 1365 |
1366 ~PatchingRelocIterator() { postpass(); } | |
1367 }; | |
1972 | 1368 |
1369 #endif // SHARE_VM_CODE_RELOCINFO_HPP |