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
|