8373369: [REDO] Remove ThreadLocalAllocBuffer::_reserve_for_allocation_prefetch

Reviewed-by: mdoerr, kvn, tschatzl
This commit is contained in:
Albert Mingkun Yang 2026-03-18 09:07:14 +00:00
parent 706fbb3044
commit 3a93daf189
9 changed files with 84 additions and 70 deletions

View File

@ -6327,36 +6327,8 @@ instruct loadConD_Ex(regD dst, immD src) %{
// Prefetch instructions.
// Must be safe to execute with invalid address (cannot fault).
// Special prefetch versions which use the dcbz instruction.
instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{
match(PrefetchAllocation (AddP mem src));
predicate(AllocatePrefetchStyle == 3);
ins_cost(MEMORY_REF_COST);
format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %}
size(4);
ins_encode %{
__ dcbz($src$$Register, $mem$$base$$Register);
%}
ins_pipe(pipe_class_memory);
%}
instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{
match(PrefetchAllocation mem);
predicate(AllocatePrefetchStyle == 3);
ins_cost(MEMORY_REF_COST);
format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %}
size(4);
ins_encode %{
__ dcbz($mem$$base$$Register);
%}
ins_pipe(pipe_class_memory);
%}
instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{
match(PrefetchAllocation (AddP mem src));
predicate(AllocatePrefetchStyle != 3);
ins_cost(MEMORY_REF_COST);
format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %}
@ -6369,7 +6341,6 @@ instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{
instruct prefetch_alloc_no_offset(indirectMemory mem) %{
match(PrefetchAllocation mem);
predicate(AllocatePrefetchStyle != 3);
ins_cost(MEMORY_REF_COST);
format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %}

View File

@ -37,7 +37,6 @@
#include "utilities/copy.hpp"
size_t ThreadLocalAllocBuffer::_max_size = 0;
int ThreadLocalAllocBuffer::_reserve_for_allocation_prefetch = 0;
unsigned int ThreadLocalAllocBuffer::_target_refills = 0;
ThreadLocalAllocBuffer::ThreadLocalAllocBuffer() :
@ -225,30 +224,6 @@ void ThreadLocalAllocBuffer::startup_initialization() {
// abort during VM initialization.
_target_refills = MAX2(_target_refills, 2U);
#ifdef COMPILER2
// If the C2 compiler is present, extra space is needed at the end of
// TLABs, otherwise prefetching instructions generated by the C2
// compiler will fault (due to accessing memory outside of heap).
// The amount of space is the max of the number of lines to
// prefetch for array and for instance allocations. (Extra space must be
// reserved to accommodate both types of allocations.)
//
// Only SPARC-specific BIS instructions are known to fault. (Those
// instructions are generated if AllocatePrefetchStyle==3 and
// AllocatePrefetchInstr==1). To be on the safe side, however,
// extra space is reserved for all combinations of
// AllocatePrefetchStyle and AllocatePrefetchInstr.
//
// If the C2 compiler is not present, no space is reserved.
// +1 for rounding up to next cache line, +1 to be safe
if (CompilerConfig::is_c2_or_jvmci_compiler_enabled()) {
int lines = MAX2(AllocatePrefetchLines, AllocateInstancePrefetchLines) + 2;
_reserve_for_allocation_prefetch = (AllocatePrefetchDistance + AllocatePrefetchStepSize * lines) /
(int)HeapWordSize;
}
#endif
// During jvm startup, the main thread is initialized
// before the heap is initialized. So reinitialize it now.
guarantee(Thread::current()->is_Java_thread(), "tlab initialization thread not Java thread");
@ -454,8 +429,7 @@ void ThreadLocalAllocStats::publish() {
}
size_t ThreadLocalAllocBuffer::end_reserve() {
size_t reserve_size = CollectedHeap::lab_alignment_reserve();
return MAX2(reserve_size, (size_t)_reserve_for_allocation_prefetch);
return CollectedHeap::lab_alignment_reserve();
}
size_t ThreadLocalAllocBuffer::estimated_used_bytes() const {

View File

@ -57,7 +57,6 @@ private:
uint64_t _allocated_before_last_gc; // total bytes allocated up until the last gc
static size_t _max_size; // maximum size of any TLAB
static int _reserve_for_allocation_prefetch; // Reserve at the end of the TLAB
static unsigned _target_refills; // expected number of refills between GCs
unsigned _number_of_refills;

View File

@ -1917,8 +1917,7 @@ Node* PhaseMacroExpand::prefetch_allocation(Node* i_o, Node*& needgc_false,
transform_later(cache_adr);
cache_adr = new CastP2XNode(needgc_false, cache_adr);
transform_later(cache_adr);
// Address is aligned to execute prefetch to the beginning of cache line size
// (it is important when BIS instruction is used on SPARC as prefetch).
// Address is aligned to execute prefetch to the beginning of cache line size.
Node* mask = _igvn.MakeConX(~(intptr_t)(step_size-1));
cache_adr = new AndXNode(cache_adr, mask);
transform_later(cache_adr);

View File

@ -335,7 +335,6 @@
nonstatic_field(ThreadLocalAllocBuffer, _pf_top, HeapWord*) \
nonstatic_field(ThreadLocalAllocBuffer, _desired_size, size_t) \
nonstatic_field(ThreadLocalAllocBuffer, _refill_waste_limit, size_t) \
static_field(ThreadLocalAllocBuffer, _reserve_for_allocation_prefetch, int) \
static_field(ThreadLocalAllocBuffer, _target_refills, unsigned) \
nonstatic_field(ThreadLocalAllocBuffer, _number_of_refills, unsigned) \
nonstatic_field(ThreadLocalAllocBuffer, _refill_waste, unsigned) \

View File

@ -76,10 +76,9 @@ public class ThreadLocalAllocBuffer extends VMObject {
private long endReserve() {
long labAlignmentReserve = VM.getVM().getLabAlignmentReserve();
long reserveForAllocationPrefetch = VM.getVM().getReserveForAllocationPrefetch();
long heapWordSize = VM.getVM().getHeapWordSize();
return Math.max(labAlignmentReserve, reserveForAllocationPrefetch) * heapWordSize;
return labAlignmentReserve * heapWordSize;
}
/** Support for iteration over heap -- not sure how this will

View File

@ -123,7 +123,6 @@ public class VM {
private int invocationEntryBCI;
private ReversePtrs revPtrs;
private VMRegImpl vmregImpl;
private int reserveForAllocationPrefetch;
private int labAlignmentReserve;
// System.getProperties from debuggee VM
@ -447,8 +446,6 @@ public class VM {
boolType = (CIntegerType) db.lookupType("bool");
Type threadLocalAllocBuffer = db.lookupType("ThreadLocalAllocBuffer");
CIntegerField reserveForAllocationPrefetchField = threadLocalAllocBuffer.getCIntegerField("_reserve_for_allocation_prefetch");
reserveForAllocationPrefetch = (int)reserveForAllocationPrefetchField.getCInteger(intType);
Type collectedHeap = db.lookupType("CollectedHeap");
CIntegerField labAlignmentReserveField = collectedHeap.getCIntegerField("_lab_alignment_reserve");
@ -915,10 +912,6 @@ public class VM {
return vmInternalInfo;
}
public int getReserveForAllocationPrefetch() {
return reserveForAllocationPrefetch;
}
public int getLabAlignmentReserve() {
return labAlignmentReserve;
}

View File

@ -83,6 +83,8 @@ compiler/c2/aarch64/TestStaticCallStub.java 8359963 linux-aarch64,macosx-aarch64
compiler/longcountedloops/TestLoopNestTooManyTraps.java 8376591 generic-all
compiler/unsafe/AlignmentGapAccess.java 8373487 generic-all
#############################################################################
# :hotspot_gc
@ -196,4 +198,3 @@ vmTestbase/nsk/monitoring/ThreadMXBean/findMonitorDeadlockedThreads/find006/Test
# in either implementation or test code.
#############################################################################

View File

@ -0,0 +1,79 @@
/*
* Copyright (c) 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @summary Stress allocation prefetch with large legal AllocatePrefetch* values
* @requires vm.compiler2.enabled
*
* @run main/othervm -Xbatch -XX:-TieredCompilation -XX:+UseTLAB
* -XX:AllocatePrefetchStyle=1
* -XX:AllocatePrefetchDistance=512
* -XX:AllocatePrefetchStepSize=512
* -XX:AllocatePrefetchLines=64
* -XX:AllocateInstancePrefetchLines=64
* compiler.c2.TestAllocatePrefetchStyleLargeFlags
* @run main/othervm -Xbatch -XX:-TieredCompilation -XX:+UseTLAB
* -XX:AllocatePrefetchStyle=2
* -XX:AllocatePrefetchDistance=512
* -XX:AllocatePrefetchStepSize=512
* -XX:AllocatePrefetchLines=64
* -XX:AllocateInstancePrefetchLines=64
* compiler.c2.TestAllocatePrefetchStyleLargeFlags
* @run main/othervm -Xbatch -XX:-TieredCompilation -XX:+UseTLAB
* -XX:AllocatePrefetchStyle=3
* -XX:AllocatePrefetchDistance=512
* -XX:AllocatePrefetchStepSize=512
* -XX:AllocatePrefetchLines=64
* -XX:AllocateInstancePrefetchLines=64
* compiler.c2.TestAllocatePrefetchStyleLargeFlags
*/
package compiler.c2;
public class TestAllocatePrefetchStyleLargeFlags {
private static volatile Object sink;
private static final class Payload {
private final int value;
private Payload(int value) {
this.value = value;
}
}
private static Object allocateInstance(int value) {
return new Payload(value);
}
private static Object allocateArray(int value) {
return new int[value & 31];
}
public static void main(String[] args) {
for (int i = 0; i < 50_000; i++) {
sink = allocateInstance(i);
sink = allocateArray(i);
}
}
}