use of org.graalvm.compiler.hotspot.replacements.HotSpotInvocationPluginHelper in project graal by oracle.
the class HotSpotGraphBuilderPlugins method registerClassPlugins.
private static void registerClassPlugins(Plugins plugins, GraalHotSpotVMConfig config, Replacements replacements) {
Registration r = new Registration(plugins.getInvocationPlugins(), Class.class, replacements);
r.register(new InvocationPlugin("getModifiers", Receiver.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
ValueNode klass = helper.readKlassFromClass(receiver.get());
// Primitive Class case
ValueNode nonNullKlass = helper.emitNullReturnGuard(klass, ConstantNode.forInt(Modifier.ABSTRACT | Modifier.FINAL | Modifier.PUBLIC), GraalDirectives.UNLIKELY_PROBABILITY);
// other return Klass::_modifier_flags
helper.emitFinalReturn(JavaKind.Int, helper.readKlassModifierFlags(nonNullKlass));
}
return true;
}
});
r.register(new InvocationPlugin("isInterface", Receiver.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
ValueNode klass = helper.readKlassFromClass(receiver.get());
// Primitive Class case returns false
ValueNode klassNonNull = helper.emitNullReturnGuard(klass, ConstantNode.forBoolean(false), GraalDirectives.UNLIKELY_PROBABILITY);
ValueNode accessFlags = helper.readKlassAccessFlags(klassNonNull);
// return (Klass::_access_flags & Modifier.INTERFACE) == 0 ? false : true
LogicNode test = IntegerTestNode.create(accessFlags, ConstantNode.forInt(Modifier.INTERFACE), NodeView.DEFAULT);
helper.emitFinalReturn(JavaKind.Boolean, ConditionalNode.create(test, ConstantNode.forBoolean(false), ConstantNode.forBoolean(true), NodeView.DEFAULT));
}
return true;
}
});
r.register(new InvocationPlugin("isPrimitive", Receiver.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
ValueNode klass = helper.readKlassFromClass(receiver.get());
LogicNode isNull = b.add(IsNullNode.create(klass));
b.addPush(JavaKind.Boolean, ConditionalNode.create(isNull, b.add(forBoolean(true)), b.add(forBoolean(false)), NodeView.DEFAULT));
}
return true;
}
});
r.register(new InvocationPlugin("getSuperclass", Receiver.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
ValueNode klass = helper.readKlassFromClass(receiver.get());
ConstantNode nullValue = ConstantNode.defaultForKind(JavaKind.Object);
// Primitive Class case returns null
PiNode klassNonNull = helper.emitNullReturnGuard(klass, nullValue, GraalDirectives.UNLIKELY_PROBABILITY);
// if ((Klass::_access_flags & Modifer.INTERCAE) != 0) return null
ValueNode accessFlags = helper.readKlassAccessFlags(klassNonNull);
LogicNode test = IntegerTestNode.create(accessFlags, ConstantNode.forInt(Modifier.INTERFACE), NodeView.DEFAULT);
helper.emitReturnIfNot(test, nullValue, GraalDirectives.UNLIKELY_PROBABILITY);
// Handle array Class case
// if (Klass::_layout_helper < 0) return Object.class
ValueNode layoutHelper = helper.klassLayoutHelper(klassNonNull);
ResolvedJavaType objectType = b.getMetaAccess().lookupJavaType(Object.class);
ValueNode objectClass = ConstantNode.forConstant(b.getConstantReflection().asJavaClass(objectType), b.getMetaAccess());
helper.emitReturnIf(layoutHelper, Condition.LT, ConstantNode.forInt(config.klassLayoutHelperNeutralValue), objectClass, GraalDirectives.UNLIKELY_PROBABILITY);
// Read Klass::_super
ValueNode superKlass = helper.readKlassSuperKlass(klassNonNull);
// Return null if super is null
PiNode superKlassNonNull = helper.emitNullReturnGuard(superKlass, nullValue, GraalDirectives.UNLIKELY_PROBABILITY);
// Convert Klass to Class and return
helper.emitFinalReturn(JavaKind.Object, new HubGetClassNode(b.getMetaAccess(), superKlassNonNull));
}
return true;
}
});
r.registerConditional(config.jvmAccIsHiddenClass != 0, new InvocationPlugin("isHidden", Receiver.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
ValueNode klass = helper.readKlassFromClass(receiver.get());
// Primitive Class case returns false
ValueNode nonNullKlass = helper.emitNullReturnGuard(klass, ConstantNode.forBoolean(false), GraalDirectives.UNLIKELY_PROBABILITY);
// return (Klass::_access_flags & jvmAccIsHiddenClass) == 0 ? false : true
ValueNode accessFlags = helper.readKlassAccessFlags(nonNullKlass);
LogicNode test = IntegerTestNode.create(accessFlags, ConstantNode.forInt(config.jvmAccIsHiddenClass), NodeView.DEFAULT);
helper.emitFinalReturn(JavaKind.Boolean, ConditionalNode.create(test, ConstantNode.forBoolean(false), ConstantNode.forBoolean(true), NodeView.DEFAULT));
}
return true;
}
});
}
use of org.graalvm.compiler.hotspot.replacements.HotSpotInvocationPluginHelper in project graal by oracle.
the class HotSpotGraphBuilderPlugins method registerReflectionPlugins.
private static void registerReflectionPlugins(InvocationPlugins plugins, Replacements replacements, GraalHotSpotVMConfig config) {
Registration r = new Registration(plugins, reflectionClass, replacements);
r.register(new InlineOnlyInvocationPlugin("getCallerClass") {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
b.addPush(JavaKind.Object, new HotSpotReflectionGetCallerClassNode(MacroParams.of(b, targetMethod)));
return true;
}
});
r.register(new InvocationPlugin("getClassAccessFlags", Class.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg) {
try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
ValueNode klass = helper.readKlassFromClass(b.nullCheckedValue(arg));
// Primitive Class case
ValueNode klassNonNull = helper.emitNullReturnGuard(klass, ConstantNode.forInt(Modifier.ABSTRACT | Modifier.FINAL | Modifier.PUBLIC), GraalDirectives.UNLIKELY_PROBABILITY);
// Return (Klass::_access_flags & jvmAccWrittenFlags)
ValueNode accessFlags = helper.readKlassAccessFlags(klassNonNull);
helper.emitFinalReturn(JavaKind.Int, new AndNode(accessFlags, ConstantNode.forInt(config.jvmAccWrittenFlags)));
}
return true;
}
});
}
use of org.graalvm.compiler.hotspot.replacements.HotSpotInvocationPluginHelper in project graal by oracle.
the class HotSpotGraphBuilderPlugins method registerThreadPlugins.
private static void registerThreadPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, Replacements replacements) {
Registration r = new Registration(plugins, Thread.class, replacements);
r.register(new InvocationPlugin("currentThread") {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
ValueNode value = helper.readCurrentThreadObject();
b.push(JavaKind.Object, value);
}
return true;
}
});
// This substitution is no longer in used when threadObj is a handle
r.registerConditional(config.osThreadInterruptedOffset != Integer.MAX_VALUE && !config.threadObjectFieldIsHandle, new InvocationPlugin("isInterrupted", Receiver.class, boolean.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode clearInterrupted) {
try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
ValueNode receiverThreadObject = receiver.get();
CurrentJavaThreadNode thread = b.add(new CurrentJavaThreadNode(helper.getWordKind()));
ValueNode currentThreadObject = helper.readCurrentThreadObject(thread);
// if (this != Thread.currentThread()) do fallback
helper.doFallbackIf(receiverThreadObject, NE, currentThreadObject, GraalDirectives.UNLIKELY_PROBABILITY);
ValueNode osThread = helper.readOsThread(thread);
ValueNode interrupted = helper.readOsThreadInterrupted(osThread);
// if (thread._osthread._isinterrupted == 0) return false
helper.emitReturnIf(interrupted, EQ, ConstantNode.forInt(0), ConstantNode.forBoolean(false), GraalDirectives.LIKELY_PROBABILITY);
// if (clearInterrupted) fallback to invoke
helper.doFallbackIf(clearInterrupted, EQ, ConstantNode.forBoolean(true), GraalDirectives.UNLIKELY_PROBABILITY);
// return interrupted == 0 ? false : true
LogicNode test = helper.createCompare(interrupted, CanonicalCondition.EQ, ConstantNode.forInt(0));
helper.emitFinalReturn(JavaKind.Boolean, ConditionalNode.create(test, ConstantNode.forBoolean(false), ConstantNode.forBoolean(true), NodeView.DEFAULT));
}
return true;
}
});
}
use of org.graalvm.compiler.hotspot.replacements.HotSpotInvocationPluginHelper in project graal by oracle.
the class HotSpotGraphBuilderPlugins method registerArrayPlugins.
private static void registerArrayPlugins(InvocationPlugins plugins, Replacements replacements, GraalHotSpotVMConfig config) {
Registration r = new Registration(plugins, Array.class, replacements);
r.setAllowOverwrite(true);
r.register(new InvocationPlugin("newInstance", Class.class, int.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode componentType, ValueNode length) {
try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
// If (componentType == null) then deopt
ValueNode nonNullComponentType = b.nullCheckedValue(componentType);
// Read Class.array_klass
ValueNode arrayClass = helper.loadArrayKlass(nonNullComponentType);
// Take the fallback path is the array klass is null
helper.doFallbackIf(IsNullNode.create(arrayClass), GraalDirectives.UNLIKELY_PROBABILITY);
// Otherwise perform the array allocation
helper.emitFinalReturn(JavaKind.Object, new DynamicNewArrayNode(nonNullComponentType, length, true));
}
return true;
}
});
}
use of org.graalvm.compiler.hotspot.replacements.HotSpotInvocationPluginHelper in project graal by oracle.
the class HotSpotGraphBuilderPlugins method registerStringPlugins.
private static void registerStringPlugins(InvocationPlugins plugins, Replacements replacements, WordTypes wordTypes, ArrayCopyForeignCalls foreignCalls, GraalHotSpotVMConfig vmConfig) {
final Registration utf16r = new Registration(plugins, "java.lang.StringUTF16", replacements);
utf16r.register(new InvocationPlugin("toBytes", char[].class, int.class, int.class) {
private static final int MAX_LENGTH = Integer.MAX_VALUE >> 1;
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value, ValueNode srcBegin, ValueNode length) {
try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, vmConfig)) {
helper.intrinsicRangeCheck(srcBegin, Condition.LT, ConstantNode.forInt(0));
helper.intrinsicRangeCheck(length, Condition.LT, ConstantNode.forInt(0));
helper.intrinsicRangeCheck(length, Condition.GT, ConstantNode.forInt(MAX_LENGTH));
ValueNode valueLength = b.add(new ArrayLengthNode(value));
ValueNode limit = b.add(new SubNode(valueLength, length));
helper.intrinsicRangeCheck(srcBegin, Condition.GT, limit);
ValueNode newArray = b.add(new NewArrayNode(b.getMetaAccess().lookupJavaType(Byte.TYPE), b.add(new LeftShiftNode(length, ConstantNode.forInt(1))), false));
b.addPush(JavaKind.Object, newArray);
// The stateAfter should include the value pushed, so push it first and then
// perform the call that fills in the array.
b.add(new ArrayCopyCallNode(foreignCalls, wordTypes, value, srcBegin, newArray, ConstantNode.forInt(0), length, JavaKind.Char, LocationIdentity.init(), false, true, true, vmConfig.heapWordSize));
}
return true;
}
});
utf16r.register(new InvocationPlugin("getChars", byte[].class, int.class, int.class, char[].class, int.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value, ValueNode srcBegin, ValueNode srcEnd, ValueNode dst, ValueNode dstBegin) {
try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, vmConfig)) {
ValueNode length = helper.sub(srcEnd, srcBegin);
helper.intrinsicRangeCheck(srcBegin, Condition.LT, ConstantNode.forInt(0));
helper.intrinsicRangeCheck(length, Condition.LT, ConstantNode.forInt(0));
ValueNode srcLimit = helper.sub(helper.shr(helper.length(value), 1), length);
helper.intrinsicRangeCheck(srcBegin, Condition.GT, srcLimit);
ValueNode limit = helper.sub(helper.length(dst), length);
helper.intrinsicRangeCheck(dstBegin, Condition.GT, limit);
b.add(new ArrayCopyCallNode(foreignCalls, wordTypes, value, srcBegin, dst, dstBegin, length, JavaKind.Char, JavaKind.Byte, JavaKind.Char, false, true, true, vmConfig.heapWordSize));
}
return true;
}
});
}
Aggregations