Skip to content

Commit 03232d4

Browse files
committed
8359200: Memory corruption in MStack::push
Reviewed-by: epeter, shade Backport-of: ed39e17
1 parent 4111730 commit 03232d4

File tree

8 files changed

+80
-21
lines changed

8 files changed

+80
-21
lines changed

src/hotspot/share/libadt/vectset.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ void VectorSet::init(Arena* arena) {
4747

4848
// Expand the existing set to a bigger size
4949
void VectorSet::grow(uint new_word_capacity) {
50-
_nesting.check(_set_arena); // Check if a potential reallocation in the arena is safe
5150
assert(new_word_capacity >= _size, "Should have been checked before, use maybe_grow?");
5251
assert(new_word_capacity < (1U << 30), "");
5352
uint x = next_power_of_2(new_word_capacity);

src/hotspot/share/libadt/vectset.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ class VectorSet : public AnyObj {
5252

5353
// Grow vector to required word capacity
5454
void maybe_grow(uint new_word_capacity) {
55+
_nesting.check(_set_arena); // Check if a potential reallocation in the arena is safe
5556
if (new_word_capacity >= _size) {
5657
grow(new_word_capacity);
5758
}

src/hotspot/share/opto/block.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,8 @@
3737
#include "utilities/copy.hpp"
3838
#include "utilities/powerOfTwo.hpp"
3939

40-
void Block_Array::grow( uint i ) {
41-
_nesting.check(_arena); // Check if a potential reallocation in the arena is safe
42-
if (i < Max()) {
43-
return; // No need to grow
44-
}
40+
void Block_Array::grow(uint i) {
41+
assert(i >= Max(), "Should have been checked before, use maybe_grow?");
4542
DEBUG_ONLY(_limit = i+1);
4643
if( i < _size ) return;
4744
if( !_size ) {

src/hotspot/share/opto/block.hpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,13 @@ class Block_Array : public ArenaObj {
5353
ReallocMark _nesting; // Safety checks for arena reallocation
5454
protected:
5555
Block **_blocks;
56-
void grow( uint i ); // Grow array node to fit
56+
void maybe_grow(uint i) {
57+
_nesting.check(_arena); // Check if a potential reallocation in the arena is safe
58+
if (i >= Max()) {
59+
grow(i);
60+
}
61+
}
62+
void grow(uint i); // Grow array node to fit
5763

5864
public:
5965
Block_Array(Arena *a) : _size(OptoBlockListSize), _arena(a) {
@@ -68,7 +74,7 @@ class Block_Array : public ArenaObj {
6874
Block *operator[] ( uint i ) const // Lookup, or assert for not mapped
6975
{ assert( i < Max(), "oob" ); return _blocks[i]; }
7076
// Extend the mapping: index i maps to Block *n.
71-
void map( uint i, Block *n ) { grow(i); _blocks[i] = n; }
77+
void map( uint i, Block *n ) { maybe_grow(i); _blocks[i] = n; }
7278
uint Max() const { DEBUG_ONLY(return _limit); return _size; }
7379
};
7480

src/hotspot/share/opto/matcher.hpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,8 @@ class Matcher : public PhaseTransform {
6565
Node_Stack::push(n, (uint)ns);
6666
}
6767
void push(Node *n, Node_State ns, Node *parent, int indx) {
68-
++_inode_top;
69-
if ((_inode_top + 1) >= _inode_max) grow();
70-
_inode_top->node = parent;
71-
_inode_top->indx = (uint)indx;
72-
++_inode_top;
73-
_inode_top->node = n;
74-
_inode_top->indx = (uint)ns;
68+
Node_Stack::push(parent, (uint)indx);
69+
Node_Stack::push(n, (uint)ns);
7570
}
7671
Node *parent() {
7772
pop();

src/hotspot/share/opto/node.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2798,7 +2798,6 @@ const RegMask &Node::in_RegMask(uint) const {
27982798
}
27992799

28002800
void Node_Array::grow(uint i) {
2801-
_nesting.check(_a); // Check if a potential reallocation in the arena is safe
28022801
assert(i >= _max, "Should have been checked before, use maybe_grow?");
28032802
assert(_max > 0, "invariant");
28042803
uint old = _max;
@@ -3038,10 +3037,6 @@ void Unique_Node_List::remove_useless_nodes(VectorSet &useful) {
30383037

30393038
//=============================================================================
30403039
void Node_Stack::grow() {
3041-
_nesting.check(_a); // Check if a potential reallocation in the arena is safe
3042-
if (_inode_top < _inode_max) {
3043-
return; // No need to grow
3044-
}
30453040
size_t old_top = pointer_delta(_inode_top,_inodes,sizeof(INode)); // save _top
30463041
size_t old_max = pointer_delta(_inode_max,_inodes,sizeof(INode));
30473042
size_t max = old_max << 1; // max * 2

src/hotspot/share/opto/node.hpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1633,6 +1633,7 @@ class Node_Array : public AnyObj {
16331633

16341634
// Grow array to required capacity
16351635
void maybe_grow(uint i) {
1636+
_nesting.check(_a); // Check if a potential reallocation in the arena is safe
16361637
if (i >= _max) {
16371638
grow(i);
16381639
}
@@ -1884,7 +1885,15 @@ class Node_Stack {
18841885
INode *_inodes; // Array storage for the stack
18851886
Arena *_a; // Arena to allocate in
18861887
ReallocMark _nesting; // Safety checks for arena reallocation
1888+
1889+
void maybe_grow() {
1890+
_nesting.check(_a); // Check if a potential reallocation in the arena is safe
1891+
if (_inode_top >= _inode_max) {
1892+
grow();
1893+
}
1894+
}
18871895
void grow();
1896+
18881897
public:
18891898
Node_Stack(int size) {
18901899
size_t max = (size > OptoNodeListSize) ? size : OptoNodeListSize;
@@ -1907,7 +1916,7 @@ class Node_Stack {
19071916
}
19081917
void push(Node *n, uint i) {
19091918
++_inode_top;
1910-
grow();
1919+
maybe_grow();
19111920
INode *top = _inode_top; // optimization
19121921
top->node = n;
19131922
top->indx = i;
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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+
/*
25+
* @test
26+
* @library /test/lib /
27+
* @bug 8359200
28+
* @key randomness
29+
* @requires vm.flagless & vm.compiler2.enabled & vm.debug == true
30+
* @summary Test that -XX:OptoNodeListSize does not crash the VM.
31+
* @run driver compiler.arguments.TestOptoNodeListSize
32+
*/
33+
34+
package compiler.arguments;
35+
36+
import java.io.IOException;
37+
import java.util.Random;
38+
39+
import jdk.test.lib.process.ProcessTools;
40+
import jdk.test.lib.process.OutputAnalyzer;
41+
import jdk.test.lib.Utils;
42+
43+
public class TestOptoNodeListSize {
44+
private static final Random RANDOM = Utils.getRandomInstance();
45+
46+
public static void main(String[] args) throws IOException {
47+
if (args.length == 0) {
48+
int size = RANDOM.nextInt(1000) + 1;
49+
ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:OptoNodeListSize=" + size,
50+
"-Xcomp", "-XX:-TieredCompilation", "compiler.arguments.TestOptoNodeListSize", "run");
51+
OutputAnalyzer output = new OutputAnalyzer(pb.start());
52+
output.shouldHaveExitValue(0);
53+
} else {
54+
System.out.println("Test passed.");
55+
}
56+
}
57+
}

0 commit comments

Comments
 (0)