Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/compiler/env/J9SegmentAllocator.cpp
6000 views
1
/*******************************************************************************
2
* Copyright (c) 2000, 2021 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7
* or the Apache License, Version 2.0 which accompanies this distribution and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
20
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
21
*******************************************************************************/
22
23
#include <new>
24
#include "env/J9SegmentAllocator.hpp"
25
#include "infra/Assert.hpp"
26
#include "control/Options.hpp"
27
#include "control/Options_inlines.hpp"
28
#include "control/CompilationRuntime.hpp"
29
#include "env/VerboseLog.hpp"
30
#include "OMR/Bytes.hpp"
31
#include "j9.h"
32
#undef min
33
#undef max
34
35
namespace J9 {
36
37
SegmentAllocator::SegmentAllocator(
38
int32_t segmentType,
39
J9JavaVM &javaVM
40
) throw() :
41
_segmentType(segmentType),
42
_javaVM(javaVM)
43
{
44
TR_ASSERT(((pageSize() & (pageSize()-1)) == 0), "Page size is not a power of 2, %llu", static_cast<unsigned long long>(pageSize()) );
45
}
46
47
SegmentAllocator::~SegmentAllocator() throw()
48
{
49
}
50
51
J9MemorySegment *
52
SegmentAllocator::allocate(const size_t segmentSize, const std::nothrow_t &tag) throw()
53
{
54
size_t const alignedSize = pageAlign(segmentSize);
55
56
// If low on physical memory we may want to return NULL when allocating scratch segments
57
if (_segmentType & MEMORY_TYPE_JIT_SCRATCH_SPACE)
58
{
59
bool incomplete;
60
TR::CompilationInfo *compInfo = TR::CompilationInfo::get(_javaVM.jitConfig);
61
uint64_t freePhysicalMemory = compInfo->computeAndCacheFreePhysicalMemory(incomplete, 20);
62
if (freePhysicalMemory != OMRPORT_MEMINFO_NOT_AVAILABLE && !incomplete)
63
{
64
if (freePhysicalMemory < (TR::Options::getSafeReservePhysicalMemoryValue() + segmentSize))
65
{
66
// Set a flag that will determine one compilation thread to suspend itself
67
// Even if multiple threads enter his path we still want to suspend only
68
// one thread, not several. This is why we use a flag and not a counter.
69
//
70
// We allow a small race condition: it is possible that between the test
71
// for available physical memory and setting of the flag below, another
72
// compilation thread has suspended itself and reset the flag. The code
73
// below is going to set the flag again, possibly resulting into two
74
// compilation threads being suspended. This is still fine, because, if
75
// needed, a new compilation thread will be activated when a compilation
76
// request is queued
77
compInfo->setSuspendThreadDueToLowPhysicalMemory(true);
78
return NULL;
79
}
80
}
81
}
82
J9MemorySegment * newSegment =
83
_javaVM.internalVMFunctions->allocateMemorySegment(
84
&_javaVM,
85
alignedSize,
86
_segmentType,
87
J9MEM_CATEGORY_JIT
88
);
89
TR_ASSERT(
90
!newSegment || (newSegment->heapAlloc == newSegment->heapBase),
91
"Segment @ %p { heapBase: %p, heapAlloc: %p, heapTop: %p } is stale",
92
newSegment,
93
newSegment->heapBase,
94
newSegment->heapAlloc,
95
newSegment->heapTop
96
);
97
preventAllocationOfBTLMemory(newSegment, &_javaVM, _segmentType);
98
return newSegment;
99
}
100
101
J9MemorySegment &
102
SegmentAllocator::allocate(size_t const segmentSize)
103
{
104
J9MemorySegment * newSegment = allocate(segmentSize, std::nothrow);
105
if (!newSegment) throw std::bad_alloc();
106
return *newSegment;
107
}
108
109
void
110
SegmentAllocator::deallocate(J9MemorySegment &unusedSegment) throw()
111
{
112
_javaVM.internalVMFunctions->freeMemorySegment(&_javaVM, &unusedSegment, TRUE);
113
}
114
115
J9MemorySegment &
116
SegmentAllocator::request(size_t segmentSize)
117
{
118
return allocate(segmentSize);
119
}
120
121
void
122
SegmentAllocator::release(J9MemorySegment &unusedSegment) throw()
123
{
124
deallocate(unusedSegment);
125
}
126
127
size_t
128
SegmentAllocator::pageSize() throw()
129
{
130
PORT_ACCESS_FROM_JAVAVM(&_javaVM);
131
static const size_t pageSize = j9vmem_supported_page_sizes()[0];
132
return pageSize;
133
}
134
135
size_t
136
SegmentAllocator::pageAlign(const size_t requestedSize) throw()
137
{
138
size_t const pageSize = this->pageSize();
139
size_t alignedSize = OMR::align(requestedSize, pageSize);
140
return alignedSize;
141
}
142
143
144
void
145
SegmentAllocator::preventAllocationOfBTLMemory(J9MemorySegment * &segment, J9JavaVM * javaVM, int32_t segmentType)
146
{
147
#if defined(J9ZOS390)
148
// Special code for zOS. If we allocated BTL memory (first 16MB), then we must
149
// release this segment, failing the compilation and forcing to use only one compilation thread
150
if (TR::Options::getCmdLineOptions()->getOption(TR_DontAllocateScratchBTL) &&
151
segment && ((uintptr_t)(segment->heapBase) < (uintptr_t)(1 << 24)))
152
{
153
// If applicable, reduce the number of compilation threads to 1
154
TR::CompilationInfo * compInfo = TR::CompilationInfo::get();
155
if (compInfo)
156
{
157
if (!compInfo->getRampDownMCT())
158
{
159
compInfo->setRampDownMCT();
160
if (TR::Options::getCmdLineOptions()->getVerboseOption(TR_VerboseCompilationThreads))
161
{
162
TR_VerboseLog::writeLineLocked(TR_Vlog_INFO, "t=%u setRampDownMCT because JIT allocated BTL memory", (uint32_t)compInfo->getPersistentInfo()->getElapsedTime());
163
}
164
}
165
else
166
{
167
// Perhaps we should consider lowering the compilation aggressiveness
168
if (!TR::Options::getAOTCmdLineOptions()->getOption(TR_NoOptServer))
169
{
170
TR::Options::getAOTCmdLineOptions()->setOption(TR_NoOptServer);
171
}
172
if (!TR::Options::getJITCmdLineOptions()->getOption(TR_NoOptServer))
173
{
174
TR::Options::getJITCmdLineOptions()->setOption(TR_NoOptServer);
175
}
176
}
177
178
// For scratch memory refuse to return memory below the line. Free the segment and let the compilation fail
179
// Compilation will be retried at lower opt level. However, We should not reject requests coming from hooks.
180
if (segmentType & MEMORY_TYPE_JIT_SCRATCH_SPACE)
181
{
182
J9VMThread *crtVMThread = javaVM->internalVMFunctions->currentVMThread(javaVM);
183
if (compInfo->getCompInfoForThread(crtVMThread))
184
{
185
javaVM->internalVMFunctions->freeMemorySegment(javaVM, segment, TRUE);
186
segment = NULL;
187
}
188
}
189
}
190
}
191
#endif // defined(J9ZOS390)
192
}
193
194
}
195
196