8146608: [JVMCI] DebugInfo Tests on DeoptimizeALot runs fails in assert(_pc == *pc_addr || pc == *pc_addr) frame::patch_pc() /frame_x86.cpp:285

Reviewed-by: twisti
This commit is contained in:
Roland Schatz 2016-02-03 12:16:44 +01:00
parent eb2347dd71
commit 76b459d629
13 changed files with 78 additions and 34 deletions

View File

@ -24,6 +24,7 @@ package jdk.vm.ci.hotspot;
import jdk.vm.ci.code.BytecodeFrame;
import jdk.vm.ci.code.CompiledCode;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.code.site.DataPatch;
import jdk.vm.ci.code.site.Infopoint;
import jdk.vm.ci.code.site.Site;
@ -99,9 +100,9 @@ public class HotSpotCompiledCode implements CompiledCode {
protected final int totalFrameSize;
/**
* Offset in bytes for the custom stack area (relative to sp).
* The deopt rescue slot. Must be non-null if there is a safepoint in the method.
*/
protected final int customStackAreaOffset;
protected final StackSlot deoptRescueSlot;
public static class Comment {
@ -115,7 +116,7 @@ public class HotSpotCompiledCode implements CompiledCode {
}
public HotSpotCompiledCode(String name, byte[] targetCode, int targetCodeSize, Site[] sites, Assumption[] assumptions, ResolvedJavaMethod[] methods, Comment[] comments, byte[] dataSection,
int dataSectionAlignment, DataPatch[] dataSectionPatches, boolean isImmutablePIC, int totalFrameSize, int customStackAreaOffset) {
int dataSectionAlignment, DataPatch[] dataSectionPatches, boolean isImmutablePIC, int totalFrameSize, StackSlot deoptRescueSlot) {
this.name = name;
this.targetCode = targetCode;
this.targetCodeSize = targetCodeSize;
@ -129,7 +130,7 @@ public class HotSpotCompiledCode implements CompiledCode {
this.dataSectionPatches = dataSectionPatches;
this.isImmutablePIC = isImmutablePIC;
this.totalFrameSize = totalFrameSize;
this.customStackAreaOffset = customStackAreaOffset;
this.deoptRescueSlot = deoptRescueSlot;
assert validateFrames();
}

View File

@ -22,6 +22,7 @@
*/
package jdk.vm.ci.hotspot;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.code.site.DataPatch;
import jdk.vm.ci.code.site.Site;
import jdk.vm.ci.inittimer.SuppressFBWarnings;
@ -55,9 +56,9 @@ public final class HotSpotCompiledNmethod extends HotSpotCompiledCode {
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "set by the VM") private String installationFailureMessage;
public HotSpotCompiledNmethod(String name, byte[] targetCode, int targetCodeSize, Site[] sites, Assumption[] assumptions, ResolvedJavaMethod[] methods, Comment[] comments, byte[] dataSection,
int dataSectionAlignment, DataPatch[] dataSectionPatches, boolean isImmutablePIC, int totalFrameSize, int customStackAreaOffset, HotSpotResolvedJavaMethod method, int entryBCI,
int dataSectionAlignment, DataPatch[] dataSectionPatches, boolean isImmutablePIC, int totalFrameSize, StackSlot deoptRescueSlot, HotSpotResolvedJavaMethod method, int entryBCI,
int id, long jvmciEnv, boolean hasUnsafeAccess) {
super(name, targetCode, targetCodeSize, sites, assumptions, methods, comments, dataSection, dataSectionAlignment, dataSectionPatches, isImmutablePIC, totalFrameSize, customStackAreaOffset);
super(name, targetCode, targetCodeSize, sites, assumptions, methods, comments, dataSection, dataSectionAlignment, dataSectionPatches, isImmutablePIC, totalFrameSize, deoptRescueSlot);
this.method = method;
this.entryBCI = entryBCI;
this.id = id;

View File

@ -546,7 +546,7 @@ JVMCIEnv::CodeInstallResult CodeInstaller::install(JVMCICompiler* compiler, Hand
// Make sure a valid compile_id is associated with every compile
id = CompileBroker::assign_compile_id_unlocked(Thread::current(), method, entry_bci);
}
result = JVMCIEnv::register_method(method, nm, entry_bci, &_offsets, _custom_stack_area_offset, &buffer,
result = JVMCIEnv::register_method(method, nm, entry_bci, &_offsets, _orig_pc_offset, &buffer,
stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table,
compiler, _debug_recorder, _dependencies, env, id,
has_unsafe_access, _has_wide_vector, installed_code, compiled_code, speculation_log);
@ -576,7 +576,19 @@ void CodeInstaller::initialize_fields(oop target, oop compiled_code, TRAPS) {
_code_handle = JNIHandles::make_local(HotSpotCompiledCode::targetCode(compiled_code));
_code_size = HotSpotCompiledCode::targetCodeSize(compiled_code);
_total_frame_size = HotSpotCompiledCode::totalFrameSize(compiled_code);
_custom_stack_area_offset = HotSpotCompiledCode::customStackAreaOffset(compiled_code);
oop deoptRescueSlot = HotSpotCompiledCode::deoptRescueSlot(compiled_code);
if (deoptRescueSlot == NULL) {
_orig_pc_offset = -1;
} else {
_orig_pc_offset = StackSlot::offset(deoptRescueSlot);
if (StackSlot::addFrameSize(deoptRescueSlot)) {
_orig_pc_offset += _total_frame_size;
}
if (_orig_pc_offset < 0) {
JVMCI_ERROR("invalid deopt rescue slot: %d", _orig_pc_offset);
}
}
// Pre-calculate the constants section size. This is required for PC-relative addressing.
_data_section_handle = JNIHandles::make_local(HotSpotCompiledCode::dataSection(compiled_code));
@ -724,6 +736,9 @@ JVMCIEnv::CodeInstallResult CodeInstaller::initialize_buffer(CodeBuffer& buffer,
if (site_InfopointReason::SAFEPOINT() == reason || site_InfopointReason::CALL() == reason || site_InfopointReason::IMPLICIT_EXCEPTION() == reason) {
TRACE_jvmci_4("safepoint at %i", pc_offset);
site_Safepoint(buffer, pc_offset, site, CHECK_OK);
if (_orig_pc_offset < 0) {
JVMCI_ERROR_OK("method contains safepoint, but has not deopt rescue slot");
}
} else {
TRACE_jvmci_4("infopoint at %i", pc_offset);
site_Infopoint(buffer, pc_offset, site, CHECK_OK);

View File

@ -125,7 +125,7 @@ private:
jobject _code_handle;
jint _code_size;
jint _total_frame_size;
jint _custom_stack_area_offset;
jint _orig_pc_offset;
jint _parameter_count;
jint _constants_size;
#ifndef PRODUCT

View File

@ -91,7 +91,7 @@ class JVMCIJavaClasses : AllStatic {
objArrayOop_field(HotSpotCompiledCode, dataSectionPatches, "[Ljdk/vm/ci/code/site/DataPatch;") \
boolean_field(HotSpotCompiledCode, isImmutablePIC) \
int_field(HotSpotCompiledCode, totalFrameSize) \
int_field(HotSpotCompiledCode, customStackAreaOffset) \
oop_field(HotSpotCompiledCode, deoptRescueSlot, "Ljdk/vm/ci/code/StackSlot;") \
end_class \
start_class(HotSpotCompiledCode_Comment) \
oop_field(HotSpotCompiledCode_Comment, text, "Ljava/lang/String;") \

View File

@ -181,6 +181,8 @@ public abstract class TestAssembler {
private int stackAlignment;
private int curStackSlot;
private StackSlot deoptRescue;
protected TestAssembler(CodeCacheProvider codeCache, int initialFrameSize, int stackAlignment, PlatformKind narrowOopKind, Register... registers) {
this.narrowOopKind = LIRKind.reference(narrowOopKind);
@ -216,6 +218,10 @@ public abstract class TestAssembler {
return StackSlot.get(kind, -curStackSlot, true);
}
protected void setDeoptRescueSlot(StackSlot deoptRescue) {
this.deoptRescue = deoptRescue;
}
protected void recordImplicitException(DebugInfo info) {
sites.add(new Infopoint(code.position(), info, InfopointReason.IMPLICIT_EXCEPTION));
}
@ -249,7 +255,7 @@ public abstract class TestAssembler {
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,
finishedDataPatches, false, frameSize, 0, method, 0, id, 0L, false);
finishedDataPatches, false, frameSize, deoptRescue, method, 0, id, 0L, false);
}
protected static class Buffer {

View File

@ -63,6 +63,7 @@ public class AMD64TestAssembler extends TestAssembler {
emitFatNop();
code.emitByte(0x50 | AMD64.rbp.encoding); // PUSH rbp
emitMove(true, AMD64.rbp, AMD64.rsp); // MOV rbp, rsp
setDeoptRescueSlot(newStackSlot(LIRKind.value(AMD64Kind.QWORD)));
}
@Override

View File

@ -68,6 +68,7 @@ public class SPARCTestAssembler extends TestAssembler {
@Override
public void emitPrologue() {
emitOp3(0b10, SPARC.sp, 0b111100, SPARC.sp, -SPARC.REGISTER_SAFE_AREA_SIZE); // SAVE sp, -128, sp
setDeoptRescueSlot(newStackSlot(LIRKind.value(SPARCKind.XWORD)));
}
@Override

View File

@ -28,6 +28,7 @@ import java.lang.reflect.Method;
import jdk.vm.ci.code.Architecture;
import jdk.vm.ci.code.CodeCacheProvider;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.code.site.DataPatch;
import jdk.vm.ci.code.site.Site;
import jdk.vm.ci.hotspot.HotSpotCompiledCode;
@ -71,9 +72,9 @@ public class CodeInstallerTest {
dummyMethod = metaAccess.lookupJavaMethod(method);
}
protected void installEmptyCode(Site[] sites, Assumption[] assumptions, Comment[] comments, int dataSectionAlignment, DataPatch[] dataSectionPatches) {
protected void installEmptyCode(Site[] sites, Assumption[] assumptions, Comment[] comments, int dataSectionAlignment, DataPatch[] dataSectionPatches, StackSlot deoptRescueSlot) {
HotSpotCompiledCode code = new HotSpotCompiledCode("dummyMethod", new byte[0], 0, sites, assumptions, new ResolvedJavaMethod[]{dummyMethod}, comments, new byte[8], dataSectionAlignment,
dataSectionPatches, false, 0, 0);
dataSectionPatches, false, 0, deoptRescueSlot);
codeCache.addCode(dummyMethod, code, null, null);
}

View File

@ -30,6 +30,7 @@
package compiler.jvmci.errors;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.code.site.ConstantReference;
import jdk.vm.ci.code.site.DataPatch;
import jdk.vm.ci.code.site.DataSectionReference;
@ -80,104 +81,111 @@ public class TestInvalidCompilationResult extends CodeInstallerTest {
@Test(expected = JVMCIError.class)
public void testInvalidAssumption() {
installEmptyCode(new Site[0], new Assumption[]{new InvalidAssumption()}, new Comment[0], 16, new DataPatch[0]);
installEmptyCode(new Site[0], new Assumption[]{new InvalidAssumption()}, new Comment[0], 16, new DataPatch[0], null);
}
@Test(expected = JVMCIError.class)
public void testInvalidAlignment() {
installEmptyCode(new Site[0], new Assumption[0], new Comment[0], 7, new DataPatch[0]);
installEmptyCode(new Site[0], new Assumption[0], new Comment[0], 7, new DataPatch[0], null);
}
@Test(expected = NullPointerException.class)
public void testNullDataPatchInDataSection() {
installEmptyCode(new Site[0], new Assumption[0], new Comment[0], 16, new DataPatch[]{null});
installEmptyCode(new Site[0], new Assumption[0], new Comment[0], 16, 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)});
installEmptyCode(new Site[0], new Assumption[0], new Comment[0], 16, 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)});
installEmptyCode(new Site[0], new Assumption[0], new Comment[0], 16, 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)});
installEmptyCode(new Site[0], new Assumption[0], new Comment[0], 16, 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)});
installEmptyCode(new Site[0], new Assumption[0], new Comment[0], 16, 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)});
installEmptyCode(new Site[0], new Assumption[0], new Comment[0], 16, 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]);
installEmptyCode(new Site[]{new DataPatch(0, null)}, new Assumption[0], new Comment[0], 16, 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]);
installEmptyCode(new Site[]{new DataPatch(0, ref)}, new Assumption[0], new Comment[0], 16, 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]);
installEmptyCode(new Site[]{new DataPatch(0, ref)}, new Assumption[0], new Comment[0], 16, 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]);
installEmptyCode(new Site[]{new DataPatch(0, ref)}, new Assumption[0], new Comment[0], 16, 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]);
installEmptyCode(new Site[]{new DataPatch(0, ref)}, new Assumption[0], new Comment[0], 16, 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]);
installEmptyCode(new Site[]{new Mark(0, new Object())}, new Assumption[0], new Comment[0], 16, 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]);
installEmptyCode(new Site[]{new Mark(0, -1)}, new Assumption[0], new Comment[0], 16, 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]);
installEmptyCode(new Site[]{null}, new Assumption[0], new Comment[0], 16, 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]);
installEmptyCode(new Site[]{info}, new Assumption[0], new Comment[0], 16, new DataPatch[0], null);
}
@Test(expected = JVMCIError.class)
public void testSafepointMissingDebugInfo() {
Infopoint info = new Infopoint(0, null, InfopointReason.SAFEPOINT);
installEmptyCode(new Site[]{info}, new Assumption[0], new Comment[0], 16, new DataPatch[0]);
StackSlot deoptRescueSlot = StackSlot.get(null, 0, true);
installEmptyCode(new Site[]{info}, new Assumption[0], new Comment[0], 16, 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);
}
}

View File

@ -66,10 +66,14 @@ public class TestInvalidDebugInfo extends CodeInstallerTest {
}
private void test(VirtualObject[] vobj, JavaValue[] values, JavaKind[] slotKinds, int locals, int stack, int locks) {
test(vobj, values, slotKinds, locals, stack, locks, StackSlot.get(null, 0, true));
}
private void test(VirtualObject[] vobj, JavaValue[] values, JavaKind[] slotKinds, int locals, int stack, int locks, StackSlot deoptRescueSlot) {
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]);
installEmptyCode(new Site[]{new Infopoint(0, info, InfopointReason.SAFEPOINT)}, new Assumption[0], new Comment[0], 16, new DataPatch[0], deoptRescueSlot);
}
@Test(expected = NullPointerException.class)
@ -82,6 +86,11 @@ public class TestInvalidDebugInfo extends CodeInstallerTest {
test(new JavaValue[0], null, 0, 0, 0);
}
@Test(expected = JVMCIError.class)
public void testMissingDeoptRescueSlot() {
test(null, new JavaValue[0], new JavaKind[0], 0, 0, 0, null);
}
@Test(expected = JVMCIError.class)
public void testUnexpectedScopeValuesLength() {
test(new JavaValue[]{JavaConstant.FALSE}, new JavaKind[0], 0, 0, 0);

View File

@ -35,6 +35,7 @@ import jdk.vm.ci.code.DebugInfo;
import jdk.vm.ci.code.Location;
import jdk.vm.ci.code.ReferenceMap;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.code.site.DataPatch;
import jdk.vm.ci.code.site.Infopoint;
import jdk.vm.ci.code.site.InfopointReason;
@ -61,7 +62,7 @@ public class TestInvalidOopMap extends CodeInstallerTest {
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]);
installEmptyCode(new Site[]{new Infopoint(0, info, InfopointReason.SAFEPOINT)}, new Assumption[0], new Comment[0], 16, new DataPatch[0], StackSlot.get(null, 0, true));
}
@Test(expected = NullPointerException.class)

View File

@ -109,7 +109,7 @@ public class JvmciNotifyInstallEventTest implements HotSpotVMEventListener {
.getResolvedMethod(SimpleClass.class, testMethod);
HotSpotCompiledCode compiledCode = new HotSpotCompiledCode(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, 0);
new DataPatch[0], false, 0, null);
codeCache.installCode(method, compiledCode, /* installedCode = */ null, /* speculationLog = */ null,
/* isDefault = */ false);
Asserts.assertEQ(gotInstallNotification, 1,