src/share/vm/interpreter/bytecode.hpp

Sun, 13 Apr 2008 17:43:42 -0400

author
coleenp
date
Sun, 13 Apr 2008 17:43:42 -0400
changeset 548
ba764ed4b6f2
parent 435
a61af66fc99e
child 1161
be93aad57795
permissions
-rw-r--r--

6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
Summary: Compressed oops in instances, arrays, and headers. Code contributors are coleenp, phh, never, swamyv
Reviewed-by: jmasa, kamg, acorn, tbell, kvn, rasbold

     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  */
    25 // Base class for different kinds of abstractions working
    26 // relative to an objects 'this' pointer.
    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; }
    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); }
    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); }
    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)    ; }
    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); }
    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); }
    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 };
    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).
    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;
    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()); }
    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()); }
    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)); }
    98   // Attribute modification
    99   void    set_code(Bytecodes::Code code);
   100   void    set_fast_index(int i);
   102   // Creation
   103   inline friend Bytecode* Bytecode_at(address bcp);
   104 };
   106 inline Bytecode* Bytecode_at(address bcp) {
   107   return (Bytecode*)bcp;
   108 }
   111 // Abstractions for lookupswitch bytecode
   113 class LookupswitchPair: ThisRelativeObj {
   114  private:
   115   int  _match;
   116   int  _offset;
   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 };
   124 class Bytecode_lookupswitch: public Bytecode {
   125  public:
   126   void verify() const PRODUCT_RETURN;
   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 };
   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 }
   144 class Bytecode_tableswitch: public Bytecode {
   145  public:
   146   void verify() const PRODUCT_RETURN;
   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; }
   155   // Creation
   156   inline friend Bytecode_tableswitch* Bytecode_tableswitch_at(address bcp);
   157 };
   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 }
   166 // Abstraction for invoke_{virtual, static, interface, special}
   168 class Bytecode_invoke: public ResourceObj {
   169  protected:
   170   methodHandle _method;                          // method containing the bytecode
   171   int          _bci;                             // position of the bytecode
   173   Bytecode_invoke(methodHandle method, int bci)  : _method(method), _bci(bci) {}
   175  public:
   176   void verify() const;
   178   // Attributes
   179   methodHandle method() const                    { return _method; }
   180   int          bci() const                       { return _bci; }
   181   address      bcp() const                       { return _method->bcp_from(bci()); }
   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
   188   Bytecodes::Code code() const                   { return Bytecodes::code_at(bcp(), _method()); }
   189   Bytecodes::Code adjusted_invoke_code() const   { return Bytecodes::java_code(code()); }
   191   methodHandle static_target(TRAPS);             // "specified" method   (from constant pool)
   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; }
   199   bool is_valid() const                          { return is_invokeinterface() ||
   200                                                           is_invokevirtual()   ||
   201                                                           is_invokestatic()    ||
   202                                                           is_invokespecial();     }
   204   // Creation
   205   inline friend Bytecode_invoke* Bytecode_invoke_at(methodHandle method, int bci);
   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 };
   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 }
   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 }
   223 // Abstraction for all field accesses (put/get field/static_
   224 class Bytecode_field: public Bytecode {
   225 public:
   226   void verify() const;
   228   int  index() const;
   229   bool is_static() const;
   231   // Creation
   232   inline friend Bytecode_field* Bytecode_field_at(const methodOop method, address bcp);
   233 };
   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 }
   242 // Abstraction for {get,put}static
   244 class Bytecode_static: public Bytecode {
   245  public:
   246   void verify() const;
   248   // Returns the result type of the send by inspecting the field ref
   249   BasicType result_type(methodOop method) const;
   251   // Creation
   252   inline friend Bytecode_static* Bytecode_static_at(const methodOop method, address bcp);
   253 };
   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 }
   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 java_hwrd_at(1); };
   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 java_hwrd_at(1); };
   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 java_hwrd_at(1); };
   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 java_hwrd_at(1); };
   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 java_hwrd_at(1); };
   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