Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
8287373: remove unnecessary paddings in generated code
Reviewed-by: kvn
  • Loading branch information
Boris Ulasevich committed Jun 15, 2022
1 parent 2471f8f commit 68b2057
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 33 deletions.
2 changes: 1 addition & 1 deletion src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp
Expand Up @@ -2632,7 +2632,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_t

// allocate space for the code
// setup code generation tools
CodeBuffer buffer("handler_blob", 1024, 512);
CodeBuffer buffer("handler_blob", 2048, 1024);
MacroAssembler* masm = new MacroAssembler(&buffer);

const Register java_thread = rdi; // callee-saved for VC++
Expand Down
7 changes: 4 additions & 3 deletions src/hotspot/share/asm/codeBuffer.cpp
Expand Up @@ -96,13 +96,14 @@ CodeBuffer::CodeBuffer(CodeBlob* blob) DEBUG_ONLY(: Scrubber(this, sizeof(*this)
}

void CodeBuffer::initialize(csize_t code_size, csize_t locs_size) {
// Compute maximal alignment.
int align = _insts.alignment();
// Always allow for empty slop around each section.
int slop = (int) CodeSection::end_slop();

assert(SECT_LIMIT == 3, "total_size explicitly lists all section alignments");
int total_size = code_size + _consts.alignment() + _insts.alignment() + _stubs.alignment() + SECT_LIMIT * slop;

assert(blob() == NULL, "only once");
set_blob(BufferBlob::create(_name, code_size + (align+slop) * (SECT_LIMIT+1)));
set_blob(BufferBlob::create(_name, total_size));
if (blob() == NULL) {
// The assembler constructor will throw a fatal on an empty CodeBuffer.
return; // caller must test this
Expand Down
31 changes: 25 additions & 6 deletions src/hotspot/share/asm/codeBuffer.hpp
Expand Up @@ -27,6 +27,7 @@

#include "code/oopRecorder.hpp"
#include "code/relocInfo.hpp"
#include "compiler/compiler_globals.hpp"
#include "utilities/align.hpp"
#include "utilities/debug.hpp"
#include "utilities/macros.hpp"
Expand Down Expand Up @@ -251,16 +252,19 @@ class CodeSection {
void relocate(address at, RelocationHolder const& rspec, int format = 0);
void relocate(address at, relocInfo::relocType rtype, int format = 0, jint method_index = 0);

// alignment requirement for starting offset
// Requirements are that the instruction area and the
// stubs area must start on CodeEntryAlignment, and
// the ctable on sizeof(jdouble)
int alignment() const { return MAX2((int)sizeof(jdouble), (int)CodeEntryAlignment); }
static int alignment(int section);
int alignment() { return alignment(_index); }

// Slop between sections, used only when allocating temporary BufferBlob buffers.
static csize_t end_slop() { return MAX2((int)sizeof(jdouble), (int)CodeEntryAlignment); }

csize_t align_at_start(csize_t off) const { return (csize_t) align_up(off, alignment()); }
csize_t align_at_start(csize_t off, int section) const {
return (csize_t) align_up(off, alignment(section));
}

csize_t align_at_start(csize_t off) const {
return (csize_t) align_up(off, alignment(_index));
}

// Ensure there's enough space left in the current section.
// Return true if there was an expansion.
Expand Down Expand Up @@ -702,4 +706,19 @@ inline bool CodeSection::maybe_expand_to_ensure_remaining(csize_t amount) {
return false;
}

inline int CodeSection::alignment(int section) {
if (section == CodeBuffer::SECT_CONSTS) {
return (int) sizeof(jdouble);
}
if (section == CodeBuffer::SECT_INSTS) {
return (int) CodeEntryAlignment;
}
if (CodeBuffer::SECT_STUBS) {
// CodeBuffer installer expects sections to be HeapWordSize aligned
return HeapWordSize;
}
ShouldNotReachHere();
return 0;
}

#endif // SHARE_ASM_CODEBUFFER_HPP
8 changes: 7 additions & 1 deletion src/hotspot/share/jvmci/jvmciCodeInstaller.cpp
Expand Up @@ -662,7 +662,13 @@ JVMCI::CodeInstallResult CodeInstaller::initialize_buffer(CodeBuffer& buffer, bo
// section itself so they don't need to be accounted for in the
// locs_buffer above.
int stubs_size = estimate_stubs_size(JVMCI_CHECK_OK);
int total_size = align_up(_code_size, buffer.insts()->alignment()) + align_up(_constants_size, buffer.consts()->alignment()) + align_up(stubs_size, buffer.stubs()->alignment());

assert((CodeBuffer::SECT_INSTS == CodeBuffer::SECT_STUBS - 1) &&
(CodeBuffer::SECT_CONSTS == CodeBuffer::SECT_INSTS - 1), "sections order: consts, insts, stubs");
// buffer content: [constants + code_align] + [code + stubs_align] + [stubs]
int total_size = align_up(_constants_size, CodeSection::alignment(CodeBuffer::SECT_INSTS)) +
align_up(_code_size, CodeSection::alignment(CodeBuffer::SECT_STUBS)) +
stubs_size;

if (check_size && total_size > JVMCINMethodSizeLimit) {
return JVMCI::code_too_large;
Expand Down
Expand Up @@ -85,9 +85,12 @@ public boolean equals(Object obj) {
}
}

// DataSectionAlignment value matches the alignment sizeof(jdouble) of the CodeBuffer::SECT_CONSTS code section
static final int validDataSectionAlignment = 8;

@Test(expected = JVMCIError.class)
public void testInvalidAssumption() {
installEmptyCode(new Site[0], new Assumption[]{new InvalidAssumption()}, new Comment[0], 16, new DataPatch[0], null);
installEmptyCode(new Site[0], new Assumption[]{new InvalidAssumption()}, new Comment[0], validDataSectionAlignment, new DataPatch[0], null);
}

@Test(expected = JVMCIError.class)
Expand All @@ -97,101 +100,101 @@ public void testInvalidAlignment() {

@Test(expected = NullPointerException.class)
public void testNullDataPatchInDataSection() {
installEmptyCode(new Site[0], new Assumption[0], new Comment[0], 16, new DataPatch[]{null}, null);
installEmptyCode(new Site[0], new Assumption[0], new Comment[0], validDataSectionAlignment, new DataPatch[]{null}, null);
}

@Test(expected = NullPointerException.class)
public void testNullReferenceInDataSection() {
installEmptyCode(new Site[0], new Assumption[0], new Comment[0], 16, new DataPatch[]{new DataPatch(0, null)}, null);
installEmptyCode(new Site[0], new Assumption[0], new Comment[0], validDataSectionAlignment, new DataPatch[]{new DataPatch(0, null)}, null);
}

@Test(expected = JVMCIError.class)
public void testInvalidDataSectionReference() {
DataSectionReference ref = new DataSectionReference();
ref.setOffset(0);
installEmptyCode(new Site[0], new Assumption[0], new Comment[0], 16, new DataPatch[]{new DataPatch(0, ref)}, null);
installEmptyCode(new Site[0], new Assumption[0], new Comment[0], validDataSectionAlignment, new DataPatch[]{new DataPatch(0, ref)}, null);
}

@Test(expected = JVMCIError.class)
public void testInvalidNarrowMethodInDataSection() {
HotSpotConstant c = (HotSpotConstant) dummyMethod.getEncoding();
ConstantReference ref = new ConstantReference((VMConstant) c.compress());
installEmptyCode(new Site[0], new Assumption[0], new Comment[0], 16, new DataPatch[]{new DataPatch(0, ref)}, null);
installEmptyCode(new Site[0], new Assumption[0], new Comment[0], validDataSectionAlignment, new DataPatch[]{new DataPatch(0, ref)}, null);
}

@Test(expected = NullPointerException.class)
public void testNullConstantInDataSection() {
ConstantReference ref = new ConstantReference(null);
installEmptyCode(new Site[0], new Assumption[0], new Comment[0], 16, new DataPatch[]{new DataPatch(0, ref)}, null);
installEmptyCode(new Site[0], new Assumption[0], new Comment[0], validDataSectionAlignment, new DataPatch[]{new DataPatch(0, ref)}, null);
}

@Test(expected = JVMCIError.class)
public void testInvalidConstantInDataSection() {
ConstantReference ref = new ConstantReference(new InvalidVMConstant());
installEmptyCode(new Site[0], new Assumption[0], new Comment[0], 16, new DataPatch[]{new DataPatch(0, ref)}, null);
installEmptyCode(new Site[0], new Assumption[0], new Comment[0], validDataSectionAlignment, new DataPatch[]{new DataPatch(0, ref)}, null);
}

@Test(expected = NullPointerException.class)
public void testNullReferenceInCode() {
installEmptyCode(new Site[]{new DataPatch(0, null)}, new Assumption[0], new Comment[0], 16, new DataPatch[0], null);
installEmptyCode(new Site[]{new DataPatch(0, null)}, new Assumption[0], new Comment[0], validDataSectionAlignment, new DataPatch[0], null);
}

@Test(expected = NullPointerException.class)
public void testNullConstantInCode() {
ConstantReference ref = new ConstantReference(null);
installEmptyCode(new Site[]{new DataPatch(0, ref)}, new Assumption[0], new Comment[0], 16, new DataPatch[0], null);
installEmptyCode(new Site[]{new DataPatch(0, ref)}, new Assumption[0], new Comment[0], validDataSectionAlignment, new DataPatch[0], null);
}

@Test(expected = JVMCIError.class)
public void testInvalidConstantInCode() {
ConstantReference ref = new ConstantReference(new InvalidVMConstant());
installEmptyCode(new Site[]{new DataPatch(0, ref)}, new Assumption[0], new Comment[0], 16, new DataPatch[0], null);
installEmptyCode(new Site[]{new DataPatch(0, ref)}, new Assumption[0], new Comment[0], validDataSectionAlignment, new DataPatch[0], null);
}

@Test(expected = JVMCIError.class)
public void testInvalidReference() {
InvalidReference ref = new InvalidReference();
installEmptyCode(new Site[]{new DataPatch(0, ref)}, new Assumption[0], new Comment[0], 16, new DataPatch[0], null);
installEmptyCode(new Site[]{new DataPatch(0, ref)}, new Assumption[0], new Comment[0], validDataSectionAlignment, new DataPatch[0], null);
}

@Test(expected = JVMCIError.class)
public void testOutOfBoundsDataSectionReference() {
DataSectionReference ref = new DataSectionReference();
ref.setOffset(0x1000);
installEmptyCode(new Site[]{new DataPatch(0, ref)}, new Assumption[0], new Comment[0], 16, new DataPatch[0], null);
installEmptyCode(new Site[]{new DataPatch(0, ref)}, new Assumption[0], new Comment[0], validDataSectionAlignment, new DataPatch[0], null);
}

@Test(expected = JVMCIError.class)
public void testInvalidMark() {
installEmptyCode(new Site[]{new Mark(0, new Object())}, new Assumption[0], new Comment[0], 16, new DataPatch[0], null);
installEmptyCode(new Site[]{new Mark(0, new Object())}, new Assumption[0], new Comment[0], validDataSectionAlignment, new DataPatch[0], null);
}

@Test(expected = JVMCIError.class)
public void testInvalidMarkInt() {
installEmptyCode(new Site[]{new Mark(0, -1)}, new Assumption[0], new Comment[0], 16, new DataPatch[0], null);
installEmptyCode(new Site[]{new Mark(0, -1)}, new Assumption[0], new Comment[0], validDataSectionAlignment, new DataPatch[0], null);
}

@Test(expected = NullPointerException.class)
public void testNullSite() {
installEmptyCode(new Site[]{null}, new Assumption[0], new Comment[0], 16, new DataPatch[0], null);
installEmptyCode(new Site[]{null}, new Assumption[0], new Comment[0], validDataSectionAlignment, new DataPatch[0], null);
}

@Test(expected = JVMCIError.class)
public void testInfopointMissingDebugInfo() {
Infopoint info = new Infopoint(0, null, InfopointReason.METHOD_START);
installEmptyCode(new Site[]{info}, new Assumption[0], new Comment[0], 16, new DataPatch[0], null);
installEmptyCode(new Site[]{info}, new Assumption[0], new Comment[0], validDataSectionAlignment, new DataPatch[0], null);
}

@Test(expected = JVMCIError.class)
public void testSafepointMissingDebugInfo() {
Infopoint info = new Infopoint(0, null, InfopointReason.SAFEPOINT);
StackSlot deoptRescueSlot = StackSlot.get(null, 0, true);
installEmptyCode(new Site[]{info}, new Assumption[0], new Comment[0], 16, new DataPatch[0], deoptRescueSlot);
installEmptyCode(new Site[]{info}, new Assumption[0], new Comment[0], validDataSectionAlignment, new DataPatch[0], deoptRescueSlot);
}

@Test(expected = JVMCIError.class)
public void testInvalidDeoptRescueSlot() {
StackSlot deoptRescueSlot = StackSlot.get(null, -1, false);
installEmptyCode(new Site[]{}, new Assumption[0], new Comment[0], 16, new DataPatch[0], deoptRescueSlot);
installEmptyCode(new Site[]{}, new Assumption[0], new Comment[0], validDataSectionAlignment, new DataPatch[0], deoptRescueSlot);
}
}
Expand Up @@ -97,7 +97,7 @@ private void test(VirtualObject[] vobj, JavaValue[] values, JavaKind[] slotKinds
BytecodeFrame frame = new BytecodeFrame(null, dummyMethod, 0, false, false, values, slotKinds, locals, stack, locks);
DebugInfo info = new DebugInfo(frame, vobj);
info.setReferenceMap(new HotSpotReferenceMap(new Location[0], new Location[0], new int[0], 8));
installEmptyCode(new Site[]{new Infopoint(0, info, InfopointReason.SAFEPOINT)}, new Assumption[0], new Comment[0], 16, new DataPatch[0], deoptRescueSlot);
installEmptyCode(new Site[]{new Infopoint(0, info, InfopointReason.SAFEPOINT)}, new Assumption[0], new Comment[0], 8, new DataPatch[0], deoptRescueSlot);
}

@Test(expected = NullPointerException.class)
Expand Down
Expand Up @@ -67,7 +67,7 @@ private void test(ReferenceMap refMap) {
BytecodePosition pos = new BytecodePosition(null, dummyMethod, 0);
DebugInfo info = new DebugInfo(pos);
info.setReferenceMap(refMap);
installEmptyCode(new Site[]{new Infopoint(0, info, InfopointReason.SAFEPOINT)}, new Assumption[0], new Comment[0], 16, new DataPatch[0], StackSlot.get(null, 0, true));
installEmptyCode(new Site[]{new Infopoint(0, info, InfopointReason.SAFEPOINT)}, new Assumption[0], new Comment[0], 8, new DataPatch[0], StackSlot.get(null, 0, true));
}

@Test(expected = NullPointerException.class)
Expand Down
Expand Up @@ -116,10 +116,11 @@ private void runTest() {
}
HotSpotResolvedJavaMethod method = CTVMUtilities
.getResolvedMethod(SimpleClass.class, testMethod);
int dataSectionAlignment = 8; // CodeBuffer::SECT_CONSTS code section alignment
HotSpotCompiledCode compiledCode = new HotSpotCompiledNmethod(METHOD_NAME,
new byte[0], 0, new Site[0], new Assumption[0],
new ResolvedJavaMethod[]{method}, new Comment[0], new byte[0],
16, new DataPatch[0], false, 0, null,
dataSectionAlignment, new DataPatch[0], false, 0, null,
method, 0, 1, 0L, false);
codeCache.installCode(method, compiledCode, /* installedCode = */ null,
/* speculationLog = */ null, /* isDefault = */ false);
Expand Down
Expand Up @@ -316,7 +316,8 @@ public HotSpotCompiledCode finish(HotSpotResolvedJavaMethod method) {
Site[] finishedSites = sites.toArray(new Site[0]);
byte[] finishedData = data.finish();
DataPatch[] finishedDataPatches = dataPatches.toArray(new DataPatch[0]);
return new HotSpotCompiledNmethod(method.getName(), finishedCode, finishedCode.length, finishedSites, new Assumption[0], new ResolvedJavaMethod[]{method}, new Comment[0], finishedData, 16,
int dataSectionAlignment = 8; // CodeBuffer::SECT_CONSTS code section alignment
return new HotSpotCompiledNmethod(method.getName(), finishedCode, finishedCode.length, finishedSites, new Assumption[0], new ResolvedJavaMethod[]{method}, new Comment[0], finishedData, dataSectionAlignment,
finishedDataPatches, false, frameSize, deoptRescue, method, 0, id, 0L, false);
}

Expand Down

0 comments on commit 68b2057

Please sign in to comment.