src/share/vm/interpreter/bytecode.hpp

changeset 2462
8012aa3ccede
parent 2314
f95d63e2154a
child 2497
3582bf76420e
     1.1 --- a/src/share/vm/interpreter/bytecode.hpp	Wed Jan 12 13:59:18 2011 -0800
     1.2 +++ b/src/share/vm/interpreter/bytecode.hpp	Thu Jan 13 22:15:41 2011 -0800
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -38,14 +38,20 @@
    1.11  # include "bytes_zero.hpp"
    1.12  #endif
    1.13  
    1.14 -// Base class for different kinds of abstractions working
    1.15 -// relative to an objects 'this' pointer.
    1.16 +class ciBytecodeStream;
    1.17  
    1.18 -class ThisRelativeObj VALUE_OBJ_CLASS_SPEC {
    1.19 - public:
    1.20 +// The base class for different kinds of bytecode abstractions.
    1.21 +// Provides the primitive operations to manipulate code relative
    1.22 +// to the bcp.
    1.23 +
    1.24 +class Bytecode: public StackObj {
    1.25 + protected:
    1.26 +  const address   _bcp;
    1.27 +  const Bytecodes::Code _code;
    1.28 +
    1.29    // Address computation
    1.30 -  address addr_at            (int offset)        const     { return (address)this + offset; }
    1.31 -  int     byte_at            (int offset)        const     { return *(addr_at(offset)); }
    1.32 +  address addr_at            (int offset)        const     { return (address)_bcp + offset; }
    1.33 +  u_char byte_at(int offset) const               { return *addr_at(offset); }
    1.34    address aligned_addr_at    (int offset)        const     { return (address)round_to((intptr_t)addr_at(offset), jintSize); }
    1.35    int     aligned_offset     (int offset)        const     { return aligned_addr_at(offset) - addr_at(0); }
    1.36  
    1.37 @@ -54,31 +60,20 @@
    1.38    int     get_Java_u4_at     (int offset)        const     { return Bytes::get_Java_u4(addr_at(offset)); }
    1.39    int     get_native_u2_at   (int offset)        const     { return Bytes::get_native_u2(addr_at(offset)); }
    1.40    int     get_native_u4_at   (int offset)        const     { return Bytes::get_native_u4(addr_at(offset)); }
    1.41 -};
    1.42 -
    1.43 -
    1.44 -// The base class for different kinds of bytecode abstractions.
    1.45 -// Provides the primitive operations to manipulate code relative
    1.46 -// to an objects 'this' pointer.
    1.47 -// FIXME: Make this a ResourceObj, include the enclosing methodOop, and cache the opcode.
    1.48 -
    1.49 -class Bytecode: public ThisRelativeObj {
    1.50 - protected:
    1.51 -  u_char byte_at(int offset) const               { return *addr_at(offset); }
    1.52 -  bool check_must_rewrite(Bytecodes::Code bc) const;
    1.53  
    1.54   public:
    1.55 +  Bytecode(methodOop method, address bcp): _bcp(bcp), _code(Bytecodes::code_at(method, addr_at(0))) {
    1.56 +    assert(method != NULL, "this form requires a valid methodOop");
    1.57 +  }
    1.58 +  // Defined in ciStreams.hpp
    1.59 +  inline Bytecode(const ciBytecodeStream* stream, address bcp = NULL);
    1.60 +
    1.61    // Attributes
    1.62 -  address bcp() const                            { return addr_at(0); }
    1.63 -  int instruction_size() const                   { return Bytecodes::length_at(bcp()); }
    1.64 +  address bcp() const                            { return _bcp; }
    1.65 +  int instruction_size() const                   { return Bytecodes::length_for_code_at(_code, bcp()); }
    1.66  
    1.67 -  // Warning: Use code() with caution on live bytecode streams.  4926272
    1.68 -  Bytecodes::Code code() const                   { return Bytecodes::code_at(addr_at(0)); }
    1.69 +  Bytecodes::Code code() const                   { return _code; }
    1.70    Bytecodes::Code java_code() const              { return Bytecodes::java_code(code()); }
    1.71 -  bool must_rewrite(Bytecodes::Code code) const  { return Bytecodes::can_rewrite(code) && check_must_rewrite(code); }
    1.72 -
    1.73 -  // Creation
    1.74 -  inline friend Bytecode* Bytecode_at(address bcp);
    1.75  
    1.76    // Static functions for parsing bytecodes in place.
    1.77    int get_index_u1(Bytecodes::Code bc) const {
    1.78 @@ -89,7 +84,7 @@
    1.79      assert_same_format_as(bc, is_wide); assert_index_size(2, bc, is_wide);
    1.80      address p = addr_at(is_wide ? 2 : 1);
    1.81      if (can_use_native_byte_order(bc, is_wide))
    1.82 -          return Bytes::get_native_u2(p);
    1.83 +      return Bytes::get_native_u2(p);
    1.84      else  return Bytes::get_Java_u2(p);
    1.85    }
    1.86    int get_index_u1_cpcache(Bytecodes::Code bc) const {
    1.87 @@ -138,20 +133,17 @@
    1.88    }
    1.89  };
    1.90  
    1.91 -inline Bytecode* Bytecode_at(address bcp) {
    1.92 -  // Warning: Use with caution on live bytecode streams.  4926272
    1.93 -  return (Bytecode*)bcp;
    1.94 -}
    1.95 -
    1.96  
    1.97  // Abstractions for lookupswitch bytecode
    1.98 +class LookupswitchPair VALUE_OBJ_CLASS_SPEC {
    1.99 + private:
   1.100 +  const address _bcp;
   1.101  
   1.102 -class LookupswitchPair: ThisRelativeObj {
   1.103 - private:
   1.104 -  int  _match;
   1.105 -  int  _offset;
   1.106 +  address addr_at            (int offset)        const     { return _bcp + offset; }
   1.107 +  int     get_Java_u4_at     (int offset)        const     { return Bytes::get_Java_u4(addr_at(offset)); }
   1.108  
   1.109   public:
   1.110 +  LookupswitchPair(address bcp): _bcp(bcp) {}
   1.111    int  match() const                             { return get_Java_u4_at(0 * jintSize); }
   1.112    int  offset() const                            { return get_Java_u4_at(1 * jintSize); }
   1.113  };
   1.114 @@ -159,26 +151,25 @@
   1.115  
   1.116  class Bytecode_lookupswitch: public Bytecode {
   1.117   public:
   1.118 +  Bytecode_lookupswitch(methodOop method, address bcp): Bytecode(method, bcp) { verify(); }
   1.119 +  // Defined in ciStreams.hpp
   1.120 +  inline Bytecode_lookupswitch(const ciBytecodeStream* stream);
   1.121    void verify() const PRODUCT_RETURN;
   1.122  
   1.123    // Attributes
   1.124    int  default_offset() const                    { return get_Java_u4_at(aligned_offset(1 + 0*jintSize)); }
   1.125    int  number_of_pairs() const                   { return get_Java_u4_at(aligned_offset(1 + 1*jintSize)); }
   1.126 -  LookupswitchPair* pair_at(int i) const         { assert(0 <= i && i < number_of_pairs(), "pair index out of bounds");
   1.127 -                                                   return (LookupswitchPair*)aligned_addr_at(1 + (1 + i)*2*jintSize); }
   1.128 -  // Creation
   1.129 -  inline friend Bytecode_lookupswitch* Bytecode_lookupswitch_at(address bcp);
   1.130 +  LookupswitchPair pair_at(int i) const          {
   1.131 +    assert(0 <= i && i < number_of_pairs(), "pair index out of bounds");
   1.132 +    return LookupswitchPair(aligned_addr_at(1 + (1 + i)*2*jintSize));
   1.133 +  }
   1.134  };
   1.135  
   1.136 -inline Bytecode_lookupswitch* Bytecode_lookupswitch_at(address bcp) {
   1.137 -  Bytecode_lookupswitch* b = (Bytecode_lookupswitch*)bcp;
   1.138 -  DEBUG_ONLY(b->verify());
   1.139 -  return b;
   1.140 -}
   1.141 -
   1.142 -
   1.143  class Bytecode_tableswitch: public Bytecode {
   1.144   public:
   1.145 +  Bytecode_tableswitch(methodOop method, address bcp): Bytecode(method, bcp) { verify(); }
   1.146 +  // Defined in ciStreams.hpp
   1.147 +  inline Bytecode_tableswitch(const ciBytecodeStream* stream);
   1.148    void verify() const PRODUCT_RETURN;
   1.149  
   1.150    // Attributes
   1.151 @@ -187,52 +178,36 @@
   1.152    int  high_key() const                          { return get_Java_u4_at(aligned_offset(1 + 2*jintSize)); }
   1.153    int  dest_offset_at(int i) const;
   1.154    int  length()                                  { return high_key()-low_key()+1; }
   1.155 -
   1.156 -  // Creation
   1.157 -  inline friend Bytecode_tableswitch* Bytecode_tableswitch_at(address bcp);
   1.158  };
   1.159  
   1.160 -inline Bytecode_tableswitch* Bytecode_tableswitch_at(address bcp) {
   1.161 -  Bytecode_tableswitch* b = (Bytecode_tableswitch*)bcp;
   1.162 -  DEBUG_ONLY(b->verify());
   1.163 -  return b;
   1.164 -}
   1.165 -
   1.166 -
   1.167  // Common code for decoding invokes and field references.
   1.168  
   1.169 -class Bytecode_member_ref: public ResourceObj {
   1.170 +class Bytecode_member_ref: public Bytecode {
   1.171   protected:
   1.172 -  methodHandle _method;                          // method containing the bytecode
   1.173 -  int          _bci;                             // position of the bytecode
   1.174 +  const methodHandle _method;                          // method containing the bytecode
   1.175  
   1.176 -  Bytecode_member_ref(methodHandle method, int bci)  : _method(method), _bci(bci) {}
   1.177 +  Bytecode_member_ref(methodHandle method, int bci)  : Bytecode(method(), method()->bcp_from(bci)), _method(method) {}
   1.178 +
   1.179 +  methodHandle method() const                    { return _method; }
   1.180  
   1.181   public:
   1.182 -  // Attributes
   1.183 -  methodHandle method() const                    { return _method; }
   1.184 -  int          bci() const                       { return _bci; }
   1.185 -  address      bcp() const                       { return _method->bcp_from(bci()); }
   1.186 -  Bytecode*    bytecode() const                  { return Bytecode_at(bcp()); }
   1.187 -
   1.188    int          index() const;                    // cache index (loaded from instruction)
   1.189    int          pool_index() const;               // constant pool index
   1.190    symbolOop    name() const;                     // returns the name of the method or field
   1.191    symbolOop    signature() const;                // returns the signature of the method or field
   1.192  
   1.193    BasicType    result_type(Thread* thread) const; // returns the result type of the getfield or invoke
   1.194 -
   1.195 -  Bytecodes::Code code() const                   { return Bytecodes::code_at(bcp(), _method()); }
   1.196 -  Bytecodes::Code java_code() const              { return Bytecodes::java_code(code()); }
   1.197  };
   1.198  
   1.199  // Abstraction for invoke_{virtual, static, interface, special}
   1.200  
   1.201  class Bytecode_invoke: public Bytecode_member_ref {
   1.202   protected:
   1.203 -  Bytecode_invoke(methodHandle method, int bci)  : Bytecode_member_ref(method, bci) {}
   1.204 +  // Constructor that skips verification
   1.205 +  Bytecode_invoke(methodHandle method, int bci, bool unused)  : Bytecode_member_ref(method, bci) {}
   1.206  
   1.207   public:
   1.208 +  Bytecode_invoke(methodHandle method, int bci)  : Bytecode_member_ref(method, bci) { verify(); }
   1.209    void verify() const;
   1.210  
   1.211    // Attributes
   1.212 @@ -253,31 +228,20 @@
   1.213                                                            is_invokespecial()   ||
   1.214                                                            is_invokedynamic(); }
   1.215  
   1.216 -  // Creation
   1.217 -  inline friend Bytecode_invoke* Bytecode_invoke_at(methodHandle method, int bci);
   1.218 -
   1.219 -  // Like Bytecode_invoke_at. Instead it returns NULL if the bci is not at an invoke.
   1.220 -  inline friend Bytecode_invoke* Bytecode_invoke_at_check(methodHandle method, int bci);
   1.221 +  // Helper to skip verification.   Used is_valid() to check if the result is really an invoke
   1.222 +  inline friend Bytecode_invoke Bytecode_invoke_check(methodHandle method, int bci);
   1.223  };
   1.224  
   1.225 -inline Bytecode_invoke* Bytecode_invoke_at(methodHandle method, int bci) {
   1.226 -  Bytecode_invoke* b = new Bytecode_invoke(method, bci);
   1.227 -  DEBUG_ONLY(b->verify());
   1.228 -  return b;
   1.229 -}
   1.230 -
   1.231 -inline Bytecode_invoke* Bytecode_invoke_at_check(methodHandle method, int bci) {
   1.232 -  Bytecode_invoke* b = new Bytecode_invoke(method, bci);
   1.233 -  return b->is_valid() ? b : NULL;
   1.234 +inline Bytecode_invoke Bytecode_invoke_check(methodHandle method, int bci) {
   1.235 +  return Bytecode_invoke(method, bci, false);
   1.236  }
   1.237  
   1.238  
   1.239  // Abstraction for all field accesses (put/get field/static)
   1.240  class Bytecode_field: public Bytecode_member_ref {
   1.241 - protected:
   1.242 -  Bytecode_field(methodHandle method, int bci)  : Bytecode_member_ref(method, bci) {}
   1.243 + public:
   1.244 +  Bytecode_field(methodHandle method, int bci)  : Bytecode_member_ref(method, bci) { verify(); }
   1.245  
   1.246 - public:
   1.247    // Testers
   1.248    bool is_getfield() const                       { return java_code() == Bytecodes::_getfield; }
   1.249    bool is_putfield() const                       { return java_code() == Bytecodes::_putfield; }
   1.250 @@ -292,131 +256,64 @@
   1.251                                                            is_getstatic()  ||
   1.252                                                            is_putstatic(); }
   1.253    void verify() const;
   1.254 -
   1.255 -  // Creation
   1.256 -  inline friend Bytecode_field* Bytecode_field_at(methodHandle method, int bci);
   1.257  };
   1.258  
   1.259 -inline Bytecode_field* Bytecode_field_at(methodHandle method, int bci) {
   1.260 -  Bytecode_field* b = new Bytecode_field(method, bci);
   1.261 -  DEBUG_ONLY(b->verify());
   1.262 -  return b;
   1.263 -}
   1.264 -
   1.265 -
   1.266  // Abstraction for checkcast
   1.267 -
   1.268  class Bytecode_checkcast: public Bytecode {
   1.269   public:
   1.270 +  Bytecode_checkcast(methodOop method, address bcp): Bytecode(method, bcp) { verify(); }
   1.271    void verify() const { assert(Bytecodes::java_code(code()) == Bytecodes::_checkcast, "check checkcast"); }
   1.272  
   1.273    // Returns index
   1.274    long index() const   { return get_index_u2(Bytecodes::_checkcast); };
   1.275 -
   1.276 -  // Creation
   1.277 -  inline friend Bytecode_checkcast* Bytecode_checkcast_at(address bcp);
   1.278  };
   1.279  
   1.280 -inline Bytecode_checkcast* Bytecode_checkcast_at(address bcp) {
   1.281 -  Bytecode_checkcast* b = (Bytecode_checkcast*)bcp;
   1.282 -  DEBUG_ONLY(b->verify());
   1.283 -  return b;
   1.284 -}
   1.285 -
   1.286 -
   1.287  // Abstraction for instanceof
   1.288 -
   1.289  class Bytecode_instanceof: public Bytecode {
   1.290   public:
   1.291 +  Bytecode_instanceof(methodOop method, address bcp): Bytecode(method, bcp) { verify(); }
   1.292    void verify() const { assert(code() == Bytecodes::_instanceof, "check instanceof"); }
   1.293  
   1.294    // Returns index
   1.295    long index() const   { return get_index_u2(Bytecodes::_instanceof); };
   1.296 -
   1.297 -  // Creation
   1.298 -  inline friend Bytecode_instanceof* Bytecode_instanceof_at(address bcp);
   1.299  };
   1.300  
   1.301 -inline Bytecode_instanceof* Bytecode_instanceof_at(address bcp) {
   1.302 -  Bytecode_instanceof* b = (Bytecode_instanceof*)bcp;
   1.303 -  DEBUG_ONLY(b->verify());
   1.304 -  return b;
   1.305 -}
   1.306 -
   1.307 -
   1.308  class Bytecode_new: public Bytecode {
   1.309   public:
   1.310 +  Bytecode_new(methodOop method, address bcp): Bytecode(method, bcp) { verify(); }
   1.311    void verify() const { assert(java_code() == Bytecodes::_new, "check new"); }
   1.312  
   1.313    // Returns index
   1.314    long index() const   { return get_index_u2(Bytecodes::_new); };
   1.315 -
   1.316 -  // Creation
   1.317 -  inline friend Bytecode_new* Bytecode_new_at(address bcp);
   1.318  };
   1.319  
   1.320 -inline Bytecode_new* Bytecode_new_at(address bcp) {
   1.321 -  Bytecode_new* b = (Bytecode_new*)bcp;
   1.322 -  DEBUG_ONLY(b->verify());
   1.323 -  return b;
   1.324 -}
   1.325 -
   1.326 -
   1.327  class Bytecode_multianewarray: public Bytecode {
   1.328   public:
   1.329 +  Bytecode_multianewarray(methodOop method, address bcp): Bytecode(method, bcp) { verify(); }
   1.330    void verify() const { assert(java_code() == Bytecodes::_multianewarray, "check new"); }
   1.331  
   1.332    // Returns index
   1.333    long index() const   { return get_index_u2(Bytecodes::_multianewarray); };
   1.334 -
   1.335 -  // Creation
   1.336 -  inline friend Bytecode_multianewarray* Bytecode_multianewarray_at(address bcp);
   1.337  };
   1.338  
   1.339 -inline Bytecode_multianewarray* Bytecode_multianewarray_at(address bcp) {
   1.340 -  Bytecode_multianewarray* b = (Bytecode_multianewarray*)bcp;
   1.341 -  DEBUG_ONLY(b->verify());
   1.342 -  return b;
   1.343 -}
   1.344 -
   1.345 -
   1.346  class Bytecode_anewarray: public Bytecode {
   1.347   public:
   1.348 +  Bytecode_anewarray(methodOop method, address bcp): Bytecode(method, bcp) { verify(); }
   1.349    void verify() const { assert(java_code() == Bytecodes::_anewarray, "check anewarray"); }
   1.350  
   1.351    // Returns index
   1.352    long index() const   { return get_index_u2(Bytecodes::_anewarray); };
   1.353 -
   1.354 -  // Creation
   1.355 -  inline friend Bytecode_anewarray* Bytecode_anewarray_at(address bcp);
   1.356  };
   1.357  
   1.358 -inline Bytecode_anewarray* Bytecode_anewarray_at(address bcp) {
   1.359 -  Bytecode_anewarray* b = (Bytecode_anewarray*)bcp;
   1.360 -  DEBUG_ONLY(b->verify());
   1.361 -  return b;
   1.362 -}
   1.363 -
   1.364 -
   1.365  // Abstraction for ldc, ldc_w and ldc2_w
   1.366 -
   1.367 -class Bytecode_loadconstant: public ResourceObj {
   1.368 +class Bytecode_loadconstant: public Bytecode {
   1.369   private:
   1.370 -  int          _bci;
   1.371 -  methodHandle _method;
   1.372 -
   1.373 -  Bytecodes::Code code() const                   { return bytecode()->code(); }
   1.374 +  const methodHandle _method;
   1.375  
   1.376    int raw_index() const;
   1.377  
   1.378 -  Bytecode_loadconstant(methodHandle method, int bci) : _method(method), _bci(bci) {}
   1.379 -
   1.380   public:
   1.381 -  // Attributes
   1.382 -  methodHandle method() const                    { return _method; }
   1.383 -  int          bci() const                       { return _bci; }
   1.384 -  address      bcp() const                       { return _method->bcp_from(bci()); }
   1.385 -  Bytecode*    bytecode() const                  { return Bytecode_at(bcp()); }
   1.386 +  Bytecode_loadconstant(methodHandle method, int bci): Bytecode(method(), method->bcp_from(bci)), _method(method) { verify(); }
   1.387  
   1.388    void verify() const {
   1.389      assert(_method.not_null(), "must supply method");
   1.390 @@ -437,15 +334,6 @@
   1.391    BasicType result_type() const;        // returns the result type of the ldc
   1.392  
   1.393    oop resolve_constant(TRAPS) const;
   1.394 -
   1.395 -  // Creation
   1.396 -  inline friend Bytecode_loadconstant* Bytecode_loadconstant_at(methodHandle method, int bci);
   1.397  };
   1.398  
   1.399 -inline Bytecode_loadconstant* Bytecode_loadconstant_at(methodHandle method, int bci) {
   1.400 -  Bytecode_loadconstant* b = new Bytecode_loadconstant(method, bci);
   1.401 -  DEBUG_ONLY(b->verify());
   1.402 -  return b;
   1.403 -}
   1.404 -
   1.405  #endif // SHARE_VM_INTERPRETER_BYTECODE_HPP

mercurial