< prev index next >

src/hotspot/share/oops/resolvedFieldEntry.hpp

Print this page

 38 // together and are used to populate this structure. These entries are contained
 39 // within the ConstantPoolCache and are accessed with indices added to the bytecode after
 40 // rewriting.
 41 
 42 // Field bytecodes start with a constant pool index as their operand, which is then rewritten to
 43 // a "field index", which is an index into the array of ResolvedFieldEntry.
 44 
 45 // The explicit paddings are necessary for generating deterministic CDS archives. They prevent
 46 // the C++ compiler from potentially inserting random values in unused gaps.
 47 
 48 class InstanceKlass;
 49 
 50 class ResolvedFieldEntry {
 51   friend class VMStructs;
 52 
 53   InstanceKlass* _field_holder; // Field holder klass
 54   int _field_offset;            // Field offset in bytes
 55   u2 _field_index;              // Index into field information in holder InstanceKlass
 56   u2 _cpool_index;              // Constant pool index
 57   u1 _tos_state;                // TOS state
 58   u1 _flags;                    // Flags: [0000|00|is_final|is_volatile]
 59   u1 _get_code, _put_code;      // Get and Put bytecodes of the field
 60 #ifdef _LP64
 61   u4 _padding;
 62 #endif
 63 
 64 public:
 65   ResolvedFieldEntry(u2 cpi) :
 66     _field_holder(nullptr),
 67     _field_offset(0),
 68     _field_index(0),
 69     _cpool_index(cpi),
 70     _tos_state(0),
 71     _flags(0),
 72     _get_code(0),
 73     _put_code(0)
 74 #ifdef _LP64
 75     , _padding(0)
 76 #endif
 77     {}
 78 
 79   ResolvedFieldEntry() :
 80     ResolvedFieldEntry(0) {}
 81 
 82   // Bit shift to get flags
 83   // Note: Only two flags exists at the moment but more could be added
 84   enum {
 85       is_volatile_shift     = 0,
 86       is_final_shift        = 1, // unused
 87       max_flag_shift        = is_final_shift



 88   };
 89 
 90   // Getters
 91   InstanceKlass* field_holder() const { return _field_holder; }
 92   int field_offset()            const { return _field_offset; }
 93   u2 field_index()              const { return _field_index;  }
 94   u2 constant_pool_index()      const { return _cpool_index;  }
 95   u1 tos_state()                const { return _tos_state;    }
 96   u1 get_code()                 const { return AtomicAccess::load_acquire(&_get_code);      }
 97   u1 put_code()                 const { return AtomicAccess::load_acquire(&_put_code);      }
 98   bool is_final()               const { return (_flags & (1 << is_final_shift))    != 0; }
 99   bool is_volatile ()           const { return (_flags & (1 << is_volatile_shift)) != 0; }



100   bool is_resolved(Bytecodes::Code code) const {
101     switch(code) {
102     case Bytecodes::_getstatic:
103     case Bytecodes::_getfield:
104       return (get_code() == code);
105     case Bytecodes::_putstatic:
106     case Bytecodes::_putfield:
107       return (put_code() == code);
108     default:
109       ShouldNotReachHere();
110       return false;
111     }
112   }
113 
114   // Printing
115   void print_on(outputStream* st) const;
116 
117  private:
118   void set_flags(bool is_final_flag, bool is_volatile_flag) {
119     int new_flags = (is_final_flag << is_final_shift) | static_cast<int>(is_volatile_flag);









120     _flags = checked_cast<u1>(new_flags);
121     assert(is_final() == is_final_flag, "Must be");
122     assert(is_volatile() == is_volatile_flag, "Must be");




123   }
124 
125   inline void set_bytecode(u1* code, u1 new_code) {
126   #ifdef ASSERT
127     // Read once.
128     volatile Bytecodes::Code c = (Bytecodes::Code)*code;
129     assert(c == 0 || c == new_code || new_code == 0, "update must be consistent");
130   #endif
131     AtomicAccess::release_store(code, new_code);
132   }
133 
134    // Debug help
135   void assert_is_valid() const NOT_DEBUG_RETURN;
136 
137  public:
138   // Populate the strucutre with resolution information
139   void fill_in(const fieldDescriptor& info, u1 tos_state, u1 get_code, u1 put_code);
140 
141   // CDS
142 #if INCLUDE_CDS

 38 // together and are used to populate this structure. These entries are contained
 39 // within the ConstantPoolCache and are accessed with indices added to the bytecode after
 40 // rewriting.
 41 
 42 // Field bytecodes start with a constant pool index as their operand, which is then rewritten to
 43 // a "field index", which is an index into the array of ResolvedFieldEntry.
 44 
 45 // The explicit paddings are necessary for generating deterministic CDS archives. They prevent
 46 // the C++ compiler from potentially inserting random values in unused gaps.
 47 
 48 class InstanceKlass;
 49 
 50 class ResolvedFieldEntry {
 51   friend class VMStructs;
 52 
 53   InstanceKlass* _field_holder; // Field holder klass
 54   int _field_offset;            // Field offset in bytes
 55   u2 _field_index;              // Index into field information in holder InstanceKlass
 56   u2 _cpool_index;              // Constant pool index
 57   u1 _tos_state;                // TOS state
 58   u1 _flags;                    // Flags: [000|has_null_marker|is_null_free_inline_type|is_flat|is_final|is_volatile]
 59   u1 _get_code, _put_code;      // Get and Put bytecodes of the field
 60 #ifdef _LP64
 61   u4 _padding;
 62 #endif
 63 
 64 public:
 65   ResolvedFieldEntry(u2 cpi) :
 66     _field_holder(nullptr),
 67     _field_offset(0),
 68     _field_index(0),
 69     _cpool_index(cpi),
 70     _tos_state(0),
 71     _flags(0),
 72     _get_code(0),
 73     _put_code(0)
 74 #ifdef _LP64
 75     , _padding(0)
 76 #endif
 77     {}
 78 
 79   ResolvedFieldEntry() :
 80     ResolvedFieldEntry(0) {}
 81 
 82   // Bit shift to get flags

 83   enum {
 84       is_volatile_shift     = 0,
 85       is_final_shift        = 1, // unused
 86       is_flat_shift         = 2,
 87       is_null_free_inline_type_shift = 3,
 88       has_null_marker_shift = 4,
 89       max_flag_shift = has_null_marker_shift
 90   };
 91 
 92   // Getters
 93   InstanceKlass* field_holder()   const { return _field_holder; }
 94   int field_offset()              const { return _field_offset; }
 95   u2 field_index()                const { return _field_index;  }
 96   u2 constant_pool_index()        const { return _cpool_index;  }
 97   u1 tos_state()                  const { return _tos_state;    }
 98   u1 get_code()                   const { return AtomicAccess::load_acquire(&_get_code);   }
 99   u1 put_code()                   const { return AtomicAccess::load_acquire(&_put_code);   }
100   bool is_volatile ()             const { return (_flags & (1 << is_volatile_shift)) != 0; }
101   bool is_final()                 const { return (_flags & (1 << is_final_shift))    != 0; }
102   bool is_flat()                  const { return (_flags & (1 << is_flat_shift))     != 0; }
103   bool is_null_free_inline_type() const { return (_flags & (1 << is_null_free_inline_type_shift)) != 0; }
104   bool has_null_marker()          const { return (_flags & (1 << has_null_marker_shift)) != 0; }
105   bool is_resolved(Bytecodes::Code code) const {
106     switch(code) {
107     case Bytecodes::_getstatic:
108     case Bytecodes::_getfield:
109       return (get_code() == code);
110     case Bytecodes::_putstatic:
111     case Bytecodes::_putfield:
112       return (put_code() == code);
113     default:
114       ShouldNotReachHere();
115       return false;
116     }
117   }
118 
119   // Printing
120   void print_on(outputStream* st) const;
121 
122  private:
123   void set_flags(bool is_volatile_flag,
124                  bool is_final_flag,
125                  bool is_flat_flag,
126                  bool is_null_free_inline_type_flag,
127                  bool has_null_marker_flag) {
128     int new_flags =
129         ((is_volatile_flag ? 1 : 0) << is_volatile_shift) |
130         ((is_final_flag ? 1 : 0) << is_final_shift) |
131         ((is_flat_flag ? 1 : 0) << is_flat_shift) |
132         ((is_null_free_inline_type_flag ? 1 : 0) << is_null_free_inline_type_shift) |
133         ((has_null_marker_flag  ? 1 : 0) << has_null_marker_shift);
134     _flags = checked_cast<u1>(new_flags);

135     assert(is_volatile() == is_volatile_flag, "Must be");
136     assert(is_final() == is_final_flag, "Must be");
137     assert(is_flat() == is_flat_flag, "Must be");
138     assert(is_null_free_inline_type() == is_null_free_inline_type_flag, "Must be");
139     assert(has_null_marker() == has_null_marker_flag, "Must be");
140   }
141 
142   inline void set_bytecode(u1* code, u1 new_code) {
143   #ifdef ASSERT
144     // Read once.
145     volatile Bytecodes::Code c = (Bytecodes::Code)*code;
146     assert(c == 0 || c == new_code || new_code == 0, "update must be consistent");
147   #endif
148     AtomicAccess::release_store(code, new_code);
149   }
150 
151    // Debug help
152   void assert_is_valid() const NOT_DEBUG_RETURN;
153 
154  public:
155   // Populate the strucutre with resolution information
156   void fill_in(const fieldDescriptor& info, u1 tos_state, u1 get_code, u1 put_code);
157 
158   // CDS
159 #if INCLUDE_CDS
< prev index next >