Skip to content

Commit 880c138

Browse files
Evgeny Nikitiniignatev
authored andcommitted
8265349: vmTestbase/../stress/compiler/deoptimize/Test.java fails with OOME due to CodeCache exhaustion.
Reviewed-by: iignatyev
1 parent 001c514 commit 880c138

File tree

2 files changed

+59
-38
lines changed

2 files changed

+59
-38
lines changed

test/hotspot/jtreg/ProblemList-Xcomp.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,3 @@
3030
vmTestbase/nsk/jvmti/SetFieldAccessWatch/setfldw001/TestDescription.java 8205957 generic-all
3131

3232
vmTestbase/vm/mlvm/mixed/stress/regression/b6969574/INDIFY_Test.java 8265295 windows-x64
33-
34-
vmTestbase/vm/mlvm/meth/stress/compiler/deoptimize/Test.java#id1 8265349 generic-all

test/hotspot/jtreg/vmTestbase/vm/mlvm/meth/share/MHTransformationGen.java

Lines changed: 59 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -35,6 +35,8 @@
3535
import java.util.Optional;
3636
import java.util.function.BiConsumer;
3737

38+
import jdk.test.lib.Platform;
39+
3840
import nsk.share.test.LazyIntArrayToString;
3941
import nsk.share.test.TestUtils;
4042
import vm.mlvm.meth.share.transform.v2.MHArrayEnvelopeTFPair;
@@ -68,45 +70,66 @@ public class MHTransformationGen {
6870

6971
private static final boolean USE_THROW_CATCH = false; // Test bugs
7072

71-
private static final Optional<MemoryPoolMXBean> NON_SEGMENTED_CODE_CACHE_POOL;
72-
private static final Optional<MemoryPoolMXBean> NON_NMETHODS_POOL;
73-
private static final Optional<MemoryPoolMXBean> PROFILED_NMETHODS_POOL;
74-
private static final Optional<MemoryPoolMXBean> NON_PROFILED_NMETHODS_POOL ;
75-
76-
// Limit numbers are arbitrary, feel free to change if arguably necessary
77-
private static final int NON_SEGMENTED_CACHE_ALLOWANCE = 2_000_000;
78-
private static final int SEGMENTED_CACHE_ALLOWANCE = 1_000_000;
79-
80-
static {
81-
var pools = ManagementFactory.getMemoryPoolMXBeans();
82-
NON_SEGMENTED_CODE_CACHE_POOL = pools.stream()
83-
.filter(pool -> pool.getName().equals("CodeCache")).findFirst();
84-
NON_NMETHODS_POOL = pools.stream()
85-
.filter(pool -> pool.getName().equals("CodeHeap 'non-nmethods'")).findFirst();
86-
PROFILED_NMETHODS_POOL = pools.stream()
87-
.filter(pool -> pool.getName().equals("CodeHeap 'profiled nmethods'")).findFirst();
88-
NON_PROFILED_NMETHODS_POOL = pools.stream()
89-
.filter(pool -> pool.getName().equals("CodeHeap 'non-profiled nmethods'")).findFirst();
90-
}
73+
/**
74+
* The class is used for periodical checks if a code-cache consuming operation
75+
* could be executed (i.e. if code cache has enought free space for a typical operation).
76+
*/
77+
private static class CodeCacheMonitor {
78+
79+
private static final Optional<MemoryPoolMXBean> NON_SEGMENTED_CODE_CACHE_POOL;
80+
private static final Optional<MemoryPoolMXBean> NON_NMETHODS_POOL;
81+
private static final Optional<MemoryPoolMXBean> PROFILED_NMETHODS_POOL;
82+
private static final Optional<MemoryPoolMXBean> NON_PROFILED_NMETHODS_POOL;
83+
84+
// Trial runs show up that maximal increase in code cache consumption between checks (for one
85+
// cycle/tree build in MHTransformationGen::createSequence), falls within the following intervals:
86+
//
87+
// | Threads number | Without Xcomp | With Xcomp |
88+
// |----------------|---------------|------------|
89+
// | 1 | 100-200 K | 400-500 K |
90+
// | 10 | 1 - 2 M | 5-6 M |
91+
//
92+
// Those numbers are approximate (since trees are generated randomly and the total consumption
93+
// between checks depends on how threads are aligned - for example, if all threads finish up their
94+
// cycles approximately at one time, the consumption increase will be the highest, like with a
95+
// resonance's amplitude)
96+
// The 10 threads is chosen as it is a typical number for multi-threaded tests.
97+
//
98+
// Based on these numbers, values of 10 M for Xcomp and 5 M for non-Xcomp, were suggested.
99+
private static final int NON_SEGMENTED_CACHE_ALLOWANCE = Platform.isComp() ? 10_000_000 : 5_000_000;
100+
private static final int SEGMENTED_CACHE_ALLOWANCE = Platform.isComp() ? 10_000_000 : 5_000_000;
101+
102+
static {
103+
var pools = ManagementFactory.getMemoryPoolMXBeans();
104+
NON_SEGMENTED_CODE_CACHE_POOL = pools.stream()
105+
.filter(pool -> pool.getName().equals("CodeCache")).findFirst();
106+
NON_NMETHODS_POOL = pools.stream()
107+
.filter(pool -> pool.getName().equals("CodeHeap 'non-nmethods'")).findFirst();
108+
PROFILED_NMETHODS_POOL = pools.stream()
109+
.filter(pool -> pool.getName().equals("CodeHeap 'profiled nmethods'")).findFirst();
110+
NON_PROFILED_NMETHODS_POOL = pools.stream()
111+
.filter(pool -> pool.getName().equals("CodeHeap 'non-profiled nmethods'")).findFirst();
112+
}
91113

92-
public static class ThrowCatchTestException extends Throwable {
93-
private static final long serialVersionUID = -6749961303738648241L;
94-
}
114+
public static final boolean isCodeCacheEffectivelyFull() {
115+
var result = new Object() { boolean value = false; };
95116

96-
private static final boolean isCodeCacheEffectivelyFull() {
97-
var result = new Object() { boolean value = false; };
117+
BiConsumer<MemoryPoolMXBean, Integer> check = (pool, limit) -> {
118+
var usage = pool.getUsage();
119+
result.value |= usage.getMax() - usage.getUsed() < limit;
120+
};
98121

99-
BiConsumer<MemoryPoolMXBean, Integer> check = (pool, limit) -> {
100-
var usage = pool.getUsage();
101-
result.value |= usage.getMax() - usage.getUsed() < limit;
102-
};
122+
NON_SEGMENTED_CODE_CACHE_POOL.ifPresent(pool -> check.accept(pool, NON_SEGMENTED_CACHE_ALLOWANCE));
123+
NON_NMETHODS_POOL.ifPresent(pool -> check.accept(pool, SEGMENTED_CACHE_ALLOWANCE));
124+
PROFILED_NMETHODS_POOL.ifPresent(pool -> check.accept(pool, SEGMENTED_CACHE_ALLOWANCE));
125+
NON_PROFILED_NMETHODS_POOL.ifPresent(pool -> check.accept(pool, SEGMENTED_CACHE_ALLOWANCE));
103126

104-
NON_SEGMENTED_CODE_CACHE_POOL.ifPresent(pool -> check.accept(pool, NON_SEGMENTED_CACHE_ALLOWANCE));
105-
NON_NMETHODS_POOL.ifPresent(pool -> check.accept(pool, SEGMENTED_CACHE_ALLOWANCE));
106-
PROFILED_NMETHODS_POOL.ifPresent(pool -> check.accept(pool, SEGMENTED_CACHE_ALLOWANCE));
107-
NON_PROFILED_NMETHODS_POOL.ifPresent(pool -> check.accept(pool, SEGMENTED_CACHE_ALLOWANCE));
127+
return result.value;
128+
}
129+
};
108130

109-
return result.value;
131+
public static class ThrowCatchTestException extends Throwable {
132+
private static final long serialVersionUID = -6749961303738648241L;
110133
}
111134

112135
@SuppressWarnings("unused")
@@ -131,7 +154,7 @@ public static MHMacroTF createSequence(Argument finalRetVal, Object boundObj, Me
131154

132155
final int cyclesToBuild = nextInt(MAX_CYCLES);
133156
for ( int i = 0; i < cyclesToBuild; i++) {
134-
if (isCodeCacheEffectivelyFull()) {
157+
if (CodeCacheMonitor.isCodeCacheEffectivelyFull()) {
135158
Env.traceNormal("Not enought code cache to build up MH sequences anymore. " +
136159
" Has only been able to achieve " + i + " out of " + cyclesToBuild);
137160
break;

0 commit comments

Comments
 (0)