--- a/hotspot/src/share/vm/interpreter/bytecode.hpp Mon Jun 07 14:17:01 2010 -0700
+++ b/hotspot/src/share/vm/interpreter/bytecode.hpp Wed Jun 09 18:50:45 2010 -0700
@@ -76,9 +76,13 @@
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 @@
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 @@
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 @@
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 @@
}
-// 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 @@
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 @@
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 @@
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 @@
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 @@
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;
}