src/share/vm/runtime/relocator.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/runtime

src/share/vm/runtime/relocator.cpp

Print this page
rev 5732 : [mq]: comments2


 124 
 125 //-----------------------------------------------------------------------------------------------------------
 126 // Relocator code
 127 
 128 Relocator::Relocator(methodHandle m, RelocatorListener* listener) {
 129   set_method(m);
 130   set_code_length(method()->code_size());
 131   set_code_array(NULL);
 132   // Allocate code array and copy bytecodes
 133   if (!expand_code_array(0)) {
 134     // Should have at least MAX_METHOD_LENGTH available or the verifier
 135     // would have failed.
 136     ShouldNotReachHere();
 137   }
 138   set_compressed_line_number_table(NULL);
 139   set_compressed_line_number_table_size(0);
 140   _listener = listener;
 141 }
 142 
 143 // size is the new size of the instruction at bci. Hence, if size is less than the current
 144 // instruction sice, we will shrink the code.
 145 methodHandle Relocator::insert_space_at(int bci, int size, u_char inst_buffer[], TRAPS) {
 146   _changes = new GrowableArray<ChangeItem*> (10);
 147   _changes->push(new ChangeWiden(bci, size, inst_buffer));
 148 
 149   if (TraceRelocator) {
 150     tty->print_cr("Space at: %d Size: %d", bci, size);
 151     _method->print();
 152     _method->print_codes();
 153     tty->print_cr("-------------------------------------------------");
 154   }
 155 
 156   if (!handle_code_changes()) return methodHandle();
 157 
 158     // Construct the new method
 159   methodHandle new_method = Method::clone_with_new_data(method(),
 160                               code_array(), code_length(),
 161                               compressed_line_number_table(),
 162                               compressed_line_number_table_size(),
 163                               CHECK_(methodHandle()));
 164 


 175   }
 176 
 177   return new_method;
 178 }
 179 
 180 
 181 bool Relocator::handle_code_changes() {
 182   assert(_changes != NULL, "changes vector must be initialized");
 183 
 184   while (!_changes->is_empty()) {
 185     // Inv: everything is aligned.
 186     ChangeItem* ci = _changes->first();
 187 
 188     if (TraceRelocator) {
 189       ci->print();
 190     }
 191 
 192     // Execute operation
 193     if (!ci->handle_code_change(this)) return false;
 194 
 195     // Shuffel items up
 196     for (int index = 1; index < _changes->length(); index++) {
 197       _changes->at_put(index-1, _changes->at(index));
 198     }
 199     _changes->pop();
 200   }
 201   return true;
 202 }
 203 
 204 
 205 bool Relocator::is_opcode_lookupswitch(Bytecodes::Code bc) {
 206   switch (bc) {
 207     case Bytecodes::_tableswitch:       return false;
 208     case Bytecodes::_lookupswitch:                   // not rewritten on ia64
 209     case Bytecodes::_fast_linearswitch:              // rewritten _lookupswitch
 210     case Bytecodes::_fast_binaryswitch: return true; // rewritten _lookupswitch
 211     default: ShouldNotReachHere();
 212   }
 213   return true; // dummy
 214 }
 215 
 216 // We need a special instruction size method, since lookupswitches and tableswitches might not be
 217 // properly alligned during relocation
 218 int Relocator::rc_instr_len(int bci) {
 219   Bytecodes::Code bc= code_at(bci);
 220   switch (bc) {
 221     // In the case of switch instructions, see if we have the original
 222     // padding recorded.
 223     case Bytecodes::_tableswitch:
 224     case Bytecodes::_lookupswitch:
 225     case Bytecodes::_fast_linearswitch:
 226     case Bytecodes::_fast_binaryswitch:
 227     {
 228       int pad = get_orig_switch_pad(bci, is_opcode_lookupswitch(bc));
 229       if (pad == -1) {
 230         return instruction_length_at(bci);
 231       }
 232       // Otherwise, depends on the switch type.
 233       switch (bc) {
 234         case Bytecodes::_tableswitch: {
 235           int lo = int_at(bci + 1 + pad + 4 * 1);
 236           int hi = int_at(bci + 1 + pad + 4 * 2);
 237           int n = hi - lo + 1;


 594 
 595 // The instruction at "bci", whose size is "ilen", is changing size by
 596 // "delta".  Reallocate, move code, recalculate jumps, and enqueue
 597 // change items as necessary.
 598 bool Relocator::relocate_code(int bci, int ilen, int delta) {
 599   int next_bci = bci + ilen;
 600   if (delta > 0 && code_length() + delta > code_array_length())  {
 601     // Expand allocated code space, if necessary.
 602     if (!expand_code_array(delta)) {
 603           return false;
 604     }
 605   }
 606 
 607   // We require 4-byte alignment of code arrays.
 608   assert(((intptr_t)code_array() & 3) == 0, "check code alignment");
 609   // Change jumps before doing the copying; this routine requires aligned switches.
 610   change_jumps(bci, delta);
 611 
 612   // In case we have shrunken a tableswitch/lookupswitch statement, we store the last
 613   // bytes that get overwritten. We have to copy the bytes after the change_jumps method
 614   // has been called, since it is likly to update last offset in a tableswitch/lookupswitch
 615   if (delta < 0) {
 616     assert(delta>=-3, "we cannot overwrite more than 3 bytes");
 617     memcpy(_overwrite, addr_at(bci + ilen + delta), -delta);
 618   }
 619 
 620   memmove(addr_at(next_bci + delta), addr_at(next_bci), code_length() - next_bci);
 621   set_code_length(code_length() + delta);
 622   // Also adjust exception tables...
 623   adjust_exception_table(bci, delta);
 624   // Line number tables...
 625   adjust_line_no_table(bci, delta);
 626   // And local variable table...
 627   adjust_local_var_table(bci, delta);
 628 
 629   // Adjust stack maps
 630   adjust_stack_map_table(bci, delta);
 631 
 632   // Relocate the pending change stack...
 633   for (int j = 0; j < _changes->length(); j++) {
 634     ChangeItem* ci = _changes->at(j);




 124 
 125 //-----------------------------------------------------------------------------------------------------------
 126 // Relocator code
 127 
 128 Relocator::Relocator(methodHandle m, RelocatorListener* listener) {
 129   set_method(m);
 130   set_code_length(method()->code_size());
 131   set_code_array(NULL);
 132   // Allocate code array and copy bytecodes
 133   if (!expand_code_array(0)) {
 134     // Should have at least MAX_METHOD_LENGTH available or the verifier
 135     // would have failed.
 136     ShouldNotReachHere();
 137   }
 138   set_compressed_line_number_table(NULL);
 139   set_compressed_line_number_table_size(0);
 140   _listener = listener;
 141 }
 142 
 143 // size is the new size of the instruction at bci. Hence, if size is less than the current
 144 // instruction size, we will shrink the code.
 145 methodHandle Relocator::insert_space_at(int bci, int size, u_char inst_buffer[], TRAPS) {
 146   _changes = new GrowableArray<ChangeItem*> (10);
 147   _changes->push(new ChangeWiden(bci, size, inst_buffer));
 148 
 149   if (TraceRelocator) {
 150     tty->print_cr("Space at: %d Size: %d", bci, size);
 151     _method->print();
 152     _method->print_codes();
 153     tty->print_cr("-------------------------------------------------");
 154   }
 155 
 156   if (!handle_code_changes()) return methodHandle();
 157 
 158     // Construct the new method
 159   methodHandle new_method = Method::clone_with_new_data(method(),
 160                               code_array(), code_length(),
 161                               compressed_line_number_table(),
 162                               compressed_line_number_table_size(),
 163                               CHECK_(methodHandle()));
 164 


 175   }
 176 
 177   return new_method;
 178 }
 179 
 180 
 181 bool Relocator::handle_code_changes() {
 182   assert(_changes != NULL, "changes vector must be initialized");
 183 
 184   while (!_changes->is_empty()) {
 185     // Inv: everything is aligned.
 186     ChangeItem* ci = _changes->first();
 187 
 188     if (TraceRelocator) {
 189       ci->print();
 190     }
 191 
 192     // Execute operation
 193     if (!ci->handle_code_change(this)) return false;
 194 
 195     // Shuffle items up
 196     for (int index = 1; index < _changes->length(); index++) {
 197       _changes->at_put(index-1, _changes->at(index));
 198     }
 199     _changes->pop();
 200   }
 201   return true;
 202 }
 203 
 204 
 205 bool Relocator::is_opcode_lookupswitch(Bytecodes::Code bc) {
 206   switch (bc) {
 207     case Bytecodes::_tableswitch:       return false;
 208     case Bytecodes::_lookupswitch:                   // not rewritten on ia64
 209     case Bytecodes::_fast_linearswitch:              // rewritten _lookupswitch
 210     case Bytecodes::_fast_binaryswitch: return true; // rewritten _lookupswitch
 211     default: ShouldNotReachHere();
 212   }
 213   return true; // dummy
 214 }
 215 
 216 // We need a special instruction size method, since lookupswitches and tableswitches might not be
 217 // properly aligned during relocation
 218 int Relocator::rc_instr_len(int bci) {
 219   Bytecodes::Code bc= code_at(bci);
 220   switch (bc) {
 221     // In the case of switch instructions, see if we have the original
 222     // padding recorded.
 223     case Bytecodes::_tableswitch:
 224     case Bytecodes::_lookupswitch:
 225     case Bytecodes::_fast_linearswitch:
 226     case Bytecodes::_fast_binaryswitch:
 227     {
 228       int pad = get_orig_switch_pad(bci, is_opcode_lookupswitch(bc));
 229       if (pad == -1) {
 230         return instruction_length_at(bci);
 231       }
 232       // Otherwise, depends on the switch type.
 233       switch (bc) {
 234         case Bytecodes::_tableswitch: {
 235           int lo = int_at(bci + 1 + pad + 4 * 1);
 236           int hi = int_at(bci + 1 + pad + 4 * 2);
 237           int n = hi - lo + 1;


 594 
 595 // The instruction at "bci", whose size is "ilen", is changing size by
 596 // "delta".  Reallocate, move code, recalculate jumps, and enqueue
 597 // change items as necessary.
 598 bool Relocator::relocate_code(int bci, int ilen, int delta) {
 599   int next_bci = bci + ilen;
 600   if (delta > 0 && code_length() + delta > code_array_length())  {
 601     // Expand allocated code space, if necessary.
 602     if (!expand_code_array(delta)) {
 603           return false;
 604     }
 605   }
 606 
 607   // We require 4-byte alignment of code arrays.
 608   assert(((intptr_t)code_array() & 3) == 0, "check code alignment");
 609   // Change jumps before doing the copying; this routine requires aligned switches.
 610   change_jumps(bci, delta);
 611 
 612   // In case we have shrunken a tableswitch/lookupswitch statement, we store the last
 613   // bytes that get overwritten. We have to copy the bytes after the change_jumps method
 614   // has been called, since it is likely to update last offset in a tableswitch/lookupswitch
 615   if (delta < 0) {
 616     assert(delta>=-3, "we cannot overwrite more than 3 bytes");
 617     memcpy(_overwrite, addr_at(bci + ilen + delta), -delta);
 618   }
 619 
 620   memmove(addr_at(next_bci + delta), addr_at(next_bci), code_length() - next_bci);
 621   set_code_length(code_length() + delta);
 622   // Also adjust exception tables...
 623   adjust_exception_table(bci, delta);
 624   // Line number tables...
 625   adjust_line_no_table(bci, delta);
 626   // And local variable table...
 627   adjust_local_var_table(bci, delta);
 628 
 629   // Adjust stack maps
 630   adjust_stack_map_table(bci, delta);
 631 
 632   // Relocate the pending change stack...
 633   for (int j = 0; j < _changes->length(); j++) {
 634     ChangeItem* ci = _changes->at(j);


src/share/vm/runtime/relocator.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File