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 |
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 |