< prev index next >
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotNodePlugin.java
Print this page
*** 1,7 ****
/*
! * Copyright (c) 2015, 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.
--- 1,7 ----
/*
! * Copyright (c) 2015, 2019, 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.
*** 22,71 ****
*/
package org.graalvm.compiler.hotspot.meta;
import static org.graalvm.compiler.core.common.GraalOptions.ImmutableCode;
import org.graalvm.compiler.core.common.type.StampPair;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.extended.GuardingNode;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderTool;
import org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin;
import org.graalvm.compiler.nodes.graphbuilderconf.NodePlugin;
import org.graalvm.compiler.nodes.graphbuilderconf.TypePlugin;
import org.graalvm.compiler.nodes.util.ConstantFoldUtil;
import org.graalvm.compiler.word.Word;
import org.graalvm.compiler.word.WordOperationPlugin;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.JavaTypeProfile;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
/**
! * This plugin handles the HotSpot-specific customizations of bytecode parsing:
! * <p>
! * {@link Word}-type rewriting for {@link GraphBuilderContext#parsingIntrinsic intrinsic} functions
! * (snippets and method substitutions), by forwarding to the {@link WordOperationPlugin}. Note that
! * we forward the {@link NodePlugin} and {@link TypePlugin} methods, but not the
* {@link InlineInvokePlugin} methods implemented by {@link WordOperationPlugin}. The latter is not
* necessary because HotSpot only uses the {@link Word} type in methods that are force-inlined,
! * i.e., there are never non-inlined invokes that involve the {@link Word} type.
! * <p>
! * Constant folding of field loads.
*/
public final class HotSpotNodePlugin implements NodePlugin, TypePlugin {
protected final WordOperationPlugin wordOperationPlugin;
! public HotSpotNodePlugin(WordOperationPlugin wordOperationPlugin) {
this.wordOperationPlugin = wordOperationPlugin;
}
@Override
public boolean canChangeStackKind(GraphBuilderContext b) {
if (b.parsingIntrinsic()) {
--- 22,98 ----
*/
package org.graalvm.compiler.hotspot.meta;
+ import static jdk.vm.ci.meta.DeoptimizationAction.None;
+ import static jdk.vm.ci.meta.DeoptimizationReason.TransferToInterpreter;
import static org.graalvm.compiler.core.common.GraalOptions.ImmutableCode;
+ import org.graalvm.compiler.core.common.CompilationIdentifier;
+ import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.core.common.type.StampPair;
+ import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
+ import org.graalvm.compiler.hotspot.HotSpotCompilationIdentifier;
+ import org.graalvm.compiler.hotspot.nodes.CurrentJavaThreadNode;
+ import org.graalvm.compiler.hotspot.word.HotSpotWordTypes;
import org.graalvm.compiler.nodes.ConstantNode;
+ import org.graalvm.compiler.nodes.FixedGuardNode;
+ import org.graalvm.compiler.nodes.FixedWithNextNode;
+ import org.graalvm.compiler.nodes.LogicNode;
+ import org.graalvm.compiler.nodes.NamedLocationIdentity;
+ import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
+ import org.graalvm.compiler.nodes.calc.IntegerEqualsNode;
import org.graalvm.compiler.nodes.extended.GuardingNode;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderTool;
import org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin;
import org.graalvm.compiler.nodes.graphbuilderconf.NodePlugin;
import org.graalvm.compiler.nodes.graphbuilderconf.TypePlugin;
+ import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType;
+ import org.graalvm.compiler.nodes.memory.ReadNode;
+ import org.graalvm.compiler.nodes.memory.address.AddressNode;
+ import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
import org.graalvm.compiler.nodes.util.ConstantFoldUtil;
import org.graalvm.compiler.word.Word;
import org.graalvm.compiler.word.WordOperationPlugin;
+ import jdk.internal.vm.compiler.word.LocationIdentity;
+ import jdk.vm.ci.hotspot.HotSpotCompilationRequest;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.JavaTypeProfile;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
+ import java.lang.reflect.Field;
+ import sun.misc.Unsafe;
+
/**
! * This plugin does HotSpot-specific customization of bytecode parsing:
! * <ul>
! * <li>{@link Word}-type rewriting for {@link GraphBuilderContext#parsingIntrinsic intrinsic}
! * functions (snippets and method substitutions), by forwarding to the {@link WordOperationPlugin}.
! * Note that we forward the {@link NodePlugin} and {@link TypePlugin} methods, but not the
* {@link InlineInvokePlugin} methods implemented by {@link WordOperationPlugin}. The latter is not
* necessary because HotSpot only uses the {@link Word} type in methods that are force-inlined,
! * i.e., there are never non-inlined invokes that involve the {@link Word} type.</li>
! * <li>Constant folding of field loads.</li>
! * </ul>
*/
public final class HotSpotNodePlugin implements NodePlugin, TypePlugin {
protected final WordOperationPlugin wordOperationPlugin;
+ private final GraalHotSpotVMConfig config;
+ private final HotSpotWordTypes wordTypes;
! public HotSpotNodePlugin(WordOperationPlugin wordOperationPlugin, GraalHotSpotVMConfig config, HotSpotWordTypes wordTypes) {
this.wordOperationPlugin = wordOperationPlugin;
+ this.config = config;
+ this.wordTypes = wordTypes;
}
@Override
public boolean canChangeStackKind(GraphBuilderContext b) {
if (b.parsingIntrinsic()) {
*** 178,183 ****
--- 205,264 ----
if (b.parsingIntrinsic() && wordOperationPlugin.handleInstanceOf(b, object, type, profile)) {
return true;
}
return false;
}
+
+ @Override
+ public FixedWithNextNode instrumentExceptionDispatch(StructuredGraph graph, FixedWithNextNode afterExceptionLoaded) {
+ CompilationIdentifier id = graph.compilationId();
+ if (id instanceof HotSpotCompilationIdentifier) {
+ HotSpotCompilationRequest request = ((HotSpotCompilationIdentifier) id).getRequest();
+ if (request != null) {
+ long compileState = request.getJvmciEnv();
+ if (compileState != 0 &&
+ config.jvmciCompileStateCanPostOnExceptionsOffset != Integer.MIN_VALUE &&
+ config.javaThreadShouldPostOnExceptionsFlagOffset != Integer.MIN_VALUE) {
+ long canPostOnExceptionsOffset = compileState + config.jvmciCompileStateCanPostOnExceptionsOffset;
+ boolean canPostOnExceptions = UNSAFE.getByte(canPostOnExceptionsOffset) != 0;
+ if (canPostOnExceptions) {
+ // If the exception capability is set, then generate code
+ // to check the JavaThread.should_post_on_exceptions flag to see
+ // if we actually need to report exception events for the current
+ // thread. If not, take the fast path otherwise deoptimize.
+ CurrentJavaThreadNode thread = graph.unique(new CurrentJavaThreadNode(wordTypes.getWordKind()));
+ ValueNode offset = graph.unique(ConstantNode.forLong(config.javaThreadShouldPostOnExceptionsFlagOffset));
+ AddressNode address = graph.unique(new OffsetAddressNode(thread, offset));
+ ReadNode shouldPostException = graph.add(new ReadNode(address, JAVA_THREAD_SHOULD_POST_ON_EXCEPTIONS_FLAG_LOCATION, StampFactory.intValue(), BarrierType.NONE));
+ afterExceptionLoaded.setNext(shouldPostException);
+ ValueNode zero = graph.unique(ConstantNode.forInt(0));
+ LogicNode cond = graph.unique(new IntegerEqualsNode(shouldPostException, zero));
+ FixedGuardNode check = graph.add(new FixedGuardNode(cond, TransferToInterpreter, None, false));
+ shouldPostException.setNext(check);
+ return check;
+ }
+ }
+ }
+ }
+ return afterExceptionLoaded;
+ }
+
+ private static final LocationIdentity JAVA_THREAD_SHOULD_POST_ON_EXCEPTIONS_FLAG_LOCATION = NamedLocationIdentity.mutable("JavaThread::_should_post_on_exceptions_flag");
+
+ private static final Unsafe UNSAFE = initUnsafe();
+
+ private static Unsafe initUnsafe() {
+ try {
+ // Fast path when we are trusted.
+ return Unsafe.getUnsafe();
+ } catch (SecurityException se) {
+ // Slow path when we are not trusted.
+ try {
+ Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
+ theUnsafe.setAccessible(true);
+ return (Unsafe) theUnsafe.get(Unsafe.class);
+ } catch (Exception e) {
+ throw new RuntimeException("exception while trying to get Unsafe", e);
+ }
+ }
+ }
}
< prev index next >