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_receiver() const                      { return !is_invokestatic() && !is_invokedynamic(); }
 209   bool has_giant_index() const                   { return is_invokedynamic(); }
 210 
 211   bool is_valid() const                          { return is_invokeinterface() ||
 212                                                           is_invokevirtual()   ||
 213                                                           is_invokestatic()    ||
 214                                                           is_invokespecial()   ||
 215                                                           is_invokedynamic(); }
 216 
 217   // Creation
 218   inline friend Bytecode_invoke* Bytecode_invoke_at(methodHandle method, int bci);
 219 
 220   // Like Bytecode_invoke_at. Instead it returns NULL if the bci is not at an invoke.
 221   inline friend Bytecode_invoke* Bytecode_invoke_at_check(methodHandle method, int bci);
 222 };
 223 
 224 inline Bytecode_invoke* Bytecode_invoke_at(methodHandle method, int bci) {
 225   Bytecode_invoke* b = new Bytecode_invoke(method, bci);
 226   debug_only(b->verify());
 227   return b;
 228 }
 229 
 230 inline Bytecode_invoke* Bytecode_invoke_at_check(methodHandle method, int bci) {
 231   Bytecode_invoke* b = new Bytecode_invoke(method, bci);
 232   return b->is_valid() ? b : NULL;
 233 }
 234 
 235 
 236 // Abstraction for all field accesses (put/get field/static_
 237 class Bytecode_field: public Bytecode {
 238 public:
 239   void verify() const;
 240 
 241   int  index() const;
 242   bool is_static() const;
 243 
 244   // Creation
 245   inline friend Bytecode_field* Bytecode_field_at(const methodOop method, address bcp);
 246 };
 247 
 248 inline Bytecode_field* Bytecode_field_at(const methodOop method, address bcp) {
 249   Bytecode_field* b = (Bytecode_field*)bcp;
 250   debug_only(b->verify());
 251   return b;
 252 }
 253 
 254 
 255 // Abstraction for {get,put}static
 256 
 257 class Bytecode_static: public Bytecode {
 258  public:
 259   void verify() const;
 260 
 261   // Returns the result type of the send by inspecting the field ref
 262   BasicType result_type(methodOop method) const;
 263 
 264   // Creation
 265   inline friend Bytecode_static* Bytecode_static_at(const methodOop method, address bcp);
 266 };
 267 
 268 inline Bytecode_static* Bytecode_static_at(const methodOop method, address bcp) {
 269   Bytecode_static* b = (Bytecode_static*)bcp;
 270   debug_only(b->verify());
 271   return b;
 272 }
 273 
 274 
 275 // Abstraction for checkcast
 276 
 277 class Bytecode_checkcast: public Bytecode {
 278  public:
 279   void verify() const { assert(Bytecodes::java_code(code()) == Bytecodes::_checkcast, "check checkcast"); }
 280 
 281   // Returns index
 282   long index() const   { return java_hwrd_at(1); };
 283 
 284   // Creation
 285   inline friend Bytecode_checkcast* Bytecode_checkcast_at(address bcp);
 286 };
 287 
 288 inline Bytecode_checkcast* Bytecode_checkcast_at(address bcp) {
 289   Bytecode_checkcast* b = (Bytecode_checkcast*)bcp;
 290   debug_only(b->verify());
 291   return b;
 292 }
 293 
 294 
 295 // Abstraction for instanceof
 296 
 297 class Bytecode_instanceof: public Bytecode {
 298  public:
 299   void verify() const { assert(code() == Bytecodes::_instanceof, "check instanceof"); }
 300 
 301   // Returns index
 302   long index() const   { return java_hwrd_at(1); };
 303 
 304   // Creation
 305   inline friend Bytecode_instanceof* Bytecode_instanceof_at(address bcp);
 306 };
 307 
 308 inline Bytecode_instanceof* Bytecode_instanceof_at(address bcp) {
 309   Bytecode_instanceof* b = (Bytecode_instanceof*)bcp;
 310   debug_only(b->verify());
 311   return b;
 312 }
 313 
 314 
 315 class Bytecode_new: public Bytecode {
 316  public:
 317   void verify() const { assert(java_code() == Bytecodes::_new, "check new"); }
 318 
 319   // Returns index
 320   long index() const   { return java_hwrd_at(1); };
 321 
 322   // Creation
 323   inline friend Bytecode_new* Bytecode_new_at(address bcp);
 324 };
 325 
 326 inline Bytecode_new* Bytecode_new_at(address bcp) {
 327   Bytecode_new* b = (Bytecode_new*)bcp;
 328   debug_only(b->verify());
 329   return b;
 330 }
 331 
 332 
 333 class Bytecode_multianewarray: public Bytecode {
 334  public:
 335   void verify() const { assert(java_code() == Bytecodes::_multianewarray, "check new"); }
 336 
 337   // Returns index
 338   long index() const   { return java_hwrd_at(1); };
 339 
 340   // Creation
 341   inline friend Bytecode_multianewarray* Bytecode_multianewarray_at(address bcp);
 342 };
 343 
 344 inline Bytecode_multianewarray* Bytecode_multianewarray_at(address bcp) {
 345   Bytecode_multianewarray* b = (Bytecode_multianewarray*)bcp;
 346   debug_only(b->verify());
 347   return b;
 348 }
 349 
 350 
 351 class Bytecode_anewarray: public Bytecode {
 352  public:
 353   void verify() const { assert(java_code() == Bytecodes::_anewarray, "check anewarray"); }
 354 
 355   // Returns index
 356   long index() const   { return java_hwrd_at(1); };
 357 
 358   // Creation
 359   inline friend Bytecode_anewarray* Bytecode_anewarray_at(address bcp);
 360 };
 361 
 362 inline Bytecode_anewarray* Bytecode_anewarray_at(address bcp) {
 363   Bytecode_anewarray* b = (Bytecode_anewarray*)bcp;
 364   debug_only(b->verify());
 365   return b;
 366 }
 367 
 368 
 369 // Abstraction for ldc, ldc_w and ldc2_w
 370 
 371 class Bytecode_loadconstant: public Bytecode {
 372  public:
 373   void verify() const {
 374     Bytecodes::Code stdc = Bytecodes::java_code(code());
 375     assert(stdc == Bytecodes::_ldc ||
 376            stdc == Bytecodes::_ldc_w ||
 377            stdc == Bytecodes::_ldc2_w, "load constant");
 378   }
 379 
 380   int index() const;
 381 
 382   inline friend Bytecode_loadconstant* Bytecode_loadconstant_at(const methodOop method, address bcp);
 383 };
 384 
 385 inline Bytecode_loadconstant* Bytecode_loadconstant_at(const methodOop method, address bcp) {
 386   Bytecode_loadconstant* b = (Bytecode_loadconstant*)bcp;
 387   debug_only(b->verify());
 388   return b;
 389 }