diff -r e92b3d8118f1 -r 6b2aecc4f7d8 hotspot/src/share/vm/interpreter/bytecode.hpp --- 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; }