hotspot/src/share/vm/interpreter/bytecode.hpp
changeset 5882 6b2aecc4f7d8
parent 5702 201c5cde25bb
child 7397 5b173b4ca846
--- 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;
 }