Skip to content

Commit 858be30

Browse files
committed
8366879: [lworld] C2's lock elimination fails after JDK-8335256
1 parent 2fddd34 commit 858be30

File tree

5 files changed

+98
-25
lines changed

5 files changed

+98
-25
lines changed

src/hotspot/share/opto/compile.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2879,7 +2879,7 @@ void Compile::Optimize() {
28792879
if (C->macro_count() > 0) {
28802880
// Eliminate some macro nodes before EA to reduce analysis pressure
28812881
PhaseMacroExpand mexp(igvn);
2882-
mexp.eliminate_macro_nodes();
2882+
mexp.eliminate_macro_nodes(/* eliminate_locks= */ false);
28832883
if (failing()) {
28842884
return;
28852885
}
@@ -2904,7 +2904,7 @@ void Compile::Optimize() {
29042904
if (C->macro_count() > 0) {
29052905
// Eliminate some macro nodes before EA to reduce analysis pressure
29062906
PhaseMacroExpand mexp(igvn);
2907-
mexp.eliminate_macro_nodes();
2907+
mexp.eliminate_macro_nodes(/* eliminate_locks= */ false);
29082908
if (failing()) {
29092909
return;
29102910
}

src/hotspot/share/opto/locknode.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ class BoxLockNode : public Node {
9393

9494
void set_local() {
9595
assert((_kind == Regular || _kind == Local || _kind == Coarsened),
96-
"incorrect kind for Local transitioni: %s", _kind_name[(int)_kind]);
96+
"incorrect kind for Local transition: %s", _kind_name[(int)_kind]);
9797
_kind = Local;
9898
}
9999
void set_nested() {

src/hotspot/share/opto/macro.cpp

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2972,7 +2972,7 @@ void PhaseMacroExpand::refine_strip_mined_loop_macro_nodes() {
29722972

29732973
//---------------------------eliminate_macro_nodes----------------------
29742974
// Eliminate scalar replaced allocations and associated locks.
2975-
void PhaseMacroExpand::eliminate_macro_nodes() {
2975+
void PhaseMacroExpand::eliminate_macro_nodes(bool eliminate_locks) {
29762976
if (C->macro_count() == 0) {
29772977
return;
29782978
}
@@ -2985,23 +2985,28 @@ void PhaseMacroExpand::eliminate_macro_nodes() {
29852985
break;
29862986
}
29872987

2988-
// Before elimination may re-mark (change to Nested or NonEscObj)
2989-
// all associated (same box and obj) lock and unlock nodes.
2990-
int cnt = C->macro_count();
2991-
for (int i=0; i < cnt; i++) {
2992-
Node *n = C->macro_node(i);
2993-
if (n->is_AbstractLock()) { // Lock and Unlock nodes
2994-
mark_eliminated_locking_nodes(n->as_AbstractLock());
2988+
// Postpone lock elimination to after EA when most allocations are eliminated
2989+
// because they might block lock elimination if their escape state isn't
2990+
// determined yet and we only got one chance at eliminating the lock.
2991+
if (eliminate_locks) {
2992+
// Before elimination may re-mark (change to Nested or NonEscObj)
2993+
// all associated (same box and obj) lock and unlock nodes.
2994+
int cnt = C->macro_count();
2995+
for (int i=0; i < cnt; i++) {
2996+
Node *n = C->macro_node(i);
2997+
if (n->is_AbstractLock()) { // Lock and Unlock nodes
2998+
mark_eliminated_locking_nodes(n->as_AbstractLock());
2999+
}
3000+
}
3001+
// Re-marking may break consistency of Coarsened locks.
3002+
if (!C->coarsened_locks_consistent()) {
3003+
return; // recompile without Coarsened locks if broken
3004+
} else {
3005+
// After coarsened locks are eliminated locking regions
3006+
// become unbalanced. We should not execute any more
3007+
// locks elimination optimizations on them.
3008+
C->mark_unbalanced_boxes();
29953009
}
2996-
}
2997-
// Re-marking may break consistency of Coarsened locks.
2998-
if (!C->coarsened_locks_consistent()) {
2999-
return; // recompile without Coarsened locks if broken
3000-
} else {
3001-
// After coarsened locks are eliminated locking regions
3002-
// become unbalanced. We should not execute any more
3003-
// locks elimination optimizations on them.
3004-
C->mark_unbalanced_boxes();
30053010
}
30063011

30073012
bool progress = false;
@@ -3028,12 +3033,14 @@ void PhaseMacroExpand::eliminate_macro_nodes() {
30283033
}
30293034
case Node::Class_Lock:
30303035
case Node::Class_Unlock:
3031-
success = eliminate_locking_node(n->as_AbstractLock());
3036+
if (eliminate_locks) {
3037+
success = eliminate_locking_node(n->as_AbstractLock());
30323038
#ifndef PRODUCT
3033-
if (success && PrintOptoStatistics) {
3034-
Atomic::inc(&PhaseMacroExpand::_monitor_objects_removed_counter);
3035-
}
3039+
if (success && PrintOptoStatistics) {
3040+
Atomic::inc(&PhaseMacroExpand::_monitor_objects_removed_counter);
3041+
}
30363042
#endif
3043+
}
30373044
break;
30383045
case Node::Class_ArrayCopy:
30393046
break;

src/hotspot/share/opto/macro.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ class PhaseMacroExpand : public Phase {
223223
}
224224

225225
void refine_strip_mined_loop_macro_nodes();
226-
void eliminate_macro_nodes();
226+
void eliminate_macro_nodes(bool eliminate_locks = true);
227227
bool expand_macro_nodes();
228228

229229
SafePointScalarObjectNode* create_scalarized_object_description(AllocateNode *alloc, SafePointNode* sfpt, Unique_Node_List* value_worklist);
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
package compiler.valhalla.inlinetypes;
25+
26+
import compiler.lib.ir_framework.*;
27+
import jdk.test.lib.Asserts;
28+
29+
/*
30+
* @test
31+
* @bug 8366879
32+
* @summary Test that locks are successfully eliminated by C2.
33+
* @library /test/lib /
34+
* @run driver compiler.valhalla.inlinetypes.TestLockElimination
35+
*/
36+
public class TestLockElimination {
37+
38+
static class MyClass {
39+
public synchronized int val() {
40+
return 42;
41+
}
42+
}
43+
44+
@Test
45+
@IR(failOn = { IRNode.ALLOC, IRNode.FAST_LOCK, IRNode.FAST_UNLOCK })
46+
public static int test(int max) {
47+
MyClass obj = new MyClass();
48+
int res = 0;
49+
for (int i = 0; i < max; i++) {
50+
int x = obj.val();
51+
int y = obj.val();
52+
res += x + y;
53+
}
54+
return res;
55+
}
56+
57+
@Run(test = "test")
58+
public static void test_runner() {
59+
int res = test(3);
60+
Asserts.assertEquals(res, 252);
61+
}
62+
63+
public static void main(String[] args) {
64+
TestFramework.run();
65+
}
66+
}

0 commit comments

Comments
 (0)