34 // Java shorts but in the future it could simply be used as a real 35 // array type. FieldInfo generally shouldn't be used directly. 36 // Fields should be queried either through InstanceKlass or through 37 // the various FieldStreams. 38 class FieldInfo VALUE_OBJ_CLASS_SPEC { 39 friend class fieldDescriptor; 40 friend class JavaFieldStream; 41 friend class ClassFileParser; 42 43 public: 44 // fields 45 // Field info extracted from the class file and stored 46 // as an array of 6 shorts. 47 48 #define FIELDINFO_TAG_SIZE 3 49 #define FIELDINFO_TAG_BLANK 0 50 #define FIELDINFO_TAG_OFFSET 1 51 #define FIELDINFO_TAG_TYPE_PLAIN 2 52 #define FIELDINFO_TAG_TYPE_CONTENDED 3 53 #define FIELDINFO_TAG_TYPE_MASK 3 54 #define FIELDINFO_TAG_MASK 15 55 #define FIELDINFO_FLATTENING_OFFSET 2 56 #define FIELDINFO_FLATTENABLE_OFFSET 3 57 58 // Packed field has the tag, and can be either of: 59 // hi bits <--------------------------- lo bits 60 // |---------high---------|---------low---------| 61 // ..........................................00 - blank 62 // [------------------offset----------------]01 - real field offset 63 // ......................[-------type-------]10 - plain field with type 64 // [--contention_group--][-------type-------]11 - contended field with type and contention group 65 enum FieldOffset { 66 access_flags_offset = 0, 67 name_index_offset = 1, 68 signature_index_offset = 2, 69 initval_index_offset = 3, 70 low_packed_offset = 4, 71 high_packed_offset = 5, 72 field_slots = 6 73 }; 74 75 private: 76 u2 _shorts[field_slots]; 181 182 Symbol* name(const constantPoolHandle& cp) const { 183 int index = name_index(); 184 if (is_internal()) { 185 return lookup_symbol(index); 186 } 187 return cp->symbol_at(index); 188 } 189 190 Symbol* signature(const constantPoolHandle& cp) const { 191 int index = signature_index(); 192 if (is_internal()) { 193 return lookup_symbol(index); 194 } 195 return cp->symbol_at(index); 196 } 197 198 void set_access_flags(u2 val) { _shorts[access_flags_offset] = val; } 199 void set_offset(u4 val) { 200 val = val << FIELDINFO_TAG_SIZE; // make room for tag 201 bool flatten = is_flatten(); 202 _shorts[low_packed_offset] = extract_low_short_from_int(val) | FIELDINFO_TAG_OFFSET; 203 if (flatten) set_flattening(true); 204 _shorts[high_packed_offset] = extract_high_short_from_int(val); 205 assert(is_flatten() || !flatten, "just checking"); 206 } 207 208 void set_allocation_type(int type) { 209 bool b = is_flatten(); 210 u2 lo = _shorts[low_packed_offset]; 211 switch(lo & FIELDINFO_TAG_TYPE_MASK) { 212 case FIELDINFO_TAG_BLANK: 213 _shorts[low_packed_offset] |= ((type << FIELDINFO_TAG_SIZE)) & 0xFFFF; 214 _shorts[low_packed_offset] &= ~FIELDINFO_TAG_TYPE_MASK; 215 _shorts[low_packed_offset] |= FIELDINFO_TAG_TYPE_PLAIN; 216 assert(is_flatten() || !b, "Just checking"); 217 return; 218 #ifndef PRODUCT 219 case FIELDINFO_TAG_TYPE_PLAIN: 220 case FIELDINFO_TAG_TYPE_CONTENDED: 221 case FIELDINFO_TAG_OFFSET: 222 fatal("Setting the field type with overwriting"); 223 #endif 224 } 225 ShouldNotReachHere(); 226 } 227 228 void set_flattening(bool b) { 229 if (b) { 230 _shorts[low_packed_offset] |= 1 << FIELDINFO_FLATTENING_OFFSET; 231 } else { 232 _shorts[low_packed_offset] &= ~(1 << FIELDINFO_FLATTENING_OFFSET); 233 } 234 } 235 236 bool is_flatten() { 237 return ((_shorts[low_packed_offset] >> FIELDINFO_FLATTENING_OFFSET) & 1) != 0; 238 } 239 240 void set_flattenable(bool b) { 241 if (b) { 242 _shorts[low_packed_offset] |= 1 << FIELDINFO_FLATTENABLE_OFFSET; 243 } else { 244 _shorts[low_packed_offset] &= ~(1 << FIELDINFO_FLATTENABLE_OFFSET); 245 } 246 } 247 248 bool is_flattenable() { 249 return ((_shorts[low_packed_offset] >> FIELDINFO_FLATTENABLE_OFFSET) & 1) != 0; 250 } 251 252 void set_contended_group(u2 val) { 253 u2 lo = _shorts[low_packed_offset]; 254 switch(lo & FIELDINFO_TAG_TYPE_MASK) { 255 case FIELDINFO_TAG_TYPE_PLAIN: 256 _shorts[low_packed_offset] |= FIELDINFO_TAG_TYPE_CONTENDED; 257 _shorts[high_packed_offset] = val; 258 return; 259 #ifndef PRODUCT 260 case FIELDINFO_TAG_TYPE_CONTENDED: 261 fatal("Overwriting contended group"); 262 case FIELDINFO_TAG_BLANK: 263 fatal("Setting contended group for the blank field"); 264 case FIELDINFO_TAG_OFFSET: 265 fatal("Setting contended group for field with offset"); 266 #endif 267 } 268 ShouldNotReachHere(); 269 } 270 271 bool is_internal() const { 272 return (access_flags() & JVM_ACC_FIELD_INTERNAL) != 0; 273 } 274 275 bool is_stable() const { 276 return (access_flags() & JVM_ACC_FIELD_STABLE) != 0; 277 } 278 void set_stable(bool z) { 279 if (z) _shorts[access_flags_offset] |= JVM_ACC_FIELD_STABLE; 280 else _shorts[access_flags_offset] &= ~JVM_ACC_FIELD_STABLE; 281 } 282 283 Symbol* lookup_symbol(int symbol_index) const { 284 assert(is_internal(), "only internal fields"); 285 return vmSymbols::symbol_at((vmSymbols::SID)symbol_index); 286 } 287 }; 288 289 #endif // SHARE_VM_OOPS_FIELDINFO_HPP | 34 // Java shorts but in the future it could simply be used as a real 35 // array type. FieldInfo generally shouldn't be used directly. 36 // Fields should be queried either through InstanceKlass or through 37 // the various FieldStreams. 38 class FieldInfo VALUE_OBJ_CLASS_SPEC { 39 friend class fieldDescriptor; 40 friend class JavaFieldStream; 41 friend class ClassFileParser; 42 43 public: 44 // fields 45 // Field info extracted from the class file and stored 46 // as an array of 6 shorts. 47 48 #define FIELDINFO_TAG_SIZE 3 49 #define FIELDINFO_TAG_BLANK 0 50 #define FIELDINFO_TAG_OFFSET 1 51 #define FIELDINFO_TAG_TYPE_PLAIN 2 52 #define FIELDINFO_TAG_TYPE_CONTENDED 3 53 #define FIELDINFO_TAG_TYPE_MASK 3 54 #define FIELDINFO_TAG_MASK 7 55 #define FIELDINFO_FLATTENED_OFFSET 2 56 57 // Packed field has the tag, and can be either of: 58 // hi bits <--------------------------- lo bits 59 // |---------high---------|---------low---------| 60 // ..........................................00 - blank 61 // [------------------offset----------------]01 - real field offset 62 // ......................[-------type-------]10 - plain field with type 63 // [--contention_group--][-------type-------]11 - contended field with type and contention group 64 enum FieldOffset { 65 access_flags_offset = 0, 66 name_index_offset = 1, 67 signature_index_offset = 2, 68 initval_index_offset = 3, 69 low_packed_offset = 4, 70 high_packed_offset = 5, 71 field_slots = 6 72 }; 73 74 private: 75 u2 _shorts[field_slots]; 180 181 Symbol* name(const constantPoolHandle& cp) const { 182 int index = name_index(); 183 if (is_internal()) { 184 return lookup_symbol(index); 185 } 186 return cp->symbol_at(index); 187 } 188 189 Symbol* signature(const constantPoolHandle& cp) const { 190 int index = signature_index(); 191 if (is_internal()) { 192 return lookup_symbol(index); 193 } 194 return cp->symbol_at(index); 195 } 196 197 void set_access_flags(u2 val) { _shorts[access_flags_offset] = val; } 198 void set_offset(u4 val) { 199 val = val << FIELDINFO_TAG_SIZE; // make room for tag 200 bool flattened = is_flattened(); 201 _shorts[low_packed_offset] = extract_low_short_from_int(val) | FIELDINFO_TAG_OFFSET; 202 if (flattened) set_flattened(true); 203 _shorts[high_packed_offset] = extract_high_short_from_int(val); 204 assert(is_flattened() || !flattened, "just checking"); 205 } 206 207 void set_allocation_type(int type) { 208 bool b = is_flattened(); 209 u2 lo = _shorts[low_packed_offset]; 210 switch(lo & FIELDINFO_TAG_TYPE_MASK) { 211 case FIELDINFO_TAG_BLANK: 212 _shorts[low_packed_offset] |= ((type << FIELDINFO_TAG_SIZE)) & 0xFFFF; 213 _shorts[low_packed_offset] &= ~FIELDINFO_TAG_TYPE_MASK; 214 _shorts[low_packed_offset] |= FIELDINFO_TAG_TYPE_PLAIN; 215 assert(is_flattened() || !b, "Just checking"); 216 return; 217 #ifndef PRODUCT 218 case FIELDINFO_TAG_TYPE_PLAIN: 219 case FIELDINFO_TAG_TYPE_CONTENDED: 220 case FIELDINFO_TAG_OFFSET: 221 fatal("Setting the field type with overwriting"); 222 #endif 223 } 224 ShouldNotReachHere(); 225 } 226 227 void set_flattened(bool b) { 228 if (b) { 229 _shorts[low_packed_offset] |= 1 << FIELDINFO_FLATTENED_OFFSET; 230 } else { 231 _shorts[low_packed_offset] &= ~(1 << FIELDINFO_FLATTENED_OFFSET); 232 } 233 } 234 235 bool is_flattened() { 236 return ((_shorts[low_packed_offset] >> FIELDINFO_FLATTENED_OFFSET) & 1) != 0; 237 } 238 239 void set_contended_group(u2 val) { 240 u2 lo = _shorts[low_packed_offset]; 241 switch(lo & FIELDINFO_TAG_TYPE_MASK) { 242 case FIELDINFO_TAG_TYPE_PLAIN: 243 _shorts[low_packed_offset] |= FIELDINFO_TAG_TYPE_CONTENDED; 244 _shorts[high_packed_offset] = val; 245 return; 246 #ifndef PRODUCT 247 case FIELDINFO_TAG_TYPE_CONTENDED: 248 fatal("Overwriting contended group"); 249 case FIELDINFO_TAG_BLANK: 250 fatal("Setting contended group for the blank field"); 251 case FIELDINFO_TAG_OFFSET: 252 fatal("Setting contended group for field with offset"); 253 #endif 254 } 255 ShouldNotReachHere(); 256 } 257 258 bool is_internal() const { 259 return (access_flags() & JVM_ACC_FIELD_INTERNAL) != 0; 260 } 261 262 bool is_stable() const { 263 return (access_flags() & JVM_ACC_FIELD_STABLE) != 0; 264 } 265 void set_stable(bool z) { 266 if (z) _shorts[access_flags_offset] |= JVM_ACC_FIELD_STABLE; 267 else _shorts[access_flags_offset] &= ~JVM_ACC_FIELD_STABLE; 268 } 269 270 bool is_flattenable() const { 271 return (access_flags() & JVM_ACC_FLATTENABLE) != 0; 272 } 273 274 Symbol* lookup_symbol(int symbol_index) const { 275 assert(is_internal(), "only internal fields"); 276 return vmSymbols::symbol_at((vmSymbols::SID)symbol_index); 277 } 278 }; 279 280 #endif // SHARE_VM_OOPS_FIELDINFO_HPP |