equal
deleted
inserted
replaced
360 // May be cleaned concurrently, so must use the Compile_lock. |
360 // May be cleaned concurrently, so must use the Compile_lock. |
361 // The log parameter is for clean_weak_klass_links to report unlinked classes. |
361 // The log parameter is for clean_weak_klass_links to report unlinked classes. |
362 Klass* Klass::subklass(bool log) const { |
362 Klass* Klass::subklass(bool log) const { |
363 // Need load_acquire on the _subklass, because it races with inserts that |
363 // Need load_acquire on the _subklass, because it races with inserts that |
364 // publishes freshly initialized data. |
364 // publishes freshly initialized data. |
365 for (Klass* chain = OrderAccess::load_acquire(&_subklass); |
365 for (Klass* chain = Atomic::load_acquire(&_subklass); |
366 chain != NULL; |
366 chain != NULL; |
367 // Do not need load_acquire on _next_sibling, because inserts never |
367 // Do not need load_acquire on _next_sibling, because inserts never |
368 // create _next_sibling edges to dead data. |
368 // create _next_sibling edges to dead data. |
369 chain = Atomic::load(&chain->_next_sibling)) |
369 chain = Atomic::load(&chain->_next_sibling)) |
370 { |
370 { |
400 return NULL; |
400 return NULL; |
401 } |
401 } |
402 |
402 |
403 void Klass::set_subklass(Klass* s) { |
403 void Klass::set_subklass(Klass* s) { |
404 assert(s != this, "sanity check"); |
404 assert(s != this, "sanity check"); |
405 OrderAccess::release_store(&_subklass, s); |
405 Atomic::release_store(&_subklass, s); |
406 } |
406 } |
407 |
407 |
408 void Klass::set_next_sibling(Klass* s) { |
408 void Klass::set_next_sibling(Klass* s) { |
409 assert(s != this, "sanity check"); |
409 assert(s != this, "sanity check"); |
410 // Does not need release semantics. If used by cleanup, it will link to |
410 // Does not need release semantics. If used by cleanup, it will link to |
425 |
425 |
426 // Make sure there is no stale subklass head |
426 // Make sure there is no stale subklass head |
427 super->clean_subklass(); |
427 super->clean_subklass(); |
428 |
428 |
429 for (;;) { |
429 for (;;) { |
430 Klass* prev_first_subklass = OrderAccess::load_acquire(&_super->_subklass); |
430 Klass* prev_first_subklass = Atomic::load_acquire(&_super->_subklass); |
431 if (prev_first_subklass != NULL) { |
431 if (prev_first_subklass != NULL) { |
432 // set our sibling to be the superklass' previous first subklass |
432 // set our sibling to be the superklass' previous first subklass |
433 assert(prev_first_subklass->is_loader_alive(), "May not attach not alive klasses"); |
433 assert(prev_first_subklass->is_loader_alive(), "May not attach not alive klasses"); |
434 set_next_sibling(prev_first_subklass); |
434 set_next_sibling(prev_first_subklass); |
435 } |
435 } |
444 } |
444 } |
445 |
445 |
446 void Klass::clean_subklass() { |
446 void Klass::clean_subklass() { |
447 for (;;) { |
447 for (;;) { |
448 // Need load_acquire, due to contending with concurrent inserts |
448 // Need load_acquire, due to contending with concurrent inserts |
449 Klass* subklass = OrderAccess::load_acquire(&_subklass); |
449 Klass* subklass = Atomic::load_acquire(&_subklass); |
450 if (subklass == NULL || subklass->is_loader_alive()) { |
450 if (subklass == NULL || subklass->is_loader_alive()) { |
451 return; |
451 return; |
452 } |
452 } |
453 // Try to fix _subklass until it points at something not dead. |
453 // Try to fix _subklass until it points at something not dead. |
454 Atomic::cmpxchg(subklass->next_sibling(), &_subklass, subklass); |
454 Atomic::cmpxchg(subklass->next_sibling(), &_subklass, subklass); |