122 assert(last_offset > first_offset && last_tsz, "Invariant");
123 return 1 << upper_log2(last_offset - first_offset);
124 }
125
126 instanceOop ValueKlass::allocate_instance(TRAPS) {
127 int size = size_helper(); // Query before forming handle.
128
129 instanceOop oop = (instanceOop)Universe::heap()->obj_allocate(this, size, CHECK_NULL);
130 assert(oop->mark().is_always_locked(), "Unlocked value type");
131 return oop;
132 }
133
134 instanceOop ValueKlass::allocate_instance_buffer(TRAPS) {
135 int size = size_helper(); // Query before forming handle.
136
137 instanceOop oop = (instanceOop)Universe::heap()->obj_buffer_allocate(this, size, CHECK_NULL);
138 assert(oop->mark().is_always_locked(), "Unlocked value type");
139 return oop;
140 }
141
142 bool ValueKlass::is_atomic() {
143 return (nonstatic_field_size() * heapOopSize) <= longSize;
144 }
145
146 int ValueKlass::nonstatic_oop_count() {
147 int oops = 0;
148 int map_count = nonstatic_oop_map_count();
149 OopMapBlock* block = start_of_nonstatic_oop_maps();
150 OopMapBlock* end = block + map_count;
151 while (block != end) {
152 oops += block->count();
153 block++;
154 }
155 return oops;
156 }
157
158 oop ValueKlass::read_flattened_field(oop obj, int offset, TRAPS) {
159 oop res = NULL;
160 this->initialize(CHECK_NULL); // will throw an exception if in error state
161 if (is_empty_value()) {
162 res = (instanceOop)default_value();
163 } else {
164 Handle obj_h(THREAD, obj);
165 res = allocate_instance_buffer(CHECK_NULL);
178 }
179 }
180
181 // Arrays of...
182
183 bool ValueKlass::flatten_array() {
184 if (!ValueArrayFlatten) {
185 return false;
186 }
187
188 int elem_bytes = raw_value_byte_size();
189 // Too big
190 if ((ValueArrayElemMaxFlatSize >= 0) && (elem_bytes > ValueArrayElemMaxFlatSize)) {
191 return false;
192 }
193 // Too many embedded oops
194 if ((ValueArrayElemMaxFlatOops >= 0) && (nonstatic_oop_count() > ValueArrayElemMaxFlatOops)) {
195 return false;
196 }
197
198 return true;
199 }
200
201 void ValueKlass::remove_unshareable_info() {
202 InstanceKlass::remove_unshareable_info();
203
204 *((Array<SigEntry>**)adr_extended_sig()) = NULL;
205 *((Array<VMRegPair>**)adr_return_regs()) = NULL;
206 *((address*)adr_pack_handler()) = NULL;
207 *((address*)adr_pack_handler_jobject()) = NULL;
208 *((address*)adr_unpack_handler()) = NULL;
209 assert(pack_handler() == NULL, "pack handler not null");
210 *((Klass**)adr_value_array_klass()) = NULL;
211 }
212
213 void ValueKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS) {
214 InstanceKlass::restore_unshareable_info(loader_data, protection_domain, CHECK);
215 oop val = allocate_instance(CHECK);
216 set_default_value(val);
217 }
236 ResourceMark rm;
237 {
238 // Atomic creation of array_klasses
239 MutexLocker ma(THREAD, MultiArray_lock);
240 if (get_value_array_klass() == NULL) {
241 vak = allocate_value_array_klass(CHECK_NULL);
242 Atomic::release_store((Klass**)adr_value_array_klass(), vak);
243 }
244 }
245 }
246 if (!vak->is_valueArray_klass()) {
247 storage_props.clear_flattened();
248 }
249 if (or_null) {
250 return vak->array_klass_or_null(storage_props, rank);
251 }
252 return vak->array_klass(storage_props, rank, THREAD);
253 }
254
255 Klass* ValueKlass::allocate_value_array_klass(TRAPS) {
256 if (flatten_array() && (is_atomic() || (!ValueArrayAtomicAccess))) {
257 return ValueArrayKlass::allocate_klass(ArrayStorageProperties::flattened_and_null_free, this, THREAD);
258 }
259 return ObjArrayKlass::allocate_objArray_klass(ArrayStorageProperties::null_free, 1, this, THREAD);
260 }
261
262 void ValueKlass::array_klasses_do(void f(Klass* k)) {
263 InstanceKlass::array_klasses_do(f);
264 if (get_value_array_klass() != NULL)
265 ArrayKlass::cast(get_value_array_klass())->array_klasses_do(f);
266 }
267
268 // Value type arguments are not passed by reference, instead each
269 // field of the value type is passed as an argument. This helper
270 // function collects the fields of the value types (including embedded
271 // value type's fields) in a list. Included with the field's type is
272 // the offset of each field in the value type: i2c and c2i adapters
273 // need that to load or store fields. Finally, the list of fields is
274 // sorted in order of increasing offsets: the adapters and the
275 // compiled code need to agree upon the order of fields.
276 //
|
122 assert(last_offset > first_offset && last_tsz, "Invariant");
123 return 1 << upper_log2(last_offset - first_offset);
124 }
125
126 instanceOop ValueKlass::allocate_instance(TRAPS) {
127 int size = size_helper(); // Query before forming handle.
128
129 instanceOop oop = (instanceOop)Universe::heap()->obj_allocate(this, size, CHECK_NULL);
130 assert(oop->mark().is_always_locked(), "Unlocked value type");
131 return oop;
132 }
133
134 instanceOop ValueKlass::allocate_instance_buffer(TRAPS) {
135 int size = size_helper(); // Query before forming handle.
136
137 instanceOop oop = (instanceOop)Universe::heap()->obj_buffer_allocate(this, size, CHECK_NULL);
138 assert(oop->mark().is_always_locked(), "Unlocked value type");
139 return oop;
140 }
141
142 int ValueKlass::nonstatic_oop_count() {
143 int oops = 0;
144 int map_count = nonstatic_oop_map_count();
145 OopMapBlock* block = start_of_nonstatic_oop_maps();
146 OopMapBlock* end = block + map_count;
147 while (block != end) {
148 oops += block->count();
149 block++;
150 }
151 return oops;
152 }
153
154 oop ValueKlass::read_flattened_field(oop obj, int offset, TRAPS) {
155 oop res = NULL;
156 this->initialize(CHECK_NULL); // will throw an exception if in error state
157 if (is_empty_value()) {
158 res = (instanceOop)default_value();
159 } else {
160 Handle obj_h(THREAD, obj);
161 res = allocate_instance_buffer(CHECK_NULL);
174 }
175 }
176
177 // Arrays of...
178
179 bool ValueKlass::flatten_array() {
180 if (!ValueArrayFlatten) {
181 return false;
182 }
183
184 int elem_bytes = raw_value_byte_size();
185 // Too big
186 if ((ValueArrayElemMaxFlatSize >= 0) && (elem_bytes > ValueArrayElemMaxFlatSize)) {
187 return false;
188 }
189 // Too many embedded oops
190 if ((ValueArrayElemMaxFlatOops >= 0) && (nonstatic_oop_count() > ValueArrayElemMaxFlatOops)) {
191 return false;
192 }
193
194 // Declared atomic but not naturally atomic.
195 if (is_declared_atomic() && !is_naturally_atomic()) {
196 return false;
197 }
198
199 return true;
200 }
201
202 void ValueKlass::remove_unshareable_info() {
203 InstanceKlass::remove_unshareable_info();
204
205 *((Array<SigEntry>**)adr_extended_sig()) = NULL;
206 *((Array<VMRegPair>**)adr_return_regs()) = NULL;
207 *((address*)adr_pack_handler()) = NULL;
208 *((address*)adr_pack_handler_jobject()) = NULL;
209 *((address*)adr_unpack_handler()) = NULL;
210 assert(pack_handler() == NULL, "pack handler not null");
211 *((Klass**)adr_value_array_klass()) = NULL;
212 }
213
214 void ValueKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS) {
215 InstanceKlass::restore_unshareable_info(loader_data, protection_domain, CHECK);
216 oop val = allocate_instance(CHECK);
217 set_default_value(val);
218 }
237 ResourceMark rm;
238 {
239 // Atomic creation of array_klasses
240 MutexLocker ma(THREAD, MultiArray_lock);
241 if (get_value_array_klass() == NULL) {
242 vak = allocate_value_array_klass(CHECK_NULL);
243 Atomic::release_store((Klass**)adr_value_array_klass(), vak);
244 }
245 }
246 }
247 if (!vak->is_valueArray_klass()) {
248 storage_props.clear_flattened();
249 }
250 if (or_null) {
251 return vak->array_klass_or_null(storage_props, rank);
252 }
253 return vak->array_klass(storage_props, rank, THREAD);
254 }
255
256 Klass* ValueKlass::allocate_value_array_klass(TRAPS) {
257 if (flatten_array() && (is_naturally_atomic() || (!ValueArrayAtomicAccess))) {
258 return ValueArrayKlass::allocate_klass(ArrayStorageProperties::flattened_and_null_free, this, THREAD);
259 }
260 return ObjArrayKlass::allocate_objArray_klass(ArrayStorageProperties::null_free, 1, this, THREAD);
261 }
262
263 void ValueKlass::array_klasses_do(void f(Klass* k)) {
264 InstanceKlass::array_klasses_do(f);
265 if (get_value_array_klass() != NULL)
266 ArrayKlass::cast(get_value_array_klass())->array_klasses_do(f);
267 }
268
269 // Value type arguments are not passed by reference, instead each
270 // field of the value type is passed as an argument. This helper
271 // function collects the fields of the value types (including embedded
272 // value type's fields) in a list. Included with the field's type is
273 // the offset of each field in the value type: i2c and c2i adapters
274 // need that to load or store fields. Finally, the list of fields is
275 // sorted in order of increasing offsets: the adapters and the
276 // compiled code need to agree upon the order of fields.
277 //
|