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