< prev index next >

src/hotspot/share/oops/valueKlass.cpp

Print this page
rev 59083 : DRAFT 8236522: NonTearable marker interface for inline classes to enforce atomicity


 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 //


< prev index next >