< prev index next >

src/hotspot/share/oops/fieldInfo.hpp

Print this page




  28 #include "oops/constantPool.hpp"
  29 #include "oops/typeArrayOop.hpp"
  30 #include "classfile/vmSymbols.hpp"
  31 
  32 // This class represents the field information contained in the fields
  33 // array of an InstanceKlass.  Currently it's laid on top an array of
  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 {
  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             2
  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_MASK             3


  54 
  55   // Packed field has the tag, and can be either of:
  56   //    hi bits <--------------------------- lo bits
  57   //   |---------high---------|---------low---------|
  58   //    ..........................................00  - blank
  59   //    [------------------offset----------------]01  - real field offset
  60   //    ......................[-------type-------]10  - plain field with type
  61   //    [--contention_group--][-------type-------]11  - contended field with type and contention group



  62   enum FieldOffset {
  63     access_flags_offset      = 0,
  64     name_index_offset        = 1,
  65     signature_index_offset   = 2,
  66     initval_index_offset     = 3,
  67     low_packed_offset        = 4,
  68     high_packed_offset       = 5,
  69     field_slots              = 6
  70   };
  71 
  72  private:
  73   u2 _shorts[field_slots];
  74 
  75   void set_name_index(u2 val)                    { _shorts[name_index_offset] = val;         }
  76   void set_signature_index(u2 val)               { _shorts[signature_index_offset] = val;    }
  77   void set_initval_index(u2 val)                 { _shorts[initval_index_offset] = val;      }
  78 
  79   u2 name_index() const                          { return _shorts[name_index_offset];        }
  80   u2 signature_index() const                     { return _shorts[signature_index_offset];   }
  81   u2 initval_index() const                       { return _shorts[initval_index_offset];     }


  86   }
  87   static FieldInfo* from_field_array(u2* fields, int index) {
  88     return ((FieldInfo*)(fields + index * field_slots));
  89   }
  90 
  91   void initialize(u2 access_flags,
  92                   u2 name_index,
  93                   u2 signature_index,
  94                   u2 initval_index) {
  95     _shorts[access_flags_offset] = access_flags;
  96     _shorts[name_index_offset] = name_index;
  97     _shorts[signature_index_offset] = signature_index;
  98     _shorts[initval_index_offset] = initval_index;
  99     _shorts[low_packed_offset] = 0;
 100     _shorts[high_packed_offset] = 0;
 101   }
 102 
 103   u2 access_flags() const                        { return _shorts[access_flags_offset];            }
 104   u4 offset() const {
 105     u2 lo = _shorts[low_packed_offset];
 106     switch(lo & FIELDINFO_TAG_MASK) {
 107       case FIELDINFO_TAG_OFFSET:
 108         return build_int_from_shorts(_shorts[low_packed_offset], _shorts[high_packed_offset]) >> FIELDINFO_TAG_SIZE;
 109 #ifndef PRODUCT
 110       case FIELDINFO_TAG_TYPE_PLAIN:
 111         fatal("Asking offset for the plain type field");
 112       case FIELDINFO_TAG_TYPE_CONTENDED:
 113         fatal("Asking offset for the contended type field");
 114       case FIELDINFO_TAG_BLANK:
 115         fatal("Asking offset for the blank field");
 116 #endif
 117     }
 118     ShouldNotReachHere();
 119     return 0;
 120   }
 121 
 122   bool is_contended() const {
 123     u2 lo = _shorts[low_packed_offset];
 124     switch(lo & FIELDINFO_TAG_MASK) {
 125       case FIELDINFO_TAG_TYPE_PLAIN:
 126         return false;
 127       case FIELDINFO_TAG_TYPE_CONTENDED:
 128         return true;
 129 #ifndef PRODUCT
 130       case FIELDINFO_TAG_OFFSET:
 131         fatal("Asking contended flag for the field with offset");
 132       case FIELDINFO_TAG_BLANK:
 133         fatal("Asking contended flag for the blank field");
 134 #endif
 135     }
 136     ShouldNotReachHere();
 137     return false;
 138   }
 139 
 140   u2 contended_group() const {
 141     u2 lo = _shorts[low_packed_offset];
 142     switch(lo & FIELDINFO_TAG_MASK) {
 143       case FIELDINFO_TAG_TYPE_PLAIN:
 144         return 0;
 145       case FIELDINFO_TAG_TYPE_CONTENDED:
 146         return _shorts[high_packed_offset];
 147 #ifndef PRODUCT
 148       case FIELDINFO_TAG_OFFSET:
 149         fatal("Asking the contended group for the field with offset");
 150       case FIELDINFO_TAG_BLANK:
 151         fatal("Asking the contended group for the blank field");
 152 #endif
 153     }
 154     ShouldNotReachHere();
 155     return 0;
 156  }
 157 
 158   u2 allocation_type() const {
 159     u2 lo = _shorts[low_packed_offset];
 160     switch(lo & FIELDINFO_TAG_MASK) {
 161       case FIELDINFO_TAG_TYPE_PLAIN:
 162       case FIELDINFO_TAG_TYPE_CONTENDED:
 163         return (lo >> FIELDINFO_TAG_SIZE);
 164 #ifndef PRODUCT
 165       case FIELDINFO_TAG_OFFSET:
 166         fatal("Asking the field type for field with offset");
 167       case FIELDINFO_TAG_BLANK:
 168         fatal("Asking the field type for the blank field");
 169 #endif
 170     }
 171     ShouldNotReachHere();
 172     return 0;
 173   }
 174 
 175   bool is_offset_set() const {
 176     return (_shorts[low_packed_offset] & FIELDINFO_TAG_MASK) == FIELDINFO_TAG_OFFSET;
 177   }
 178 
 179   Symbol* name(const constantPoolHandle& cp) const {
 180     int index = name_index();
 181     if (is_internal()) {
 182       return lookup_symbol(index);
 183     }
 184     return cp->symbol_at(index);
 185   }
 186 
 187   Symbol* signature(const constantPoolHandle& cp) const {
 188     int index = signature_index();
 189     if (is_internal()) {
 190       return lookup_symbol(index);
 191     }
 192     return cp->symbol_at(index);
 193   }
 194 
 195   void set_access_flags(u2 val)                  { _shorts[access_flags_offset] = val;             }
 196   void set_offset(u4 val)                        {
 197     val = val << FIELDINFO_TAG_SIZE; // make room for tag

 198     _shorts[low_packed_offset] = extract_low_short_from_int(val) | FIELDINFO_TAG_OFFSET;

 199     _shorts[high_packed_offset] = extract_high_short_from_int(val);

 200   }
 201 
 202   void set_allocation_type(int type) {

 203     u2 lo = _shorts[low_packed_offset];
 204     switch(lo & FIELDINFO_TAG_MASK) {
 205       case FIELDINFO_TAG_BLANK:
 206         _shorts[low_packed_offset] = ((type << FIELDINFO_TAG_SIZE)) & 0xFFFF;
 207         _shorts[low_packed_offset] &= ~FIELDINFO_TAG_MASK;
 208         _shorts[low_packed_offset] |= FIELDINFO_TAG_TYPE_PLAIN;

 209         return;
 210 #ifndef PRODUCT
 211       case FIELDINFO_TAG_TYPE_PLAIN:
 212       case FIELDINFO_TAG_TYPE_CONTENDED:
 213       case FIELDINFO_TAG_OFFSET:
 214         fatal("Setting the field type with overwriting");
 215 #endif
 216     }
 217     ShouldNotReachHere();
 218   }
 219 












 220   void set_contended_group(u2 val) {
 221     u2 lo = _shorts[low_packed_offset];
 222     switch(lo & FIELDINFO_TAG_MASK) {
 223       case FIELDINFO_TAG_TYPE_PLAIN:
 224         _shorts[low_packed_offset] |= FIELDINFO_TAG_TYPE_CONTENDED;
 225         _shorts[high_packed_offset] = val;
 226         return;
 227 #ifndef PRODUCT
 228       case FIELDINFO_TAG_TYPE_CONTENDED:
 229         fatal("Overwriting contended group");
 230       case FIELDINFO_TAG_BLANK:
 231         fatal("Setting contended group for the blank field");
 232       case FIELDINFO_TAG_OFFSET:
 233         fatal("Setting contended group for field with offset");
 234 #endif
 235     }
 236     ShouldNotReachHere();
 237   }
 238 
 239   bool is_internal() const {
 240     return (access_flags() & JVM_ACC_FIELD_INTERNAL) != 0;
 241   }
 242 
 243   bool is_stable() const {
 244     return (access_flags() & JVM_ACC_FIELD_STABLE) != 0;
 245   }
 246   void set_stable(bool z) {
 247     if (z) _shorts[access_flags_offset] |=  JVM_ACC_FIELD_STABLE;
 248     else   _shorts[access_flags_offset] &= ~JVM_ACC_FIELD_STABLE;




 249   }
 250 
 251   Symbol* lookup_symbol(int symbol_index) const {
 252     assert(is_internal(), "only internal fields");
 253     return vmSymbols::symbol_at((vmSymbols::SID)symbol_index);
 254   }
 255 };
 256 
 257 #endif // SHARE_OOPS_FIELDINFO_HPP


  28 #include "oops/constantPool.hpp"
  29 #include "oops/typeArrayOop.hpp"
  30 #include "classfile/vmSymbols.hpp"
  31 
  32 // This class represents the field information contained in the fields
  33 // array of an InstanceKlass.  Currently it's laid on top an array of
  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 {
  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_TAG_FLATTENED        4
  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---------------]F01  - real field offset
  62   //    ......................[-------type------]F10  - plain field with type
  63   //    [--contention_group--][-------type------]F11  - contended field with type and contention group
  64   //
  65   // Bit F indicates if the field has been flattened (F=1) or nor (F=0)
  66 
  67   enum FieldOffset {
  68     access_flags_offset      = 0,
  69     name_index_offset        = 1,
  70     signature_index_offset   = 2,
  71     initval_index_offset     = 3,
  72     low_packed_offset        = 4,
  73     high_packed_offset       = 5,
  74     field_slots              = 6
  75   };
  76 
  77  private:
  78   u2 _shorts[field_slots];
  79 
  80   void set_name_index(u2 val)                    { _shorts[name_index_offset] = val;         }
  81   void set_signature_index(u2 val)               { _shorts[signature_index_offset] = val;    }
  82   void set_initval_index(u2 val)                 { _shorts[initval_index_offset] = val;      }
  83 
  84   u2 name_index() const                          { return _shorts[name_index_offset];        }
  85   u2 signature_index() const                     { return _shorts[signature_index_offset];   }
  86   u2 initval_index() const                       { return _shorts[initval_index_offset];     }


  91   }
  92   static FieldInfo* from_field_array(u2* fields, int index) {
  93     return ((FieldInfo*)(fields + index * field_slots));
  94   }
  95 
  96   void initialize(u2 access_flags,
  97                   u2 name_index,
  98                   u2 signature_index,
  99                   u2 initval_index) {
 100     _shorts[access_flags_offset] = access_flags;
 101     _shorts[name_index_offset] = name_index;
 102     _shorts[signature_index_offset] = signature_index;
 103     _shorts[initval_index_offset] = initval_index;
 104     _shorts[low_packed_offset] = 0;
 105     _shorts[high_packed_offset] = 0;
 106   }
 107 
 108   u2 access_flags() const                        { return _shorts[access_flags_offset];            }
 109   u4 offset() const {
 110     u2 lo = _shorts[low_packed_offset];
 111     switch(lo & FIELDINFO_TAG_TYPE_MASK) {
 112       case FIELDINFO_TAG_OFFSET:
 113         return build_int_from_shorts(_shorts[low_packed_offset], _shorts[high_packed_offset]) >> FIELDINFO_TAG_SIZE;
 114 #ifndef PRODUCT
 115       case FIELDINFO_TAG_TYPE_PLAIN:
 116         fatal("Asking offset for the plain type field");
 117       case FIELDINFO_TAG_TYPE_CONTENDED:
 118         fatal("Asking offset for the contended type field");
 119       case FIELDINFO_TAG_BLANK:
 120         fatal("Asking offset for the blank field");
 121 #endif
 122     }
 123     ShouldNotReachHere();
 124     return 0;
 125   }
 126 
 127   bool is_contended() const {
 128     u2 lo = _shorts[low_packed_offset];
 129     switch(lo & FIELDINFO_TAG_TYPE_MASK) {
 130       case FIELDINFO_TAG_TYPE_PLAIN:
 131         return false;
 132       case FIELDINFO_TAG_TYPE_CONTENDED:
 133         return true;
 134 #ifndef PRODUCT
 135       case FIELDINFO_TAG_OFFSET:
 136         fatal("Asking contended flag for the field with offset");
 137       case FIELDINFO_TAG_BLANK:
 138         fatal("Asking contended flag for the blank field");
 139 #endif
 140     }
 141     ShouldNotReachHere();
 142     return false;
 143   }
 144 
 145   u2 contended_group() const {
 146     u2 lo = _shorts[low_packed_offset];
 147     switch(lo & FIELDINFO_TAG_TYPE_MASK) {
 148       case FIELDINFO_TAG_TYPE_PLAIN:
 149         return 0;
 150       case FIELDINFO_TAG_TYPE_CONTENDED:
 151         return _shorts[high_packed_offset];
 152 #ifndef PRODUCT
 153       case FIELDINFO_TAG_OFFSET:
 154         fatal("Asking the contended group for the field with offset");
 155       case FIELDINFO_TAG_BLANK:
 156         fatal("Asking the contended group for the blank field");
 157 #endif
 158     }
 159     ShouldNotReachHere();
 160     return 0;
 161  }
 162 
 163   u2 allocation_type() const {
 164     u2 lo = _shorts[low_packed_offset];
 165     switch(lo & FIELDINFO_TAG_TYPE_MASK) {
 166       case FIELDINFO_TAG_TYPE_PLAIN:
 167       case FIELDINFO_TAG_TYPE_CONTENDED:
 168         return (lo >> FIELDINFO_TAG_SIZE);
 169 #ifndef PRODUCT
 170       case FIELDINFO_TAG_OFFSET:
 171         fatal("Asking the field type for field with offset");
 172       case FIELDINFO_TAG_BLANK:
 173         fatal("Asking the field type for the blank field");
 174 #endif
 175     }
 176     ShouldNotReachHere();
 177     return 0;
 178   }
 179 
 180   bool is_offset_set() const {
 181     return (_shorts[low_packed_offset] & FIELDINFO_TAG_TYPE_MASK) == FIELDINFO_TAG_OFFSET;
 182   }
 183 
 184   Symbol* name(const constantPoolHandle& cp) const {
 185     int index = name_index();
 186     if (is_internal()) {
 187       return lookup_symbol(index);
 188     }
 189     return cp->symbol_at(index);
 190   }
 191 
 192   Symbol* signature(const constantPoolHandle& cp) const {
 193     int index = signature_index();
 194     if (is_internal()) {
 195       return lookup_symbol(index);
 196     }
 197     return cp->symbol_at(index);
 198   }
 199 
 200   void set_access_flags(u2 val)                  { _shorts[access_flags_offset] = val;             }
 201   void set_offset(u4 val)                        {
 202     val = val << FIELDINFO_TAG_SIZE; // make room for tag
 203     bool flattened = is_flattened();
 204     _shorts[low_packed_offset] = extract_low_short_from_int(val) | FIELDINFO_TAG_OFFSET;
 205     if (flattened) set_flattened(true);
 206     _shorts[high_packed_offset] = extract_high_short_from_int(val);
 207     assert(is_flattened() || !flattened, "just checking");
 208   }
 209 
 210   void set_allocation_type(int type) {
 211     bool b = is_flattened();
 212     u2 lo = _shorts[low_packed_offset];
 213     switch(lo & FIELDINFO_TAG_TYPE_MASK) {
 214       case FIELDINFO_TAG_BLANK:
 215         _shorts[low_packed_offset] |= ((type << FIELDINFO_TAG_SIZE)) & 0xFFFF;
 216         _shorts[low_packed_offset] &= ~FIELDINFO_TAG_TYPE_MASK;
 217         _shorts[low_packed_offset] |= FIELDINFO_TAG_TYPE_PLAIN;
 218         assert(is_flattened() || !b, "Just checking");
 219         return;
 220 #ifndef PRODUCT
 221       case FIELDINFO_TAG_TYPE_PLAIN:
 222       case FIELDINFO_TAG_TYPE_CONTENDED:
 223       case FIELDINFO_TAG_OFFSET:
 224         fatal("Setting the field type with overwriting");
 225 #endif
 226     }
 227     ShouldNotReachHere();
 228   }
 229 
 230   void set_flattened(bool b) {
 231     if (b) {
 232       _shorts[low_packed_offset] |= FIELDINFO_TAG_FLATTENED;
 233     } else {
 234       _shorts[low_packed_offset] &= ~FIELDINFO_TAG_FLATTENED;
 235     }
 236   }
 237 
 238   bool is_flattened() {
 239     return (_shorts[low_packed_offset] & FIELDINFO_TAG_FLATTENED) != 0;
 240   }
 241 
 242   void set_contended_group(u2 val) {
 243     u2 lo = _shorts[low_packed_offset];
 244     switch(lo & FIELDINFO_TAG_TYPE_MASK) {
 245       case FIELDINFO_TAG_TYPE_PLAIN:
 246         _shorts[low_packed_offset] |= FIELDINFO_TAG_TYPE_CONTENDED;
 247         _shorts[high_packed_offset] = val;
 248         return;
 249 #ifndef PRODUCT
 250       case FIELDINFO_TAG_TYPE_CONTENDED:
 251         fatal("Overwriting contended group");
 252       case FIELDINFO_TAG_BLANK:
 253         fatal("Setting contended group for the blank field");
 254       case FIELDINFO_TAG_OFFSET:
 255         fatal("Setting contended group for field with offset");
 256 #endif
 257     }
 258     ShouldNotReachHere();
 259   }
 260 
 261   bool is_internal() const {
 262     return (access_flags() & JVM_ACC_FIELD_INTERNAL) != 0;
 263   }
 264 
 265   bool is_stable() const {
 266     return (access_flags() & JVM_ACC_FIELD_STABLE) != 0;
 267   }
 268   void set_stable(bool z) {
 269     if (z) _shorts[access_flags_offset] |=  JVM_ACC_FIELD_STABLE;
 270     else   _shorts[access_flags_offset] &= ~JVM_ACC_FIELD_STABLE;
 271   }
 272 
 273   bool is_flattenable() const {
 274     return (access_flags() & JVM_ACC_FLATTENABLE) != 0;
 275   }
 276 
 277   Symbol* lookup_symbol(int symbol_index) const {
 278     assert(is_internal(), "only internal fields");
 279     return vmSymbols::symbol_at((vmSymbols::SID)symbol_index);
 280   }
 281 };
 282 
 283 #endif // SHARE_OOPS_FIELDINFO_HPP
< prev index next >