src/hotspot/share/oops/cpCache.hpp
changeset 47684 c3c04b6e14f8
parent 47634 6a0c42c40cd1
child 48557 2e867226b914
equal deleted inserted replaced
47682:e4a89dfa1247 47684:c3c04b6e14f8
    29 #include "memory/allocation.hpp"
    29 #include "memory/allocation.hpp"
    30 #include "oops/array.hpp"
    30 #include "oops/array.hpp"
    31 #include "oops/oopHandle.hpp"
    31 #include "oops/oopHandle.hpp"
    32 #include "runtime/orderAccess.hpp"
    32 #include "runtime/orderAccess.hpp"
    33 #include "utilities/align.hpp"
    33 #include "utilities/align.hpp"
       
    34 #include "utilities/constantTag.hpp"
    34 
    35 
    35 class PSPromotionManager;
    36 class PSPromotionManager;
    36 
    37 
    37 // The ConstantPoolCache is not a cache! It is the resolution table that the
    38 // The ConstantPoolCache is not a cache! It is the resolution table that the
    38 // interpreter uses to avoid going into the runtime and a way to access resolved
    39 // interpreter uses to avoid going into the runtime and a way to access resolved
    48 // --------------------------------
    49 // --------------------------------
    49 // _indices   [ b2 | b1 |  index  ]  index = constant_pool_index
    50 // _indices   [ b2 | b1 |  index  ]  index = constant_pool_index
    50 // _f1        [  entry specific   ]  metadata ptr (method or klass)
    51 // _f1        [  entry specific   ]  metadata ptr (method or klass)
    51 // _f2        [  entry specific   ]  vtable or res_ref index, or vfinal method ptr
    52 // _f2        [  entry specific   ]  vtable or res_ref index, or vfinal method ptr
    52 // _flags     [tos|0|F=1|0|0|0|f|v|0 |0000|field_index] (for field entries)
    53 // _flags     [tos|0|F=1|0|0|0|f|v|0 |0000|field_index] (for field entries)
    53 // bit length [ 4 |1| 1 |1|1|1|1|1|1 |-4--|----16-----]
    54 // bit length [ 4 |1| 1 |1|1|1|1|1|1 |1     |-3-|----16-----]
    54 // _flags     [tos|0|F=0|M|A|I|f|0|vf|0000|00000|psize] (for method entries)
    55 // _flags     [tos|0|F=0|M|A|I|f|0|vf|indy_rf|000|00000|psize] (for method entries)
    55 // bit length [ 4 |1| 1 |1|1|1|1|1|1 |-4--|--8--|--8--]
    56 // bit length [ 4 |1| 1 |1|1|1|1|1|1 |-4--|--8--|--8--]
    56 
    57 
    57 // --------------------------------
    58 // --------------------------------
    58 //
    59 //
    59 // with:
    60 // with:
    69 // A      = call site has an appendix argument (loaded from resolved references)
    70 // A      = call site has an appendix argument (loaded from resolved references)
    70 // I      = interface call is forced virtual (must use a vtable index or vfinal)
    71 // I      = interface call is forced virtual (must use a vtable index or vfinal)
    71 // f      = field or method is final
    72 // f      = field or method is final
    72 // v      = field is volatile
    73 // v      = field is volatile
    73 // vf     = virtual but final (method entries only: is_vfinal())
    74 // vf     = virtual but final (method entries only: is_vfinal())
       
    75 // indy_rf = call site specifier method resolution failed
    74 //
    76 //
    75 // The flags after TosState have the following interpretation:
    77 // The flags after TosState have the following interpretation:
    76 // bit 27: 0 for fields, 1 for methods
    78 // bit 27: 0 for fields, 1 for methods
    77 // f  flag true if field is marked final
    79 // f  flag true if field is marked final
    78 // v  flag true if field is volatile (only for fields)
    80 // v  flag true if field is volatile (only for fields)
   183     has_appendix_shift         = 24,  // (A) does the call site have an appendix argument?
   185     has_appendix_shift         = 24,  // (A) does the call site have an appendix argument?
   184     is_forced_virtual_shift    = 23,  // (I) is the interface reference forced to virtual mode?
   186     is_forced_virtual_shift    = 23,  // (I) is the interface reference forced to virtual mode?
   185     is_final_shift             = 22,  // (f) is the field or method final?
   187     is_final_shift             = 22,  // (f) is the field or method final?
   186     is_volatile_shift          = 21,  // (v) is the field volatile?
   188     is_volatile_shift          = 21,  // (v) is the field volatile?
   187     is_vfinal_shift            = 20,  // (vf) did the call resolve to a final method?
   189     is_vfinal_shift            = 20,  // (vf) did the call resolve to a final method?
       
   190     indy_resolution_failed_shift= 19, // (indy_rf) did call site specifier resolution fail ?
   188     // low order bits give field index (for FieldInfo) or method parameter size:
   191     // low order bits give field index (for FieldInfo) or method parameter size:
   189     field_index_bits           = 16,
   192     field_index_bits           = 16,
   190     field_index_mask           = right_n_bits(field_index_bits),
   193     field_index_mask           = right_n_bits(field_index_bits),
   191     parameter_size_bits        = 8,  // subset of field_index_mask, range is 0..255
   194     parameter_size_bits        = 8,  // subset of field_index_mask, range is 0..255
   192     parameter_size_mask        = right_n_bits(parameter_size_bits),
   195     parameter_size_mask        = right_n_bits(parameter_size_bits),
   279     const constantPoolHandle& cpool,                    // holding constant pool (required for locking)
   282     const constantPoolHandle& cpool,                    // holding constant pool (required for locking)
   280     Bytecodes::Code invoke_code,                 // _invokehandle or _invokedynamic
   283     Bytecodes::Code invoke_code,                 // _invokehandle or _invokedynamic
   281     const CallInfo &call_info                    // Call link information
   284     const CallInfo &call_info                    // Call link information
   282   );
   285   );
   283 
   286 
       
   287   // Return TRUE if resolution failed and this thread got to record the failure
       
   288   // status.  Return FALSE if another thread succeeded or failed in resolving
       
   289   // the method and recorded the success or failure before this thread had a
       
   290   // chance to record its failure.
       
   291   bool save_and_throw_indy_exc(const constantPoolHandle& cpool, int cpool_index,
       
   292                                int index, constantTag tag, TRAPS);
       
   293 
   284   // invokedynamic and invokehandle call sites have two entries in the
   294   // invokedynamic and invokehandle call sites have two entries in the
   285   // resolved references array:
   295   // resolved references array:
   286   //   appendix   (at index+0)
   296   //   appendix   (at index+0)
   287   //   MethodType (at index+1)
   297   //   MethodType (at index+1)
   288   enum {
   298   enum {
   340   // of _f1 must be ordered with the loads performed by
   350   // of _f1 must be ordered with the loads performed by
   341   // cache->main_entry_index().
   351   // cache->main_entry_index().
   342   bool      is_f1_null() const                   { Metadata* f1 = f1_ord(); return f1 == NULL; }  // classifies a CPC entry as unbound
   352   bool      is_f1_null() const                   { Metadata* f1 = f1_ord(); return f1 == NULL; }  // classifies a CPC entry as unbound
   343   int       f2_as_index() const                  { assert(!is_vfinal(), ""); return (int) _f2; }
   353   int       f2_as_index() const                  { assert(!is_vfinal(), ""); return (int) _f2; }
   344   Method*   f2_as_vfinal_method() const          { assert(is_vfinal(), ""); return (Method*)_f2; }
   354   Method*   f2_as_vfinal_method() const          { assert(is_vfinal(), ""); return (Method*)_f2; }
       
   355   intx flags_ord() const                         { return (intx)OrderAccess::load_acquire(&_flags); }
   345   int  field_index() const                       { assert(is_field_entry(),  ""); return (_flags & field_index_mask); }
   356   int  field_index() const                       { assert(is_field_entry(),  ""); return (_flags & field_index_mask); }
   346   int  parameter_size() const                    { assert(is_method_entry(), ""); return (_flags & parameter_size_mask); }
   357   int  parameter_size() const                    { assert(is_method_entry(), ""); return (_flags & parameter_size_mask); }
   347   bool is_volatile() const                       { return (_flags & (1 << is_volatile_shift))       != 0; }
   358   bool is_volatile() const                       { return (_flags & (1 << is_volatile_shift))       != 0; }
   348   bool is_final() const                          { return (_flags & (1 << is_final_shift))          != 0; }
   359   bool is_final() const                          { return (_flags & (1 << is_final_shift))          != 0; }
   349   bool is_forced_virtual() const                 { return (_flags & (1 << is_forced_virtual_shift)) != 0; }
   360   bool is_forced_virtual() const                 { return (_flags & (1 << is_forced_virtual_shift)) != 0; }
   350   bool is_vfinal() const                         { return (_flags & (1 << is_vfinal_shift))         != 0; }
   361   bool is_vfinal() const                         { return (_flags & (1 << is_vfinal_shift))         != 0; }
       
   362   bool indy_resolution_failed() const            { intx flags = flags_ord(); return (flags & (1 << indy_resolution_failed_shift)) != 0; }
   351   bool has_appendix() const                      { return (!is_f1_null()) && (_flags & (1 << has_appendix_shift))      != 0; }
   363   bool has_appendix() const                      { return (!is_f1_null()) && (_flags & (1 << has_appendix_shift))      != 0; }
   352   bool has_method_type() const                   { return (!is_f1_null()) && (_flags & (1 << has_method_type_shift))   != 0; }
   364   bool has_method_type() const                   { return (!is_f1_null()) && (_flags & (1 << has_method_type_shift))   != 0; }
   353   bool is_method_entry() const                   { return (_flags & (1 << is_field_entry_shift))    == 0; }
   365   bool is_method_entry() const                   { return (_flags & (1 << is_field_entry_shift))    == 0; }
   354   bool is_field_entry() const                    { return (_flags & (1 << is_field_entry_shift))    != 0; }
   366   bool is_field_entry() const                    { return (_flags & (1 << is_field_entry_shift))    != 0; }
   355   bool is_long() const                           { return flag_state() == ltos; }
   367   bool is_long() const                           { return flag_state() == ltos; }
   356   bool is_double() const                         { return flag_state() == dtos; }
   368   bool is_double() const                         { return flag_state() == dtos; }
   357   TosState flag_state() const                    { assert((uint)number_of_states <= (uint)tos_state_mask+1, "");
   369   TosState flag_state() const                    { assert((uint)number_of_states <= (uint)tos_state_mask+1, "");
   358                                                    return (TosState)((_flags >> tos_state_shift) & tos_state_mask); }
   370                                                    return (TosState)((_flags >> tos_state_shift) & tos_state_mask); }
       
   371   void set_indy_resolution_failed();
   359 
   372 
   360   // Code generation support
   373   // Code generation support
   361   static WordSize size()                         {
   374   static WordSize size()                         {
   362     return in_WordSize(align_up((int)sizeof(ConstantPoolCacheEntry), wordSize) / wordSize);
   375     return in_WordSize(align_up((int)sizeof(ConstantPoolCacheEntry), wordSize) / wordSize);
   363   }
   376   }