Skip to content

Commit f2bad3a

Browse files
committed
Merge
2 parents 47c9b43 + 61e5e39 commit f2bad3a

File tree

12 files changed

+190
-22
lines changed

12 files changed

+190
-22
lines changed

src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2055,6 +2055,15 @@ void ShenandoahHeap::op_weak_refs() {
20552055
}
20562056
}
20572057

2058+
void ShenandoahHeap::stw_weak_refs(bool full_gc) {
2059+
// Weak refs processing
2060+
ShenandoahTimingsTracker t(full_gc ? ShenandoahPhaseTimings::full_gc_weakrefs_process
2061+
: ShenandoahPhaseTimings::degen_gc_weakrefs_process);
2062+
ShenandoahGCWorkerPhase worker_phase(full_gc ? ShenandoahPhaseTimings::full_gc_weakrefs_process
2063+
: ShenandoahPhaseTimings::degen_gc_weakrefs_process);
2064+
ref_processor()->process_references(workers(), false /* concurrent */);
2065+
}
2066+
20582067
void ShenandoahHeap::op_weak_roots() {
20592068
if (is_concurrent_weak_root_in_progress()) {
20602069
// Concurrent weak root processing
@@ -2194,12 +2203,6 @@ void ShenandoahHeap::op_degenerated(ShenandoahDegenPoint point) {
21942203
ShenandoahCodeRoots::disarm_nmethods();
21952204
}
21962205

2197-
{
2198-
ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_weak_refs_work);
2199-
ShenandoahGCWorkerPhase worker_phase(ShenandoahPhaseTimings::conc_weak_refs_work);
2200-
ref_processor()->process_references(workers(), false /* concurrent */);
2201-
}
2202-
22032206
op_cleanup_early();
22042207

22052208
case _degenerated_evac:
@@ -2485,6 +2488,7 @@ void ShenandoahHeap::stw_process_weak_roots(bool full_gc) {
24852488
void ShenandoahHeap::parallel_cleaning(bool full_gc) {
24862489
assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
24872490
assert(is_stw_gc_in_progress(), "Only for Degenerated and Full GC");
2491+
stw_weak_refs(full_gc);
24882492
stw_process_weak_roots(full_gc);
24892493
stw_unload_classes(full_gc);
24902494
}

src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,7 @@ class ShenandoahHeap : public CollectedHeap {
515515
private:
516516
void stw_unload_classes(bool full_gc);
517517
void stw_process_weak_roots(bool full_gc);
518+
void stw_weak_refs(bool full_gc);
518519

519520
// Prepare concurrent root processing
520521
void prepare_concurrent_roots();

src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,6 @@ void ShenandoahMarkCompact::phase1_mark_heap() {
249249
cm->mark_roots(ShenandoahPhaseTimings::full_gc_scan_roots);
250250
cm->finish_mark_from_roots(/* full_gc = */ true);
251251
heap->mark_complete_marking_context();
252-
rp->process_references(heap->workers(), false /* concurrent */);
253252
heap->parallel_cleaning(true /* full_gc */);
254253
}
255254

src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,11 @@ bool ShenandoahPhaseTimings::is_worker_phase(Phase phase) {
105105
case full_gc_adjust_roots:
106106
case degen_gc_scan_conc_roots:
107107
case degen_gc_update_roots:
108+
case full_gc_weakrefs_process:
108109
case full_gc_scan_conc_roots:
109110
case full_gc_purge_class_unload:
110111
case full_gc_purge_weak_par:
112+
case degen_gc_weakrefs_process:
111113
case degen_gc_purge_class_unload:
112114
case degen_gc_purge_weak_par:
113115
case heap_iteration_roots:

src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ class outputStream;
118118
f(degen_gc, "Pause Degenerated GC (N)") \
119119
f(degen_gc_scan_conc_roots, " Degen Mark Roots") \
120120
SHENANDOAH_PAR_PHASE_DO(degen_gc_conc_mark_, " DM: ", f) \
121+
f(degen_gc_weakrefs, " Weak References") \
122+
f(degen_gc_weakrefs_process, " Process") \
121123
f(degen_gc_purge, " System Purge") \
122124
f(degen_gc_purge_class_unload, " Unload Classes") \
123125
SHENANDOAH_PAR_PHASE_DO(degen_gc_purge_cu_par_, " DCU: ", f) \

src/hotspot/share/opto/block.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1221,6 +1221,26 @@ void PhaseCFG::verify() const {
12211221
if (j >= 1 && n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_CreateEx) {
12221222
assert(j == 1 || block->get_node(j-1)->is_Phi(), "CreateEx must be first instruction in block");
12231223
}
1224+
// Verify that memory-writing nodes (such as stores and calls) are placed
1225+
// in their original loop L (given by the control input) or in an ancestor
1226+
// of L. This is guaranteed by the freq. estimation model for reducible
1227+
// CFGs, and by special handling in PhaseCFG::schedule_late() otherwise.
1228+
if (n->is_Mach() && n->bottom_type()->has_memory() && n->in(0) != NULL) {
1229+
Block* original_block = find_block_for_node(n->in(0));
1230+
assert(original_block != NULL, "missing block for memory-writing node");
1231+
CFGLoop* original_or_ancestor = original_block->_loop;
1232+
assert(block->_loop != NULL && original_or_ancestor != NULL, "no loop");
1233+
bool found = false;
1234+
do {
1235+
if (block->_loop == original_or_ancestor) {
1236+
found = true;
1237+
break;
1238+
}
1239+
original_or_ancestor = original_or_ancestor->parent();
1240+
} while (original_or_ancestor != NULL);
1241+
assert(found, "memory-writing node is not placed in its original loop "
1242+
"or an ancestor of it");
1243+
}
12241244
if (n->needs_anti_dependence_check()) {
12251245
verify_anti_dependences(block, n);
12261246
}

src/hotspot/share/opto/block.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -501,8 +501,8 @@ class PhaseCFG : public Phase {
501501
CFGLoop* create_loop_tree();
502502
bool is_dominator(Node* dom_node, Node* node);
503503
bool is_CFG(Node* n);
504-
bool is_control_proj_or_safepoint(Node* n);
505-
Block* find_block_for_node(Node* n);
504+
bool is_control_proj_or_safepoint(Node* n) const;
505+
Block* find_block_for_node(Node* n) const;
506506
bool is_dominating_control(Node* dom_ctrl, Node* n);
507507
#ifndef PRODUCT
508508
bool _trace_opto_pipelining; // tracing flag

src/hotspot/share/opto/gcm.cpp

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,14 +152,14 @@ bool PhaseCFG::is_CFG(Node* n) {
152152
return n->is_block_proj() || n->is_block_start() || is_control_proj_or_safepoint(n);
153153
}
154154

155-
bool PhaseCFG::is_control_proj_or_safepoint(Node* n) {
155+
bool PhaseCFG::is_control_proj_or_safepoint(Node* n) const {
156156
bool result = (n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_SafePoint) || (n->is_Proj() && n->as_Proj()->bottom_type() == Type::CONTROL);
157157
assert(!result || (n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_SafePoint)
158158
|| (n->is_Proj() && n->as_Proj()->_con == 0), "If control projection, it must be projection 0");
159159
return result;
160160
}
161161

162-
Block* PhaseCFG::find_block_for_node(Node* n) {
162+
Block* PhaseCFG::find_block_for_node(Node* n) const {
163163
if (n->is_block_start() || n->is_block_proj()) {
164164
return get_block_for_node(n);
165165
} else {
@@ -1274,6 +1274,46 @@ void PhaseCFG::schedule_late(VectorSet &visited, Node_Stack &stack) {
12741274
default:
12751275
break;
12761276
}
1277+
if (C->has_irreducible_loop() && self->bottom_type()->has_memory()) {
1278+
// If the CFG is irreducible, keep memory-writing nodes as close as
1279+
// possible to their original block (given by the control input). This
1280+
// prevents PhaseCFG::hoist_to_cheaper_block() from placing such nodes
1281+
// into descendants of their original loop, as in the following example:
1282+
//
1283+
// Original placement of store in B1 (loop L1):
1284+
//
1285+
// B1 (L1):
1286+
// m1 <- ..
1287+
// m2 <- store m1, ..
1288+
// B2 (L2):
1289+
// jump B2
1290+
// B3 (L1):
1291+
// .. <- .. m2, ..
1292+
//
1293+
// Wrong "hoisting" of store to B2 (in loop L2, child of L1):
1294+
//
1295+
// B1 (L1):
1296+
// m1 <- ..
1297+
// B2 (L2):
1298+
// m2 <- store m1, ..
1299+
// # Wrong: m1 and m2 interfere at this point.
1300+
// jump B2
1301+
// B3 (L1):
1302+
// .. <- .. m2, ..
1303+
//
1304+
// This "hoist inversion" can happen due to CFGLoop::compute_freq()'s
1305+
// inaccurate estimation of frequencies for irreducible CFGs, which can
1306+
// lead to for example assigning B1 and B3 a higher frequency than B2.
1307+
#ifndef PRODUCT
1308+
if (trace_opto_pipelining()) {
1309+
tty->print_cr("# Irreducible loops: schedule in earliest block B%d:",
1310+
early->_pre_order);
1311+
self->dump();
1312+
}
1313+
#endif
1314+
schedule_node_into_block(self, early);
1315+
continue;
1316+
}
12771317
}
12781318

12791319
// Gather LCA of all uses

src/hotspot/share/opto/macro.cpp

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2562,11 +2562,8 @@ void PhaseMacroExpand::eliminate_macro_nodes() {
25622562
bool progress = true;
25632563
while (progress) {
25642564
progress = false;
2565-
for (int i = C->macro_count(); i > 0; i--) {
2566-
if (i > C->macro_count()) {
2567-
i = C->macro_count(); // more than 1 element can be eliminated at once
2568-
}
2569-
Node* n = C->macro_node(i-1);
2565+
for (int i = C->macro_count(); i > 0; i = MIN2(i - 1, C->macro_count())) { // more than 1 element can be eliminated at once
2566+
Node* n = C->macro_node(i - 1);
25702567
bool success = false;
25712568
DEBUG_ONLY(int old_macro_count = C->macro_count();)
25722569
if (n->is_AbstractLock()) {
@@ -2581,11 +2578,8 @@ void PhaseMacroExpand::eliminate_macro_nodes() {
25812578
progress = true;
25822579
while (progress) {
25832580
progress = false;
2584-
for (int i = C->macro_count(); i > 0; i--) {
2585-
if (i > C->macro_count()) {
2586-
i = C->macro_count(); // more than 1 element can be eliminated at once
2587-
}
2588-
Node* n = C->macro_node(i-1);
2581+
for (int i = C->macro_count(); i > 0; i = MIN2(i - 1, C->macro_count())) { // more than 1 element can be eliminated at once
2582+
Node* n = C->macro_node(i - 1);
25892583
bool success = false;
25902584
DEBUG_ONLY(int old_macro_count = C->macro_count();)
25912585
switch (n->class_id()) {

src/jdk.compiler/share/classes/com/sun/tools/doclint/DocLint.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public abstract class DocLint implements Plugin {
5050

5151
public static synchronized DocLint newDocLint() {
5252
if (docLintProvider == null) {
53-
docLintProvider = ServiceLoader.load(DocLint.class).stream()
53+
docLintProvider = ServiceLoader.load(DocLint.class, ClassLoader.getSystemClassLoader()).stream()
5454
.filter(p_ -> p_.get().getName().equals("doclint"))
5555
.findFirst()
5656
.orElse(new ServiceLoader.Provider<>() {

0 commit comments

Comments
 (0)