1 /* 2 * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 25 package org.graalvm.compiler.hotspot.sparc; 26 27 import static jdk.vm.ci.code.ValueUtil.asRegister; 28 import static jdk.vm.ci.sparc.SPARC.g0; 29 30 import org.graalvm.compiler.asm.sparc.SPARCAddress; 31 import org.graalvm.compiler.asm.sparc.SPARCMacroAssembler; 32 import org.graalvm.compiler.asm.sparc.SPARCMacroAssembler.ScratchRegister; 33 import org.graalvm.compiler.core.common.LIRKind; 34 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; 35 import org.graalvm.compiler.hotspot.HotSpotDebugInfoBuilder; 36 import org.graalvm.compiler.lir.LIRFrameState; 37 import org.graalvm.compiler.lir.LIRInstructionClass; 38 import org.graalvm.compiler.lir.Opcode; 39 import org.graalvm.compiler.lir.asm.CompilationResultBuilder; 40 import org.graalvm.compiler.lir.gen.LIRGeneratorTool; 41 import org.graalvm.compiler.lir.sparc.SPARCLIRInstruction; 42 43 import jdk.vm.ci.code.Register; 44 import jdk.vm.ci.code.ValueUtil; 45 import jdk.vm.ci.code.site.InfopointReason; 46 import jdk.vm.ci.meta.AllocatableValue; 47 import jdk.vm.ci.meta.Value; 48 49 /** 50 * Emits a safepoint poll. 51 */ 52 @Opcode("SAFEPOINT") 53 public class SPARCHotSpotSafepointOp extends SPARCLIRInstruction { 54 public static final LIRInstructionClass<SPARCHotSpotSafepointOp> TYPE = LIRInstructionClass.create(SPARCHotSpotSafepointOp.class); 55 public static final SizeEstimate SIZE = SizeEstimate.create(9); 56 57 @State protected LIRFrameState state; 58 @Use({OperandFlag.REG, OperandFlag.ILLEGAL}) AllocatableValue safepointPollAddress; 59 private final GraalHotSpotVMConfig config; 60 private final Register thread; 61 62 public SPARCHotSpotSafepointOp(LIRFrameState state, GraalHotSpotVMConfig config, Register thread, LIRGeneratorTool tool) { 63 super(TYPE, SIZE); 64 this.state = state; 65 this.config = config; 66 this.thread = thread; 67 SPARCHotSpotLIRGenerator lirGen = (SPARCHotSpotLIRGenerator) tool; 68 safepointPollAddress = lirGen.getSafepointAddressValue(); 69 } 70 71 @Override 72 public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { 73 emitCode(crb, masm, config, false, state, thread, safepointPollAddress); 74 } 75 76 public static void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm, GraalHotSpotVMConfig config, boolean atReturn, LIRFrameState state, Register thread, 77 Value safepointPollAddress) { 78 if (config.threadLocalHandshakes) { 79 emitThreadLocalPoll(crb, masm, config, atReturn, state, thread); 80 } else { 81 emitGlobalPoll(crb, masm, config, atReturn, state, asRegister(safepointPollAddress)); 82 } 83 } 84 85 /** 86 * Emit a global safepoint poll. 87 */ 88 private static void emitGlobalPoll(CompilationResultBuilder crb, SPARCMacroAssembler masm, GraalHotSpotVMConfig config, boolean atReturn, LIRFrameState state, Register safepointPollAddress) { 89 crb.recordMark(atReturn ? config.MARKID_POLL_RETURN_FAR : config.MARKID_POLL_FAR); 90 if (state != null) { 91 final int pos = masm.position(); 92 crb.recordInfopoint(pos, state, InfopointReason.SAFEPOINT); 93 } 94 masm.ldx(new SPARCAddress(safepointPollAddress, 0), g0); 95 } 96 97 /** 98 * Emit a thread-local safepoint poll. 99 */ 100 private static void emitThreadLocalPoll(CompilationResultBuilder crb, SPARCMacroAssembler masm, GraalHotSpotVMConfig config, boolean atReturn, LIRFrameState state, Register thread) { 101 assert !atReturn || state == null : "state is unneeded at return"; 102 103 assert config.threadPollingPageOffset >= 0; 104 105 try (ScratchRegister scratchReg = masm.getScratchRegister()) { 106 Register scratch = scratchReg.getRegister(); 107 108 masm.ldx(new SPARCAddress(thread, config.threadPollingPageOffset), scratch); 109 110 crb.recordMark(atReturn ? config.MARKID_POLL_RETURN_FAR : config.MARKID_POLL_FAR); 111 if (state != null) { 112 final int pos = masm.position(); 113 crb.recordInfopoint(pos, state, InfopointReason.SAFEPOINT); 114 } 115 masm.ldx(new SPARCAddress(scratch, 0), g0); 116 } 117 } 118 119 static AllocatableValue getSafepointAddressValue(SPARCHotSpotLIRGenerator gen) { 120 if (gen.config.threadLocalHandshakes) { 121 return Value.ILLEGAL; 122 } else { 123 return gen.newVariable(LIRKind.value(gen.target().arch.getWordKind())); 124 } 125 } 126 127 static void emitPrologue(SPARCHotSpotNodeLIRBuilder lir, SPARCHotSpotLIRGenerator gen) { 128 if (!gen.config.threadLocalHandshakes) { 129 AllocatableValue var = gen.getSafepointAddressValue(); 130 lir.append(new SPARCHotSpotSafepointOp.SPARCLoadSafepointPollAddress(var, gen.config)); 131 gen.append(((HotSpotDebugInfoBuilder) lir.getDebugInfoBuilder()).lockStack()); 132 } 133 } 134 135 public static class SPARCLoadSafepointPollAddress extends SPARCLIRInstruction { 136 public static final LIRInstructionClass<SPARCLoadSafepointPollAddress> TYPE = LIRInstructionClass.create(SPARCLoadSafepointPollAddress.class); 137 public static final SizeEstimate SIZE = SizeEstimate.create(2); 138 139 @Def({OperandFlag.REG}) protected AllocatableValue result; 140 private final GraalHotSpotVMConfig config; 141 142 public SPARCLoadSafepointPollAddress(AllocatableValue result, GraalHotSpotVMConfig config) { 143 super(TYPE, SIZE); 144 this.result = result; 145 this.config = config; 146 } 147 148 @Override 149 public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { 150 masm.setx(config.safepointPollingAddress, ValueUtil.asRegister(result), false); 151 } 152 } 153 }