1 /* 2 * Copyright (c) 2013, 2015, 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 package org.graalvm.compiler.hotspot.amd64; 24 25 import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC; 26 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.HINT; 27 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG; 28 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK; 29 import static jdk.vm.ci.code.ValueUtil.asRegister; 30 import static jdk.vm.ci.code.ValueUtil.isRegister; 31 import static jdk.vm.ci.code.ValueUtil.isStackSlot; 32 33 import org.graalvm.compiler.asm.amd64.AMD64Address; 34 import org.graalvm.compiler.core.common.CompressEncoding; 35 import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler; 36 import org.graalvm.compiler.debug.GraalError; 37 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; 38 import org.graalvm.compiler.lir.LIRInstructionClass; 39 import org.graalvm.compiler.lir.StandardOp.LoadConstantOp; 40 import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction; 41 import org.graalvm.compiler.lir.asm.CompilationResultBuilder; 42 43 import jdk.vm.ci.code.Register; 44 import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant; 45 import jdk.vm.ci.hotspot.HotSpotObjectConstant; 46 import jdk.vm.ci.meta.AllocatableValue; 47 import jdk.vm.ci.meta.Constant; 48 49 public class AMD64HotSpotMove { 50 51 public static final class HotSpotLoadObjectConstantOp extends AMD64LIRInstruction implements LoadConstantOp { 52 public static final LIRInstructionClass<HotSpotLoadObjectConstantOp> TYPE = LIRInstructionClass.create(HotSpotLoadObjectConstantOp.class); 53 54 @Def({REG, STACK}) private AllocatableValue result; 55 private final HotSpotObjectConstant input; 56 57 public HotSpotLoadObjectConstantOp(AllocatableValue result, HotSpotObjectConstant input) { 58 super(TYPE); 59 this.result = result; 60 this.input = input; 61 } 62 63 @Override 64 public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { 65 if (GeneratePIC.getValue(crb.getOptions())) { 66 throw GraalError.shouldNotReachHere("Object constant load should not be happening directly"); 67 } 68 boolean compressed = input.isCompressed(); 69 if (crb.target.inlineObjects) { 70 crb.recordInlineDataInCode(input); 71 if (isRegister(result)) { 72 if (compressed) { 73 masm.movl(asRegister(result), 0xDEADDEAD); 74 } else { 75 masm.movq(asRegister(result), 0xDEADDEADDEADDEADL); 76 } 77 } else { 78 assert isStackSlot(result); 79 if (compressed) { 80 masm.movl((AMD64Address) crb.asAddress(result), 0xDEADDEAD); 81 } else { 82 throw GraalError.shouldNotReachHere("Cannot store 64-bit constants to memory"); 83 } 84 } 85 } else { 86 if (isRegister(result)) { 87 AMD64Address address = (AMD64Address) crb.recordDataReferenceInCode(input, compressed ? 4 : 8); 88 if (compressed) { 89 masm.movl(asRegister(result), address); 90 } else { 91 masm.movq(asRegister(result), address); 92 } 93 } else { 94 throw GraalError.shouldNotReachHere("Cannot directly store data patch to memory"); 95 } 96 } 97 } 98 99 @Override 100 public Constant getConstant() { 101 return input; 102 } 103 104 @Override 105 public AllocatableValue getResult() { 106 return result; 107 } 108 } 109 110 public static final class BaseMove extends AMD64LIRInstruction { 111 public static final LIRInstructionClass<BaseMove> TYPE = LIRInstructionClass.create(BaseMove.class); 112 113 @Def({REG, HINT}) protected AllocatableValue result; 114 private final GraalHotSpotVMConfig config; 115 116 public BaseMove(AllocatableValue result, GraalHotSpotVMConfig config) { 117 super(TYPE); 118 this.result = result; 119 this.config = config; 120 } 121 122 @Override 123 public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { 124 masm.movq(asRegister(result), masm.getPlaceholder(-1)); 125 crb.recordMark(config.MARKID_NARROW_KLASS_BASE_ADDRESS); 126 } 127 128 } 129 130 public static final class HotSpotLoadMetaspaceConstantOp extends AMD64LIRInstruction implements LoadConstantOp { 131 public static final LIRInstructionClass<HotSpotLoadMetaspaceConstantOp> TYPE = LIRInstructionClass.create(HotSpotLoadMetaspaceConstantOp.class); 132 133 @Def({REG, STACK}) private AllocatableValue result; 134 private final HotSpotMetaspaceConstant input; 135 136 public HotSpotLoadMetaspaceConstantOp(AllocatableValue result, HotSpotMetaspaceConstant input) { 137 super(TYPE); 138 this.result = result; 139 this.input = input; 140 } 141 142 @Override 143 public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { 144 if (GeneratePIC.getValue(crb.getOptions())) { 145 throw GraalError.shouldNotReachHere("Metaspace constant load should not be happening directly"); 146 } 147 boolean compressed = input.isCompressed(); 148 if (isRegister(result)) { 149 if (compressed) { 150 crb.recordInlineDataInCode(input); 151 masm.movl(asRegister(result), 0xDEADDEAD); 152 } else { 153 crb.recordInlineDataInCode(input); 154 masm.movq(asRegister(result), 0xDEADDEADDEADDEADL); 155 } 156 } else { 157 assert isStackSlot(result); 158 if (compressed) { 159 crb.recordInlineDataInCode(input); 160 masm.movl((AMD64Address) crb.asAddress(result), 0xDEADDEAD); 161 } else { 162 throw GraalError.shouldNotReachHere("Cannot store 64-bit constants to memory"); 163 } 164 } 165 } 166 167 @Override 168 public Constant getConstant() { 169 return input; 170 } 171 172 @Override 173 public AllocatableValue getResult() { 174 return result; 175 } 176 } 177 178 public static void decodeKlassPointer(CompilationResultBuilder crb, AMD64MacroAssembler masm, Register register, Register scratch, AMD64Address address, GraalHotSpotVMConfig config) { 179 CompressEncoding encoding = config.getKlassEncoding(); 180 masm.movl(register, address); 181 if (encoding.getShift() != 0) { 182 masm.shlq(register, encoding.getShift()); 183 } 184 boolean pic = GeneratePIC.getValue(crb.getOptions()); 185 if (pic || encoding.hasBase()) { 186 if (pic) { 187 masm.movq(scratch, masm.getPlaceholder(-1)); 188 crb.recordMark(config.MARKID_NARROW_KLASS_BASE_ADDRESS); 189 } else { 190 assert encoding.getBase() != 0; 191 masm.movq(scratch, encoding.getBase()); 192 } 193 masm.addq(register, scratch); 194 } 195 } 196 }