1 /*
   2  * Copyright 1997-2009 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 class Bytecode: public ThisRelativeObj {
  70  protected:
  71   u_char byte_at(int offset) const               { return *addr_at(offset); }
  72   bool check_must_rewrite() const;
  73 
  74  public:
  75   // Attributes
  76   address bcp() const                            { return addr_at(0); }
  77   address next_bcp() const                       { return addr_at(0) + Bytecodes::length_at(bcp()); }
  78   int instruction_size() const                   { return Bytecodes::length_at(bcp()); }
  79 
  80   Bytecodes::Code code() const                   { return Bytecodes::code_at(addr_at(0)); }
  81   Bytecodes::Code java_code() const              { return Bytecodes::java_code(code()); }
  82   bool must_rewrite() const                      { return Bytecodes::can_rewrite(code()) && check_must_rewrite(); }
  83   bool is_active_breakpoint() const              { return Bytecodes::is_active_breakpoint_at(bcp()); }
  84 
  85   int     one_byte_index() const                 { assert_index_size(1); return byte_at(1); }
  86   int     two_byte_index() const                 { assert_index_size(2); return (byte_at(1) << 8) + byte_at(2); }
  87 
  88   int     offset() const                         { return (two_byte_index() << 16) >> 16; }
  89   address destination() const                    { return bcp() + offset(); }
  90 
  91   // Attribute modification
  92   void    set_code(Bytecodes::Code code);
  93 
  94   // Creation
  95   inline friend Bytecode* Bytecode_at(address bcp);
  96 
  97  private:
  98   void assert_index_size(int required_size) const {
  99 #ifdef ASSERT
 100     int isize = instruction_size() - 1;
 101     if (isize == 2 && code() == Bytecodes::_iinc)
 102       isize = 1;
 103     else if (isize <= 2)
 104       ;                         // no change
 105     else if (code() == Bytecodes::_invokedynamic)
 106       isize = 4;
 107     else
 108       isize = 2;
 109     assert(isize = required_size, "wrong index size");
 110 #endif
 111   }
 112 };
 113 
 114 inline Bytecode* Bytecode_at(address bcp) {
 115   return (Bytecode*)bcp;
 116 }
 117 
 118 
 119 // Abstractions for lookupswitch bytecode
 120 
 121 class LookupswitchPair: ThisRelativeObj {
 122  private:
 123   int  _match;
 124   int  _offset;
 125 
 126  public:
 127   int  match() const                             { return java_signed_word_at(0 * jintSize); }
 128   int  offset() const                            { return java_signed_word_at(1 * jintSize); }
 129 };
 130 
 131 
 132 class Bytecode_lookupswitch: public Bytecode {
 133  public:
 134   void verify() const PRODUCT_RETURN;
 135 
 136   // Attributes
 137   int  default_offset() const                    { return java_signed_word_at(aligned_offset(1 + 0*jintSize)); }
 138   int  number_of_pairs() const                   { return java_signed_word_at(aligned_offset(1 + 1*jintSize)); }
 139   LookupswitchPair* pair_at(int i) const         { assert(0 <= i && i < number_of_pairs(), "pair index out of bounds");
 140                                                    return (LookupswitchPair*)aligned_addr_at(1 + (1 + i)*2*jintSize); }
 141   // Creation
 142   inline friend Bytecode_lookupswitch* Bytecode_lookupswitch_at(address bcp);
 143 };
 144 
 145 inline Bytecode_lookupswitch* Bytecode_lookupswitch_at(address bcp) {
 146   Bytecode_lookupswitch* b = (Bytecode_lookupswitch*)bcp;
 147   debug_only(b->verify());
 148   return b;
 149 }
 150 
 151 
 152 class Bytecode_tableswitch: public Bytecode {
 153  public:
 154   void verify() const PRODUCT_RETURN;
 155 
 156   // Attributes
 157   int  default_offset() const                    { return java_signed_word_at(aligned_offset(1 + 0*jintSize)); }
 158   int  low_key() const                           { return java_signed_word_at(aligned_offset(1 + 1*jintSize)); }
 159   int  high_key() const                          { return java_signed_word_at(aligned_offset(1 + 2*jintSize)); }
 160   int  dest_offset_at(int i) const;
 161   int  length()                                  { return high_key()-low_key()+1; }
 162 
 163   // Creation
 164   inline friend Bytecode_tableswitch* Bytecode_tableswitch_at(address bcp);
 165 };
 166 
 167 inline Bytecode_tableswitch* Bytecode_tableswitch_at(address bcp) {
 168   Bytecode_tableswitch* b = (Bytecode_tableswitch*)bcp;
 169   debug_only(b->verify());
 170   return b;
 171 }
 172 
 173 
 174 // Abstraction for invoke_{virtual, static, interface, special}
 175 
 176 class Bytecode_invoke: public ResourceObj {
 177  protected:
 178   methodHandle _method;                          // method containing the bytecode
 179   int          _bci;                             // position of the bytecode
 180 
 181   Bytecode_invoke(methodHandle method, int bci)  : _method(method), _bci(bci) {}
 182 
 183  public:
 184   void verify() const;
 185 
 186   // Attributes
 187   methodHandle method() const                    { return _method; }
 188   int          bci() const                       { return _bci; }
 189   address      bcp() const                       { return _method->bcp_from(bci()); }
 190 
 191   int          index() const;                    // the constant pool index for the invoke
 192   symbolOop    name() const;                     // returns the name of the invoked method
 193   symbolOop    signature() const;                // returns the signature of the invoked method
 194   BasicType    result_type(Thread *thread) const; // returns the result type of the invoke
 195 
 196   Bytecodes::Code code() const                   { return Bytecodes::code_at(bcp(), _method()); }
 197   Bytecodes::Code adjusted_invoke_code() const   { return Bytecodes::java_code(code()); }
 198 
 199   methodHandle static_target(TRAPS);             // "specified" method   (from constant pool)
 200 
 201   // Testers
 202   bool is_invokeinterface() const                { return adjusted_invoke_code() == Bytecodes::_invokeinterface; }
 203   bool is_invokevirtual() const                  { return adjusted_invoke_code() == Bytecodes::_invokevirtual; }
 204   bool is_invokestatic() const                   { return adjusted_invoke_code() == Bytecodes::_invokestatic; }
 205   bool is_invokespecial() const                  { return adjusted_invoke_code() == Bytecodes::_invokespecial; }
 206   bool is_invokedynamic() const                  { return adjusted_invoke_code() == Bytecodes::_invokedynamic; }
 207 
 208   bool has_giant_index() const                   { return is_invokedynamic(); }
 209 
 210   bool is_valid() const                          { return is_invokeinterface() ||
 211                                                           is_invokevirtual()   ||
 212                                                           is_invokestatic()    ||
 213                                                           is_invokespecial()   ||
 214                                                           is_invokedynamic(); }
 215 
 216   // Creation
 217   inline friend Bytecode_invoke* Bytecode_invoke_at(methodHandle method, int bci);
 218 
 219   // Like Bytecode_invoke_at. Instead it returns NULL if the bci is not at an invoke.
 220   inline friend Bytecode_invoke* Bytecode_invoke_at_check(methodHandle method, int bci);
 221 };
 222 
 223 inline Bytecode_invoke* Bytecode_invoke_at(methodHandle method, int bci) {
 224   Bytecode_invoke* b = new Bytecode_invoke(method, bci);
 225   debug_only(b->verify());
 226   return b;
 227 }
 228 
 229 inline Bytecode_invoke* Bytecode_invoke_at_check(methodHandle method, int bci) {
 230   Bytecode_invoke* b = new Bytecode_invoke(method, bci);
 231   return b->is_valid() ? b : NULL;
 232 }
 233 
 234 
 235 // Abstraction for all field accesses (put/get field/static_
 236 class Bytecode_field: public Bytecode {
 237 public:
 238   void verify() const;
 239 
 240   int  index() const;
 241   bool is_static() const;
 242 
 243   // Creation
 244   inline friend Bytecode_field* Bytecode_field_at(const methodOop method, address bcp);
 245 };
 246 
 247 inline Bytecode_field* Bytecode_field_at(const methodOop method, address bcp) {
 248   Bytecode_field* b = (Bytecode_field*)bcp;
 249   debug_only(b->verify());
 250   return b;
 251 }
 252 
 253 
 254 // Abstraction for {get,put}static
 255 
 256 class Bytecode_static: public Bytecode {
 257  public:
 258   void verify() const;
 259 
 260   // Returns the result type of the send by inspecting the field ref
 261   BasicType result_type(methodOop method) const;
 262 
 263   // Creation
 264   inline friend Bytecode_static* Bytecode_static_at(const methodOop method, address bcp);
 265 };
 266 
 267 inline Bytecode_static* Bytecode_static_at(const methodOop method, address bcp) {
 268   Bytecode_static* b = (Bytecode_static*)bcp;
 269   debug_only(b->verify());
 270   return b;
 271 }
 272 
 273 
 274 // Abstraction for checkcast
 275 
 276 class Bytecode_checkcast: public Bytecode {
 277  public:
 278   void verify() const { assert(Bytecodes::java_code(code()) == Bytecodes::_checkcast, "check checkcast"); }
 279 
 280   // Returns index
 281   long index() const   { return java_hwrd_at(1); };
 282 
 283   // Creation
 284   inline friend Bytecode_checkcast* Bytecode_checkcast_at(address bcp);
 285 };
 286 
 287 inline Bytecode_checkcast* Bytecode_checkcast_at(address bcp) {
 288   Bytecode_checkcast* b = (Bytecode_checkcast*)bcp;
 289   debug_only(b->verify());
 290   return b;
 291 }
 292 
 293 
 294 // Abstraction for instanceof
 295 
 296 class Bytecode_instanceof: public Bytecode {
 297  public:
 298   void verify() const { assert(code() == Bytecodes::_instanceof, "check instanceof"); }
 299 
 300   // Returns index
 301   long index() const   { return java_hwrd_at(1); };
 302 
 303   // Creation
 304   inline friend Bytecode_instanceof* Bytecode_instanceof_at(address bcp);
 305 };
 306 
 307 inline Bytecode_instanceof* Bytecode_instanceof_at(address bcp) {
 308   Bytecode_instanceof* b = (Bytecode_instanceof*)bcp;
 309   debug_only(b->verify());
 310   return b;
 311 }
 312 
 313 
 314 class Bytecode_new: public Bytecode {
 315  public:
 316   void verify() const { assert(java_code() == Bytecodes::_new, "check new"); }
 317 
 318   // Returns index
 319   long index() const   { return java_hwrd_at(1); };
 320 
 321   // Creation
 322   inline friend Bytecode_new* Bytecode_new_at(address bcp);
 323 };
 324 
 325 inline Bytecode_new* Bytecode_new_at(address bcp) {
 326   Bytecode_new* b = (Bytecode_new*)bcp;
 327   debug_only(b->verify());
 328   return b;
 329 }
 330 
 331 
 332 class Bytecode_multianewarray: public Bytecode {
 333  public:
 334   void verify() const { assert(java_code() == Bytecodes::_multianewarray, "check new"); }
 335 
 336   // Returns index
 337   long index() const   { return java_hwrd_at(1); };
 338 
 339   // Creation
 340   inline friend Bytecode_multianewarray* Bytecode_multianewarray_at(address bcp);
 341 };
 342 
 343 inline Bytecode_multianewarray* Bytecode_multianewarray_at(address bcp) {
 344   Bytecode_multianewarray* b = (Bytecode_multianewarray*)bcp;
 345   debug_only(b->verify());
 346   return b;
 347 }
 348 
 349 
 350 class Bytecode_anewarray: public Bytecode {
 351  public:
 352   void verify() const { assert(java_code() == Bytecodes::_anewarray, "check anewarray"); }
 353 
 354   // Returns index
 355   long index() const   { return java_hwrd_at(1); };
 356 
 357   // Creation
 358   inline friend Bytecode_anewarray* Bytecode_anewarray_at(address bcp);
 359 };
 360 
 361 inline Bytecode_anewarray* Bytecode_anewarray_at(address bcp) {
 362   Bytecode_anewarray* b = (Bytecode_anewarray*)bcp;
 363   debug_only(b->verify());
 364   return b;
 365 }
 366 
 367 
 368 // Abstraction for ldc, ldc_w and ldc2_w
 369 
 370 class Bytecode_loadconstant: public Bytecode {
 371  public:
 372   void verify() const {
 373     Bytecodes::Code stdc = Bytecodes::java_code(code());
 374     assert(stdc == Bytecodes::_ldc ||
 375            stdc == Bytecodes::_ldc_w ||
 376            stdc == Bytecodes::_ldc2_w, "load constant");
 377   }
 378 
 379   int index() const;
 380 
 381   inline friend Bytecode_loadconstant* Bytecode_loadconstant_at(const methodOop method, address bcp);
 382 };
 383 
 384 inline Bytecode_loadconstant* Bytecode_loadconstant_at(const methodOop method, address bcp) {
 385   Bytecode_loadconstant* b = (Bytecode_loadconstant*)bcp;
 386   debug_only(b->verify());
 387   return b;
 388 }