< 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 >