--- /dev/null 2016-05-31 09:42:47.975716356 -0700 +++ new/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java 2016-12-09 00:49:00.627048421 -0800 @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2013, 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.sparc; + +import static org.graalvm.compiler.hotspot.HotSpotBackend.EXCEPTION_HANDLER_IN_CALLER; +import static jdk.vm.ci.sparc.SPARC.g5; +import static jdk.vm.ci.sparc.SPARC.o7; + +import org.graalvm.compiler.core.common.LIRKind; +import org.graalvm.compiler.core.common.spi.ForeignCallLinkage; +import org.graalvm.compiler.core.gen.DebugInfoBuilder; +import org.graalvm.compiler.core.sparc.SPARCNodeLIRBuilder; +import org.graalvm.compiler.core.sparc.SPARCNodeMatchRules; +import org.graalvm.compiler.debug.Debug; +import org.graalvm.compiler.hotspot.HotSpotDebugInfoBuilder; +import org.graalvm.compiler.hotspot.HotSpotLIRGenerator; +import org.graalvm.compiler.hotspot.HotSpotLockStack; +import org.graalvm.compiler.hotspot.HotSpotNodeLIRBuilder; +import org.graalvm.compiler.hotspot.nodes.DirectCompareAndSwapNode; +import org.graalvm.compiler.hotspot.nodes.HotSpotDirectCallTargetNode; +import org.graalvm.compiler.hotspot.nodes.HotSpotIndirectCallTargetNode; +import org.graalvm.compiler.lir.LIRFrameState; +import org.graalvm.compiler.lir.Variable; +import org.graalvm.compiler.lir.gen.LIRGeneratorTool; +import org.graalvm.compiler.lir.sparc.SPARCBreakpointOp; +import org.graalvm.compiler.lir.sparc.SPARCMove.CompareAndSwapOp; +import org.graalvm.compiler.nodes.BreakpointNode; +import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind; +import org.graalvm.compiler.nodes.DirectCallTargetNode; +import org.graalvm.compiler.nodes.FullInfopointNode; +import org.graalvm.compiler.nodes.IndirectCallTargetNode; +import org.graalvm.compiler.nodes.SafepointNode; +import org.graalvm.compiler.nodes.StructuredGraph; +import org.graalvm.compiler.nodes.ValueNode; +import org.graalvm.compiler.nodes.spi.NodeValueMap; + +import jdk.vm.ci.code.BytecodeFrame; +import jdk.vm.ci.code.CallingConvention; +import jdk.vm.ci.code.Register; +import jdk.vm.ci.code.RegisterValue; +import jdk.vm.ci.hotspot.HotSpotCallingConventionType; +import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod; +import jdk.vm.ci.meta.AllocatableValue; +import jdk.vm.ci.meta.JavaType; +import jdk.vm.ci.meta.Value; +import jdk.vm.ci.sparc.SPARCKind; + +public class SPARCHotSpotNodeLIRBuilder extends SPARCNodeLIRBuilder implements HotSpotNodeLIRBuilder { + + public SPARCHotSpotNodeLIRBuilder(StructuredGraph graph, LIRGeneratorTool lirGen, SPARCNodeMatchRules nodeMatchRules) { + super(graph, lirGen, nodeMatchRules); + assert gen instanceof SPARCHotSpotLIRGenerator; + assert getDebugInfoBuilder() instanceof HotSpotDebugInfoBuilder; + ((SPARCHotSpotLIRGenerator) gen).setDebugInfoBuilder(((HotSpotDebugInfoBuilder) getDebugInfoBuilder())); + } + + @Override + protected DebugInfoBuilder createDebugInfoBuilder(StructuredGraph graph, NodeValueMap nodeValueMap) { + HotSpotLockStack lockStack = new HotSpotLockStack(gen.getResult().getFrameMapBuilder(), LIRKind.value(SPARCKind.XWORD)); + return new HotSpotDebugInfoBuilder(nodeValueMap, lockStack, (HotSpotLIRGenerator) gen); + } + + private SPARCHotSpotLIRGenerator getGen() { + return (SPARCHotSpotLIRGenerator) gen; + } + + @Override + public void visitSafepointNode(SafepointNode i) { + LIRFrameState info = state(i); + append(new SPARCHotSpotSafepointOp(info, getGen().config, gen)); + } + + @Override + public void visitDirectCompareAndSwap(DirectCompareAndSwapNode x) { + AllocatableValue address = gen.asAllocatable(operand(x.getAddress())); + AllocatableValue cmpValue = gen.asAllocatable(operand(x.expectedValue())); + AllocatableValue newValue = gen.asAllocatable(operand(x.newValue())); + assert cmpValue.getValueKind().equals(newValue.getValueKind()); + + Variable result = gen.newVariable(newValue.getValueKind()); + append(new CompareAndSwapOp(result, address, cmpValue, newValue)); + setResult(x, result); + } + + @Override + protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { + InvokeKind invokeKind = ((HotSpotDirectCallTargetNode) callTarget).invokeKind(); + if (invokeKind.isIndirect()) { + append(new SPARCHotspotDirectVirtualCallOp(callTarget.targetMethod(), result, parameters, temps, callState, invokeKind, getGen().config)); + } else { + assert invokeKind.isDirect(); + HotSpotResolvedJavaMethod resolvedMethod = (HotSpotResolvedJavaMethod) callTarget.targetMethod(); + assert resolvedMethod.isConcrete() : "Cannot make direct call to abstract method."; + append(new SPARCHotspotDirectStaticCallOp(callTarget.targetMethod(), result, parameters, temps, callState, invokeKind, getGen().config)); + } + } + + @Override + protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { + Value metaspaceMethodSrc = operand(((HotSpotIndirectCallTargetNode) callTarget).metaspaceMethod()); + AllocatableValue metaspaceMethod = g5.asValue(metaspaceMethodSrc.getValueKind()); + gen.emitMove(metaspaceMethod, metaspaceMethodSrc); + + Value targetAddressSrc = operand(callTarget.computedAddress()); + AllocatableValue targetAddress = o7.asValue(targetAddressSrc.getValueKind()); + gen.emitMove(targetAddress, targetAddressSrc); + append(new SPARCIndirectCallOp(callTarget.targetMethod(), result, parameters, temps, metaspaceMethod, targetAddress, callState, getGen().config)); + } + + @Override + public void emitPatchReturnAddress(ValueNode address) { + append(new SPARCHotSpotPatchReturnAddressOp(gen.load(operand(address)))); + } + + @Override + public void emitJumpToExceptionHandler(ValueNode address) { + append(new SPARCHotSpotJumpToExceptionHandlerOp(gen.load(operand(address)))); + } + + @Override + public void emitJumpToExceptionHandlerInCaller(ValueNode handlerInCallerPc, ValueNode exception, ValueNode exceptionPc) { + Variable handler = gen.load(operand(handlerInCallerPc)); + ForeignCallLinkage linkage = gen.getForeignCalls().lookupForeignCall(EXCEPTION_HANDLER_IN_CALLER); + CallingConvention linkageCc = linkage.getOutgoingCallingConvention(); + assert linkageCc.getArgumentCount() == 2; + RegisterValue exceptionFixed = (RegisterValue) linkageCc.getArgument(0); + RegisterValue exceptionPcFixed = (RegisterValue) linkageCc.getArgument(1); + gen.emitMove(exceptionFixed, operand(exception)); + gen.emitMove(exceptionPcFixed, operand(exceptionPc)); + Register thread = getGen().getProviders().getRegisters().getThreadRegister(); + SPARCHotSpotJumpToExceptionHandlerInCallerOp op = new SPARCHotSpotJumpToExceptionHandlerInCallerOp(handler, exceptionFixed, exceptionPcFixed, getGen().config.threadIsMethodHandleReturnOffset, + thread); + append(op); + } + + @Override + protected void emitPrologue(StructuredGraph graph) { + super.emitPrologue(graph); + AllocatableValue var = getGen().getSafepointAddressValue(); + append(new SPARCHotSpotSafepointOp.SPARCLoadSafepointPollAddress(var, getGen().config)); + getGen().append(((HotSpotDebugInfoBuilder) getDebugInfoBuilder()).lockStack()); + } + + @Override + public void visitFullInfopointNode(FullInfopointNode i) { + if (i.getState() != null && i.getState().bci == BytecodeFrame.AFTER_BCI) { + Debug.log("Ignoring InfopointNode for AFTER_BCI"); + } else { + super.visitFullInfopointNode(i); + } + } + + @Override + public void visitBreakpointNode(BreakpointNode node) { + JavaType[] sig = new JavaType[node.arguments().size()]; + for (int i = 0; i < sig.length; i++) { + sig[i] = node.arguments().get(i).stamp().javaType(gen.getMetaAccess()); + } + + Value[] parameters = visitInvokeArguments(gen.getResult().getFrameMapBuilder().getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCall, null, sig, gen), + node.arguments()); + append(new SPARCBreakpointOp(parameters)); + } +}