6939203: JSR 292 needs method handle constants

Add new CP types CONSTANT_MethodHandle, CONSTANT_MethodType; extend 'ldc' bytecode.

Reviewed-by: twisti, never
This commit is contained in:
John R Rose 2010-06-09 18:50:45 -07:00
parent 154ae789ef
commit 1f4cfb029b
60 changed files with 1549 additions and 378 deletions

View file

@ -76,9 +76,13 @@ class Bytecode: public ThisRelativeObj {
return Bytes::get_native_u2(p);
else return Bytes::get_Java_u2(p);
}
int get_index_u1_cpcache(Bytecodes::Code bc) const {
assert_same_format_as(bc); assert_index_size(1, bc);
return *(jubyte*)addr_at(1) + constantPoolOopDesc::CPCACHE_INDEX_TAG;
}
int get_index_u2_cpcache(Bytecodes::Code bc) const {
assert_same_format_as(bc); assert_index_size(2, bc); assert_native_index(bc);
return Bytes::get_native_u2(addr_at(1)) DEBUG_ONLY(+ constantPoolOopDesc::CPCACHE_INDEX_TAG);
return Bytes::get_native_u2(addr_at(1)) + constantPoolOopDesc::CPCACHE_INDEX_TAG;
}
int get_index_u4(Bytecodes::Code bc) const {
assert_same_format_as(bc); assert_index_size(4, bc);
@ -152,7 +156,7 @@ class Bytecode_lookupswitch: public Bytecode {
inline Bytecode_lookupswitch* Bytecode_lookupswitch_at(address bcp) {
Bytecode_lookupswitch* b = (Bytecode_lookupswitch*)bcp;
debug_only(b->verify());
DEBUG_ONLY(b->verify());
return b;
}
@ -174,44 +178,56 @@ class Bytecode_tableswitch: public Bytecode {
inline Bytecode_tableswitch* Bytecode_tableswitch_at(address bcp) {
Bytecode_tableswitch* b = (Bytecode_tableswitch*)bcp;
debug_only(b->verify());
DEBUG_ONLY(b->verify());
return b;
}
// Abstraction for invoke_{virtual, static, interface, special}
// Common code for decoding invokes and field references.
class Bytecode_invoke: public ResourceObj {
class Bytecode_member_ref: public ResourceObj {
protected:
methodHandle _method; // method containing the bytecode
int _bci; // position of the bytecode
Bytecode_invoke(methodHandle method, int bci) : _method(method), _bci(bci) {}
Bytecode_member_ref(methodHandle method, int bci) : _method(method), _bci(bci) {}
public:
// Attributes
methodHandle method() const { return _method; }
int bci() const { return _bci; }
address bcp() const { return _method->bcp_from(bci()); }
Bytecode* bytecode() const { return Bytecode_at(bcp()); }
int index() const; // cache index (loaded from instruction)
int pool_index() const; // constant pool index
symbolOop name() const; // returns the name of the method or field
symbolOop signature() const; // returns the signature of the method or field
BasicType result_type(Thread* thread) const; // returns the result type of the getfield or invoke
Bytecodes::Code code() const { return Bytecodes::code_at(bcp(), _method()); }
Bytecodes::Code java_code() const { return Bytecodes::java_code(code()); }
};
// Abstraction for invoke_{virtual, static, interface, special}
class Bytecode_invoke: public Bytecode_member_ref {
protected:
Bytecode_invoke(methodHandle method, int bci) : Bytecode_member_ref(method, bci) {}
public:
void verify() const;
// Attributes
methodHandle method() const { return _method; }
int bci() const { return _bci; }
address bcp() const { return _method->bcp_from(bci()); }
int index() const; // the constant pool index for the invoke
symbolOop name() const; // returns the name of the invoked method
symbolOop signature() const; // returns the signature of the invoked method
BasicType result_type(Thread *thread) const; // returns the result type of the invoke
Bytecodes::Code code() const { return Bytecodes::code_at(bcp(), _method()); }
Bytecodes::Code adjusted_invoke_code() const { return Bytecodes::java_code(code()); }
methodHandle static_target(TRAPS); // "specified" method (from constant pool)
// Testers
bool is_invokeinterface() const { return adjusted_invoke_code() == Bytecodes::_invokeinterface; }
bool is_invokevirtual() const { return adjusted_invoke_code() == Bytecodes::_invokevirtual; }
bool is_invokestatic() const { return adjusted_invoke_code() == Bytecodes::_invokestatic; }
bool is_invokespecial() const { return adjusted_invoke_code() == Bytecodes::_invokespecial; }
bool is_invokedynamic() const { return adjusted_invoke_code() == Bytecodes::_invokedynamic; }
bool is_invokeinterface() const { return java_code() == Bytecodes::_invokeinterface; }
bool is_invokevirtual() const { return java_code() == Bytecodes::_invokevirtual; }
bool is_invokestatic() const { return java_code() == Bytecodes::_invokestatic; }
bool is_invokespecial() const { return java_code() == Bytecodes::_invokespecial; }
bool is_invokedynamic() const { return java_code() == Bytecodes::_invokedynamic; }
bool has_receiver() const { return !is_invokestatic() && !is_invokedynamic(); }
@ -230,7 +246,7 @@ class Bytecode_invoke: public ResourceObj {
inline Bytecode_invoke* Bytecode_invoke_at(methodHandle method, int bci) {
Bytecode_invoke* b = new Bytecode_invoke(method, bci);
debug_only(b->verify());
DEBUG_ONLY(b->verify());
return b;
}
@ -240,21 +256,34 @@ inline Bytecode_invoke* Bytecode_invoke_at_check(methodHandle method, int bci) {
}
// Abstraction for all field accesses (put/get field/static_
class Bytecode_field: public Bytecode {
public:
// Abstraction for all field accesses (put/get field/static)
class Bytecode_field: public Bytecode_member_ref {
protected:
Bytecode_field(methodHandle method, int bci) : Bytecode_member_ref(method, bci) {}
public:
// Testers
bool is_getfield() const { return java_code() == Bytecodes::_getfield; }
bool is_putfield() const { return java_code() == Bytecodes::_putfield; }
bool is_getstatic() const { return java_code() == Bytecodes::_getstatic; }
bool is_putstatic() const { return java_code() == Bytecodes::_putstatic; }
bool is_getter() const { return is_getfield() || is_getstatic(); }
bool is_static() const { return is_getstatic() || is_putstatic(); }
bool is_valid() const { return is_getfield() ||
is_putfield() ||
is_getstatic() ||
is_putstatic(); }
void verify() const;
int index() const;
bool is_static() const;
// Creation
inline friend Bytecode_field* Bytecode_field_at(const methodOop method, address bcp);
inline friend Bytecode_field* Bytecode_field_at(methodHandle method, int bci);
};
inline Bytecode_field* Bytecode_field_at(const methodOop method, address bcp) {
Bytecode_field* b = (Bytecode_field*)bcp;
debug_only(b->verify());
inline Bytecode_field* Bytecode_field_at(methodHandle method, int bci) {
Bytecode_field* b = new Bytecode_field(method, bci);
DEBUG_ONLY(b->verify());
return b;
}
@ -274,7 +303,7 @@ class Bytecode_checkcast: public Bytecode {
inline Bytecode_checkcast* Bytecode_checkcast_at(address bcp) {
Bytecode_checkcast* b = (Bytecode_checkcast*)bcp;
debug_only(b->verify());
DEBUG_ONLY(b->verify());
return b;
}
@ -294,7 +323,7 @@ class Bytecode_instanceof: public Bytecode {
inline Bytecode_instanceof* Bytecode_instanceof_at(address bcp) {
Bytecode_instanceof* b = (Bytecode_instanceof*)bcp;
debug_only(b->verify());
DEBUG_ONLY(b->verify());
return b;
}
@ -312,7 +341,7 @@ class Bytecode_new: public Bytecode {
inline Bytecode_new* Bytecode_new_at(address bcp) {
Bytecode_new* b = (Bytecode_new*)bcp;
debug_only(b->verify());
DEBUG_ONLY(b->verify());
return b;
}
@ -330,7 +359,7 @@ class Bytecode_multianewarray: public Bytecode {
inline Bytecode_multianewarray* Bytecode_multianewarray_at(address bcp) {
Bytecode_multianewarray* b = (Bytecode_multianewarray*)bcp;
debug_only(b->verify());
DEBUG_ONLY(b->verify());
return b;
}
@ -348,29 +377,57 @@ class Bytecode_anewarray: public Bytecode {
inline Bytecode_anewarray* Bytecode_anewarray_at(address bcp) {
Bytecode_anewarray* b = (Bytecode_anewarray*)bcp;
debug_only(b->verify());
DEBUG_ONLY(b->verify());
return b;
}
// Abstraction for ldc, ldc_w and ldc2_w
class Bytecode_loadconstant: public Bytecode {
class Bytecode_loadconstant: public ResourceObj {
private:
int _bci;
methodHandle _method;
Bytecodes::Code code() const { return bytecode()->code(); }
int raw_index() const;
Bytecode_loadconstant(methodHandle method, int bci) : _method(method), _bci(bci) {}
public:
// Attributes
methodHandle method() const { return _method; }
int bci() const { return _bci; }
address bcp() const { return _method->bcp_from(bci()); }
Bytecode* bytecode() const { return Bytecode_at(bcp()); }
void verify() const {
assert(_method.not_null(), "must supply method");
Bytecodes::Code stdc = Bytecodes::java_code(code());
assert(stdc == Bytecodes::_ldc ||
stdc == Bytecodes::_ldc_w ||
stdc == Bytecodes::_ldc2_w, "load constant");
}
int index() const;
// Only non-standard bytecodes (fast_aldc) have CP cache indexes.
bool has_cache_index() const { return code() >= Bytecodes::number_of_java_codes; }
inline friend Bytecode_loadconstant* Bytecode_loadconstant_at(const methodOop method, address bcp);
int pool_index() const; // index into constant pool
int cache_index() const { // index into CP cache (or -1 if none)
return has_cache_index() ? raw_index() : -1;
}
BasicType result_type() const; // returns the result type of the ldc
oop resolve_constant(TRAPS) const;
// Creation
inline friend Bytecode_loadconstant* Bytecode_loadconstant_at(methodHandle method, int bci);
};
inline Bytecode_loadconstant* Bytecode_loadconstant_at(const methodOop method, address bcp) {
Bytecode_loadconstant* b = (Bytecode_loadconstant*)bcp;
debug_only(b->verify());
inline Bytecode_loadconstant* Bytecode_loadconstant_at(methodHandle method, int bci) {
Bytecode_loadconstant* b = new Bytecode_loadconstant(method, bci);
DEBUG_ONLY(b->verify());
return b;
}