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
|