1 /* 2 * Copyright (c) 2011, 2019, 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.meta; 26 27 import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE; 28 import static org.graalvm.compiler.core.common.GraalOptions.AlwaysInlineVTableStubs; 29 import static org.graalvm.compiler.core.common.GraalOptions.InlineVTableStubs; 30 import static org.graalvm.compiler.core.common.GraalOptions.OmitHotExceptionStacktrace; 31 import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProviderImpl.OSR_MIGRATION_END; 32 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.CLASS_KLASS_LOCATION; 33 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.CLASS_MIRROR_HANDLE_LOCATION; 34 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.CLASS_MIRROR_LOCATION; 35 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.COMPRESSED_HUB_LOCATION; 36 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.DISPLACED_MARK_WORD_LOCATION; 37 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.HUB_LOCATION; 38 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.HUB_WRITE_LOCATION; 39 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.KLASS_LAYOUT_HELPER_LOCATION; 40 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.OBJ_ARRAY_KLASS_ELEMENT_KLASS_LOCATION; 41 import static jdk.internal.vm.compiler.word.LocationIdentity.any; 42 43 import java.lang.ref.Reference; 44 import java.util.EnumMap; 45 46 import org.graalvm.compiler.api.directives.GraalDirectives; 47 import org.graalvm.compiler.core.common.CompressEncoding; 48 import org.graalvm.compiler.core.common.GraalOptions; 49 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor; 50 import org.graalvm.compiler.core.common.spi.ForeignCallsProvider; 51 import org.graalvm.compiler.core.common.type.ObjectStamp; 52 import org.graalvm.compiler.core.common.type.Stamp; 53 import org.graalvm.compiler.core.common.type.StampFactory; 54 import org.graalvm.compiler.core.common.type.StampPair; 55 import org.graalvm.compiler.debug.DebugCloseable; 56 import org.graalvm.compiler.debug.DebugHandlersFactory; 57 import org.graalvm.compiler.debug.GraalError; 58 import org.graalvm.compiler.graph.Node; 59 import org.graalvm.compiler.graph.NodeInputList; 60 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; 61 import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider; 62 import org.graalvm.compiler.hotspot.nodes.BeginLockScopeNode; 63 import org.graalvm.compiler.hotspot.nodes.HotSpotCompressionNode; 64 import org.graalvm.compiler.hotspot.nodes.HotSpotDirectCallTargetNode; 65 import org.graalvm.compiler.hotspot.nodes.HotSpotIndirectCallTargetNode; 66 import org.graalvm.compiler.hotspot.nodes.KlassBeingInitializedCheckNode; 67 import org.graalvm.compiler.hotspot.nodes.aot.InitializeKlassNode; 68 import org.graalvm.compiler.hotspot.nodes.aot.ResolveConstantNode; 69 import org.graalvm.compiler.hotspot.nodes.aot.ResolveDynamicConstantNode; 70 import org.graalvm.compiler.hotspot.nodes.aot.ResolveMethodAndLoadCountersNode; 71 import org.graalvm.compiler.hotspot.nodes.profiling.ProfileNode; 72 import org.graalvm.compiler.hotspot.nodes.type.HotSpotNarrowOopStamp; 73 import org.graalvm.compiler.hotspot.nodes.type.KlassPointerStamp; 74 import org.graalvm.compiler.hotspot.nodes.type.MethodPointerStamp; 75 import org.graalvm.compiler.hotspot.replacements.AssertionSnippets; 76 import org.graalvm.compiler.hotspot.replacements.ClassGetHubNode; 77 import org.graalvm.compiler.hotspot.replacements.HashCodeSnippets; 78 import org.graalvm.compiler.hotspot.replacements.HotSpotG1WriteBarrierSnippets; 79 import org.graalvm.compiler.hotspot.replacements.HotSpotSerialWriteBarrierSnippets; 80 import org.graalvm.compiler.hotspot.replacements.HubGetClassNode; 81 import org.graalvm.compiler.hotspot.replacements.IdentityHashCodeNode; 82 import org.graalvm.compiler.hotspot.replacements.InstanceOfSnippets; 83 import org.graalvm.compiler.hotspot.replacements.KlassLayoutHelperNode; 84 import org.graalvm.compiler.hotspot.replacements.LoadExceptionObjectSnippets; 85 import org.graalvm.compiler.hotspot.replacements.MonitorSnippets; 86 import org.graalvm.compiler.hotspot.replacements.NewObjectSnippets; 87 import org.graalvm.compiler.hotspot.replacements.ObjectCloneSnippets; 88 import org.graalvm.compiler.hotspot.replacements.StringToBytesSnippets; 89 import org.graalvm.compiler.hotspot.replacements.UnsafeLoadSnippets; 90 import org.graalvm.compiler.hotspot.replacements.aot.ResolveConstantSnippets; 91 import org.graalvm.compiler.hotspot.replacements.arraycopy.HotSpotArraycopySnippets; 92 import org.graalvm.compiler.hotspot.replacements.profiling.ProfileSnippets; 93 import org.graalvm.compiler.hotspot.stubs.ForeignCallSnippets; 94 import org.graalvm.compiler.hotspot.word.KlassPointer; 95 import org.graalvm.compiler.nodes.AbstractBeginNode; 96 import org.graalvm.compiler.nodes.AbstractDeoptimizeNode; 97 import org.graalvm.compiler.nodes.CompressionNode.CompressionOp; 98 import org.graalvm.compiler.nodes.ComputeObjectAddressNode; 99 import org.graalvm.compiler.nodes.ConstantNode; 100 import org.graalvm.compiler.nodes.FixedNode; 101 import org.graalvm.compiler.nodes.GetObjectAddressNode; 102 import org.graalvm.compiler.nodes.Invoke; 103 import org.graalvm.compiler.nodes.LogicNode; 104 import org.graalvm.compiler.nodes.LoweredCallTargetNode; 105 import org.graalvm.compiler.nodes.NodeView; 106 import org.graalvm.compiler.nodes.ParameterNode; 107 import org.graalvm.compiler.nodes.SafepointNode; 108 import org.graalvm.compiler.nodes.StartNode; 109 import org.graalvm.compiler.nodes.StructuredGraph; 110 import org.graalvm.compiler.nodes.UnwindNode; 111 import org.graalvm.compiler.nodes.ValueNode; 112 import org.graalvm.compiler.nodes.calc.AddNode; 113 import org.graalvm.compiler.nodes.calc.FloatingNode; 114 import org.graalvm.compiler.nodes.calc.IntegerDivRemNode; 115 import org.graalvm.compiler.nodes.calc.IsNullNode; 116 import org.graalvm.compiler.nodes.calc.RemNode; 117 import org.graalvm.compiler.nodes.debug.StringToBytesNode; 118 import org.graalvm.compiler.nodes.debug.VerifyHeapNode; 119 import org.graalvm.compiler.nodes.extended.BytecodeExceptionNode; 120 import org.graalvm.compiler.nodes.extended.BytecodeExceptionNode.BytecodeExceptionKind; 121 import org.graalvm.compiler.nodes.extended.ForeignCallNode; 122 import org.graalvm.compiler.nodes.extended.GetClassNode; 123 import org.graalvm.compiler.nodes.extended.GuardedUnsafeLoadNode; 124 import org.graalvm.compiler.nodes.extended.LoadHubNode; 125 import org.graalvm.compiler.nodes.extended.LoadMethodNode; 126 import org.graalvm.compiler.nodes.extended.OSRLocalNode; 127 import org.graalvm.compiler.nodes.extended.OSRLockNode; 128 import org.graalvm.compiler.nodes.extended.OSRMonitorEnterNode; 129 import org.graalvm.compiler.nodes.extended.OSRStartNode; 130 import org.graalvm.compiler.nodes.extended.RawLoadNode; 131 import org.graalvm.compiler.nodes.extended.StoreHubNode; 132 import org.graalvm.compiler.nodes.gc.G1ArrayRangePostWriteBarrier; 133 import org.graalvm.compiler.nodes.gc.G1ArrayRangePreWriteBarrier; 134 import org.graalvm.compiler.nodes.gc.G1PostWriteBarrier; 135 import org.graalvm.compiler.nodes.gc.G1PreWriteBarrier; 136 import org.graalvm.compiler.nodes.gc.G1ReferentFieldReadBarrier; 137 import org.graalvm.compiler.nodes.gc.SerialArrayRangeWriteBarrier; 138 import org.graalvm.compiler.nodes.gc.SerialWriteBarrier; 139 import org.graalvm.compiler.nodes.java.ClassIsAssignableFromNode; 140 import org.graalvm.compiler.nodes.java.DynamicNewArrayNode; 141 import org.graalvm.compiler.nodes.java.DynamicNewInstanceNode; 142 import org.graalvm.compiler.nodes.java.InstanceOfDynamicNode; 143 import org.graalvm.compiler.nodes.java.InstanceOfNode; 144 import org.graalvm.compiler.nodes.java.LoadExceptionObjectNode; 145 import org.graalvm.compiler.nodes.java.MethodCallTargetNode; 146 import org.graalvm.compiler.nodes.java.MonitorExitNode; 147 import org.graalvm.compiler.nodes.java.MonitorIdNode; 148 import org.graalvm.compiler.nodes.java.NewArrayNode; 149 import org.graalvm.compiler.nodes.java.NewInstanceNode; 150 import org.graalvm.compiler.nodes.java.NewMultiArrayNode; 151 import org.graalvm.compiler.nodes.java.RawMonitorEnterNode; 152 import org.graalvm.compiler.nodes.memory.FloatingReadNode; 153 import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType; 154 import org.graalvm.compiler.nodes.memory.ReadNode; 155 import org.graalvm.compiler.nodes.memory.WriteNode; 156 import org.graalvm.compiler.nodes.memory.address.AddressNode; 157 import org.graalvm.compiler.nodes.spi.LoweringProvider; 158 import org.graalvm.compiler.nodes.spi.LoweringTool; 159 import org.graalvm.compiler.nodes.spi.StampProvider; 160 import org.graalvm.compiler.nodes.type.StampTool; 161 import org.graalvm.compiler.nodes.util.GraphUtil; 162 import org.graalvm.compiler.options.OptionValues; 163 import org.graalvm.compiler.replacements.DefaultJavaLoweringProvider; 164 import org.graalvm.compiler.replacements.arraycopy.ArrayCopyNode; 165 import org.graalvm.compiler.replacements.arraycopy.ArrayCopySnippets; 166 import org.graalvm.compiler.replacements.arraycopy.ArrayCopyWithDelayedLoweringNode; 167 import org.graalvm.compiler.replacements.nodes.AssertionNode; 168 import org.graalvm.compiler.serviceprovider.JavaVersionUtil; 169 import jdk.internal.vm.compiler.word.LocationIdentity; 170 171 import jdk.vm.ci.code.TargetDescription; 172 import jdk.vm.ci.hotspot.HotSpotCallingConventionType; 173 import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider; 174 import jdk.vm.ci.hotspot.HotSpotResolvedJavaField; 175 import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod; 176 import jdk.vm.ci.meta.JavaConstant; 177 import jdk.vm.ci.meta.JavaKind; 178 import jdk.vm.ci.meta.JavaType; 179 import jdk.vm.ci.meta.MetaAccessProvider; 180 import jdk.vm.ci.meta.ResolvedJavaField; 181 import jdk.vm.ci.meta.ResolvedJavaType; 182 183 /** 184 * HotSpot implementation of {@link LoweringProvider}. 185 */ 186 public abstract class DefaultHotSpotLoweringProvider extends DefaultJavaLoweringProvider implements HotSpotLoweringProvider { 187 188 protected final HotSpotGraalRuntimeProvider runtime; 189 protected final HotSpotRegistersProvider registers; 190 protected final HotSpotConstantReflectionProvider constantReflection; 191 192 protected InstanceOfSnippets.Templates instanceofSnippets; 193 protected NewObjectSnippets.Templates newObjectSnippets; 194 protected MonitorSnippets.Templates monitorSnippets; 195 protected HotSpotSerialWriteBarrierSnippets.Templates serialWriteBarrierSnippets; 196 protected HotSpotG1WriteBarrierSnippets.Templates g1WriteBarrierSnippets; 197 protected LoadExceptionObjectSnippets.Templates exceptionObjectSnippets; 198 protected UnsafeLoadSnippets.Templates unsafeLoadSnippets; 199 protected AssertionSnippets.Templates assertionSnippets; 200 protected ArrayCopySnippets.Templates arraycopySnippets; 201 protected StringToBytesSnippets.Templates stringToBytesSnippets; 202 protected HashCodeSnippets.Templates hashCodeSnippets; 203 protected ResolveConstantSnippets.Templates resolveConstantSnippets; 204 protected ProfileSnippets.Templates profileSnippets; 205 206 protected ObjectCloneSnippets.Templates objectCloneSnippets; 207 protected ForeignCallSnippets.Templates foreignCallSnippets; 208 209 public DefaultHotSpotLoweringProvider(HotSpotGraalRuntimeProvider runtime, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls, HotSpotRegistersProvider registers, 210 HotSpotConstantReflectionProvider constantReflection, TargetDescription target) { 211 super(metaAccess, foreignCalls, target, runtime.getVMConfig().useCompressedOops); 212 this.runtime = runtime; 213 this.registers = registers; 214 this.constantReflection = constantReflection; 215 } 216 217 @Override 218 public void initialize(OptionValues options, Iterable<DebugHandlersFactory> factories, HotSpotProviders providers, GraalHotSpotVMConfig config) { 219 super.initialize(options, factories, runtime, providers, providers.getSnippetReflection()); 220 221 assert target == providers.getCodeCache().getTarget(); 222 instanceofSnippets = new InstanceOfSnippets.Templates(options, factories, runtime, providers, target); 223 newObjectSnippets = new NewObjectSnippets.Templates(options, factories, runtime, providers, target, config); 224 monitorSnippets = new MonitorSnippets.Templates(options, factories, runtime, providers, target, config.useFastLocking); 225 g1WriteBarrierSnippets = new HotSpotG1WriteBarrierSnippets.Templates(options, factories, runtime, providers, target, config); 226 serialWriteBarrierSnippets = new HotSpotSerialWriteBarrierSnippets.Templates(options, factories, runtime, providers, target, config); 227 exceptionObjectSnippets = new LoadExceptionObjectSnippets.Templates(options, factories, providers, target); 228 unsafeLoadSnippets = new UnsafeLoadSnippets.Templates(options, factories, providers, target); 229 assertionSnippets = new AssertionSnippets.Templates(options, factories, providers, target); 230 arraycopySnippets = new ArrayCopySnippets.Templates(new HotSpotArraycopySnippets(), options, factories, runtime, providers, providers.getSnippetReflection(), target); 231 stringToBytesSnippets = new StringToBytesSnippets.Templates(options, factories, providers, target); 232 hashCodeSnippets = new HashCodeSnippets.Templates(options, factories, providers, target); 233 resolveConstantSnippets = new ResolveConstantSnippets.Templates(options, factories, providers, target); 234 objectCloneSnippets = new ObjectCloneSnippets.Templates(options, factories, providers, target); 235 foreignCallSnippets = new ForeignCallSnippets.Templates(options, factories, providers, target); 236 if (JavaVersionUtil.JAVA_SPEC <= 8) { 237 // AOT only introduced in JDK 9 238 profileSnippets = null; 239 } else { 240 profileSnippets = new ProfileSnippets.Templates(options, factories, providers, target); 241 } 242 } 243 244 public ArrayCopySnippets.Templates getArraycopySnippets() { 245 return arraycopySnippets; 246 } 247 248 public MonitorSnippets.Templates getMonitorSnippets() { 249 return monitorSnippets; 250 } 251 252 @Override 253 @SuppressWarnings("try") 254 public void lower(Node n, LoweringTool tool) { 255 StructuredGraph graph = (StructuredGraph) n.graph(); 256 try (DebugCloseable context = n.withNodeSourcePosition()) { 257 if (n instanceof Invoke) { 258 lowerInvoke((Invoke) n, tool, graph); 259 } else if (n instanceof LoadMethodNode) { 260 lowerLoadMethodNode((LoadMethodNode) n); 261 } else if (n instanceof GetClassNode) { 262 lowerGetClassNode((GetClassNode) n, tool, graph); 263 } else if (n instanceof StoreHubNode) { 264 lowerStoreHubNode((StoreHubNode) n, graph); 265 } else if (n instanceof OSRStartNode) { 266 lowerOSRStartNode((OSRStartNode) n); 267 } else if (n instanceof BytecodeExceptionNode) { 268 lowerBytecodeExceptionNode((BytecodeExceptionNode) n); 269 } else if (n instanceof InstanceOfNode) { 270 InstanceOfNode instanceOfNode = (InstanceOfNode) n; 271 if (graph.getGuardsStage().areDeoptsFixed()) { 272 instanceofSnippets.lower(instanceOfNode, tool); 273 } else { 274 if (instanceOfNode.allowsNull()) { 275 ValueNode object = instanceOfNode.getValue(); 276 LogicNode newTypeCheck = graph.addOrUniqueWithInputs(InstanceOfNode.create(instanceOfNode.type(), object, instanceOfNode.profile(), instanceOfNode.getAnchor())); 277 LogicNode newNode = LogicNode.or(graph.unique(IsNullNode.create(object)), newTypeCheck, GraalDirectives.UNLIKELY_PROBABILITY); 278 instanceOfNode.replaceAndDelete(newNode); 279 } 280 } 281 } else if (n instanceof InstanceOfDynamicNode) { 282 InstanceOfDynamicNode instanceOfDynamicNode = (InstanceOfDynamicNode) n; 283 if (graph.getGuardsStage().areDeoptsFixed()) { 284 instanceofSnippets.lower(instanceOfDynamicNode, tool); 285 } else { 286 ValueNode mirror = instanceOfDynamicNode.getMirrorOrHub(); 287 if (mirror.stamp(NodeView.DEFAULT).getStackKind() == JavaKind.Object) { 288 ClassGetHubNode classGetHub = graph.unique(new ClassGetHubNode(mirror)); 289 instanceOfDynamicNode.setMirror(classGetHub); 290 } 291 292 if (instanceOfDynamicNode.allowsNull()) { 293 ValueNode object = instanceOfDynamicNode.getObject(); 294 LogicNode newTypeCheck = graph.addOrUniqueWithInputs( 295 InstanceOfDynamicNode.create(graph.getAssumptions(), tool.getConstantReflection(), instanceOfDynamicNode.getMirrorOrHub(), object, false)); 296 LogicNode newNode = LogicNode.or(graph.unique(IsNullNode.create(object)), newTypeCheck, GraalDirectives.UNLIKELY_PROBABILITY); 297 instanceOfDynamicNode.replaceAndDelete(newNode); 298 } 299 } 300 } else if (n instanceof ClassIsAssignableFromNode) { 301 if (graph.getGuardsStage().areDeoptsFixed()) { 302 instanceofSnippets.lower((ClassIsAssignableFromNode) n, tool); 303 } 304 } else if (n instanceof NewInstanceNode) { 305 if (graph.getGuardsStage().areFrameStatesAtDeopts()) { 306 newObjectSnippets.lower((NewInstanceNode) n, registers, tool); 307 } 308 } else if (n instanceof DynamicNewInstanceNode) { 309 DynamicNewInstanceNode newInstanceNode = (DynamicNewInstanceNode) n; 310 if (newInstanceNode.getClassClass() == null) { 311 JavaConstant classClassMirror = constantReflection.asJavaClass(metaAccess.lookupJavaType(Class.class)); 312 ConstantNode classClass = ConstantNode.forConstant(classClassMirror, tool.getMetaAccess(), graph); 313 newInstanceNode.setClassClass(classClass); 314 } 315 if (graph.getGuardsStage().areFrameStatesAtDeopts()) { 316 newObjectSnippets.lower(newInstanceNode, registers, tool); 317 } 318 } else if (n instanceof NewArrayNode) { 319 if (graph.getGuardsStage().areFrameStatesAtDeopts()) { 320 newObjectSnippets.lower((NewArrayNode) n, registers, tool); 321 } 322 } else if (n instanceof DynamicNewArrayNode) { 323 DynamicNewArrayNode dynamicNewArrayNode = (DynamicNewArrayNode) n; 324 if (dynamicNewArrayNode.getVoidClass() == null) { 325 JavaConstant voidClassMirror = constantReflection.asJavaClass(metaAccess.lookupJavaType(void.class)); 326 ConstantNode voidClass = ConstantNode.forConstant(voidClassMirror, tool.getMetaAccess(), graph); 327 dynamicNewArrayNode.setVoidClass(voidClass); 328 } 329 if (graph.getGuardsStage().areFrameStatesAtDeopts()) { 330 newObjectSnippets.lower(dynamicNewArrayNode, registers, tool); 331 } 332 } else if (n instanceof VerifyHeapNode) { 333 if (graph.getGuardsStage().areFrameStatesAtDeopts()) { 334 newObjectSnippets.lower((VerifyHeapNode) n, registers, tool); 335 } 336 } else if (n instanceof RawMonitorEnterNode) { 337 if (graph.getGuardsStage().areFrameStatesAtDeopts()) { 338 monitorSnippets.lower((RawMonitorEnterNode) n, registers, tool); 339 } 340 } else if (n instanceof MonitorExitNode) { 341 if (graph.getGuardsStage().areFrameStatesAtDeopts()) { 342 monitorSnippets.lower((MonitorExitNode) n, registers, tool); 343 } 344 } else if (n instanceof ArrayCopyNode) { 345 arraycopySnippets.lower((ArrayCopyNode) n, tool); 346 } else if (n instanceof ArrayCopyWithDelayedLoweringNode) { 347 arraycopySnippets.lower((ArrayCopyWithDelayedLoweringNode) n, tool); 348 } else if (n instanceof G1PreWriteBarrier) { 349 g1WriteBarrierSnippets.lower((G1PreWriteBarrier) n, tool); 350 } else if (n instanceof G1PostWriteBarrier) { 351 g1WriteBarrierSnippets.lower((G1PostWriteBarrier) n, tool); 352 } else if (n instanceof G1ReferentFieldReadBarrier) { 353 g1WriteBarrierSnippets.lower((G1ReferentFieldReadBarrier) n, tool); 354 } else if (n instanceof SerialWriteBarrier) { 355 serialWriteBarrierSnippets.lower((SerialWriteBarrier) n, tool); 356 } else if (n instanceof SerialArrayRangeWriteBarrier) { 357 serialWriteBarrierSnippets.lower((SerialArrayRangeWriteBarrier) n, tool); 358 } else if (n instanceof G1ArrayRangePreWriteBarrier) { 359 g1WriteBarrierSnippets.lower((G1ArrayRangePreWriteBarrier) n, tool); 360 } else if (n instanceof G1ArrayRangePostWriteBarrier) { 361 g1WriteBarrierSnippets.lower((G1ArrayRangePostWriteBarrier) n, tool); 362 } else if (n instanceof NewMultiArrayNode) { 363 if (graph.getGuardsStage().areFrameStatesAtDeopts()) { 364 newObjectSnippets.lower((NewMultiArrayNode) n, tool); 365 } 366 } else if (n instanceof LoadExceptionObjectNode) { 367 exceptionObjectSnippets.lower((LoadExceptionObjectNode) n, registers, tool); 368 } else if (n instanceof AssertionNode) { 369 assertionSnippets.lower((AssertionNode) n, tool); 370 } else if (n instanceof StringToBytesNode) { 371 if (graph.getGuardsStage().areDeoptsFixed()) { 372 stringToBytesSnippets.lower((StringToBytesNode) n, tool); 373 } 374 } else if (n instanceof IntegerDivRemNode) { 375 // Nothing to do for division nodes. The HotSpot signal handler catches divisions by 376 // zero and the MIN_VALUE / -1 cases. 377 } else if (n instanceof AbstractDeoptimizeNode || n instanceof UnwindNode || n instanceof RemNode || n instanceof SafepointNode) { 378 /* No lowering, we generate LIR directly for these nodes. */ 379 } else if (n instanceof ClassGetHubNode) { 380 lowerClassGetHubNode((ClassGetHubNode) n, tool); 381 } else if (n instanceof HubGetClassNode) { 382 lowerHubGetClassNode((HubGetClassNode) n, tool); 383 } else if (n instanceof KlassLayoutHelperNode) { 384 lowerKlassLayoutHelperNode((KlassLayoutHelperNode) n, tool); 385 } else if (n instanceof ComputeObjectAddressNode) { 386 if (graph.getGuardsStage().areFrameStatesAtDeopts()) { 387 lowerComputeObjectAddressNode((ComputeObjectAddressNode) n); 388 } 389 } else if (n instanceof IdentityHashCodeNode) { 390 hashCodeSnippets.lower((IdentityHashCodeNode) n, tool); 391 } else if (n instanceof ResolveDynamicConstantNode) { 392 if (graph.getGuardsStage().areFrameStatesAtDeopts()) { 393 resolveConstantSnippets.lower((ResolveDynamicConstantNode) n, tool); 394 } 395 } else if (n instanceof ResolveConstantNode) { 396 if (graph.getGuardsStage().areFrameStatesAtDeopts()) { 397 resolveConstantSnippets.lower((ResolveConstantNode) n, tool); 398 } 399 } else if (n instanceof ResolveMethodAndLoadCountersNode) { 400 if (graph.getGuardsStage().areFrameStatesAtDeopts()) { 401 resolveConstantSnippets.lower((ResolveMethodAndLoadCountersNode) n, tool); 402 } 403 } else if (n instanceof InitializeKlassNode) { 404 if (graph.getGuardsStage().areFrameStatesAtDeopts()) { 405 resolveConstantSnippets.lower((InitializeKlassNode) n, tool); 406 } 407 } else if (n instanceof ProfileNode) { 408 profileSnippets.lower((ProfileNode) n, tool); 409 } else if (n instanceof KlassBeingInitializedCheckNode) { 410 newObjectSnippets.lower((KlassBeingInitializedCheckNode) n, registers, tool); 411 } else { 412 super.lower(n, tool); 413 } 414 } 415 } 416 417 private static void lowerComputeObjectAddressNode(ComputeObjectAddressNode n) { 418 /* 419 * Lower the node into a ComputeObjectAddress node and an Add but ensure that it's below any 420 * potential safepoints and above it's uses. 421 */ 422 for (Node use : n.usages().snapshot()) { 423 if (use instanceof FixedNode) { 424 FixedNode fixed = (FixedNode) use; 425 StructuredGraph graph = n.graph(); 426 GetObjectAddressNode address = graph.add(new GetObjectAddressNode(n.getObject())); 427 graph.addBeforeFixed(fixed, address); 428 AddNode add = graph.addOrUnique(new AddNode(address, n.getOffset())); 429 use.replaceFirstInput(n, add); 430 } else { 431 throw GraalError.shouldNotReachHere("Unexpected floating use of ComputeObjectAddressNode " + n); 432 } 433 } 434 GraphUtil.unlinkFixedNode(n); 435 n.safeDelete(); 436 } 437 438 private void lowerKlassLayoutHelperNode(KlassLayoutHelperNode n, LoweringTool tool) { 439 if (tool.getLoweringStage() == LoweringTool.StandardLoweringStage.HIGH_TIER) { 440 return; 441 } 442 StructuredGraph graph = n.graph(); 443 assert !n.getHub().isConstant(); 444 AddressNode address = createOffsetAddress(graph, n.getHub(), runtime.getVMConfig().klassLayoutHelperOffset); 445 n.replaceAtUsagesAndDelete(graph.unique(new FloatingReadNode(address, KLASS_LAYOUT_HELPER_LOCATION, null, n.stamp(NodeView.DEFAULT), null, BarrierType.NONE))); 446 } 447 448 private void lowerHubGetClassNode(HubGetClassNode n, LoweringTool tool) { 449 if (tool.getLoweringStage() == LoweringTool.StandardLoweringStage.HIGH_TIER) { 450 return; 451 } 452 453 ValueNode hub = n.getHub(); 454 GraalHotSpotVMConfig vmConfig = runtime.getVMConfig(); 455 StructuredGraph graph = n.graph(); 456 assert !hub.isConstant() || GraalOptions.ImmutableCode.getValue(graph.getOptions()); 457 AddressNode mirrorAddress = createOffsetAddress(graph, hub, vmConfig.classMirrorOffset); 458 FloatingReadNode read = graph.unique( 459 new FloatingReadNode(mirrorAddress, CLASS_MIRROR_LOCATION, null, vmConfig.classMirrorIsHandle ? StampFactory.forKind(target.wordJavaKind) : n.stamp(NodeView.DEFAULT), 460 null, BarrierType.NONE)); 461 if (vmConfig.classMirrorIsHandle) { 462 AddressNode address = createOffsetAddress(graph, read, 0); 463 read = graph.unique(new FloatingReadNode(address, CLASS_MIRROR_HANDLE_LOCATION, null, n.stamp(NodeView.DEFAULT), null, BarrierType.NONE)); 464 } 465 n.replaceAtUsagesAndDelete(read); 466 } 467 468 private void lowerClassGetHubNode(ClassGetHubNode n, LoweringTool tool) { 469 if (tool.getLoweringStage() == LoweringTool.StandardLoweringStage.HIGH_TIER) { 470 return; 471 } 472 473 StructuredGraph graph = n.graph(); 474 assert !n.getValue().isConstant(); 475 AddressNode address = createOffsetAddress(graph, n.getValue(), runtime.getVMConfig().klassOffset); 476 FloatingReadNode read = graph.unique(new FloatingReadNode(address, CLASS_KLASS_LOCATION, null, n.stamp(NodeView.DEFAULT), null, BarrierType.NONE)); 477 n.replaceAtUsagesAndDelete(read); 478 } 479 480 private void lowerInvoke(Invoke invoke, LoweringTool tool, StructuredGraph graph) { 481 if (invoke.callTarget() instanceof MethodCallTargetNode) { 482 MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget(); 483 NodeInputList<ValueNode> parameters = callTarget.arguments(); 484 ValueNode receiver = parameters.isEmpty() ? null : parameters.get(0); 485 486 if (!callTarget.isStatic()) { 487 assert receiver != null : "non-static call must have a receiver"; 488 if (receiver.stamp(NodeView.DEFAULT) instanceof ObjectStamp && !StampTool.isPointerNonNull(receiver)) { 489 ValueNode nonNullReceiver = createNullCheckedValue(receiver, invoke.asNode(), tool); 490 parameters.set(0, nonNullReceiver); 491 receiver = nonNullReceiver; 492 } 493 } 494 JavaType[] signature = callTarget.targetMethod().getSignature().toParameterTypes(callTarget.isStatic() ? null : callTarget.targetMethod().getDeclaringClass()); 495 496 LoweredCallTargetNode loweredCallTarget = null; 497 OptionValues options = graph.getOptions(); 498 if (InlineVTableStubs.getValue(options) && callTarget.invokeKind().isIndirect() && (AlwaysInlineVTableStubs.getValue(options) || invoke.isPolymorphic())) { 499 HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) callTarget.targetMethod(); 500 ResolvedJavaType receiverType = invoke.getReceiverType(); 501 if (hsMethod.isInVirtualMethodTable(receiverType)) { 502 JavaKind wordKind = runtime.getTarget().wordJavaKind; 503 ValueNode hub = createReadHub(graph, receiver, tool); 504 505 ReadNode metaspaceMethod = createReadVirtualMethod(graph, hub, hsMethod, receiverType); 506 // We use LocationNode.ANY_LOCATION for the reads that access the 507 // compiled code entry as HotSpot does not guarantee they are final 508 // values. 509 int methodCompiledEntryOffset = runtime.getVMConfig().methodCompiledEntryOffset; 510 AddressNode address = createOffsetAddress(graph, metaspaceMethod, methodCompiledEntryOffset); 511 ReadNode compiledEntry = graph.add(new ReadNode(address, any(), StampFactory.forKind(wordKind), BarrierType.NONE)); 512 513 loweredCallTarget = graph.add(new HotSpotIndirectCallTargetNode(metaspaceMethod, compiledEntry, parameters.toArray(new ValueNode[parameters.size()]), callTarget.returnStamp(), 514 signature, callTarget.targetMethod(), 515 HotSpotCallingConventionType.JavaCall, callTarget.invokeKind())); 516 517 graph.addBeforeFixed(invoke.asNode(), metaspaceMethod); 518 graph.addAfterFixed(metaspaceMethod, compiledEntry); 519 } 520 } 521 522 if (loweredCallTarget == null) { 523 loweredCallTarget = graph.add(new HotSpotDirectCallTargetNode(parameters.toArray(new ValueNode[parameters.size()]), callTarget.returnStamp(), 524 signature, callTarget.targetMethod(), 525 HotSpotCallingConventionType.JavaCall, 526 callTarget.invokeKind())); 527 } 528 callTarget.replaceAndDelete(loweredCallTarget); 529 } 530 } 531 532 private CompressEncoding getOopEncoding() { 533 return runtime.getVMConfig().getOopEncoding(); 534 } 535 536 @Override 537 protected Stamp loadCompressedStamp(ObjectStamp stamp) { 538 return HotSpotNarrowOopStamp.compressed(stamp, getOopEncoding()); 539 } 540 541 @Override 542 protected ValueNode newCompressionNode(CompressionOp op, ValueNode value) { 543 return new HotSpotCompressionNode(op, value, getOopEncoding()); 544 } 545 546 @Override 547 public ValueNode staticFieldBase(StructuredGraph graph, ResolvedJavaField f) { 548 HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) f; 549 JavaConstant base = constantReflection.asJavaClass(field.getDeclaringClass()); 550 return ConstantNode.forConstant(base, metaAccess, graph); 551 } 552 553 @Override 554 protected ValueNode createReadArrayComponentHub(StructuredGraph graph, ValueNode arrayHub, FixedNode anchor) { 555 /* 556 * Anchor the read of the element klass to the cfg, because it is only valid when arrayClass 557 * is an object class, which might not be the case in other parts of the compiled method. 558 */ 559 AddressNode address = createOffsetAddress(graph, arrayHub, runtime.getVMConfig().arrayClassElementOffset); 560 return graph.unique(new FloatingReadNode(address, OBJ_ARRAY_KLASS_ELEMENT_KLASS_LOCATION, null, KlassPointerStamp.klassNonNull(), AbstractBeginNode.prevBegin(anchor))); 561 } 562 563 @Override 564 protected void lowerUnsafeLoadNode(RawLoadNode load, LoweringTool tool) { 565 StructuredGraph graph = load.graph(); 566 if (!(load instanceof GuardedUnsafeLoadNode) && !graph.getGuardsStage().allowsFloatingGuards() && addReadBarrier(load)) { 567 unsafeLoadSnippets.lower(load, tool); 568 } else { 569 super.lowerUnsafeLoadNode(load, tool); 570 } 571 } 572 573 private void lowerLoadMethodNode(LoadMethodNode loadMethodNode) { 574 StructuredGraph graph = loadMethodNode.graph(); 575 HotSpotResolvedJavaMethod method = (HotSpotResolvedJavaMethod) loadMethodNode.getMethod(); 576 ReadNode metaspaceMethod = createReadVirtualMethod(graph, loadMethodNode.getHub(), method, loadMethodNode.getReceiverType()); 577 graph.replaceFixed(loadMethodNode, metaspaceMethod); 578 } 579 580 private static void lowerGetClassNode(GetClassNode getClass, LoweringTool tool, StructuredGraph graph) { 581 StampProvider stampProvider = tool.getStampProvider(); 582 LoadHubNode hub = graph.unique(new LoadHubNode(stampProvider, getClass.getObject())); 583 HubGetClassNode hubGetClass = graph.unique(new HubGetClassNode(tool.getMetaAccess(), hub)); 584 getClass.replaceAtUsagesAndDelete(hubGetClass); 585 hub.lower(tool); 586 hubGetClass.lower(tool); 587 } 588 589 private void lowerStoreHubNode(StoreHubNode storeHub, StructuredGraph graph) { 590 WriteNode hub = createWriteHub(graph, storeHub.getObject(), storeHub.getValue()); 591 graph.replaceFixed(storeHub, hub); 592 } 593 594 private void lowerOSRStartNode(OSRStartNode osrStart) { 595 StructuredGraph graph = osrStart.graph(); 596 if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { 597 StartNode newStart = graph.add(new StartNode()); 598 ParameterNode buffer = graph.addWithoutUnique(new ParameterNode(0, StampPair.createSingle(StampFactory.forKind(runtime.getTarget().wordJavaKind)))); 599 ForeignCallNode migrationEnd = graph.add(new ForeignCallNode(foreignCalls, OSR_MIGRATION_END, buffer)); 600 migrationEnd.setStateAfter(osrStart.stateAfter()); 601 newStart.setNext(migrationEnd); 602 FixedNode next = osrStart.next(); 603 osrStart.setNext(null); 604 migrationEnd.setNext(next); 605 graph.setStart(newStart); 606 607 final int wordSize = target.wordSize; 608 609 // @formatter:off 610 // taken from c2 locals_addr = osr_buf + (max_locals-1)*wordSize) 611 // @formatter:on 612 int localsOffset = (graph.method().getMaxLocals() - 1) * wordSize; 613 for (OSRLocalNode osrLocal : graph.getNodes(OSRLocalNode.TYPE)) { 614 int size = osrLocal.getStackKind().getSlotCount(); 615 int offset = localsOffset - (osrLocal.index() + size - 1) * wordSize; 616 AddressNode address = createOffsetAddress(graph, buffer, offset); 617 ReadNode load = graph.add(new ReadNode(address, any(), osrLocal.stamp(NodeView.DEFAULT), BarrierType.NONE)); 618 osrLocal.replaceAndDelete(load); 619 graph.addBeforeFixed(migrationEnd, load); 620 } 621 622 // @formatter:off 623 // taken from c2 monitors_addr = osr_buf + (max_locals+mcnt*2-1)*wordSize); 624 // @formatter:on 625 final int lockCount = osrStart.stateAfter().locksSize(); 626 final int locksOffset = (graph.method().getMaxLocals() + lockCount * 2 - 1) * wordSize; 627 628 // first initialize the lock slots for all enters with the displaced marks read from the 629 // buffer 630 for (OSRMonitorEnterNode osrMonitorEnter : graph.getNodes(OSRMonitorEnterNode.TYPE)) { 631 MonitorIdNode monitorID = osrMonitorEnter.getMonitorId(); 632 OSRLockNode lock = (OSRLockNode) osrMonitorEnter.object(); 633 final int index = lock.index(); 634 635 final int offsetDisplacedHeader = locksOffset - ((index * 2) + 1) * wordSize; 636 final int offsetLockObject = locksOffset - index * 2 * wordSize; 637 638 // load the displaced mark from the osr buffer 639 AddressNode addressDisplacedHeader = createOffsetAddress(graph, buffer, offsetDisplacedHeader); 640 ReadNode loadDisplacedHeader = graph.add(new ReadNode(addressDisplacedHeader, any(), lock.stamp(NodeView.DEFAULT), BarrierType.NONE)); 641 graph.addBeforeFixed(migrationEnd, loadDisplacedHeader); 642 643 // we need to initialize the stack slot for the lock 644 BeginLockScopeNode beginLockScope = graph.add(new BeginLockScopeNode(lock.getStackKind(), monitorID.getLockDepth())); 645 graph.addBeforeFixed(migrationEnd, beginLockScope); 646 647 // write the displaced mark to the correct stack slot 648 AddressNode addressDisplacedMark = createOffsetAddress(graph, beginLockScope, runtime.getVMConfig().basicLockDisplacedHeaderOffset); 649 WriteNode writeStackSlot = graph.add(new WriteNode(addressDisplacedMark, DISPLACED_MARK_WORD_LOCATION, loadDisplacedHeader, BarrierType.NONE)); 650 graph.addBeforeFixed(migrationEnd, writeStackSlot); 651 652 // load the lock object from the osr buffer 653 AddressNode addressLockObject = createOffsetAddress(graph, buffer, offsetLockObject); 654 ReadNode loadObject = graph.add(new ReadNode(addressLockObject, any(), lock.stamp(NodeView.DEFAULT), BarrierType.NONE)); 655 lock.replaceAndDelete(loadObject); 656 graph.addBeforeFixed(migrationEnd, loadObject); 657 } 658 659 osrStart.replaceAtUsagesAndDelete(newStart); 660 } 661 } 662 663 static final class Exceptions { 664 protected static final EnumMap<BytecodeExceptionKind, RuntimeException> cachedExceptions; 665 666 static { 667 cachedExceptions = new EnumMap<>(BytecodeExceptionKind.class); 668 cachedExceptions.put(BytecodeExceptionKind.NULL_POINTER, clearStackTrace(new NullPointerException())); 669 cachedExceptions.put(BytecodeExceptionKind.OUT_OF_BOUNDS, clearStackTrace(new ArrayIndexOutOfBoundsException())); 670 cachedExceptions.put(BytecodeExceptionKind.CLASS_CAST, clearStackTrace(new ClassCastException())); 671 cachedExceptions.put(BytecodeExceptionKind.ARRAY_STORE, clearStackTrace(new ArrayStoreException())); 672 cachedExceptions.put(BytecodeExceptionKind.DIVISION_BY_ZERO, clearStackTrace(new ArithmeticException())); 673 } 674 675 private static RuntimeException clearStackTrace(RuntimeException ex) { 676 ex.setStackTrace(new StackTraceElement[0]); 677 return ex; 678 } 679 } 680 681 public static final class RuntimeCalls { 682 public static final EnumMap<BytecodeExceptionKind, ForeignCallDescriptor> runtimeCalls; 683 684 static { 685 runtimeCalls = new EnumMap<>(BytecodeExceptionKind.class); 686 runtimeCalls.put(BytecodeExceptionKind.ARRAY_STORE, new ForeignCallDescriptor("createArrayStoreException", ArrayStoreException.class, Object.class)); 687 runtimeCalls.put(BytecodeExceptionKind.CLASS_CAST, new ForeignCallDescriptor("createClassCastException", ClassCastException.class, Object.class, KlassPointer.class)); 688 runtimeCalls.put(BytecodeExceptionKind.NULL_POINTER, new ForeignCallDescriptor("createNullPointerException", NullPointerException.class)); 689 runtimeCalls.put(BytecodeExceptionKind.OUT_OF_BOUNDS, new ForeignCallDescriptor("createOutOfBoundsException", ArrayIndexOutOfBoundsException.class, int.class, int.class)); 690 runtimeCalls.put(BytecodeExceptionKind.DIVISION_BY_ZERO, new ForeignCallDescriptor("createDivisionByZeroException", ArithmeticException.class)); 691 runtimeCalls.put(BytecodeExceptionKind.INTEGER_EXACT_OVERFLOW, new ForeignCallDescriptor("createIntegerExactOverflowException", ArithmeticException.class)); 692 runtimeCalls.put(BytecodeExceptionKind.LONG_EXACT_OVERFLOW, new ForeignCallDescriptor("createLongExactOverflowException", ArithmeticException.class)); 693 } 694 } 695 696 private void throwCachedException(BytecodeExceptionNode node) { 697 if (IS_IN_NATIVE_IMAGE) { 698 throw new InternalError("Can't throw exception from SVM object"); 699 } 700 Throwable exception = Exceptions.cachedExceptions.get(node.getExceptionKind()); 701 assert exception != null; 702 703 StructuredGraph graph = node.graph(); 704 FloatingNode exceptionNode = ConstantNode.forConstant(constantReflection.forObject(exception), metaAccess, graph); 705 graph.replaceFixedWithFloating(node, exceptionNode); 706 } 707 708 private void lowerBytecodeExceptionNode(BytecodeExceptionNode node) { 709 if (OmitHotExceptionStacktrace.getValue(node.getOptions())) { 710 throwCachedException(node); 711 return; 712 } 713 714 ForeignCallDescriptor descriptor = RuntimeCalls.runtimeCalls.get(node.getExceptionKind()); 715 assert descriptor != null; 716 717 StructuredGraph graph = node.graph(); 718 ForeignCallNode foreignCallNode = graph.add(new ForeignCallNode(foreignCalls, descriptor, node.stamp(NodeView.DEFAULT), node.getArguments())); 719 foreignCallNode.setStateAfter(node.stateAfter()); 720 graph.replaceFixedWithFixed(node, foreignCallNode); 721 } 722 723 private boolean addReadBarrier(RawLoadNode load) { 724 if (runtime.getVMConfig().useG1GC && load.graph().getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS && load.object().getStackKind() == JavaKind.Object && 725 load.accessKind() == JavaKind.Object && !StampTool.isPointerAlwaysNull(load.object())) { 726 ResolvedJavaType type = StampTool.typeOrNull(load.object()); 727 if (type != null && !type.isArray()) { 728 return true; 729 } 730 } 731 return false; 732 } 733 734 private ReadNode createReadVirtualMethod(StructuredGraph graph, ValueNode hub, HotSpotResolvedJavaMethod method, ResolvedJavaType receiverType) { 735 return createReadVirtualMethod(graph, hub, method.vtableEntryOffset(receiverType)); 736 } 737 738 private ReadNode createReadVirtualMethod(StructuredGraph graph, ValueNode hub, int vtableEntryOffset) { 739 assert vtableEntryOffset > 0; 740 // We use LocationNode.ANY_LOCATION for the reads that access the vtable 741 // entry as HotSpot does not guarantee that this is a final value. 742 Stamp methodStamp = MethodPointerStamp.methodNonNull(); 743 AddressNode address = createOffsetAddress(graph, hub, vtableEntryOffset); 744 ReadNode metaspaceMethod = graph.add(new ReadNode(address, any(), methodStamp, BarrierType.NONE)); 745 return metaspaceMethod; 746 } 747 748 @Override 749 protected ValueNode createReadHub(StructuredGraph graph, ValueNode object, LoweringTool tool) { 750 if (tool.getLoweringStage() != LoweringTool.StandardLoweringStage.LOW_TIER) { 751 return graph.unique(new LoadHubNode(tool.getStampProvider(), object)); 752 } 753 assert !object.isConstant() || object.isNullConstant(); 754 755 KlassPointerStamp hubStamp = KlassPointerStamp.klassNonNull(); 756 if (runtime.getVMConfig().useCompressedClassPointers) { 757 hubStamp = hubStamp.compressed(runtime.getVMConfig().getKlassEncoding()); 758 } 759 760 AddressNode address = createOffsetAddress(graph, object, runtime.getVMConfig().hubOffset); 761 LocationIdentity hubLocation = runtime.getVMConfig().useCompressedClassPointers ? COMPRESSED_HUB_LOCATION : HUB_LOCATION; 762 FloatingReadNode memoryRead = graph.unique(new FloatingReadNode(address, hubLocation, null, hubStamp, null, BarrierType.NONE)); 763 if (runtime.getVMConfig().useCompressedClassPointers) { 764 return HotSpotCompressionNode.uncompress(memoryRead, runtime.getVMConfig().getKlassEncoding()); 765 } else { 766 return memoryRead; 767 } 768 } 769 770 private WriteNode createWriteHub(StructuredGraph graph, ValueNode object, ValueNode value) { 771 assert !object.isConstant() || object.asConstant().isDefaultForKind(); 772 773 ValueNode writeValue = value; 774 if (runtime.getVMConfig().useCompressedClassPointers) { 775 writeValue = HotSpotCompressionNode.compress(value, runtime.getVMConfig().getKlassEncoding()); 776 } 777 778 AddressNode address = createOffsetAddress(graph, object, runtime.getVMConfig().hubOffset); 779 return graph.add(new WriteNode(address, HUB_WRITE_LOCATION, writeValue, BarrierType.NONE)); 780 } 781 782 @Override 783 protected BarrierType fieldLoadBarrierType(ResolvedJavaField f) { 784 HotSpotResolvedJavaField loadField = (HotSpotResolvedJavaField) f; 785 if (loadField.getJavaKind() == JavaKind.Object && metaAccess.lookupJavaType(Reference.class).equals(loadField.getDeclaringClass()) && 786 loadField.getName().equals("referent")) { 787 return BarrierType.WEAK_FIELD; 788 } 789 return super.fieldLoadBarrierType(f); 790 } 791 792 @Override 793 public int fieldOffset(ResolvedJavaField f) { 794 return f.getOffset(); 795 } 796 797 @Override 798 public int arrayLengthOffset() { 799 return runtime.getVMConfig().arrayOopDescLengthOffset(); 800 } 801 802 @Override 803 protected final JavaKind getStorageKind(ResolvedJavaField field) { 804 return field.getJavaKind(); 805 } 806 807 @Override 808 public ObjectCloneSnippets.Templates getObjectCloneSnippets() { 809 return objectCloneSnippets; 810 } 811 812 @Override 813 public ForeignCallSnippets.Templates getForeignCallSnippets() { 814 return foreignCallSnippets; 815 } 816 }