< 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 public:
 59   ResolvedFieldEntry(u2 cpi) :
 60     _field_holder(nullptr),
 61     _field_offset(0),
 62     _field_index(0),
 63     _cpool_index(cpi),
 64     _tos_state(0),
 65     _flags(0),
 66     _get_code(0),
 67     _put_code(0) {}
 68   ResolvedFieldEntry() :
 69     ResolvedFieldEntry(0) {}
 70 
 71   // Bit shift to get flags
 72   // Note: Only two flags exists at the moment but more could be added
 73   enum {
 74       is_volatile_shift     = 0,
 75       is_final_shift        = 1, // unused





 76   };
 77 
 78   // Getters
 79   InstanceKlass* field_holder() const { return _field_holder; }
 80   int field_offset()            const { return _field_offset; }
 81   u2 field_index()              const { return _field_index;  }
 82   u2 constant_pool_index()      const { return _cpool_index;  }
 83   u1 tos_state()                const { return _tos_state;    }
 84   u1 get_code()                 const { return Atomic::load_acquire(&_get_code);      }
 85   u1 put_code()                 const { return Atomic::load_acquire(&_put_code);      }
 86   bool is_final()               const { return (_flags & (1 << is_final_shift))    != 0; }
 87   bool is_volatile ()           const { return (_flags & (1 << is_volatile_shift)) != 0; }




 88   bool is_resolved(Bytecodes::Code code) const {
 89     switch(code) {
 90     case Bytecodes::_getstatic:
 91     case Bytecodes::_getfield:
 92       return (get_code() == code);
 93     case Bytecodes::_putstatic:
 94     case Bytecodes::_putfield:
 95       return (put_code() == code);
 96     default:
 97       ShouldNotReachHere();
 98       return false;
 99     }
100   }
101 
102   // Printing
103   void print_on(outputStream* st) const;
104 
105   void set_flags(bool is_final_flag, bool is_volatile_flag) {
106     int new_flags = (is_final_flag << is_final_shift) | static_cast<int>(is_volatile_flag);





107     _flags = checked_cast<u1>(new_flags);
108     assert(is_final() == is_final_flag, "Must be");
109     assert(is_volatile() == is_volatile_flag, "Must be");




110   }
111 
112   inline void set_bytecode(u1* code, u1 new_code) {
113   #ifdef ASSERT
114     // Read once.
115     volatile Bytecodes::Code c = (Bytecodes::Code)*code;
116     assert(c == 0 || c == new_code || new_code == 0, "update must be consistent");
117   #endif
118     Atomic::release_store(code, new_code);
119   }
120 
121   // Populate the strucutre with resolution information
122   void fill_in(InstanceKlass* klass, int offset, u2 index, u1 tos_state, u1 b1, u1 b2) {
123     _field_holder = klass;
124     _field_offset = offset;
125     _field_index = index;
126     _tos_state = tos_state;
127 
128     // These must be set after the other fields
129     set_bytecode(&_get_code, b1);
130     set_bytecode(&_put_code, b2);

131   }
132 
133   // CDS
134   void remove_unshareable_info();
135 
136   // Offsets
137   static ByteSize field_holder_offset() { return byte_offset_of(ResolvedFieldEntry, _field_holder); }
138   static ByteSize field_offset_offset() { return byte_offset_of(ResolvedFieldEntry, _field_offset); }
139   static ByteSize field_index_offset()  { return byte_offset_of(ResolvedFieldEntry, _field_index);  }
140   static ByteSize get_code_offset()     { return byte_offset_of(ResolvedFieldEntry, _get_code);     }
141   static ByteSize put_code_offset()     { return byte_offset_of(ResolvedFieldEntry, _put_code);     }
142   static ByteSize type_offset()         { return byte_offset_of(ResolvedFieldEntry, _tos_state);    }
143   static ByteSize flags_offset()        { return byte_offset_of(ResolvedFieldEntry, _flags);        }
144 


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