Mercurial > hg > truffle
comparison src/share/vm/interpreter/bytecode.hpp @ 1602:136b78722a08
6939203: JSR 292 needs method handle constants
Summary: Add new CP types CONSTANT_MethodHandle, CONSTANT_MethodType; extend 'ldc' bytecode.
Reviewed-by: twisti, never
author | jrose |
---|---|
date | Wed, 09 Jun 2010 18:50:45 -0700 |
parents | e9ff18c4ace7 |
children | f95d63e2154a |
comparison
equal
deleted
inserted
replaced
1585:49fac4acd688 | 1602:136b78722a08 |
---|---|
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)); |
150 inline friend Bytecode_lookupswitch* Bytecode_lookupswitch_at(address bcp); | 154 inline friend Bytecode_lookupswitch* Bytecode_lookupswitch_at(address bcp); |
151 }; | 155 }; |
152 | 156 |
153 inline Bytecode_lookupswitch* Bytecode_lookupswitch_at(address bcp) { | 157 inline Bytecode_lookupswitch* Bytecode_lookupswitch_at(address bcp) { |
154 Bytecode_lookupswitch* b = (Bytecode_lookupswitch*)bcp; | 158 Bytecode_lookupswitch* b = (Bytecode_lookupswitch*)bcp; |
155 debug_only(b->verify()); | 159 DEBUG_ONLY(b->verify()); |
156 return b; | 160 return b; |
157 } | 161 } |
158 | 162 |
159 | 163 |
160 class Bytecode_tableswitch: public Bytecode { | 164 class Bytecode_tableswitch: public Bytecode { |
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 |
272 inline friend Bytecode_checkcast* Bytecode_checkcast_at(address bcp); | 301 inline friend Bytecode_checkcast* Bytecode_checkcast_at(address bcp); |
273 }; | 302 }; |
274 | 303 |
275 inline Bytecode_checkcast* Bytecode_checkcast_at(address bcp) { | 304 inline Bytecode_checkcast* Bytecode_checkcast_at(address bcp) { |
276 Bytecode_checkcast* b = (Bytecode_checkcast*)bcp; | 305 Bytecode_checkcast* b = (Bytecode_checkcast*)bcp; |
277 debug_only(b->verify()); | 306 DEBUG_ONLY(b->verify()); |
278 return b; | 307 return b; |
279 } | 308 } |
280 | 309 |
281 | 310 |
282 // Abstraction for instanceof | 311 // Abstraction for instanceof |
292 inline friend Bytecode_instanceof* Bytecode_instanceof_at(address bcp); | 321 inline friend Bytecode_instanceof* Bytecode_instanceof_at(address bcp); |
293 }; | 322 }; |
294 | 323 |
295 inline Bytecode_instanceof* Bytecode_instanceof_at(address bcp) { | 324 inline Bytecode_instanceof* Bytecode_instanceof_at(address bcp) { |
296 Bytecode_instanceof* b = (Bytecode_instanceof*)bcp; | 325 Bytecode_instanceof* b = (Bytecode_instanceof*)bcp; |
297 debug_only(b->verify()); | 326 DEBUG_ONLY(b->verify()); |
298 return b; | 327 return b; |
299 } | 328 } |
300 | 329 |
301 | 330 |
302 class Bytecode_new: public Bytecode { | 331 class Bytecode_new: public Bytecode { |
310 inline friend Bytecode_new* Bytecode_new_at(address bcp); | 339 inline friend Bytecode_new* Bytecode_new_at(address bcp); |
311 }; | 340 }; |
312 | 341 |
313 inline Bytecode_new* Bytecode_new_at(address bcp) { | 342 inline Bytecode_new* Bytecode_new_at(address bcp) { |
314 Bytecode_new* b = (Bytecode_new*)bcp; | 343 Bytecode_new* b = (Bytecode_new*)bcp; |
315 debug_only(b->verify()); | 344 DEBUG_ONLY(b->verify()); |
316 return b; | 345 return b; |
317 } | 346 } |
318 | 347 |
319 | 348 |
320 class Bytecode_multianewarray: public Bytecode { | 349 class Bytecode_multianewarray: public Bytecode { |
328 inline friend Bytecode_multianewarray* Bytecode_multianewarray_at(address bcp); | 357 inline friend Bytecode_multianewarray* Bytecode_multianewarray_at(address bcp); |
329 }; | 358 }; |
330 | 359 |
331 inline Bytecode_multianewarray* Bytecode_multianewarray_at(address bcp) { | 360 inline Bytecode_multianewarray* Bytecode_multianewarray_at(address bcp) { |
332 Bytecode_multianewarray* b = (Bytecode_multianewarray*)bcp; | 361 Bytecode_multianewarray* b = (Bytecode_multianewarray*)bcp; |
333 debug_only(b->verify()); | 362 DEBUG_ONLY(b->verify()); |
334 return b; | 363 return b; |
335 } | 364 } |
336 | 365 |
337 | 366 |
338 class Bytecode_anewarray: public Bytecode { | 367 class Bytecode_anewarray: public Bytecode { |
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 } |