1/* 2 * Copyright (c) 2015, 2017, 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 */ 23package org.graalvm.compiler.hotspot.nodes; 24 25import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC; 26import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG; 27import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1; 28import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; 29 30import org.graalvm.compiler.api.replacements.Fold; 31import org.graalvm.compiler.api.replacements.Fold.InjectedParameter; 32import org.graalvm.compiler.core.common.type.Stamp; 33import org.graalvm.compiler.core.common.type.StampFactory; 34import org.graalvm.compiler.graph.Node; 35import org.graalvm.compiler.graph.NodeClass; 36import org.graalvm.compiler.graph.spi.Canonicalizable; 37import org.graalvm.compiler.graph.spi.CanonicalizerTool; 38import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; 39import org.graalvm.compiler.hotspot.HotSpotLIRGenerator; 40import org.graalvm.compiler.nodeinfo.NodeInfo; 41import org.graalvm.compiler.nodes.ConstantNode; 42import org.graalvm.compiler.nodes.calc.FloatingNode; 43import org.graalvm.compiler.nodes.spi.LIRLowerable; 44import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; 45 46import jdk.vm.ci.meta.JavaKind; 47import jdk.vm.ci.meta.Value; 48 49/** 50 * Represents {@link GraalHotSpotVMConfig} values that may change after compilation. 51 */ 52@NodeInfo(cycles = CYCLES_1, size = SIZE_1) 53public class GraalHotSpotVMConfigNode extends FloatingNode implements LIRLowerable, Canonicalizable { 54 public static final NodeClass<GraalHotSpotVMConfigNode> TYPE = NodeClass.create(GraalHotSpotVMConfigNode.class); 55 56 private final GraalHotSpotVMConfig config; 57 protected final int markId; 58 59 /** 60 * Constructor for {@link #areConfigValuesConstant()}. 61 * 62 * @param config 63 */ 64 public GraalHotSpotVMConfigNode(@InjectedNodeParameter GraalHotSpotVMConfig config) { 65 super(TYPE, StampFactory.forKind(JavaKind.Boolean)); 66 this.config = config; 67 this.markId = 0; 68 } 69 70 /** 71 * Constructor for node intrinsics below. 72 * 73 * @param config 74 * @param markId id of the config value 75 */ 76 public GraalHotSpotVMConfigNode(@InjectedNodeParameter Stamp stamp, @InjectedNodeParameter GraalHotSpotVMConfig config, int markId) { 77 super(TYPE, stamp); 78 this.config = config; 79 this.markId = markId; 80 } 81 82 /** 83 * Constructor with explicit type specification. 84 * 85 * @param config 86 * @param markId id of the config value 87 * @param kind explicit type of the node 88 */ 89 public GraalHotSpotVMConfigNode(GraalHotSpotVMConfig config, int markId, JavaKind kind) { 90 super(TYPE, StampFactory.forKind(kind)); 91 this.config = config; 92 this.markId = markId; 93 } 94 95 @Override 96 public void generate(NodeLIRBuilderTool generator) { 97 Value res = ((HotSpotLIRGenerator) generator.getLIRGeneratorTool()).emitLoadConfigValue(markId, generator.getLIRGeneratorTool().getLIRKind(stamp)); 98 generator.setResult(this, res); 99 } 100 101 @NodeIntrinsic 102 private static native boolean areConfigValuesConstant(); 103 104 @NodeIntrinsic 105 private static native long loadLongConfigValue(@ConstantNodeParameter int markId); 106 107 @NodeIntrinsic 108 private static native int loadIntConfigValue(@ConstantNodeParameter int markId); 109 110 @NodeIntrinsic 111 private static native byte loadByteConfigValue(@ConstantNodeParameter int markId); 112 113 public static long cardTableAddress() { 114 return loadLongConfigValue(cardTableAddressMark(INJECTED_VMCONFIG)); 115 } 116 117 public static boolean isCardTableAddressConstant() { 118 return areConfigValuesConstant(); 119 } 120 121 public static long heapTopAddress() { 122 return loadLongConfigValue(heapTopAddressMark(INJECTED_VMCONFIG)); 123 } 124 125 public static long heapEndAddress() { 126 return loadLongConfigValue(heapEndAddressMark(INJECTED_VMCONFIG)); 127 } 128 129 public static long crcTableAddress() { 130 return loadLongConfigValue(crcTableAddressMark(INJECTED_VMCONFIG)); 131 } 132 133 public static int logOfHeapRegionGrainBytes() { 134 return loadIntConfigValue(logOfHeapRegionGrainBytesMark(INJECTED_VMCONFIG)); 135 } 136 137 public static boolean inlineContiguousAllocationSupported() { 138 return loadByteConfigValue(inlineContiguousAllocationSupportedMark(INJECTED_VMCONFIG)) != 0; 139 } 140 141 @Fold 142 public static int cardTableAddressMark(@InjectedParameter GraalHotSpotVMConfig config) { 143 return config.MARKID_CARD_TABLE_ADDRESS; 144 } 145 146 @Fold 147 public static int heapTopAddressMark(@InjectedParameter GraalHotSpotVMConfig config) { 148 return config.MARKID_HEAP_TOP_ADDRESS; 149 } 150 151 @Fold 152 public static int heapEndAddressMark(@InjectedParameter GraalHotSpotVMConfig config) { 153 return config.MARKID_HEAP_END_ADDRESS; 154 } 155 156 @Fold 157 public static int crcTableAddressMark(@InjectedParameter GraalHotSpotVMConfig config) { 158 return config.MARKID_CRC_TABLE_ADDRESS; 159 } 160 161 @Fold 162 public static int logOfHeapRegionGrainBytesMark(@InjectedParameter GraalHotSpotVMConfig config) { 163 return config.MARKID_LOG_OF_HEAP_REGION_GRAIN_BYTES; 164 } 165 166 @Fold 167 public static int inlineContiguousAllocationSupportedMark(@InjectedParameter GraalHotSpotVMConfig config) { 168 return config.MARKID_INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED; 169 } 170 171 @Override 172 public Node canonical(CanonicalizerTool tool) { 173 if (markId == 0) { 174 return ConstantNode.forBoolean(!GeneratePIC.getValue(tool.getOptions())); 175 } 176 if (!GeneratePIC.getValue(tool.getOptions())) { 177 if (markId == config.MARKID_CARD_TABLE_ADDRESS) { 178 return ConstantNode.forLong(config.cardtableStartAddress); 179 } else if (markId == config.MARKID_HEAP_TOP_ADDRESS) { 180 return ConstantNode.forLong(config.heapTopAddress); 181 } else if (markId == config.MARKID_HEAP_END_ADDRESS) { 182 return ConstantNode.forLong(config.heapEndAddress); 183 } else if (markId == config.MARKID_CRC_TABLE_ADDRESS) { 184 return ConstantNode.forLong(config.crcTableAddress); 185 } else if (markId == config.MARKID_LOG_OF_HEAP_REGION_GRAIN_BYTES) { 186 return ConstantNode.forInt(config.logOfHRGrainBytes); 187 } else if (markId == config.MARKID_INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED) { 188 return ConstantNode.forBoolean(config.inlineContiguousAllocationSupported); 189 } else { 190 assert false; 191 } 192 } 193 return this; 194 } 195} 196