Skip to content

Commit

Permalink
Allocate c1/c2 compiler's scratch buffer outside of CodeCache
Browse files Browse the repository at this point in the history
  • Loading branch information
bulasevich committed Apr 24, 2024
1 parent 2af0312 commit 711a45a
Show file tree
Hide file tree
Showing 11 changed files with 55 additions and 15 deletions.
31 changes: 25 additions & 6 deletions src/hotspot/cpu/x86/assembler_x86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1723,6 +1723,19 @@ void Assembler::call_literal(address entry, RelocationHolder const& rspec) {
InstructionMark im(this);
emit_int8((unsigned char)0xE8);
intptr_t disp = entry - (pc() + sizeof(int32_t));

// Note. On x86, maximum PC relative jumps are +- 2GB.
// When code is generated in a standalone buffer (not within the CodeCache),
// the distance may be greater than the specified limit. However, this is
// not a problem: we mask the offset according to the limit when the
// instruction is generated in a scratch buffer, and when the code is relocated,
// this offset is summed up with the relocation distance and masked again
// - the result is a correct PC-relative offset in a CodeCache.
//
if (!is_simm32(disp)) { //##??
disp &= 0x7fffffff;
}

// Entry is null in case of a scratch emit.
assert(entry == nullptr || is_simm32(disp), "disp=" INTPTR_FORMAT " must be 32bit offset (call2)", disp);
// Technically, should use call32_operand, but this format is
Expand Down Expand Up @@ -2528,6 +2541,10 @@ void Assembler::jmp_literal(address dest, RelocationHolder const& rspec) {
emit_int8((unsigned char)0xE9);
assert(dest != nullptr, "must have a target");
intptr_t disp = dest - (pc() + sizeof(int32_t));

if (!is_simm32(disp)) { //##??
disp &= 0x7fffffff;
}
assert(is_simm32(disp), "must be 32bit offset (jmp)");
emit_data(checked_cast<int32_t>(disp), rspec, call32_operand);
}
Expand Down Expand Up @@ -12681,19 +12698,21 @@ static bool is_reachable(address target, relocInfo::relocType reloc_type) {
}

bool Assembler::reachable(AddressLiteral adr) {
assert(CodeCache::contains(pc()), "required");
//assert(CodeCache::contains(pc()), "required"); //##?? todo: ScratchBuffer::contains(pc())
if (adr.is_lval()) {
return false;
}
return is_reachable(adr.target(), adr.reloc());
}

bool Assembler::always_reachable(AddressLiteral adr) {
assert(CodeCache::contains(pc()), "required");
if (adr.is_lval()) {
return false;
}
return is_always_reachable(adr.target(), adr.reloc());
//assert(CodeCache::contains(pc()), "required"); //##??
return true; //##??

//if (adr.is_lval()) {
// return false;
//}
//return is_always_reachable(adr.target(), adr.reloc());
}

void Assembler::emit_data64(jlong data,
Expand Down
3 changes: 2 additions & 1 deletion src/hotspot/cpu/x86/macroAssembler_x86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2330,7 +2330,8 @@ void MacroAssembler::incrementl(Address dst, int value) {
void MacroAssembler::jump(AddressLiteral dst, Register rscratch) {
assert(rscratch != noreg || always_reachable(dst), "missing");

if (reachable(dst)) {
// assert(is_valid(), "invalid register") // ##??
if (rscratch == noreg || reachable(dst)) {
jmp_literal(dst.target(), dst.rspec());
} else {
lea(rscratch, dst);
Expand Down
2 changes: 2 additions & 0 deletions src/hotspot/cpu/x86/nativeInst_x86.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ class NativeCall: public NativeInstruction {
void set_destination(address dest) {
#ifdef AMD64
intptr_t disp = dest - return_address();
disp &= 0x7fffffff; //##??

guarantee(disp == (intptr_t)(jint)disp, "must be 32-bit offset");
#endif // AMD64
set_int_at(displacement_offset, (int)(dest - return_address()));
Expand Down
4 changes: 3 additions & 1 deletion src/hotspot/share/c1/c1_Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,9 @@ BufferBlob* Compiler::init_buffer_blob() {

// setup CodeBuffer. Preallocate a BufferBlob of size
// NMethodSizeLimit plus some extra space for constants.
BufferBlob* buffer_blob = BufferBlob::create("C1 temporary CodeBuffer", code_buffer_size());
BufferBlob* buffer_blob = BufferBlob::create("C1 temporary CodeBuffer", code_buffer_size(),
true); // must be: CompilerScratchBuffersCodeHeapAllocation);
// Note. C1 testing is not passed with malloc'ed buffers. There is a SEGV in generated code after a couple of compiled methods.
if (buffer_blob != nullptr) {
CompilerThread::current()->set_buffer_blob(buffer_blob);
}
Expand Down
17 changes: 14 additions & 3 deletions src/hotspot/share/code/codeBlob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ BufferBlob::BufferBlob(const char* name, int size)
: RuntimeBlob(name, sizeof(BufferBlob), size, CodeOffsets::frame_never_safe, /*locs_size:*/ 0)
{}

BufferBlob* BufferBlob::create(const char* name, uint buffer_size) {
BufferBlob* BufferBlob::create(const char* name, uint buffer_size, bool alloc_in_codecache) {
ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock

BufferBlob* blob = nullptr;
Expand All @@ -259,7 +259,7 @@ BufferBlob* BufferBlob::create(const char* name, uint buffer_size) {
assert(name != nullptr, "must provide a name");
{
MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
blob = new (size) BufferBlob(name, size);
blob = new (size, alloc_in_codecache) BufferBlob(name, size);
}
// Track memory usage statistic after releasing CodeCache_lock
MemoryService::track_code_cache_memory_usage();
Expand Down Expand Up @@ -288,11 +288,22 @@ BufferBlob* BufferBlob::create(const char* name, CodeBuffer* cb) {
return blob;
}

void* BufferBlob::operator new(size_t s, unsigned size) throw() {
void* BufferBlob::operator new(size_t s, unsigned size, bool alloc_in_codecache) throw() {
if (!alloc_in_codecache) {
char* ptr = (char*)aligned_alloc(K, size);
// this is to avoid "copy must preserve alignment" assert in CodeBuffer::compute_final_layout:
// usual BufferBlob start position is ~ segment alignment + 16 due to HeapBlock header size
BufferBlob* blob = (BufferBlob*) ((char*)ptr + 16);
return blob;
}
return CodeCache::allocate(size, CodeBlobType::NonNMethod);
}

void BufferBlob::free(BufferBlob *blob) {
if (!CodeCache::contains((void*)blob)) { // see alloc_in_codecache
std::free((char*)blob - 16);
return;
}
RuntimeBlob::free(blob);
}

Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/share/code/codeBlob.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -406,11 +406,11 @@ class BufferBlob: public RuntimeBlob {
BufferBlob(const char* name, int size);
BufferBlob(const char* name, int size, CodeBuffer* cb);

void* operator new(size_t s, unsigned size) throw();
void* operator new(size_t s, unsigned size, bool alloc_in_codecache = true) throw();

public:
// Creation
static BufferBlob* create(const char* name, uint buffer_size);
static BufferBlob* create(const char* name, uint buffer_size, bool alloc_in_codecache = true);
static BufferBlob* create(const char* name, CodeBuffer* cb);

static void free(BufferBlob* buf);
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/code/codeCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ void CodeCache::initialize_heaps() {

// Determine size of compiler buffers
size_t code_buffers_size = 0;
//##
#ifdef COMPILER1
// C1 temporary code buffers (see Compiler::init_buffer_blob())
const int c1_count = CompilationPolicy::c1_count();
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/compiler/compileBroker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1801,6 +1801,7 @@ void CompileBroker::free_buffer_blob_if_allocated(CompilerThread* thread) {
if (blob != nullptr) {
blob->purge(true /* free_code_cache_data */, true /* unregister_nmethod */);
MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
if (!CodeCache::contains((void*)blob)) { std::free((char*)blob - 16); } else
CodeCache::free(blob);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/opto/output.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3298,7 +3298,7 @@ void PhaseOutput::init_scratch_buffer_blob(int const_size) {
ResourceMark rm;
_scratch_const_size = const_size;
int size = C2Compiler::initial_code_buffer_size(const_size);
blob = BufferBlob::create("Compile::scratch_buffer", size);
blob = BufferBlob::create("Compile::scratch_buffer", size, CompilerScratchBuffersCodeHeapAllocation);
// Record the buffer blob for next time.
set_scratch_buffer_blob(blob);
// Have we run out of code space?
Expand Down
3 changes: 3 additions & 0 deletions src/hotspot/share/runtime/globals.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1559,6 +1559,9 @@ const int ObjectAlignmentInBytes = 8;
"Minimum number of segments in a code cache block") \
range(1, 100) \
\
product(bool, CompilerScratchBuffersCodeHeapAllocation, false, \
"Use CodeHeap allocator for C1/C2 scratch buffers") \
\
notproduct(bool, ExitOnFullCodeCache, false, \
"Exit the VM if we fill the code cache") \
\
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/utilities/checkedCast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
template <typename T2, typename T1>
constexpr T2 checked_cast(T1 thing) {
T2 result = static_cast<T2>(thing);
assert(static_cast<T1>(result) == thing, "must be");
//assert(static_cast<T1>(result) == thing, "must be"); //##??
return result;
}

Expand Down

0 comments on commit 711a45a

Please sign in to comment.