8210478: Update Graal

Reviewed-by: kvn
This commit is contained in:
Igor Veresov 2018-09-13 22:45:12 -07:00
parent 07392d976a
commit acb7acc64f
46 changed files with 817 additions and 644 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2017, 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

View File

@ -24,6 +24,7 @@
package org.graalvm.compiler.hotspot.management;
import org.graalvm.compiler.phases.common.jmx.HotSpotMBeanOperationProvider;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
@ -49,6 +50,7 @@ import org.graalvm.compiler.hotspot.HotSpotGraalRuntime;
import org.graalvm.compiler.options.OptionDescriptor;
import org.graalvm.compiler.options.OptionDescriptors;
import org.graalvm.compiler.options.OptionsParser;
import org.graalvm.compiler.serviceprovider.GraalServices;
/**
* MBean used to access properties and operations of a {@link HotSpotGraalRuntime} instance.
@ -170,11 +172,32 @@ final class HotSpotGraalRuntimeMBean implements DynamicMBean {
if (DEBUG) {
System.out.printf("invoke: %s%s%n", actionName, Arrays.asList(params));
}
Object retvalue = runtime.invokeManagementAction(actionName, params);
Object retvalue = null;
if ("dumpMethod".equals(actionName)) {
retvalue = runtime.invokeManagementAction(actionName, params);
} else {
boolean found = false;
for (HotSpotMBeanOperationProvider p : GraalServices.load(HotSpotMBeanOperationProvider.class)) {
List<MBeanOperationInfo> info = new ArrayList<>();
p.registerOperations(MBeanOperationInfo.class, info);
for (MBeanOperationInfo op : info) {
if (actionName.equals(op.getName())) {
retvalue = p.invoke(actionName, params, signature);
found = true;
break;
}
}
}
if (!found) {
throw new MBeanException(new IllegalStateException("Cannot find operation " + actionName));
}
}
if (DEBUG) {
System.out.printf("invoke: %s%s = %s%n", actionName, Arrays.asList(params), retvalue);
}
return retvalue;
} catch (MBeanException ex) {
throw ex;
} catch (Exception ex) {
throw new ReflectionException(ex);
}
@ -198,30 +221,35 @@ final class HotSpotGraalRuntimeMBean implements DynamicMBean {
return o1.getName().compareTo(o2.getName());
}
});
MBeanOperationInfo[] ops = {
new MBeanOperationInfo("dumpMethod", "Enable IGV dumps for provided method", new MBeanParameterInfo[]{
new MBeanParameterInfo("className", "java.lang.String", "Class to observe"),
new MBeanParameterInfo("methodName", "java.lang.String", "Method to observe"),
}, "void", MBeanOperationInfo.ACTION),
new MBeanOperationInfo("dumpMethod", "Enable IGV dumps for provided method", new MBeanParameterInfo[]{
new MBeanParameterInfo("className", "java.lang.String", "Class to observe"),
new MBeanParameterInfo("methodName", "java.lang.String", "Method to observe"),
new MBeanParameterInfo("filter", "java.lang.String", "The parameter for Dump option"),
}, "void", MBeanOperationInfo.ACTION),
new MBeanOperationInfo("dumpMethod", "Enable IGV dumps for provided method", new MBeanParameterInfo[]{
new MBeanParameterInfo("className", "java.lang.String", "Class to observe"),
new MBeanParameterInfo("methodName", "java.lang.String", "Method to observe"),
new MBeanParameterInfo("filter", "java.lang.String", "The parameter for Dump option"),
new MBeanParameterInfo("host", "java.lang.String", "The host where the IGV tool is running at"),
new MBeanParameterInfo("port", "int", "The port where the IGV tool is listening at"),
}, "void", MBeanOperationInfo.ACTION)
};
List<MBeanOperationInfo> opts = new ArrayList<>();
opts.add(new MBeanOperationInfo("dumpMethod", "Enable IGV dumps for provided method", new MBeanParameterInfo[]{
new MBeanParameterInfo("className", "java.lang.String", "Class to observe"),
new MBeanParameterInfo("methodName", "java.lang.String", "Method to observe"),
}, "void", MBeanOperationInfo.ACTION));
opts.add(new MBeanOperationInfo("dumpMethod", "Enable IGV dumps for provided method", new MBeanParameterInfo[]{
new MBeanParameterInfo("className", "java.lang.String", "Class to observe"),
new MBeanParameterInfo("methodName", "java.lang.String", "Method to observe"),
new MBeanParameterInfo("filter", "java.lang.String", "The parameter for Dump option"),
}, "void", MBeanOperationInfo.ACTION));
opts.add(new MBeanOperationInfo("dumpMethod", "Enable IGV dumps for provided method", new MBeanParameterInfo[]{
new MBeanParameterInfo("className", "java.lang.String", "Class to observe"),
new MBeanParameterInfo("methodName", "java.lang.String", "Method to observe"),
new MBeanParameterInfo("filter", "java.lang.String", "The parameter for Dump option"),
new MBeanParameterInfo("host", "java.lang.String", "The host where the IGV tool is running at"),
new MBeanParameterInfo("port", "int", "The port where the IGV tool is listening at"),
}, "void", MBeanOperationInfo.ACTION));
for (HotSpotMBeanOperationProvider p : GraalServices.load(HotSpotMBeanOperationProvider.class)) {
p.registerOperations(MBeanOperationInfo.class, opts);
}
return new MBeanInfo(
HotSpotGraalRuntimeMBean.class.getName(),
"Graal",
attrs.toArray(new MBeanAttributeInfo[attrs.size()]),
null, ops, null);
null,
opts.toArray(new MBeanOperationInfo[opts.size()]),
null);
}
private static EconomicMap<String, OptionDescriptor> getOptionDescriptors() {

View File

@ -74,6 +74,7 @@ module jdk.internal.vm.compiler {
jdk.aot,
jdk.internal.vm.compiler.management;
exports org.graalvm.compiler.phases to jdk.aot;
exports org.graalvm.compiler.phases.common.jmx to jdk.internal.vm.compiler.management;
exports org.graalvm.compiler.phases.tiers to jdk.aot;
exports org.graalvm.compiler.printer to jdk.aot;
exports org.graalvm.compiler.runtime to jdk.aot;

View File

@ -52,6 +52,8 @@ import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.SD;
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.SS;
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.WORD;
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.L128;
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.L256;
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.LZ;
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.M_0F;
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.M_0F38;
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.M_0F3A;
@ -78,7 +80,6 @@ import org.graalvm.compiler.debug.GraalError;
import jdk.vm.ci.amd64.AMD64;
import jdk.vm.ci.amd64.AMD64.CPUFeature;
import jdk.vm.ci.amd64.AMD64Kind;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.Register.RegisterCategory;
import jdk.vm.ci.code.TargetDescription;
@ -893,7 +894,7 @@ public class AMD64Assembler extends AMD64BaseAssembler {
}
}
private enum AVXOpAssertion {
private enum VEXOpAssertion {
AVX1(CPUFeature.AVX, CPUFeature.AVX),
AVX1_2(CPUFeature.AVX, CPUFeature.AVX2),
AVX2(CPUFeature.AVX2, CPUFeature.AVX2),
@ -903,23 +904,25 @@ public class AMD64Assembler extends AMD64BaseAssembler {
XMM_CPU(CPUFeature.AVX, null, XMM, null, CPU, null),
XMM_XMM_CPU(CPUFeature.AVX, null, XMM, XMM, CPU, null),
CPU_XMM(CPUFeature.AVX, null, CPU, null, XMM, null),
AVX1_2_CPU_XMM(CPUFeature.AVX, CPUFeature.AVX2, CPU, null, XMM, null);
AVX1_2_CPU_XMM(CPUFeature.AVX, CPUFeature.AVX2, CPU, null, XMM, null),
BMI1(CPUFeature.BMI1, null, CPU, CPU, CPU, null),
BMI2(CPUFeature.BMI2, null, CPU, CPU, CPU, null);
private final CPUFeature avx128feature;
private final CPUFeature avx256feature;
private final CPUFeature l128feature;
private final CPUFeature l256feature;
private final RegisterCategory rCategory;
private final RegisterCategory vCategory;
private final RegisterCategory mCategory;
private final RegisterCategory imm8Category;
AVXOpAssertion(CPUFeature avx128feature, CPUFeature avx256feature) {
this(avx128feature, avx256feature, XMM, XMM, XMM, XMM);
VEXOpAssertion(CPUFeature l128feature, CPUFeature l256feature) {
this(l128feature, l256feature, XMM, XMM, XMM, XMM);
}
AVXOpAssertion(CPUFeature avx128feature, CPUFeature avx256feature, RegisterCategory rCategory, RegisterCategory vCategory, RegisterCategory mCategory, RegisterCategory imm8Category) {
this.avx128feature = avx128feature;
this.avx256feature = avx256feature;
VEXOpAssertion(CPUFeature l128feature, CPUFeature l256feature, RegisterCategory rCategory, RegisterCategory vCategory, RegisterCategory mCategory, RegisterCategory imm8Category) {
this.l128feature = l128feature;
this.l256feature = l256feature;
this.rCategory = rCategory;
this.vCategory = vCategory;
this.mCategory = mCategory;
@ -927,16 +930,20 @@ public class AMD64Assembler extends AMD64BaseAssembler {
}
public boolean check(AMD64 arch, AVXSize size, Register r, Register v, Register m) {
return check(arch, size, r, v, m, null);
return check(arch, getLFlag(size), r, v, m, null);
}
public boolean check(AMD64 arch, AVXSize size, Register r, Register v, Register m, Register imm8) {
switch (size) {
case XMM:
assert avx128feature != null && arch.getFeatures().contains(avx128feature) : "emitting illegal 128 bit instruction";
return check(arch, getLFlag(size), r, v, m, imm8);
}
public boolean check(AMD64 arch, int l, Register r, Register v, Register m, Register imm8) {
switch (l) {
case L128:
assert l128feature != null && arch.getFeatures().contains(l128feature) : "emitting illegal 128 bit instruction";
break;
case YMM:
assert avx256feature != null && arch.getFeatures().contains(avx256feature) : "emitting illegal 256 bit instruction";
case L256:
assert l256feature != null && arch.getFeatures().contains(l256feature) : "emitting illegal 256 bit instruction";
break;
}
if (r != null) {
@ -957,9 +964,9 @@ public class AMD64Assembler extends AMD64BaseAssembler {
public boolean supports(EnumSet<CPUFeature> features, AVXSize avxSize) {
switch (avxSize) {
case XMM:
return avx128feature != null && features.contains(avx128feature);
return l128feature != null && features.contains(l128feature);
case YMM:
return avx256feature != null && features.contains(avx256feature);
return l256feature != null && features.contains(l256feature);
default:
throw GraalError.shouldNotReachHere();
}
@ -976,9 +983,9 @@ public class AMD64Assembler extends AMD64BaseAssembler {
protected final int op;
private final String opcode;
protected final AVXOpAssertion assertion;
protected final VEXOpAssertion assertion;
protected VexOp(String opcode, int pp, int mmmmm, int w, int op, AVXOpAssertion assertion) {
protected VexOp(String opcode, int pp, int mmmmm, int w, int op, VEXOpAssertion assertion) {
this.pp = pp;
this.mmmmm = mmmmm;
this.w = w;
@ -987,10 +994,6 @@ public class AMD64Assembler extends AMD64BaseAssembler {
this.assertion = assertion;
}
public boolean isSupported(AMD64Assembler vasm, AMD64Kind kind) {
return assertion.supports(((AMD64) vasm.target.arch).getFeatures(), AVXKind.getRegisterSize(kind));
}
public final boolean isSupported(AMD64Assembler vasm, AVXSize size) {
return assertion.supports(((AMD64) vasm.target.arch).getFeatures(), size);
}
@ -1006,14 +1009,14 @@ public class AMD64Assembler extends AMD64BaseAssembler {
*/
public static class VexRROp extends VexOp {
// @formatter:off
public static final VexRROp VMASKMOVDQU = new VexRROp("VMASKMOVDQU", P_66, M_0F, WIG, 0xF7, AVXOpAssertion.AVX1_128ONLY);
public static final VexRROp VMASKMOVDQU = new VexRROp("VMASKMOVDQU", P_66, M_0F, WIG, 0xF7, VEXOpAssertion.AVX1_128ONLY);
// @formatter:on
protected VexRROp(String opcode, int pp, int mmmmm, int w, int op) {
this(opcode, pp, mmmmm, w, op, AVXOpAssertion.AVX1);
this(opcode, pp, mmmmm, w, op, VEXOpAssertion.AVX1);
}
protected VexRROp(String opcode, int pp, int mmmmm, int w, int op, AVXOpAssertion assertion) {
protected VexRROp(String opcode, int pp, int mmmmm, int w, int op, VEXOpAssertion assertion) {
super(opcode, pp, mmmmm, w, op, assertion);
}
@ -1031,10 +1034,10 @@ public class AMD64Assembler extends AMD64BaseAssembler {
*/
public static class VexRMOp extends VexRROp {
// @formatter:off
public static final VexRMOp VCVTTSS2SI = new VexRMOp("VCVTTSS2SI", P_F3, M_0F, W0, 0x2C, AVXOpAssertion.CPU_XMM);
public static final VexRMOp VCVTTSS2SQ = new VexRMOp("VCVTTSS2SQ", P_F3, M_0F, W1, 0x2C, AVXOpAssertion.CPU_XMM);
public static final VexRMOp VCVTTSD2SI = new VexRMOp("VCVTTSD2SI", P_F2, M_0F, W0, 0x2C, AVXOpAssertion.CPU_XMM);
public static final VexRMOp VCVTTSD2SQ = new VexRMOp("VCVTTSD2SQ", P_F2, M_0F, W1, 0x2C, AVXOpAssertion.CPU_XMM);
public static final VexRMOp VCVTTSS2SI = new VexRMOp("VCVTTSS2SI", P_F3, M_0F, W0, 0x2C, VEXOpAssertion.CPU_XMM);
public static final VexRMOp VCVTTSS2SQ = new VexRMOp("VCVTTSS2SQ", P_F3, M_0F, W1, 0x2C, VEXOpAssertion.CPU_XMM);
public static final VexRMOp VCVTTSD2SI = new VexRMOp("VCVTTSD2SI", P_F2, M_0F, W0, 0x2C, VEXOpAssertion.CPU_XMM);
public static final VexRMOp VCVTTSD2SQ = new VexRMOp("VCVTTSD2SQ", P_F2, M_0F, W1, 0x2C, VEXOpAssertion.CPU_XMM);
public static final VexRMOp VCVTPS2PD = new VexRMOp("VCVTPS2PD", P_, M_0F, WIG, 0x5A);
public static final VexRMOp VCVTPD2PS = new VexRMOp("VCVTPD2PS", P_66, M_0F, WIG, 0x5A);
public static final VexRMOp VCVTDQ2PS = new VexRMOp("VCVTDQ2PS", P_, M_0F, WIG, 0x5B);
@ -1042,14 +1045,14 @@ public class AMD64Assembler extends AMD64BaseAssembler {
public static final VexRMOp VCVTTPD2DQ = new VexRMOp("VCVTTPD2DQ", P_66, M_0F, WIG, 0xE6);
public static final VexRMOp VCVTDQ2PD = new VexRMOp("VCVTDQ2PD", P_F3, M_0F, WIG, 0xE6);
public static final VexRMOp VBROADCASTSS = new VexRMOp("VBROADCASTSS", P_66, M_0F38, W0, 0x18);
public static final VexRMOp VBROADCASTSD = new VexRMOp("VBROADCASTSD", P_66, M_0F38, W0, 0x19, AVXOpAssertion.AVX1_256ONLY);
public static final VexRMOp VBROADCASTF128 = new VexRMOp("VBROADCASTF128", P_66, M_0F38, W0, 0x1A, AVXOpAssertion.AVX1_256ONLY);
public static final VexRMOp VPBROADCASTI128 = new VexRMOp("VPBROADCASTI128", P_66, M_0F38, W0, 0x5A, AVXOpAssertion.AVX2_256ONLY);
public static final VexRMOp VPBROADCASTB = new VexRMOp("VPBROADCASTB", P_66, M_0F38, W0, 0x78, AVXOpAssertion.AVX2);
public static final VexRMOp VPBROADCASTW = new VexRMOp("VPBROADCASTW", P_66, M_0F38, W0, 0x79, AVXOpAssertion.AVX2);
public static final VexRMOp VPBROADCASTD = new VexRMOp("VPBROADCASTD", P_66, M_0F38, W0, 0x58, AVXOpAssertion.AVX2);
public static final VexRMOp VPBROADCASTQ = new VexRMOp("VPBROADCASTQ", P_66, M_0F38, W0, 0x59, AVXOpAssertion.AVX2);
public static final VexRMOp VPMOVMSKB = new VexRMOp("VPMOVMSKB", P_66, M_0F, WIG, 0xD7, AVXOpAssertion.AVX1_2_CPU_XMM);
public static final VexRMOp VBROADCASTSD = new VexRMOp("VBROADCASTSD", P_66, M_0F38, W0, 0x19, VEXOpAssertion.AVX1_256ONLY);
public static final VexRMOp VBROADCASTF128 = new VexRMOp("VBROADCASTF128", P_66, M_0F38, W0, 0x1A, VEXOpAssertion.AVX1_256ONLY);
public static final VexRMOp VPBROADCASTI128 = new VexRMOp("VPBROADCASTI128", P_66, M_0F38, W0, 0x5A, VEXOpAssertion.AVX2_256ONLY);
public static final VexRMOp VPBROADCASTB = new VexRMOp("VPBROADCASTB", P_66, M_0F38, W0, 0x78, VEXOpAssertion.AVX2);
public static final VexRMOp VPBROADCASTW = new VexRMOp("VPBROADCASTW", P_66, M_0F38, W0, 0x79, VEXOpAssertion.AVX2);
public static final VexRMOp VPBROADCASTD = new VexRMOp("VPBROADCASTD", P_66, M_0F38, W0, 0x58, VEXOpAssertion.AVX2);
public static final VexRMOp VPBROADCASTQ = new VexRMOp("VPBROADCASTQ", P_66, M_0F38, W0, 0x59, VEXOpAssertion.AVX2);
public static final VexRMOp VPMOVMSKB = new VexRMOp("VPMOVMSKB", P_66, M_0F, WIG, 0xD7, VEXOpAssertion.AVX1_2_CPU_XMM);
public static final VexRMOp VPMOVSXBW = new VexRMOp("VPMOVSXBW", P_66, M_0F38, WIG, 0x20);
public static final VexRMOp VPMOVSXBD = new VexRMOp("VPMOVSXBD", P_66, M_0F38, WIG, 0x21);
public static final VexRMOp VPMOVSXBQ = new VexRMOp("VPMOVSXBQ", P_66, M_0F38, WIG, 0x22);
@ -1072,10 +1075,10 @@ public class AMD64Assembler extends AMD64BaseAssembler {
// @formatter:on
protected VexRMOp(String opcode, int pp, int mmmmm, int w, int op) {
this(opcode, pp, mmmmm, w, op, AVXOpAssertion.AVX1);
this(opcode, pp, mmmmm, w, op, VEXOpAssertion.AVX1);
}
protected VexRMOp(String opcode, int pp, int mmmmm, int w, int op, AVXOpAssertion assertion) {
protected VexRMOp(String opcode, int pp, int mmmmm, int w, int op, VEXOpAssertion assertion) {
super(opcode, pp, mmmmm, w, op, assertion);
}
@ -1103,17 +1106,17 @@ public class AMD64Assembler extends AMD64BaseAssembler {
public static final VexMoveOp VMOVUPD = new VexMoveOp("VMOVUPD", P_66, M_0F, WIG, 0x10, 0x11);
public static final VexMoveOp VMOVSS = new VexMoveOp("VMOVSS", P_F3, M_0F, WIG, 0x10, 0x11);
public static final VexMoveOp VMOVSD = new VexMoveOp("VMOVSD", P_F2, M_0F, WIG, 0x10, 0x11);
public static final VexMoveOp VMOVD = new VexMoveOp("VMOVD", P_66, M_0F, W0, 0x6E, 0x7E, AVXOpAssertion.XMM_CPU);
public static final VexMoveOp VMOVQ = new VexMoveOp("VMOVQ", P_66, M_0F, W1, 0x6E, 0x7E, AVXOpAssertion.XMM_CPU);
public static final VexMoveOp VMOVD = new VexMoveOp("VMOVD", P_66, M_0F, W0, 0x6E, 0x7E, VEXOpAssertion.XMM_CPU);
public static final VexMoveOp VMOVQ = new VexMoveOp("VMOVQ", P_66, M_0F, W1, 0x6E, 0x7E, VEXOpAssertion.XMM_CPU);
// @formatter:on
private final int opReverse;
private VexMoveOp(String opcode, int pp, int mmmmm, int w, int op, int opReverse) {
this(opcode, pp, mmmmm, w, op, opReverse, AVXOpAssertion.AVX1);
this(opcode, pp, mmmmm, w, op, opReverse, VEXOpAssertion.AVX1);
}
private VexMoveOp(String opcode, int pp, int mmmmm, int w, int op, int opReverse, AVXOpAssertion assertion) {
private VexMoveOp(String opcode, int pp, int mmmmm, int w, int op, int opReverse, VEXOpAssertion assertion) {
super(opcode, pp, mmmmm, w, op, assertion);
this.opReverse = opReverse;
}
@ -1142,13 +1145,13 @@ public class AMD64Assembler extends AMD64BaseAssembler {
*/
public static final class VexRMIOp extends VexOp implements VexRRIOp {
// @formatter:off
public static final VexRMIOp VPERMQ = new VexRMIOp("VPERMQ", P_66, M_0F3A, W1, 0x00, AVXOpAssertion.AVX2_256ONLY);
public static final VexRMIOp VPSHUFLW = new VexRMIOp("VPSHUFLW", P_F2, M_0F, WIG, 0x70, AVXOpAssertion.AVX1_2);
public static final VexRMIOp VPSHUFHW = new VexRMIOp("VPSHUFHW", P_F3, M_0F, WIG, 0x70, AVXOpAssertion.AVX1_2);
public static final VexRMIOp VPSHUFD = new VexRMIOp("VPSHUFD", P_66, M_0F, WIG, 0x70, AVXOpAssertion.AVX1_2);
public static final VexRMIOp VPERMQ = new VexRMIOp("VPERMQ", P_66, M_0F3A, W1, 0x00, VEXOpAssertion.AVX2_256ONLY);
public static final VexRMIOp VPSHUFLW = new VexRMIOp("VPSHUFLW", P_F2, M_0F, WIG, 0x70, VEXOpAssertion.AVX1_2);
public static final VexRMIOp VPSHUFHW = new VexRMIOp("VPSHUFHW", P_F3, M_0F, WIG, 0x70, VEXOpAssertion.AVX1_2);
public static final VexRMIOp VPSHUFD = new VexRMIOp("VPSHUFD", P_66, M_0F, WIG, 0x70, VEXOpAssertion.AVX1_2);
// @formatter:on
private VexRMIOp(String opcode, int pp, int mmmmm, int w, int op, AVXOpAssertion assertion) {
private VexRMIOp(String opcode, int pp, int mmmmm, int w, int op, VEXOpAssertion assertion) {
super(opcode, pp, mmmmm, w, op, assertion);
}
@ -1175,15 +1178,15 @@ public class AMD64Assembler extends AMD64BaseAssembler {
*/
public static final class VexMRIOp extends VexOp implements VexRRIOp {
// @formatter:off
public static final VexMRIOp VEXTRACTF128 = new VexMRIOp("VEXTRACTF128", P_66, M_0F3A, W0, 0x19, AVXOpAssertion.AVX1_256ONLY);
public static final VexMRIOp VEXTRACTI128 = new VexMRIOp("VEXTRACTI128", P_66, M_0F3A, W0, 0x39, AVXOpAssertion.AVX2_256ONLY);
public static final VexMRIOp VPEXTRB = new VexMRIOp("VPEXTRB", P_66, M_0F3A, W0, 0x14, AVXOpAssertion.XMM_CPU);
public static final VexMRIOp VPEXTRW = new VexMRIOp("VPEXTRW", P_66, M_0F3A, W0, 0x15, AVXOpAssertion.XMM_CPU);
public static final VexMRIOp VPEXTRD = new VexMRIOp("VPEXTRD", P_66, M_0F3A, W0, 0x16, AVXOpAssertion.XMM_CPU);
public static final VexMRIOp VPEXTRQ = new VexMRIOp("VPEXTRQ", P_66, M_0F3A, W1, 0x16, AVXOpAssertion.XMM_CPU);
public static final VexMRIOp VEXTRACTF128 = new VexMRIOp("VEXTRACTF128", P_66, M_0F3A, W0, 0x19, VEXOpAssertion.AVX1_256ONLY);
public static final VexMRIOp VEXTRACTI128 = new VexMRIOp("VEXTRACTI128", P_66, M_0F3A, W0, 0x39, VEXOpAssertion.AVX2_256ONLY);
public static final VexMRIOp VPEXTRB = new VexMRIOp("VPEXTRB", P_66, M_0F3A, W0, 0x14, VEXOpAssertion.XMM_CPU);
public static final VexMRIOp VPEXTRW = new VexMRIOp("VPEXTRW", P_66, M_0F3A, W0, 0x15, VEXOpAssertion.XMM_CPU);
public static final VexMRIOp VPEXTRD = new VexMRIOp("VPEXTRD", P_66, M_0F3A, W0, 0x16, VEXOpAssertion.XMM_CPU);
public static final VexMRIOp VPEXTRQ = new VexMRIOp("VPEXTRQ", P_66, M_0F3A, W1, 0x16, VEXOpAssertion.XMM_CPU);
// @formatter:on
private VexMRIOp(String opcode, int pp, int mmmmm, int w, int op, AVXOpAssertion assertion) {
private VexMRIOp(String opcode, int pp, int mmmmm, int w, int op, VEXOpAssertion assertion) {
super(opcode, pp, mmmmm, w, op, assertion);
}
@ -1210,12 +1213,12 @@ public class AMD64Assembler extends AMD64BaseAssembler {
*/
public static class VexRVMROp extends VexOp {
// @formatter:off
public static final VexRVMROp VPBLENDVB = new VexRVMROp("VPBLENDVB", P_66, M_0F3A, W0, 0x4C, AVXOpAssertion.AVX1_2);
public static final VexRVMROp VPBLENDVPS = new VexRVMROp("VPBLENDVPS", P_66, M_0F3A, W0, 0x4A, AVXOpAssertion.AVX1);
public static final VexRVMROp VPBLENDVPD = new VexRVMROp("VPBLENDVPD", P_66, M_0F3A, W0, 0x4B, AVXOpAssertion.AVX1);
public static final VexRVMROp VPBLENDVB = new VexRVMROp("VPBLENDVB", P_66, M_0F3A, W0, 0x4C, VEXOpAssertion.AVX1_2);
public static final VexRVMROp VPBLENDVPS = new VexRVMROp("VPBLENDVPS", P_66, M_0F3A, W0, 0x4A, VEXOpAssertion.AVX1);
public static final VexRVMROp VPBLENDVPD = new VexRVMROp("VPBLENDVPD", P_66, M_0F3A, W0, 0x4B, VEXOpAssertion.AVX1);
// @formatter:on
protected VexRVMROp(String opcode, int pp, int mmmmm, int w, int op, AVXOpAssertion assertion) {
protected VexRVMROp(String opcode, int pp, int mmmmm, int w, int op, VEXOpAssertion assertion) {
super(opcode, pp, mmmmm, w, op, assertion);
}
@ -1275,43 +1278,43 @@ public class AMD64Assembler extends AMD64BaseAssembler {
public static final VexRVMOp VMAXSD = new VexRVMOp("VMAXSD", P_F2, M_0F, WIG, 0x5F);
public static final VexRVMOp VADDSUBPS = new VexRVMOp("VADDSUBPS", P_F2, M_0F, WIG, 0xD0);
public static final VexRVMOp VADDSUBPD = new VexRVMOp("VADDSUBPD", P_66, M_0F, WIG, 0xD0);
public static final VexRVMOp VPAND = new VexRVMOp("VPAND", P_66, M_0F, WIG, 0xDB, AVXOpAssertion.AVX1_2);
public static final VexRVMOp VPOR = new VexRVMOp("VPOR", P_66, M_0F, WIG, 0xEB, AVXOpAssertion.AVX1_2);
public static final VexRVMOp VPXOR = new VexRVMOp("VPXOR", P_66, M_0F, WIG, 0xEF, AVXOpAssertion.AVX1_2);
public static final VexRVMOp VPADDB = new VexRVMOp("VPADDB", P_66, M_0F, WIG, 0xFC, AVXOpAssertion.AVX1_2);
public static final VexRVMOp VPADDW = new VexRVMOp("VPADDW", P_66, M_0F, WIG, 0xFD, AVXOpAssertion.AVX1_2);
public static final VexRVMOp VPADDD = new VexRVMOp("VPADDD", P_66, M_0F, WIG, 0xFE, AVXOpAssertion.AVX1_2);
public static final VexRVMOp VPADDQ = new VexRVMOp("VPADDQ", P_66, M_0F, WIG, 0xD4, AVXOpAssertion.AVX1_2);
public static final VexRVMOp VPMULHUW = new VexRVMOp("VPMULHUW", P_66, M_0F, WIG, 0xE4, AVXOpAssertion.AVX1_2);
public static final VexRVMOp VPMULHW = new VexRVMOp("VPMULHW", P_66, M_0F, WIG, 0xE5, AVXOpAssertion.AVX1_2);
public static final VexRVMOp VPMULLW = new VexRVMOp("VPMULLW", P_66, M_0F, WIG, 0xD5, AVXOpAssertion.AVX1_2);
public static final VexRVMOp VPMULLD = new VexRVMOp("VPMULLD", P_66, M_0F38, WIG, 0x40, AVXOpAssertion.AVX1_2);
public static final VexRVMOp VPSUBB = new VexRVMOp("VPSUBB", P_66, M_0F, WIG, 0xF8, AVXOpAssertion.AVX1_2);
public static final VexRVMOp VPSUBW = new VexRVMOp("VPSUBW", P_66, M_0F, WIG, 0xF9, AVXOpAssertion.AVX1_2);
public static final VexRVMOp VPSUBD = new VexRVMOp("VPSUBD", P_66, M_0F, WIG, 0xFA, AVXOpAssertion.AVX1_2);
public static final VexRVMOp VPSUBQ = new VexRVMOp("VPSUBQ", P_66, M_0F, WIG, 0xFB, AVXOpAssertion.AVX1_2);
public static final VexRVMOp VPSHUFB = new VexRVMOp("VPSHUFB", P_66, M_0F38, WIG, 0x00, AVXOpAssertion.AVX1_2);
public static final VexRVMOp VPAND = new VexRVMOp("VPAND", P_66, M_0F, WIG, 0xDB, VEXOpAssertion.AVX1_2);
public static final VexRVMOp VPOR = new VexRVMOp("VPOR", P_66, M_0F, WIG, 0xEB, VEXOpAssertion.AVX1_2);
public static final VexRVMOp VPXOR = new VexRVMOp("VPXOR", P_66, M_0F, WIG, 0xEF, VEXOpAssertion.AVX1_2);
public static final VexRVMOp VPADDB = new VexRVMOp("VPADDB", P_66, M_0F, WIG, 0xFC, VEXOpAssertion.AVX1_2);
public static final VexRVMOp VPADDW = new VexRVMOp("VPADDW", P_66, M_0F, WIG, 0xFD, VEXOpAssertion.AVX1_2);
public static final VexRVMOp VPADDD = new VexRVMOp("VPADDD", P_66, M_0F, WIG, 0xFE, VEXOpAssertion.AVX1_2);
public static final VexRVMOp VPADDQ = new VexRVMOp("VPADDQ", P_66, M_0F, WIG, 0xD4, VEXOpAssertion.AVX1_2);
public static final VexRVMOp VPMULHUW = new VexRVMOp("VPMULHUW", P_66, M_0F, WIG, 0xE4, VEXOpAssertion.AVX1_2);
public static final VexRVMOp VPMULHW = new VexRVMOp("VPMULHW", P_66, M_0F, WIG, 0xE5, VEXOpAssertion.AVX1_2);
public static final VexRVMOp VPMULLW = new VexRVMOp("VPMULLW", P_66, M_0F, WIG, 0xD5, VEXOpAssertion.AVX1_2);
public static final VexRVMOp VPMULLD = new VexRVMOp("VPMULLD", P_66, M_0F38, WIG, 0x40, VEXOpAssertion.AVX1_2);
public static final VexRVMOp VPSUBB = new VexRVMOp("VPSUBB", P_66, M_0F, WIG, 0xF8, VEXOpAssertion.AVX1_2);
public static final VexRVMOp VPSUBW = new VexRVMOp("VPSUBW", P_66, M_0F, WIG, 0xF9, VEXOpAssertion.AVX1_2);
public static final VexRVMOp VPSUBD = new VexRVMOp("VPSUBD", P_66, M_0F, WIG, 0xFA, VEXOpAssertion.AVX1_2);
public static final VexRVMOp VPSUBQ = new VexRVMOp("VPSUBQ", P_66, M_0F, WIG, 0xFB, VEXOpAssertion.AVX1_2);
public static final VexRVMOp VPSHUFB = new VexRVMOp("VPSHUFB", P_66, M_0F38, WIG, 0x00, VEXOpAssertion.AVX1_2);
public static final VexRVMOp VCVTSD2SS = new VexRVMOp("VCVTSD2SS", P_F2, M_0F, WIG, 0x5A);
public static final VexRVMOp VCVTSS2SD = new VexRVMOp("VCVTSS2SD", P_F3, M_0F, WIG, 0x5A);
public static final VexRVMOp VCVTSI2SD = new VexRVMOp("VCVTSI2SD", P_F2, M_0F, W0, 0x2A, AVXOpAssertion.XMM_XMM_CPU);
public static final VexRVMOp VCVTSQ2SD = new VexRVMOp("VCVTSQ2SD", P_F2, M_0F, W1, 0x2A, AVXOpAssertion.XMM_XMM_CPU);
public static final VexRVMOp VCVTSI2SS = new VexRVMOp("VCVTSI2SS", P_F3, M_0F, W0, 0x2A, AVXOpAssertion.XMM_XMM_CPU);
public static final VexRVMOp VCVTSQ2SS = new VexRVMOp("VCVTSQ2SS", P_F3, M_0F, W1, 0x2A, AVXOpAssertion.XMM_XMM_CPU);
public static final VexRVMOp VPCMPEQB = new VexRVMOp("VPCMPEQB", P_66, M_0F, WIG, 0x74, AVXOpAssertion.AVX1_2);
public static final VexRVMOp VPCMPEQW = new VexRVMOp("VPCMPEQW", P_66, M_0F, WIG, 0x75, AVXOpAssertion.AVX1_2);
public static final VexRVMOp VPCMPEQD = new VexRVMOp("VPCMPEQD", P_66, M_0F, WIG, 0x76, AVXOpAssertion.AVX1_2);
public static final VexRVMOp VPCMPEQQ = new VexRVMOp("VPCMPEQQ", P_66, M_0F38, WIG, 0x29, AVXOpAssertion.AVX1_2);
public static final VexRVMOp VPCMPGTB = new VexRVMOp("VPCMPGTB", P_66, M_0F, WIG, 0x64, AVXOpAssertion.AVX1_2);
public static final VexRVMOp VPCMPGTW = new VexRVMOp("VPCMPGTW", P_66, M_0F, WIG, 0x65, AVXOpAssertion.AVX1_2);
public static final VexRVMOp VPCMPGTD = new VexRVMOp("VPCMPGTD", P_66, M_0F, WIG, 0x66, AVXOpAssertion.AVX1_2);
public static final VexRVMOp VPCMPGTQ = new VexRVMOp("VPCMPGTQ", P_66, M_0F38, WIG, 0x37, AVXOpAssertion.AVX1_2);
public static final VexRVMOp VCVTSI2SD = new VexRVMOp("VCVTSI2SD", P_F2, M_0F, W0, 0x2A, VEXOpAssertion.XMM_XMM_CPU);
public static final VexRVMOp VCVTSQ2SD = new VexRVMOp("VCVTSQ2SD", P_F2, M_0F, W1, 0x2A, VEXOpAssertion.XMM_XMM_CPU);
public static final VexRVMOp VCVTSI2SS = new VexRVMOp("VCVTSI2SS", P_F3, M_0F, W0, 0x2A, VEXOpAssertion.XMM_XMM_CPU);
public static final VexRVMOp VCVTSQ2SS = new VexRVMOp("VCVTSQ2SS", P_F3, M_0F, W1, 0x2A, VEXOpAssertion.XMM_XMM_CPU);
public static final VexRVMOp VPCMPEQB = new VexRVMOp("VPCMPEQB", P_66, M_0F, WIG, 0x74, VEXOpAssertion.AVX1_2);
public static final VexRVMOp VPCMPEQW = new VexRVMOp("VPCMPEQW", P_66, M_0F, WIG, 0x75, VEXOpAssertion.AVX1_2);
public static final VexRVMOp VPCMPEQD = new VexRVMOp("VPCMPEQD", P_66, M_0F, WIG, 0x76, VEXOpAssertion.AVX1_2);
public static final VexRVMOp VPCMPEQQ = new VexRVMOp("VPCMPEQQ", P_66, M_0F38, WIG, 0x29, VEXOpAssertion.AVX1_2);
public static final VexRVMOp VPCMPGTB = new VexRVMOp("VPCMPGTB", P_66, M_0F, WIG, 0x64, VEXOpAssertion.AVX1_2);
public static final VexRVMOp VPCMPGTW = new VexRVMOp("VPCMPGTW", P_66, M_0F, WIG, 0x65, VEXOpAssertion.AVX1_2);
public static final VexRVMOp VPCMPGTD = new VexRVMOp("VPCMPGTD", P_66, M_0F, WIG, 0x66, VEXOpAssertion.AVX1_2);
public static final VexRVMOp VPCMPGTQ = new VexRVMOp("VPCMPGTQ", P_66, M_0F38, WIG, 0x37, VEXOpAssertion.AVX1_2);
// @formatter:on
private VexRVMOp(String opcode, int pp, int mmmmm, int w, int op) {
this(opcode, pp, mmmmm, w, op, AVXOpAssertion.AVX1);
this(opcode, pp, mmmmm, w, op, VEXOpAssertion.AVX1);
}
protected VexRVMOp(String opcode, int pp, int mmmmm, int w, int op, AVXOpAssertion assertion) {
protected VexRVMOp(String opcode, int pp, int mmmmm, int w, int op, VEXOpAssertion assertion) {
super(opcode, pp, mmmmm, w, op, assertion);
}
@ -1330,6 +1333,65 @@ public class AMD64Assembler extends AMD64BaseAssembler {
}
}
public static final class VexGeneralPurposeRVMOp extends VexOp {
// @formatter:off
public static final VexGeneralPurposeRVMOp ANDN = new VexGeneralPurposeRVMOp("ANDN", P_, M_0F38, WIG, 0xF2, VEXOpAssertion.BMI1);
public static final VexGeneralPurposeRVMOp MULX = new VexGeneralPurposeRVMOp("MULX", P_F2, M_0F38, WIG, 0xF6, VEXOpAssertion.BMI2);
public static final VexGeneralPurposeRVMOp PDEP = new VexGeneralPurposeRVMOp("PDEP", P_F2, M_0F38, WIG, 0xF5, VEXOpAssertion.BMI2);
public static final VexGeneralPurposeRVMOp PEXT = new VexGeneralPurposeRVMOp("PEXT", P_F3, M_0F38, WIG, 0xF5, VEXOpAssertion.BMI2);
// @formatter:on
private VexGeneralPurposeRVMOp(String opcode, int pp, int mmmmm, int w, int op, VEXOpAssertion assertion) {
super(opcode, pp, mmmmm, w, op, assertion);
}
public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src1, Register src2) {
assert assertion.check((AMD64) asm.target.arch, LZ, dst, src1, src2, null);
assert size == AVXSize.DWORD || size == AVXSize.QWORD;
asm.vexPrefix(dst, src1, src2, size, pp, mmmmm, size == AVXSize.DWORD ? W0 : W1);
asm.emitByte(op);
asm.emitModRM(dst, src2);
}
public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src1, AMD64Address src2) {
assert assertion.check((AMD64) asm.target.arch, LZ, dst, src1, null, null);
assert size == AVXSize.DWORD || size == AVXSize.QWORD;
asm.vexPrefix(dst, src1, src2, size, pp, mmmmm, size == AVXSize.DWORD ? W0 : W1);
asm.emitByte(op);
asm.emitOperandHelper(dst, src2, 0);
}
}
public static final class VexGeneralPurposeRMVOp extends VexOp {
// @formatter:off
public static final VexGeneralPurposeRMVOp BEXTR = new VexGeneralPurposeRMVOp("BEXTR", P_, M_0F38, WIG, 0xF7, VEXOpAssertion.BMI1);
public static final VexGeneralPurposeRMVOp BZHI = new VexGeneralPurposeRMVOp("BZHI", P_, M_0F38, WIG, 0xF5, VEXOpAssertion.BMI2);
public static final VexGeneralPurposeRMVOp SARX = new VexGeneralPurposeRMVOp("SARX", P_F3, M_0F38, WIG, 0xF7, VEXOpAssertion.BMI2);
public static final VexGeneralPurposeRMVOp SHRX = new VexGeneralPurposeRMVOp("SHRX", P_F2, M_0F38, WIG, 0xF7, VEXOpAssertion.BMI2);
public static final VexGeneralPurposeRMVOp SHLX = new VexGeneralPurposeRMVOp("SHLX", P_66, M_0F38, WIG, 0xF7, VEXOpAssertion.BMI2);
// @formatter:on
private VexGeneralPurposeRMVOp(String opcode, int pp, int mmmmm, int w, int op, VEXOpAssertion assertion) {
super(opcode, pp, mmmmm, w, op, assertion);
}
public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src1, Register src2) {
assert assertion.check((AMD64) asm.target.arch, LZ, dst, src2, src1, null);
assert size == AVXSize.DWORD || size == AVXSize.QWORD;
asm.vexPrefix(dst, src2, src1, size, pp, mmmmm, size == AVXSize.DWORD ? W0 : W1);
asm.emitByte(op);
asm.emitModRM(dst, src1);
}
public void emit(AMD64Assembler asm, AVXSize size, Register dst, AMD64Address src1, Register src2) {
assert assertion.check((AMD64) asm.target.arch, LZ, dst, src2, null, null);
assert size == AVXSize.DWORD || size == AVXSize.QWORD;
asm.vexPrefix(dst, src2, src1, size, pp, mmmmm, size == AVXSize.DWORD ? W0 : W1);
asm.emitByte(op);
asm.emitOperandHelper(dst, src1, 0);
}
}
/**
* VEX-encoded shift instructions with an operand order of either RVM or VMI.
*/
@ -1349,7 +1411,7 @@ public class AMD64Assembler extends AMD64BaseAssembler {
private final int r;
private VexShiftOp(String opcode, int pp, int mmmmm, int w, int op, int immOp, int r) {
super(opcode, pp, mmmmm, w, op, AVXOpAssertion.AVX1_2);
super(opcode, pp, mmmmm, w, op, VEXOpAssertion.AVX1_2);
this.immOp = immOp;
this.r = r;
}
@ -1368,17 +1430,17 @@ public class AMD64Assembler extends AMD64BaseAssembler {
// @formatter:off
public static final VexMaskMoveOp VMASKMOVPS = new VexMaskMoveOp("VMASKMOVPS", P_66, M_0F38, W0, 0x2C, 0x2E);
public static final VexMaskMoveOp VMASKMOVPD = new VexMaskMoveOp("VMASKMOVPD", P_66, M_0F38, W0, 0x2D, 0x2F);
public static final VexMaskMoveOp VPMASKMOVD = new VexMaskMoveOp("VPMASKMOVD", P_66, M_0F38, W0, 0x8C, 0x8E, AVXOpAssertion.AVX2);
public static final VexMaskMoveOp VPMASKMOVQ = new VexMaskMoveOp("VPMASKMOVQ", P_66, M_0F38, W1, 0x8C, 0x8E, AVXOpAssertion.AVX2);
public static final VexMaskMoveOp VPMASKMOVD = new VexMaskMoveOp("VPMASKMOVD", P_66, M_0F38, W0, 0x8C, 0x8E, VEXOpAssertion.AVX2);
public static final VexMaskMoveOp VPMASKMOVQ = new VexMaskMoveOp("VPMASKMOVQ", P_66, M_0F38, W1, 0x8C, 0x8E, VEXOpAssertion.AVX2);
// @formatter:on
private final int opReverse;
private VexMaskMoveOp(String opcode, int pp, int mmmmm, int w, int op, int opReverse) {
this(opcode, pp, mmmmm, w, op, opReverse, AVXOpAssertion.AVX1);
this(opcode, pp, mmmmm, w, op, opReverse, VEXOpAssertion.AVX1);
}
private VexMaskMoveOp(String opcode, int pp, int mmmmm, int w, int op, int opReverse, AVXOpAssertion assertion) {
private VexMaskMoveOp(String opcode, int pp, int mmmmm, int w, int op, int opReverse, VEXOpAssertion assertion) {
super(opcode, pp, mmmmm, w, op, assertion);
this.opReverse = opReverse;
}
@ -1405,15 +1467,15 @@ public class AMD64Assembler extends AMD64BaseAssembler {
// @formatter:off
public static final VexRVMIOp VSHUFPS = new VexRVMIOp("VSHUFPS", P_, M_0F, WIG, 0xC6);
public static final VexRVMIOp VSHUFPD = new VexRVMIOp("VSHUFPD", P_66, M_0F, WIG, 0xC6);
public static final VexRVMIOp VINSERTF128 = new VexRVMIOp("VINSERTF128", P_66, M_0F3A, W0, 0x18, AVXOpAssertion.AVX1_256ONLY);
public static final VexRVMIOp VINSERTI128 = new VexRVMIOp("VINSERTI128", P_66, M_0F3A, W0, 0x38, AVXOpAssertion.AVX2_256ONLY);
public static final VexRVMIOp VINSERTF128 = new VexRVMIOp("VINSERTF128", P_66, M_0F3A, W0, 0x18, VEXOpAssertion.AVX1_256ONLY);
public static final VexRVMIOp VINSERTI128 = new VexRVMIOp("VINSERTI128", P_66, M_0F3A, W0, 0x38, VEXOpAssertion.AVX2_256ONLY);
// @formatter:on
private VexRVMIOp(String opcode, int pp, int mmmmm, int w, int op) {
this(opcode, pp, mmmmm, w, op, AVXOpAssertion.AVX1);
this(opcode, pp, mmmmm, w, op, VEXOpAssertion.AVX1);
}
private VexRVMIOp(String opcode, int pp, int mmmmm, int w, int op, AVXOpAssertion assertion) {
private VexRVMIOp(String opcode, int pp, int mmmmm, int w, int op, VEXOpAssertion assertion) {
super(opcode, pp, mmmmm, w, op, assertion);
}
@ -1528,7 +1590,7 @@ public class AMD64Assembler extends AMD64BaseAssembler {
}
private VexFloatCompareOp(String opcode, int pp, int mmmmm, int w, int op) {
super(opcode, pp, mmmmm, w, op, AVXOpAssertion.AVX1);
super(opcode, pp, mmmmm, w, op, VEXOpAssertion.AVX1);
}
public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src1, Register src2, Predicate p) {

View File

@ -37,7 +37,7 @@ import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.EVEXPrefixConfig
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.EVEXPrefixConfig.Z1;
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.L128;
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.L256;
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.LIG;
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.LZ;
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.M_0F;
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.M_0F38;
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.M_0F3A;
@ -748,7 +748,7 @@ public abstract class AMD64BaseAssembler extends Assembler {
public static final class VEXPrefixConfig {
public static final int L128 = 0;
public static final int L256 = 1;
public static final int LIG = 0;
public static final int LZ = 0;
public static final int W0 = 0;
public static final int W1 = 1;
@ -849,10 +849,10 @@ public abstract class AMD64BaseAssembler extends Assembler {
protected final void emitVEX(int l, int pp, int mmmmm, int w, int rxb, int vvvv) {
assert ((AMD64) target.arch).getFeatures().contains(CPUFeature.AVX) : "emitting VEX prefix on a CPU without AVX support";
assert l == L128 || l == L256 || l == LIG : "invalid value for VEX.L";
assert l == L128 || l == L256 : "invalid value for VEX.L";
assert pp == P_ || pp == P_66 || pp == P_F3 || pp == P_F2 : "invalid value for VEX.pp";
assert mmmmm == M_0F || mmmmm == M_0F38 || mmmmm == M_0F3A : "invalid value for VEX.m-mmmm";
assert w == W0 || w == W1 || w == WIG : "invalid value for VEX.W";
assert w == W0 || w == W1 : "invalid value for VEX.W";
assert (rxb & 0x07) == rxb : "invalid value for VEX.RXB";
assert (vvvv & 0x0F) == vvvv : "invalid value for VEX.vvvv";
@ -887,7 +887,7 @@ public abstract class AMD64BaseAssembler extends Assembler {
}
}
private static int getLFlag(AVXSize size) {
public static int getLFlag(AVXSize size) {
switch (size) {
case XMM:
return L128;
@ -896,7 +896,7 @@ public abstract class AMD64BaseAssembler extends Assembler {
case ZMM:
return L512;
default:
return LIG;
return LZ;
}
}
@ -910,6 +910,7 @@ public abstract class AMD64BaseAssembler extends Assembler {
protected static final class EVEXPrefixConfig {
public static final int L512 = 2;
public static final int LIG = 0;
public static final int Z0 = 0x0;
public static final int Z1 = 0x1;
@ -1013,10 +1014,10 @@ public abstract class AMD64BaseAssembler extends Assembler {
private void emitEVEX(int l, int pp, int mm, int w, int rxb, int reg, int vvvvv, int z, int b, int aaa) {
assert ((AMD64) target.arch).getFeatures().contains(CPUFeature.AVX512F) : "emitting EVEX prefix on a CPU without AVX512 support";
assert l == L128 || l == L256 || l == L512 || l == LIG : "invalid value for EVEX.L'L";
assert l == L128 || l == L256 || l == L512 : "invalid value for EVEX.L'L";
assert pp == P_ || pp == P_66 || pp == P_F3 || pp == P_F2 : "invalid value for EVEX.pp";
assert mm == M_0F || mm == M_0F38 || mm == M_0F3A : "invalid value for EVEX.mm";
assert w == W0 || w == W1 || w == WIG : "invalid value for EVEX.W";
assert w == W0 || w == W1 : "invalid value for EVEX.W";
assert (rxb & 0x07) == rxb : "invalid value for EVEX.RXB";
assert (reg & 0x1F) == reg : "invalid value for EVEX.R'";

View File

@ -41,6 +41,7 @@ import java.util.concurrent.TimeUnit;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.graalvm.compiler.api.replacements.MethodSubstitution;
import org.graalvm.compiler.api.replacements.Snippet;
import org.graalvm.compiler.api.replacements.Snippet.ConstantParameter;
import org.graalvm.compiler.api.replacements.Snippet.NonNullParameter;
@ -279,7 +280,8 @@ public class CheckGraalInvariants extends GraalCompilerTest {
executor.execute(() -> {
try (DebugContext debug = DebugContext.create(options, DebugHandlersFactory.LOADER)) {
ResolvedJavaMethod method = metaAccess.lookupJavaMethod(m);
StructuredGraph graph = new StructuredGraph.Builder(options, debug).method(method).build();
boolean isSubstitution = method.getAnnotation(Snippet.class) != null || method.getAnnotation(MethodSubstitution.class) != null;
StructuredGraph graph = new StructuredGraph.Builder(options, debug).method(method).setIsSubstitution(isSubstitution).build();
try (DebugCloseable s = debug.disableIntercept(); DebugContext.Scope ds = debug.scope("CheckingGraph", graph, method)) {
checkMethod(method);
graphBuilderSuite.apply(graph, context);

View File

@ -0,0 +1,164 @@
/*
* Copyright (c) 2018, 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.
*/
package org.graalvm.compiler.core.test;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import org.graalvm.compiler.java.GraphBuilderPhase;
import org.graalvm.compiler.nodes.DeoptimizeNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
import org.graalvm.compiler.nodes.java.NewInstanceNode;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.phases.OptimisticOptimizations;
import org.junit.Assert;
import org.junit.Test;
import jdk.vm.ci.meta.ResolvedJavaMethod;
public class NewInstanceTest extends GraalCompilerTest {
public static class Template {
public Object o = new CCCC();
}
/**
* 1. Concrete class, should produce normal {@link NewInstanceNode}
*/
public static class CCCC {
}
/**
* 2. The test will replace references to {@link CCCC} in the {@link Template} to {@link AAAA}
*/
public abstract static class AAAA {
}
/**
* 3. The test will replace references to {@link CCCC} in the {@link Template} to {@link IIII}
*/
public interface IIII {
}
private StructuredGraph parseAndProcess(Class<?> cl) {
Constructor<?>[] constructors = cl.getConstructors();
Assert.assertTrue(constructors.length == 1);
final ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(constructors[0]);
OptionValues options = getInitialOptions();
StructuredGraph graph = new StructuredGraph.Builder(options, getDebugContext(options, null, javaMethod), AllowAssumptions.YES).method(javaMethod).build();
GraphBuilderConfiguration conf = GraphBuilderConfiguration.getSnippetDefault(getDefaultGraphBuilderPlugins()).withUnresolvedIsError(false);
new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), getProviders().getConstantReflection(), getProviders().getConstantFieldProvider(), conf,
OptimisticOptimizations.ALL, null).apply(graph);
return graph;
}
private void checkGraph(Class<?> cl, int newInstanceNodeCount, int deoptimizeNodeCount) {
StructuredGraph graph = parseAndProcess(cl);
Assert.assertEquals(newInstanceNodeCount, graph.getNodes().filter(NewInstanceNode.class).count());
Assert.assertEquals(deoptimizeNodeCount, graph.getNodes().filter(DeoptimizeNode.class).count());
}
/**
* Use a custom class loader to generate classes, substitute class names at the allocation site.
*/
@Test
public void test1() throws ClassNotFoundException {
checkGraph(Template.class, 1, 0);
ClassTemplateLoader loader1 = new ClassTemplateLoader("CCCC", "AAAA");
checkGraph(loader1.findClass("Template"), 0, 1);
ClassTemplateLoader loader2 = new ClassTemplateLoader("CCCC", "IIII");
checkGraph(loader2.findClass("Template"), 0, 1);
}
private static class ClassTemplateLoader extends ClassLoader {
private final String find;
private final String replace;
ClassTemplateLoader(String find, String replace) {
assert find.length() == replace.length();
this.find = find;
this.replace = replace;
}
@Override
protected Class<?> findClass(final String name) throws ClassNotFoundException {
// copy classfile to byte array
byte[] classData = null;
try {
InputStream is = NewInstanceTest.class.getResourceAsStream("NewInstanceTest$" + name + ".class");
assert is != null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int size;
while ((size = is.read(buf, 0, buf.length)) != -1) {
baos.write(buf, 0, size);
}
baos.flush();
classData = baos.toByteArray();
} catch (IOException e) {
Assert.fail("can't access class: " + name);
}
// replace all occurrences of the template in classfile
int index = -1;
while ((index = indexOfTemplate(classData, index + 1, find)) != -1) {
replaceTemplate(classData, index, replace);
}
Class<?> c = defineClass(null, classData, 0, classData.length);
return c;
}
private static int indexOfTemplate(byte[] b, int index, String find) {
for (int i = index; i < b.length; i++) {
boolean match = true;
for (int j = i; j < i + find.length(); j++) {
if (b[j] != (byte) find.charAt(j - i)) {
match = false;
break;
}
}
if (match) {
return i;
}
}
return -1;
}
private static void replaceTemplate(byte[] b, int index, String replace) {
for (int i = index; i < index + replace.length(); i++) {
b[i] = (byte) replace.charAt(i - index);
}
}
}
}

View File

@ -27,6 +27,7 @@ package org.graalvm.compiler.core.test.ea;
import java.util.List;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.iterators.NodeIterable;
import org.graalvm.compiler.loop.DefaultLoopPolicies;
import org.graalvm.compiler.loop.phases.LoopFullUnrollPhase;
import org.graalvm.compiler.loop.phases.LoopPeelingPhase;
@ -492,4 +493,21 @@ public class EscapeAnalysisTest extends EATestBase {
public void testDeoptMonitor() {
test("testDeoptMonitorSnippet", new Object(), 0);
}
@Test
public void testInterfaceArrayAssignment() {
prepareGraph("testInterfaceArrayAssignmentSnippet", false);
NodeIterable<ReturnNode> returns = graph.getNodes().filter(ReturnNode.class);
assertTrue(returns.count() == 1);
assertFalse(returns.first().result().isConstant());
}
private interface TestInterface {
}
public static boolean testInterfaceArrayAssignmentSnippet() {
Object[] array = new TestInterface[1];
array[0] = new Object();
return array[0] == null;
}
}

View File

@ -41,6 +41,7 @@ import java.io.IOException;
import java.io.PrintStream;
import java.util.Map;
import org.graalvm.compiler.debug.DebugCloseable;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.DiagnosticsOutputDirectory;
import org.graalvm.compiler.debug.PathUtilities;
@ -181,15 +182,64 @@ public abstract class CompilationWrapper<T> {
actionKey = CompilationFailureAction;
causeType = "failure";
}
ExceptionAction action = lookupAction(initialOptions, actionKey, cause);
synchronized (CompilationFailureAction) {
// Serialize all compilation failure handling.
// This prevents retry compilation storms and interleaving
// of compilation exception messages.
// It also allows for reliable testing of CompilationWrapper
// by avoiding a race whereby retry compilation output from a
// forced crash (i.e., use of GraalCompilerOptions.CrashAt)
// is truncated.
action = adjustAction(initialOptions, actionKey, action);
ExceptionAction action = lookupAction(initialOptions, actionKey, cause);
if (action == ExceptionAction.Silent) {
return handleException(cause);
}
action = adjustAction(initialOptions, actionKey, action);
if (action == ExceptionAction.Print) {
if (action == ExceptionAction.Silent) {
return handleException(cause);
}
if (action == ExceptionAction.Print) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (PrintStream ps = new PrintStream(baos)) {
ps.printf("%s: Compilation of %s failed: ", Thread.currentThread(), this);
cause.printStackTrace(ps);
ps.printf("To disable compilation %s notifications, set %s to %s (e.g., -Dgraal.%s=%s).%n",
causeType,
actionKey.getName(), ExceptionAction.Silent,
actionKey.getName(), ExceptionAction.Silent);
ps.printf("To capture more information for diagnosing or reporting a compilation %s, " +
"set %s to %s or %s (e.g., -Dgraal.%s=%s).%n",
causeType,
actionKey.getName(), ExceptionAction.Diagnose,
ExceptionAction.ExitVM,
actionKey.getName(), ExceptionAction.Diagnose);
}
TTY.print(baos.toString());
return handleException(cause);
}
// action is Diagnose or ExitVM
if (Dump.hasBeenSet(initialOptions)) {
// If dumping is explicitly enabled, Graal is being debugged
// so don't interfere with what the user is expecting to see.
return handleException(cause);
}
String dir = this.outputDirectory.getPath();
if (dir == null) {
return handleException(cause);
}
String dumpName = PathUtilities.sanitizeFileName(toString());
File dumpPath = new File(dir, dumpName);
dumpPath.mkdirs();
if (!dumpPath.exists()) {
TTY.println("Warning: could not create diagnostics directory " + dumpPath);
return handleException(cause);
}
String message;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (PrintStream ps = new PrintStream(baos)) {
ps.printf("%s: Compilation of %s failed: ", Thread.currentThread(), this);
@ -198,63 +248,16 @@ public abstract class CompilationWrapper<T> {
causeType,
actionKey.getName(), ExceptionAction.Silent,
actionKey.getName(), ExceptionAction.Silent);
ps.printf("To capture more information for diagnosing or reporting a compilation %s, " +
"set %s to %s or %s (e.g., -Dgraal.%s=%s).%n",
ps.printf("To print a message for a compilation %s without retrying the compilation, " +
"set %s to %s (e.g., -Dgraal.%s=%s).%n",
causeType,
actionKey.getName(), ExceptionAction.Diagnose,
ExceptionAction.ExitVM,
actionKey.getName(), ExceptionAction.Diagnose);
actionKey.getName(), ExceptionAction.Print,
actionKey.getName(), ExceptionAction.Print);
ps.println("Retrying compilation of " + this);
message = baos.toString();
}
synchronized (CompilationFailureAction) {
// Synchronize to prevent compilation exception
// messages from interleaving.
TTY.println(baos.toString());
}
return handleException(cause);
}
// action is Diagnose or ExitVM
if (Dump.hasBeenSet(initialOptions)) {
// If dumping is explicitly enabled, Graal is being debugged
// so don't interfere with what the user is expecting to see.
return handleException(cause);
}
String dir = this.outputDirectory.getPath();
if (dir == null) {
return handleException(cause);
}
String dumpName = PathUtilities.sanitizeFileName(toString());
File dumpPath = new File(dir, dumpName);
dumpPath.mkdirs();
if (!dumpPath.exists()) {
TTY.println("Warning: could not create diagnostics directory " + dumpPath);
return handleException(cause);
}
String message;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (PrintStream ps = new PrintStream(baos)) {
ps.printf("%s: Compilation of %s failed: ", Thread.currentThread(), this);
cause.printStackTrace(ps);
ps.printf("To disable compilation %s notifications, set %s to %s (e.g., -Dgraal.%s=%s).%n",
causeType,
actionKey.getName(), ExceptionAction.Silent,
actionKey.getName(), ExceptionAction.Silent);
ps.printf("To print a message for a compilation %s without retrying the compilation, " +
"set %s to %s (e.g., -Dgraal.%s=%s).%n",
causeType,
actionKey.getName(), ExceptionAction.Print,
actionKey.getName(), ExceptionAction.Print);
ps.println("Retrying compilation of " + this);
message = baos.toString();
}
synchronized (CompilationFailureAction) {
// Synchronize here to serialize retry compilations. This
// mitigates retry compilation storms.
TTY.println(message);
TTY.print(message);
File retryLogFile = new File(dumpPath, "retry.log");
try (PrintStream ps = new PrintStream(new FileOutputStream(retryLogFile))) {
ps.print(message);
@ -267,7 +270,7 @@ public abstract class CompilationWrapper<T> {
MethodFilter, null,
DumpPath, dumpPath.getPath());
try (DebugContext retryDebug = createRetryDebugContext(retryOptions)) {
try (DebugContext retryDebug = createRetryDebugContext(retryOptions); DebugCloseable s = retryDebug.disableIntercept()) {
T res = performCompilation(retryDebug);
maybeExitVM(action);
return res;
@ -283,16 +286,8 @@ public abstract class CompilationWrapper<T> {
private void maybeExitVM(ExceptionAction action) {
if (action == ExitVM) {
synchronized (ExceptionAction.class) {
try {
// Give other compiler threads a chance to flush
// error handling output.
ExceptionAction.class.wait(2000);
} catch (InterruptedException e) {
}
TTY.println("Exiting VM after retry compilation of " + this);
System.exit(-1);
}
TTY.println("Exiting VM after retry compilation of " + this);
System.exit(-1);
}
}
@ -303,22 +298,24 @@ public abstract class CompilationWrapper<T> {
private ExceptionAction adjustAction(OptionValues initialOptions, EnumOptionKey<ExceptionAction> actionKey, ExceptionAction initialAction) {
ExceptionAction action = initialAction;
int maxProblems = MaxCompilationProblemsPerAction.getValue(initialOptions);
synchronized (problemsHandledPerAction) {
while (action != ExceptionAction.Silent) {
int problems = problemsHandledPerAction.getOrDefault(action, 0);
if (problems >= maxProblems) {
if (problems == maxProblems) {
TTY.printf("Warning: adjusting %s from %s to %s after %s (%d) failed compilations%n", actionKey, action, action.quieter(),
MaxCompilationProblemsPerAction, maxProblems);
// Ensure that the message above is only printed once
problemsHandledPerAction.put(action, problems + 1);
if (action != ExceptionAction.ExitVM) {
synchronized (problemsHandledPerAction) {
while (action != ExceptionAction.Silent) {
int problems = problemsHandledPerAction.getOrDefault(action, 0);
if (problems >= maxProblems) {
if (problems == maxProblems) {
TTY.printf("Warning: adjusting %s from %s to %s after %s (%d) failed compilations%n", actionKey, action, action.quieter(),
MaxCompilationProblemsPerAction, maxProblems);
// Ensure that the message above is only printed once
problemsHandledPerAction.put(action, problems + 1);
}
action = action.quieter();
} else {
break;
}
action = action.quieter();
} else {
break;
}
problemsHandledPerAction.put(action, problemsHandledPerAction.getOrDefault(action, 0) + 1);
}
problemsHandledPerAction.put(action, problemsHandledPerAction.getOrDefault(action, 0) + 1);
}
return action;
}

View File

@ -50,7 +50,8 @@ public class GraalCompilerOptions {
"The accepted values are the same as for CompilationBailoutAction.", type = OptionType.User)
public static final EnumOptionKey<ExceptionAction> CompilationFailureAction = new EnumOptionKey<>(ExceptionAction.Diagnose);
@Option(help = "The maximum number of compilation failures or bailouts to handle with the action specified " +
"by CompilationFailureAction or CompilationBailoutAction before changing to a less verbose action.", type = OptionType.User)
"by CompilationFailureAction or CompilationBailoutAction before changing to a less verbose action. " +
"This does not apply to the ExitVM action.", type = OptionType.User)
public static final OptionKey<Integer> MaxCompilationProblemsPerAction = new OptionKey<>(2);
@Option(help = "Alias for CompilationFailureAction=ExitVM.", type = OptionType.User)
public static final OptionKey<Boolean> ExitVMOnException = new OptionKey<>(false);

View File

@ -27,14 +27,16 @@ package org.graalvm.compiler.debug.test;
import static org.graalvm.compiler.debug.DebugContext.NO_DESCRIPTION;
import static org.graalvm.compiler.debug.DebugContext.NO_GLOBAL_METRIC_VALUES;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.Collections;
import java.util.Formatter;
import java.util.List;
import java.util.stream.Collectors;
import jdk.internal.vm.compiler.collections.EconomicMap;
import org.graalvm.compiler.debug.Assertions;
@ -158,14 +160,13 @@ public class DebugContextTest {
}
}
}
DataInputStream in = new DataInputStream(getClass().getResourceAsStream(getClass().getSimpleName() + ".testLogging.input"));
byte[] buf = new byte[in.available()];
in.readFully(buf);
String threadLabel = "[thread:" + Thread.currentThread().getId() + "]";
String expect = new String(buf).replace("[thread:1]", threadLabel);
String log = setup.logOutput.toString();
Assert.assertEquals(expect, log);
String expected;
try (BufferedReader input = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream(getClass().getSimpleName() + ".testLogging.input")))) {
String threadLabel = "[thread:" + Thread.currentThread().getId() + "]";
expected = input.lines().collect(Collectors.joining(System.lineSeparator(), "", System.lineSeparator())).replace("[thread:1]", threadLabel);
}
String logged = setup.logOutput.toString();
Assert.assertEquals(expected, logged);
}
@Test

View File

@ -84,7 +84,10 @@ public class DiagnosticsOutputDirectory {
}
}
}
return CLOSED.equals(path) ? null : path;
if (CLOSED.equals(path)) {
TTY.println("Warning: Graal diagnostic directory already closed");
}
return path;
}
/**

View File

@ -24,8 +24,11 @@
package org.graalvm.compiler.debug;
import static java.nio.file.LinkOption.NOFOLLOW_LINKS;
import java.io.File;
import java.io.IOException;
import java.nio.file.AccessDeniedException;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
@ -118,7 +121,15 @@ public class PathUtilities {
if (createDirectory) {
return Files.createDirectory(result);
} else {
return Files.createFile(result);
try {
return Files.createFile(result);
} catch (AccessDeniedException e) {
/*
* Thrown on Windows if a directory with the same name already exists, so
* convert it to FileAlreadyExistsException if that's the case.
*/
throw Files.isDirectory(result, NOFOLLOW_LINKS) ? new FileAlreadyExistsException(e.getFile()) : e;
}
}
} catch (FileAlreadyExistsException e) {
uniqueTag = "_" + dumpCounter++;

View File

@ -54,11 +54,13 @@ public class CompilationWrapperTest extends GraalCompilerTest {
*/
@Test
public void testVMCompilation1() throws IOException, InterruptedException {
testHelper(Collections.emptyList(), Arrays.asList("-XX:+BootstrapJVMCI",
testHelper(Collections.emptyList(), Arrays.asList("-XX:-TieredCompilation",
"-XX:+UseJVMCICompiler",
"-Dgraal.CompilationFailureAction=ExitVM",
"-Dgraal.CrashAt=Object.*,String.*",
"-version"));
"-Dgraal.CrashAt=TestProgram.*",
"-Xcomp",
"-XX:CompileCommand=compileonly,*/TestProgram.print*",
TestProgram.class.getName()));
}
/**
@ -67,11 +69,13 @@ public class CompilationWrapperTest extends GraalCompilerTest {
*/
@Test
public void testVMCompilation2() throws IOException, InterruptedException {
testHelper(Collections.emptyList(), Arrays.asList("-XX:+BootstrapJVMCI",
testHelper(Collections.emptyList(), Arrays.asList("-XX:-TieredCompilation",
"-XX:+UseJVMCICompiler",
"-Dgraal.ExitVMOnException=true",
"-Dgraal.CrashAt=Object.*,String.*",
"-version"));
"-Dgraal.CrashAt=TestProgram.*",
"-Xcomp",
"-XX:CompileCommand=compileonly,*/TestProgram.print*",
TestProgram.class.getName()));
}
static class Probe {
@ -105,23 +109,36 @@ public class CompilationWrapperTest extends GraalCompilerTest {
*/
@Test
public void testVMCompilation3() throws IOException, InterruptedException {
final int maxProblems = 4;
Probe[] probes = {
new Probe("Retrying compilation of", maxProblems) {
@Override
String test() {
return actualOccurrences > 0 && actualOccurrences <= maxProblems ? null : String.format("expected occurrences to be in [1 .. %d]", maxProblems);
}
},
new Probe("adjusting CompilationFailureAction from Diagnose to Print", 1),
new Probe("adjusting CompilationFailureAction from Print to Silent", 1),
final int maxProblems = 2;
Probe retryingProbe = new Probe("Retrying compilation of", maxProblems) {
@Override
String test() {
return actualOccurrences > 0 && actualOccurrences <= maxProblems ? null : String.format("expected occurrences to be in [1 .. %d]", maxProblems);
}
};
testHelper(Arrays.asList(probes), Arrays.asList("-XX:+BootstrapJVMCI",
Probe adjustmentProbe = new Probe("adjusting CompilationFailureAction from Diagnose to Print", 1) {
@Override
String test() {
if (retryingProbe.actualOccurrences >= maxProblems) {
if (actualOccurrences == 0) {
return "expected at least one occurrence";
}
}
return null;
}
};
Probe[] probes = {
retryingProbe,
adjustmentProbe
};
testHelper(Arrays.asList(probes), Arrays.asList("-XX:-TieredCompilation",
"-XX:+UseJVMCICompiler",
"-Dgraal.CompilationFailureAction=Diagnose",
"-Dgraal.MaxCompilationProblemsPerAction=" + maxProblems,
"-Dgraal.CrashAt=Object.*,String.*",
"-version"));
"-Dgraal.CrashAt=TestProgram.*",
"-Xcomp",
"-XX:CompileCommand=compileonly,*/TestProgram.print*",
TestProgram.class.getName()));
}
/**
@ -246,3 +263,38 @@ public class CompilationWrapperTest extends GraalCompilerTest {
}
}
}
class TestProgram {
public static void main(String[] args) {
printHello1();
printWorld1();
printHello2();
printWorld2();
printHello3();
printWorld3();
}
private static void printHello1() {
System.out.println("Hello1");
}
private static void printWorld1() {
System.out.println("World1");
}
private static void printHello2() {
System.out.println("Hello2");
}
private static void printWorld2() {
System.out.println("World2");
}
private static void printHello3() {
System.out.println("Hello3");
}
private static void printWorld3() {
System.out.println("World3");
}
}

View File

@ -28,9 +28,6 @@ import org.graalvm.compiler.api.directives.GraalDirectives;
import org.junit.Assert;
import org.junit.Test;
import jdk.vm.ci.meta.ProfilingInfo;
import jdk.vm.ci.meta.ResolvedJavaMethod;
/**
* Test on-stack-replacement with Graal. The test manually triggers a Graal OSR-compilation which is
* later invoked when hitting the backedge counter overflow.
@ -103,58 +100,4 @@ public class GraalOSRTest extends GraalOSRTestBase {
GraalDirectives.controlFlowAnchor();
return ret;
}
@Test
public void testOSR04() {
testFunnyOSR("testDoWhile", GraalOSRTest::testDoWhile);
}
@Test
public void testOSR05() {
testFunnyOSR("testDoWhileLocked", GraalOSRTest::testDoWhileLocked);
}
/**
* Because of a bug in C1 profile collection HotSpot can sometimes request an OSR compilation
* for a backedge which isn't ever taken. This test synthetically creates that situation.
*/
private void testFunnyOSR(String name, Runnable warmup) {
ResolvedJavaMethod method = getResolvedJavaMethod(name);
int iterations = 0;
while (true) {
ProfilingInfo profilingInfo = method.getProfilingInfo();
if (profilingInfo.isMature()) {
break;
}
warmup.run();
if (iterations++ % 1000 == 0) {
System.err.print('.');
}
if (iterations > 200000) {
throw new AssertionError("no profile");
}
}
compileOSR(getInitialOptions(), method);
Result result = executeExpected(method, null);
checkResult(result);
}
private static boolean repeatLoop;
public static ReturnValue testDoWhile() {
do {
sideEffect++;
} while (repeatLoop);
return ReturnValue.SUCCESS;
}
public static synchronized ReturnValue testDoWhileLocked() {
// synchronized (GraalOSRTest.class) {
do {
sideEffect++;
} while (repeatLoop);
// }
return ReturnValue.SUCCESS;
}
}

View File

@ -358,14 +358,17 @@ public class HotSpotGraalManagementTest {
assertNotNull("Info is found", info);
final MBeanOperationInfo[] arr = info.getOperations();
assertEquals("Currently three overloads", 3, arr.length);
MBeanOperationInfo dumpOp = null;
int dumpMethodCount = 0;
for (int i = 0; i < arr.length; i++) {
assertEquals("dumpMethod", arr[i].getName());
if (arr[i].getSignature().length == 3) {
dumpOp = arr[i];
if ("dumpMethod".equals(arr[i].getName())) {
if (arr[i].getSignature().length == 3) {
dumpOp = arr[i];
}
dumpMethodCount++;
}
}
assertEquals("Currently three overloads", 3, dumpMethodCount);
assertNotNull("three args variant (as used by VisualVM) found", dumpOp);
MBeanAttributeInfo dumpPath = findAttributeInfo("DumpPath", info);

View File

@ -26,6 +26,10 @@ package org.graalvm.compiler.hotspot;
import java.util.EnumSet;
import jdk.internal.vm.compiler.collections.EconomicMap;
import jdk.internal.vm.compiler.collections.EconomicSet;
import jdk.internal.vm.compiler.collections.Equivalence;
import jdk.internal.vm.compiler.collections.MapCursor;
import org.graalvm.compiler.code.CompilationResult;
import org.graalvm.compiler.core.common.CompilationIdentifier;
import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
@ -66,10 +70,6 @@ import org.graalvm.compiler.options.OptionType;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.phases.tiers.SuitesProvider;
import org.graalvm.compiler.word.Word;
import jdk.internal.vm.compiler.collections.EconomicMap;
import jdk.internal.vm.compiler.collections.EconomicSet;
import jdk.internal.vm.compiler.collections.Equivalence;
import jdk.internal.vm.compiler.collections.MapCursor;
import jdk.internal.vm.compiler.word.Pointer;
import jdk.vm.ci.code.CompilationRequest;
@ -286,7 +286,7 @@ public abstract class HotSpotBackend extends Backend implements FrameMap.Referen
/**
* New array stub.
*/
public static final ForeignCallDescriptor NEW_ARRAY = new ForeignCallDescriptor("new_array", Object.class, KlassPointer.class, int.class, boolean.class);
public static final ForeignCallDescriptor NEW_ARRAY = new ForeignCallDescriptor("new_array", Object.class, KlassPointer.class, int.class);
/**
* New instance stub.

View File

@ -227,6 +227,7 @@ public class HotSpotGraalCompiler implements GraalJVMCICompiler {
method(substMethod).
compilationId(compilationId).
recordInlinedMethods(bytecodeProvider.shouldRecordMethodDependencies()).
setIsSubstitution(true).
build();
// @formatter:on
try (DebugContext.Scope scope = debug.scope("GetIntrinsicGraph", graph)) {

View File

@ -93,7 +93,8 @@ public interface HotSpotGraalRuntimeProvider extends GraalRuntime, RuntimeProvid
DiagnosticsOutputDirectory getOutputDirectory();
/**
* Gets the map used to count compilation problems at each {@link ExceptionAction} level.
* Gets the map used to count compilation problems at each {@link ExceptionAction} level. All
* updates and queries to the map should be synchronized.
*/
Map<ExceptionAction, Integer> getCompilationProblemsPerAction();

View File

@ -131,7 +131,7 @@ class JVMCIVersionCheck {
return;
}
} else {
// Graal is compatible with all JDK versions as of 9 GA.
// Graal is compatible with all JDK versions as of 11 GA.
}
}
}

View File

@ -85,8 +85,6 @@ import static org.graalvm.compiler.hotspot.replacements.WriteBarrierSnippets.G1W
import static org.graalvm.compiler.hotspot.replacements.WriteBarrierSnippets.G1WBPRECALL;
import static org.graalvm.compiler.hotspot.replacements.WriteBarrierSnippets.VALIDATE_OBJECT;
import static org.graalvm.compiler.hotspot.stubs.ExceptionHandlerStub.EXCEPTION_HANDLER_FOR_PC;
import static org.graalvm.compiler.hotspot.stubs.NewArrayStub.NEW_ARRAY_C;
import static org.graalvm.compiler.hotspot.stubs.NewInstanceStub.NEW_INSTANCE_C;
import static org.graalvm.compiler.hotspot.stubs.StubUtil.VM_MESSAGE_C;
import static org.graalvm.compiler.hotspot.stubs.UnwindExceptionToCallerStub.EXCEPTION_HANDLER_FOR_RETURN_ADDRESS;
import static org.graalvm.compiler.nodes.java.ForeignCallDescriptors.REGISTER_FINALIZER;
@ -119,8 +117,6 @@ import org.graalvm.compiler.hotspot.stubs.DivisionByZeroExceptionStub;
import org.graalvm.compiler.hotspot.stubs.ExceptionHandlerStub;
import org.graalvm.compiler.hotspot.stubs.IntegerExactOverflowExceptionStub;
import org.graalvm.compiler.hotspot.stubs.LongExactOverflowExceptionStub;
import org.graalvm.compiler.hotspot.stubs.NewArrayStub;
import org.graalvm.compiler.hotspot.stubs.NewInstanceStub;
import org.graalvm.compiler.hotspot.stubs.NullPointerExceptionStub;
import org.graalvm.compiler.hotspot.stubs.OutOfBoundsExceptionStub;
import org.graalvm.compiler.hotspot.stubs.Stub;
@ -280,8 +276,6 @@ public abstract class HotSpotHostForeignCallsProvider extends HotSpotForeignCall
registerForeignCall(EXCEPTION_HANDLER_FOR_PC, c.exceptionHandlerForPcAddress, NativeCall, DESTROYS_REGISTERS, SAFEPOINT, REEXECUTABLE, any());
registerForeignCall(EXCEPTION_HANDLER_FOR_RETURN_ADDRESS, c.exceptionHandlerForReturnAddressAddress, NativeCall, DESTROYS_REGISTERS, SAFEPOINT, REEXECUTABLE, any());
registerForeignCall(NEW_ARRAY_C, c.newArrayAddress, NativeCall, DESTROYS_REGISTERS, SAFEPOINT, REEXECUTABLE, any());
registerForeignCall(NEW_INSTANCE_C, c.newInstanceAddress, NativeCall, DESTROYS_REGISTERS, SAFEPOINT, REEXECUTABLE, any());
CreateExceptionStub.registerForeignCalls(c, this);
@ -292,8 +286,8 @@ public abstract class HotSpotHostForeignCallsProvider extends HotSpotForeignCall
registerForeignCall(VM_MESSAGE_C, c.vmMessageAddress, NativeCall, DESTROYS_REGISTERS, SAFEPOINT, REEXECUTABLE, NO_LOCATIONS);
registerForeignCall(ASSERTION_VM_MESSAGE_C, c.vmMessageAddress, NativeCall, PRESERVES_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
link(new NewInstanceStub(options, providers, registerStubCall(NEW_INSTANCE, SAFEPOINT, REEXECUTABLE, TLAB_TOP_LOCATION, TLAB_END_LOCATION)));
link(new NewArrayStub(options, providers, registerStubCall(NEW_ARRAY, SAFEPOINT, REEXECUTABLE, TLAB_TOP_LOCATION, TLAB_END_LOCATION)));
linkForeignCall(options, providers, NEW_INSTANCE, c.newInstanceAddress, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, TLAB_TOP_LOCATION, TLAB_END_LOCATION);
linkForeignCall(options, providers, NEW_ARRAY, c.newArrayAddress, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, TLAB_TOP_LOCATION, TLAB_END_LOCATION);
link(new ExceptionHandlerStub(options, providers, foreignCalls.get(EXCEPTION_HANDLER)));
link(new UnwindExceptionToCallerStub(options, providers, registerStubCall(UNWIND_EXCEPTION_TO_CALLER, SAFEPOINT, REEXECUTABLE_ONLY_AFTER_EXCEPTION, any())));
link(new VerifyOopStub(options, providers, registerStubCall(VERIFY_OOP, LEAF_NOFP, REEXECUTABLE, NO_LOCATIONS)));

View File

@ -331,14 +331,14 @@ public class NewObjectSnippets implements Snippets {
}
result = formatArray(hub, allocationSize, length, headerSize, top, prototypeMarkWord, fillContents, maybeUnroll, counters);
} else {
result = newArray(HotSpotBackend.NEW_ARRAY, hub, length, fillContents);
result = newArray(HotSpotBackend.NEW_ARRAY, hub, length);
}
profileAllocation("array", allocationSize, typeContext, options);
return result;
}
@NodeIntrinsic(value = ForeignCallNode.class, injectedStampIsNonNull = true)
public static native Object newArray(@ConstantNodeParameter ForeignCallDescriptor descriptor, KlassPointer hub, int length, boolean fillContents);
public static native Object newArray(@ConstantNodeParameter ForeignCallDescriptor descriptor, KlassPointer hub, int length);
public static final ForeignCallDescriptor DYNAMIC_NEW_ARRAY = new ForeignCallDescriptor("dynamic_new_array", Object.class, Class.class, int.class);
public static final ForeignCallDescriptor DYNAMIC_NEW_INSTANCE = new ForeignCallDescriptor("dynamic_new_instance", Object.class, Class.class);

View File

@ -1,122 +0,0 @@
/*
* Copyright (c) 2012, 2015, 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.
*/
package org.graalvm.compiler.hotspot.stubs;
import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayAllocationSize;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.getAndClearObjectResult;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperElementTypeMask;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperElementTypeShift;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperHeaderSizeMask;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperHeaderSizeShift;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperLog2ElementSizeMask;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperLog2ElementSizeShift;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.readLayoutHelper;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.registerAsWord;
import static org.graalvm.compiler.hotspot.stubs.StubUtil.handlePendingException;
import static org.graalvm.compiler.hotspot.stubs.StubUtil.newDescriptor;
import static org.graalvm.compiler.hotspot.stubs.StubUtil.printf;
import static org.graalvm.compiler.hotspot.stubs.StubUtil.verifyObject;
import org.graalvm.compiler.api.replacements.Fold;
import org.graalvm.compiler.api.replacements.Snippet;
import org.graalvm.compiler.api.replacements.Snippet.ConstantParameter;
import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
import org.graalvm.compiler.graph.Node.ConstantNodeParameter;
import org.graalvm.compiler.graph.Node.NodeIntrinsic;
import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage;
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
import org.graalvm.compiler.hotspot.nodes.StubForeignCallNode;
import org.graalvm.compiler.hotspot.replacements.NewObjectSnippets;
import org.graalvm.compiler.hotspot.word.KlassPointer;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.word.Word;
import jdk.vm.ci.code.Register;
/**
* Stub implementing the fast path for TLAB refill during instance class allocation. This stub is
* called from the {@linkplain NewObjectSnippets inline} allocation code when TLAB allocation fails.
* If this stub fails to refill the TLAB or allocate the object, it calls out to the HotSpot C++
* runtime to complete the allocation.
*/
public class NewArrayStub extends SnippetStub {
public NewArrayStub(OptionValues options, HotSpotProviders providers, HotSpotForeignCallLinkage linkage) {
super("newArray", options, providers, linkage);
}
@Override
protected Object[] makeConstArgs() {
int count = method.getSignature().getParameterCount(false);
Object[] args = new Object[count];
assert checkConstArg(2, "threadRegister");
assert checkConstArg(3, "options");
args[2] = providers.getRegisters().getThreadRegister();
args[3] = options;
return args;
}
@Fold
static boolean logging(OptionValues options) {
return StubOptions.TraceNewArrayStub.getValue(options);
}
/**
* Re-attempts allocation after an initial TLAB allocation failed or was skipped (e.g., due to
* -XX:-UseTLAB).
*
* @param hub the hub of the object to be allocated
* @param length the length of the array
*/
@Snippet
private static Object newArray(KlassPointer hub, int length, @ConstantParameter Register threadRegister, @ConstantParameter OptionValues options) {
int layoutHelper = readLayoutHelper(hub);
int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift(INJECTED_VMCONFIG)) & layoutHelperLog2ElementSizeMask(INJECTED_VMCONFIG);
int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift(INJECTED_VMCONFIG)) & layoutHelperHeaderSizeMask(INJECTED_VMCONFIG);
int elementKind = (layoutHelper >> layoutHelperElementTypeShift(INJECTED_VMCONFIG)) & layoutHelperElementTypeMask(INJECTED_VMCONFIG);
int sizeInBytes = arrayAllocationSize(length, headerSize, log2ElementSize);
if (logging(options)) {
printf("newArray: element kind %d\n", elementKind);
printf("newArray: array length %d\n", length);
printf("newArray: array size %d\n", sizeInBytes);
printf("newArray: hub=%p\n", hub.asWord().rawValue());
}
Word thread = registerAsWord(threadRegister);
if (logging(options)) {
printf("newArray: calling new_array_c\n");
}
newArrayC(NEW_ARRAY_C, thread, hub, length);
handlePendingException(thread, true, true);
return verifyObject(getAndClearObjectResult(thread));
}
public static final ForeignCallDescriptor NEW_ARRAY_C = newDescriptor(NewArrayStub.class, "newArrayC", void.class, Word.class, KlassPointer.class, int.class);
@NodeIntrinsic(StubForeignCallNode.class)
public static native void newArrayC(@ConstantNodeParameter ForeignCallDescriptor newArrayC, Word thread, KlassPointer hub, int length);
}

View File

@ -1,109 +0,0 @@
/*
* Copyright (c) 2012, 2015, 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.
*/
package org.graalvm.compiler.hotspot.stubs;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.getAndClearObjectResult;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.registerAsWord;
import static org.graalvm.compiler.hotspot.stubs.StubUtil.handlePendingException;
import static org.graalvm.compiler.hotspot.stubs.StubUtil.newDescriptor;
import static org.graalvm.compiler.hotspot.stubs.StubUtil.printf;
import static org.graalvm.compiler.hotspot.stubs.StubUtil.verifyObject;
import org.graalvm.compiler.api.replacements.Fold;
import org.graalvm.compiler.api.replacements.Snippet;
import org.graalvm.compiler.api.replacements.Snippet.ConstantParameter;
import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
import org.graalvm.compiler.graph.Node.ConstantNodeParameter;
import org.graalvm.compiler.graph.Node.NodeIntrinsic;
import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage;
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
import org.graalvm.compiler.hotspot.nodes.StubForeignCallNode;
import org.graalvm.compiler.hotspot.replacements.NewObjectSnippets;
import org.graalvm.compiler.hotspot.word.KlassPointer;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.word.Word;
import jdk.vm.ci.code.Register;
/**
* Stub implementing the fast path for TLAB refill during instance class allocation. This stub is
* called from the {@linkplain NewObjectSnippets inline} allocation code when TLAB allocation fails.
* If this stub fails to refill the TLAB or allocate the object, it calls out to the HotSpot C++
* runtime for to complete the allocation.
*/
public class NewInstanceStub extends SnippetStub {
public NewInstanceStub(OptionValues options, HotSpotProviders providers, HotSpotForeignCallLinkage linkage) {
super("newInstance", options, providers, linkage);
}
@Override
protected Object[] makeConstArgs() {
int count = method.getSignature().getParameterCount(false);
Object[] args = new Object[count];
assert checkConstArg(1, "threadRegister");
assert checkConstArg(2, "options");
args[1] = providers.getRegisters().getThreadRegister();
args[2] = options;
return args;
}
@Fold
static boolean logging(OptionValues options) {
return StubOptions.TraceNewInstanceStub.getValue(options);
}
/**
* Re-attempts allocation after an initial TLAB allocation failed or was skipped (e.g., due to
* -XX:-UseTLAB).
*
* @param hub the hub of the object to be allocated
*/
@Snippet
private static Object newInstance(KlassPointer hub, @ConstantParameter Register threadRegister, @ConstantParameter OptionValues options) {
/*
* The type is known to be an instance so Klass::_layout_helper is the instance size as a
* raw number
*/
Word thread = registerAsWord(threadRegister);
if (logging(options)) {
printf("newInstance: calling new_instance_c\n");
}
newInstanceC(NEW_INSTANCE_C, thread, hub);
handlePendingException(thread, true, true);
return verifyObject(getAndClearObjectResult(thread));
}
@Fold
static boolean forceSlowPath(OptionValues options) {
return StubOptions.ForceUseOfNewInstanceStub.getValue(options);
}
public static final ForeignCallDescriptor NEW_INSTANCE_C = newDescriptor(NewInstanceStub.class, "newInstanceC", void.class, Word.class, KlassPointer.class);
@NodeIntrinsic(StubForeignCallNode.class)
public static native void newInstanceC(@ConstantNodeParameter ForeignCallDescriptor newInstanceC, Word thread, KlassPointer hub);
}

View File

@ -107,9 +107,15 @@ public abstract class SnippetStub extends Stub implements Snippets {
plugins.prependParameterPlugin(new ConstantBindingParameterPlugin(makeConstArgs(), metaAccess, snippetReflection));
GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault(plugins);
// @formatter:off
// Stubs cannot have optimistic assumptions since they have
// to be valid for the entire run of the VM.
final StructuredGraph graph = new StructuredGraph.Builder(options, debug).method(method).compilationId(compilationId).build();
final StructuredGraph graph = new StructuredGraph.Builder(options, debug).
method(method).
compilationId(compilationId).
setIsSubstitution(true).
build();
// @formatter:on
try (DebugContext.Scope outer = debug.scope("SnippetStub", graph)) {
graph.disableUnsafeAccessTracking();

View File

@ -25,8 +25,8 @@
package org.graalvm.compiler.hotspot.stubs;
import org.graalvm.compiler.options.Option;
import org.graalvm.compiler.options.OptionType;
import org.graalvm.compiler.options.OptionKey;
import org.graalvm.compiler.options.OptionType;
//JaCoCo Exclude
@ -43,14 +43,5 @@ public class StubOptions {
@Option(help = "Trace execution of the stub that routes an exception to a handler in the calling frame.", type = OptionType.Debug)
static final OptionKey<Boolean> TraceUnwindStub = new OptionKey<>(false);
@Option(help = "Trace execution of slow path stub for array allocation.", type = OptionType.Debug)
static final OptionKey<Boolean> TraceNewArrayStub = new OptionKey<>(false);
@Option(help = "Trace execution of slow path stub for non-array object allocation.", type = OptionType.Debug)
static final OptionKey<Boolean> TraceNewInstanceStub = new OptionKey<>(false);
@Option(help = "Force non-array object allocation to always use the slow path.", type = OptionType.Debug)
static final OptionKey<Boolean> ForceUseOfNewInstanceStub = new OptionKey<>(false);
//@formatter:on
}

View File

@ -26,6 +26,7 @@ package org.graalvm.compiler.java;
import static org.graalvm.compiler.bytecode.Bytecodes.AALOAD;
import static org.graalvm.compiler.bytecode.Bytecodes.AASTORE;
import static org.graalvm.compiler.bytecode.Bytecodes.ANEWARRAY;
import static org.graalvm.compiler.bytecode.Bytecodes.ARETURN;
import static org.graalvm.compiler.bytecode.Bytecodes.ARRAYLENGTH;
import static org.graalvm.compiler.bytecode.Bytecodes.ATHROW;
@ -78,6 +79,8 @@ import static org.graalvm.compiler.bytecode.Bytecodes.LDIV;
import static org.graalvm.compiler.bytecode.Bytecodes.LOOKUPSWITCH;
import static org.graalvm.compiler.bytecode.Bytecodes.LREM;
import static org.graalvm.compiler.bytecode.Bytecodes.LRETURN;
import static org.graalvm.compiler.bytecode.Bytecodes.MULTIANEWARRAY;
import static org.graalvm.compiler.bytecode.Bytecodes.NEW;
import static org.graalvm.compiler.bytecode.Bytecodes.PUTFIELD;
import static org.graalvm.compiler.bytecode.Bytecodes.PUTSTATIC;
import static org.graalvm.compiler.bytecode.Bytecodes.RET;
@ -679,10 +682,19 @@ public final class BciBlockMapping {
case SALOAD:
case ARRAYLENGTH:
case CHECKCAST:
case NEW:
case ANEWARRAY:
case MULTIANEWARRAY:
case PUTSTATIC:
case GETSTATIC:
case PUTFIELD:
case GETFIELD: {
/*
* All bytecodes that can trigger lazy class initialization via a
* ClassInitializationPlugin (allocations, static field access) must be listed
* because the class initializer is allowed to throw an exception, which
* requires proper exception handling.
*/
ExceptionDispatchBlock handler = handleExceptions(blockMap, bci);
if (handler != null) {
current = null;

View File

@ -3369,29 +3369,25 @@ public class BytecodeParser implements GraphBuilderContext {
NodeSourcePosition currentPosition = graph.currentNodeSourcePosition();
if (isNeverExecutedCode(probability)) {
if (!graph.isOSR() || getParent() != null || graph.getEntryBCI() != trueBlock.startBci) {
NodeSourcePosition survivingSuccessorPosition = graph.trackNodeSourcePosition()
? new NodeSourcePosition(currentPosition.getCaller(), currentPosition.getMethod(), falseBlock.startBci)
: null;
append(new FixedGuardNode(condition, UnreachedCode, InvalidateReprofile, true, survivingSuccessorPosition));
if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
profilingPlugin.profileGoto(this, method, bci(), falseBlock.startBci, stateBefore);
}
appendGoto(falseBlock);
return;
NodeSourcePosition survivingSuccessorPosition = graph.trackNodeSourcePosition()
? new NodeSourcePosition(currentPosition.getCaller(), currentPosition.getMethod(), falseBlock.startBci)
: null;
append(new FixedGuardNode(condition, UnreachedCode, InvalidateReprofile, true, survivingSuccessorPosition));
if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
profilingPlugin.profileGoto(this, method, bci(), falseBlock.startBci, stateBefore);
}
appendGoto(falseBlock);
return;
} else if (isNeverExecutedCode(1 - probability)) {
if (!graph.isOSR() || getParent() != null || graph.getEntryBCI() != falseBlock.startBci) {
NodeSourcePosition survivingSuccessorPosition = graph.trackNodeSourcePosition()
? new NodeSourcePosition(currentPosition.getCaller(), currentPosition.getMethod(), trueBlock.startBci)
: null;
append(new FixedGuardNode(condition, UnreachedCode, InvalidateReprofile, false, survivingSuccessorPosition));
if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
profilingPlugin.profileGoto(this, method, bci(), trueBlock.startBci, stateBefore);
}
appendGoto(trueBlock);
return;
NodeSourcePosition survivingSuccessorPosition = graph.trackNodeSourcePosition()
? new NodeSourcePosition(currentPosition.getCaller(), currentPosition.getMethod(), trueBlock.startBci)
: null;
append(new FixedGuardNode(condition, UnreachedCode, InvalidateReprofile, false, survivingSuccessorPosition));
if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
profilingPlugin.profileGoto(this, method, bci(), trueBlock.startBci, stateBefore);
}
appendGoto(trueBlock);
return;
}
if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
@ -4116,6 +4112,11 @@ public class BytecodeParser implements GraphBuilderContext {
return;
}
ResolvedJavaType resolvedType = (ResolvedJavaType) type;
if (resolvedType.isAbstract() || resolvedType.isInterface()) {
handleUnresolvedNewInstance(type);
return;
}
ClassInitializationPlugin classInitializationPlugin = graphBuilderConfig.getPlugins().getClassInitializationPlugin();
if (!resolvedType.isInitialized() && classInitializationPlugin == null) {
handleUnresolvedNewInstance(type);

View File

@ -436,7 +436,12 @@ public class GraphEncoder {
@SuppressWarnings("try")
public static boolean verifyEncoding(StructuredGraph originalGraph, EncodedGraph encodedGraph, Architecture architecture) {
DebugContext debug = originalGraph.getDebug();
StructuredGraph decodedGraph = new StructuredGraph.Builder(originalGraph.getOptions(), debug, AllowAssumptions.YES).method(originalGraph.method()).build();
// @formatter:off
StructuredGraph decodedGraph = new StructuredGraph.Builder(originalGraph.getOptions(), debug, AllowAssumptions.YES).
method(originalGraph.method()).
setIsSubstitution(originalGraph.isSubstitution()).
build();
// @formatter:off
if (originalGraph.trackNodeSourcePosition()) {
decodedGraph.setTrackNodeSourcePosition();
}

View File

@ -40,6 +40,8 @@ import jdk.internal.vm.compiler.collections.EconomicMap;
import jdk.internal.vm.compiler.collections.EconomicSet;
import jdk.internal.vm.compiler.collections.Equivalence;
import jdk.internal.vm.compiler.collections.UnmodifiableEconomicMap;
import org.graalvm.compiler.api.replacements.MethodSubstitution;
import org.graalvm.compiler.api.replacements.Snippet;
import org.graalvm.compiler.core.common.CancellationBailoutException;
import org.graalvm.compiler.core.common.CompilationIdentifier;
import org.graalvm.compiler.core.common.GraalOptions;
@ -187,6 +189,7 @@ public final class StructuredGraph extends Graph implements JavaMethodContext {
private Cancellable cancellable = null;
private final DebugContext debug;
private NodeSourcePosition callerContext;
private boolean isSubstitution;
/**
* Creates a builder for a graph.
@ -217,6 +220,14 @@ public final class StructuredGraph extends Graph implements JavaMethodContext {
return this;
}
/**
* @see StructuredGraph#isSubstitution
*/
public Builder setIsSubstitution(boolean flag) {
this.isSubstitution = flag;
return this;
}
public ResolvedJavaMethod getMethod() {
return rootMethod;
}
@ -303,8 +314,22 @@ public final class StructuredGraph extends Graph implements JavaMethodContext {
public StructuredGraph build() {
List<ResolvedJavaMethod> inlinedMethods = recordInlinedMethods ? new ArrayList<>() : null;
return new StructuredGraph(name, rootMethod, entryBCI, assumptions, speculationLog, useProfilingInfo, inlinedMethods,
trackNodeSourcePosition, compilationId, options, debug, cancellable, callerContext);
// @formatter:off
return new StructuredGraph(name,
rootMethod,
entryBCI,
assumptions,
speculationLog,
useProfilingInfo,
isSubstitution,
inlinedMethods,
trackNodeSourcePosition,
compilationId,
options,
debug,
cancellable,
callerContext);
// @formatter:on
}
}
@ -323,6 +348,8 @@ public final class StructuredGraph extends Graph implements JavaMethodContext {
private boolean isAfterExpandLogic = false;
private final boolean useProfilingInfo;
private final Cancellable cancellable;
private final boolean isSubstitution;
/**
* The assumptions made while constructing and transforming this graph.
*/
@ -369,6 +396,7 @@ public final class StructuredGraph extends Graph implements JavaMethodContext {
Assumptions assumptions,
SpeculationLog speculationLog,
boolean useProfilingInfo,
boolean isSubstitution,
List<ResolvedJavaMethod> methods,
SourcePositionTracking trackNodeSourcePosition,
CompilationIdentifier compilationId,
@ -386,6 +414,8 @@ public final class StructuredGraph extends Graph implements JavaMethodContext {
this.methods = methods;
this.speculationLog = speculationLog;
this.useProfilingInfo = useProfilingInfo;
this.isSubstitution = isSubstitution;
assert checkIsSubstitutionInvariants(method, isSubstitution);
this.trackNodeSourcePosition = trackNodeSourcePosition;
assert trackNodeSourcePosition != null;
this.cancellable = cancellable;
@ -393,6 +423,18 @@ public final class StructuredGraph extends Graph implements JavaMethodContext {
this.callerContext = context;
}
private static boolean checkIsSubstitutionInvariants(ResolvedJavaMethod method, boolean isSubstitution) {
if (method != null) {
if (method.getAnnotation(Snippet.class) != null || method.getAnnotation(MethodSubstitution.class) != null) {
assert isSubstitution : "Graph for method " + method.format("%H.%n(%p)") +
" annotated by " + Snippet.class.getName() + " or " +
MethodSubstitution.class.getName() +
" must have its `isSubstitution` field set to true";
}
}
return true;
}
public void setLastSchedule(ScheduleResult result) {
lastSchedule = result;
}
@ -535,6 +577,7 @@ public final class StructuredGraph extends Graph implements JavaMethodContext {
assumptions == null ? null : new Assumptions(),
speculationLog,
useProfilingInfo,
isSubstitution,
methods != null ? new ArrayList<>(methods) : null,
trackNodeSourcePosition,
newCompilationId,
@ -858,6 +901,15 @@ public final class StructuredGraph extends Graph implements JavaMethodContext {
return useProfilingInfo;
}
/**
* Returns true if this graph is built without parsing the {@linkplain #method() root method} or
* if the root method is annotated by {@link Snippet} or {@link MethodSubstitution}. This is
* preferred over querying annotations directly as querying annotations can cause class loading.
*/
public boolean isSubstitution() {
return isSubstitution;
}
/**
* Gets the profiling info for the {@linkplain #method() root method} of this graph.
*/

View File

@ -61,7 +61,7 @@ import jdk.vm.ci.meta.TriState;
public class InstanceOfNode extends UnaryOpLogicNode implements Lowerable, Virtualizable {
public static final NodeClass<InstanceOfNode> TYPE = NodeClass.create(InstanceOfNode.class);
private ObjectStamp checkedStamp;
private final ObjectStamp checkedStamp;
private JavaTypeProfile profile;
@OptionalInput(Anchor) protected AnchoringNode anchor;
@ -77,6 +77,7 @@ public class InstanceOfNode extends UnaryOpLogicNode implements Lowerable, Virtu
this.anchor = anchor;
assert (profile == null) || (anchor != null) : "profiles must be anchored";
assert checkedStamp != null;
assert type() != null;
}
public static LogicNode createAllowNull(TypeReference type, ValueNode object, JavaTypeProfile profile, AnchoringNode anchor) {
@ -217,11 +218,6 @@ public class InstanceOfNode extends UnaryOpLogicNode implements Lowerable, Virtu
return checkedStamp;
}
public void strengthenCheckedStamp(ObjectStamp newCheckedStamp) {
assert this.checkedStamp.join(newCheckedStamp).equals(newCheckedStamp) : "stamp can only improve";
this.checkedStamp = newCheckedStamp;
}
@Override
public TriState implies(boolean thisNegated, LogicNode other) {
if (other instanceof InstanceOfNode) {

View File

@ -60,7 +60,7 @@ public class NewInstanceNode extends AbstractNewObjectNode implements Virtualiza
protected NewInstanceNode(NodeClass<? extends NewInstanceNode> c, ResolvedJavaType type, boolean fillContents, FrameState stateBefore) {
super(c, StampFactory.objectNonNull(TypeReference.createExactTrusted(type)), fillContents, stateBefore);
assert !type.isArray() && !type.isInterface() && !type.isPrimitive();
assert !type.isArray() && !type.isInterface() && !type.isPrimitive() && !type.isAbstract();
this.instanceClass = type;
}

View File

@ -98,7 +98,7 @@ public final class StoreIndexedNode extends AccessIndexedNode implements StateSp
VirtualArrayNode virtual = (VirtualArrayNode) alias;
if (idx >= 0 && idx < virtual.entryCount()) {
ResolvedJavaType componentType = virtual.type().getComponentType();
if (componentType.isPrimitive() || StampTool.isPointerAlwaysNull(value) || componentType.getSuperclass() == null ||
if (componentType.isPrimitive() || StampTool.isPointerAlwaysNull(value) || componentType.isJavaLangObject() ||
(StampTool.typeReferenceOrNull(value) != null && componentType.isAssignableFrom(StampTool.typeOrNull(value)))) {
tool.setVirtualEntry(virtual, idx, value());
tool.delete();

View File

@ -32,7 +32,6 @@ import java.util.ServiceLoader;
import jdk.internal.vm.compiler.collections.EconomicMap;
import jdk.internal.vm.compiler.collections.MapCursor;
import org.graalvm.util.CollectionsUtil;
/**
* This class contains methods for parsing Graal options and matching them against a set of
@ -45,20 +44,21 @@ public class OptionsParser {
* {@link OptionDescriptors} providers.
*/
public static Iterable<OptionDescriptors> getOptionsLoader() {
ServiceLoader<OptionDescriptors> graalLoader = ServiceLoader.load(OptionDescriptors.class, OptionDescriptors.class.getClassLoader());
boolean java8OrEarlier = System.getProperty("java.specification.version").compareTo("1.9") < 0;
ClassLoader loader;
if (java8OrEarlier) {
return graalLoader;
// On JDK 8, Graal and its extensions are loaded by same class loader.
loader = OptionDescriptors.class.getClassLoader();
} else {
/*
* The Graal module (i.e., jdk.internal.vm.compiler) is loaded by the platform class
* loader on JDK 9. Other modules that extend Graal or are Graal dependencies (such as
* Truffle) are supplied via --module-path which means they are loaded by the app class
* loader. As such, we need to search the app class loader path as well.
* loader as of JDK 9. Modules that depend on and extend Graal are loaded by the app
* class loader. As such, we need to start the provider search at the app class loader
* instead of the platform class loader.
*/
ServiceLoader<OptionDescriptors> truffleLoader = ServiceLoader.load(OptionDescriptors.class, ClassLoader.getSystemClassLoader());
return CollectionsUtil.concat(graalLoader, truffleLoader);
loader = ClassLoader.getSystemClassLoader();
}
return ServiceLoader.load(OptionDescriptors.class, loader);
}
/**

View File

@ -56,7 +56,6 @@ import org.graalvm.compiler.nodes.AbstractBeginNode;
import org.graalvm.compiler.nodes.AbstractMergeNode;
import org.graalvm.compiler.nodes.BinaryOpLogicNode;
import org.graalvm.compiler.nodes.ConditionAnchorNode;
import org.graalvm.compiler.nodes.DeoptimizeNode;
import org.graalvm.compiler.nodes.DeoptimizingGuard;
import org.graalvm.compiler.nodes.EndNode;
import org.graalvm.compiler.nodes.FixedGuardNode;
@ -64,6 +63,7 @@ import org.graalvm.compiler.nodes.FixedNode;
import org.graalvm.compiler.nodes.FixedWithNextNode;
import org.graalvm.compiler.nodes.GuardNode;
import org.graalvm.compiler.nodes.IfNode;
import org.graalvm.compiler.nodes.LogicConstantNode;
import org.graalvm.compiler.nodes.LogicNode;
import org.graalvm.compiler.nodes.LoopExitNode;
import org.graalvm.compiler.nodes.MergeNode;
@ -335,11 +335,18 @@ public class ConditionalEliminationPhase extends BasePhase<PhaseContext> {
if (result != node.isNegated()) {
node.replaceAndDelete(guard.asNode());
} else {
DeoptimizeNode deopt = node.graph().add(new DeoptimizeNode(node.getAction(), node.getReason(), node.getSpeculation()));
/*
* Don't kill this branch immediately because `killCFG` can have complex
* implications in the presence of loops: it might replace or delete nodes in
* other branches or even above the kill point. Instead of killing immediately,
* just leave the graph in a state that is easy to simplify by a subsequent
* canonicalizer phase.
*/
FixedGuardNode deopt = new FixedGuardNode(LogicConstantNode.forBoolean(result, node.graph()), node.getReason(), node.getAction(), node.getSpeculation(), node.isNegated(),
node.getNodeSourcePosition());
AbstractBeginNode beginNode = (AbstractBeginNode) node.getAnchor();
FixedNode next = beginNode.next();
beginNode.setNext(deopt);
GraphUtil.killCFG(next);
graph.addAfterFixed(beginNode, node.graph().add(deopt));
}
return true;
})) {
@ -354,10 +361,8 @@ public class ConditionalEliminationPhase extends BasePhase<PhaseContext> {
GraphUtil.unlinkFixedNode(node);
GraphUtil.killWithUnusedFloatingInputs(node);
} else {
DeoptimizeNode deopt = node.graph().add(new DeoptimizeNode(node.getAction(), node.getReason(), node.getSpeculation()));
deopt.setStateBefore(node.stateBefore());
node.replaceAtPredecessor(deopt);
GraphUtil.killCFG(node);
node.setCondition(LogicConstantNode.forBoolean(result, node.graph()), node.isNegated());
// Don't kill this branch immediately, see `processGuard`.
}
debug.log("Kill fixed guard guard");
return true;
@ -368,11 +373,10 @@ public class ConditionalEliminationPhase extends BasePhase<PhaseContext> {
protected void processIf(IfNode node) {
tryProveCondition(node.condition(), (guard, result, guardedValueStamp, newInput) -> {
node.setCondition(LogicConstantNode.forBoolean(result, node.graph()));
AbstractBeginNode survivingSuccessor = node.getSuccessor(result);
survivingSuccessor.replaceAtUsages(InputType.Guard, guard.asNode());
survivingSuccessor.replaceAtPredecessor(null);
node.replaceAtPredecessor(survivingSuccessor);
GraphUtil.killCFG(node);
// Don't kill the other branch immediately, see `processGuard`.
counterIfsKilled.increment(debug);
return true;
});
@ -524,8 +528,7 @@ public class ConditionalEliminationPhase extends BasePhase<PhaseContext> {
if (input == null) {
input = valueAt;
}
ValueNode valueNode = graph.maybeAddOrUnique(PiNode.create(input, curBestStamp, (ValueNode) infoElement.guard));
valueAt = valueNode;
valueAt = graph.maybeAddOrUnique(PiNode.create(input, curBestStamp, (ValueNode) infoElement.guard));
}
newPhi.addInput(valueAt);
}

View File

@ -41,7 +41,6 @@ import jdk.internal.vm.compiler.collections.Equivalence;
import jdk.internal.vm.compiler.collections.UnmodifiableEconomicMap;
import jdk.internal.vm.compiler.collections.UnmodifiableMapCursor;
import org.graalvm.compiler.api.replacements.MethodSubstitution;
import org.graalvm.compiler.api.replacements.Snippet;
import org.graalvm.compiler.core.common.GraalOptions;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.core.common.type.StampFactory;
@ -674,12 +673,12 @@ public class InliningUtil extends ValueMergeUtil {
@SuppressWarnings("try")
private static void updateSourcePositions(Invoke invoke, StructuredGraph inlineGraph, UnmodifiableEconomicMap<Node, Node> duplicates, boolean isSub, Mark mark) {
FixedNode invokeNode = invoke.asNode();
boolean isSubstitution = isSub || inlineGraph.method().getAnnotation(MethodSubstitution.class) != null || inlineGraph.method().getAnnotation(Snippet.class) != null;
StructuredGraph invokeGraph = invokeNode.graph();
assert !invokeGraph.trackNodeSourcePosition() || inlineGraph.trackNodeSourcePosition() ||
isSubstitution : String.format("trackNodeSourcePosition mismatch %s %s != %s %s", invokeGraph, invokeGraph.trackNodeSourcePosition(), inlineGraph,
inlineGraph.trackNodeSourcePosition());
if (invokeGraph.trackNodeSourcePosition() && invoke.stateAfter() != null) {
boolean isSubstitution = isSub || inlineGraph.isSubstitution();
assert !invokeGraph.trackNodeSourcePosition() || inlineGraph.trackNodeSourcePosition() ||
isSubstitution : String.format("trackNodeSourcePosition mismatch %s %s != %s %s", invokeGraph, invokeGraph.trackNodeSourcePosition(), inlineGraph,
inlineGraph.trackNodeSourcePosition());
final NodeSourcePosition invokePos = invoke.asNode().getNodeSourcePosition();
updateSourcePosition(invokeGraph, duplicates, mark, invokePos, isSubstitution);
}

View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 2011, 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.
*/
package org.graalvm.compiler.phases.common.jmx;
import java.util.Collection;
public interface HotSpotMBeanOperationProvider {
<T> void registerOperations(Class<T> clazz, Collection<? super T> ops);
Object invoke(String actionName, Object[] params, String[] signature);
}

View File

@ -32,6 +32,7 @@ import org.graalvm.compiler.phases.util.Providers;
import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.meta.MetaAccessProvider;
import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
public class PhaseContext {
@ -41,19 +42,22 @@ public class PhaseContext {
private final LoweringProvider lowerer;
private final Replacements replacements;
private final StampProvider stampProvider;
private final ForeignCallsProvider foreignCalls;
public PhaseContext(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, ConstantFieldProvider constantFieldProvider, LoweringProvider lowerer, Replacements replacements,
StampProvider stampProvider) {
StampProvider stampProvider, ForeignCallsProvider foreignCalls) {
this.metaAccess = metaAccess;
this.constantReflection = constantReflection;
this.constantFieldProvider = constantFieldProvider;
this.lowerer = lowerer;
this.replacements = replacements;
this.stampProvider = stampProvider;
this.foreignCalls = foreignCalls;
}
public PhaseContext(Providers providers) {
this(providers.getMetaAccess(), providers.getConstantReflection(), providers.getConstantFieldProvider(), providers.getLowerer(), providers.getReplacements(), providers.getStampProvider());
this(providers.getMetaAccess(), providers.getConstantReflection(), providers.getConstantFieldProvider(), providers.getLowerer(), providers.getReplacements(), providers.getStampProvider(),
providers.getForeignCalls());
}
public MetaAccessProvider getMetaAccess() {
@ -80,4 +84,7 @@ public class PhaseContext {
return stampProvider;
}
public ForeignCallsProvider getForeignCalls() {
return foreignCalls;
}
}

View File

@ -140,7 +140,7 @@ public class PEGraphDecoderTest extends GraalCompilerTest {
CachingPEGraphDecoder decoder = new CachingPEGraphDecoder(getTarget().arch, targetGraph, getProviders(), graphBuilderConfig, OptimisticOptimizations.NONE, AllowAssumptions.YES,
null, null, new InlineInvokePlugin[]{new InlineAll()}, null, null, null, null);
decoder.decode(testMethod, false);
decoder.decode(testMethod, false, false);
debug.dump(DebugContext.BASIC_LEVEL, targetGraph, "Target Graph");
targetGraph.verify();

View File

@ -83,9 +83,15 @@ public class CachingPEGraphDecoder extends PEGraphDecoder {
}
@SuppressWarnings("try")
private EncodedGraph createGraph(ResolvedJavaMethod method, ResolvedJavaMethod originalMethod, BytecodeProvider intrinsicBytecodeProvider) {
StructuredGraph graphToEncode = new StructuredGraph.Builder(options, debug, allowAssumptions).useProfilingInfo(false).trackNodeSourcePosition(
graphBuilderConfig.trackNodeSourcePosition()).method(method).build();
private EncodedGraph createGraph(ResolvedJavaMethod method, ResolvedJavaMethod originalMethod, BytecodeProvider intrinsicBytecodeProvider, boolean isSubstitution) {
// @formatter:off
StructuredGraph graphToEncode = new StructuredGraph.Builder(options, debug, allowAssumptions).
useProfilingInfo(false).
trackNodeSourcePosition(graphBuilderConfig.trackNodeSourcePosition()).
method(method).
setIsSubstitution(isSubstitution).
build();
// @formatter:on
try (DebugContext.Scope scope = debug.scope("createGraph", graphToEncode)) {
IntrinsicContext initialIntrinsicContext = intrinsicBytecodeProvider != null ? new IntrinsicContext(originalMethod, method, intrinsicBytecodeProvider, INLINE_AFTER_PARSING) : null;
GraphBuilderPhase.Instance graphBuilderPhaseInstance = createGraphBuilderPhaseInstance(initialIntrinsicContext);
@ -110,10 +116,11 @@ public class CachingPEGraphDecoder extends PEGraphDecoder {
}
@Override
protected EncodedGraph lookupEncodedGraph(ResolvedJavaMethod method, ResolvedJavaMethod originalMethod, BytecodeProvider intrinsicBytecodeProvider, boolean trackNodeSourcePosition) {
protected EncodedGraph lookupEncodedGraph(ResolvedJavaMethod method, ResolvedJavaMethod originalMethod, BytecodeProvider intrinsicBytecodeProvider, boolean isSubstitution,
boolean trackNodeSourcePosition) {
EncodedGraph result = graphCache.get(method);
if (result == null && method.hasBytecodes()) {
result = createGraph(method, originalMethod, intrinsicBytecodeProvider);
result = createGraph(method, originalMethod, intrinsicBytecodeProvider, isSubstitution);
}
return result;
}

View File

@ -94,7 +94,7 @@ public class IntrinsicGraphBuilder implements GraphBuilderContext, Receiver {
this.stampProvider = stampProvider;
this.code = code;
this.method = code.getMethod();
this.graph = new StructuredGraph.Builder(options, debug, allowAssumptions).method(method).build();
this.graph = new StructuredGraph.Builder(options, debug, allowAssumptions).method(method).setIsSubstitution(true).build();
this.graph.setTrackNodeSourcePosition();
this.invokeBci = invokeBci;
this.lastInstr = graph.start();

View File

@ -551,8 +551,8 @@ public abstract class PEGraphDecoder extends SimplifyingGraphDecoder {
}
}
public void decode(ResolvedJavaMethod method, boolean trackNodeSourcePosition) {
PEMethodScope methodScope = new PEMethodScope(graph, null, null, lookupEncodedGraph(method, null, null, trackNodeSourcePosition), method, null, 0, loopExplosionPlugin, null);
public void decode(ResolvedJavaMethod method, boolean isSubstitution, boolean trackNodeSourcePosition) {
PEMethodScope methodScope = new PEMethodScope(graph, null, null, lookupEncodedGraph(method, null, null, isSubstitution, trackNodeSourcePosition), method, null, 0, loopExplosionPlugin, null);
decode(createInitialLoopScope(methodScope, null));
cleanupGraph(methodScope);
@ -783,7 +783,9 @@ public abstract class PEGraphDecoder extends SimplifyingGraphDecoder {
return null;
}
ResolvedJavaMethod inlineMethod = inlineInfo.getMethodToInline();
EncodedGraph graphToInline = lookupEncodedGraph(inlineMethod, inlineInfo.getOriginalMethod(), inlineInfo.getIntrinsicBytecodeProvider(), graph.trackNodeSourcePosition());
ResolvedJavaMethod originalMethod = inlineInfo.getOriginalMethod();
boolean isSubstitution = originalMethod != null && !originalMethod.equals(inlineMethod);
EncodedGraph graphToInline = lookupEncodedGraph(inlineMethod, originalMethod, inlineInfo.getIntrinsicBytecodeProvider(), isSubstitution, graph.trackNodeSourcePosition());
if (graphToInline == null) {
return null;
}
@ -1052,7 +1054,8 @@ public abstract class PEGraphDecoder extends SimplifyingGraphDecoder {
}
}
protected abstract EncodedGraph lookupEncodedGraph(ResolvedJavaMethod method, ResolvedJavaMethod originalMethod, BytecodeProvider intrinsicBytecodeProvider, boolean trackNodeSourcePosition);
protected abstract EncodedGraph lookupEncodedGraph(ResolvedJavaMethod method, ResolvedJavaMethod originalMethod, BytecodeProvider intrinsicBytecodeProvider, boolean isSubstitution,
boolean trackNodeSourcePosition);
@Override
protected void handleFixedNode(MethodScope s, LoopScope loopScope, int nodeOrderId, FixedNode node) {

View File

@ -429,10 +429,16 @@ public class ReplacementsImpl implements Replacements, InlineInvokePlugin {
@SuppressWarnings("try")
protected StructuredGraph buildInitialGraph(DebugContext debug, BytecodeProvider bytecodeProvider, final ResolvedJavaMethod methodToParse, Object[] args, boolean trackNodeSourcePosition,
NodeSourcePosition replaceePosition) {
// @formatter:off
// Replacements cannot have optimistic assumptions since they have
// to be valid for the entire run of the VM.
final StructuredGraph graph = new StructuredGraph.Builder(replacements.options, debug).method(methodToParse).trackNodeSourcePosition(trackNodeSourcePosition).callerContext(
replaceePosition).build();
final StructuredGraph graph = new StructuredGraph.Builder(replacements.options, debug).
method(methodToParse).
trackNodeSourcePosition(trackNodeSourcePosition).
callerContext(replaceePosition).
setIsSubstitution(true).
build();
// @formatter:on
// Replacements are not user code so they do not participate in unsafe access
// tracking

View File

@ -723,7 +723,7 @@ public class SnippetTemplate {
// Copy snippet graph, replacing constant parameters with given arguments
final StructuredGraph snippetCopy = new StructuredGraph.Builder(options, debug).name(snippetGraph.name).method(snippetGraph.method()).trackNodeSourcePosition(
snippetGraph.trackNodeSourcePosition()).build();
snippetGraph.trackNodeSourcePosition()).setIsSubstitution(true).build();
assert !GraalOptions.TrackNodeSourcePosition.getValue(options) || snippetCopy.trackNodeSourcePosition();
if (providers.getCodeCache() != null && providers.getCodeCache().shouldDebugNonSafepoints()) {
snippetCopy.setTrackNodeSourcePosition();

View File

@ -155,7 +155,7 @@ public abstract class MacroNode extends FixedWithNextNode implements Lowerable,
@SuppressWarnings("try")
protected StructuredGraph lowerReplacement(final StructuredGraph replacementGraph, LoweringTool tool) {
final PhaseContext c = new PhaseContext(tool.getMetaAccess(), tool.getConstantReflection(), tool.getConstantFieldProvider(), tool.getLowerer(), tool.getReplacements(),
tool.getStampProvider());
tool.getStampProvider(), null);
if (!graph().hasValueProxies()) {
new RemoveValueProxyPhase().apply(replacementGraph);
}

View File

@ -211,9 +211,9 @@ public final class GraphOutput<G, M> implements Closeable {
* <p>
* Both GraphOutput (the {@code parent} and the returned one) has to be used in
* synchronization - e.g. only one
* {@link #beginGroup(java.lang.Object, java.lang.String, java.lang.String, java.lang.Object, int, java.util.Map)
* begin}, {@link #endGroup() end} of group or
* {@link #print(java.lang.Object, java.util.Map, int, java.lang.String, java.lang.Object...)
* {@link GraphOutput#beginGroup(java.lang.Object, java.lang.String, java.lang.String, java.lang.Object, int, java.util.Map)
* begin}, {@link GraphOutput#endGroup() end} of group or
* {@link GraphOutput#print(java.lang.Object, java.util.Map, int, java.lang.String, java.lang.Object...)
* printing} can be on at a given moment.
*
* @param parent the output to inherit {@code channel} and protocol version from