src/share/vm/oops/constantPool.hpp

Print this page




  68 
  69 class KlassSizeStats;
  70 
  71 class ConstantPool : public Metadata {
  72   friend class VMStructs;
  73   friend class BytecodeInterpreter;  // Directly extracts a klass in the pool for fast instanceof/checkcast
  74   friend class Universe;             // For null constructor
  75  private:
  76   Array<u1>*           _tags;        // the tag array describing the constant pool's contents
  77   ConstantPoolCache*   _cache;       // the cache holding interpreter runtime information
  78   InstanceKlass*       _pool_holder; // the corresponding class
  79   Array<u2>*           _operands;    // for variable-sized (InvokeDynamic) nodes, usually empty
  80 
  81   // Array of resolved objects from the constant pool and map from resolved
  82   // object index to original constant pool index
  83   jobject              _resolved_references;
  84   Array<u2>*           _reference_map;
  85 
  86   enum {
  87     _has_preresolution = 1,           // Flags
  88     _on_stack          = 2

  89   };
  90 
  91   int                  _flags;  // old fashioned bit twiddling
  92   int                  _length; // number of elements in the array
  93 
  94   union {
  95     // set for CDS to restore resolved references
  96     int                _resolved_reference_length;
  97     // keeps version number for redefined classes (used in backtrace)
  98     int                _version;
  99   } _saved;
 100 
 101   void set_tags(Array<u1>* tags)               { _tags = tags; }
 102   void tag_at_put(int which, jbyte t)          { tags()->at_put(which, t); }
 103   void release_tag_at_put(int which, jbyte t)  { tags()->release_at_put(which, t); }
 104 
 105   u1* tag_addr_at(int which) const             { return tags()->adr_at(which); }
 106 
 107   void set_operands(Array<u2>* operands)       { _operands = operands; }
 108 
 109   int flags() const                            { return _flags; }
 110   void set_flags(int f)                        { _flags = f; }
 111 
 112  private:
 113   intptr_t* base() const { return (intptr_t*) (((char*) this) + sizeof(ConstantPool)); }



 114 





 115   CPSlot slot_at(int which) {
 116     assert(is_within_bounds(which), "index out of bounds");
 117     // Uses volatile because the klass slot changes without a lock.
 118     volatile intptr_t adr = (intptr_t)OrderAccess::load_ptr_acquire(obj_at_addr_raw(which));
 119     assert(adr != 0 || which == 0, "cp entry for klass should not be zero");
 120     return CPSlot(adr);
 121   }
 122 
 123   void slot_at_put(int which, CPSlot s) const {
 124     assert(is_within_bounds(which), "index out of bounds");
 125     assert(s.value() != 0, "Caught something");
 126     *(intptr_t*)&base()[which] = s.value();
 127   }
 128   intptr_t* obj_at_addr_raw(int which) const {
 129     assert(is_within_bounds(which), "index out of bounds");
 130     return (intptr_t*) &base()[which];
 131   }
 132 
 133   jint* int_at_addr(int which) const {
 134     assert(is_within_bounds(which), "index out of bounds");
 135     return (jint*) &base()[which];
 136   }
 137 
 138   jlong* long_at_addr(int which) const {
 139     assert(is_within_bounds(which), "index out of bounds");
 140     return (jlong*) &base()[which];
 141   }
 142 
 143   jfloat* float_at_addr(int which) const {
 144     assert(is_within_bounds(which), "index out of bounds");
 145     return (jfloat*) &base()[which];
 146   }
 147 
 148   jdouble* double_at_addr(int which) const {
 149     assert(is_within_bounds(which), "index out of bounds");
 150     return (jdouble*) &base()[which];
 151   }
 152 
 153   ConstantPool(Array<u1>* tags);
 154   ConstantPool() { assert(DumpSharedSpaces || UseSharedSpaces, "only for CDS"); }
 155  public:
 156   static ConstantPool* allocate(ClassLoaderData* loader_data, int length, TRAPS);
 157 
 158   bool is_constantPool() const volatile     { return true; }
 159 
 160   Array<u1>* tags() const                   { return _tags; }
 161   Array<u2>* operands() const               { return _operands; }
 162 















































 163   bool has_preresolution() const            { return (_flags & _has_preresolution) != 0; }
 164   void set_has_preresolution()              { _flags |= _has_preresolution; }
 165 
 166   // Redefine classes support.  If a method refering to this constant pool
 167   // is on the executing stack, or as a handle in vm code, this constant pool
 168   // can't be removed from the set of previous versions saved in the instance
 169   // class.
 170   bool on_stack() const                      { return (_flags &_on_stack) != 0; }
 171   void set_on_stack(const bool value);
 172 




 173   // Klass holding pool
 174   InstanceKlass* pool_holder() const      { return _pool_holder; }
 175   void set_pool_holder(InstanceKlass* k)  { _pool_holder = k; }
 176   InstanceKlass** pool_holder_addr()      { return &_pool_holder; }
 177 
 178   // Interpreter runtime support
 179   ConstantPoolCache* cache() const        { return _cache; }
 180   void set_cache(ConstantPoolCache* cache){ _cache = cache; }
 181 
 182   // Create object cache in the constant pool
 183   void initialize_resolved_references(ClassLoaderData* loader_data,
 184                                       intStack reference_map,
 185                                       int constant_pool_map_length,
 186                                       TRAPS);
 187 
 188   // resolved strings, methodHandles and callsite objects from the constant pool
 189   objArrayOop resolved_references()  const;
 190   // mapping resolved object array indexes to cp indexes and back.
 191   int object_to_cp_index(int index)         { return _reference_map->at(index); }
 192   int cp_to_object_index(int index);




  68 
  69 class KlassSizeStats;
  70 
  71 class ConstantPool : public Metadata {
  72   friend class VMStructs;
  73   friend class BytecodeInterpreter;  // Directly extracts a klass in the pool for fast instanceof/checkcast
  74   friend class Universe;             // For null constructor
  75  private:
  76   Array<u1>*           _tags;        // the tag array describing the constant pool's contents
  77   ConstantPoolCache*   _cache;       // the cache holding interpreter runtime information
  78   InstanceKlass*       _pool_holder; // the corresponding class
  79   Array<u2>*           _operands;    // for variable-sized (InvokeDynamic) nodes, usually empty
  80 
  81   // Array of resolved objects from the constant pool and map from resolved
  82   // object index to original constant pool index
  83   jobject              _resolved_references;
  84   Array<u2>*           _reference_map;
  85 
  86   enum {
  87     _has_preresolution = 1,           // Flags
  88     _on_stack          = 2,
  89     _patched           = 4
  90   };
  91 
  92   int                  _flags;  // old fashioned bit twiddling
  93   int                  _length; // number of elements in the array
  94 
  95   union {
  96     // set for CDS to restore resolved references
  97     int                _resolved_reference_length;
  98     // keeps version number for redefined classes (used in backtrace)
  99     int                _version;
 100   } _saved;
 101 
 102   void set_tags(Array<u1>* tags)               { _tags = tags; }
 103   void tag_at_put(int which, jbyte t)          { tags()->at_put(which, t); }
 104   void release_tag_at_put(int which, jbyte t)  { tags()->release_at_put(which, t); }
 105 
 106   u1* tag_addr_at(int which) const             { return tags()->adr_at(which); }
 107 
 108   void set_operands(Array<u2>* operands)       { _operands = operands; }
 109 
 110   int flags() const                            { return _flags; }
 111   void set_flags(int f)                        { _flags = f; }
 112 
 113  private:
 114   intptr_t* base() const {
 115     // If the cp is patched then account for an optional pseudo-string map field
 116     return (intptr_t*) (((char*) this) + sizeof(ConstantPool) + (patched() ? sizeof(intptr_t) : 0));
 117   }
 118 
 119   GrowableArray<u4>** pseudo_string_map_addr() {
 120     // The pseudo-string map filed is optional, return NULL if the cp is not patched
 121     return (GrowableArray<u4>**) (patched() ? (((char*) this) + sizeof(ConstantPool)) : NULL);
 122   }
 123 
 124   CPSlot slot_at(int which) {
 125     assert(is_within_bounds(which), "index out of bounds");
 126     // Uses volatile because the klass slot changes without a lock.
 127     volatile intptr_t adr = (intptr_t)OrderAccess::load_ptr_acquire(obj_at_addr_raw(which));
 128     assert(adr != 0 || which == 0, "cp entry for klass should not be zero");
 129     return CPSlot(adr);
 130   }
 131 
 132   void slot_at_put(int which, CPSlot s) const {
 133     assert(is_within_bounds(which), "index out of bounds");
 134     assert(s.value() != 0, "Caught something");
 135     *(intptr_t*)&base()[which] = s.value();
 136   }
 137   intptr_t* obj_at_addr_raw(int which) const {
 138     assert(is_within_bounds(which), "index out of bounds");
 139     return (intptr_t*) &base()[which];
 140   }
 141 
 142   jint* int_at_addr(int which) const {
 143     assert(is_within_bounds(which), "index out of bounds");
 144     return (jint*) &base()[which];
 145   }
 146 
 147   jlong* long_at_addr(int which) const {
 148     assert(is_within_bounds(which), "index out of bounds");
 149     return (jlong*) &base()[which];
 150   }
 151 
 152   jfloat* float_at_addr(int which) const {
 153     assert(is_within_bounds(which), "index out of bounds");
 154     return (jfloat*) &base()[which];
 155   }
 156 
 157   jdouble* double_at_addr(int which) const {
 158     assert(is_within_bounds(which), "index out of bounds");
 159     return (jdouble*) &base()[which];
 160   }
 161 
 162   ConstantPool(Array<u1>* tags, bool patched);
 163   ConstantPool() { assert(DumpSharedSpaces || UseSharedSpaces, "only for CDS"); }
 164  public:
 165   static ConstantPool* allocate(ClassLoaderData* loader_data, int length, bool patched, TRAPS);
 166 
 167   bool is_constantPool() const volatile     { return true; }
 168 
 169   Array<u1>* tags() const                   { return _tags; }
 170   Array<u2>* operands() const               { return _operands; }
 171 
 172   // The pseudo_string_map is optional filed.
 173   // It is needed for JvmtiConstantPoolReconstituter.
 174   // Map from a pseudo-string index to the original Utf8 entry index.
 175   // Each u4 entry consist of two packed u2 integers:
 176   //   JVM_CONSTANT_String index and JVM_CONSTANT_Utf8 index
 177 
 178   GrowableArray<u4>* pseudo_string_map() {
 179     if (!patched()) {
 180       return (GrowableArray<u4>*) NULL;
 181     }
 182     GrowableArray<u4>** addr = pseudo_string_map_addr();
 183     if (*addr == NULL) {
 184      *addr = new(ResourceObj::C_HEAP, mtClass) GrowableArray<u4>(1, true);
 185     }
 186     return *addr;
 187   }
 188 
 189   void map_pseudo_string_indices(u2 index, u2 utf8_idx) {
 190     if (!patched()) {
 191       return;
 192     }
 193     u4 packed = index << 16 | utf8_idx;
 194     pseudo_string_map()->append(packed);
 195   }
 196 
 197   u2 get_pseudo_string_utf8_index(u2 index) {
 198     if (!patched()) {
 199       assert(false, "a pseudo-string map may exists for patched CP only");
 200       return 0;
 201     }
 202     GrowableArray<u4>* map = pseudo_string_map();
 203     int len = map->length();
 204     // The entries are ordered by value so that a binary search can be
 205     // used if a performance bottleneck is observed in this area.
 206     for (int i = 0; i < len; i++) {
 207       u4 packed = map->at(i);
 208       u2 idx = (packed >> 16) & 0xFF;
 209       if (idx == index) {
 210         u2 utf8_idx = packed & 0xFF;
 211         assert(utf8_idx > 0, "Utf8 index in pseudo-string map must be positive");
 212         return utf8_idx;
 213       }
 214     }
 215     assert(true, "not found a matching entry in pseudo-string map");
 216     return 0;
 217   }
 218 
 219   bool has_preresolution() const            { return (_flags & _has_preresolution) != 0; }
 220   void set_has_preresolution()              { _flags |= _has_preresolution; }
 221 
 222   // Redefine classes support.  If a method refering to this constant pool
 223   // is on the executing stack, or as a handle in vm code, this constant pool
 224   // can't be removed from the set of previous versions saved in the instance
 225   // class.
 226   bool on_stack() const                      { return (_flags &_on_stack) != 0; }
 227   void set_on_stack(const bool value);
 228 
 229   bool patched() const                    { return (_flags &_patched) != 0; }
 230   void set_patched(const bool value)      { if (value) _flags |= _patched;
 231                                             else       _flags &= ~_patched; }
 232 
 233   // Klass holding pool
 234   InstanceKlass* pool_holder() const      { return _pool_holder; }
 235   void set_pool_holder(InstanceKlass* k)  { _pool_holder = k; }
 236   InstanceKlass** pool_holder_addr()      { return &_pool_holder; }
 237 
 238   // Interpreter runtime support
 239   ConstantPoolCache* cache() const        { return _cache; }
 240   void set_cache(ConstantPoolCache* cache){ _cache = cache; }
 241 
 242   // Create object cache in the constant pool
 243   void initialize_resolved_references(ClassLoaderData* loader_data,
 244                                       intStack reference_map,
 245                                       int constant_pool_map_length,
 246                                       TRAPS);
 247 
 248   // resolved strings, methodHandles and callsite objects from the constant pool
 249   objArrayOop resolved_references()  const;
 250   // mapping resolved object array indexes to cp indexes and back.
 251   int object_to_cp_index(int index)         { return _reference_map->at(index); }
 252   int cp_to_object_index(int index);