src/share/vm/oops/cpCacheOop.hpp

changeset 3969
1d7922586cf6
parent 2982
ddd894528dbc
     1.1 --- a/src/share/vm/oops/cpCacheOop.hpp	Mon Jul 23 13:04:59 2012 -0700
     1.2 +++ b/src/share/vm/oops/cpCacheOop.hpp	Tue Jul 24 10:51:00 2012 -0700
     1.3 @@ -38,13 +38,14 @@
     1.4  // bit number |31                0|
     1.5  // bit length |-8--|-8--|---16----|
     1.6  // --------------------------------
     1.7 -// _indices   [ b2 | b1 |  index  ]
     1.8 -// _f1        [  entry specific   ]
     1.9 -// _f2        [  entry specific   ]
    1.10 -// _flags     [t|f|vf|v|m|h|unused|field_index] (for field entries)
    1.11 -// bit length |4|1|1 |1|1|0|---7--|----16-----]
    1.12 -// _flags     [t|f|vf|v|m|h|unused|eidx|psze] (for method entries)
    1.13 -// bit length |4|1|1 |1|1|1|---7--|-8--|-8--]
    1.14 +// _indices   [ b2 | b1 |  index  ]  index = constant_pool_index (!= 0, normal entries only)
    1.15 +// _indices   [  index  |  00000  ]  index = main_entry_index (secondary entries only)
    1.16 +// _f1        [  entry specific   ]  method, klass, or oop (MethodType or CallSite)
    1.17 +// _f2        [  entry specific   ]  vtable index or vfinal method
    1.18 +// _flags     [tos|0|00|00|00|f|v|f2|unused|field_index] (for field entries)
    1.19 +// bit length [ 4 |1|1 |1 | 1|1|1| 1|---5--|----16-----]
    1.20 +// _flags     [tos|M|vf|fv|ea|f|0|f2|unused|00000|psize] (for method entries)
    1.21 +// bit length [ 4 |1|1 |1 | 1|1|1| 1|---5--|--8--|--8--]
    1.22  
    1.23  // --------------------------------
    1.24  //
    1.25 @@ -52,24 +53,23 @@
    1.26  // index  = original constant pool index
    1.27  // b1     = bytecode 1
    1.28  // b2     = bytecode 2
    1.29 -// psze   = parameters size (method entries only)
    1.30 -// eidx   = interpreter entry index (method entries only)
    1.31 +// psize  = parameters size (method entries only)
    1.32  // field_index = index into field information in holder instanceKlass
    1.33  //          The index max is 0xffff (max number of fields in constant pool)
    1.34  //          and is multiplied by (instanceKlass::next_offset) when accessing.
    1.35  // t      = TosState (see below)
    1.36  // f      = field is marked final (see below)
    1.37 -// vf     = virtual, final (method entries only : is_vfinal())
    1.38 +// f2     = virtual but final (method entries only: is_vfinal())
    1.39  // v      = field is volatile (see below)
    1.40  // m      = invokeinterface used for method in class Object (see below)
    1.41  // h      = RedefineClasses/Hotswap bit (see below)
    1.42  //
    1.43  // The flags after TosState have the following interpretation:
    1.44 -// bit 27: f flag  true if field is marked final
    1.45 -// bit 26: vf flag true if virtual final method
    1.46 -// bit 25: v flag true if field is volatile (only for fields)
    1.47 -// bit 24: m flag true if invokeinterface used for method in class Object
    1.48 -// bit 23: 0 for fields, 1 for methods
    1.49 +// bit 27: 0 for fields, 1 for methods
    1.50 +// f  flag true if field is marked final
    1.51 +// v  flag true if field is volatile (only for fields)
    1.52 +// f2 flag true if f2 contains an oop (e.g., virtual final method)
    1.53 +// fv flag true if invokeinterface used for method in class Object
    1.54  //
    1.55  // The flags 31, 30, 29, 28 together build a 4 bit number 0 to 8 with the
    1.56  // following mapping to the TosState states:
    1.57 @@ -86,25 +86,26 @@
    1.58  //
    1.59  // Entry specific: field entries:
    1.60  // _indices = get (b1 section) and put (b2 section) bytecodes, original constant pool index
    1.61 -// _f1      = field holder
    1.62 -// _f2      = field offset in words
    1.63 -// _flags   = field type information, original field index in field holder
    1.64 +// _f1      = field holder (as a java.lang.Class, not a klassOop)
    1.65 +// _f2      = field offset in bytes
    1.66 +// _flags   = field type information, original FieldInfo index in field holder
    1.67  //            (field_index section)
    1.68  //
    1.69  // Entry specific: method entries:
    1.70  // _indices = invoke code for f1 (b1 section), invoke code for f2 (b2 section),
    1.71  //            original constant pool index
    1.72 -// _f1      = method for all but virtual calls, unused by virtual calls
    1.73 -//            (note: for interface calls, which are essentially virtual,
    1.74 -//             contains klassOop for the corresponding interface.
    1.75 -//            for invokedynamic, f1 contains the CallSite object for the invocation
    1.76 -// _f2      = method/vtable index for virtual calls only, unused by all other
    1.77 -//            calls.  The vf flag indicates this is a method pointer not an
    1.78 -//            index.
    1.79 -// _flags   = field type info (f section),
    1.80 -//            virtual final entry (vf),
    1.81 -//            interpreter entry index (eidx section),
    1.82 -//            parameter size (psze section)
    1.83 +// _f1      = methodOop for non-virtual calls, unused by virtual calls.
    1.84 +//            for interface calls, which are essentially virtual but need a klass,
    1.85 +//            contains klassOop for the corresponding interface.
    1.86 +//            for invokedynamic, f1 contains a site-specific CallSite object (as an appendix)
    1.87 +//            for invokehandle, f1 contains a site-specific MethodType object (as an appendix)
    1.88 +//            (upcoming metadata changes will move the appendix to a separate array)
    1.89 +// _f2      = vtable/itable index (or final methodOop) for virtual calls only,
    1.90 +//            unused by non-virtual.  The is_vfinal flag indicates this is a
    1.91 +//            method pointer for a final method, not an index.
    1.92 +// _flags   = method type info (t section),
    1.93 +//            virtual final bit (vfinal),
    1.94 +//            parameter size (psize section)
    1.95  //
    1.96  // Note: invokevirtual & invokespecial bytecodes can share the same constant
    1.97  //       pool entry and thus the same constant pool cache entry. All invoke
    1.98 @@ -138,30 +139,61 @@
    1.99      assert(existing_f1 == NULL || existing_f1 == f1, "illegal field change");
   1.100      oop_store(&_f1, f1);
   1.101    }
   1.102 -  void set_f1_if_null_atomic(oop f1);
   1.103 -  void set_f2(intx f2)                           { assert(_f2 == 0    || _f2 == f2, "illegal field change"); _f2 = f2; }
   1.104 -  int as_flags(TosState state, bool is_final, bool is_vfinal, bool is_volatile,
   1.105 -               bool is_method_interface, bool is_method);
   1.106 +  void release_set_f1(oop f1);
   1.107 +  void set_f2(intx f2)                           { assert(_f2 == 0 || _f2 == f2,            "illegal field change"); _f2 = f2; }
   1.108 +  void set_f2_as_vfinal_method(methodOop f2)     { assert(_f2 == 0 || _f2 == (intptr_t) f2, "illegal field change"); assert(is_vfinal(), "flags must be set"); _f2 = (intptr_t) f2; }
   1.109 +  int make_flags(TosState state, int option_bits, int field_index_or_method_params);
   1.110    void set_flags(intx flags)                     { _flags = flags; }
   1.111 +  bool init_flags_atomic(intx flags);
   1.112 +  void set_field_flags(TosState field_type, int option_bits, int field_index) {
   1.113 +    assert((field_index & field_index_mask) == field_index, "field_index in range");
   1.114 +    set_flags(make_flags(field_type, option_bits | (1 << is_field_entry_shift), field_index));
   1.115 +  }
   1.116 +  void set_method_flags(TosState return_type, int option_bits, int method_params) {
   1.117 +    assert((method_params & parameter_size_mask) == method_params, "method_params in range");
   1.118 +    set_flags(make_flags(return_type, option_bits, method_params));
   1.119 +  }
   1.120 +  bool init_method_flags_atomic(TosState return_type, int option_bits, int method_params) {
   1.121 +    assert((method_params & parameter_size_mask) == method_params, "method_params in range");
   1.122 +    return init_flags_atomic(make_flags(return_type, option_bits, method_params));
   1.123 +  }
   1.124  
   1.125   public:
   1.126 -  // specific bit values in flag field
   1.127 -  // Note: the interpreter knows this layout!
   1.128 -  enum FlagBitValues {
   1.129 -    hotSwapBit    = 23,
   1.130 -    methodInterface = 24,
   1.131 -    volatileField = 25,
   1.132 -    vfinalMethod  = 26,
   1.133 -    finalField    = 27
   1.134 +  // specific bit definitions for the flags field:
   1.135 +  // (Note: the interpreter must use these definitions to access the CP cache.)
   1.136 +  enum {
   1.137 +    // high order bits are the TosState corresponding to field type or method return type
   1.138 +    tos_state_bits             = 4,
   1.139 +    tos_state_mask             = right_n_bits(tos_state_bits),
   1.140 +    tos_state_shift            = BitsPerInt - tos_state_bits,  // see verify_tos_state_shift below
   1.141 +    // misc. option bits; can be any bit position in [16..27]
   1.142 +    is_vfinal_shift            = 21,
   1.143 +    is_volatile_shift          = 22,
   1.144 +    is_final_shift             = 23,
   1.145 +    has_appendix_shift         = 24,
   1.146 +    is_forced_virtual_shift    = 25,
   1.147 +    is_field_entry_shift       = 26,
   1.148 +    // low order bits give field index (for FieldInfo) or method parameter size:
   1.149 +    field_index_bits           = 16,
   1.150 +    field_index_mask           = right_n_bits(field_index_bits),
   1.151 +    parameter_size_bits        = 8,  // subset of field_index_mask, range is 0..255
   1.152 +    parameter_size_mask        = right_n_bits(parameter_size_bits),
   1.153 +    option_bits_mask           = ~(((-1) << tos_state_shift) | (field_index_mask | parameter_size_mask))
   1.154    };
   1.155  
   1.156 -  enum { field_index_mask = 0xFFFF };
   1.157 +  // specific bit definitions for the indices field:
   1.158 +  enum {
   1.159 +    main_cp_index_bits         = 2*BitsPerByte,
   1.160 +    main_cp_index_mask         = right_n_bits(main_cp_index_bits),
   1.161 +    bytecode_1_shift           = main_cp_index_bits,
   1.162 +    bytecode_1_mask            = right_n_bits(BitsPerByte), // == (u1)0xFF
   1.163 +    bytecode_2_shift           = main_cp_index_bits + BitsPerByte,
   1.164 +    bytecode_2_mask            = right_n_bits(BitsPerByte), // == (u1)0xFF
   1.165 +    // the secondary cp index overlaps with bytecodes 1 and 2:
   1.166 +    secondary_cp_index_shift   = bytecode_1_shift,
   1.167 +    secondary_cp_index_bits    = BitsPerInt - main_cp_index_bits
   1.168 +  };
   1.169  
   1.170 -  // start of type bits in flags
   1.171 -  // Note: the interpreter knows this layout!
   1.172 -  enum FlagValues {
   1.173 -    tosBits      = 28
   1.174 -  };
   1.175  
   1.176    // Initialization
   1.177    void initialize_entry(int original_index);     // initialize primary entry
   1.178 @@ -189,30 +221,40 @@
   1.179      int index                                    // Method index into interface
   1.180    );
   1.181  
   1.182 -  void set_dynamic_call(
   1.183 -    Handle call_site,                            // Resolved java.lang.invoke.CallSite (f1)
   1.184 -    methodHandle signature_invoker               // determines signature information
   1.185 +  void set_method_handle(
   1.186 +    methodHandle method,                         // adapter for invokeExact, etc.
   1.187 +    Handle appendix                              // stored in f1; could be a java.lang.invoke.MethodType
   1.188    );
   1.189  
   1.190 -  methodOop get_method_if_resolved(Bytecodes::Code invoke_code, constantPoolHandle cpool);
   1.191 +  void set_dynamic_call(
   1.192 +    methodHandle method,                         // adapter for this call site
   1.193 +    Handle appendix                              // stored in f1; could be a java.lang.invoke.CallSite
   1.194 +  );
   1.195  
   1.196 -  // For JVM_CONSTANT_InvokeDynamic cache entries:
   1.197 -  void initialize_bootstrap_method_index_in_cache(int bsm_cache_index);
   1.198 -  int  bootstrap_method_index_in_cache();
   1.199 +  // Common code for invokedynamic and MH invocations.
   1.200  
   1.201 -  void set_parameter_size(int value) {
   1.202 -    assert(parameter_size() == 0 || parameter_size() == value,
   1.203 -           "size must not change");
   1.204 -    // Setting the parameter size by itself is only safe if the
   1.205 -    // current value of _flags is 0, otherwise another thread may have
   1.206 -    // updated it and we don't want to overwrite that value.  Don't
   1.207 -    // bother trying to update it once it's nonzero but always make
   1.208 -    // sure that the final parameter size agrees with what was passed.
   1.209 -    if (_flags == 0) {
   1.210 -      Atomic::cmpxchg_ptr((value & 0xFF), &_flags, 0);
   1.211 -    }
   1.212 -    guarantee(parameter_size() == value, "size must not change");
   1.213 -  }
   1.214 +  // The "appendix" is an optional call-site-specific parameter which is
   1.215 +  // pushed by the JVM at the end of the argument list.  This argument may
   1.216 +  // be a MethodType for the MH.invokes and a CallSite for an invokedynamic
   1.217 +  // instruction.  However, its exact type and use depends on the Java upcall,
   1.218 +  // which simply returns a compiled LambdaForm along with any reference
   1.219 +  // that LambdaForm needs to complete the call.  If the upcall returns a
   1.220 +  // null appendix, the argument is not passed at all.
   1.221 +  //
   1.222 +  // The appendix is *not* represented in the signature of the symbolic
   1.223 +  // reference for the call site, but (if present) it *is* represented in
   1.224 +  // the methodOop bound to the site.  This means that static and dynamic
   1.225 +  // resolution logic needs to make slightly different assessments about the
   1.226 +  // number and types of arguments.
   1.227 +  void set_method_handle_common(
   1.228 +    Bytecodes::Code invoke_code,                 // _invokehandle or _invokedynamic
   1.229 +    methodHandle adapter,                        // invoker method (f2)
   1.230 +    Handle appendix                              // appendix such as CallSite, MethodType, etc. (f1)
   1.231 +  );
   1.232 +
   1.233 +  methodOop method_if_resolved(constantPoolHandle cpool);
   1.234 +
   1.235 +  void set_parameter_size(int value);
   1.236  
   1.237    // Which bytecode number (1 or 2) in the index field is valid for this bytecode?
   1.238    // Returns -1 if neither is valid.
   1.239 @@ -222,10 +264,11 @@
   1.240        case Bytecodes::_getfield        :    // fall through
   1.241        case Bytecodes::_invokespecial   :    // fall through
   1.242        case Bytecodes::_invokestatic    :    // fall through
   1.243 -      case Bytecodes::_invokedynamic   :    // fall through
   1.244        case Bytecodes::_invokeinterface : return 1;
   1.245        case Bytecodes::_putstatic       :    // fall through
   1.246        case Bytecodes::_putfield        :    // fall through
   1.247 +      case Bytecodes::_invokehandle    :    // fall through
   1.248 +      case Bytecodes::_invokedynamic   :    // fall through
   1.249        case Bytecodes::_invokevirtual   : return 2;
   1.250        default                          : break;
   1.251      }
   1.252 @@ -242,31 +285,43 @@
   1.253    }
   1.254  
   1.255    // Accessors
   1.256 -  bool is_secondary_entry() const                { return (_indices & 0xFFFF) == 0; }
   1.257 -  int constant_pool_index() const                { assert((_indices & 0xFFFF) != 0, "must be main entry");
   1.258 -                                                   return (_indices & 0xFFFF); }
   1.259 -  int main_entry_index() const                   { assert((_indices & 0xFFFF) == 0, "must be secondary entry");
   1.260 -                                                   return ((uintx)_indices >> 16); }
   1.261 -  Bytecodes::Code bytecode_1() const             { return Bytecodes::cast((_indices >> 16) & 0xFF); }
   1.262 -  Bytecodes::Code bytecode_2() const             { return Bytecodes::cast((_indices >> 24) & 0xFF); }
   1.263 -  volatile oop  f1() const                       { return _f1; }
   1.264 -  bool is_f1_null() const                        { return (oop)_f1 == NULL; }  // classifies a CPC entry as unbound
   1.265 -  intx f2() const                                { return _f2; }
   1.266 -  int  field_index() const;
   1.267 -  int  parameter_size() const                    { return _flags & 0xFF; }
   1.268 -  bool is_vfinal() const                         { return ((_flags & (1 << vfinalMethod)) == (1 << vfinalMethod)); }
   1.269 -  bool is_volatile() const                       { return ((_flags & (1 << volatileField)) == (1 << volatileField)); }
   1.270 -  bool is_methodInterface() const                { return ((_flags & (1 << methodInterface)) == (1 << methodInterface)); }
   1.271 -  bool is_byte() const                           { return (((uintx) _flags >> tosBits) == btos); }
   1.272 -  bool is_char() const                           { return (((uintx) _flags >> tosBits) == ctos); }
   1.273 -  bool is_short() const                          { return (((uintx) _flags >> tosBits) == stos); }
   1.274 -  bool is_int() const                            { return (((uintx) _flags >> tosBits) == itos); }
   1.275 -  bool is_long() const                           { return (((uintx) _flags >> tosBits) == ltos); }
   1.276 -  bool is_float() const                          { return (((uintx) _flags >> tosBits) == ftos); }
   1.277 -  bool is_double() const                         { return (((uintx) _flags >> tosBits) == dtos); }
   1.278 -  bool is_object() const                         { return (((uintx) _flags >> tosBits) == atos); }
   1.279 -  TosState flag_state() const                    { assert( ( (_flags >> tosBits) & 0x0F ) < number_of_states, "Invalid state in as_flags");
   1.280 -                                                   return (TosState)((_flags >> tosBits) & 0x0F); }
   1.281 +  bool is_secondary_entry() const                { return (_indices & main_cp_index_mask) == 0; }
   1.282 +  int main_entry_index() const                   { assert(is_secondary_entry(), "must be secondary entry");
   1.283 +                                                   return ((uintx)_indices >> secondary_cp_index_shift); }
   1.284 +  int primary_entry_indices() const              { assert(!is_secondary_entry(), "must be main entry");
   1.285 +                                                   return _indices; }
   1.286 +  int constant_pool_index() const                { return (primary_entry_indices() & main_cp_index_mask); }
   1.287 +  Bytecodes::Code bytecode_1() const             { return Bytecodes::cast((primary_entry_indices() >> bytecode_1_shift)
   1.288 +                                                                          & bytecode_1_mask); }
   1.289 +  Bytecodes::Code bytecode_2() const             { return Bytecodes::cast((primary_entry_indices() >> bytecode_2_shift)
   1.290 +                                                                          & bytecode_2_mask); }
   1.291 +  methodOop f1_as_method() const                 { oop f1 = _f1; assert(f1 == NULL || f1->is_method(), ""); return methodOop(f1); }
   1.292 +  klassOop  f1_as_klass() const                  { oop f1 = _f1; assert(f1 == NULL || f1->is_klass(), ""); return klassOop(f1); }
   1.293 +  oop       f1_as_klass_mirror() const           { oop f1 = f1_as_instance(); return f1; }  // i.e., return a java_mirror
   1.294 +  oop       f1_as_instance() const               { oop f1 = _f1; assert(f1 == NULL || f1->is_instance() || f1->is_array(), ""); return f1; }
   1.295 +  oop       f1_appendix() const                  { assert(has_appendix(), ""); return f1_as_instance(); }
   1.296 +  bool      is_f1_null() const                   { oop f1 = _f1; return f1 == NULL; }  // classifies a CPC entry as unbound
   1.297 +  int       f2_as_index() const                  { assert(!is_vfinal(), ""); return (int) _f2; }
   1.298 +  methodOop f2_as_vfinal_method() const          { assert(is_vfinal(), ""); return methodOop(_f2); }
   1.299 +  int  field_index() const                       { assert(is_field_entry(),  ""); return (_flags & field_index_mask); }
   1.300 +  int  parameter_size() const                    { assert(is_method_entry(), ""); return (_flags & parameter_size_mask); }
   1.301 +  bool is_volatile() const                       { return (_flags & (1 << is_volatile_shift))       != 0; }
   1.302 +  bool is_final() const                          { return (_flags & (1 << is_final_shift))          != 0; }
   1.303 +  bool has_appendix() const                      { return (_flags & (1 << has_appendix_shift))     != 0; }
   1.304 +  bool is_forced_virtual() const                 { return (_flags & (1 << is_forced_virtual_shift)) != 0; }
   1.305 +  bool is_vfinal() const                         { return (_flags & (1 << is_vfinal_shift))         != 0; }
   1.306 +  bool is_method_entry() const                   { return (_flags & (1 << is_field_entry_shift))    == 0; }
   1.307 +  bool is_field_entry() const                    { return (_flags & (1 << is_field_entry_shift))    != 0; }
   1.308 +  bool is_byte() const                           { return flag_state() == btos; }
   1.309 +  bool is_char() const                           { return flag_state() == ctos; }
   1.310 +  bool is_short() const                          { return flag_state() == stos; }
   1.311 +  bool is_int() const                            { return flag_state() == itos; }
   1.312 +  bool is_long() const                           { return flag_state() == ltos; }
   1.313 +  bool is_float() const                          { return flag_state() == ftos; }
   1.314 +  bool is_double() const                         { return flag_state() == dtos; }
   1.315 +  bool is_object() const                         { return flag_state() == atos; }
   1.316 +  TosState flag_state() const                    { assert((uint)number_of_states <= (uint)tos_state_mask+1, "");
   1.317 +                                                   return (TosState)((_flags >> tos_state_shift) & tos_state_mask); }
   1.318  
   1.319    // Code generation support
   1.320    static WordSize size()                         { return in_WordSize(sizeof(ConstantPoolCacheEntry) / HeapWordSize); }
   1.321 @@ -299,15 +354,14 @@
   1.322    bool adjust_method_entry(methodOop old_method, methodOop new_method,
   1.323           bool * trace_name_printed);
   1.324    bool is_interesting_method_entry(klassOop k);
   1.325 -  bool is_field_entry() const                    { return (_flags & (1 << hotSwapBit)) == 0; }
   1.326 -  bool is_method_entry() const                   { return (_flags & (1 << hotSwapBit)) != 0; }
   1.327  
   1.328    // Debugging & Printing
   1.329    void print (outputStream* st, int index) const;
   1.330    void verify(outputStream* st) const;
   1.331  
   1.332 -  static void verify_tosBits() {
   1.333 -    assert(tosBits == 28, "interpreter now assumes tosBits is 28");
   1.334 +  static void verify_tos_state_shift() {
   1.335 +    // When shifting flags as a 32-bit int, make sure we don't need an extra mask for tos_state:
   1.336 +    assert((((u4)-1 >> tos_state_shift) & ~tos_state_mask) == 0, "no need for tos_state mask");
   1.337    }
   1.338  };
   1.339  

mercurial