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