< prev index next >

src/hotspot/share/oops/symbol.cpp

Print this page




 183       }
 184     }
 185     return str;
 186   } else {
 187     return buf;
 188   }
 189 }
 190 
 191 const char* Symbol::as_klass_external_name() const {
 192   char* str    = as_C_string();
 193   int   length = (int)strlen(str);
 194   // Turn all '/'s into '.'s (also for array klasses)
 195   for (int index = 0; index < length; index++) {
 196     if (str[index] == '/') {
 197       str[index] = '.';
 198     }
 199   }
 200   return str;
 201 }
 202 
 203 static void print_class(outputStream *os, char *class_str, int len) {
 204   for (int i = 0; i < len; ++i) {
 205     if (class_str[i] == '/') {
 206       os->put('.');
 207     } else {
 208       os->put(class_str[i]);
 209     }
 210   }
 211 }
 212 
 213 static void print_array(outputStream *os, char *array_str, int len) {
 214   int dimensions = 0;
 215   for (int i = 0; i < len; ++i) {
 216     if (array_str[i] == '[') {
 217       dimensions++;
 218     } else if (array_str[i] == 'L') {
 219       // Expected format: L<type name>;. Skip 'L' and ';' delimiting the type name.
 220       print_class(os, array_str+i+1, len-i-2);
 221       break;
 222     } else {
 223       os->print("%s", type2name(char2type(array_str[i])));
 224     }
 225   }
 226   for (int i = 0; i < dimensions; ++i) {
 227     os->print("[]");
 228   }
 229 }
 230 
 231 void Symbol::print_as_signature_external_return_type(outputStream *os) {
 232   for (SignatureStream ss(this); !ss.is_done(); ss.next()) {
 233     if (ss.at_return_type()) {
 234       if (ss.is_array()) {
 235         print_array(os, (char*)ss.raw_bytes(), (int)ss.raw_length());
 236       } else if (ss.is_object()) {
 237         // Expected format: L<type name>;. Skip 'L' and ';' delimiting the class name.
 238         print_class(os, (char*)ss.raw_bytes()+1, (int)ss.raw_length()-2);
 239       } else {
 240         os->print("%s", type2name(ss.type()));
 241       }
 242     }
 243   }
 244 }
 245 
 246 void Symbol::print_as_signature_external_parameters(outputStream *os) {
 247   bool first = true;
 248   for (SignatureStream ss(this); !ss.is_done(); ss.next()) {
 249     if (ss.at_return_type()) break;
 250     if (!first) { os->print(", "); }
 251     if (ss.is_array()) {
 252       print_array(os, (char*)ss.raw_bytes(), (int)ss.raw_length());
 253     } else if (ss.is_object()) {
 254       // Skip 'L' and ';'.
 255       print_class(os, (char*)ss.raw_bytes()+1, (int)ss.raw_length()-2);
 256     } else {
 257       os->print("%s", type2name(ss.type()));
 258     }
 259     first = false;
 260   }
 261 }
 262 
 263 // Increment refcount while checking for zero.  If the Symbol's refcount becomes zero
 264 // a thread could be concurrently removing the Symbol.  This is used during SymbolTable
 265 // lookup to avoid reviving a dead Symbol.
 266 bool Symbol::try_increment_refcount() {
 267   uint32_t found = _length_and_refcount;
 268   while (true) {
 269     uint32_t old_value = found;
 270     int refc = extract_refcount(old_value);
 271     if (refc == PERM_REFCOUNT) {
 272       return true;  // sticky max or created permanent
 273     } else if (refc == 0) {
 274       return false; // dead, can't revive.
 275     } else {
 276       found = Atomic::cmpxchg(old_value + 1, &_length_and_refcount, old_value);
 277       if (found == old_value) {
 278         return true; // successfully updated.
 279       }
 280       // refcount changed, try again.
 281     }
 282   }




 183       }
 184     }
 185     return str;
 186   } else {
 187     return buf;
 188   }
 189 }
 190 
 191 const char* Symbol::as_klass_external_name() const {
 192   char* str    = as_C_string();
 193   int   length = (int)strlen(str);
 194   // Turn all '/'s into '.'s (also for array klasses)
 195   for (int index = 0; index < length; index++) {
 196     if (str[index] == '/') {
 197       str[index] = '.';
 198     }
 199   }
 200   return str;
 201 }
 202 




























































 203 // Increment refcount while checking for zero.  If the Symbol's refcount becomes zero
 204 // a thread could be concurrently removing the Symbol.  This is used during SymbolTable
 205 // lookup to avoid reviving a dead Symbol.
 206 bool Symbol::try_increment_refcount() {
 207   uint32_t found = _length_and_refcount;
 208   while (true) {
 209     uint32_t old_value = found;
 210     int refc = extract_refcount(old_value);
 211     if (refc == PERM_REFCOUNT) {
 212       return true;  // sticky max or created permanent
 213     } else if (refc == 0) {
 214       return false; // dead, can't revive.
 215     } else {
 216       found = Atomic::cmpxchg(old_value + 1, &_length_and_refcount, old_value);
 217       if (found == old_value) {
 218         return true; // successfully updated.
 219       }
 220       // refcount changed, try again.
 221     }
 222   }


< prev index next >