510 |
510 |
511 private: |
511 private: |
512 address _limit; // stop producing relocations after this _addr |
512 address _limit; // stop producing relocations after this _addr |
513 relocInfo* _current; // the current relocation information |
513 relocInfo* _current; // the current relocation information |
514 relocInfo* _end; // end marker; we're done iterating when _current == _end |
514 relocInfo* _end; // end marker; we're done iterating when _current == _end |
515 CodeBlob* _code; // compiled method containing _addr |
515 nmethod* _code; // compiled method containing _addr |
516 address _addr; // instruction to which the relocation applies |
516 address _addr; // instruction to which the relocation applies |
517 short _databuf; // spare buffer for compressed data |
517 short _databuf; // spare buffer for compressed data |
518 short* _data; // pointer to the relocation's data |
518 short* _data; // pointer to the relocation's data |
519 short _datalen; // number of halfwords in _data |
519 short _datalen; // number of halfwords in _data |
520 char _format; // position within the instruction |
520 char _format; // position within the instruction |
547 } |
547 } |
548 } |
548 } |
549 |
549 |
550 address compute_section_start(int n) const; // out-of-line helper |
550 address compute_section_start(int n) const; // out-of-line helper |
551 |
551 |
552 void initialize(CodeBlob* nm, address begin, address limit); |
552 void initialize(nmethod* nm, address begin, address limit); |
553 |
553 |
554 friend class PatchingRelocIterator; |
554 friend class PatchingRelocIterator; |
555 // make an uninitialized one, for PatchingRelocIterator: |
555 // make an uninitialized one, for PatchingRelocIterator: |
556 RelocIterator() { initialize_misc(); } |
556 RelocIterator() { initialize_misc(); } |
557 |
557 |
558 public: |
558 public: |
559 // constructor |
559 // constructor |
560 RelocIterator(CodeBlob* cb, address begin = NULL, address limit = NULL); |
560 RelocIterator(nmethod* nm, address begin = NULL, address limit = NULL); |
561 RelocIterator(CodeSection* cb, address begin = NULL, address limit = NULL); |
561 RelocIterator(CodeSection* cb, address begin = NULL, address limit = NULL); |
562 |
562 |
563 // get next reloc info, return !eos |
563 // get next reloc info, return !eos |
564 bool next() { |
564 bool next() { |
565 _current++; |
565 _current++; |
590 address limit() const { return _limit; } |
590 address limit() const { return _limit; } |
591 void set_limit(address x); |
591 void set_limit(address x); |
592 relocType type() const { return current()->type(); } |
592 relocType type() const { return current()->type(); } |
593 int format() const { return (relocInfo::have_format) ? current()->format() : 0; } |
593 int format() const { return (relocInfo::have_format) ? current()->format() : 0; } |
594 address addr() const { return _addr; } |
594 address addr() const { return _addr; } |
595 CodeBlob* code() const { return _code; } |
595 nmethod* code() const { return _code; } |
596 short* data() const { return _data; } |
596 short* data() const { return _data; } |
597 int datalen() const { return _datalen; } |
597 int datalen() const { return _datalen; } |
598 bool has_current() const { return _datalen >= 0; } |
598 bool has_current() const { return _datalen >= 0; } |
599 |
599 |
600 void set_addr(address addr) { _addr = addr; } |
600 void set_addr(address addr) { _addr = addr; } |
788 address new_addr_for(address olda, 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); |
789 void normalize_address(address& addr, const CodeSection* dest, bool allow_other_sections = false); |
790 |
790 |
791 public: |
791 public: |
792 // accessors which only make sense for a bound Relocation |
792 // accessors which only make sense for a bound Relocation |
793 address addr() const { return binding()->addr(); } |
793 address addr() const { return binding()->addr(); } |
794 CodeBlob* code() const { return binding()->code(); } |
794 nmethod* code() const { return binding()->code(); } |
795 bool addr_in_const() const { return binding()->addr_in_const(); } |
795 bool addr_in_const() const { return binding()->addr_in_const(); } |
796 protected: |
796 protected: |
797 short* data() const { return binding()->data(); } |
797 short* data() const { return binding()->data(); } |
798 int datalen() const { return binding()->datalen(); } |
798 int datalen() const { return binding()->datalen(); } |
799 int format() const { return binding()->format(); } |
799 int format() const { return binding()->format(); } |
800 |
800 |
980 |
980 |
981 void clear_inline_cache(); |
981 void clear_inline_cache(); |
982 |
982 |
983 // Figure out where an ic_call is hiding, given a set-oop or call. |
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. |
984 // Either ic_call or first_oop must be non-null; the other is deduced. |
985 // Code if non-NULL must be the CodeBlob, else it is deduced. |
985 // Code if non-NULL must be the nmethod, else it is deduced. |
986 // The address of the patchable oop is also deduced. |
986 // The address of the patchable oop is also deduced. |
987 // The returned iterator will enumerate over the oops and the ic_call, |
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. |
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. |
989 // Recognize relevant set_oops with: oop_reloc()->oop_addr() == oop_addr. |
990 static RelocIterator parse_ic(CodeBlob* &code, address &ic_call, address &first_oop, oop* &oop_addr, bool *is_optimized); |
990 static RelocIterator parse_ic(nmethod* &nm, address &ic_call, address &first_oop, oop* &oop_addr, bool *is_optimized); |
991 }; |
991 }; |
992 |
992 |
993 |
993 |
994 class opt_virtual_call_Relocation : public CallRelocation { |
994 class opt_virtual_call_Relocation : public CallRelocation { |
995 relocInfo::relocType type() { return relocInfo::opt_virtual_call_type; } |
995 relocInfo::relocType type() { return relocInfo::opt_virtual_call_type; } |
1302 return r; \ |
1302 return r; \ |
1303 } |
1303 } |
1304 APPLY_TO_RELOCATIONS(EACH_CASE); |
1304 APPLY_TO_RELOCATIONS(EACH_CASE); |
1305 #undef EACH_CASE |
1305 #undef EACH_CASE |
1306 |
1306 |
1307 inline RelocIterator::RelocIterator(CodeBlob* cb, address begin, address limit) { |
1307 inline RelocIterator::RelocIterator(nmethod* nm, address begin, address limit) { |
1308 initialize(cb, begin, limit); |
1308 initialize(nm, begin, limit); |
1309 } |
1309 } |
1310 |
1310 |
1311 // if you are going to patch code, you should use this subclass of |
1311 // if you are going to patch code, you should use this subclass of |
1312 // RelocIterator |
1312 // RelocIterator |
1313 class PatchingRelocIterator : public RelocIterator { |
1313 class PatchingRelocIterator : public RelocIterator { |
1321 // these are private and have no bodies defined because they should not be called |
1321 // these are private and have no bodies defined because they should not be called |
1322 PatchingRelocIterator(const RelocIterator&); |
1322 PatchingRelocIterator(const RelocIterator&); |
1323 void operator=(const RelocIterator&); |
1323 void operator=(const RelocIterator&); |
1324 |
1324 |
1325 public: |
1325 public: |
1326 PatchingRelocIterator(CodeBlob* cb, address begin =NULL, address limit =NULL) |
1326 PatchingRelocIterator(nmethod* nm, address begin = NULL, address limit = NULL) |
1327 : RelocIterator(cb, begin, limit) { prepass(); } |
1327 : RelocIterator(nm, begin, limit) { prepass(); } |
1328 |
1328 |
1329 ~PatchingRelocIterator() { postpass(); } |
1329 ~PatchingRelocIterator() { postpass(); } |
1330 }; |
1330 }; |