src/share/vm/code/relocInfo.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 6951083 Sdiff src/share/vm/code

src/share/vm/code/relocInfo.cpp

Print this page


   1 /*
   2  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
   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  *
  19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  20  * CA 95054 USA or visit www.sun.com if you need additional information or
  21  * have any questions.
  22  *


  98   bool found = false;
  99   while (itr->next() && !found) {
 100     if (itr->addr() == pc) {
 101       assert(itr->type()==old_type, "wrong relocInfo type found");
 102       itr->current()->set_type(new_type);
 103       found=true;
 104     }
 105   }
 106   assert(found, "no relocInfo found for pc");
 107 }
 108 
 109 
 110 void relocInfo::remove_reloc_info_for_address(RelocIterator *itr, address pc, relocType old_type) {
 111   change_reloc_info_for_address(itr, pc, old_type, none);
 112 }
 113 
 114 
 115 // ----------------------------------------------------------------------------------------------------
 116 // Implementation of RelocIterator
 117 
 118 void RelocIterator::initialize(CodeBlob* cb, address begin, address limit) {
 119   initialize_misc();
 120 
 121   if (cb == NULL && begin != NULL) {
 122     // allow CodeBlob to be deduced from beginning address
 123     cb = CodeCache::find_blob(begin);
 124   }
 125   assert(cb != NULL, "must be able to deduce nmethod from other arguments");
 126 
 127   _code    = cb;
 128   _current = cb->relocation_begin()-1;
 129   _end     = cb->relocation_end();
 130   _addr    = (address) cb->instructions_begin();

 131 
 132   assert(!has_current(), "just checking");
 133   address code_end = cb->instructions_end();
 134 
 135   assert(begin == NULL || begin >= cb->instructions_begin(), "in bounds");
 136  // FIX THIS  assert(limit == NULL || limit <= code_end,     "in bounds");
 137   set_limits(begin, limit);
 138 }
 139 
 140 
 141 RelocIterator::RelocIterator(CodeSection* cs, address begin, address limit) {
 142   initialize_misc();
 143 
 144   _current = cs->locs_start()-1;
 145   _end     = cs->locs_end();
 146   _addr    = cs->start();
 147   _code    = NULL; // Not cb->blob();
 148 
 149   CodeBuffer* cb = cs->outer();
 150   assert((int)SECT_LIMIT == CodeBuffer::SECT_LIMIT, "my copy must be equal");
 151   for (int n = 0; n < (int)SECT_LIMIT; n++) {
 152     _section_start[n] = cb->code_section(n)->start();
 153   }
 154 
 155   assert(!has_current(), "just checking");


 737 
 738   int targetlen = datalen() - 1 - instrlen();
 739   jint target_bits = 0;
 740   if (targetlen == 0)       target_bits = 0;
 741   else if (targetlen == 1)  target_bits = *(data()+1);
 742   else if (targetlen == 2)  target_bits = relocInfo::jint_from_data(data()+1);
 743   else                      { ShouldNotReachHere(); }
 744 
 745   _target = internal() ? address_from_scaled_offset(target_bits, addr())
 746                        : index_to_runtime_address  (target_bits);
 747 }
 748 
 749 
 750 //// miscellaneous methods
 751 oop* oop_Relocation::oop_addr() {
 752   int n = _oop_index;
 753   if (n == 0) {
 754     // oop is stored in the code stream
 755     return (oop*) pd_address_in_code();
 756   } else {
 757     // oop is stored in table at CodeBlob::oops_begin
 758     return code()->oop_addr_at(n);
 759   }
 760 }
 761 
 762 
 763 oop oop_Relocation::oop_value() {
 764   oop v = *oop_addr();
 765   // clean inline caches store a special pseudo-null
 766   if (v == (oop)Universe::non_oop_word())  v = NULL;
 767   return v;
 768 }
 769 
 770 
 771 void oop_Relocation::fix_oop_relocation() {
 772   if (!oop_is_immediate()) {
 773     // get the oop from the pool, and re-insert it into the instruction:
 774     set_value(value());
 775   }
 776 }
 777 
 778 
 779 RelocIterator virtual_call_Relocation::parse_ic(CodeBlob* &code, address &ic_call, address &first_oop,
 780                                                 oop* &oop_addr, bool *is_optimized) {
 781   assert(ic_call != NULL, "ic_call address must be set");
 782   assert(ic_call != NULL || first_oop != NULL, "must supply a non-null input");
 783   if (code == NULL) {

 784     if (ic_call != NULL) {
 785       code = CodeCache::find_blob(ic_call);
 786     } else if (first_oop != NULL) {
 787       code = CodeCache::find_blob(first_oop);
 788     }
 789     assert(code != NULL, "address to parse must be in CodeBlob");

 790   }
 791   assert(ic_call   == NULL || code->contains(ic_call),   "must be in CodeBlob");
 792   assert(first_oop == NULL || code->contains(first_oop), "must be in CodeBlob");
 793 
 794   address oop_limit = NULL;
 795 
 796   if (ic_call != NULL) {
 797     // search for the ic_call at the given address
 798     RelocIterator iter(code, ic_call, ic_call+1);
 799     bool ret = iter.next();
 800     assert(ret == true, "relocInfo must exist at this address");
 801     assert(iter.addr() == ic_call, "must find ic_call");
 802     if (iter.type() == relocInfo::virtual_call_type) {
 803       virtual_call_Relocation* r = iter.virtual_call_reloc();
 804       first_oop = r->first_oop();
 805       oop_limit = r->oop_limit();
 806       *is_optimized = false;
 807     } else {
 808       assert(iter.type() == relocInfo::opt_virtual_call_type, "must be a virtual call");
 809       *is_optimized = true;
 810       oop_addr = NULL;
 811       first_oop = NULL;
 812       return iter;
 813     }
 814   }
 815 
 816   // search for the first_oop, to get its oop_addr
 817   RelocIterator all_oops(code, first_oop);
 818   RelocIterator iter = all_oops;
 819   iter.set_limit(first_oop+1);
 820   bool found_oop = false;
 821   while (iter.next()) {
 822     if (iter.type() == relocInfo::oop_type) {
 823       assert(iter.addr() == first_oop, "must find first_oop");
 824       oop_addr = iter.oop_reloc()->oop_addr();
 825       found_oop = true;
 826       break;
 827     }
 828   }
 829   assert(found_oop, "must find first_oop");
 830 
 831   bool did_reset = false;
 832   while (ic_call == NULL) {
 833     // search forward for the ic_call matching the given first_oop
 834     while (iter.next()) {
 835       if (iter.type() == relocInfo::virtual_call_type) {
 836         virtual_call_Relocation* r = iter.virtual_call_reloc();
 837         if (r->first_oop() == first_oop) {
 838           ic_call   = r->addr();
 839           oop_limit = r->oop_limit();
 840           break;
 841         }
 842       }
 843     }
 844     guarantee(!did_reset, "cannot find ic_call");
 845     iter = RelocIterator(code); // search the whole CodeBlob
 846     did_reset = true;
 847   }
 848 
 849   assert(oop_limit != NULL && first_oop != NULL && ic_call != NULL, "");
 850   all_oops.set_limit(oop_limit);
 851   return all_oops;
 852 }
 853 
 854 
 855 address virtual_call_Relocation::first_oop() {
 856   assert(_first_oop != NULL && _first_oop < addr(), "must precede ic_call");
 857   return _first_oop;
 858 }
 859 
 860 
 861 address virtual_call_Relocation::oop_limit() {
 862   if (_oop_limit == NULL)
 863     return addr() + NativeCall::instruction_size;
 864   else
 865     return _oop_limit;


1158     skip_next = false;
1159 
1160     tty->print("         @" INTPTR_FORMAT ": ", scan);
1161     relocInfo* newscan = _current+1;
1162     if (!has_current())  newscan -= 1;  // nothing to scan here!
1163     while (scan < newscan) {
1164       tty->print("%04x", *(short*)scan & 0xFFFF);
1165       scan++;
1166     }
1167     tty->cr();
1168 
1169     if (!got_next)  break;
1170     print_current();
1171   }
1172 
1173   (*this) = save_this;
1174 }
1175 
1176 // For the debugger:
1177 extern "C"
1178 void print_blob_locs(CodeBlob* cb) {
1179   cb->print();
1180   RelocIterator iter(cb);
1181   iter.print();
1182 }
1183 extern "C"
1184 void print_buf_locs(CodeBuffer* cb) {
1185   FlagSetting fs(PrintRelocations, true);
1186   cb->print();
1187 }
1188 #endif // !PRODUCT
   1 /*
   2  * Copyright 1997-2010 Sun Microsystems, Inc.  All Rights Reserved.
   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  *
  19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  20  * CA 95054 USA or visit www.sun.com if you need additional information or
  21  * have any questions.
  22  *


  98   bool found = false;
  99   while (itr->next() && !found) {
 100     if (itr->addr() == pc) {
 101       assert(itr->type()==old_type, "wrong relocInfo type found");
 102       itr->current()->set_type(new_type);
 103       found=true;
 104     }
 105   }
 106   assert(found, "no relocInfo found for pc");
 107 }
 108 
 109 
 110 void relocInfo::remove_reloc_info_for_address(RelocIterator *itr, address pc, relocType old_type) {
 111   change_reloc_info_for_address(itr, pc, old_type, none);
 112 }
 113 
 114 
 115 // ----------------------------------------------------------------------------------------------------
 116 // Implementation of RelocIterator
 117 
 118 void RelocIterator::initialize(nmethod* nm, address begin, address limit) {
 119   initialize_misc();
 120 
 121   if (nm == NULL && begin != NULL) {
 122     // allow nmethod to be deduced from beginning address
 123     CodeBlob* cb = CodeCache::find_blob(begin);
 124     nm = cb->as_nmethod_or_null();
 125   }
 126   assert(nm != NULL, "must be able to deduce nmethod from other arguments");
 127 
 128   _code    = nm;
 129   _current = nm->relocation_begin() - 1;
 130   _end     = nm->relocation_end();
 131   _addr    = (address) nm->instructions_begin();
 132 
 133   assert(!has_current(), "just checking");
 134   address code_end = nm->instructions_end();
 135 
 136   assert(begin == NULL || begin >= nm->instructions_begin(), "in bounds");
 137  // FIX THIS  assert(limit == NULL || limit <= code_end,     "in bounds");
 138   set_limits(begin, limit);
 139 }
 140 
 141 
 142 RelocIterator::RelocIterator(CodeSection* cs, address begin, address limit) {
 143   initialize_misc();
 144 
 145   _current = cs->locs_start()-1;
 146   _end     = cs->locs_end();
 147   _addr    = cs->start();
 148   _code    = NULL; // Not cb->blob();
 149 
 150   CodeBuffer* cb = cs->outer();
 151   assert((int)SECT_LIMIT == CodeBuffer::SECT_LIMIT, "my copy must be equal");
 152   for (int n = 0; n < (int)SECT_LIMIT; n++) {
 153     _section_start[n] = cb->code_section(n)->start();
 154   }
 155 
 156   assert(!has_current(), "just checking");


 738 
 739   int targetlen = datalen() - 1 - instrlen();
 740   jint target_bits = 0;
 741   if (targetlen == 0)       target_bits = 0;
 742   else if (targetlen == 1)  target_bits = *(data()+1);
 743   else if (targetlen == 2)  target_bits = relocInfo::jint_from_data(data()+1);
 744   else                      { ShouldNotReachHere(); }
 745 
 746   _target = internal() ? address_from_scaled_offset(target_bits, addr())
 747                        : index_to_runtime_address  (target_bits);
 748 }
 749 
 750 
 751 //// miscellaneous methods
 752 oop* oop_Relocation::oop_addr() {
 753   int n = _oop_index;
 754   if (n == 0) {
 755     // oop is stored in the code stream
 756     return (oop*) pd_address_in_code();
 757   } else {
 758     // oop is stored in table at nmethod::oops_begin
 759     return code()->oop_addr_at(n);
 760   }
 761 }
 762 
 763 
 764 oop oop_Relocation::oop_value() {
 765   oop v = *oop_addr();
 766   // clean inline caches store a special pseudo-null
 767   if (v == (oop)Universe::non_oop_word())  v = NULL;
 768   return v;
 769 }
 770 
 771 
 772 void oop_Relocation::fix_oop_relocation() {
 773   if (!oop_is_immediate()) {
 774     // get the oop from the pool, and re-insert it into the instruction:
 775     set_value(value());
 776   }
 777 }
 778 
 779 
 780 RelocIterator virtual_call_Relocation::parse_ic(nmethod* &nm, address &ic_call, address &first_oop,
 781                                                 oop* &oop_addr, bool *is_optimized) {
 782   assert(ic_call != NULL, "ic_call address must be set");
 783   assert(ic_call != NULL || first_oop != NULL, "must supply a non-null input");
 784   if (nm == NULL) {
 785     CodeBlob* code;
 786     if (ic_call != NULL) {
 787       code = CodeCache::find_blob(ic_call);
 788     } else if (first_oop != NULL) {
 789       code = CodeCache::find_blob(first_oop);
 790     }
 791     nm = code->as_nmethod_or_null();
 792     assert(nm != NULL, "address to parse must be in nmethod");
 793   }
 794   assert(ic_call   == NULL || nm->contains(ic_call),   "must be in nmethod");
 795   assert(first_oop == NULL || nm->contains(first_oop), "must be in nmethod");
 796 
 797   address oop_limit = NULL;
 798 
 799   if (ic_call != NULL) {
 800     // search for the ic_call at the given address
 801     RelocIterator iter(nm, ic_call, ic_call+1);
 802     bool ret = iter.next();
 803     assert(ret == true, "relocInfo must exist at this address");
 804     assert(iter.addr() == ic_call, "must find ic_call");
 805     if (iter.type() == relocInfo::virtual_call_type) {
 806       virtual_call_Relocation* r = iter.virtual_call_reloc();
 807       first_oop = r->first_oop();
 808       oop_limit = r->oop_limit();
 809       *is_optimized = false;
 810     } else {
 811       assert(iter.type() == relocInfo::opt_virtual_call_type, "must be a virtual call");
 812       *is_optimized = true;
 813       oop_addr = NULL;
 814       first_oop = NULL;
 815       return iter;
 816     }
 817   }
 818 
 819   // search for the first_oop, to get its oop_addr
 820   RelocIterator all_oops(nm, first_oop);
 821   RelocIterator iter = all_oops;
 822   iter.set_limit(first_oop+1);
 823   bool found_oop = false;
 824   while (iter.next()) {
 825     if (iter.type() == relocInfo::oop_type) {
 826       assert(iter.addr() == first_oop, "must find first_oop");
 827       oop_addr = iter.oop_reloc()->oop_addr();
 828       found_oop = true;
 829       break;
 830     }
 831   }
 832   assert(found_oop, "must find first_oop");
 833 
 834   bool did_reset = false;
 835   while (ic_call == NULL) {
 836     // search forward for the ic_call matching the given first_oop
 837     while (iter.next()) {
 838       if (iter.type() == relocInfo::virtual_call_type) {
 839         virtual_call_Relocation* r = iter.virtual_call_reloc();
 840         if (r->first_oop() == first_oop) {
 841           ic_call   = r->addr();
 842           oop_limit = r->oop_limit();
 843           break;
 844         }
 845       }
 846     }
 847     guarantee(!did_reset, "cannot find ic_call");
 848     iter = RelocIterator(nm); // search the whole nmethod
 849     did_reset = true;
 850   }
 851 
 852   assert(oop_limit != NULL && first_oop != NULL && ic_call != NULL, "");
 853   all_oops.set_limit(oop_limit);
 854   return all_oops;
 855 }
 856 
 857 
 858 address virtual_call_Relocation::first_oop() {
 859   assert(_first_oop != NULL && _first_oop < addr(), "must precede ic_call");
 860   return _first_oop;
 861 }
 862 
 863 
 864 address virtual_call_Relocation::oop_limit() {
 865   if (_oop_limit == NULL)
 866     return addr() + NativeCall::instruction_size;
 867   else
 868     return _oop_limit;


1161     skip_next = false;
1162 
1163     tty->print("         @" INTPTR_FORMAT ": ", scan);
1164     relocInfo* newscan = _current+1;
1165     if (!has_current())  newscan -= 1;  // nothing to scan here!
1166     while (scan < newscan) {
1167       tty->print("%04x", *(short*)scan & 0xFFFF);
1168       scan++;
1169     }
1170     tty->cr();
1171 
1172     if (!got_next)  break;
1173     print_current();
1174   }
1175 
1176   (*this) = save_this;
1177 }
1178 
1179 // For the debugger:
1180 extern "C"
1181 void print_blob_locs(nmethod* nm) {
1182   nm->print();
1183   RelocIterator iter(nm);
1184   iter.print();
1185 }
1186 extern "C"
1187 void print_buf_locs(CodeBuffer* cb) {
1188   FlagSetting fs(PrintRelocations, true);
1189   cb->print();
1190 }
1191 #endif // !PRODUCT
src/share/vm/code/relocInfo.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File