8204613: StringTable: Calculates wrong number of uncleaned items

Reviewed-by: pliden, coleenp
This commit is contained in:
Robbin Ehn 2018-06-14 07:26:27 +02:00
parent 0bafbdc983
commit 6b62a66298
5 changed files with 102 additions and 16 deletions

View File

@ -198,17 +198,16 @@ size_t StringTable::item_added() {
return Atomic::add((size_t)1, &(the_table()->_items)); return Atomic::add((size_t)1, &(the_table()->_items));
} }
size_t StringTable::items_to_clean(size_t ncl) { size_t StringTable::add_items_to_clean(size_t ndead) {
size_t total = Atomic::add((size_t)ncl, &(the_table()->_uncleaned_items)); size_t total = Atomic::add((size_t)ndead, &(the_table()->_uncleaned_items));
log_trace(stringtable)( log_trace(stringtable)(
"Uncleaned items:" SIZE_FORMAT " added: " SIZE_FORMAT " total:" SIZE_FORMAT, "Uncleaned items:" SIZE_FORMAT " added: " SIZE_FORMAT " total:" SIZE_FORMAT,
the_table()->_uncleaned_items, ncl, total); the_table()->_uncleaned_items, ndead, total);
return total; return total;
} }
void StringTable::item_removed() { void StringTable::item_removed() {
Atomic::add((size_t)-1, &(the_table()->_items)); Atomic::add((size_t)-1, &(the_table()->_items));
Atomic::add((size_t)-1, &(the_table()->_uncleaned_items));
} }
double StringTable::get_load_factor() { double StringTable::get_load_factor() {
@ -405,8 +404,11 @@ void StringTable::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f,
StringTable::the_table()->_weak_handles->weak_oops_do(&stiac, tmp); StringTable::the_table()->_weak_handles->weak_oops_do(&stiac, tmp);
StringTable::the_table()->items_to_clean(stiac._count); // This is the serial case without ParState.
// Just set the correct number and check for a cleaning phase.
the_table()->_uncleaned_items = stiac._count;
StringTable::the_table()->check_concurrent_work(); StringTable::the_table()->check_concurrent_work();
if (processed != NULL) { if (processed != NULL) {
*processed = (int) stiac._count_total; *processed = (int) stiac._count_total;
} }
@ -430,8 +432,9 @@ void StringTable::possibly_parallel_unlink(
_par_state_string->weak_oops_do(&stiac, &dnc); _par_state_string->weak_oops_do(&stiac, &dnc);
StringTable::the_table()->items_to_clean(stiac._count); // Accumulate the dead strings.
StringTable::the_table()->check_concurrent_work(); the_table()->add_items_to_clean(stiac._count);
*processed = (int) stiac._count_total; *processed = (int) stiac._count_total;
*removed = (int) stiac._count; *removed = (int) stiac._count;
} }
@ -467,10 +470,8 @@ void StringTable::grow(JavaThread* jt) {
} }
struct StringTableDoDelete : StackObj { struct StringTableDoDelete : StackObj {
long _count;
StringTableDoDelete() : _count(0) {}
void operator()(WeakHandle<vm_string_table_data>* val) { void operator()(WeakHandle<vm_string_table_data>* val) {
++_count; /* do nothing */
} }
}; };
@ -524,6 +525,7 @@ void StringTable::check_concurrent_work() {
if (_has_work) { if (_has_work) {
return; return;
} }
double load_factor = StringTable::get_load_factor(); double load_factor = StringTable::get_load_factor();
double dead_factor = StringTable::get_dead_factor(); double dead_factor = StringTable::get_dead_factor();
// We should clean/resize if we have more dead than alive, // We should clean/resize if we have more dead than alive,

View File

@ -83,7 +83,7 @@ private:
static uintx item_added(); static uintx item_added();
static void item_removed(); static void item_removed();
static size_t items_to_clean(size_t ncl); size_t add_items_to_clean(size_t ndead);
StringTable(); StringTable();
@ -113,6 +113,23 @@ private:
static bool has_work() { return the_table()->_has_work; } static bool has_work() { return the_table()->_has_work; }
// GC support // GC support
// Must be called before a parallel walk where strings might die.
static void reset_dead_counter() {
the_table()->_uncleaned_items = 0;
}
// After the parallel walk this method must be called to trigger
// cleaning. Note it might trigger a resize instead.
static void finish_dead_counter() {
the_table()->check_concurrent_work();
}
// If GC uses ParState directly it should add the number of cleared
// strings to this method.
static void inc_dead_counter(size_t ndead) {
the_table()->add_items_to_clean(ndead);
}
// Delete pointers to otherwise-unreachable objects. // Delete pointers to otherwise-unreachable objects.
static void unlink(BoolObjectClosure* cl) { static void unlink(BoolObjectClosure* cl) {
unlink_or_oops_do(cl); unlink_or_oops_do(cl);
@ -150,9 +167,9 @@ private:
oop lookup_shared(jchar* name, int len, unsigned int hash) NOT_CDS_JAVA_HEAP_RETURN_(NULL); oop lookup_shared(jchar* name, int len, unsigned int hash) NOT_CDS_JAVA_HEAP_RETURN_(NULL);
static void copy_shared_string_table(CompactStringTableWriter* ch_table) NOT_CDS_JAVA_HEAP_RETURN; static void copy_shared_string_table(CompactStringTableWriter* ch_table) NOT_CDS_JAVA_HEAP_RETURN;
public: public:
static oop create_archived_string(oop s, Thread* THREAD); static oop create_archived_string(oop s, Thread* THREAD) NOT_CDS_JAVA_HEAP_RETURN_(NULL);
static void set_shared_string_mapped() { _shared_string_mapped = true; } static void set_shared_string_mapped() { _shared_string_mapped = true; }
static bool shared_string_mapped() { return _shared_string_mapped; } static bool shared_string_mapped() { return _shared_string_mapped; }
static void shared_oops_do(OopClosure* f) NOT_CDS_JAVA_HEAP_RETURN; static void shared_oops_do(OopClosure* f) NOT_CDS_JAVA_HEAP_RETURN;
static void write_to_archive() NOT_CDS_JAVA_HEAP_RETURN; static void write_to_archive() NOT_CDS_JAVA_HEAP_RETURN;
static void serialize(SerializeClosure* soc) NOT_CDS_JAVA_HEAP_RETURN; static void serialize(SerializeClosure* soc) NOT_CDS_JAVA_HEAP_RETURN;

View File

@ -3262,6 +3262,9 @@ public:
if (process_symbols) { if (process_symbols) {
SymbolTable::clear_parallel_claimed_index(); SymbolTable::clear_parallel_claimed_index();
} }
if (process_strings) {
StringTable::reset_dead_counter();
}
} }
~G1StringAndSymbolCleaningTask() { ~G1StringAndSymbolCleaningTask() {
@ -3275,6 +3278,9 @@ public:
"symbols: " SIZE_FORMAT " processed, " SIZE_FORMAT " removed", "symbols: " SIZE_FORMAT " processed, " SIZE_FORMAT " removed",
strings_processed(), strings_removed(), strings_processed(), strings_removed(),
symbols_processed(), symbols_removed()); symbols_processed(), symbols_removed());
if (_process_strings) {
StringTable::finish_dead_counter();
}
} }
void work(uint worker_id) { void work(uint worker_id) {

View File

@ -307,10 +307,12 @@ ZWeakRootsIterator::ZWeakRootsIterator() :
assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint"); assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
ZStatTimer timer(ZSubPhasePauseWeakRootsSetup); ZStatTimer timer(ZSubPhasePauseWeakRootsSetup);
SymbolTable::clear_parallel_claimed_index(); SymbolTable::clear_parallel_claimed_index();
StringTable::reset_dead_counter();
} }
ZWeakRootsIterator::~ZWeakRootsIterator() { ZWeakRootsIterator::~ZWeakRootsIterator() {
ZStatTimer timer(ZSubPhasePauseWeakRootsTeardown); ZStatTimer timer(ZSubPhasePauseWeakRootsTeardown);
StringTable::finish_dead_counter();
} }
void ZWeakRootsIterator::do_vm_weak_handles(BoolObjectClosure* is_alive, OopClosure* cl) { void ZWeakRootsIterator::do_vm_weak_handles(BoolObjectClosure* is_alive, OopClosure* cl) {
@ -341,9 +343,34 @@ void ZWeakRootsIterator::do_symbol_table(BoolObjectClosure* is_alive, OopClosure
SymbolTable::possibly_parallel_unlink(&dummy, &dummy); SymbolTable::possibly_parallel_unlink(&dummy, &dummy);
} }
class ZStringTableDeadCounterBoolObjectClosure : public BoolObjectClosure {
private:
BoolObjectClosure* const _cl;
size_t _ndead;
public:
ZStringTableDeadCounterBoolObjectClosure(BoolObjectClosure* cl) :
_cl(cl),
_ndead(0) {}
~ZStringTableDeadCounterBoolObjectClosure() {
StringTable::inc_dead_counter(_ndead);
}
virtual bool do_object_b(oop obj) {
if (_cl->do_object_b(obj)) {
return true;
}
_ndead++;
return false;
}
};
void ZWeakRootsIterator::do_string_table(BoolObjectClosure* is_alive, OopClosure* cl) { void ZWeakRootsIterator::do_string_table(BoolObjectClosure* is_alive, OopClosure* cl) {
ZStatTimer timer(ZSubPhasePauseWeakRootsStringTable); ZStatTimer timer(ZSubPhasePauseWeakRootsStringTable);
_string_table_iter.weak_oops_do(is_alive, cl); ZStringTableDeadCounterBoolObjectClosure counter_is_alive(is_alive);
_string_table_iter.weak_oops_do(&counter_is_alive, cl);
} }
void ZWeakRootsIterator::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* cl) { void ZWeakRootsIterator::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* cl) {
@ -377,7 +404,13 @@ ZConcurrentWeakRootsIterator::ZConcurrentWeakRootsIterator() :
_string_table_iter(StringTable::weak_storage()), _string_table_iter(StringTable::weak_storage()),
_vm_weak_handles(this), _vm_weak_handles(this),
_jni_weak_handles(this), _jni_weak_handles(this),
_string_table(this) {} _string_table(this) {
StringTable::reset_dead_counter();
}
ZConcurrentWeakRootsIterator::~ZConcurrentWeakRootsIterator() {
StringTable::finish_dead_counter();
}
void ZConcurrentWeakRootsIterator::do_vm_weak_handles(OopClosure* cl) { void ZConcurrentWeakRootsIterator::do_vm_weak_handles(OopClosure* cl) {
ZStatTimer timer(ZSubPhaseConcurrentWeakRootsVMWeakHandles); ZStatTimer timer(ZSubPhaseConcurrentWeakRootsVMWeakHandles);
@ -389,9 +422,36 @@ void ZConcurrentWeakRootsIterator::do_jni_weak_handles(OopClosure* cl) {
_jni_weak_handles_iter.oops_do(cl); _jni_weak_handles_iter.oops_do(cl);
} }
class ZStringTableDeadCounterOopClosure : public OopClosure {
private:
OopClosure* const _cl;
size_t _ndead;
public:
ZStringTableDeadCounterOopClosure(OopClosure* cl) :
_cl(cl),
_ndead(0) {}
~ZStringTableDeadCounterOopClosure() {
StringTable::inc_dead_counter(_ndead);
}
virtual void do_oop(oop* p) {
_cl->do_oop(p);
if (*p == NULL) {
_ndead++;
}
}
virtual void do_oop(narrowOop* p) {
ShouldNotReachHere();
}
};
void ZConcurrentWeakRootsIterator::do_string_table(OopClosure* cl) { void ZConcurrentWeakRootsIterator::do_string_table(OopClosure* cl) {
ZStatTimer timer(ZSubPhaseConcurrentWeakRootsStringTable); ZStatTimer timer(ZSubPhaseConcurrentWeakRootsStringTable);
_string_table_iter.oops_do(cl); ZStringTableDeadCounterOopClosure counter_cl(cl);
_string_table_iter.oops_do(&counter_cl);
} }
void ZConcurrentWeakRootsIterator::oops_do(OopClosure* cl) { void ZConcurrentWeakRootsIterator::oops_do(OopClosure* cl) {

View File

@ -164,6 +164,7 @@ private:
public: public:
ZConcurrentWeakRootsIterator(); ZConcurrentWeakRootsIterator();
~ZConcurrentWeakRootsIterator();
void oops_do(OopClosure* cl); void oops_do(OopClosure* cl);
}; };