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
|