< prev index next >

src/hotspot/share/oops/symbol.cpp

Print this page




 264     } else {
 265       os->print("%s", type2name(ss.type()));
 266     }
 267     first = false;
 268   }
 269 }
 270 
 271 // Increment refcount while checking for zero.  If the Symbol's refcount becomes zero
 272 // a thread could be concurrently removing the Symbol.  This is used during SymbolTable
 273 // lookup to avoid reviving a dead Symbol.
 274 bool Symbol::try_increment_refcount() {
 275   uint32_t found = _length_and_refcount;
 276   while (true) {
 277     uint32_t old_value = found;
 278     int refc = extract_refcount(old_value);
 279     if (refc == PERM_REFCOUNT) {
 280       return true;  // sticky max or created permanent
 281     } else if (refc == 0) {
 282       return false; // dead, can't revive.
 283     } else {
 284       found = Atomic::cmpxchg(old_value + 1, &_length_and_refcount, old_value);
 285       if (found == old_value) {
 286         return true; // successfully updated.
 287       }
 288       // refcount changed, try again.
 289     }
 290   }
 291 }
 292 
 293 // The increment_refcount() is called when not doing lookup. It is assumed that you
 294 // have a symbol with a non-zero refcount and it can't become zero while referenced by
 295 // this caller.
 296 void Symbol::increment_refcount() {
 297   if (!try_increment_refcount()) {
 298 #ifdef ASSERT
 299     print();
 300     fatal("refcount has gone to zero");
 301 #endif
 302   }
 303 #ifndef PRODUCT
 304   if (refcount() != PERM_REFCOUNT) { // not a permanent symbol


 307 #endif
 308 }
 309 
 310 // Decrement refcount potentially while racing increment, so we need
 311 // to check the value after attempting to decrement so that if another
 312 // thread increments to PERM_REFCOUNT the value is not decremented.
 313 void Symbol::decrement_refcount() {
 314   uint32_t found = _length_and_refcount;
 315   while (true) {
 316     uint32_t old_value = found;
 317     int refc = extract_refcount(old_value);
 318     if (refc == PERM_REFCOUNT) {
 319       return;  // refcount is permanent, permanent is sticky
 320     } else if (refc == 0) {
 321 #ifdef ASSERT
 322       print();
 323       fatal("refcount underflow");
 324 #endif
 325       return;
 326     } else {
 327       found = Atomic::cmpxchg(old_value - 1, &_length_and_refcount, old_value);
 328       if (found == old_value) {
 329         return;  // successfully updated.
 330       }
 331       // refcount changed, try again.
 332     }
 333   }
 334 }
 335 
 336 void Symbol::make_permanent() {
 337   uint32_t found = _length_and_refcount;
 338   while (true) {
 339     uint32_t old_value = found;
 340     int refc = extract_refcount(old_value);
 341     if (refc == PERM_REFCOUNT) {
 342       return;  // refcount is permanent, permanent is sticky
 343     } else if (refc == 0) {
 344 #ifdef ASSERT
 345       print();
 346       fatal("refcount underflow");
 347 #endif
 348       return;
 349     } else {
 350       int len = extract_length(old_value);
 351       found = Atomic::cmpxchg(pack_length_and_refcount(len, PERM_REFCOUNT), &_length_and_refcount, old_value);
 352       if (found == old_value) {
 353         return;  // successfully updated.
 354       }
 355       // refcount changed, try again.
 356     }
 357   }
 358 }
 359 
 360 void Symbol::metaspace_pointers_do(MetaspaceClosure* it) {
 361   if (log_is_enabled(Trace, cds)) {
 362     LogStream trace_stream(Log(cds)::trace());
 363     trace_stream.print("Iter(Symbol): %p ", this);
 364     print_value_on(&trace_stream);
 365     trace_stream.cr();
 366   }
 367 }
 368 
 369 void Symbol::print_on(outputStream* st) const {
 370   st->print("Symbol: '");
 371   print_symbol_on(st);




 264     } else {
 265       os->print("%s", type2name(ss.type()));
 266     }
 267     first = false;
 268   }
 269 }
 270 
 271 // Increment refcount while checking for zero.  If the Symbol's refcount becomes zero
 272 // a thread could be concurrently removing the Symbol.  This is used during SymbolTable
 273 // lookup to avoid reviving a dead Symbol.
 274 bool Symbol::try_increment_refcount() {
 275   uint32_t found = _length_and_refcount;
 276   while (true) {
 277     uint32_t old_value = found;
 278     int refc = extract_refcount(old_value);
 279     if (refc == PERM_REFCOUNT) {
 280       return true;  // sticky max or created permanent
 281     } else if (refc == 0) {
 282       return false; // dead, can't revive.
 283     } else {
 284       found = Atomic::cmpxchg(&_length_and_refcount, old_value, old_value + 1);
 285       if (found == old_value) {
 286         return true; // successfully updated.
 287       }
 288       // refcount changed, try again.
 289     }
 290   }
 291 }
 292 
 293 // The increment_refcount() is called when not doing lookup. It is assumed that you
 294 // have a symbol with a non-zero refcount and it can't become zero while referenced by
 295 // this caller.
 296 void Symbol::increment_refcount() {
 297   if (!try_increment_refcount()) {
 298 #ifdef ASSERT
 299     print();
 300     fatal("refcount has gone to zero");
 301 #endif
 302   }
 303 #ifndef PRODUCT
 304   if (refcount() != PERM_REFCOUNT) { // not a permanent symbol


 307 #endif
 308 }
 309 
 310 // Decrement refcount potentially while racing increment, so we need
 311 // to check the value after attempting to decrement so that if another
 312 // thread increments to PERM_REFCOUNT the value is not decremented.
 313 void Symbol::decrement_refcount() {
 314   uint32_t found = _length_and_refcount;
 315   while (true) {
 316     uint32_t old_value = found;
 317     int refc = extract_refcount(old_value);
 318     if (refc == PERM_REFCOUNT) {
 319       return;  // refcount is permanent, permanent is sticky
 320     } else if (refc == 0) {
 321 #ifdef ASSERT
 322       print();
 323       fatal("refcount underflow");
 324 #endif
 325       return;
 326     } else {
 327       found = Atomic::cmpxchg(&_length_and_refcount, old_value, old_value - 1);
 328       if (found == old_value) {
 329         return;  // successfully updated.
 330       }
 331       // refcount changed, try again.
 332     }
 333   }
 334 }
 335 
 336 void Symbol::make_permanent() {
 337   uint32_t found = _length_and_refcount;
 338   while (true) {
 339     uint32_t old_value = found;
 340     int refc = extract_refcount(old_value);
 341     if (refc == PERM_REFCOUNT) {
 342       return;  // refcount is permanent, permanent is sticky
 343     } else if (refc == 0) {
 344 #ifdef ASSERT
 345       print();
 346       fatal("refcount underflow");
 347 #endif
 348       return;
 349     } else {
 350       int len = extract_length(old_value);
 351       found = Atomic::cmpxchg(&_length_and_refcount, old_value, pack_length_and_refcount(len, PERM_REFCOUNT));
 352       if (found == old_value) {
 353         return;  // successfully updated.
 354       }
 355       // refcount changed, try again.
 356     }
 357   }
 358 }
 359 
 360 void Symbol::metaspace_pointers_do(MetaspaceClosure* it) {
 361   if (log_is_enabled(Trace, cds)) {
 362     LogStream trace_stream(Log(cds)::trace());
 363     trace_stream.print("Iter(Symbol): %p ", this);
 364     print_value_on(&trace_stream);
 365     trace_stream.cr();
 366   }
 367 }
 368 
 369 void Symbol::print_on(outputStream* st) const {
 370   st->print("Symbol: '");
 371   print_symbol_on(st);


< prev index next >