143 vm_exit_during_initialization("Invalid layout of well-known class: use -Xlog:class+load=info to see the origin of the problem class");
144 }
145 dest_offset = fd.offset();
146 }
147
148 // Overloading to pass name as a string.
149 static void compute_offset(int& dest_offset, InstanceKlass* ik,
150 const char* name_string, Symbol* signature_symbol,
151 bool is_static = false) {
152 TempNewSymbol name = SymbolTable::probe(name_string, (int)strlen(name_string));
153 if (name == NULL) {
154 ResourceMark rm;
155 log_error(class)("Name %s should be in the SymbolTable since its class is loaded", name_string);
156 vm_exit_during_initialization("Invalid layout of well-known class", ik->external_name());
157 }
158 compute_offset(dest_offset, ik, name, signature_symbol, is_static);
159 }
160
161 int java_lang_String::value_offset = 0;
162 int java_lang_String::hash_offset = 0;
163 int java_lang_String::hashIsZero_offset = 0;
164 int java_lang_String::coder_offset = 0;
165
166 bool java_lang_String::initialized = false;
167
168 bool java_lang_String::is_instance(oop obj) {
169 return is_instance_inlined(obj);
170 }
171
172 #if INCLUDE_CDS
173 #define FIELD_SERIALIZE_OFFSET(offset, klass, name, signature, is_static) \
174 f->do_u4((u4*)&offset)
175 #endif
176
177 #define FIELD_COMPUTE_OFFSET(offset, klass, name, signature, is_static) \
178 compute_offset(offset, klass, name, vmSymbols::signature(), is_static)
179
180 #define STRING_FIELDS_DO(macro) \
181 macro(value_offset, k, vmSymbols::value_name(), byte_array_signature, false); \
182 macro(hash_offset, k, "hash", int_signature, false); \
183 macro(hashIsZero_offset, k, "hashIsZero", bool_signature, false); \
184 macro(coder_offset, k, "coder", byte_signature, false);
185
186 void java_lang_String::compute_offsets() {
187 if (initialized) {
188 return;
189 }
190
191 InstanceKlass* k = SystemDictionary::String_klass();
192 STRING_FIELDS_DO(FIELD_COMPUTE_OFFSET);
193
194 initialized = true;
195 }
196
197 #if INCLUDE_CDS
198 void java_lang_String::serialize_offsets(SerializeClosure* f) {
199 STRING_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
200 f->do_u4((u4*)&initialized);
201 }
202 #endif
203
204 class CompactStringsFixup : public FieldClosure {
492 bool is_latin1 = java_lang_String::is_latin1(java_string);
493
494 jchar* result = NEW_RESOURCE_ARRAY_RETURN_NULL(jchar, length);
495 if (result != NULL) {
496 if (!is_latin1) {
497 for (int index = 0; index < length; index++) {
498 result[index] = value->char_at(index);
499 }
500 } else {
501 for (int index = 0; index < length; index++) {
502 result[index] = ((jchar) value->byte_at(index)) & 0xff;
503 }
504 }
505 } else {
506 THROW_MSG_0(vmSymbols::java_lang_OutOfMemoryError(), "could not allocate Unicode string");
507 }
508 return result;
509 }
510
511 unsigned int java_lang_String::hash_code(oop java_string) {
512 // The hash and hashIsZero fields are subject to a benign data race,
513 // making it crucial to ensure that any observable result of the
514 // calculation in this method stays correct under any possible read of
515 // these fields. Necessary restrictions to allow this to be correct
516 // without explicit memory fences or similar concurrency primitives is
517 // that we can ever only write to one of these two fields for a given
518 // String instance, and that the computation is idempotent and derived
519 // from immutable state
520 assert(initialized && (hash_offset > 0) && (hashIsZero_offset > 0), "Must be initialized");
521 if (java_lang_String::hash_is_set(java_string)) {
522 return java_string->int_field(hash_offset);
523 }
524
525 typeArrayOop value = java_lang_String::value(java_string);
526 int length = java_lang_String::length(java_string, value);
527 bool is_latin1 = java_lang_String::is_latin1(java_string);
528
529 unsigned int hash = 0;
530 if (length > 0) {
531 if (is_latin1) {
532 hash = java_lang_String::hash_code(value->byte_at_addr(0), length);
533 } else {
534 hash = java_lang_String::hash_code(value->char_at_addr(0), length);
535 }
536 }
537
538 if (hash != 0) {
539 java_string->int_field_put(hash_offset, hash);
540 } else {
541 java_string->bool_field_put(hashIsZero_offset, true);
542 }
543 return hash;
544 }
545
546 char* java_lang_String::as_quoted_ascii(oop java_string) {
547 typeArrayOop value = java_lang_String::value(java_string);
548 int length = java_lang_String::length(java_string, value);
549 bool is_latin1 = java_lang_String::is_latin1(java_string);
550
551 if (length == 0) return NULL;
552
553 char* result;
554 int result_length;
555 if (!is_latin1) {
556 jchar* base = value->char_at_addr(0);
557 result_length = UNICODE::quoted_ascii_length(base, length) + 1;
558 result = NEW_RESOURCE_ARRAY(char, result_length);
559 UNICODE::as_quoted_ascii(base, length, result, result_length);
560 } else {
561 jbyte* base = value->byte_at_addr(0);
562 result_length = UNICODE::quoted_ascii_length(base, length) + 1;
563 result = NEW_RESOURCE_ARRAY(char, result_length);
|
143 vm_exit_during_initialization("Invalid layout of well-known class: use -Xlog:class+load=info to see the origin of the problem class");
144 }
145 dest_offset = fd.offset();
146 }
147
148 // Overloading to pass name as a string.
149 static void compute_offset(int& dest_offset, InstanceKlass* ik,
150 const char* name_string, Symbol* signature_symbol,
151 bool is_static = false) {
152 TempNewSymbol name = SymbolTable::probe(name_string, (int)strlen(name_string));
153 if (name == NULL) {
154 ResourceMark rm;
155 log_error(class)("Name %s should be in the SymbolTable since its class is loaded", name_string);
156 vm_exit_during_initialization("Invalid layout of well-known class", ik->external_name());
157 }
158 compute_offset(dest_offset, ik, name, signature_symbol, is_static);
159 }
160
161 int java_lang_String::value_offset = 0;
162 int java_lang_String::hash_offset = 0;
163 int java_lang_String::coder_offset = 0;
164
165 bool java_lang_String::initialized = false;
166
167 bool java_lang_String::is_instance(oop obj) {
168 return is_instance_inlined(obj);
169 }
170
171 #if INCLUDE_CDS
172 #define FIELD_SERIALIZE_OFFSET(offset, klass, name, signature, is_static) \
173 f->do_u4((u4*)&offset)
174 #endif
175
176 #define FIELD_COMPUTE_OFFSET(offset, klass, name, signature, is_static) \
177 compute_offset(offset, klass, name, vmSymbols::signature(), is_static)
178
179 #define STRING_FIELDS_DO(macro) \
180 macro(value_offset, k, vmSymbols::value_name(), byte_array_signature, false); \
181 macro(hash_offset, k, "hash", int_signature, false); \
182 macro(coder_offset, k, "coder", byte_signature, false)
183
184 void java_lang_String::compute_offsets() {
185 if (initialized) {
186 return;
187 }
188
189 InstanceKlass* k = SystemDictionary::String_klass();
190 STRING_FIELDS_DO(FIELD_COMPUTE_OFFSET);
191
192 initialized = true;
193 }
194
195 #if INCLUDE_CDS
196 void java_lang_String::serialize_offsets(SerializeClosure* f) {
197 STRING_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
198 f->do_u4((u4*)&initialized);
199 }
200 #endif
201
202 class CompactStringsFixup : public FieldClosure {
490 bool is_latin1 = java_lang_String::is_latin1(java_string);
491
492 jchar* result = NEW_RESOURCE_ARRAY_RETURN_NULL(jchar, length);
493 if (result != NULL) {
494 if (!is_latin1) {
495 for (int index = 0; index < length; index++) {
496 result[index] = value->char_at(index);
497 }
498 } else {
499 for (int index = 0; index < length; index++) {
500 result[index] = ((jchar) value->byte_at(index)) & 0xff;
501 }
502 }
503 } else {
504 THROW_MSG_0(vmSymbols::java_lang_OutOfMemoryError(), "could not allocate Unicode string");
505 }
506 return result;
507 }
508
509 unsigned int java_lang_String::hash_code(oop java_string) {
510 typeArrayOop value = java_lang_String::value(java_string);
511 int length = java_lang_String::length(java_string, value);
512 // Zero length string will hash to zero with String.hashCode() function.
513 if (length == 0) return 0;
514
515 bool is_latin1 = java_lang_String::is_latin1(java_string);
516
517 if (is_latin1) {
518 return java_lang_String::hash_code(value->byte_at_addr(0), length);
519 } else {
520 return java_lang_String::hash_code(value->char_at_addr(0), length);
521 }
522 }
523
524 char* java_lang_String::as_quoted_ascii(oop java_string) {
525 typeArrayOop value = java_lang_String::value(java_string);
526 int length = java_lang_String::length(java_string, value);
527 bool is_latin1 = java_lang_String::is_latin1(java_string);
528
529 if (length == 0) return NULL;
530
531 char* result;
532 int result_length;
533 if (!is_latin1) {
534 jchar* base = value->char_at_addr(0);
535 result_length = UNICODE::quoted_ascii_length(base, length) + 1;
536 result = NEW_RESOURCE_ARRAY(char, result_length);
537 UNICODE::as_quoted_ascii(base, length, result, result_length);
538 } else {
539 jbyte* base = value->byte_at_addr(0);
540 result_length = UNICODE::quoted_ascii_length(base, length) + 1;
541 result = NEW_RESOURCE_ARRAY(char, result_length);
|