mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 11:04:34 +02:00
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:
parent
154ae789ef
commit
1f4cfb029b
60 changed files with 1549 additions and 378 deletions
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue