hotspot/src/share/vm/interpreter/bytecode.hpp
changeset 1 489c9b5090e2
child 2570 ecc7862946d4
equal deleted inserted replaced
0:fd16c54261b3 1:489c9b5090e2
       
     1 /*
       
     2  * Copyright 1997-2002 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    21  * have any questions.
       
    22  *
       
    23  */
       
    24 
       
    25 // Base class for different kinds of abstractions working
       
    26 // relative to an objects 'this' pointer.
       
    27 
       
    28 class ThisRelativeObj VALUE_OBJ_CLASS_SPEC {
       
    29  private:
       
    30   int     sign_extend        (int x, int size)   const     { const int s = (BytesPerInt - size)*BitsPerByte; return (x << s) >> s; }
       
    31 
       
    32  public:
       
    33   // Address computation
       
    34   address addr_at            (int offset)        const     { return (address)this + offset; }
       
    35   address aligned_addr_at    (int offset)        const     { return (address)round_to((intptr_t)addr_at(offset), jintSize); }
       
    36   int     aligned_offset     (int offset)        const     { return aligned_addr_at(offset) - addr_at(0); }
       
    37 
       
    38   // Java unsigned accessors (using Java spec byte ordering)
       
    39   int     java_byte_at       (int offset)        const     { return *(jubyte*)addr_at(offset); }
       
    40   int     java_hwrd_at       (int offset)        const     { return java_byte_at(offset) << (1 * BitsPerByte) | java_byte_at(offset + 1); }
       
    41   int     java_word_at       (int offset)        const     { return java_hwrd_at(offset) << (2 * BitsPerByte) | java_hwrd_at(offset + 2); }
       
    42 
       
    43   // Java signed accessors (using Java spec byte ordering)
       
    44   int     java_signed_byte_at(int offset)        const     { return sign_extend(java_byte_at(offset), 1); }
       
    45   int     java_signed_hwrd_at(int offset)        const     { return sign_extend(java_hwrd_at(offset), 2); }
       
    46   int     java_signed_word_at(int offset)        const     { return             java_word_at(offset)    ; }
       
    47 
       
    48   // Fast accessors (using the machine's natural byte ordering)
       
    49   int     fast_byte_at       (int offset)        const     { return *(jubyte *)addr_at(offset); }
       
    50   int     fast_hwrd_at       (int offset)        const     { return *(jushort*)addr_at(offset); }
       
    51   int     fast_word_at       (int offset)        const     { return *(juint  *)addr_at(offset); }
       
    52 
       
    53   // Fast signed accessors (using the machine's natural byte ordering)
       
    54   int     fast_signed_byte_at(int offset)        const     { return *(jbyte *)addr_at(offset); }
       
    55   int     fast_signed_hwrd_at(int offset)        const     { return *(jshort*)addr_at(offset); }
       
    56   int     fast_signed_word_at(int offset)        const     { return *(jint  *)addr_at(offset); }
       
    57 
       
    58   // Fast manipulators (using the machine's natural byte ordering)
       
    59   void    set_fast_byte_at   (int offset, int x) const     { *(jbyte *)addr_at(offset) = (jbyte )x; }
       
    60   void    set_fast_hwrd_at   (int offset, int x) const     { *(jshort*)addr_at(offset) = (jshort)x; }
       
    61   void    set_fast_word_at   (int offset, int x) const     { *(jint  *)addr_at(offset) = (jint  )x; }
       
    62 };
       
    63 
       
    64 
       
    65 // The base class for different kinds of bytecode abstractions.
       
    66 // Provides the primitive operations to manipulate code relative
       
    67 // to an objects 'this' pointer.
       
    68 //
       
    69 // Note: Even though it seems that the fast_index & set_fast_index
       
    70 //       functions are machine specific, they're not. They only use
       
    71 //       the natural way to store a 16bit index on a given machine,
       
    72 //       independent of the particular byte ordering. Since all other
       
    73 //       places in the system that refer to these indices use the
       
    74 //       same method (the natural byte ordering on the platform)
       
    75 //       this will always work and be machine-independent).
       
    76 
       
    77 class Bytecode: public ThisRelativeObj {
       
    78  protected:
       
    79   u_char byte_at(int offset) const               { return *addr_at(offset); }
       
    80   bool check_must_rewrite() const;
       
    81 
       
    82  public:
       
    83   // Attributes
       
    84   address bcp() const                            { return addr_at(0); }
       
    85   address next_bcp() const                       { return addr_at(0) + Bytecodes::length_at(bcp()); }
       
    86 
       
    87   Bytecodes::Code code() const                   { return Bytecodes::code_at(addr_at(0)); }
       
    88   Bytecodes::Code java_code() const              { return Bytecodes::java_code(code()); }
       
    89   bool must_rewrite() const                      { return Bytecodes::can_rewrite(code()) && check_must_rewrite(); }
       
    90   bool is_active_breakpoint() const              { return Bytecodes::is_active_breakpoint_at(bcp()); }
       
    91 
       
    92   int     one_byte_index() const                 { return byte_at(1); }
       
    93   int     two_byte_index() const                 { return (byte_at(1) << 8) + byte_at(2); }
       
    94   int     offset() const                         { return (two_byte_index() << 16) >> 16; }
       
    95   address destination() const                    { return bcp() + offset(); }
       
    96   int     fast_index() const                     { return Bytes::get_native_u2(addr_at(1)); }
       
    97 
       
    98   // Attribute modification
       
    99   void    set_code(Bytecodes::Code code);
       
   100   void    set_fast_index(int i);
       
   101 
       
   102   // Creation
       
   103   inline friend Bytecode* Bytecode_at(address bcp);
       
   104 };
       
   105 
       
   106 inline Bytecode* Bytecode_at(address bcp) {
       
   107   return (Bytecode*)bcp;
       
   108 }
       
   109 
       
   110 
       
   111 // Abstractions for lookupswitch bytecode
       
   112 
       
   113 class LookupswitchPair: ThisRelativeObj {
       
   114  private:
       
   115   int  _match;
       
   116   int  _offset;
       
   117 
       
   118  public:
       
   119   int  match() const                             { return java_signed_word_at(0 * jintSize); }
       
   120   int  offset() const                            { return java_signed_word_at(1 * jintSize); }
       
   121 };
       
   122 
       
   123 
       
   124 class Bytecode_lookupswitch: public Bytecode {
       
   125  public:
       
   126   void verify() const PRODUCT_RETURN;
       
   127 
       
   128   // Attributes
       
   129   int  default_offset() const                    { return java_signed_word_at(aligned_offset(1 + 0*jintSize)); }
       
   130   int  number_of_pairs() const                   { return java_signed_word_at(aligned_offset(1 + 1*jintSize)); }
       
   131   LookupswitchPair* pair_at(int i) const         { assert(0 <= i && i < number_of_pairs(), "pair index out of bounds");
       
   132                                                    return (LookupswitchPair*)aligned_addr_at(1 + (1 + i)*2*jintSize); }
       
   133   // Creation
       
   134   inline friend Bytecode_lookupswitch* Bytecode_lookupswitch_at(address bcp);
       
   135 };
       
   136 
       
   137 inline Bytecode_lookupswitch* Bytecode_lookupswitch_at(address bcp) {
       
   138   Bytecode_lookupswitch* b = (Bytecode_lookupswitch*)bcp;
       
   139   debug_only(b->verify());
       
   140   return b;
       
   141 }
       
   142 
       
   143 
       
   144 class Bytecode_tableswitch: public Bytecode {
       
   145  public:
       
   146   void verify() const PRODUCT_RETURN;
       
   147 
       
   148   // Attributes
       
   149   int  default_offset() const                    { return java_signed_word_at(aligned_offset(1 + 0*jintSize)); }
       
   150   int  low_key() const                           { return java_signed_word_at(aligned_offset(1 + 1*jintSize)); }
       
   151   int  high_key() const                          { return java_signed_word_at(aligned_offset(1 + 2*jintSize)); }
       
   152   int  dest_offset_at(int i) const;
       
   153   int  length()                                  { return high_key()-low_key()+1; }
       
   154 
       
   155   // Creation
       
   156   inline friend Bytecode_tableswitch* Bytecode_tableswitch_at(address bcp);
       
   157 };
       
   158 
       
   159 inline Bytecode_tableswitch* Bytecode_tableswitch_at(address bcp) {
       
   160   Bytecode_tableswitch* b = (Bytecode_tableswitch*)bcp;
       
   161   debug_only(b->verify());
       
   162   return b;
       
   163 }
       
   164 
       
   165 
       
   166 // Abstraction for invoke_{virtual, static, interface, special}
       
   167 
       
   168 class Bytecode_invoke: public ResourceObj {
       
   169  protected:
       
   170   methodHandle _method;                          // method containing the bytecode
       
   171   int          _bci;                             // position of the bytecode
       
   172 
       
   173   Bytecode_invoke(methodHandle method, int bci)  : _method(method), _bci(bci) {}
       
   174 
       
   175  public:
       
   176   void verify() const;
       
   177 
       
   178   // Attributes
       
   179   methodHandle method() const                    { return _method; }
       
   180   int          bci() const                       { return _bci; }
       
   181   address      bcp() const                       { return _method->bcp_from(bci()); }
       
   182 
       
   183   int          index() const;                    // the constant pool index for the invoke
       
   184   symbolOop    name() const;                     // returns the name of the invoked method
       
   185   symbolOop    signature() const;                // returns the signature of the invoked method
       
   186   BasicType    result_type(Thread *thread) const; // returns the result type of the invoke
       
   187 
       
   188   Bytecodes::Code code() const                   { return Bytecodes::code_at(bcp(), _method()); }
       
   189   Bytecodes::Code adjusted_invoke_code() const   { return Bytecodes::java_code(code()); }
       
   190 
       
   191   methodHandle static_target(TRAPS);             // "specified" method   (from constant pool)
       
   192 
       
   193   // Testers
       
   194   bool is_invokeinterface() const                { return adjusted_invoke_code() == Bytecodes::_invokeinterface; }
       
   195   bool is_invokevirtual() const                  { return adjusted_invoke_code() == Bytecodes::_invokevirtual; }
       
   196   bool is_invokestatic() const                   { return adjusted_invoke_code() == Bytecodes::_invokestatic; }
       
   197   bool is_invokespecial() const                  { return adjusted_invoke_code() == Bytecodes::_invokespecial; }
       
   198 
       
   199   bool is_valid() const                          { return is_invokeinterface() ||
       
   200                                                           is_invokevirtual()   ||
       
   201                                                           is_invokestatic()    ||
       
   202                                                           is_invokespecial();     }
       
   203 
       
   204   // Creation
       
   205   inline friend Bytecode_invoke* Bytecode_invoke_at(methodHandle method, int bci);
       
   206 
       
   207   // Like Bytecode_invoke_at. Instead it returns NULL if the bci is not at an invoke.
       
   208   inline friend Bytecode_invoke* Bytecode_invoke_at_check(methodHandle method, int bci);
       
   209 };
       
   210 
       
   211 inline Bytecode_invoke* Bytecode_invoke_at(methodHandle method, int bci) {
       
   212   Bytecode_invoke* b = new Bytecode_invoke(method, bci);
       
   213   debug_only(b->verify());
       
   214   return b;
       
   215 }
       
   216 
       
   217 inline Bytecode_invoke* Bytecode_invoke_at_check(methodHandle method, int bci) {
       
   218   Bytecode_invoke* b = new Bytecode_invoke(method, bci);
       
   219   return b->is_valid() ? b : NULL;
       
   220 }
       
   221 
       
   222 
       
   223 // Abstraction for all field accesses (put/get field/static_
       
   224 class Bytecode_field: public Bytecode {
       
   225 public:
       
   226   void verify() const;
       
   227 
       
   228   int  index() const;
       
   229   bool is_static() const;
       
   230 
       
   231   // Creation
       
   232   inline friend Bytecode_field* Bytecode_field_at(const methodOop method, address bcp);
       
   233 };
       
   234 
       
   235 inline Bytecode_field* Bytecode_field_at(const methodOop method, address bcp) {
       
   236   Bytecode_field* b = (Bytecode_field*)bcp;
       
   237   debug_only(b->verify());
       
   238   return b;
       
   239 }
       
   240 
       
   241 
       
   242 // Abstraction for {get,put}static
       
   243 
       
   244 class Bytecode_static: public Bytecode {
       
   245  public:
       
   246   void verify() const;
       
   247 
       
   248   // Returns the result type of the send by inspecting the field ref
       
   249   BasicType result_type(methodOop method) const;
       
   250 
       
   251   // Creation
       
   252   inline friend Bytecode_static* Bytecode_static_at(const methodOop method, address bcp);
       
   253 };
       
   254 
       
   255 inline Bytecode_static* Bytecode_static_at(const methodOop method, address bcp) {
       
   256   Bytecode_static* b = (Bytecode_static*)bcp;
       
   257   debug_only(b->verify());
       
   258   return b;
       
   259 }
       
   260 
       
   261 
       
   262 // Abstraction for checkcast
       
   263 
       
   264 class Bytecode_checkcast: public Bytecode {
       
   265  public:
       
   266   void verify() const { assert(Bytecodes::java_code(code()) == Bytecodes::_checkcast, "check checkcast"); }
       
   267 
       
   268   // Returns index
       
   269   long index() const   { return java_hwrd_at(1); };
       
   270 
       
   271   // Creation
       
   272   inline friend Bytecode_checkcast* Bytecode_checkcast_at(address bcp);
       
   273 };
       
   274 
       
   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 }
       
   280 
       
   281 
       
   282 // Abstraction for instanceof
       
   283 
       
   284 class Bytecode_instanceof: public Bytecode {
       
   285  public:
       
   286   void verify() const { assert(code() == Bytecodes::_instanceof, "check instanceof"); }
       
   287 
       
   288   // Returns index
       
   289   long index() const   { return java_hwrd_at(1); };
       
   290 
       
   291   // Creation
       
   292   inline friend Bytecode_instanceof* Bytecode_instanceof_at(address bcp);
       
   293 };
       
   294 
       
   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 }
       
   300 
       
   301 
       
   302 class Bytecode_new: public Bytecode {
       
   303  public:
       
   304   void verify() const { assert(java_code() == Bytecodes::_new, "check new"); }
       
   305 
       
   306   // Returns index
       
   307   long index() const   { return java_hwrd_at(1); };
       
   308 
       
   309   // Creation
       
   310   inline friend Bytecode_new* Bytecode_new_at(address bcp);
       
   311 };
       
   312 
       
   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 }
       
   318 
       
   319 
       
   320 class Bytecode_multianewarray: public Bytecode {
       
   321  public:
       
   322   void verify() const { assert(java_code() == Bytecodes::_multianewarray, "check new"); }
       
   323 
       
   324   // Returns index
       
   325   long index() const   { return java_hwrd_at(1); };
       
   326 
       
   327   // Creation
       
   328   inline friend Bytecode_multianewarray* Bytecode_multianewarray_at(address bcp);
       
   329 };
       
   330 
       
   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 }
       
   336 
       
   337 
       
   338 class Bytecode_anewarray: public Bytecode {
       
   339  public:
       
   340   void verify() const { assert(java_code() == Bytecodes::_anewarray, "check anewarray"); }
       
   341 
       
   342   // Returns index
       
   343   long index() const   { return java_hwrd_at(1); };
       
   344 
       
   345   // Creation
       
   346   inline friend Bytecode_anewarray* Bytecode_anewarray_at(address bcp);
       
   347 };
       
   348 
       
   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 }
       
   354 
       
   355 
       
   356 // Abstraction for ldc, ldc_w and ldc2_w
       
   357 
       
   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   }
       
   366 
       
   367   int index() const;
       
   368 
       
   369   inline friend Bytecode_loadconstant* Bytecode_loadconstant_at(const methodOop method, address bcp);
       
   370 };
       
   371 
       
   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 }