src/hotspot/share/classfile/javaClasses.cpp
changeset 54486 7fd299216e97
parent 54439 d9b46b7de028
child 54511 fbfcebad8e66
equal deleted inserted replaced
54485:ddc19ea5059c 54486:7fd299216e97
   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);