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