Mercurial > hg > truffle
comparison src/share/vm/code/relocInfo.hpp @ 11041:7875ea94bea5
8017308: Remove unused breakpoint relocation type
Summary: remove unused breakpoint relocation type
Reviewed-by: kvn
author | goetz |
---|---|
date | Mon, 24 Jun 2013 11:53:54 -0700 |
parents | da91efe96a93 |
children | 9758d9f36299 53fa76359eb1 |
comparison
equal
deleted
inserted
replaced
11025:fc8a1a5de78e | 11041:7875ea94bea5 |
---|---|
47 // A ValueObj type which acts as a union holding a Relocation object. | 47 // A ValueObj type which acts as a union holding a Relocation object. |
48 // Represents a relocation spec passed into a CodeBuffer during assembly. | 48 // Represents a relocation spec passed into a CodeBuffer during assembly. |
49 // RelocIterator | 49 // RelocIterator |
50 // A StackObj which iterates over the relocations associated with | 50 // A StackObj which iterates over the relocations associated with |
51 // a range of code addresses. Can be used to operate a copy of code. | 51 // a range of code addresses. Can be used to operate a copy of code. |
52 // PatchingRelocIterator | |
53 // Specialized subtype of RelocIterator which removes breakpoints | |
54 // temporarily during iteration, then restores them. | |
55 // BoundRelocation | 52 // BoundRelocation |
56 // An _internal_ type shared by packers and unpackers of relocations. | 53 // An _internal_ type shared by packers and unpackers of relocations. |
57 // It pastes together a RelocationHolder with some pointers into | 54 // It pastes together a RelocationHolder with some pointers into |
58 // code and relocInfo streams. | 55 // code and relocInfo streams. |
59 | 56 |
201 // subset of the set-oops has been correctly from the clean state | 198 // subset of the set-oops has been correctly from the clean state |
202 // upon entry to the VEP of the compiled method. In the case of a | 199 // upon entry to the VEP of the compiled method. In the case of a |
203 // machine (Intel) with a single set-oop instruction, the 32-bit | 200 // machine (Intel) with a single set-oop instruction, the 32-bit |
204 // immediate field must not straddle a unit of memory coherence. | 201 // immediate field must not straddle a unit of memory coherence. |
205 // //%note reloc_3 | 202 // //%note reloc_3 |
206 // | |
207 // relocInfo::breakpoint_type -- a conditional breakpoint in the code | |
208 // Value: none | |
209 // Instruction types: any whatsoever | |
210 // Data: [b [T]t i...] | |
211 // The b is a bit-packed word representing the breakpoint's attributes. | |
212 // The t is a target address which the breakpoint calls (when it is enabled). | |
213 // The i... is a place to store one or two instruction words overwritten | |
214 // by a trap, so that the breakpoint may be subsequently removed. | |
215 // | 203 // |
216 // relocInfo::static_stub_type -- an extra stub for each static_call_type | 204 // relocInfo::static_stub_type -- an extra stub for each static_call_type |
217 // Value: none | 205 // Value: none |
218 // Instruction types: a virtual call: { set_oop; jump; } | 206 // Instruction types: a virtual call: { set_oop; jump; } |
219 // Data: [[N]n] the offset of the associated static_call reloc | 207 // Data: [[N]n] the offset of the associated static_call reloc |
269 external_word_type = 7, // reference to fixed external address | 257 external_word_type = 7, // reference to fixed external address |
270 internal_word_type = 8, // reference within the current code blob | 258 internal_word_type = 8, // reference within the current code blob |
271 section_word_type = 9, // internal, but a cross-section reference | 259 section_word_type = 9, // internal, but a cross-section reference |
272 poll_type = 10, // polling instruction for safepoints | 260 poll_type = 10, // polling instruction for safepoints |
273 poll_return_type = 11, // polling instruction for safepoints at return | 261 poll_return_type = 11, // polling instruction for safepoints at return |
274 breakpoint_type = 12, // an initialization barrier or safepoint | 262 metadata_type = 12, // metadata that used to be oops |
275 metadata_type = 13, // metadata that used to be oops | 263 yet_unused_type_1 = 13, // Still unused |
276 yet_unused_type_2 = 14, // Still unused | 264 yet_unused_type_2 = 14, // Still unused |
277 data_prefix_tag = 15, // tag for a prefix (carries data arguments) | 265 data_prefix_tag = 15, // tag for a prefix (carries data arguments) |
278 type_mask = 15 // A mask which selects only the above values | 266 type_mask = 15 // A mask which selects only the above values |
279 }; | 267 }; |
280 | 268 |
310 visitor(runtime_call) \ | 298 visitor(runtime_call) \ |
311 visitor(external_word) \ | 299 visitor(external_word) \ |
312 visitor(internal_word) \ | 300 visitor(internal_word) \ |
313 visitor(poll) \ | 301 visitor(poll) \ |
314 visitor(poll_return) \ | 302 visitor(poll_return) \ |
315 visitor(breakpoint) \ | |
316 visitor(section_word) \ | 303 visitor(section_word) \ |
317 | 304 |
318 | 305 |
319 public: | 306 public: |
320 enum { | 307 enum { |
452 format_mask = (1<<format_width) - 1 | 439 format_mask = (1<<format_width) - 1 |
453 }; | 440 }; |
454 public: | 441 public: |
455 enum { | 442 enum { |
456 // Conservatively large estimate of maximum length (in shorts) | 443 // Conservatively large estimate of maximum length (in shorts) |
457 // of any relocation record (probably breakpoints are largest). | 444 // of any relocation record. |
458 // Extended format is length prefix, data words, and tag/offset suffix. | 445 // Extended format is length prefix, data words, and tag/offset suffix. |
459 length_limit = 1 + 1 + (3*BytesPerWord/BytesPerShort) + 1, | 446 length_limit = 1 + 1 + (3*BytesPerWord/BytesPerShort) + 1, |
460 have_format = format_width > 0 | 447 have_format = format_width > 0 |
461 }; | 448 }; |
462 }; | 449 }; |
569 | 556 |
570 void initialize_misc(); | 557 void initialize_misc(); |
571 | 558 |
572 void initialize(nmethod* nm, address begin, address limit); | 559 void initialize(nmethod* nm, address begin, address limit); |
573 | 560 |
574 friend class PatchingRelocIterator; | |
575 // make an uninitialized one, for PatchingRelocIterator: | |
576 RelocIterator() { initialize_misc(); } | 561 RelocIterator() { initialize_misc(); } |
577 | 562 |
578 public: | 563 public: |
579 // constructor | 564 // constructor |
580 RelocIterator(nmethod* nm, address begin = NULL, address limit = NULL); | 565 RelocIterator(nmethod* nm, address begin = NULL, address limit = NULL); |
777 // platform-dependent utilities for decoding and patching instructions | 762 // platform-dependent utilities for decoding and patching instructions |
778 void pd_set_data_value (address x, intptr_t off, bool verify_only = false); // a set or mem-ref | 763 void pd_set_data_value (address x, intptr_t off, bool verify_only = false); // a set or mem-ref |
779 void pd_verify_data_value (address x, intptr_t off) { pd_set_data_value(x, off, true); } | 764 void pd_verify_data_value (address x, intptr_t off) { pd_set_data_value(x, off, true); } |
780 address pd_call_destination (address orig_addr = NULL); | 765 address pd_call_destination (address orig_addr = NULL); |
781 void pd_set_call_destination (address x); | 766 void pd_set_call_destination (address x); |
782 void pd_swap_in_breakpoint (address x, short* instrs, int instrlen); | |
783 void pd_swap_out_breakpoint (address x, short* instrs, int instrlen); | |
784 static int pd_breakpoint_size (); | |
785 | 767 |
786 // this extracts the address of an address in the code stream instead of the reloc data | 768 // this extracts the address of an address in the code stream instead of the reloc data |
787 address* pd_address_in_code (); | 769 address* pd_address_in_code (); |
788 | 770 |
789 // this extracts an address from the code stream instead of the reloc data | 771 // this extracts an address from the code stream instead of the reloc data |
1299 class poll_return_Relocation : public Relocation { | 1281 class poll_return_Relocation : public Relocation { |
1300 bool is_data() { return true; } | 1282 bool is_data() { return true; } |
1301 relocInfo::relocType type() { return relocInfo::poll_return_type; } | 1283 relocInfo::relocType type() { return relocInfo::poll_return_type; } |
1302 void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest); | 1284 void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest); |
1303 }; | 1285 }; |
1304 | |
1305 | |
1306 class breakpoint_Relocation : public Relocation { | |
1307 relocInfo::relocType type() { return relocInfo::breakpoint_type; } | |
1308 | |
1309 enum { | |
1310 // attributes which affect the interpretation of the data: | |
1311 removable_attr = 0x0010, // buffer [i...] allows for undoing the trap | |
1312 internal_attr = 0x0020, // the target is an internal addr (local stub) | |
1313 settable_attr = 0x0040, // the target is settable | |
1314 | |
1315 // states which can change over time: | |
1316 enabled_state = 0x0100, // breakpoint must be active in running code | |
1317 active_state = 0x0200, // breakpoint instruction actually in code | |
1318 | |
1319 kind_mask = 0x000F, // mask for extracting kind | |
1320 high_bit = 0x4000 // extra bit which is always set | |
1321 }; | |
1322 | |
1323 public: | |
1324 enum { | |
1325 // kinds: | |
1326 initialization = 1, | |
1327 safepoint = 2 | |
1328 }; | |
1329 | |
1330 // If target is NULL, 32 bits are reserved for a later set_target(). | |
1331 static RelocationHolder spec(int kind, address target = NULL, bool internal_target = false) { | |
1332 RelocationHolder rh = newHolder(); | |
1333 new(rh) breakpoint_Relocation(kind, target, internal_target); | |
1334 return rh; | |
1335 } | |
1336 | |
1337 private: | |
1338 // We require every bits value to NOT to fit into relocInfo::datalen_width, | |
1339 // because we are going to actually store state in the reloc, and so | |
1340 // cannot allow it to be compressed (and hence copied by the iterator). | |
1341 | |
1342 short _bits; // bit-encoded kind, attrs, & state | |
1343 address _target; | |
1344 | |
1345 breakpoint_Relocation(int kind, address target, bool internal_target); | |
1346 | |
1347 friend class RelocIterator; | |
1348 breakpoint_Relocation() { } | |
1349 | |
1350 short bits() const { return _bits; } | |
1351 short& live_bits() const { return data()[0]; } | |
1352 short* instrs() const { return data() + datalen() - instrlen(); } | |
1353 int instrlen() const { return removable() ? pd_breakpoint_size() : 0; } | |
1354 | |
1355 void set_bits(short x) { | |
1356 assert(live_bits() == _bits, "must be the only mutator of reloc info"); | |
1357 live_bits() = _bits = x; | |
1358 } | |
1359 | |
1360 public: | |
1361 address target() const; | |
1362 void set_target(address x); | |
1363 | |
1364 int kind() const { return bits() & kind_mask; } | |
1365 bool enabled() const { return (bits() & enabled_state) != 0; } | |
1366 bool active() const { return (bits() & active_state) != 0; } | |
1367 bool internal() const { return (bits() & internal_attr) != 0; } | |
1368 bool removable() const { return (bits() & removable_attr) != 0; } | |
1369 bool settable() const { return (bits() & settable_attr) != 0; } | |
1370 | |
1371 void set_enabled(bool b); // to activate, you must also say set_active | |
1372 void set_active(bool b); // actually inserts bpt (must be enabled 1st) | |
1373 | |
1374 // data is packed as 16 bits, followed by the target (1 or 2 words), followed | |
1375 // if necessary by empty storage for saving away original instruction bytes. | |
1376 void pack_data_to(CodeSection* dest); | |
1377 void unpack_data(); | |
1378 | |
1379 // during certain operations, breakpoints must be out of the way: | |
1380 void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { | |
1381 assert(!active(), "cannot perform relocation on enabled breakpoints"); | |
1382 } | |
1383 }; | |
1384 | |
1385 | 1286 |
1386 // We know all the xxx_Relocation classes, so now we can define these: | 1287 // We know all the xxx_Relocation classes, so now we can define these: |
1387 #define EACH_CASE(name) \ | 1288 #define EACH_CASE(name) \ |
1388 inline name##_Relocation* RelocIterator::name##_reloc() { \ | 1289 inline name##_Relocation* RelocIterator::name##_reloc() { \ |
1389 assert(type() == relocInfo::name##_type, "type must agree"); \ | 1290 assert(type() == relocInfo::name##_type, "type must agree"); \ |
1399 | 1300 |
1400 inline RelocIterator::RelocIterator(nmethod* nm, address begin, address limit) { | 1301 inline RelocIterator::RelocIterator(nmethod* nm, address begin, address limit) { |
1401 initialize(nm, begin, limit); | 1302 initialize(nm, begin, limit); |
1402 } | 1303 } |
1403 | 1304 |
1404 // if you are going to patch code, you should use this subclass of | |
1405 // RelocIterator | |
1406 class PatchingRelocIterator : public RelocIterator { | |
1407 private: | |
1408 RelocIterator _init_state; | |
1409 | |
1410 void prepass(); // deactivates all breakpoints | |
1411 void postpass(); // reactivates all enabled breakpoints | |
1412 | |
1413 // do not copy these puppies; it would have unpredictable side effects | |
1414 // these are private and have no bodies defined because they should not be called | |
1415 PatchingRelocIterator(const RelocIterator&); | |
1416 void operator=(const RelocIterator&); | |
1417 | |
1418 public: | |
1419 PatchingRelocIterator(nmethod* nm, address begin = NULL, address limit = NULL) | |
1420 : RelocIterator(nm, begin, limit) { prepass(); } | |
1421 | |
1422 ~PatchingRelocIterator() { postpass(); } | |
1423 }; | |
1424 | |
1425 #endif // SHARE_VM_CODE_RELOCINFO_HPP | 1305 #endif // SHARE_VM_CODE_RELOCINFO_HPP |