48 |
52 |
49 address _start; // Start of bytecodes |
53 address _start; // Start of bytecodes |
50 address _end; // Past end of bytecodes |
54 address _end; // Past end of bytecodes |
51 address _pc; // Current PC |
55 address _pc; // Current PC |
52 Bytecodes::Code _bc; // Current bytecode |
56 Bytecodes::Code _bc; // Current bytecode |
|
57 Bytecodes::Code _raw_bc; // Current bytecode, raw form |
53 |
58 |
54 void reset( address base, unsigned int size ) { |
59 void reset( address base, unsigned int size ) { |
55 _bc_start =_was_wide = 0; |
60 _bc_start =_was_wide = 0; |
56 _start = _pc = base; _end = base + size; } |
61 _start = _pc = base; _end = base + size; } |
|
62 |
|
63 void assert_wide(bool require_wide) const { |
|
64 if (require_wide) |
|
65 { assert(is_wide(), "must be a wide instruction"); } |
|
66 else { assert(!is_wide(), "must not be a wide instruction"); } |
|
67 } |
|
68 |
|
69 Bytecode* bytecode() const { return Bytecode_at(_bc_start); } |
|
70 Bytecode* next_bytecode() const { return Bytecode_at(_pc); } |
57 |
71 |
58 public: |
72 public: |
59 // End-Of-Bytecodes |
73 // End-Of-Bytecodes |
60 static Bytecodes::Code EOBC() { |
74 static Bytecodes::Code EOBC() { |
61 return Bytecodes::_illegal; |
75 return Bytecodes::_illegal; |
107 _bc_start = _pc; // Capture start of bc |
122 _bc_start = _pc; // Capture start of bc |
108 if( _pc >= _end ) return EOBC(); // End-Of-Bytecodes |
123 if( _pc >= _end ) return EOBC(); // End-Of-Bytecodes |
109 |
124 |
110 // Fetch Java bytecode |
125 // Fetch Java bytecode |
111 // All rewritten bytecodes maintain the size of original bytecode. |
126 // All rewritten bytecodes maintain the size of original bytecode. |
112 _bc = Bytecodes::java_code((Bytecodes::Code)*_pc); |
127 _bc = Bytecodes::java_code(_raw_bc = (Bytecodes::Code)*_pc); |
113 int csize = Bytecodes::length_for(_bc); // Expected size |
128 int csize = Bytecodes::length_for(_bc); // Expected size |
114 |
129 _pc += csize; // Bump PC past bytecode |
115 if( _bc == Bytecodes::_wide ) { |
130 if (csize == 0) { |
116 _bc=wide(); // Handle wide bytecode |
131 _bc = next_wide_or_table(_bc); |
117 } else if( csize == 0 ) { |
|
118 _bc=table(_bc); // Handle inline tables |
|
119 } else { |
|
120 _pc += csize; // Bump PC past bytecode |
|
121 } |
132 } |
122 return check_java(_bc); |
133 return check_java(_bc); |
123 } |
134 } |
124 |
135 |
125 bool is_wide() const { return ( _pc == _was_wide ); } |
136 bool is_wide() const { return ( _pc == _was_wide ); } |
|
137 |
|
138 // Does this instruction contain an index which refes into the CP cache? |
|
139 bool uses_cp_cache() const { return Bytecodes::uses_cp_cache(cur_bc_raw()); } |
|
140 |
|
141 int get_index_u1() const { |
|
142 return bytecode()->get_index_u1(cur_bc_raw()); |
|
143 } |
126 |
144 |
127 // Get a byte index following this bytecode. |
145 // Get a byte index following this bytecode. |
128 // If prefixed with a wide bytecode, get a wide index. |
146 // If prefixed with a wide bytecode, get a wide index. |
129 int get_index() const { |
147 int get_index() const { |
130 assert_index_size(is_wide() ? 2 : 1); |
|
131 return (_pc == _was_wide) // was widened? |
148 return (_pc == _was_wide) // was widened? |
132 ? Bytes::get_Java_u2(_bc_start+2) // yes, return wide index |
149 ? get_index_u2(true) // yes, return wide index |
133 : _bc_start[1]; // no, return narrow index |
150 : get_index_u1(); // no, return narrow index |
134 } |
151 } |
135 |
152 |
136 // Get 2-byte index (getfield/putstatic/etc) |
153 // Get 2-byte index (byte swapping depending on which bytecode) |
137 int get_index_big() const { |
154 int get_index_u2(bool is_wide = false) const { |
138 assert_index_size(2); |
155 return bytecode()->get_index_u2(cur_bc_raw(), is_wide); |
139 return Bytes::get_Java_u2(_bc_start+1); |
156 } |
140 } |
157 |
141 |
158 // Get 2-byte index in native byte order. (Rewriter::rewrite makes these.) |
142 // Get 2-byte index (or 4-byte, for invokedynamic) |
159 int get_index_u2_cpcache() const { |
143 int get_index_int() const { |
160 return bytecode()->get_index_u2_cpcache(cur_bc_raw()); |
144 return has_giant_index() ? get_index_giant() : get_index_big(); |
|
145 } |
161 } |
146 |
162 |
147 // Get 4-byte index, for invokedynamic. |
163 // Get 4-byte index, for invokedynamic. |
148 int get_index_giant() const { |
164 int get_index_u4() const { |
149 assert_index_size(4); |
165 return bytecode()->get_index_u4(cur_bc_raw()); |
150 return Bytes::get_native_u4(_bc_start+1); |
166 } |
151 } |
167 |
152 |
168 bool has_index_u4() const { |
153 bool has_giant_index() const { return (cur_bc() == Bytecodes::_invokedynamic); } |
169 return bytecode()->has_index_u4(cur_bc_raw()); |
|
170 } |
154 |
171 |
155 // Get dimensions byte (multinewarray) |
172 // Get dimensions byte (multinewarray) |
156 int get_dimensions() const { return *(unsigned char*)(_pc-1); } |
173 int get_dimensions() const { return *(unsigned char*)(_pc-1); } |
157 |
174 |
158 // Sign-extended index byte/short, no widening |
175 // Sign-extended index byte/short, no widening |
159 int get_byte() const { return (int8_t)(_pc[-1]); } |
176 int get_constant_u1() const { return bytecode()->get_constant_u1(instruction_size()-1, cur_bc_raw()); } |
160 int get_short() const { return (int16_t)Bytes::get_Java_u2(_pc-2); } |
177 int get_constant_u2(bool is_wide = false) const { return bytecode()->get_constant_u2(instruction_size()-2, cur_bc_raw(), is_wide); } |
161 int get_long() const { return (int32_t)Bytes::get_Java_u4(_pc-4); } |
|
162 |
178 |
163 // Get a byte signed constant for "iinc". Invalid for other bytecodes. |
179 // Get a byte signed constant for "iinc". Invalid for other bytecodes. |
164 // If prefixed with a wide bytecode, get a wide constant |
180 // If prefixed with a wide bytecode, get a wide constant |
165 int get_iinc_con() const {return (_pc==_was_wide) ? get_short() :get_byte();} |
181 int get_iinc_con() const {return (_pc==_was_wide) ? (jshort) get_constant_u2(true) : (jbyte) get_constant_u1();} |
166 |
182 |
167 // 2-byte branch offset from current pc |
183 // 2-byte branch offset from current pc |
168 int get_dest( ) const { |
184 int get_dest() const { |
169 assert( Bytecodes::length_at(_bc_start) == sizeof(jshort)+1, "get_dest called with bad bytecode" ); |
185 return cur_bci() + bytecode()->get_offset_s2(cur_bc_raw()); |
170 return _bc_start-_start + (short)Bytes::get_Java_u2(_pc-2); |
|
171 } |
186 } |
172 |
187 |
173 // 2-byte branch offset from next pc |
188 // 2-byte branch offset from next pc |
174 int next_get_dest( ) const { |
189 int next_get_dest() const { |
175 address next_bc_start = _pc; |
190 assert(_pc < _end, ""); |
176 assert( _pc < _end, "" ); |
191 return next_bci() + next_bytecode()->get_offset_s2(Bytecodes::_ifeq); |
177 Bytecodes::Code next_bc = (Bytecodes::Code)*_pc; |
|
178 assert( next_bc != Bytecodes::_wide, ""); |
|
179 int next_csize = Bytecodes::length_for(next_bc); |
|
180 assert( next_csize != 0, "" ); |
|
181 assert( next_bc <= Bytecodes::_jsr_w, ""); |
|
182 address next_pc = _pc + next_csize; |
|
183 assert( Bytecodes::length_at(next_bc_start) == sizeof(jshort)+1, "next_get_dest called with bad bytecode" ); |
|
184 return next_bc_start-_start + (short)Bytes::get_Java_u2(next_pc-2); |
|
185 } |
192 } |
186 |
193 |
187 // 4-byte branch offset from current pc |
194 // 4-byte branch offset from current pc |
188 int get_far_dest( ) const { |
195 int get_far_dest() const { |
189 assert( Bytecodes::length_at(_bc_start) == sizeof(jint)+1, "dest4 called with bad bytecode" ); |
196 return cur_bci() + bytecode()->get_offset_s4(cur_bc_raw()); |
190 return _bc_start-_start + (int)Bytes::get_Java_u4(_pc-4); |
|
191 } |
197 } |
192 |
198 |
193 // For a lookup or switch table, return target destination |
199 // For a lookup or switch table, return target destination |
194 int get_int_table( int index ) const { |
200 int get_int_table( int index ) const { |
195 return Bytes::get_Java_u4((address)&_table_base[index]); } |
201 return Bytes::get_Java_u4((address)&_table_base[index]); } |