< prev index next >

src/hotspot/share/oops/resolvedFieldEntry.hpp

Print this page

 35 // like getfield, putfield, getstatic, and putstatic. A member of this class can be initialized
 36 // with the constant pool index associated with the bytecode before any resolution is done, where
 37 // "resolution" refers to populating the getcode and putcode fields and other relevant information.
 38 // The field's type (TOS), offset, holder klass, and index within that class can all be acquired
 39 // together and are used to populate this structure. These entries are contained
 40 // within the ConstantPoolCache and are accessed with indices added to the bytecode after
 41 // rewriting.
 42 
 43 // Field bytecodes start with a constant pool index as their operand, which is then rewritten to
 44 // a "field index", which is an index into the array of ResolvedFieldEntry.
 45 
 46 //class InstanceKlass;
 47 class ResolvedFieldEntry {
 48   friend class VMStructs;
 49 
 50   InstanceKlass* _field_holder; // Field holder klass
 51   int _field_offset;            // Field offset in bytes
 52   u2 _field_index;              // Index into field information in holder InstanceKlass
 53   u2 _cpool_index;              // Constant pool index
 54   u1 _tos_state;                // TOS state
 55   u1 _flags;                    // Flags: [0000|00|is_final|is_volatile]
 56   u1 _get_code, _put_code;      // Get and Put bytecodes of the field
 57 
 58   void copy_from(const ResolvedFieldEntry& other) {
 59     _field_holder = other._field_holder;
 60     _field_offset = other._field_offset;
 61     _field_index = other._field_index;
 62     _cpool_index = other._cpool_index;
 63     _tos_state = other._tos_state;
 64     _flags = other._flags;
 65     _get_code = other._get_code;
 66     _put_code = other._put_code;
 67   }
 68 
 69 public:
 70   ResolvedFieldEntry(u2 cpi) :
 71     _field_holder(nullptr),
 72     _field_offset(0),
 73     _field_index(0),
 74     _cpool_index(cpi),
 75     _tos_state(0),

 77     _get_code(0),
 78     _put_code(0) {}
 79 
 80   ResolvedFieldEntry() :
 81     ResolvedFieldEntry(0) {}
 82 
 83   ResolvedFieldEntry(const ResolvedFieldEntry& other) {
 84     copy_from(other);
 85   }
 86 
 87   ResolvedFieldEntry& operator=(const ResolvedFieldEntry& other) {
 88     copy_from(other);
 89     return *this;
 90   }
 91 
 92   // Bit shift to get flags
 93   // Note: Only two flags exists at the moment but more could be added
 94   enum {
 95       is_volatile_shift     = 0,
 96       is_final_shift        = 1, // unused




 97   };
 98 
 99   // Getters
100   InstanceKlass* field_holder() const { return _field_holder; }
101   int field_offset()            const { return _field_offset; }
102   u2 field_index()              const { return _field_index;  }
103   u2 constant_pool_index()      const { return _cpool_index;  }
104   u1 tos_state()                const { return _tos_state;    }
105   u1 get_code()                 const { return Atomic::load_acquire(&_get_code);      }
106   u1 put_code()                 const { return Atomic::load_acquire(&_put_code);      }
107   bool is_final()               const { return (_flags & (1 << is_final_shift))    != 0; }
108   bool is_volatile ()           const { return (_flags & (1 << is_volatile_shift)) != 0; }



109   bool is_resolved(Bytecodes::Code code) const {
110     switch(code) {
111     case Bytecodes::_getstatic:
112     case Bytecodes::_getfield:
113       return (get_code() == code);
114     case Bytecodes::_putstatic:
115     case Bytecodes::_putfield:
116       return (put_code() == code);
117     default:
118       ShouldNotReachHere();
119       return false;
120     }
121   }
122 
123   // Printing
124   void print_on(outputStream* st) const;
125 
126   void set_flags(bool is_final_flag, bool is_volatile_flag) {
127     int new_flags = (is_final_flag << is_final_shift) | static_cast<int>(is_volatile_flag);




128     _flags = checked_cast<u1>(new_flags);
129     assert(is_final() == is_final_flag, "Must be");
130     assert(is_volatile() == is_volatile_flag, "Must be");



131   }
132 
133   inline void set_bytecode(u1* code, u1 new_code) {
134   #ifdef ASSERT
135     // Read once.
136     volatile Bytecodes::Code c = (Bytecodes::Code)*code;
137     assert(c == 0 || c == new_code || new_code == 0, "update must be consistent");
138   #endif
139     Atomic::release_store(code, new_code);
140   }
141 
142   // Populate the strucutre with resolution information
143   void fill_in(InstanceKlass* klass, int offset, u2 index, u1 tos_state, u1 b1, u1 b2) {
144     _field_holder = klass;
145     _field_offset = offset;
146     _field_index = index;
147     _tos_state = tos_state;
148 
149     // These must be set after the other fields
150     set_bytecode(&_get_code, b1);
151     set_bytecode(&_put_code, b2);

152   }
153 
154   // CDS
155 #if INCLUDE_CDS
156   void remove_unshareable_info();
157   void mark_and_relocate();
158 #endif
159 
160   // Offsets
161   static ByteSize field_holder_offset() { return byte_offset_of(ResolvedFieldEntry, _field_holder); }
162   static ByteSize field_offset_offset() { return byte_offset_of(ResolvedFieldEntry, _field_offset); }
163   static ByteSize field_index_offset()  { return byte_offset_of(ResolvedFieldEntry, _field_index);  }
164   static ByteSize get_code_offset()     { return byte_offset_of(ResolvedFieldEntry, _get_code);     }
165   static ByteSize put_code_offset()     { return byte_offset_of(ResolvedFieldEntry, _put_code);     }
166   static ByteSize type_offset()         { return byte_offset_of(ResolvedFieldEntry, _tos_state);    }
167   static ByteSize flags_offset()        { return byte_offset_of(ResolvedFieldEntry, _flags);        }
168 


169 };
170 
171 #endif //SHARE_OOPS_RESOLVEDFIELDENTRY_HPP

 35 // like getfield, putfield, getstatic, and putstatic. A member of this class can be initialized
 36 // with the constant pool index associated with the bytecode before any resolution is done, where
 37 // "resolution" refers to populating the getcode and putcode fields and other relevant information.
 38 // The field's type (TOS), offset, holder klass, and index within that class can all be acquired
 39 // together and are used to populate this structure. These entries are contained
 40 // within the ConstantPoolCache and are accessed with indices added to the bytecode after
 41 // rewriting.
 42 
 43 // Field bytecodes start with a constant pool index as their operand, which is then rewritten to
 44 // a "field index", which is an index into the array of ResolvedFieldEntry.
 45 
 46 //class InstanceKlass;
 47 class ResolvedFieldEntry {
 48   friend class VMStructs;
 49 
 50   InstanceKlass* _field_holder; // Field holder klass
 51   int _field_offset;            // Field offset in bytes
 52   u2 _field_index;              // Index into field information in holder InstanceKlass
 53   u2 _cpool_index;              // Constant pool index
 54   u1 _tos_state;                // TOS state
 55   u1 _flags;                    // Flags: [000|has_null_marker|is_null_free_inline_type|is_flat|is_final|is_volatile]
 56   u1 _get_code, _put_code;      // Get and Put bytecodes of the field
 57 
 58   void copy_from(const ResolvedFieldEntry& other) {
 59     _field_holder = other._field_holder;
 60     _field_offset = other._field_offset;
 61     _field_index = other._field_index;
 62     _cpool_index = other._cpool_index;
 63     _tos_state = other._tos_state;
 64     _flags = other._flags;
 65     _get_code = other._get_code;
 66     _put_code = other._put_code;
 67   }
 68 
 69 public:
 70   ResolvedFieldEntry(u2 cpi) :
 71     _field_holder(nullptr),
 72     _field_offset(0),
 73     _field_index(0),
 74     _cpool_index(cpi),
 75     _tos_state(0),

 77     _get_code(0),
 78     _put_code(0) {}
 79 
 80   ResolvedFieldEntry() :
 81     ResolvedFieldEntry(0) {}
 82 
 83   ResolvedFieldEntry(const ResolvedFieldEntry& other) {
 84     copy_from(other);
 85   }
 86 
 87   ResolvedFieldEntry& operator=(const ResolvedFieldEntry& other) {
 88     copy_from(other);
 89     return *this;
 90   }
 91 
 92   // Bit shift to get flags
 93   // Note: Only two flags exists at the moment but more could be added
 94   enum {
 95       is_volatile_shift     = 0,
 96       is_final_shift        = 1, // unused
 97       is_flat_shift         = 2,
 98       is_null_free_inline_type_shift = 3,
 99       has_null_marker_shift = 4,
100       max_flag_shift = has_null_marker_shift
101   };
102 
103   // Getters
104   InstanceKlass* field_holder() const { return _field_holder; }
105   int field_offset()            const { return _field_offset; }
106   u2 field_index()              const { return _field_index;  }
107   u2 constant_pool_index()      const { return _cpool_index;  }
108   u1 tos_state()                const { return _tos_state;    }
109   u1 get_code()                 const { return Atomic::load_acquire(&_get_code);      }
110   u1 put_code()                 const { return Atomic::load_acquire(&_put_code);      }
111   bool is_final()               const { return (_flags & (1 << is_final_shift))    != 0; }
112   bool is_volatile ()           const { return (_flags & (1 << is_volatile_shift)) != 0; }
113   bool is_flat()                const { return (_flags & (1 << is_flat_shift))     != 0; }
114   bool is_null_free_inline_type() const { return (_flags & (1 << is_null_free_inline_type_shift)) != 0; }
115   bool has_null_marker()        const { return (_flags & (1 << has_null_marker_shift)) != 0; }
116   bool is_resolved(Bytecodes::Code code) const {
117     switch(code) {
118     case Bytecodes::_getstatic:
119     case Bytecodes::_getfield:
120       return (get_code() == code);
121     case Bytecodes::_putstatic:
122     case Bytecodes::_putfield:
123       return (put_code() == code);
124     default:
125       ShouldNotReachHere();
126       return false;
127     }
128   }
129 
130   // Printing
131   void print_on(outputStream* st) const;
132 
133   void set_flags(bool is_final_flag, bool is_volatile_flag, bool is_flat_flag, bool is_null_free_inline_type_flag,
134                  bool has_null_marker_flag) {
135     u1 new_flags = ((is_final_flag ? 1 : 0) << is_final_shift) | static_cast<int>(is_volatile_flag) |
136       ((is_flat_flag ? 1 : 0) << is_flat_shift) |
137       ((is_null_free_inline_type_flag ? 1 : 0) << is_null_free_inline_type_shift) |
138       ((has_null_marker_flag ? 1 : 0) << has_null_marker_shift);
139     _flags = checked_cast<u1>(new_flags);
140     assert(is_final() == is_final_flag, "Must be");
141     assert(is_volatile() == is_volatile_flag, "Must be");
142     assert(is_flat() == is_flat_flag, "Must be");
143     assert(is_null_free_inline_type() == is_null_free_inline_type_flag, "Must be");
144     assert(has_null_marker() == has_null_marker_flag, "Must be");
145   }
146 
147   inline void set_bytecode(u1* code, u1 new_code) {
148   #ifdef ASSERT
149     // Read once.
150     volatile Bytecodes::Code c = (Bytecodes::Code)*code;
151     assert(c == 0 || c == new_code || new_code == 0, "update must be consistent");
152   #endif
153     Atomic::release_store(code, new_code);
154   }
155 
156   // Populate the structure with resolution information
157   void fill_in(InstanceKlass* klass, int offset, u2 index, u1 tos_state, u1 b1, u1 b2) {
158     _field_holder = klass;
159     _field_offset = offset;
160     _field_index = index;
161     _tos_state = tos_state;
162 
163     // These must be set after the other fields
164     set_bytecode(&_get_code, b1);
165     set_bytecode(&_put_code, b2);
166     assert(is_valid(), "invalid");
167   }
168 
169   // CDS
170 #if INCLUDE_CDS
171   void remove_unshareable_info();
172   void mark_and_relocate();
173 #endif
174 
175   // Offsets
176   static ByteSize field_holder_offset() { return byte_offset_of(ResolvedFieldEntry, _field_holder); }
177   static ByteSize field_offset_offset() { return byte_offset_of(ResolvedFieldEntry, _field_offset); }
178   static ByteSize field_index_offset()  { return byte_offset_of(ResolvedFieldEntry, _field_index);  }
179   static ByteSize get_code_offset()     { return byte_offset_of(ResolvedFieldEntry, _get_code);     }
180   static ByteSize put_code_offset()     { return byte_offset_of(ResolvedFieldEntry, _put_code);     }
181   static ByteSize type_offset()         { return byte_offset_of(ResolvedFieldEntry, _tos_state);    }
182   static ByteSize flags_offset()        { return byte_offset_of(ResolvedFieldEntry, _flags);        }
183 
184   // Debug help
185   bool is_valid() const;
186 };
187 
188 #endif //SHARE_OOPS_RESOLVEDFIELDENTRY_HPP
< prev index next >