8379396: "assert(offset + partition_size <= size()) failed: partition failed" when combining NonProfiledCodeHeapSize and large value for CICompilerCount

Reviewed-by: dlong, kvn
This commit is contained in:
Boris Ulasevich 2026-05-07 13:40:00 +00:00
parent a6d763ac87
commit c833dc0a0b
4 changed files with 52 additions and 12 deletions

View File

@ -65,6 +65,7 @@
#include "sanitizers/leak.hpp"
#include "services/memoryService.hpp"
#include "utilities/align.hpp"
#include "utilities/integerCast.hpp"
#include "utilities/vmError.hpp"
#include "utilities/xmlstream.hpp"
#ifdef COMPILER1
@ -228,9 +229,14 @@ void CodeCache::initialize_heaps() {
assert(heap_available(CodeBlobType::MethodNonProfiled), "MethodNonProfiled heap is always available for segmented code heap");
size_t compiler_buffer_size = 0;
COMPILER1_PRESENT(compiler_buffer_size += CompilationPolicy::c1_count() * Compiler::code_buffer_size());
COMPILER2_PRESENT(compiler_buffer_size += CompilationPolicy::c2_count() * C2Compiler::initial_code_buffer_size());
uint64_t compiler_buffer_size_uint64 = 0;
COMPILER1_PRESENT(compiler_buffer_size_uint64 += (uint64_t)CompilationPolicy::c1_count() * Compiler::code_buffer_size());
COMPILER2_PRESENT(compiler_buffer_size_uint64 += (uint64_t)CompilationPolicy::c2_count() * C2Compiler::initial_code_buffer_size());
if (compiler_buffer_size_uint64 > (uint64_t)CODE_CACHE_SIZE_LIMIT) {
err_msg msg("CICompilerCount is too large (%" PRIdPTR "): compiler buffer size exceeds the CodeCache size limit", CICompilerCount);
vm_exit_during_initialization(msg);
}
size_t compiler_buffer_size = integer_cast_permit_tautology<size_t>(compiler_buffer_size_uint64);
if (!non_nmethod.set) {
non_nmethod.size += compiler_buffer_size;

View File

@ -61,9 +61,21 @@ JVMFlag::Error CICompilerCountConstraintFunc(intx value, bool verbose) {
"at least %d \n",
value, min_number_of_compiler_threads);
return JVMFlag::VIOLATES_CONSTRAINT;
} else {
return JVMFlag::SUCCESS;
}
// Limit CICompilerCount to a reasonable value in product builds.
#ifndef ASSERT
int active_processor_count = os::active_processor_count();
// On a single-CPU machine we still can run C1 and C2 compiler threads, so allow up to 2x for tiered.
int reasonable_threads_num = CompilerConfig::is_tiered() ? active_processor_count * 2 : active_processor_count;
if (value > reasonable_threads_num) {
JVMFlag::printError(verbose, "CICompilerCount is too large (%" PRIdPTR ") for current active processor count %d \n",
CICompilerCount, active_processor_count);
return JVMFlag::VIOLATES_CONSTRAINT;
}
#endif
return JVMFlag::SUCCESS;
}
JVMFlag::Error AllocatePrefetchStepSizeConstraintFunc(int value, bool verbose) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -23,7 +23,7 @@
/*
* @test CheckCheckCICompilerCount
* @bug 8130858 8132525 8162881
* @bug 8130858 8132525 8162881 8379396
* @summary Check that correct range of values for CICompilerCount are allowed depending on whether tiered is enabled or not
* @library /test/lib /
* @requires vm.flagless
@ -186,7 +186,25 @@ public class CheckCICompilerCount {
0
};
private static void verifyValidOption(String[] arguments, String expected_output, int exit, boolean tiered) throws Exception {
private static final String[][] INVALID_ARGUMENTS = {
{
"-XX:CICompilerCount=100M",
"-version"
},
};
private static final String[] INVALID_EXPECTED_OUTPUTS = {
// "CICompilerCount is too large" is a common prefix for two different messages:
// - product build: flag constraint fires early: "CICompilerCount is too large for current active processor count N"
// - debug build: CodeCache overflow guard fires: "CICompilerCount is too large: compiler buffer size exceeds the CodeCache size limit"
"CICompilerCount is too large"
};
private static final int[] INVALID_EXIT = {
1,
};
private static void verifyOptionBehavior(String[] arguments, String expected_output, int exit, boolean tiered) throws Exception {
ProcessBuilder pb;
OutputAnalyzer out;
@ -215,11 +233,15 @@ public class CheckCICompilerCount {
}
for (int i = 0; i < NON_TIERED_ARGUMENTS.length; i++) {
verifyValidOption(NON_TIERED_ARGUMENTS[i], NON_TIERED_EXPECTED_OUTPUTS[i], NON_TIERED_EXIT[i], false);
verifyOptionBehavior(NON_TIERED_ARGUMENTS[i], NON_TIERED_EXPECTED_OUTPUTS[i], NON_TIERED_EXIT[i], false);
}
for (int i = 0; i < TIERED_ARGUMENTS.length; i++) {
verifyValidOption(TIERED_ARGUMENTS[i], TIERED_EXPECTED_OUTPUTS[i], TIERED_EXIT[i], true);
verifyOptionBehavior(TIERED_ARGUMENTS[i], TIERED_EXPECTED_OUTPUTS[i], TIERED_EXIT[i], true);
}
for (int i = 0; i < INVALID_ARGUMENTS.length; i++) {
verifyOptionBehavior(INVALID_ARGUMENTS[i], INVALID_EXPECTED_OUTPUTS[i], INVALID_EXIT[i], true);
}
}
}

View File

@ -52,8 +52,8 @@ public class SmallCodeCacheStartup {
try {
analyzer.shouldHaveExitValue(0);
} catch (RuntimeException e) {
// Error occurred during initialization, did we run out of adapter space?
assertTrue(analyzer.getOutput().contains("VirtualMachineError: Out of space in CodeCache"),
// Error occurred during initialization
assertTrue(analyzer.getOutput().contains("CICompilerCount is too large"),
"Expected VirtualMachineError");
}