74 address p = addr_at(is_wide ? 2 : 1); |
74 address p = addr_at(is_wide ? 2 : 1); |
75 if (can_use_native_byte_order(bc, is_wide)) |
75 if (can_use_native_byte_order(bc, is_wide)) |
76 return Bytes::get_native_u2(p); |
76 return Bytes::get_native_u2(p); |
77 else return Bytes::get_Java_u2(p); |
77 else return Bytes::get_Java_u2(p); |
78 } |
78 } |
|
79 int get_index_u1_cpcache(Bytecodes::Code bc) const { |
|
80 assert_same_format_as(bc); assert_index_size(1, bc); |
|
81 return *(jubyte*)addr_at(1) + constantPoolOopDesc::CPCACHE_INDEX_TAG; |
|
82 } |
79 int get_index_u2_cpcache(Bytecodes::Code bc) const { |
83 int get_index_u2_cpcache(Bytecodes::Code bc) const { |
80 assert_same_format_as(bc); assert_index_size(2, bc); assert_native_index(bc); |
84 assert_same_format_as(bc); assert_index_size(2, bc); assert_native_index(bc); |
81 return Bytes::get_native_u2(addr_at(1)) DEBUG_ONLY(+ constantPoolOopDesc::CPCACHE_INDEX_TAG); |
85 return Bytes::get_native_u2(addr_at(1)) + constantPoolOopDesc::CPCACHE_INDEX_TAG; |
82 } |
86 } |
83 int get_index_u4(Bytecodes::Code bc) const { |
87 int get_index_u4(Bytecodes::Code bc) const { |
84 assert_same_format_as(bc); assert_index_size(4, bc); |
88 assert_same_format_as(bc); assert_index_size(4, bc); |
85 assert(can_use_native_byte_order(bc), ""); |
89 assert(can_use_native_byte_order(bc), ""); |
86 return Bytes::get_native_u4(addr_at(1)); |
90 return Bytes::get_native_u4(addr_at(1)); |
172 inline friend Bytecode_tableswitch* Bytecode_tableswitch_at(address bcp); |
176 inline friend Bytecode_tableswitch* Bytecode_tableswitch_at(address bcp); |
173 }; |
177 }; |
174 |
178 |
175 inline Bytecode_tableswitch* Bytecode_tableswitch_at(address bcp) { |
179 inline Bytecode_tableswitch* Bytecode_tableswitch_at(address bcp) { |
176 Bytecode_tableswitch* b = (Bytecode_tableswitch*)bcp; |
180 Bytecode_tableswitch* b = (Bytecode_tableswitch*)bcp; |
177 debug_only(b->verify()); |
181 DEBUG_ONLY(b->verify()); |
178 return b; |
182 return b; |
179 } |
183 } |
180 |
184 |
181 |
185 |
182 // Abstraction for invoke_{virtual, static, interface, special} |
186 // Common code for decoding invokes and field references. |
183 |
187 |
184 class Bytecode_invoke: public ResourceObj { |
188 class Bytecode_member_ref: public ResourceObj { |
185 protected: |
189 protected: |
186 methodHandle _method; // method containing the bytecode |
190 methodHandle _method; // method containing the bytecode |
187 int _bci; // position of the bytecode |
191 int _bci; // position of the bytecode |
188 |
192 |
189 Bytecode_invoke(methodHandle method, int bci) : _method(method), _bci(bci) {} |
193 Bytecode_member_ref(methodHandle method, int bci) : _method(method), _bci(bci) {} |
190 |
194 |
191 public: |
195 public: |
192 void verify() const; |
|
193 |
|
194 // Attributes |
196 // Attributes |
195 methodHandle method() const { return _method; } |
197 methodHandle method() const { return _method; } |
196 int bci() const { return _bci; } |
198 int bci() const { return _bci; } |
197 address bcp() const { return _method->bcp_from(bci()); } |
199 address bcp() const { return _method->bcp_from(bci()); } |
198 |
200 Bytecode* bytecode() const { return Bytecode_at(bcp()); } |
199 int index() const; // the constant pool index for the invoke |
201 |
200 symbolOop name() const; // returns the name of the invoked method |
202 int index() const; // cache index (loaded from instruction) |
201 symbolOop signature() const; // returns the signature of the invoked method |
203 int pool_index() const; // constant pool index |
202 BasicType result_type(Thread *thread) const; // returns the result type of the invoke |
204 symbolOop name() const; // returns the name of the method or field |
|
205 symbolOop signature() const; // returns the signature of the method or field |
|
206 |
|
207 BasicType result_type(Thread* thread) const; // returns the result type of the getfield or invoke |
203 |
208 |
204 Bytecodes::Code code() const { return Bytecodes::code_at(bcp(), _method()); } |
209 Bytecodes::Code code() const { return Bytecodes::code_at(bcp(), _method()); } |
205 Bytecodes::Code adjusted_invoke_code() const { return Bytecodes::java_code(code()); } |
210 Bytecodes::Code java_code() const { return Bytecodes::java_code(code()); } |
206 |
211 }; |
|
212 |
|
213 // Abstraction for invoke_{virtual, static, interface, special} |
|
214 |
|
215 class Bytecode_invoke: public Bytecode_member_ref { |
|
216 protected: |
|
217 Bytecode_invoke(methodHandle method, int bci) : Bytecode_member_ref(method, bci) {} |
|
218 |
|
219 public: |
|
220 void verify() const; |
|
221 |
|
222 // Attributes |
207 methodHandle static_target(TRAPS); // "specified" method (from constant pool) |
223 methodHandle static_target(TRAPS); // "specified" method (from constant pool) |
208 |
224 |
209 // Testers |
225 // Testers |
210 bool is_invokeinterface() const { return adjusted_invoke_code() == Bytecodes::_invokeinterface; } |
226 bool is_invokeinterface() const { return java_code() == Bytecodes::_invokeinterface; } |
211 bool is_invokevirtual() const { return adjusted_invoke_code() == Bytecodes::_invokevirtual; } |
227 bool is_invokevirtual() const { return java_code() == Bytecodes::_invokevirtual; } |
212 bool is_invokestatic() const { return adjusted_invoke_code() == Bytecodes::_invokestatic; } |
228 bool is_invokestatic() const { return java_code() == Bytecodes::_invokestatic; } |
213 bool is_invokespecial() const { return adjusted_invoke_code() == Bytecodes::_invokespecial; } |
229 bool is_invokespecial() const { return java_code() == Bytecodes::_invokespecial; } |
214 bool is_invokedynamic() const { return adjusted_invoke_code() == Bytecodes::_invokedynamic; } |
230 bool is_invokedynamic() const { return java_code() == Bytecodes::_invokedynamic; } |
215 |
231 |
216 bool has_receiver() const { return !is_invokestatic() && !is_invokedynamic(); } |
232 bool has_receiver() const { return !is_invokestatic() && !is_invokedynamic(); } |
217 |
233 |
218 bool is_valid() const { return is_invokeinterface() || |
234 bool is_valid() const { return is_invokeinterface() || |
219 is_invokevirtual() || |
235 is_invokevirtual() || |
228 inline friend Bytecode_invoke* Bytecode_invoke_at_check(methodHandle method, int bci); |
244 inline friend Bytecode_invoke* Bytecode_invoke_at_check(methodHandle method, int bci); |
229 }; |
245 }; |
230 |
246 |
231 inline Bytecode_invoke* Bytecode_invoke_at(methodHandle method, int bci) { |
247 inline Bytecode_invoke* Bytecode_invoke_at(methodHandle method, int bci) { |
232 Bytecode_invoke* b = new Bytecode_invoke(method, bci); |
248 Bytecode_invoke* b = new Bytecode_invoke(method, bci); |
233 debug_only(b->verify()); |
249 DEBUG_ONLY(b->verify()); |
234 return b; |
250 return b; |
235 } |
251 } |
236 |
252 |
237 inline Bytecode_invoke* Bytecode_invoke_at_check(methodHandle method, int bci) { |
253 inline Bytecode_invoke* Bytecode_invoke_at_check(methodHandle method, int bci) { |
238 Bytecode_invoke* b = new Bytecode_invoke(method, bci); |
254 Bytecode_invoke* b = new Bytecode_invoke(method, bci); |
239 return b->is_valid() ? b : NULL; |
255 return b->is_valid() ? b : NULL; |
240 } |
256 } |
241 |
257 |
242 |
258 |
243 // Abstraction for all field accesses (put/get field/static_ |
259 // Abstraction for all field accesses (put/get field/static) |
244 class Bytecode_field: public Bytecode { |
260 class Bytecode_field: public Bytecode_member_ref { |
245 public: |
261 protected: |
|
262 Bytecode_field(methodHandle method, int bci) : Bytecode_member_ref(method, bci) {} |
|
263 |
|
264 public: |
|
265 // Testers |
|
266 bool is_getfield() const { return java_code() == Bytecodes::_getfield; } |
|
267 bool is_putfield() const { return java_code() == Bytecodes::_putfield; } |
|
268 bool is_getstatic() const { return java_code() == Bytecodes::_getstatic; } |
|
269 bool is_putstatic() const { return java_code() == Bytecodes::_putstatic; } |
|
270 |
|
271 bool is_getter() const { return is_getfield() || is_getstatic(); } |
|
272 bool is_static() const { return is_getstatic() || is_putstatic(); } |
|
273 |
|
274 bool is_valid() const { return is_getfield() || |
|
275 is_putfield() || |
|
276 is_getstatic() || |
|
277 is_putstatic(); } |
246 void verify() const; |
278 void verify() const; |
247 |
279 |
248 int index() const; |
280 // Creation |
249 bool is_static() const; |
281 inline friend Bytecode_field* Bytecode_field_at(methodHandle method, int bci); |
250 |
282 }; |
251 // Creation |
283 |
252 inline friend Bytecode_field* Bytecode_field_at(const methodOop method, address bcp); |
284 inline Bytecode_field* Bytecode_field_at(methodHandle method, int bci) { |
253 }; |
285 Bytecode_field* b = new Bytecode_field(method, bci); |
254 |
286 DEBUG_ONLY(b->verify()); |
255 inline Bytecode_field* Bytecode_field_at(const methodOop method, address bcp) { |
|
256 Bytecode_field* b = (Bytecode_field*)bcp; |
|
257 debug_only(b->verify()); |
|
258 return b; |
287 return b; |
259 } |
288 } |
260 |
289 |
261 |
290 |
262 // Abstraction for checkcast |
291 // Abstraction for checkcast |
346 inline friend Bytecode_anewarray* Bytecode_anewarray_at(address bcp); |
375 inline friend Bytecode_anewarray* Bytecode_anewarray_at(address bcp); |
347 }; |
376 }; |
348 |
377 |
349 inline Bytecode_anewarray* Bytecode_anewarray_at(address bcp) { |
378 inline Bytecode_anewarray* Bytecode_anewarray_at(address bcp) { |
350 Bytecode_anewarray* b = (Bytecode_anewarray*)bcp; |
379 Bytecode_anewarray* b = (Bytecode_anewarray*)bcp; |
351 debug_only(b->verify()); |
380 DEBUG_ONLY(b->verify()); |
352 return b; |
381 return b; |
353 } |
382 } |
354 |
383 |
355 |
384 |
356 // Abstraction for ldc, ldc_w and ldc2_w |
385 // Abstraction for ldc, ldc_w and ldc2_w |
357 |
386 |
358 class Bytecode_loadconstant: public Bytecode { |
387 class Bytecode_loadconstant: public ResourceObj { |
359 public: |
388 private: |
|
389 int _bci; |
|
390 methodHandle _method; |
|
391 |
|
392 Bytecodes::Code code() const { return bytecode()->code(); } |
|
393 |
|
394 int raw_index() const; |
|
395 |
|
396 Bytecode_loadconstant(methodHandle method, int bci) : _method(method), _bci(bci) {} |
|
397 |
|
398 public: |
|
399 // Attributes |
|
400 methodHandle method() const { return _method; } |
|
401 int bci() const { return _bci; } |
|
402 address bcp() const { return _method->bcp_from(bci()); } |
|
403 Bytecode* bytecode() const { return Bytecode_at(bcp()); } |
|
404 |
360 void verify() const { |
405 void verify() const { |
|
406 assert(_method.not_null(), "must supply method"); |
361 Bytecodes::Code stdc = Bytecodes::java_code(code()); |
407 Bytecodes::Code stdc = Bytecodes::java_code(code()); |
362 assert(stdc == Bytecodes::_ldc || |
408 assert(stdc == Bytecodes::_ldc || |
363 stdc == Bytecodes::_ldc_w || |
409 stdc == Bytecodes::_ldc_w || |
364 stdc == Bytecodes::_ldc2_w, "load constant"); |
410 stdc == Bytecodes::_ldc2_w, "load constant"); |
365 } |
411 } |
366 |
412 |
367 int index() const; |
413 // Only non-standard bytecodes (fast_aldc) have CP cache indexes. |
368 |
414 bool has_cache_index() const { return code() >= Bytecodes::number_of_java_codes; } |
369 inline friend Bytecode_loadconstant* Bytecode_loadconstant_at(const methodOop method, address bcp); |
415 |
370 }; |
416 int pool_index() const; // index into constant pool |
371 |
417 int cache_index() const { // index into CP cache (or -1 if none) |
372 inline Bytecode_loadconstant* Bytecode_loadconstant_at(const methodOop method, address bcp) { |
418 return has_cache_index() ? raw_index() : -1; |
373 Bytecode_loadconstant* b = (Bytecode_loadconstant*)bcp; |
419 } |
374 debug_only(b->verify()); |
420 |
375 return b; |
421 BasicType result_type() const; // returns the result type of the ldc |
376 } |
422 |
|
423 oop resolve_constant(TRAPS) const; |
|
424 |
|
425 // Creation |
|
426 inline friend Bytecode_loadconstant* Bytecode_loadconstant_at(methodHandle method, int bci); |
|
427 }; |
|
428 |
|
429 inline Bytecode_loadconstant* Bytecode_loadconstant_at(methodHandle method, int bci) { |
|
430 Bytecode_loadconstant* b = new Bytecode_loadconstant(method, bci); |
|
431 DEBUG_ONLY(b->verify()); |
|
432 return b; |
|
433 } |