8213229: Investigate treating StringTable as weak in young collections
Reviewed-by: zgu, kbarrett
--- a/src/hotspot/share/classfile/stringTable.cpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/classfile/stringTable.cpp Tue Jan 29 11:30:17 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -376,68 +376,11 @@
} while(true);
}
-// GC support
-class StringTableIsAliveCounter : public BoolObjectClosure {
- BoolObjectClosure* _real_boc;
- public:
- size_t _count;
- size_t _count_total;
- StringTableIsAliveCounter(BoolObjectClosure* boc) : _real_boc(boc), _count(0),
- _count_total(0) {}
- bool do_object_b(oop obj) {
- bool ret = _real_boc->do_object_b(obj);
- if (!ret) {
- ++_count;
- }
- ++_count_total;
- return ret;
- }
-};
-
-void StringTable::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f,
- size_t* processed, size_t* removed) {
- DoNothingClosure dnc;
- assert(is_alive != NULL, "No closure");
- StringTableIsAliveCounter stiac(is_alive);
- OopClosure* tmp = f != NULL ? f : &dnc;
-
- StringTable::the_table()->_weak_handles->weak_oops_do(&stiac, tmp);
-
- // This is the serial case without ParState.
- // Just set the correct number and check for a cleaning phase.
- the_table()->_uncleaned_items_count = stiac._count;
- StringTable::the_table()->check_concurrent_work();
-
- if (processed != NULL) {
- *processed = stiac._count_total;
- }
- if (removed != NULL) {
- *removed = stiac._count;
- }
-}
-
void StringTable::oops_do(OopClosure* f) {
assert(f != NULL, "No closure");
StringTable::the_table()->_weak_handles->oops_do(f);
}
-void StringTable::possibly_parallel_unlink(
- OopStorage::ParState<false, false>* _par_state_string, BoolObjectClosure* cl,
- size_t* processed, size_t* removed)
-{
- DoNothingClosure dnc;
- assert(cl != NULL, "No closure");
- StringTableIsAliveCounter stiac(cl);
-
- _par_state_string->weak_oops_do(&stiac, &dnc);
-
- // Accumulate the dead strings.
- the_table()->add_items_to_clean(stiac._count);
-
- *processed = stiac._count_total;
- *removed = stiac._count;
-}
-
void StringTable::possibly_parallel_oops_do(
OopStorage::ParState<false /* concurrent */, false /* const */>*
_par_state_string, OopClosure* f)
--- a/src/hotspot/share/classfile/stringTable.hpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/classfile/stringTable.hpp Tue Jan 29 11:30:17 2019 +0100
@@ -128,20 +128,10 @@
the_table()->add_items_to_clean(ndead);
}
- // Delete pointers to otherwise-unreachable objects.
- static void unlink(BoolObjectClosure* cl) {
- unlink_or_oops_do(cl);
- }
- static void unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f = NULL,
- size_t* processed = NULL, size_t* removed = NULL);
-
// Serially invoke "f->do_oop" on the locations of all oops in the table.
static void oops_do(OopClosure* f);
// Possibly parallel versions of the above
- static void possibly_parallel_unlink(
- OopStorage::ParState<false /* concurrent */, false /* const*/>* par_state_string,
- BoolObjectClosure* cl, size_t* processed, size_t* removed);
static void possibly_parallel_oops_do(
OopStorage::ParState<false /* concurrent */, false /* const*/>* par_state_string,
OopClosure* f);
--- a/src/hotspot/share/gc/cms/cmsHeap.cpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/cms/cmsHeap.cpp Tue Jan 29 11:30:17 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -225,15 +225,11 @@
ScanningOption so,
bool only_strong_roots,
OopsInGenClosure* root_closure,
- CLDClosure* cld_closure,
- OopStorage::ParState<false, false>* par_state_string) {
+ CLDClosure* cld_closure) {
MarkingCodeBlobClosure mark_code_closure(root_closure, !CodeBlobToOopClosure::FixRelocations);
CLDClosure* weak_cld_closure = only_strong_roots ? NULL : cld_closure;
process_roots(scope, so, root_closure, cld_closure, weak_cld_closure, &mark_code_closure);
- if (!only_strong_roots) {
- process_string_table_roots(scope, root_closure, par_state_string);
- }
if (young_gen_as_roots &&
_process_strong_tasks->try_claim_task(GCH_PS_younger_gens)) {
--- a/src/hotspot/share/gc/cms/cmsHeap.hpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/cms/cmsHeap.hpp Tue Jan 29 11:30:17 2019 +0100
@@ -91,8 +91,7 @@
ScanningOption so,
bool only_strong_roots,
OopsInGenClosure* root_closure,
- CLDClosure* cld_closure,
- OopStorage::ParState<false, false>* par_state_string = NULL);
+ CLDClosure* cld_closure);
GCMemoryManager* old_manager() const { return _old_manager; }
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp Tue Jan 29 11:30:17 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -4333,8 +4333,7 @@
GenCollectedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
_collector->should_unload_classes(),
&par_mri_cl,
- &cld_closure,
- &_par_state_string);
+ &cld_closure);
assert(_collector->should_unload_classes()
|| (_collector->CMSCollector::roots_scanning_options() & GenCollectedHeap::SO_AllCodeCache),
@@ -4464,8 +4463,7 @@
GenCollectedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
_collector->should_unload_classes(),
&par_mrias_cl,
- NULL, // The dirty klasses will be handled below
- &_par_state_string);
+ NULL); // The dirty klasses will be handled below
assert(_collector->should_unload_classes()
|| (_collector->CMSCollector::roots_scanning_options() & GenCollectedHeap::SO_AllCodeCache),
@@ -5277,12 +5275,6 @@
// Clean up unreferenced symbols in symbol table.
SymbolTable::unlink();
}
-
- {
- GCTraceTime(Debug, gc, phases) t("Scrub String Table", _gc_timer_cm);
- // Delete entries for dead interned strings.
- StringTable::unlink(&_is_alive_closure);
- }
}
// Restore any preserved marks as a result of mark stack or
--- a/src/hotspot/share/gc/cms/parNewGeneration.cpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/cms/parNewGeneration.cpp Tue Jan 29 11:30:17 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -606,8 +606,7 @@
heap->young_process_roots(_strong_roots_scope,
&par_scan_state.to_space_root_closure(),
&par_scan_state.older_gen_closure(),
- &cld_scan_closure,
- &_par_state_string);
+ &cld_scan_closure);
par_scan_state.end_strong_roots();
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp Tue Jan 29 11:30:17 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -3362,24 +3362,54 @@
void G1CollectedHeap::complete_cleaning(BoolObjectClosure* is_alive,
bool class_unloading_occurred) {
- uint n_workers = workers()->active_workers();
-
- G1StringDedupUnlinkOrOopsDoClosure dedup_closure(is_alive, NULL, false);
- ParallelCleaningTask g1_unlink_task(is_alive, &dedup_closure, n_workers, class_unloading_occurred);
- workers()->run_task(&g1_unlink_task);
+ uint num_workers = workers()->active_workers();
+ ParallelCleaningTask unlink_task(is_alive, num_workers, class_unloading_occurred, false);
+ workers()->run_task(&unlink_task);
}
-void G1CollectedHeap::partial_cleaning(BoolObjectClosure* is_alive,
- bool process_strings,
- bool process_string_dedup) {
- if (!process_strings && !process_string_dedup) {
- // Nothing to clean.
- return;
+// Clean string dedup data structures.
+// Ideally we would prefer to use a StringDedupCleaningTask here, but we want to
+// record the durations of the phases. Hence the almost-copy.
+class G1StringDedupCleaningTask : public AbstractGangTask {
+ BoolObjectClosure* _is_alive;
+ OopClosure* _keep_alive;
+ G1GCPhaseTimes* _phase_times;
+
+public:
+ G1StringDedupCleaningTask(BoolObjectClosure* is_alive,
+ OopClosure* keep_alive,
+ G1GCPhaseTimes* phase_times) :
+ AbstractGangTask("Partial Cleaning Task"),
+ _is_alive(is_alive),
+ _keep_alive(keep_alive),
+ _phase_times(phase_times)
+ {
+ assert(G1StringDedup::is_enabled(), "String deduplication disabled.");
+ StringDedup::gc_prologue(true);
}
- G1StringDedupUnlinkOrOopsDoClosure dedup_closure(is_alive, NULL, false);
- StringCleaningTask g1_unlink_task(is_alive, process_string_dedup ? &dedup_closure : NULL, process_strings);
- workers()->run_task(&g1_unlink_task);
+ ~G1StringDedupCleaningTask() {
+ StringDedup::gc_epilogue();
+ }
+
+ void work(uint worker_id) {
+ StringDedupUnlinkOrOopsDoClosure cl(_is_alive, _keep_alive);
+ {
+ G1GCParPhaseTimesTracker x(_phase_times, G1GCPhaseTimes::StringDedupQueueFixup, worker_id);
+ StringDedupQueue::unlink_or_oops_do(&cl);
+ }
+ {
+ G1GCParPhaseTimesTracker x(_phase_times, G1GCPhaseTimes::StringDedupTableFixup, worker_id);
+ StringDedupTable::unlink_or_oops_do(&cl, worker_id);
+ }
+ }
+};
+
+void G1CollectedHeap::string_dedup_cleaning(BoolObjectClosure* is_alive,
+ OopClosure* keep_alive,
+ G1GCPhaseTimes* phase_times) {
+ G1StringDedupCleaningTask cl(is_alive, keep_alive, phase_times);
+ workers()->run_task(&cl);
}
class G1RedirtyLoggedCardsTask : public AbstractGangTask {
@@ -3911,11 +3941,6 @@
// not copied during the pause.
process_discovered_references(per_thread_states);
- // FIXME
- // CM's reference processing also cleans up the string table.
- // Should we do that here also? We could, but it is a serial operation
- // and could significantly increase the pause time.
-
G1STWIsAliveClosure is_alive(this);
G1KeepAliveClosure keep_alive(this);
@@ -3923,12 +3948,12 @@
g1_policy()->phase_times()->weak_phase_times());
if (G1StringDedup::is_enabled()) {
- double fixup_start = os::elapsedTime();
-
- G1StringDedup::unlink_or_oops_do(&is_alive, &keep_alive, true, g1_policy()->phase_times());
-
- double fixup_time_ms = (os::elapsedTime() - fixup_start) * 1000.0;
- g1_policy()->phase_times()->record_string_dedup_fixup_time(fixup_time_ms);
+ double string_dedup_time_ms = os::elapsedTime();
+
+ string_dedup_cleaning(&is_alive, &keep_alive, g1_policy()->phase_times());
+
+ double string_cleanup_time_ms = (os::elapsedTime() - string_dedup_time_ms) * 1000.0;
+ g1_policy()->phase_times()->record_string_deduplication_time(string_cleanup_time_ms);
}
if (evacuation_failed()) {
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp Tue Jan 29 11:30:17 2019 +0100
@@ -1332,14 +1332,12 @@
// after a full GC.
void rebuild_strong_code_roots();
- // Partial cleaning used when class unloading is disabled.
- // Let the caller choose what structures to clean out:
- // - StringTable
- // - StringDeduplication structures
- void partial_cleaning(BoolObjectClosure* is_alive, bool unlink_strings, bool unlink_string_dedup);
+ // Partial cleaning of VM internal data structures.
+ void string_dedup_cleaning(BoolObjectClosure* is_alive,
+ OopClosure* keep_alive,
+ G1GCPhaseTimes* phase_times = NULL);
- // Complete cleaning used when class unloading is enabled.
- // Cleans out all structures handled by partial_cleaning and also the CodeCache.
+ // Performs cleaning of data structures after class unloading.
void complete_cleaning(BoolObjectClosure* is_alive, bool class_unloading_occurred);
// Redirty logged cards in the refinement queue.
--- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp Tue Jan 29 11:30:17 2019 +0100
@@ -1655,11 +1655,9 @@
GCTraceTime(Debug, gc, phases) debug("Class Unloading", _gc_timer_cm);
bool purged_classes = SystemDictionary::do_unloading(_gc_timer_cm);
_g1h->complete_cleaning(&g1_is_alive, purged_classes);
- } else {
- GCTraceTime(Debug, gc, phases) debug("Cleanup", _gc_timer_cm);
- // No need to clean string table as it is treated as strong roots when
- // class unloading is disabled.
- _g1h->partial_cleaning(&g1_is_alive, false, G1StringDedup::is_enabled());
+ } else if (StringDedup::is_enabled()) {
+ GCTraceTime(Debug, gc, phases) debug("String Deduplication", _gc_timer_cm);
+ _g1h->string_dedup_cleaning(&g1_is_alive, NULL);
}
}
--- a/src/hotspot/share/gc/g1/g1FullCollector.cpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1FullCollector.cpp Tue Jan 29 11:30:17 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -224,10 +224,10 @@
// Unload classes and purge the SystemDictionary.
bool purged_class = SystemDictionary::do_unloading(scope()->timer());
_heap->complete_cleaning(&_is_alive, purged_class);
- } else {
- GCTraceTime(Debug, gc, phases) debug("Phase 1: String and Symbol Tables Cleanup", scope()->timer());
- // If no class unloading just clean out strings.
- _heap->partial_cleaning(&_is_alive, true, G1StringDedup::is_enabled());
+ } else if (G1StringDedup::is_enabled()) {
+ GCTraceTime(Debug, gc, phases) debug("Phase 1: String Dedup Cleanup", scope()->timer());
+ // If no class unloading just clean out string deduplication data.
+ _heap->string_dedup_cleaning(&_is_alive, NULL);
}
scope()->tracer()->report_object_count_after_gc(&_is_alive);
--- a/src/hotspot/share/gc/g1/g1FullGCAdjustTask.cpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1FullGCAdjustTask.cpp Tue Jan 29 11:30:17 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -86,7 +86,7 @@
_weak_proc_task(collector->workers()),
_hrclaimer(collector->workers()),
_adjust(),
- _adjust_string_dedup(NULL, &_adjust, G1StringDedup::is_enabled()) {
+ _string_dedup_cleaning_task(NULL, &_adjust, false) {
// Need cleared claim bits for the roots processing
ClassLoaderDataGraph::clear_claimed_marks();
}
@@ -110,15 +110,10 @@
CLDToOopClosure adjust_cld(&_adjust, ClassLoaderData::_claim_strong);
CodeBlobToOopClosure adjust_code(&_adjust, CodeBlobToOopClosure::FixRelocations);
- _root_processor.process_all_roots(
- &_adjust,
- &adjust_cld,
- &adjust_code);
+ _root_processor.process_all_roots(&_adjust, &adjust_cld, &adjust_code);
- // Adjust string dedup if enabled.
- if (G1StringDedup::is_enabled()) {
- G1StringDedup::parallel_unlink(&_adjust_string_dedup, worker_id);
- }
+ // Adjust string dedup data structures.
+ _string_dedup_cleaning_task.work(worker_id);
// Now adjust pointers region by region
G1AdjustRegionClosure blk(collector()->mark_bitmap(), worker_id);
--- a/src/hotspot/share/gc/g1/g1FullGCAdjustTask.hpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1FullGCAdjustTask.hpp Tue Jan 29 11:30:17 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,7 @@
#include "gc/g1/g1RootProcessor.hpp"
#include "gc/g1/g1StringDedup.hpp"
#include "gc/g1/heapRegionManager.hpp"
+#include "gc/shared/parallelCleaning.hpp"
#include "gc/shared/weakProcessorPhaseTimes.hpp"
#include "gc/shared/weakProcessor.hpp"
#include "utilities/ticks.hpp"
@@ -42,7 +43,7 @@
WeakProcessor::Task _weak_proc_task;
HeapRegionClaimer _hrclaimer;
G1AdjustClosure _adjust;
- G1StringDedupUnlinkOrOopsDoClosure _adjust_string_dedup;
+ StringDedupCleaningTask _string_dedup_cleaning_task;
public:
G1FullGCAdjustTask(G1FullCollector* collector);
--- a/src/hotspot/share/gc/g1/g1FullGCMarkTask.cpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1FullGCMarkTask.cpp Tue Jan 29 11:30:17 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -49,15 +49,13 @@
MarkingCodeBlobClosure code_closure(marker->mark_closure(), !CodeBlobToOopClosure::FixRelocations);
if (ClassUnloading) {
- _root_processor.process_strong_roots(
- marker->mark_closure(),
- marker->cld_closure(),
- &code_closure);
+ _root_processor.process_strong_roots(marker->mark_closure(),
+ marker->cld_closure(),
+ &code_closure);
} else {
- _root_processor.process_all_roots_no_string_table(
- marker->mark_closure(),
- marker->cld_closure(),
- &code_closure);
+ _root_processor.process_all_roots(marker->mark_closure(),
+ marker->cld_closure(),
+ &code_closure);
}
// Mark stack is populated, now process and drain it.
--- a/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp Tue Jan 29 11:30:17 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -53,7 +53,6 @@
// Root scanning phases
_gc_par_phases[ThreadRoots] = new WorkerDataArray<double>(max_gc_threads, "Thread Roots (ms):");
- _gc_par_phases[StringTableRoots] = new WorkerDataArray<double>(max_gc_threads, "StringTable Roots (ms):");
_gc_par_phases[UniverseRoots] = new WorkerDataArray<double>(max_gc_threads, "Universe Roots (ms):");
_gc_par_phases[JNIRoots] = new WorkerDataArray<double>(max_gc_threads, "JNI Handles Roots (ms):");
_gc_par_phases[ObjectSynchronizerRoots] = new WorkerDataArray<double>(max_gc_threads, "ObjectSynchronizer Roots (ms):");
@@ -136,7 +135,7 @@
_cur_strong_code_root_purge_time_ms = 0.0;
_cur_evac_fail_recalc_used = 0.0;
_cur_evac_fail_remove_self_forwards = 0.0;
- _cur_string_dedup_fixup_time_ms = 0.0;
+ _cur_string_deduplication_time_ms = 0.0;
_cur_prepare_tlab_time_ms = 0.0;
_cur_resize_tlab_time_ms = 0.0;
_cur_derived_pointer_table_update_time_ms = 0.0;
@@ -290,12 +289,12 @@
}
}
-void G1GCPhaseTimes::debug_phase(WorkerDataArray<double>* phase) const {
+void G1GCPhaseTimes::debug_phase(WorkerDataArray<double>* phase, uint extra_indent) const {
LogTarget(Debug, gc, phases) lt;
if (lt.is_enabled()) {
ResourceMark rm;
LogStream ls(lt);
- log_phase(phase, 2, &ls, true);
+ log_phase(phase, 2 + extra_indent, &ls, true);
}
}
@@ -417,7 +416,7 @@
_recorded_total_free_cset_time_ms +
_cur_fast_reclaim_humongous_time_ms +
_cur_expand_heap_time_ms +
- _cur_string_dedup_fixup_time_ms;
+ _cur_string_deduplication_time_ms;
info_time("Post Evacuate Collection Set", sum_ms);
@@ -430,9 +429,9 @@
_weak_phase_times.log_print(2);
if (G1StringDedup::is_enabled()) {
- debug_time("String Dedup Fixup", _cur_string_dedup_fixup_time_ms);
- debug_phase(_gc_par_phases[StringDedupQueueFixup]);
- debug_phase(_gc_par_phases[StringDedupTableFixup]);
+ debug_time("String Deduplication", _cur_string_deduplication_time_ms);
+ debug_phase(_gc_par_phases[StringDedupQueueFixup], 1);
+ debug_phase(_gc_par_phases[StringDedupTableFixup], 1);
}
if (G1CollectedHeap::heap()->evacuation_failed()) {
@@ -497,7 +496,6 @@
"GCWorkerStart",
"ExtRootScan",
"ThreadRoots",
- "StringTableRoots",
"UniverseRoots",
"JNIRoots",
"ObjectSynchronizerRoots",
--- a/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp Tue Jan 29 11:30:17 2019 +0100
@@ -48,7 +48,6 @@
GCWorkerStart,
ExtRootScan,
ThreadRoots,
- StringTableRoots,
UniverseRoots,
JNIRoots,
ObjectSynchronizerRoots,
@@ -104,8 +103,6 @@
private:
// Markers for grouping the phases in the GCPhases enum above
static const int GCMainParPhasesLast = GCWorkerEnd;
- static const int StringDedupPhasesFirst = StringDedupQueueFixup;
- static const int StringDedupPhasesLast = StringDedupTableFixup;
WorkerDataArray<double>* _gc_par_phases[GCParPhasesSentinel];
@@ -134,7 +131,7 @@
double _cur_evac_fail_recalc_used;
double _cur_evac_fail_remove_self_forwards;
- double _cur_string_dedup_fixup_time_ms;
+ double _cur_string_deduplication_time_ms;
double _cur_prepare_tlab_time_ms;
double _cur_resize_tlab_time_ms;
@@ -187,7 +184,7 @@
void details(T* phase, const char* indent) const;
void log_phase(WorkerDataArray<double>* phase, uint indent, outputStream* out, bool print_sum) const;
- void debug_phase(WorkerDataArray<double>* phase) const;
+ void debug_phase(WorkerDataArray<double>* phase, uint extra_indent = 0) const;
void trace_phase(WorkerDataArray<double>* phase, bool print_sum = true) const;
void info_time(const char* name, double value) const;
@@ -272,8 +269,8 @@
_cur_evac_fail_remove_self_forwards = ms;
}
- void record_string_dedup_fixup_time(double ms) {
- _cur_string_dedup_fixup_time_ms = ms;
+ void record_string_deduplication_time(double ms) {
+ _cur_string_deduplication_time_ms = ms;
}
void record_ref_proc_time(double ms) {
--- a/src/hotspot/share/gc/g1/g1HeapVerifier.cpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1HeapVerifier.cpp Tue Jan 29 11:30:17 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -490,9 +490,7 @@
{
G1RootProcessor root_processor(_g1h, 1);
- root_processor.process_all_roots(&rootsCl,
- &cldCl,
- &blobsCl);
+ root_processor.process_all_roots(&rootsCl, &cldCl, &blobsCl);
}
bool failures = rootsCl.failures() || codeRootsCl.failures();
--- a/src/hotspot/share/gc/g1/g1RootProcessor.cpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1RootProcessor.cpp Tue Jan 29 11:30:17 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -90,7 +90,6 @@
}
process_vm_roots(closures, phase_times, worker_i);
- process_string_table_roots(closures, phase_times, worker_i);
{
// Now the CM ref_processor roots.
@@ -188,34 +187,17 @@
void G1RootProcessor::process_all_roots(OopClosure* oops,
CLDClosure* clds,
- CodeBlobClosure* blobs,
- bool process_string_table) {
+ CodeBlobClosure* blobs) {
AllRootsClosures closures(oops, clds);
process_java_roots(&closures, NULL, 0);
process_vm_roots(&closures, NULL, 0);
- if (process_string_table) {
- process_string_table_roots(&closures, NULL, 0);
- }
process_code_cache_roots(blobs, NULL, 0);
_process_strong_tasks.all_tasks_completed(n_workers());
}
-void G1RootProcessor::process_all_roots(OopClosure* oops,
- CLDClosure* clds,
- CodeBlobClosure* blobs) {
- process_all_roots(oops, clds, blobs, true);
-}
-
-void G1RootProcessor::process_all_roots_no_string_table(OopClosure* oops,
- CLDClosure* clds,
- CodeBlobClosure* blobs) {
- assert(!ClassUnloading, "Should only be used when class unloading is disabled");
- process_all_roots(oops, clds, blobs, false);
-}
-
void G1RootProcessor::process_java_roots(G1RootClosures* closures,
G1GCPhaseTimes* phase_times,
uint worker_i) {
@@ -295,16 +277,6 @@
}
}
-void G1RootProcessor::process_string_table_roots(G1RootClosures* closures,
- G1GCPhaseTimes* phase_times,
- uint worker_i) {
- assert(closures->weak_oops() != NULL, "Should only be called when all roots are processed");
- G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::StringTableRoots, worker_i);
- // All threads execute the following. A specific chunk of buckets
- // from the StringTable are the individual tasks.
- StringTable::possibly_parallel_oops_do(&_par_state_string, closures->weak_oops());
-}
-
void G1RootProcessor::process_code_cache_roots(CodeBlobClosure* code_closure,
G1GCPhaseTimes* phase_times,
uint worker_i) {
--- a/src/hotspot/share/gc/g1/g1RootProcessor.hpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1RootProcessor.hpp Tue Jan 29 11:30:17 2019 +0100
@@ -75,11 +75,6 @@
void worker_has_discovered_all_strong_classes();
void wait_until_all_strong_classes_discovered();
- void process_all_roots(OopClosure* oops,
- CLDClosure* clds,
- CodeBlobClosure* blobs,
- bool process_string_table);
-
void process_java_roots(G1RootClosures* closures,
G1GCPhaseTimes* phase_times,
uint worker_i);
@@ -88,10 +83,6 @@
G1GCPhaseTimes* phase_times,
uint worker_i);
- void process_string_table_roots(G1RootClosures* closures,
- G1GCPhaseTimes* phase_times,
- uint worker_i);
-
void process_code_cache_roots(CodeBlobClosure* code_closure,
G1GCPhaseTimes* phase_times,
uint worker_i);
@@ -101,7 +92,7 @@
// Apply correct closures from pss to the strongly and weakly reachable roots in the system
// in a single pass.
- // Record and report timing measurements for sub phases using the worker_i
+ // Record and report timing measurements for sub phases using worker_id.
void evacuate_roots(G1ParScanThreadState* pss, uint worker_id);
// Apply oops, clds and blobs to all strongly reachable roots in the system
@@ -114,13 +105,6 @@
CLDClosure* clds,
CodeBlobClosure* blobs);
- // Apply oops, clds and blobs to strongly and weakly reachable roots in the system,
- // the only thing different from process_all_roots is that we skip the string table
- // to avoid keeping every string live when doing class unloading.
- void process_all_roots_no_string_table(OopClosure* oops,
- CLDClosure* clds,
- CodeBlobClosure* blobs);
-
// Number of worker threads used by the root processor.
uint n_workers() const;
};
--- a/src/hotspot/share/gc/g1/g1StringDedup.cpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1StringDedup.cpp Tue Jan 29 11:30:17 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -89,53 +89,3 @@
}
}
-void G1StringDedup::oops_do(OopClosure* keep_alive) {
- assert(is_enabled(), "String deduplication not enabled");
- unlink_or_oops_do(NULL, keep_alive, true /* allow_resize_and_rehash */);
-}
-
-void G1StringDedup::parallel_unlink(G1StringDedupUnlinkOrOopsDoClosure* unlink, uint worker_id) {
- assert(is_enabled(), "String deduplication not enabled");
- StringDedupQueue::unlink_or_oops_do(unlink);
- StringDedupTable::unlink_or_oops_do(unlink, worker_id);
-}
-
-//
-// Task for parallel unlink_or_oops_do() operation on the deduplication queue
-// and table.
-//
-class G1StringDedupUnlinkOrOopsDoTask : public AbstractGangTask {
-private:
- G1StringDedupUnlinkOrOopsDoClosure _cl;
- G1GCPhaseTimes* _phase_times;
-
-public:
- G1StringDedupUnlinkOrOopsDoTask(BoolObjectClosure* is_alive,
- OopClosure* keep_alive,
- bool allow_resize_and_rehash,
- G1GCPhaseTimes* phase_times) :
- AbstractGangTask("G1StringDedupUnlinkOrOopsDoTask"),
- _cl(is_alive, keep_alive, allow_resize_and_rehash), _phase_times(phase_times) { }
-
- virtual void work(uint worker_id) {
- {
- G1GCParPhaseTimesTracker x(_phase_times, G1GCPhaseTimes::StringDedupQueueFixup, worker_id);
- StringDedupQueue::unlink_or_oops_do(&_cl);
- }
- {
- G1GCParPhaseTimesTracker x(_phase_times, G1GCPhaseTimes::StringDedupTableFixup, worker_id);
- StringDedupTable::unlink_or_oops_do(&_cl, worker_id);
- }
- }
-};
-
-void G1StringDedup::unlink_or_oops_do(BoolObjectClosure* is_alive,
- OopClosure* keep_alive,
- bool allow_resize_and_rehash,
- G1GCPhaseTimes* phase_times) {
- assert(is_enabled(), "String deduplication not enabled");
-
- G1StringDedupUnlinkOrOopsDoTask task(is_alive, keep_alive, allow_resize_and_rehash, phase_times);
- G1CollectedHeap* g1h = G1CollectedHeap::heap();
- g1h->workers()->run_task(&task);
-}
--- a/src/hotspot/share/gc/g1/g1StringDedup.hpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1StringDedup.hpp Tue Jan 29 11:30:17 2019 +0100
@@ -78,35 +78,6 @@
static void enqueue_from_mark(oop java_string, uint worker_id);
static void enqueue_from_evacuation(bool from_young, bool to_young,
unsigned int queue, oop java_string);
-
- static void oops_do(OopClosure* keep_alive);
- static void parallel_unlink(G1StringDedupUnlinkOrOopsDoClosure* unlink, uint worker_id);
- static void unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive,
- bool allow_resize_and_rehash, G1GCPhaseTimes* phase_times = NULL);
-};
-
-//
-// This closure encapsulates the state and the closures needed when scanning
-// the deduplication queue and table during the unlink_or_oops_do() operation.
-// A single instance of this closure is created and then shared by all worker
-// threads participating in the scan.
-//
-class G1StringDedupUnlinkOrOopsDoClosure : public StringDedupUnlinkOrOopsDoClosure {
-public:
- G1StringDedupUnlinkOrOopsDoClosure(BoolObjectClosure* is_alive,
- OopClosure* keep_alive,
- bool allow_resize_and_rehash) :
- StringDedupUnlinkOrOopsDoClosure(is_alive, keep_alive) {
- if (G1StringDedup::is_enabled()) {
- G1StringDedup::gc_prologue(allow_resize_and_rehash);
- }
- }
-
- ~G1StringDedupUnlinkOrOopsDoClosure() {
- if (G1StringDedup::is_enabled()) {
- G1StringDedup::gc_epilogue();
- }
- }
};
#endif // SHARE_GC_G1_G1STRINGDEDUP_HPP
--- a/src/hotspot/share/gc/parallel/psMarkSweep.cpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/parallel/psMarkSweep.cpp Tue Jan 29 11:30:17 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -567,12 +567,6 @@
}
{
- GCTraceTime(Debug, gc, phases) t("Scrub String Table", _gc_timer);
- // Delete entries for dead interned strings.
- StringTable::unlink(is_alive_closure());
- }
-
- {
GCTraceTime(Debug, gc, phases) t("Scrub Symbol Table", _gc_timer);
// Clean up unreferenced symbols in symbol table.
SymbolTable::unlink();
@@ -630,7 +624,6 @@
CodeBlobToOopClosure adjust_from_blobs(adjust_pointer_closure(), CodeBlobToOopClosure::FixRelocations);
CodeCache::blobs_do(&adjust_from_blobs);
AOTLoader::oops_do(adjust_pointer_closure());
- StringTable::oops_do(adjust_pointer_closure());
ref_processor()->weak_oops_do(adjust_pointer_closure());
PSScavenge::reference_processor()->weak_oops_do(adjust_pointer_closure());
--- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp Tue Jan 29 11:30:17 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -2185,12 +2185,6 @@
}
{
- GCTraceTime(Debug, gc, phases) t("Scrub String Table", &_gc_timer);
- // Delete entries for dead interned strings.
- StringTable::unlink(is_alive_closure());
- }
-
- {
GCTraceTime(Debug, gc, phases) t("Scrub Symbol Table", &_gc_timer);
// Clean up unreferenced symbols in symbol table.
SymbolTable::unlink();
@@ -2226,7 +2220,6 @@
CodeBlobToOopClosure adjust_from_blobs(&oop_closure, CodeBlobToOopClosure::FixRelocations);
CodeCache::blobs_do(&adjust_from_blobs);
AOTLoader::oops_do(&oop_closure);
- StringTable::oops_do(&oop_closure);
ref_processor()->weak_oops_do(&oop_closure);
// Roots were visited so references into the young gen in roots
// may have been scanned. Process them also.
--- a/src/hotspot/share/gc/parallel/psScavenge.cpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/parallel/psScavenge.cpp Tue Jan 29 11:30:17 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -430,12 +430,6 @@
WeakProcessor::weak_oops_do(&_is_alive_closure, &root_closure);
}
- {
- GCTraceTime(Debug, gc, phases) tm("Scrub String Table", &_gc_timer);
- // Unlink any dead interned Strings and process the remaining live ones.
- StringTable::unlink_or_oops_do(&_is_alive_closure, &root_closure);
- }
-
// Verify that usage of root_closure didn't copy any objects.
assert(promotion_manager->stacks_empty(),"stacks should be empty at this point");
--- a/src/hotspot/share/gc/serial/genMarkSweep.cpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/serial/genMarkSweep.cpp Tue Jan 29 11:30:17 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -240,12 +240,6 @@
}
{
- GCTraceTime(Debug, gc, phases) t("Scrub String Table", gc_timer());
- // Delete entries for dead interned strings.
- StringTable::unlink(&is_alive);
- }
-
- {
GCTraceTime(Debug, gc, phases) t("Scrub Symbol Table", gc_timer());
// Clean up unreferenced symbols in symbol table.
SymbolTable::unlink();
--- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp Tue Jan 29 11:30:17 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -849,33 +849,14 @@
}
}
-void GenCollectedHeap::process_string_table_roots(StrongRootsScope* scope,
- OopClosure* root_closure,
- OopStorage::ParState<false, false>* par_state_string) {
- assert(root_closure != NULL, "Must be set");
- // All threads execute the following. A specific chunk of buckets
- // from the StringTable are the individual tasks.
-
- // Either we should be single threaded or have a ParState
- assert((scope->n_threads() <= 1) || par_state_string != NULL, "Parallel but no ParState");
-
- if (scope->n_threads() > 1) {
- StringTable::possibly_parallel_oops_do(par_state_string, root_closure);
- } else {
- StringTable::oops_do(root_closure);
- }
-}
-
void GenCollectedHeap::young_process_roots(StrongRootsScope* scope,
OopsInGenClosure* root_closure,
OopsInGenClosure* old_gen_closure,
- CLDClosure* cld_closure,
- OopStorage::ParState<false, false>* par_state_string) {
+ CLDClosure* cld_closure) {
MarkingCodeBlobClosure mark_code_closure(root_closure, CodeBlobToOopClosure::FixRelocations);
process_roots(scope, SO_ScavengeCodeCache, root_closure,
cld_closure, cld_closure, &mark_code_closure);
- process_string_table_roots(scope, root_closure, par_state_string);
if (_process_strong_tasks->try_claim_task(GCH_PS_younger_gens)) {
root_closure->reset_generation();
@@ -895,19 +876,11 @@
ScanningOption so,
bool only_strong_roots,
OopsInGenClosure* root_closure,
- CLDClosure* cld_closure,
- OopStorage::ParState<false, false>* par_state_string) {
+ CLDClosure* cld_closure) {
MarkingCodeBlobClosure mark_code_closure(root_closure, is_adjust_phase);
CLDClosure* weak_cld_closure = only_strong_roots ? NULL : cld_closure;
process_roots(scope, so, root_closure, cld_closure, weak_cld_closure, &mark_code_closure);
- if (is_adjust_phase) {
- // We never treat the string table as roots during marking
- // for the full gc, so we only need to process it during
- // the adjust phase.
- process_string_table_roots(scope, root_closure, par_state_string);
- }
-
_process_strong_tasks->all_tasks_completed(scope->n_threads());
}
--- a/src/hotspot/share/gc/shared/genCollectedHeap.hpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.hpp Tue Jan 29 11:30:17 2019 +0100
@@ -400,10 +400,6 @@
CLDClosure* weak_cld_closure,
CodeBlobToOopClosure* code_roots);
- void process_string_table_roots(StrongRootsScope* scope,
- OopClosure* root_closure,
- OopStorage::ParState<false, false>* par_state_string);
-
// Accessor for memory state verification support
NOT_PRODUCT(
virtual size_t skip_header_HeapWords() { return 0; }
@@ -416,16 +412,14 @@
void young_process_roots(StrongRootsScope* scope,
OopsInGenClosure* root_closure,
OopsInGenClosure* old_gen_closure,
- CLDClosure* cld_closure,
- OopStorage::ParState<false, false>* par_state_string = NULL);
+ CLDClosure* cld_closure);
void full_process_roots(StrongRootsScope* scope,
bool is_adjust_phase,
ScanningOption so,
bool only_strong_roots,
OopsInGenClosure* root_closure,
- CLDClosure* cld_closure,
- OopStorage::ParState<false, false>* par_state_string = NULL);
+ CLDClosure* cld_closure);
// Apply "root_closure" to all the weak roots of the system.
// These include JNI weak roots, string table,
--- a/src/hotspot/share/gc/shared/parallelCleaning.cpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/shared/parallelCleaning.cpp Tue Jan 29 11:30:17 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,48 +31,35 @@
#include "memory/resourceArea.hpp"
#include "logging/log.hpp"
-StringCleaningTask::StringCleaningTask(BoolObjectClosure* is_alive, StringDedupUnlinkOrOopsDoClosure* dedup_closure, bool process_strings) :
- AbstractGangTask("String Unlinking"),
- _is_alive(is_alive),
- _dedup_closure(dedup_closure),
- _par_state_string(StringTable::weak_storage()),
- _initial_string_table_size((int) StringTable::the_table()->table_size()),
- _process_strings(process_strings), _strings_processed(0), _strings_removed(0) {
+StringDedupCleaningTask::StringDedupCleaningTask(BoolObjectClosure* is_alive,
+ OopClosure* keep_alive,
+ bool resize_table) :
+ AbstractGangTask("String Dedup Cleaning"),
+ _dedup_closure(is_alive, keep_alive) {
- if (process_strings) {
- StringTable::reset_dead_counter();
+ if (StringDedup::is_enabled()) {
+ StringDedup::gc_prologue(resize_table);
}
}
-StringCleaningTask::~StringCleaningTask() {
- log_info(gc, stringtable)(
- "Cleaned string table, "
- "strings: " SIZE_FORMAT " processed, " SIZE_FORMAT " removed",
- strings_processed(), strings_removed());
- if (_process_strings) {
- StringTable::finish_dead_counter();
+StringDedupCleaningTask::~StringDedupCleaningTask() {
+ if (StringDedup::is_enabled()) {
+ StringDedup::gc_epilogue();
}
}
-void StringCleaningTask::work(uint worker_id) {
- size_t strings_processed = 0;
- size_t strings_removed = 0;
- if (_process_strings) {
- StringTable::possibly_parallel_unlink(&_par_state_string, _is_alive, &strings_processed, &strings_removed);
- Atomic::add(strings_processed, &_strings_processed);
- Atomic::add(strings_removed, &_strings_removed);
- }
- if (_dedup_closure != NULL) {
- StringDedup::parallel_unlink(_dedup_closure, worker_id);
+void StringDedupCleaningTask::work(uint worker_id) {
+ if (StringDedup::is_enabled()) {
+ StringDedup::parallel_unlink(&_dedup_closure, worker_id);
}
}
CodeCacheUnloadingTask::CodeCacheUnloadingTask(uint num_workers, BoolObjectClosure* is_alive, bool unloading_occurred) :
- _unloading_scope(is_alive),
- _unloading_occurred(unloading_occurred),
- _num_workers(num_workers),
- _first_nmethod(NULL),
- _claimed_nmethod(NULL) {
+ _unloading_scope(is_alive),
+ _unloading_occurred(unloading_occurred),
+ _num_workers(num_workers),
+ _first_nmethod(NULL),
+ _claimed_nmethod(NULL) {
// Get first alive nmethod
CompiledMethodIterator iter(CompiledMethodIterator::only_alive);
if(iter.next()) {
@@ -175,10 +162,12 @@
}
ParallelCleaningTask::ParallelCleaningTask(BoolObjectClosure* is_alive,
- StringDedupUnlinkOrOopsDoClosure* dedup_closure, uint num_workers, bool unloading_occurred) :
+ uint num_workers,
+ bool unloading_occurred,
+ bool resize_dedup_table) :
AbstractGangTask("Parallel Cleaning"),
_unloading_occurred(unloading_occurred),
- _string_task(is_alive, StringDedup::is_enabled() ? dedup_closure : NULL, true),
+ _string_dedup_task(is_alive, NULL, resize_dedup_table),
_code_cache_task(num_workers, is_alive, unloading_occurred),
_klass_cleaning_task() {
}
@@ -188,8 +177,8 @@
// Do first pass of code cache cleaning.
_code_cache_task.work(worker_id);
- // Clean the Strings and Symbols.
- _string_task.work(worker_id);
+ // Clean the string dedup data structures.
+ _string_dedup_task.work(worker_id);
// Clean all klasses that were not unloaded.
// The weak metadata in klass doesn't need to be
--- a/src/hotspot/share/gc/shared/parallelCleaning.hpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/shared/parallelCleaning.hpp Tue Jan 29 11:30:17 2019 +0100
@@ -33,27 +33,14 @@
class ParallelCleaningTask;
-class StringCleaningTask : public AbstractGangTask {
-private:
- BoolObjectClosure* _is_alive;
- StringDedupUnlinkOrOopsDoClosure * const _dedup_closure;
-
- OopStorage::ParState<false /* concurrent */, false /* const */> _par_state_string;
-
- int _initial_string_table_size;
-
- bool _process_strings;
- volatile size_t _strings_processed;
- volatile size_t _strings_removed;
+class StringDedupCleaningTask : public AbstractGangTask {
+ StringDedupUnlinkOrOopsDoClosure _dedup_closure;
public:
- StringCleaningTask(BoolObjectClosure* is_alive, StringDedupUnlinkOrOopsDoClosure* dedup_closure, bool process_strings);
- ~StringCleaningTask();
+ StringDedupCleaningTask(BoolObjectClosure* is_alive, OopClosure* keep_alive, bool resize_table);
+ ~StringDedupCleaningTask();
void work(uint worker_id);
-
- size_t strings_processed() const { return _strings_processed; }
- size_t strings_removed() const { return _strings_removed; }
};
class CodeCacheUnloadingTask {
@@ -100,18 +87,21 @@
void work();
};
-// To minimize the remark pause times, the tasks below are done in parallel.
+// Do cleanup of some weakly held data in the same parallel task.
+// Assumes a non-moving context.
class ParallelCleaningTask : public AbstractGangTask {
private:
- bool _unloading_occurred;
- StringCleaningTask _string_task;
- CodeCacheUnloadingTask _code_cache_task;
- KlassCleaningTask _klass_cleaning_task;
+ bool _unloading_occurred;
+ StringDedupCleaningTask _string_dedup_task;
+ CodeCacheUnloadingTask _code_cache_task;
+ KlassCleaningTask _klass_cleaning_task;
public:
// The constructor is run in the VMThread.
- ParallelCleaningTask(BoolObjectClosure* is_alive, StringDedupUnlinkOrOopsDoClosure* dedup_closure,
- uint num_workers, bool unloading_occurred);
+ ParallelCleaningTask(BoolObjectClosure* is_alive,
+ uint num_workers,
+ bool unloading_occurred,
+ bool resize_dedup_table);
void work(uint worker_id);
};
--- a/src/hotspot/share/gc/shared/stringdedup/stringDedup.cpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/shared/stringdedup/stringDedup.cpp Tue Jan 29 11:30:17 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -53,7 +53,6 @@
StringDedupTable::deduplicate(java_string, &dummy);
}
-
void StringDedup::parallel_unlink(StringDedupUnlinkOrOopsDoClosure* unlink, uint worker_id) {
assert(is_enabled(), "String deduplication not enabled");
StringDedupQueue::unlink_or_oops_do(unlink);
@@ -80,5 +79,8 @@
StringDedupUnlinkOrOopsDoClosure::StringDedupUnlinkOrOopsDoClosure(BoolObjectClosure* is_alive,
OopClosure* keep_alive) :
- _is_alive(is_alive), _keep_alive(keep_alive) {
+ _always_true(),
+ _do_nothing(),
+ _is_alive(is_alive != NULL ? is_alive : &_always_true),
+ _keep_alive(keep_alive != NULL ? keep_alive : &_do_nothing) {
}
--- a/src/hotspot/share/gc/shared/stringdedup/stringDedup.hpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/shared/stringdedup/stringDedup.hpp Tue Jan 29 11:30:17 2019 +0100
@@ -113,30 +113,18 @@
// the deduplication queue and table during the unlink_or_oops_do() operation.
//
class StringDedupUnlinkOrOopsDoClosure : public StackObj {
-private:
+ AlwaysTrueClosure _always_true;
+ DoNothingClosure _do_nothing;
BoolObjectClosure* _is_alive;
OopClosure* _keep_alive;
public:
StringDedupUnlinkOrOopsDoClosure(BoolObjectClosure* is_alive,
- OopClosure* keep_alive);
+ OopClosure* keep_alive);
- // Applies and returns the result from the is_alive closure, or
- // returns true if no such closure was provided.
- bool is_alive(oop o) {
- if (_is_alive != NULL) {
- return _is_alive->do_object_b(o);
- }
- return true;
- }
+ bool is_alive(oop o) { return _is_alive->do_object_b(o); }
- // Applies the keep_alive closure, or does nothing if no such
- // closure was provided.
- void keep_alive(oop* p) {
- if (_keep_alive != NULL) {
- _keep_alive->do_oop(p);
- }
- }
+ void keep_alive(oop* p) { _keep_alive->do_oop(p); }
};
#endif // SHARE_GC_SHARED_STRINGDEDUP_STRINGDEDUP_HPP
--- a/src/hotspot/share/gc/shared/weakProcessor.cpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/shared/weakProcessor.cpp Tue Jan 29 11:30:17 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,9 +23,9 @@
*/
#include "precompiled.hpp"
+#include "classfile/stringTable.hpp"
#include "gc/shared/oopStorage.inline.hpp"
#include "gc/shared/oopStorageParState.inline.hpp"
-#include "gc/shared/weakProcessor.hpp"
#include "gc/shared/weakProcessor.inline.hpp"
#include "gc/shared/weakProcessorPhases.hpp"
#include "gc/shared/weakProcessorPhaseTimes.hpp"
@@ -35,13 +35,19 @@
#include "utilities/macros.hpp"
void WeakProcessor::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive) {
+ StringTable::reset_dead_counter();
+ CountingIsAliveClosure<BoolObjectClosure> cl(is_alive);
FOR_EACH_WEAK_PROCESSOR_PHASE(phase) {
if (WeakProcessorPhases::is_serial(phase)) {
- WeakProcessorPhases::processor(phase)(is_alive, keep_alive);
+ WeakProcessorPhases::processor(phase)(&cl, keep_alive);
} else {
- WeakProcessorPhases::oop_storage(phase)->weak_oops_do(is_alive, keep_alive);
+ WeakProcessorPhases::oop_storage(phase)->weak_oops_do(&cl, keep_alive);
+ }
+ if (WeakProcessorPhases::is_stringtable(phase)) {
+ StringTable::inc_dead_counter(cl.num_dead());
}
}
+ StringTable::finish_dead_counter();
}
void WeakProcessor::oops_do(OopClosure* closure) {
@@ -93,6 +99,7 @@
OopStorage* storage = WeakProcessorPhases::oop_storage(phase);
new (states++) StorageState(storage, _nworkers);
}
+ StringTable::reset_dead_counter();
}
WeakProcessor::Task::Task(uint nworkers) :
@@ -122,6 +129,7 @@
}
FREE_C_HEAP_ARRAY(StorageState, _storage_states);
}
+ StringTable::finish_dead_counter();
}
void WeakProcessor::GangTask::work(uint worker_id) {
--- a/src/hotspot/share/gc/shared/weakProcessor.inline.hpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/shared/weakProcessor.inline.hpp Tue Jan 29 11:30:17 2019 +0100
@@ -25,6 +25,7 @@
#ifndef SHARE_GC_SHARED_WEAKPROCESSOR_INLINE_HPP
#define SHARE_GC_SHARED_WEAKPROCESSOR_INLINE_HPP
+#include "classfile/stringTable.hpp"
#include "gc/shared/oopStorage.inline.hpp"
#include "gc/shared/oopStorageParState.inline.hpp"
#include "gc/shared/weakProcessor.hpp"
@@ -36,6 +37,27 @@
class BoolObjectClosure;
class OopClosure;
+template<typename T>
+class CountingIsAliveClosure : public BoolObjectClosure {
+ T* _inner;
+
+ size_t _num_dead;
+ size_t _num_total;
+
+public:
+ CountingIsAliveClosure(T* cl) : _inner(cl), _num_dead(0), _num_total(0) { }
+
+ virtual bool do_object_b(oop obj) {
+ bool result = _inner->do_object_b(obj);
+ _num_dead += !result;
+ _num_total++;
+ return result;
+ }
+
+ size_t num_dead() const { return _num_dead; }
+ size_t num_total() const { return _num_total; }
+};
+
template<typename IsAlive, typename KeepAlive>
void WeakProcessor::Task::work(uint worker_id,
IsAlive* is_alive,
@@ -45,16 +67,26 @@
worker_id, _nworkers);
FOR_EACH_WEAK_PROCESSOR_PHASE(phase) {
+ CountingIsAliveClosure<IsAlive> cl(is_alive);
if (WeakProcessorPhases::is_serial(phase)) {
uint serial_index = WeakProcessorPhases::serial_index(phase);
if (_serial_phases_done.try_claim_task(serial_index)) {
WeakProcessorPhaseTimeTracker pt(_phase_times, phase);
- WeakProcessorPhases::processor(phase)(is_alive, keep_alive);
+ WeakProcessorPhases::processor(phase)(&cl, keep_alive);
+ if (_phase_times != NULL) {
+ _phase_times->record_phase_items(phase, cl.num_dead(), cl.num_total());
+ }
}
} else {
WeakProcessorPhaseTimeTracker pt(_phase_times, phase, worker_id);
uint storage_index = WeakProcessorPhases::oop_storage_index(phase);
- _storage_states[storage_index].weak_oops_do(is_alive, keep_alive);
+ _storage_states[storage_index].weak_oops_do(&cl, keep_alive);
+ if (_phase_times != NULL) {
+ _phase_times->record_worker_items(worker_id, phase, cl.num_dead(), cl.num_total());
+ }
+ }
+ if (WeakProcessorPhases::is_stringtable(phase)) {
+ StringTable::inc_dead_counter(cl.num_dead());
}
}
--- a/src/hotspot/share/gc/shared/weakProcessorPhaseTimes.cpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/shared/weakProcessorPhaseTimes.cpp Tue Jan 29 11:30:17 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -49,6 +49,7 @@
#ifdef ASSERT
static bool is_initialized_time(double t) { return t >= 0.0; }
+static bool is_initialized_items(size_t i) { return i != 0; }
#endif // ASSERT
static void reset_times(double* times, size_t ntimes) {
@@ -57,28 +58,43 @@
}
}
+static void reset_items(size_t* items, size_t nitems) {
+ for (size_t i = 0; i < nitems; ++i) {
+ items[i] = 0;
+ }
+}
+
WeakProcessorPhaseTimes::WeakProcessorPhaseTimes(uint max_threads) :
_max_threads(max_threads),
_active_workers(0),
_total_time_sec(uninitialized_time),
- _worker_phase_times_sec()
+ _worker_data(),
+ _worker_dead_items(),
+ _worker_total_items()
{
assert(_max_threads > 0, "max_threads must not be zero");
reset_times(_phase_times_sec, ARRAY_SIZE(_phase_times_sec));
+ reset_items(_phase_dead_items, ARRAY_SIZE(_phase_dead_items));
+ reset_items(_phase_total_items, ARRAY_SIZE(_phase_total_items));
if (_max_threads > 1) {
- WorkerDataArray<double>** wpt = _worker_phase_times_sec;
+ WorkerDataArray<double>** wpt = _worker_data;
FOR_EACH_WEAK_PROCESSOR_OOP_STORAGE_PHASE(phase) {
const char* description = WeakProcessorPhases::description(phase);
- *wpt++ = new WorkerDataArray<double>(_max_threads, description);
+ *wpt = new WorkerDataArray<double>(_max_threads, description);
+ (*wpt)->link_thread_work_items(new WorkerDataArray<size_t>(_max_threads, "Dead"), DeadItems);
+ (*wpt)->link_thread_work_items(new WorkerDataArray<size_t>(_max_threads, "Total"), TotalItems);
+ wpt++;
}
}
}
WeakProcessorPhaseTimes::~WeakProcessorPhaseTimes() {
- for (size_t i = 0; i < ARRAY_SIZE(_worker_phase_times_sec); ++i) {
- delete _worker_phase_times_sec[i];
+ for (size_t i = 0; i < ARRAY_SIZE(_worker_data); ++i) {
+ delete _worker_data[i];
+ delete _worker_dead_items[i];
+ delete _worker_total_items[i];
}
}
@@ -100,9 +116,11 @@
_active_workers = 0;
_total_time_sec = uninitialized_time;
reset_times(_phase_times_sec, ARRAY_SIZE(_phase_times_sec));
+ reset_items(_phase_dead_items, ARRAY_SIZE(_phase_dead_items));
+ reset_items(_phase_total_items, ARRAY_SIZE(_phase_total_items));
if (_max_threads > 1) {
- for (size_t i = 0; i < ARRAY_SIZE(_worker_phase_times_sec); ++i) {
- _worker_phase_times_sec[i]->reset();
+ for (size_t i = 0; i < ARRAY_SIZE(_worker_data); ++i) {
+ _worker_data[i]->reset();
}
}
}
@@ -129,10 +147,20 @@
_phase_times_sec[phase_index(phase)] = time_sec;
}
+void WeakProcessorPhaseTimes::record_phase_items(WeakProcessorPhase phase, size_t num_dead, size_t num_total) {
+ uint p = phase_index(phase);
+ assert(!is_initialized_items(_phase_dead_items[p]),
+ "Already set dead items for phase %u", p);
+ assert(!is_initialized_items(_phase_total_items[p]),
+ "Already set total items for phase %u", p);
+ _phase_dead_items[p] = num_dead;
+ _phase_total_items[p] = num_total;
+}
+
WorkerDataArray<double>* WeakProcessorPhaseTimes::worker_data(WeakProcessorPhase phase) const {
assert_oop_storage_phase(phase);
assert(active_workers() > 1, "No worker data when single-threaded");
- return _worker_phase_times_sec[WeakProcessorPhases::oop_storage_index(phase)];
+ return _worker_data[WeakProcessorPhases::oop_storage_index(phase)];
}
double WeakProcessorPhaseTimes::worker_time_sec(uint worker_id, WeakProcessorPhase phase) const {
@@ -155,6 +183,18 @@
}
}
+void WeakProcessorPhaseTimes::record_worker_items(uint worker_id,
+ WeakProcessorPhase phase,
+ size_t num_dead,
+ size_t num_total) {
+ if (active_workers() == 1) {
+ record_phase_items(phase, num_dead, num_total);
+ } else {
+ worker_data(phase)->set_or_add_thread_work_item(worker_id, num_dead, DeadItems);
+ worker_data(phase)->set_or_add_thread_work_item(worker_id, num_total, TotalItems);
+ }
+}
+
static double elapsed_time_sec(Ticks start_time, Ticks end_time) {
return (end_time - start_time).seconds();
}
@@ -223,6 +263,16 @@
indent_str(indent),
WeakProcessorPhases::description(phase),
phase_time_sec(phase) * MILLIUNITS);
+
+ log_debug(gc, phases)("%s%s: " SIZE_FORMAT,
+ indent_str(indent + 1),
+ "Dead",
+ _phase_dead_items[phase_index(phase)]);
+
+ log_debug(gc, phases)("%s%s: " SIZE_FORMAT,
+ indent_str(indent + 1),
+ "Total",
+ _phase_total_items[phase_index(phase)]);
}
void WeakProcessorPhaseTimes::log_mt_phase_summary(WeakProcessorPhase phase,
@@ -231,27 +281,36 @@
LogStream ls(lt);
ls.print("%s", indents[indent]);
worker_data(phase)->print_summary_on(&ls, true);
+ log_mt_phase_details(worker_data(phase), indent + 1);
+
+ for (uint i = 0; i < worker_data(phase)->MaxThreadWorkItems; i++) {
+ WorkerDataArray<size_t>* work_items = worker_data(phase)->thread_work_items(i);
+ if (work_items != NULL) {
+ ls.print("%s", indents[indent + 1]);
+ work_items->print_summary_on(&ls, true);
+ log_mt_phase_details(work_items, indent + 1);
+ }
+ }
}
-void WeakProcessorPhaseTimes::log_mt_phase_details(WeakProcessorPhase phase,
+template <typename T>
+void WeakProcessorPhaseTimes::log_mt_phase_details(WorkerDataArray<T>* data,
uint indent) const {
LogTarget(Trace, gc, phases) lt;
- LogStream ls(lt);
- ls.print("%s", indents[indent]);
- worker_data(phase)->print_details_on(&ls);
+ if (lt.is_enabled()) {
+ LogStream ls(lt);
+ ls.print("%s", indents[indent]);
+ data->print_details_on(&ls);
+ }
}
void WeakProcessorPhaseTimes::log_print_phases(uint indent) const {
if (log_is_enabled(Debug, gc, phases)) {
- bool details_enabled = log_is_enabled(Trace, gc, phases);
FOR_EACH_WEAK_PROCESSOR_PHASE(phase) {
if (is_serial_phase(phase) || (active_workers() == 1)) {
log_st_phase(phase, indent);
} else {
log_mt_phase_summary(phase, indent);
- if (details_enabled) {
- log_mt_phase_details(phase, indent + 1);
- }
}
}
}
--- a/src/hotspot/share/gc/shared/weakProcessorPhaseTimes.hpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/shared/weakProcessorPhaseTimes.hpp Tue Jan 29 11:30:17 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,10 @@
template<typename T> class WorkerDataArray;
class WeakProcessorPhaseTimes : public CHeapObj<mtGC> {
+ enum {
+ DeadItems,
+ TotalItems
+ };
uint _max_threads;
uint _active_workers;
@@ -43,15 +47,20 @@
// processed by multiple threads are unused, as are entries for
// unexecuted phases.
double _phase_times_sec[WeakProcessorPhases::phase_count];
+ size_t _phase_dead_items[WeakProcessorPhases::phase_count];
+ size_t _phase_total_items[WeakProcessorPhases::phase_count];
- // Per-worker times, if multiple threads used and the phase was executed.
- WorkerDataArray<double>* _worker_phase_times_sec[WeakProcessorPhases::oop_storage_phase_count];
+ // Per-worker times and linked items, if multiple threads used and the phase was executed.
+ WorkerDataArray<double>* _worker_data[WeakProcessorPhases::oop_storage_phase_count];
+ WorkerDataArray<size_t>* _worker_dead_items[WeakProcessorPhases::oop_storage_phase_count];
+ WorkerDataArray<size_t>* _worker_total_items[WeakProcessorPhases::oop_storage_phase_count];
WorkerDataArray<double>* worker_data(WeakProcessorPhase phase) const;
void log_st_phase(WeakProcessorPhase phase, uint indent) const;
void log_mt_phase_summary(WeakProcessorPhase phase, uint indent) const;
- void log_mt_phase_details(WeakProcessorPhase phase, uint indent) const;
+ template <typename T>
+ void log_mt_phase_details(WorkerDataArray<T>* data, uint indent) const;
public:
WeakProcessorPhaseTimes(uint max_threads);
@@ -67,7 +76,9 @@
void record_total_time_sec(double time_sec);
void record_phase_time_sec(WeakProcessorPhase phase, double time_sec);
+ void record_phase_items(WeakProcessorPhase phase, size_t num_dead, size_t num_total);
void record_worker_time_sec(uint worker_id, WeakProcessorPhase phase, double time_sec);
+ void record_worker_items(uint worker_id, WeakProcessorPhase phase, size_t num_dead, size_t num_total);
void reset();
--- a/src/hotspot/share/gc/shared/weakProcessorPhases.cpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/shared/weakProcessorPhases.cpp Tue Jan 29 11:30:17 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "classfile/stringTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "gc/shared/weakProcessorPhases.hpp"
#include "runtime/jniHandles.hpp"
@@ -78,6 +79,7 @@
JVMTI_ONLY(case jvmti: return "JVMTI weak processing";)
JFR_ONLY(case jfr: return "JFR weak processing";)
case jni: return "JNI weak processing";
+ case stringtable: return "StringTable weak processing";
case vm: return "VM weak processing";
default:
ShouldNotReachHere();
@@ -98,9 +100,14 @@
OopStorage* WeakProcessorPhases::oop_storage(Phase phase) {
switch (phase) {
case jni: return JNIHandles::weak_global_handles();
+ case stringtable: return StringTable::weak_storage();
case vm: return SystemDictionary::vm_weak_oop_storage();
default:
ShouldNotReachHere();
return NULL;
}
}
+
+bool WeakProcessorPhases::is_stringtable(Phase phase) {
+ return phase == stringtable;
+}
--- a/src/hotspot/share/gc/shared/weakProcessorPhases.hpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/shared/weakProcessorPhases.hpp Tue Jan 29 11:30:17 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -44,6 +44,7 @@
// OopStorage phases.
jni,
+ stringtable,
vm
};
@@ -65,6 +66,8 @@
static const char* description(Phase phase);
static Processor processor(Phase phase); // Precondition: is_serial(phase)
static OopStorage* oop_storage(Phase phase); // Precondition: is_oop_storage(phase)
+
+ static bool is_stringtable(Phase phase);
};
typedef WeakProcessorPhases::Phase WeakProcessorPhase;
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Tue Jan 29 11:30:17 2019 +0100
@@ -1923,8 +1923,7 @@
ShenandoahPhaseTimings::full_gc_purge_par :
ShenandoahPhaseTimings::purge_par);
uint active = _workers->active_workers();
- StringDedupUnlinkOrOopsDoClosure dedup_cl(is_alive, NULL);
- ParallelCleaningTask unlink_task(is_alive, &dedup_cl, active, purged_class);
+ ParallelCleaningTask unlink_task(is_alive, active, purged_class, true);
_workers->run_task(&unlink_task);
}
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp Tue Jan 29 11:30:17 2019 +0100
@@ -78,7 +78,6 @@
WeakProcessor::oops_do(oops);
ObjectSynchronizer::oops_do(oops);
SystemDictionary::oops_do(oops);
- StringTable::oops_do(oops);
if (ShenandoahStringDedup::is_enabled()) {
ShenandoahStringDedup::oops_do_slow(oops);
@@ -209,13 +208,6 @@
ObjectSynchronizer::oops_do(strong_roots);
}
}
-
- // All threads execute the following. A specific chunk of buckets
- // from the StringTable are the individual tasks.
- if (weak_roots != NULL) {
- ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::StringTableRoots, worker_id);
- StringTable::possibly_parallel_oops_do(&_par_state_string, weak_roots);
- }
}
uint ShenandoahRootProcessor::n_workers() const {
--- a/src/hotspot/share/logging/logPrefix.hpp Tue Jan 29 10:13:23 2019 +0100
+++ b/src/hotspot/share/logging/logPrefix.hpp Tue Jan 29 11:30:17 2019 +0100
@@ -79,7 +79,6 @@
LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, ref, start)) \
LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, reloc)) \
LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, start)) \
- LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, stringtable)) \
LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, symboltable)) \
LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, sweep)) \
LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, task)) \
--- a/test/hotspot/jtreg/gc/g1/TestGCLogMessages.java Tue Jan 29 10:13:23 2019 +0100
+++ b/test/hotspot/jtreg/gc/g1/TestGCLogMessages.java Tue Jan 29 11:30:17 2019 +0100
@@ -108,7 +108,6 @@
new LogMessageWithLevel("Skipped Cards", Level.DEBUG),
// Ext Root Scan
new LogMessageWithLevel("Thread Roots", Level.TRACE),
- new LogMessageWithLevel("StringTable Roots", Level.TRACE),
new LogMessageWithLevel("Universe Roots", Level.TRACE),
new LogMessageWithLevel("JNI Handles Roots", Level.TRACE),
new LogMessageWithLevel("ObjectSynchronizer Roots", Level.TRACE),
@@ -126,7 +125,9 @@
new LogMessageWithLevel("Redirtied Cards", Level.TRACE),
// Misc Top-level
new LogMessageWithLevel("Code Roots Purge", Level.DEBUG),
- new LogMessageWithLevel("String Dedup Fixup", Level.DEBUG),
+ new LogMessageWithLevel("String Deduplication", Level.DEBUG),
+ new LogMessageWithLevel("Queue Fixup", Level.DEBUG),
+ new LogMessageWithLevel("Table Fixup", Level.DEBUG),
new LogMessageWithLevel("Expand Heap After Collection", Level.DEBUG),
// Free CSet
new LogMessageWithLevel("Free Collection Set", Level.DEBUG),
@@ -145,6 +146,9 @@
new LogMessageWithLevel("Reference Processing", Level.DEBUG),
// VM internal reference processing
new LogMessageWithLevel("Weak Processing", Level.DEBUG),
+ new LogMessageWithLevel("JNI weak processing", Level.DEBUG),
+ new LogMessageWithLevel("StringTable weak processing", Level.DEBUG),
+ new LogMessageWithLevel("VM weak processing", Level.DEBUG),
new LogMessageWithLevelC2OrJVMCIOnly("DerivedPointerTable Update", Level.DEBUG),
new LogMessageWithLevel("Start New Collection Set", Level.DEBUG),
--- a/test/hotspot/jtreg/gc/g1/TestStringTableStats.java Tue Jan 29 10:13:23 2019 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package gc.g1;
-
-/*
- * @test TestStringTableStats
- * @bug 8027476 8027455
- * @summary Ensure that the G1TraceStringTableScrubbing prints the expected message.
- * @key gc
- * @requires vm.gc.G1
- * @library /test/lib
- * @modules java.base/jdk.internal.misc
- * java.management
- * @run main gc.g1.TestStringTableStats
- */
-
-import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.process.ProcessTools;
-
-public class TestStringTableStats {
- public static void main(String[] args) throws Exception {
-
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
- "-XX:+UnlockExperimentalVMOptions",
- "-Xlog:gc+stringtable=trace",
- SystemGCTest.class.getName());
-
- OutputAnalyzer output = new OutputAnalyzer(pb.start());
-
- System.out.println("Output:\n" + output.getOutput());
-
- output.shouldMatch("GC\\(\\d+\\) Cleaned string table");
- output.shouldHaveExitValue(0);
- }
-
- static class SystemGCTest {
- public static void main(String [] args) {
- System.out.println("Calling System.gc()");
- System.gc();
- }
- }
-}
--- a/test/jdk/jdk/jfr/event/gc/collection/TestG1ParallelPhases.java Tue Jan 29 10:13:23 2019 +0100
+++ b/test/jdk/jdk/jfr/event/gc/collection/TestG1ParallelPhases.java Tue Jan 29 11:30:17 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -90,7 +90,6 @@
Set<String> allPhases = of(
"ExtRootScan",
"ThreadRoots",
- "StringTableRoots",
"UniverseRoots",
"JNIRoots",
"ObjectSynchronizerRoots",