< prev index next >

src/share/vm/oops/symbol.hpp

Print this page


 102 #endif
 103 
 104 class Symbol : public MetaspaceObj {
 105   friend class VMStructs;
 106   friend class SymbolTable;
 107   friend class MoveSymbols;
 108 
 109  private:
 110   ATOMIC_SHORT_PAIR(
 111     volatile short _refcount,  // needs atomic operation
 112     unsigned short _length     // number of UTF8 characters in the symbol (does not need atomic op)
 113   );
 114   short _identity_hash;
 115   jbyte _body[2];
 116 
 117   enum {
 118     // max_symbol_length is constrained by type of _length
 119     max_symbol_length = (1 << 16) -1
 120   };
 121 




 122   static int size(int length) {
 123     // minimum number of natural words needed to hold these bits (no non-heap version)
 124     return (int)heap_word_size(sizeof(Symbol) + (length > 2 ? length - 2 : 0));
 125   }
 126 
 127   void byte_at_put(int index, int value) {
 128     assert(index >=0 && index < _length, "symbol index overflow");
 129     _body[index] = value;
 130   }
 131 
 132   Symbol(const u1* name, int length, int refcount);
 133   void* operator new(size_t size, int len, TRAPS) throw();
 134   void* operator new(size_t size, int len, Arena* arena, TRAPS) throw();
 135   void* operator new(size_t size, int len, ClassLoaderData* loader_data, TRAPS) throw();
 136 
 137   void  operator delete(void* p);
 138 
 139  public:
 140   // Low-level access (used with care, since not GC-safe)
 141   const jbyte* base() const { return &_body[0]; }
 142 
 143   int size()                { return size(utf8_length()); }




 144 
 145   // Returns the largest size symbol we can safely hold.
 146   static int max_length() { return max_symbol_length; }
 147   unsigned identity_hash() const {
 148     unsigned addr_bits = (unsigned)((uintptr_t)this >> (LogMinObjAlignmentInBytes + 3));
 149     return ((unsigned)_identity_hash & 0xffff) |
 150            ((addr_bits ^ (_length << 8) ^ (( _body[0] << 8) | _body[1])) << 16);
 151   }
 152 
 153   // For symbol table alternate hashing
 154   unsigned int new_hash(juint seed);
 155 
 156   // Reference counting.  See comments above this class for when to use.
 157   int refcount() const      { return _refcount; }
 158   void increment_refcount();
 159   void decrement_refcount();
 160   // Set _refcount non zero to avoid being reclaimed by GC.
 161   void set_permanent() {
 162     assert(LogTouchedMethods, "Should not be called with LogTouchedMethods off");
 163     if (_refcount != PERM_REFCOUNT) {
 164       _refcount = PERM_REFCOUNT;
 165     }
 166   }



 167 
 168   int byte_at(int index) const {
 169     assert(index >=0 && index < _length, "symbol index overflow");
 170     return base()[index];
 171   }
 172 
 173   const jbyte* bytes() const { return base(); }
 174 
 175   int utf8_length() const { return _length; }
 176 
 177   // Compares the symbol with a string.
 178   bool equals(const char* str, int len) const {
 179     int l = utf8_length();
 180     if (l != len) return false;
 181     while (l-- > 0) {
 182       if (str[l] != (char) byte_at(l))
 183         return false;
 184     }
 185     assert(l == -1, "we should be at the beginning");
 186     return true;


 209   char* as_C_string(char* buf, int size) const;
 210   // Use buf if needed buffer length is <= size.
 211   char* as_C_string_flexible_buffer(Thread* t, char* buf, int size) const;
 212 
 213   // Returns an escaped form of a Java string.
 214   char* as_quoted_ascii() const;
 215 
 216   // Returns a null terminated utf8 string in a resource array
 217   char* as_utf8() const { return as_C_string(); }
 218   char* as_utf8_flexible_buffer(Thread* t, char* buf, int size) const {
 219     return as_C_string_flexible_buffer(t, buf, size);
 220   }
 221 
 222   jchar* as_unicode(int& length) const;
 223 
 224   // Treating this symbol as a class name, returns the Java name for the class.
 225   // String is allocated in resource area if buffer is not provided.
 226   // See Klass::external_name()
 227   const char* as_klass_external_name() const;
 228   const char* as_klass_external_name(char* buf, int size) const;



 229 
 230   // Printing
 231   void print_symbol_on(outputStream* st = NULL) const;
 232   void print_utf8_on(outputStream* st) const;
 233   void print_on(outputStream* st) const;         // First level print
 234   void print_value_on(outputStream* st) const;   // Second level print.
 235 
 236   // printing on default output stream
 237   void print()         { print_on(tty);       }
 238   void print_value()   { print_value_on(tty); }
 239 
 240 #ifndef PRODUCT
 241   // Empty constructor to create a dummy symbol object on stack
 242   // only for getting its vtable pointer.
 243   Symbol() { }
 244 
 245   static int _total_count;
 246 #endif
 247 };
 248 


 102 #endif
 103 
 104 class Symbol : public MetaspaceObj {
 105   friend class VMStructs;
 106   friend class SymbolTable;
 107   friend class MoveSymbols;
 108 
 109  private:
 110   ATOMIC_SHORT_PAIR(
 111     volatile short _refcount,  // needs atomic operation
 112     unsigned short _length     // number of UTF8 characters in the symbol (does not need atomic op)
 113   );
 114   short _identity_hash;
 115   jbyte _body[2];
 116 
 117   enum {
 118     // max_symbol_length is constrained by type of _length
 119     max_symbol_length = (1 << 16) -1
 120   };
 121 
 122   static int byte_size(int length) {
 123     // minimum number of natural words needed to hold these bits (no non-heap version)
 124     return (int)(sizeof(Symbol) + (length > 2 ? length - 2 : 0));
 125   }
 126   static int size(int length) {
 127     // minimum number of natural words needed to hold these bits (no non-heap version)
 128     return (int)heap_word_size(byte_size(length));
 129   }
 130 
 131   void byte_at_put(int index, int value) {
 132     assert(index >=0 && index < _length, "symbol index overflow");
 133     _body[index] = value;
 134   }
 135 
 136   Symbol(const u1* name, int length, int refcount);
 137   void* operator new(size_t size, int len, TRAPS) throw();
 138   void* operator new(size_t size, int len, Arena* arena, TRAPS) throw();
 139   void* operator new(size_t size, int len, ClassLoaderData* loader_data, TRAPS) throw();
 140 
 141   void  operator delete(void* p);
 142 
 143  public:
 144   // Low-level access (used with care, since not GC-safe)
 145   const jbyte* base() const { return &_body[0]; }
 146 
 147   int size()                { return size(utf8_length()); }
 148   int byte_size()           { return byte_size(utf8_length()); }
 149 
 150   // Symbols should be stored in the read-only region of CDS archive.
 151   static bool is_read_only_by_default() { return true; }
 152 
 153   // Returns the largest size symbol we can safely hold.
 154   static int max_length() { return max_symbol_length; }
 155   unsigned identity_hash() const {
 156     unsigned addr_bits = (unsigned)((uintptr_t)this >> (LogMinObjAlignmentInBytes + 3));
 157     return ((unsigned)_identity_hash & 0xffff) |
 158            ((addr_bits ^ (_length << 8) ^ (( _body[0] << 8) | _body[1])) << 16);
 159   }
 160 
 161   // For symbol table alternate hashing
 162   unsigned int new_hash(juint seed);
 163 
 164   // Reference counting.  See comments above this class for when to use.
 165   int refcount() const      { return _refcount; }
 166   void increment_refcount();
 167   void decrement_refcount();
 168   // Set _refcount non zero to avoid being reclaimed by GC.
 169   void set_permanent() {
 170     assert(LogTouchedMethods, "Should not be called with LogTouchedMethods off");
 171     if (_refcount != PERM_REFCOUNT) {
 172       _refcount = PERM_REFCOUNT;
 173     }
 174   }
 175   bool is_permanent() {
 176     return (_refcount == PERM_REFCOUNT);
 177   }
 178 
 179   int byte_at(int index) const {
 180     assert(index >=0 && index < _length, "symbol index overflow");
 181     return base()[index];
 182   }
 183 
 184   const jbyte* bytes() const { return base(); }
 185 
 186   int utf8_length() const { return _length; }
 187 
 188   // Compares the symbol with a string.
 189   bool equals(const char* str, int len) const {
 190     int l = utf8_length();
 191     if (l != len) return false;
 192     while (l-- > 0) {
 193       if (str[l] != (char) byte_at(l))
 194         return false;
 195     }
 196     assert(l == -1, "we should be at the beginning");
 197     return true;


 220   char* as_C_string(char* buf, int size) const;
 221   // Use buf if needed buffer length is <= size.
 222   char* as_C_string_flexible_buffer(Thread* t, char* buf, int size) const;
 223 
 224   // Returns an escaped form of a Java string.
 225   char* as_quoted_ascii() const;
 226 
 227   // Returns a null terminated utf8 string in a resource array
 228   char* as_utf8() const { return as_C_string(); }
 229   char* as_utf8_flexible_buffer(Thread* t, char* buf, int size) const {
 230     return as_C_string_flexible_buffer(t, buf, size);
 231   }
 232 
 233   jchar* as_unicode(int& length) const;
 234 
 235   // Treating this symbol as a class name, returns the Java name for the class.
 236   // String is allocated in resource area if buffer is not provided.
 237   // See Klass::external_name()
 238   const char* as_klass_external_name() const;
 239   const char* as_klass_external_name(char* buf, int size) const;
 240 
 241   void metaspace_pointers_do(MetaspaceClosure* it);
 242   MetaspaceObj::Type type() const { return SymbolType; }
 243 
 244   // Printing
 245   void print_symbol_on(outputStream* st = NULL) const;
 246   void print_utf8_on(outputStream* st) const;
 247   void print_on(outputStream* st) const;         // First level print
 248   void print_value_on(outputStream* st) const;   // Second level print.
 249 
 250   // printing on default output stream
 251   void print()         { print_on(tty);       }
 252   void print_value()   { print_value_on(tty); }
 253 
 254 #ifndef PRODUCT
 255   // Empty constructor to create a dummy symbol object on stack
 256   // only for getting its vtable pointer.
 257   Symbol() { }
 258 
 259   static int _total_count;
 260 #endif
 261 };
 262 
< prev index next >