110 |
110 |
111 // This is an int because it needs atomic operation on the refcount. Mask length |
111 // This is an int because it needs atomic operation on the refcount. Mask length |
112 // in high half word. length is the number of UTF8 characters in the symbol |
112 // in high half word. length is the number of UTF8 characters in the symbol |
113 volatile uint32_t _length_and_refcount; |
113 volatile uint32_t _length_and_refcount; |
114 short _identity_hash; |
114 short _identity_hash; |
115 jbyte _body[2]; |
115 u1 _body[2]; |
116 |
116 |
117 enum { |
117 enum { |
118 // max_symbol_length must fit into the top 16 bits of _length_and_refcount |
118 // max_symbol_length must fit into the top 16 bits of _length_and_refcount |
119 max_symbol_length = (1 << 16) -1 |
119 max_symbol_length = (1 << 16) -1 |
120 }; |
120 }; |
126 static int size(int length) { |
126 static int size(int length) { |
127 // minimum number of natural words needed to hold these bits (no non-heap version) |
127 // minimum number of natural words needed to hold these bits (no non-heap version) |
128 return (int)heap_word_size(byte_size(length)); |
128 return (int)heap_word_size(byte_size(length)); |
129 } |
129 } |
130 |
130 |
131 void byte_at_put(int index, int value) { |
131 void byte_at_put(int index, u1 value) { |
132 assert(index >=0 && index < length(), "symbol index overflow"); |
132 assert(index >=0 && index < length(), "symbol index overflow"); |
133 _body[index] = value; |
133 _body[index] = value; |
134 } |
134 } |
135 |
135 |
136 Symbol(const u1* name, int length, int refcount); |
136 Symbol(const u1* name, int length, int refcount); |
146 |
146 |
147 int length() const { return extract_length(_length_and_refcount); } |
147 int length() const { return extract_length(_length_and_refcount); } |
148 |
148 |
149 public: |
149 public: |
150 // Low-level access (used with care, since not GC-safe) |
150 // Low-level access (used with care, since not GC-safe) |
151 const jbyte* base() const { return &_body[0]; } |
151 const u1* base() const { return &_body[0]; } |
152 |
152 |
153 int size() { return size(utf8_length()); } |
153 int size() { return size(utf8_length()); } |
154 int byte_size() { return byte_size(utf8_length()); } |
154 int byte_size() { return byte_size(utf8_length()); } |
155 |
155 |
156 // Symbols should be stored in the read-only region of CDS archive. |
156 // Symbols should be stored in the read-only region of CDS archive. |
174 void decrement_refcount(); |
174 void decrement_refcount(); |
175 bool is_permanent() { |
175 bool is_permanent() { |
176 return (refcount() == PERM_REFCOUNT); |
176 return (refcount() == PERM_REFCOUNT); |
177 } |
177 } |
178 |
178 |
179 int byte_at(int index) const { |
179 // Function char_at() returns the Symbol's selected u1 byte as a char type. |
|
180 // |
|
181 // Note that all multi-byte chars have the sign bit set on all their bytes. |
|
182 // No single byte chars have their sign bit set. |
|
183 char char_at(int index) const { |
180 assert(index >=0 && index < length(), "symbol index overflow"); |
184 assert(index >=0 && index < length(), "symbol index overflow"); |
181 return base()[index]; |
185 return (char)base()[index]; |
182 } |
186 } |
183 |
187 |
184 const jbyte* bytes() const { return base(); } |
188 const u1* bytes() const { return base(); } |
185 |
189 |
186 int utf8_length() const { return length(); } |
190 int utf8_length() const { return length(); } |
187 |
191 |
188 // Compares the symbol with a string. |
192 // Compares the symbol with a string. |
189 bool equals(const char* str, int len) const { |
193 bool equals(const char* str, int len) const { |
190 int l = utf8_length(); |
194 int l = utf8_length(); |
191 if (l != len) return false; |
195 if (l != len) return false; |
192 while (l-- > 0) { |
196 while (l-- > 0) { |
193 if (str[l] != (char) byte_at(l)) |
197 if (str[l] != char_at(l)) |
194 return false; |
198 return false; |
195 } |
199 } |
196 assert(l == -1, "we should be at the beginning"); |
200 assert(l == -1, "we should be at the beginning"); |
197 return true; |
201 return true; |
198 } |
202 } |