158 compute_offset(dest_offset, ik, name, signature_symbol, is_static); |
158 compute_offset(dest_offset, ik, name, signature_symbol, is_static); |
159 } |
159 } |
160 |
160 |
161 int java_lang_String::value_offset = 0; |
161 int java_lang_String::value_offset = 0; |
162 int java_lang_String::hash_offset = 0; |
162 int java_lang_String::hash_offset = 0; |
|
163 int java_lang_String::hashIsZero_offset = 0; |
163 int java_lang_String::coder_offset = 0; |
164 int java_lang_String::coder_offset = 0; |
164 |
165 |
165 bool java_lang_String::initialized = false; |
166 bool java_lang_String::initialized = false; |
166 |
167 |
167 bool java_lang_String::is_instance(oop obj) { |
168 bool java_lang_String::is_instance(oop obj) { |
177 compute_offset(offset, klass, name, vmSymbols::signature(), is_static) |
178 compute_offset(offset, klass, name, vmSymbols::signature(), is_static) |
178 |
179 |
179 #define STRING_FIELDS_DO(macro) \ |
180 #define STRING_FIELDS_DO(macro) \ |
180 macro(value_offset, k, vmSymbols::value_name(), byte_array_signature, false); \ |
181 macro(value_offset, k, vmSymbols::value_name(), byte_array_signature, false); \ |
181 macro(hash_offset, k, "hash", int_signature, false); \ |
182 macro(hash_offset, k, "hash", int_signature, false); \ |
182 macro(coder_offset, k, "coder", byte_signature, false) |
183 macro(hashIsZero_offset, k, "hashIsZero", bool_signature, false); \ |
|
184 macro(coder_offset, k, "coder", byte_signature, false); |
183 |
185 |
184 void java_lang_String::compute_offsets() { |
186 void java_lang_String::compute_offsets() { |
185 if (initialized) { |
187 if (initialized) { |
186 return; |
188 return; |
187 } |
189 } |
505 } |
507 } |
506 return result; |
508 return result; |
507 } |
509 } |
508 |
510 |
509 unsigned int java_lang_String::hash_code(oop java_string) { |
511 unsigned int java_lang_String::hash_code(oop java_string) { |
510 typeArrayOop value = java_lang_String::value(java_string); |
512 // The hash and hashIsZero fields are subject to a benign data race, |
511 int length = java_lang_String::length(java_string, value); |
513 // making it crucial to ensure that any observable result of the |
512 // Zero length string will hash to zero with String.hashCode() function. |
514 // calculation in this method stays correct under any possible read of |
513 if (length == 0) return 0; |
515 // these fields. Necessary restrictions to allow this to be correct |
514 |
516 // without explicit memory fences or similar concurrency primitives is |
515 bool is_latin1 = java_lang_String::is_latin1(java_string); |
517 // that we can ever only write to one of these two fields for a given |
516 |
518 // String instance, and that the computation is idempotent and derived |
517 if (is_latin1) { |
519 // from immutable state |
518 return java_lang_String::hash_code(value->byte_at_addr(0), length); |
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); |
519 } else { |
540 } else { |
520 return java_lang_String::hash_code(value->char_at_addr(0), length); |
541 java_string->bool_field_put(hashIsZero_offset, true); |
521 } |
542 } |
|
543 return hash; |
522 } |
544 } |
523 |
545 |
524 char* java_lang_String::as_quoted_ascii(oop java_string) { |
546 char* java_lang_String::as_quoted_ascii(oop java_string) { |
525 typeArrayOop value = java_lang_String::value(java_string); |
547 typeArrayOop value = java_lang_String::value(java_string); |
526 int length = java_lang_String::length(java_string, value); |
548 int length = java_lang_String::length(java_string, value); |