Skip to content

Commit 7cd25ed

Browse files
Cesar Soares LucasTobiHartmann
authored andcommitted
8322854: Incorrect rematerialization of scalar replaced objects in C2
Reviewed-by: kvn, thartmann
1 parent 7ec2bad commit 7cd25ed

File tree

2 files changed

+76
-3
lines changed

2 files changed

+76
-3
lines changed

src/hotspot/share/opto/macro.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,8 @@ void PhaseMacroExpand::eliminate_gc_barrier(Node* p2x) {
167167
// Search for a memory operation for the specified memory slice.
168168
static Node *scan_mem_chain(Node *mem, int alias_idx, int offset, Node *start_mem, Node *alloc, PhaseGVN *phase) {
169169
Node *orig_mem = mem;
170-
Node *alloc_mem = alloc->in(TypeFunc::Memory);
170+
Node *alloc_mem = alloc->as_Allocate()->proj_out_or_null(TypeFunc::Memory, /*io_use:*/false);
171+
assert(alloc_mem != nullptr, "Allocation without a memory projection.");
171172
const TypeOopPtr *tinst = phase->C->get_adr_type(alias_idx)->isa_oopptr();
172173
while (true) {
173174
if (mem == alloc_mem || mem == start_mem ) {
@@ -371,7 +372,8 @@ Node *PhaseMacroExpand::value_from_mem_phi(Node *mem, BasicType ft, const Type *
371372
return nullptr; // Give up: phi tree too deep
372373
}
373374
Node *start_mem = C->start()->proj_out_or_null(TypeFunc::Memory);
374-
Node *alloc_mem = alloc->in(TypeFunc::Memory);
375+
Node *alloc_mem = alloc->proj_out_or_null(TypeFunc::Memory, /*io_use:*/false);
376+
assert(alloc_mem != nullptr, "Allocation without a memory projection.");
375377

376378
uint length = mem->req();
377379
GrowableArray <Node *> values(length, length, nullptr);
@@ -456,7 +458,8 @@ Node *PhaseMacroExpand::value_from_mem(Node *sfpt_mem, Node *sfpt_ctl, BasicType
456458
int offset = adr_t->offset();
457459
Node *start_mem = C->start()->proj_out_or_null(TypeFunc::Memory);
458460
Node *alloc_ctrl = alloc->in(TypeFunc::Control);
459-
Node *alloc_mem = alloc->in(TypeFunc::Memory);
461+
Node *alloc_mem = alloc->proj_out_or_null(TypeFunc::Memory, /*io_use:*/false);
462+
assert(alloc_mem != nullptr, "Allocation without a memory projection.");
460463
VectorSet visited;
461464

462465
bool done = sfpt_mem == alloc_mem;
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Copyright (c) 2024, 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+
/*
25+
* @test
26+
* @bug 8322854
27+
* @summary Check that the RAM optimization works when there is a memory loop.
28+
* @library /test/lib /
29+
* @requires vm.compiler2.enabled
30+
* @run main/othervm -XX:CompileCommand=compileonly,*TestReduceAllocationAndMemoryLoop*::test*
31+
* -XX:-TieredCompilation -Xbatch
32+
* compiler.c2.TestReduceAllocationAndMemoryLoop
33+
*/
34+
35+
package compiler.c2;
36+
37+
public class TestReduceAllocationAndMemoryLoop {
38+
public static void main(String[] args) throws Exception {
39+
// Warmup
40+
for (int i = 0; i < 50_000; ++i) {
41+
test(false, 10);
42+
}
43+
44+
// Trigger deoptimization
45+
MyClass obj = test(false, 11);
46+
if (obj.val != 42) {
47+
throw new RuntimeException("Test failed, val = " + obj.val);
48+
}
49+
}
50+
51+
static class MyClass {
52+
final int val;
53+
54+
public MyClass(int val) {
55+
this.val = val;
56+
}
57+
}
58+
59+
public static MyClass test(boolean alwaysFalse, int limit) {
60+
for (int i = 0; ; ++i) {
61+
MyClass obj = new MyClass(42);
62+
if (alwaysFalse || i > 10) {
63+
return obj;
64+
}
65+
if (i == limit) {
66+
return null;
67+
}
68+
}
69+
}
70+
}

0 commit comments

Comments
 (0)