src/share/vm/interpreter/bytecode.hpp

Wed, 02 Jun 2010 22:45:42 -0700

author
jrose
date
Wed, 02 Jun 2010 22:45:42 -0700
changeset 1934
e9ff18c4ace7
parent 1907
c18cbe5936b8
parent 1920
ab102d5d923e
child 1957
136b78722a08
permissions
-rw-r--r--

Merge

     1 /*
     2  * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    25 // Base class for different kinds of abstractions working
    26 // relative to an objects 'this' pointer.
    28 class ThisRelativeObj VALUE_OBJ_CLASS_SPEC {
    29  public:
    30   // Address computation
    31   address addr_at            (int offset)        const     { return (address)this + offset; }
    32   int     byte_at            (int offset)        const     { return *(addr_at(offset)); }
    33   address aligned_addr_at    (int offset)        const     { return (address)round_to((intptr_t)addr_at(offset), jintSize); }
    34   int     aligned_offset     (int offset)        const     { return aligned_addr_at(offset) - addr_at(0); }
    36   // Word access:
    37   int     get_Java_u2_at     (int offset)        const     { return Bytes::get_Java_u2(addr_at(offset)); }
    38   int     get_Java_u4_at     (int offset)        const     { return Bytes::get_Java_u4(addr_at(offset)); }
    39   int     get_native_u2_at   (int offset)        const     { return Bytes::get_native_u2(addr_at(offset)); }
    40   int     get_native_u4_at   (int offset)        const     { return Bytes::get_native_u4(addr_at(offset)); }
    41 };
    44 // The base class for different kinds of bytecode abstractions.
    45 // Provides the primitive operations to manipulate code relative
    46 // to an objects 'this' pointer.
    47 // FIXME: Make this a ResourceObj, include the enclosing methodOop, and cache the opcode.
    49 class Bytecode: public ThisRelativeObj {
    50  protected:
    51   u_char byte_at(int offset) const               { return *addr_at(offset); }
    52   bool check_must_rewrite(Bytecodes::Code bc) const;
    54  public:
    55   // Attributes
    56   address bcp() const                            { return addr_at(0); }
    57   int instruction_size() const                   { return Bytecodes::length_at(bcp()); }
    59   // Warning: Use code() with caution on live bytecode streams.  4926272
    60   Bytecodes::Code code() const                   { return Bytecodes::code_at(addr_at(0)); }
    61   Bytecodes::Code java_code() const              { return Bytecodes::java_code(code()); }
    62   bool must_rewrite(Bytecodes::Code code) const  { return Bytecodes::can_rewrite(code) && check_must_rewrite(code); }
    64   // Creation
    65   inline friend Bytecode* Bytecode_at(address bcp);
    67   // Static functions for parsing bytecodes in place.
    68   int get_index_u1(Bytecodes::Code bc) const {
    69     assert_same_format_as(bc); assert_index_size(1, bc);
    70     return *(jubyte*)addr_at(1);
    71   }
    72   int get_index_u2(Bytecodes::Code bc, bool is_wide = false) const {
    73     assert_same_format_as(bc, is_wide); assert_index_size(2, bc, is_wide);
    74     address p = addr_at(is_wide ? 2 : 1);
    75     if (can_use_native_byte_order(bc, is_wide))
    76           return Bytes::get_native_u2(p);
    77     else  return Bytes::get_Java_u2(p);
    78   }
    79   int get_index_u2_cpcache(Bytecodes::Code bc) const {
    80     assert_same_format_as(bc); assert_index_size(2, bc); assert_native_index(bc);
    81     return Bytes::get_native_u2(addr_at(1)) DEBUG_ONLY(+ constantPoolOopDesc::CPCACHE_INDEX_TAG);
    82   }
    83   int get_index_u4(Bytecodes::Code bc) const {
    84     assert_same_format_as(bc); assert_index_size(4, bc);
    85     assert(can_use_native_byte_order(bc), "");
    86     return Bytes::get_native_u4(addr_at(1));
    87   }
    88   bool has_index_u4(Bytecodes::Code bc) const {
    89     return bc == Bytecodes::_invokedynamic;
    90   }
    92   int get_offset_s2(Bytecodes::Code bc) const {
    93     assert_same_format_as(bc); assert_offset_size(2, bc);
    94     return (jshort) Bytes::get_Java_u2(addr_at(1));
    95   }
    96   int get_offset_s4(Bytecodes::Code bc) const {
    97     assert_same_format_as(bc); assert_offset_size(4, bc);
    98     return (jint) Bytes::get_Java_u4(addr_at(1));
    99   }
   101   int get_constant_u1(int offset, Bytecodes::Code bc) const {
   102     assert_same_format_as(bc); assert_constant_size(1, offset, bc);
   103     return *(jbyte*)addr_at(offset);
   104   }
   105   int get_constant_u2(int offset, Bytecodes::Code bc, bool is_wide = false) const {
   106     assert_same_format_as(bc, is_wide); assert_constant_size(2, offset, bc, is_wide);
   107     return (jshort) Bytes::get_Java_u2(addr_at(offset));
   108   }
   110   // These are used locally and also from bytecode streams.
   111   void assert_same_format_as(Bytecodes::Code testbc, bool is_wide = false) const NOT_DEBUG_RETURN;
   112   static void assert_index_size(int required_size, Bytecodes::Code bc, bool is_wide = false) NOT_DEBUG_RETURN;
   113   static void assert_offset_size(int required_size, Bytecodes::Code bc, bool is_wide = false) NOT_DEBUG_RETURN;
   114   static void assert_constant_size(int required_size, int where, Bytecodes::Code bc, bool is_wide = false) NOT_DEBUG_RETURN;
   115   static void assert_native_index(Bytecodes::Code bc, bool is_wide = false) NOT_DEBUG_RETURN;
   116   static bool can_use_native_byte_order(Bytecodes::Code bc, bool is_wide = false) {
   117     return (!Bytes::is_Java_byte_ordering_different() || Bytecodes::native_byte_order(bc /*, is_wide*/));
   118   }
   119 };
   121 inline Bytecode* Bytecode_at(address bcp) {
   122   // Warning: Use with caution on live bytecode streams.  4926272
   123   return (Bytecode*)bcp;
   124 }
   127 // Abstractions for lookupswitch bytecode
   129 class LookupswitchPair: ThisRelativeObj {
   130  private:
   131   int  _match;
   132   int  _offset;
   134  public:
   135   int  match() const                             { return get_Java_u4_at(0 * jintSize); }
   136   int  offset() const                            { return get_Java_u4_at(1 * jintSize); }
   137 };
   140 class Bytecode_lookupswitch: public Bytecode {
   141  public:
   142   void verify() const PRODUCT_RETURN;
   144   // Attributes
   145   int  default_offset() const                    { return get_Java_u4_at(aligned_offset(1 + 0*jintSize)); }
   146   int  number_of_pairs() const                   { return get_Java_u4_at(aligned_offset(1 + 1*jintSize)); }
   147   LookupswitchPair* pair_at(int i) const         { assert(0 <= i && i < number_of_pairs(), "pair index out of bounds");
   148                                                    return (LookupswitchPair*)aligned_addr_at(1 + (1 + i)*2*jintSize); }
   149   // Creation
   150   inline friend Bytecode_lookupswitch* Bytecode_lookupswitch_at(address bcp);
   151 };
   153 inline Bytecode_lookupswitch* Bytecode_lookupswitch_at(address bcp) {
   154   Bytecode_lookupswitch* b = (Bytecode_lookupswitch*)bcp;
   155   debug_only(b->verify());
   156   return b;
   157 }
   160 class Bytecode_tableswitch: public Bytecode {
   161  public:
   162   void verify() const PRODUCT_RETURN;
   164   // Attributes
   165   int  default_offset() const                    { return get_Java_u4_at(aligned_offset(1 + 0*jintSize)); }
   166   int  low_key() const                           { return get_Java_u4_at(aligned_offset(1 + 1*jintSize)); }
   167   int  high_key() const                          { return get_Java_u4_at(aligned_offset(1 + 2*jintSize)); }
   168   int  dest_offset_at(int i) const;
   169   int  length()                                  { return high_key()-low_key()+1; }
   171   // Creation
   172   inline friend Bytecode_tableswitch* Bytecode_tableswitch_at(address bcp);
   173 };
   175 inline Bytecode_tableswitch* Bytecode_tableswitch_at(address bcp) {
   176   Bytecode_tableswitch* b = (Bytecode_tableswitch*)bcp;
   177   debug_only(b->verify());
   178   return b;
   179 }
   182 // Abstraction for invoke_{virtual, static, interface, special}
   184 class Bytecode_invoke: public ResourceObj {
   185  protected:
   186   methodHandle _method;                          // method containing the bytecode
   187   int          _bci;                             // position of the bytecode
   189   Bytecode_invoke(methodHandle method, int bci)  : _method(method), _bci(bci) {}
   191  public:
   192   void verify() const;
   194   // Attributes
   195   methodHandle method() const                    { return _method; }
   196   int          bci() const                       { return _bci; }
   197   address      bcp() const                       { return _method->bcp_from(bci()); }
   199   int          index() const;                    // the constant pool index for the invoke
   200   symbolOop    name() const;                     // returns the name of the invoked method
   201   symbolOop    signature() const;                // returns the signature of the invoked method
   202   BasicType    result_type(Thread *thread) const; // returns the result type of the invoke
   204   Bytecodes::Code code() const                   { return Bytecodes::code_at(bcp(), _method()); }
   205   Bytecodes::Code adjusted_invoke_code() const   { return Bytecodes::java_code(code()); }
   207   methodHandle static_target(TRAPS);             // "specified" method   (from constant pool)
   209   // Testers
   210   bool is_invokeinterface() const                { return adjusted_invoke_code() == Bytecodes::_invokeinterface; }
   211   bool is_invokevirtual() const                  { return adjusted_invoke_code() == Bytecodes::_invokevirtual; }
   212   bool is_invokestatic() const                   { return adjusted_invoke_code() == Bytecodes::_invokestatic; }
   213   bool is_invokespecial() const                  { return adjusted_invoke_code() == Bytecodes::_invokespecial; }
   214   bool is_invokedynamic() const                  { return adjusted_invoke_code() == Bytecodes::_invokedynamic; }
   216   bool has_receiver() const                      { return !is_invokestatic() && !is_invokedynamic(); }
   218   bool is_valid() const                          { return is_invokeinterface() ||
   219                                                           is_invokevirtual()   ||
   220                                                           is_invokestatic()    ||
   221                                                           is_invokespecial()   ||
   222                                                           is_invokedynamic(); }
   224   // Creation
   225   inline friend Bytecode_invoke* Bytecode_invoke_at(methodHandle method, int bci);
   227   // Like Bytecode_invoke_at. Instead it returns NULL if the bci is not at an invoke.
   228   inline friend Bytecode_invoke* Bytecode_invoke_at_check(methodHandle method, int bci);
   229 };
   231 inline Bytecode_invoke* Bytecode_invoke_at(methodHandle method, int bci) {
   232   Bytecode_invoke* b = new Bytecode_invoke(method, bci);
   233   debug_only(b->verify());
   234   return b;
   235 }
   237 inline Bytecode_invoke* Bytecode_invoke_at_check(methodHandle method, int bci) {
   238   Bytecode_invoke* b = new Bytecode_invoke(method, bci);
   239   return b->is_valid() ? b : NULL;
   240 }
   243 // Abstraction for all field accesses (put/get field/static_
   244 class Bytecode_field: public Bytecode {
   245 public:
   246   void verify() const;
   248   int  index() const;
   249   bool is_static() const;
   251   // Creation
   252   inline friend Bytecode_field* Bytecode_field_at(const methodOop method, address bcp);
   253 };
   255 inline Bytecode_field* Bytecode_field_at(const methodOop method, address bcp) {
   256   Bytecode_field* b = (Bytecode_field*)bcp;
   257   debug_only(b->verify());
   258   return b;
   259 }
   262 // Abstraction for checkcast
   264 class Bytecode_checkcast: public Bytecode {
   265  public:
   266   void verify() const { assert(Bytecodes::java_code(code()) == Bytecodes::_checkcast, "check checkcast"); }
   268   // Returns index
   269   long index() const   { return get_index_u2(Bytecodes::_checkcast); };
   271   // Creation
   272   inline friend Bytecode_checkcast* Bytecode_checkcast_at(address bcp);
   273 };
   275 inline Bytecode_checkcast* Bytecode_checkcast_at(address bcp) {
   276   Bytecode_checkcast* b = (Bytecode_checkcast*)bcp;
   277   debug_only(b->verify());
   278   return b;
   279 }
   282 // Abstraction for instanceof
   284 class Bytecode_instanceof: public Bytecode {
   285  public:
   286   void verify() const { assert(code() == Bytecodes::_instanceof, "check instanceof"); }
   288   // Returns index
   289   long index() const   { return get_index_u2(Bytecodes::_instanceof); };
   291   // Creation
   292   inline friend Bytecode_instanceof* Bytecode_instanceof_at(address bcp);
   293 };
   295 inline Bytecode_instanceof* Bytecode_instanceof_at(address bcp) {
   296   Bytecode_instanceof* b = (Bytecode_instanceof*)bcp;
   297   debug_only(b->verify());
   298   return b;
   299 }
   302 class Bytecode_new: public Bytecode {
   303  public:
   304   void verify() const { assert(java_code() == Bytecodes::_new, "check new"); }
   306   // Returns index
   307   long index() const   { return get_index_u2(Bytecodes::_new); };
   309   // Creation
   310   inline friend Bytecode_new* Bytecode_new_at(address bcp);
   311 };
   313 inline Bytecode_new* Bytecode_new_at(address bcp) {
   314   Bytecode_new* b = (Bytecode_new*)bcp;
   315   debug_only(b->verify());
   316   return b;
   317 }
   320 class Bytecode_multianewarray: public Bytecode {
   321  public:
   322   void verify() const { assert(java_code() == Bytecodes::_multianewarray, "check new"); }
   324   // Returns index
   325   long index() const   { return get_index_u2(Bytecodes::_multianewarray); };
   327   // Creation
   328   inline friend Bytecode_multianewarray* Bytecode_multianewarray_at(address bcp);
   329 };
   331 inline Bytecode_multianewarray* Bytecode_multianewarray_at(address bcp) {
   332   Bytecode_multianewarray* b = (Bytecode_multianewarray*)bcp;
   333   debug_only(b->verify());
   334   return b;
   335 }
   338 class Bytecode_anewarray: public Bytecode {
   339  public:
   340   void verify() const { assert(java_code() == Bytecodes::_anewarray, "check anewarray"); }
   342   // Returns index
   343   long index() const   { return get_index_u2(Bytecodes::_anewarray); };
   345   // Creation
   346   inline friend Bytecode_anewarray* Bytecode_anewarray_at(address bcp);
   347 };
   349 inline Bytecode_anewarray* Bytecode_anewarray_at(address bcp) {
   350   Bytecode_anewarray* b = (Bytecode_anewarray*)bcp;
   351   debug_only(b->verify());
   352   return b;
   353 }
   356 // Abstraction for ldc, ldc_w and ldc2_w
   358 class Bytecode_loadconstant: public Bytecode {
   359  public:
   360   void verify() const {
   361     Bytecodes::Code stdc = Bytecodes::java_code(code());
   362     assert(stdc == Bytecodes::_ldc ||
   363            stdc == Bytecodes::_ldc_w ||
   364            stdc == Bytecodes::_ldc2_w, "load constant");
   365   }
   367   int index() const;
   369   inline friend Bytecode_loadconstant* Bytecode_loadconstant_at(const methodOop method, address bcp);
   370 };
   372 inline Bytecode_loadconstant* Bytecode_loadconstant_at(const methodOop method, address bcp) {
   373   Bytecode_loadconstant* b = (Bytecode_loadconstant*)bcp;
   374   debug_only(b->verify());
   375   return b;
   376 }

mercurial