1 /* 2 * Copyright (c) 2012, 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 24 25 package org.graalvm.compiler.hotspot.replacements; 26 27 import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_METAACCESS; 28 import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG; 29 import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProviderImpl.VERIFY_OOP; 30 import static org.graalvm.compiler.hotspot.replacements.UnsafeAccess.UNSAFE; 31 32 import org.graalvm.compiler.api.replacements.Fold; 33 import org.graalvm.compiler.api.replacements.Fold.InjectedParameter; 34 import org.graalvm.compiler.core.common.SuppressFBWarnings; 35 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor; 36 import org.graalvm.compiler.core.common.type.ObjectStamp; 37 import org.graalvm.compiler.core.common.type.TypeReference; 38 import org.graalvm.compiler.debug.GraalError; 39 import org.graalvm.compiler.graph.Node.ConstantNodeParameter; 40 import org.graalvm.compiler.graph.Node.NodeIntrinsic; 41 import org.graalvm.compiler.graph.spi.CanonicalizerTool; 42 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; 43 import org.graalvm.compiler.hotspot.nodes.ComputeObjectAddressNode; 44 import org.graalvm.compiler.hotspot.word.KlassPointer; 45 import org.graalvm.compiler.nodes.CanonicalizableLocation; 46 import org.graalvm.compiler.nodes.CompressionNode; 47 import org.graalvm.compiler.nodes.ConstantNode; 48 import org.graalvm.compiler.nodes.NamedLocationIdentity; 49 import org.graalvm.compiler.nodes.NodeView; 50 import org.graalvm.compiler.nodes.ValueNode; 51 import org.graalvm.compiler.nodes.extended.ForeignCallNode; 52 import org.graalvm.compiler.nodes.extended.LoadHubNode; 53 import org.graalvm.compiler.nodes.extended.RawLoadNode; 54 import org.graalvm.compiler.nodes.extended.StoreHubNode; 55 import org.graalvm.compiler.nodes.memory.Access; 56 import org.graalvm.compiler.nodes.memory.address.AddressNode; 57 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode; 58 import org.graalvm.compiler.nodes.type.StampTool; 59 import org.graalvm.compiler.replacements.ReplacementsUtil; 60 import org.graalvm.compiler.replacements.nodes.ReadRegisterNode; 61 import org.graalvm.compiler.replacements.nodes.WriteRegisterNode; 62 import org.graalvm.compiler.word.Word; 63 import jdk.internal.vm.compiler.word.LocationIdentity; 64 import jdk.internal.vm.compiler.word.WordFactory; 65 66 import jdk.vm.ci.code.CodeUtil; 67 import jdk.vm.ci.code.Register; 68 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; 69 import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant; 70 import jdk.vm.ci.hotspot.HotSpotResolvedObjectType; 71 import jdk.vm.ci.meta.Assumptions; 72 import jdk.vm.ci.meta.Assumptions.AssumptionResult; 73 import jdk.vm.ci.meta.JavaKind; 74 import jdk.vm.ci.meta.MetaAccessProvider; 75 import jdk.vm.ci.meta.ResolvedJavaType; 76 77 //JaCoCo Exclude 78 79 /** 80 * A collection of methods used in HotSpot snippets, substitutions and stubs. 81 */ 82 public class HotSpotReplacementsUtil { 83 84 abstract static class HotSpotOptimizingLocationIdentity extends NamedLocationIdentity implements CanonicalizableLocation { 85 HotSpotOptimizingLocationIdentity(String name)86 HotSpotOptimizingLocationIdentity(String name) { 87 super(name, true); 88 } 89 90 @Override canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool)91 public abstract ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool); 92 findReadHub(ValueNode object)93 protected ValueNode findReadHub(ValueNode object) { 94 ValueNode base = object; 95 if (base instanceof CompressionNode) { 96 base = ((CompressionNode) base).getValue(); 97 } 98 if (base instanceof Access) { 99 Access access = (Access) base; 100 if (access.getLocationIdentity().equals(HUB_LOCATION) || access.getLocationIdentity().equals(COMPRESSED_HUB_LOCATION)) { 101 AddressNode address = access.getAddress(); 102 if (address instanceof OffsetAddressNode) { 103 OffsetAddressNode offset = (OffsetAddressNode) address; 104 return offset.getBase(); 105 } 106 } 107 } else if (base instanceof LoadHubNode) { 108 LoadHubNode loadhub = (LoadHubNode) base; 109 return loadhub.getValue(); 110 } 111 return null; 112 } 113 114 /** 115 * Fold reads that convert from Class -> Hub -> Class or vice versa. 116 * 117 * @param read 118 * @param object 119 * @param otherLocation 120 * @return an earlier read or the original {@code read} 121 */ foldIndirection(ValueNode read, ValueNode object, LocationIdentity otherLocation)122 protected static ValueNode foldIndirection(ValueNode read, ValueNode object, LocationIdentity otherLocation) { 123 if (object instanceof Access) { 124 Access access = (Access) object; 125 if (access.getLocationIdentity().equals(otherLocation)) { 126 AddressNode address = access.getAddress(); 127 if (address instanceof OffsetAddressNode) { 128 OffsetAddressNode offset = (OffsetAddressNode) address; 129 assert offset.getBase().stamp(NodeView.DEFAULT).isCompatible(read.stamp(NodeView.DEFAULT)); 130 return offset.getBase(); 131 } 132 } 133 } 134 return read; 135 } 136 } 137 runtime()138 public static HotSpotJVMCIRuntime runtime() { 139 return HotSpotJVMCIRuntime.runtime(); 140 } 141 142 @Fold config(@njectedParameter GraalHotSpotVMConfig config)143 public static GraalHotSpotVMConfig config(@InjectedParameter GraalHotSpotVMConfig config) { 144 assert config != null; 145 return config; 146 } 147 148 @Fold useTLAB(@njectedParameter GraalHotSpotVMConfig config)149 public static boolean useTLAB(@InjectedParameter GraalHotSpotVMConfig config) { 150 return config.useTLAB; 151 } 152 153 @Fold verifyOops(@njectedParameter GraalHotSpotVMConfig config)154 public static boolean verifyOops(@InjectedParameter GraalHotSpotVMConfig config) { 155 return config.verifyOops; 156 } 157 158 public static final LocationIdentity EXCEPTION_OOP_LOCATION = NamedLocationIdentity.mutable("ExceptionOop"); 159 160 /** 161 * @see GraalHotSpotVMConfig#threadExceptionOopOffset 162 */ 163 @Fold threadExceptionOopOffset(@njectedParameter GraalHotSpotVMConfig config)164 public static int threadExceptionOopOffset(@InjectedParameter GraalHotSpotVMConfig config) { 165 return config.threadExceptionOopOffset; 166 } 167 168 public static final LocationIdentity EXCEPTION_PC_LOCATION = NamedLocationIdentity.mutable("ExceptionPc"); 169 170 @Fold threadExceptionPcOffset(@njectedParameter GraalHotSpotVMConfig config)171 public static int threadExceptionPcOffset(@InjectedParameter GraalHotSpotVMConfig config) { 172 return config.threadExceptionPcOffset; 173 } 174 175 public static final LocationIdentity TLAB_TOP_LOCATION = NamedLocationIdentity.mutable("TlabTop"); 176 177 @Fold threadTlabTopOffset(@njectedParameter GraalHotSpotVMConfig config)178 public static int threadTlabTopOffset(@InjectedParameter GraalHotSpotVMConfig config) { 179 return config.threadTlabTopOffset(); 180 } 181 182 public static final LocationIdentity TLAB_END_LOCATION = NamedLocationIdentity.mutable("TlabEnd"); 183 184 @Fold threadTlabEndOffset(@njectedParameter GraalHotSpotVMConfig config)185 static int threadTlabEndOffset(@InjectedParameter GraalHotSpotVMConfig config) { 186 return config.threadTlabEndOffset(); 187 } 188 189 public static final LocationIdentity TLAB_START_LOCATION = NamedLocationIdentity.mutable("TlabStart"); 190 191 @Fold threadTlabStartOffset(@njectedParameter GraalHotSpotVMConfig config)192 static int threadTlabStartOffset(@InjectedParameter GraalHotSpotVMConfig config) { 193 return config.threadTlabStartOffset(); 194 } 195 196 public static final LocationIdentity PENDING_EXCEPTION_LOCATION = NamedLocationIdentity.mutable("PendingException"); 197 198 /** 199 * @see GraalHotSpotVMConfig#pendingExceptionOffset 200 */ 201 @Fold threadPendingExceptionOffset(@njectedParameter GraalHotSpotVMConfig config)202 static int threadPendingExceptionOffset(@InjectedParameter GraalHotSpotVMConfig config) { 203 return config.pendingExceptionOffset; 204 } 205 206 public static final LocationIdentity PENDING_DEOPTIMIZATION_LOCATION = NamedLocationIdentity.mutable("PendingDeoptimization"); 207 208 /** 209 * @see GraalHotSpotVMConfig#pendingDeoptimizationOffset 210 */ 211 @Fold threadPendingDeoptimizationOffset(@njectedParameter GraalHotSpotVMConfig config)212 static int threadPendingDeoptimizationOffset(@InjectedParameter GraalHotSpotVMConfig config) { 213 return config.pendingDeoptimizationOffset; 214 } 215 216 public static final LocationIdentity OBJECT_RESULT_LOCATION = NamedLocationIdentity.mutable("ObjectResult"); 217 218 @Fold objectResultOffset(@njectedParameter GraalHotSpotVMConfig config)219 static int objectResultOffset(@InjectedParameter GraalHotSpotVMConfig config) { 220 return config.threadObjectResultOffset; 221 } 222 223 /** 224 * @see GraalHotSpotVMConfig#threadExceptionOopOffset 225 */ readExceptionOop(Word thread)226 public static Object readExceptionOop(Word thread) { 227 return thread.readObject(threadExceptionOopOffset(INJECTED_VMCONFIG), EXCEPTION_OOP_LOCATION); 228 } 229 readExceptionPc(Word thread)230 public static Word readExceptionPc(Word thread) { 231 return thread.readWord(threadExceptionPcOffset(INJECTED_VMCONFIG), EXCEPTION_PC_LOCATION); 232 } 233 234 /** 235 * @see GraalHotSpotVMConfig#threadExceptionOopOffset 236 */ writeExceptionOop(Word thread, Object value)237 public static void writeExceptionOop(Word thread, Object value) { 238 thread.writeObject(threadExceptionOopOffset(INJECTED_VMCONFIG), value, EXCEPTION_OOP_LOCATION); 239 } 240 writeExceptionPc(Word thread, Word value)241 public static void writeExceptionPc(Word thread, Word value) { 242 thread.writeWord(threadExceptionPcOffset(INJECTED_VMCONFIG), value, EXCEPTION_PC_LOCATION); 243 } 244 readTlabTop(Word thread)245 public static Word readTlabTop(Word thread) { 246 return thread.readWord(threadTlabTopOffset(INJECTED_VMCONFIG), TLAB_TOP_LOCATION); 247 } 248 readTlabEnd(Word thread)249 public static Word readTlabEnd(Word thread) { 250 return thread.readWord(threadTlabEndOffset(INJECTED_VMCONFIG), TLAB_END_LOCATION); 251 } 252 readTlabStart(Word thread)253 public static Word readTlabStart(Word thread) { 254 return thread.readWord(threadTlabStartOffset(INJECTED_VMCONFIG), TLAB_START_LOCATION); 255 } 256 writeTlabTop(Word thread, Word top)257 public static void writeTlabTop(Word thread, Word top) { 258 thread.writeWord(threadTlabTopOffset(INJECTED_VMCONFIG), top, TLAB_TOP_LOCATION); 259 } 260 261 @SuppressFBWarnings(value = "NP_NULL_PARAM_DEREF_NONVIRTUAL", justification = "foldable method parameters are injected") initializeTlab(Word thread, Word start, Word end)262 public static void initializeTlab(Word thread, Word start, Word end) { 263 thread.writeWord(threadTlabStartOffset(INJECTED_VMCONFIG), start, TLAB_START_LOCATION); 264 thread.writeWord(threadTlabTopOffset(INJECTED_VMCONFIG), start, TLAB_TOP_LOCATION); 265 thread.writeWord(threadTlabEndOffset(INJECTED_VMCONFIG), end, TLAB_END_LOCATION); 266 } 267 268 /** 269 * Clears the pending exception for the given thread. 270 * 271 * @return the pending exception, or null if there was none 272 */ 273 @SuppressFBWarnings(value = "NP_NULL_PARAM_DEREF_NONVIRTUAL", justification = "foldable method parameters are injected") clearPendingException(Word thread)274 public static Object clearPendingException(Word thread) { 275 Object result = thread.readObject(threadPendingExceptionOffset(INJECTED_VMCONFIG), PENDING_EXCEPTION_LOCATION); 276 thread.writeObject(threadPendingExceptionOffset(INJECTED_VMCONFIG), null, PENDING_EXCEPTION_LOCATION); 277 return result; 278 } 279 280 /** 281 * Reads the pending deoptimization value for the given thread. 282 * 283 * @return {@code true} if there was a pending deoptimization 284 */ readPendingDeoptimization(Word thread)285 public static int readPendingDeoptimization(Word thread) { 286 return thread.readInt(threadPendingDeoptimizationOffset(INJECTED_VMCONFIG), PENDING_DEOPTIMIZATION_LOCATION); 287 } 288 289 /** 290 * Writes the pending deoptimization value for the given thread. 291 */ writePendingDeoptimization(Word thread, int value)292 public static void writePendingDeoptimization(Word thread, int value) { 293 thread.writeInt(threadPendingDeoptimizationOffset(INJECTED_VMCONFIG), value, PENDING_DEOPTIMIZATION_LOCATION); 294 } 295 296 /** 297 * Gets and clears the object result from a runtime call stored in a thread local. 298 * 299 * @return the object that was in the thread local 300 */ getAndClearObjectResult(Word thread)301 public static Object getAndClearObjectResult(Word thread) { 302 Object result = thread.readObject(objectResultOffset(INJECTED_VMCONFIG), OBJECT_RESULT_LOCATION); 303 thread.writeObject(objectResultOffset(INJECTED_VMCONFIG), null, OBJECT_RESULT_LOCATION); 304 return result; 305 } 306 307 /* 308 * As far as Java code is concerned this can be considered immutable: it is set just after the 309 * JavaThread is created, before it is published. After that, it is never changed. 310 */ 311 public static final LocationIdentity JAVA_THREAD_THREAD_OBJECT_LOCATION = NamedLocationIdentity.immutable("JavaThread::_threadObj"); 312 313 @Fold threadObjectOffset(@njectedParameter GraalHotSpotVMConfig config)314 public static int threadObjectOffset(@InjectedParameter GraalHotSpotVMConfig config) { 315 return config.threadObjectOffset; 316 } 317 318 public static final LocationIdentity JAVA_THREAD_OSTHREAD_LOCATION = NamedLocationIdentity.mutable("JavaThread::_osthread"); 319 320 @Fold osThreadOffset(@njectedParameter GraalHotSpotVMConfig config)321 public static int osThreadOffset(@InjectedParameter GraalHotSpotVMConfig config) { 322 return config.osThreadOffset; 323 } 324 325 @Fold osThreadInterruptedOffset(@njectedParameter GraalHotSpotVMConfig config)326 public static int osThreadInterruptedOffset(@InjectedParameter GraalHotSpotVMConfig config) { 327 return config.osThreadInterruptedOffset; 328 } 329 330 @Fold getWordKind()331 public static JavaKind getWordKind() { 332 return runtime().getHostJVMCIBackend().getCodeCache().getTarget().wordJavaKind; 333 } 334 335 @Fold wordSize()336 public static int wordSize() { 337 return runtime().getHostJVMCIBackend().getCodeCache().getTarget().wordSize; 338 } 339 340 @Fold pageSize()341 public static int pageSize() { 342 return UNSAFE.pageSize(); 343 } 344 345 @Fold heapWordSize(@njectedParameter GraalHotSpotVMConfig config)346 public static int heapWordSize(@InjectedParameter GraalHotSpotVMConfig config) { 347 return config.heapWordSize; 348 } 349 350 public static final LocationIdentity PROTOTYPE_MARK_WORD_LOCATION = NamedLocationIdentity.mutable("PrototypeMarkWord"); 351 352 @Fold prototypeMarkWordOffset(@njectedParameter GraalHotSpotVMConfig config)353 public static int prototypeMarkWordOffset(@InjectedParameter GraalHotSpotVMConfig config) { 354 return config.prototypeMarkWordOffset; 355 } 356 357 @Fold arrayPrototypeMarkWord(@njectedParameter GraalHotSpotVMConfig config)358 public static long arrayPrototypeMarkWord(@InjectedParameter GraalHotSpotVMConfig config) { 359 return config.arrayPrototypeMarkWord(); 360 } 361 362 public static final LocationIdentity KLASS_ACCESS_FLAGS_LOCATION = NamedLocationIdentity.immutable("Klass::_access_flags"); 363 364 @Fold klassAccessFlagsOffset(@njectedParameter GraalHotSpotVMConfig config)365 public static int klassAccessFlagsOffset(@InjectedParameter GraalHotSpotVMConfig config) { 366 return config.klassAccessFlagsOffset; 367 } 368 369 @Fold jvmAccWrittenFlags(@njectedParameter GraalHotSpotVMConfig config)370 public static int jvmAccWrittenFlags(@InjectedParameter GraalHotSpotVMConfig config) { 371 return config.jvmAccWrittenFlags; 372 } 373 374 public static final LocationIdentity KLASS_LAYOUT_HELPER_LOCATION = new HotSpotOptimizingLocationIdentity("Klass::_layout_helper") { 375 @Override 376 public ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool) { 377 ValueNode javaObject = findReadHub(object); 378 if (javaObject != null) { 379 if (javaObject.stamp(NodeView.DEFAULT) instanceof ObjectStamp) { 380 ObjectStamp stamp = (ObjectStamp) javaObject.stamp(NodeView.DEFAULT); 381 HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) stamp.javaType(tool.getMetaAccess()); 382 if (type.isArray() && !type.getComponentType().isPrimitive()) { 383 int layout = type.layoutHelper(); 384 return ConstantNode.forInt(layout); 385 } 386 } 387 } 388 return read; 389 } 390 }; 391 392 @Fold klassLayoutHelperOffset(@njectedParameter GraalHotSpotVMConfig config)393 public static int klassLayoutHelperOffset(@InjectedParameter GraalHotSpotVMConfig config) { 394 return config.klassLayoutHelperOffset; 395 } 396 397 @NodeIntrinsic(value = KlassLayoutHelperNode.class) readLayoutHelper(KlassPointer object)398 public static native int readLayoutHelper(KlassPointer object); 399 400 /** 401 * Checks if class {@code klass} is an array. 402 * 403 * See: Klass::layout_helper_is_array 404 * 405 * @param klassNonNull the class to be checked 406 * @return true if klassNonNull is an array, false otherwise 407 */ klassIsArray(KlassPointer klassNonNull)408 public static boolean klassIsArray(KlassPointer klassNonNull) { 409 /* 410 * The less-than check only works if both values are ints. We use local variables to make 411 * sure these are still ints and haven't changed. 412 */ 413 final int layoutHelper = readLayoutHelper(klassNonNull); 414 final int layoutHelperNeutralValue = config(INJECTED_VMCONFIG).klassLayoutHelperNeutralValue; 415 return (layoutHelper < layoutHelperNeutralValue); 416 } 417 418 public static final LocationIdentity ARRAY_KLASS_COMPONENT_MIRROR = NamedLocationIdentity.immutable("ArrayKlass::_component_mirror"); 419 420 @Fold arrayKlassComponentMirrorOffset(@njectedParameter GraalHotSpotVMConfig config)421 public static int arrayKlassComponentMirrorOffset(@InjectedParameter GraalHotSpotVMConfig config) { 422 return config.getFieldOffset("ArrayKlass::_component_mirror", Integer.class, "oop"); 423 } 424 425 public static final LocationIdentity KLASS_SUPER_KLASS_LOCATION = NamedLocationIdentity.immutable("Klass::_super"); 426 427 @Fold klassSuperKlassOffset(@njectedParameter GraalHotSpotVMConfig config)428 public static int klassSuperKlassOffset(@InjectedParameter GraalHotSpotVMConfig config) { 429 return config.klassSuperKlassOffset; 430 } 431 432 public static final LocationIdentity MARK_WORD_LOCATION = NamedLocationIdentity.mutable("MarkWord"); 433 434 @Fold markOffset(@njectedParameter GraalHotSpotVMConfig config)435 public static int markOffset(@InjectedParameter GraalHotSpotVMConfig config) { 436 return config.markOffset; 437 } 438 439 public static final LocationIdentity HUB_WRITE_LOCATION = NamedLocationIdentity.mutable("Hub:write"); 440 441 public static final LocationIdentity HUB_LOCATION = new HotSpotOptimizingLocationIdentity("Hub") { 442 @Override 443 public ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool) { 444 TypeReference constantType = StampTool.typeReferenceOrNull(object); 445 if (constantType != null && constantType.isExact()) { 446 return ConstantNode.forConstant(read.stamp(NodeView.DEFAULT), tool.getConstantReflection().asObjectHub(constantType.getType()), tool.getMetaAccess()); 447 } 448 return read; 449 } 450 }; 451 452 public static final LocationIdentity COMPRESSED_HUB_LOCATION = new HotSpotOptimizingLocationIdentity("CompressedHub") { 453 @Override 454 public ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool) { 455 TypeReference constantType = StampTool.typeReferenceOrNull(object); 456 if (constantType != null && constantType.isExact()) { 457 return ConstantNode.forConstant(read.stamp(NodeView.DEFAULT), ((HotSpotMetaspaceConstant) tool.getConstantReflection().asObjectHub(constantType.getType())).compress(), 458 tool.getMetaAccess()); 459 } 460 return read; 461 } 462 }; 463 464 @Fold hubOffset(@njectedParameter GraalHotSpotVMConfig config)465 static int hubOffset(@InjectedParameter GraalHotSpotVMConfig config) { 466 return config.hubOffset; 467 } 468 initializeObjectHeader(Word memory, Word markWord, KlassPointer hub)469 public static void initializeObjectHeader(Word memory, Word markWord, KlassPointer hub) { 470 memory.writeWord(markOffset(INJECTED_VMCONFIG), markWord, MARK_WORD_LOCATION); 471 StoreHubNode.write(memory, hub); 472 } 473 474 @Fold unlockedMask(@njectedParameter GraalHotSpotVMConfig config)475 public static int unlockedMask(@InjectedParameter GraalHotSpotVMConfig config) { 476 return config.unlockedMask; 477 } 478 479 @Fold monitorMask(@njectedParameter GraalHotSpotVMConfig config)480 public static int monitorMask(@InjectedParameter GraalHotSpotVMConfig config) { 481 return config.monitorMask; 482 } 483 484 @Fold objectMonitorOwnerOffset(@njectedParameter GraalHotSpotVMConfig config)485 public static int objectMonitorOwnerOffset(@InjectedParameter GraalHotSpotVMConfig config) { 486 return config.objectMonitorOwner; 487 } 488 489 @Fold objectMonitorRecursionsOffset(@njectedParameter GraalHotSpotVMConfig config)490 public static int objectMonitorRecursionsOffset(@InjectedParameter GraalHotSpotVMConfig config) { 491 return config.objectMonitorRecursions; 492 } 493 494 @Fold objectMonitorCxqOffset(@njectedParameter GraalHotSpotVMConfig config)495 public static int objectMonitorCxqOffset(@InjectedParameter GraalHotSpotVMConfig config) { 496 return config.objectMonitorCxq; 497 } 498 499 @Fold objectMonitorEntryListOffset(@njectedParameter GraalHotSpotVMConfig config)500 public static int objectMonitorEntryListOffset(@InjectedParameter GraalHotSpotVMConfig config) { 501 return config.objectMonitorEntryList; 502 } 503 504 /** 505 * Mask for a biasable, locked or unlocked mark word. 506 * 507 * <pre> 508 * +----------------------------------+-+-+ 509 * | 1|1|1| 510 * +----------------------------------+-+-+ 511 * </pre> 512 * 513 */ 514 @Fold biasedLockMaskInPlace(@njectedParameter GraalHotSpotVMConfig config)515 public static int biasedLockMaskInPlace(@InjectedParameter GraalHotSpotVMConfig config) { 516 return config.biasedLockMaskInPlace; 517 } 518 519 @Fold epochMaskInPlace(@njectedParameter GraalHotSpotVMConfig config)520 public static int epochMaskInPlace(@InjectedParameter GraalHotSpotVMConfig config) { 521 return config.epochMaskInPlace; 522 } 523 524 /** 525 * Pattern for a biasable, unlocked mark word. 526 * 527 * <pre> 528 * +----------------------------------+-+-+ 529 * | 1|0|1| 530 * +----------------------------------+-+-+ 531 * </pre> 532 * 533 */ 534 @Fold biasedLockPattern(@njectedParameter GraalHotSpotVMConfig config)535 public static int biasedLockPattern(@InjectedParameter GraalHotSpotVMConfig config) { 536 return config.biasedLockPattern; 537 } 538 539 @Fold ageMaskInPlace(@njectedParameter GraalHotSpotVMConfig config)540 public static int ageMaskInPlace(@InjectedParameter GraalHotSpotVMConfig config) { 541 return config.ageMaskInPlace; 542 } 543 544 @Fold metaspaceArrayLengthOffset(@njectedParameter GraalHotSpotVMConfig config)545 public static int metaspaceArrayLengthOffset(@InjectedParameter GraalHotSpotVMConfig config) { 546 return config.metaspaceArrayLengthOffset; 547 } 548 549 @Fold metaspaceArrayBaseOffset(@njectedParameter GraalHotSpotVMConfig config)550 public static int metaspaceArrayBaseOffset(@InjectedParameter GraalHotSpotVMConfig config) { 551 return config.metaspaceArrayBaseOffset; 552 } 553 554 @Fold arrayLengthOffset(@njectedParameter GraalHotSpotVMConfig config)555 public static int arrayLengthOffset(@InjectedParameter GraalHotSpotVMConfig config) { 556 return config.arrayOopDescLengthOffset(); 557 } 558 559 @Fold getArrayBaseOffset(@njectedParameter MetaAccessProvider metaAccessProvider, JavaKind elementKind)560 public static int getArrayBaseOffset(@InjectedParameter MetaAccessProvider metaAccessProvider, JavaKind elementKind) { 561 return metaAccessProvider.getArrayBaseOffset(elementKind); 562 } 563 564 @Fold arrayIndexScale(@njectedParameter MetaAccessProvider metaAccessProvider, JavaKind elementKind)565 public static int arrayIndexScale(@InjectedParameter MetaAccessProvider metaAccessProvider, JavaKind elementKind) { 566 return metaAccessProvider.getArrayIndexScale(elementKind); 567 } 568 arrayStart(int[] a)569 public static Word arrayStart(int[] a) { 570 return WordFactory.unsigned(ComputeObjectAddressNode.get(a, getArrayBaseOffset(INJECTED_METAACCESS, JavaKind.Int))); 571 } 572 573 /** 574 * Idiom for making {@link GraalHotSpotVMConfig} a constant. 575 */ 576 @Fold getConfig(@njectedParameter GraalHotSpotVMConfig config)577 public static GraalHotSpotVMConfig getConfig(@InjectedParameter GraalHotSpotVMConfig config) { 578 return config; 579 } 580 581 /** 582 * Calls {@link #arrayAllocationSize(int, int, int, GraalHotSpotVMConfig)} using an injected VM 583 * configuration object. 584 */ arrayAllocationSize(int length, int headerSize, int log2ElementSize)585 public static int arrayAllocationSize(int length, int headerSize, int log2ElementSize) { 586 return arrayAllocationSize(length, headerSize, log2ElementSize, getConfig(INJECTED_VMCONFIG)); 587 } 588 589 /** 590 * Computes the size of the memory chunk allocated for an array. This size accounts for the 591 * array header size, body size and any padding after the last element to satisfy object 592 * alignment requirements. 593 * 594 * @param length the number of elements in the array 595 * @param headerSize the size of the array header 596 * @param log2ElementSize log2 of the size of an element in the array 597 * @param config the VM configuration providing the 598 * {@linkplain GraalHotSpotVMConfig#objectAlignment object alignment requirement} 599 * @return the size of the memory chunk 600 */ arrayAllocationSize(int length, int headerSize, int log2ElementSize, GraalHotSpotVMConfig config)601 public static int arrayAllocationSize(int length, int headerSize, int log2ElementSize, GraalHotSpotVMConfig config) { 602 int alignment = config.objectAlignment; 603 int size = (length << log2ElementSize) + headerSize + (alignment - 1); 604 int mask = ~(alignment - 1); 605 return size & mask; 606 } 607 608 @Fold instanceHeaderSize(@njectedParameter GraalHotSpotVMConfig config)609 public static int instanceHeaderSize(@InjectedParameter GraalHotSpotVMConfig config) { 610 return config.useCompressedClassPointers ? (2 * wordSize()) - 4 : 2 * wordSize(); 611 } 612 613 @Fold dirtyCardValue(@njectedParameter GraalHotSpotVMConfig config)614 public static byte dirtyCardValue(@InjectedParameter GraalHotSpotVMConfig config) { 615 return config.dirtyCardValue; 616 } 617 618 @Fold g1YoungCardValue(@njectedParameter GraalHotSpotVMConfig config)619 public static byte g1YoungCardValue(@InjectedParameter GraalHotSpotVMConfig config) { 620 return config.g1YoungCardValue; 621 } 622 623 @Fold cardTableShift(@njectedParameter GraalHotSpotVMConfig config)624 public static int cardTableShift(@InjectedParameter GraalHotSpotVMConfig config) { 625 return config.cardtableShift; 626 } 627 628 @Fold cardTableStart(@njectedParameter GraalHotSpotVMConfig config)629 public static long cardTableStart(@InjectedParameter GraalHotSpotVMConfig config) { 630 return config.cardtableStartAddress; 631 } 632 633 @Fold g1CardQueueIndexOffset(@njectedParameter GraalHotSpotVMConfig config)634 public static int g1CardQueueIndexOffset(@InjectedParameter GraalHotSpotVMConfig config) { 635 return config.g1CardQueueIndexOffset; 636 } 637 638 @Fold g1CardQueueBufferOffset(@njectedParameter GraalHotSpotVMConfig config)639 public static int g1CardQueueBufferOffset(@InjectedParameter GraalHotSpotVMConfig config) { 640 return config.g1CardQueueBufferOffset; 641 } 642 643 @Fold logOfHeapRegionGrainBytes(@njectedParameter GraalHotSpotVMConfig config)644 public static int logOfHeapRegionGrainBytes(@InjectedParameter GraalHotSpotVMConfig config) { 645 return config.logOfHRGrainBytes; 646 } 647 648 @Fold g1SATBQueueMarkingOffset(@njectedParameter GraalHotSpotVMConfig config)649 public static int g1SATBQueueMarkingOffset(@InjectedParameter GraalHotSpotVMConfig config) { 650 return config.g1SATBQueueMarkingOffset; 651 } 652 653 @Fold g1SATBQueueIndexOffset(@njectedParameter GraalHotSpotVMConfig config)654 public static int g1SATBQueueIndexOffset(@InjectedParameter GraalHotSpotVMConfig config) { 655 return config.g1SATBQueueIndexOffset; 656 } 657 658 @Fold g1SATBQueueBufferOffset(@njectedParameter GraalHotSpotVMConfig config)659 public static int g1SATBQueueBufferOffset(@InjectedParameter GraalHotSpotVMConfig config) { 660 return config.g1SATBQueueBufferOffset; 661 } 662 663 public static final LocationIdentity KLASS_SUPER_CHECK_OFFSET_LOCATION = NamedLocationIdentity.immutable("Klass::_super_check_offset"); 664 665 @Fold superCheckOffsetOffset(@njectedParameter GraalHotSpotVMConfig config)666 public static int superCheckOffsetOffset(@InjectedParameter GraalHotSpotVMConfig config) { 667 return config.superCheckOffsetOffset; 668 } 669 670 public static final LocationIdentity SECONDARY_SUPER_CACHE_LOCATION = NamedLocationIdentity.mutable("SecondarySuperCache"); 671 672 @Fold secondarySuperCacheOffset(@njectedParameter GraalHotSpotVMConfig config)673 public static int secondarySuperCacheOffset(@InjectedParameter GraalHotSpotVMConfig config) { 674 return config.secondarySuperCacheOffset; 675 } 676 677 public static final LocationIdentity SECONDARY_SUPERS_LOCATION = NamedLocationIdentity.immutable("SecondarySupers"); 678 679 @Fold secondarySupersOffset(@njectedParameter GraalHotSpotVMConfig config)680 public static int secondarySupersOffset(@InjectedParameter GraalHotSpotVMConfig config) { 681 return config.secondarySupersOffset; 682 } 683 684 public static final LocationIdentity DISPLACED_MARK_WORD_LOCATION = NamedLocationIdentity.mutable("DisplacedMarkWord"); 685 686 public static final LocationIdentity OBJECT_MONITOR_OWNER_LOCATION = NamedLocationIdentity.mutable("ObjectMonitor::_owner"); 687 688 public static final LocationIdentity OBJECT_MONITOR_RECURSION_LOCATION = NamedLocationIdentity.mutable("ObjectMonitor::_recursions"); 689 690 public static final LocationIdentity OBJECT_MONITOR_CXQ_LOCATION = NamedLocationIdentity.mutable("ObjectMonitor::_cxq"); 691 692 public static final LocationIdentity OBJECT_MONITOR_ENTRY_LIST_LOCATION = NamedLocationIdentity.mutable("ObjectMonitor::_EntryList"); 693 694 @Fold lockDisplacedMarkOffset(@njectedParameter GraalHotSpotVMConfig config)695 public static int lockDisplacedMarkOffset(@InjectedParameter GraalHotSpotVMConfig config) { 696 return config.basicLockDisplacedHeaderOffset; 697 } 698 699 @Fold useBiasedLocking(@njectedParameter GraalHotSpotVMConfig config)700 public static boolean useBiasedLocking(@InjectedParameter GraalHotSpotVMConfig config) { 701 return config.useBiasedLocking; 702 } 703 704 @Fold useDeferredInitBarriers(@njectedParameter GraalHotSpotVMConfig config)705 public static boolean useDeferredInitBarriers(@InjectedParameter GraalHotSpotVMConfig config) { 706 return config.useDeferredInitBarriers; 707 } 708 709 @Fold useG1GC(@njectedParameter GraalHotSpotVMConfig config)710 public static boolean useG1GC(@InjectedParameter GraalHotSpotVMConfig config) { 711 return config.useG1GC; 712 } 713 714 @Fold useCMSIncrementalMode(@njectedParameter GraalHotSpotVMConfig config)715 public static boolean useCMSIncrementalMode(@InjectedParameter GraalHotSpotVMConfig config) { 716 return config.cmsIncrementalMode; 717 } 718 719 @Fold useCompressedOops(@njectedParameter GraalHotSpotVMConfig config)720 public static boolean useCompressedOops(@InjectedParameter GraalHotSpotVMConfig config) { 721 return config.useCompressedOops; 722 } 723 724 @Fold uninitializedIdentityHashCodeValue(@njectedParameter GraalHotSpotVMConfig config)725 static int uninitializedIdentityHashCodeValue(@InjectedParameter GraalHotSpotVMConfig config) { 726 return config.uninitializedIdentityHashCodeValue; 727 } 728 729 @Fold identityHashCodeShift(@njectedParameter GraalHotSpotVMConfig config)730 static int identityHashCodeShift(@InjectedParameter GraalHotSpotVMConfig config) { 731 return config.identityHashCodeShift; 732 } 733 734 /** 735 * Loads the hub of an object (without null checking it first). 736 */ loadHub(Object object)737 public static KlassPointer loadHub(Object object) { 738 return loadHubIntrinsic(object); 739 } 740 verifyOop(Object object)741 public static Object verifyOop(Object object) { 742 if (verifyOops(INJECTED_VMCONFIG)) { 743 verifyOopStub(VERIFY_OOP, object); 744 } 745 return object; 746 } 747 748 @NodeIntrinsic(ForeignCallNode.class) verifyOopStub(@onstantNodeParameter ForeignCallDescriptor descriptor, Object object)749 private static native Object verifyOopStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Object object); 750 loadWordFromObject(Object object, int offset)751 public static Word loadWordFromObject(Object object, int offset) { 752 ReplacementsUtil.staticAssert(offset != hubOffset(INJECTED_VMCONFIG), "Use loadHubIntrinsic instead of loadWordFromObject"); 753 return loadWordFromObjectIntrinsic(object, offset, LocationIdentity.any(), getWordKind()); 754 } 755 loadWordFromObject(Object object, int offset, LocationIdentity identity)756 public static Word loadWordFromObject(Object object, int offset, LocationIdentity identity) { 757 ReplacementsUtil.staticAssert(offset != hubOffset(INJECTED_VMCONFIG), "Use loadHubIntrinsic instead of loadWordFromObject"); 758 return loadWordFromObjectIntrinsic(object, offset, identity, getWordKind()); 759 } 760 loadKlassFromObject(Object object, int offset, LocationIdentity identity)761 public static KlassPointer loadKlassFromObject(Object object, int offset, LocationIdentity identity) { 762 ReplacementsUtil.staticAssert(offset != hubOffset(INJECTED_VMCONFIG), "Use loadHubIntrinsic instead of loadWordFromObject"); 763 return loadKlassFromObjectIntrinsic(object, offset, identity, getWordKind()); 764 } 765 766 /** 767 * Reads the value of a given register. 768 * 769 * @param register a register which must not be available to the register allocator 770 * @return the value of {@code register} as a word 771 */ registerAsWord(@onstantNodeParameter Register register)772 public static Word registerAsWord(@ConstantNodeParameter Register register) { 773 return registerAsWord(register, true, false); 774 } 775 776 @NodeIntrinsic(value = ReadRegisterNode.class) registerAsWord(@onstantNodeParameter Register register, @ConstantNodeParameter boolean directUse, @ConstantNodeParameter boolean incoming)777 public static native Word registerAsWord(@ConstantNodeParameter Register register, @ConstantNodeParameter boolean directUse, @ConstantNodeParameter boolean incoming); 778 779 @NodeIntrinsic(value = WriteRegisterNode.class) writeRegisterAsWord(@onstantNodeParameter Register register, Word value)780 public static native void writeRegisterAsWord(@ConstantNodeParameter Register register, Word value); 781 782 @NodeIntrinsic(value = RawLoadNode.class) loadWordFromObjectIntrinsic(Object object, long offset, @ConstantNodeParameter LocationIdentity locationIdentity, @ConstantNodeParameter JavaKind wordKind)783 private static native Word loadWordFromObjectIntrinsic(Object object, long offset, @ConstantNodeParameter LocationIdentity locationIdentity, @ConstantNodeParameter JavaKind wordKind); 784 785 @NodeIntrinsic(value = RawLoadNode.class) loadKlassFromObjectIntrinsic(Object object, long offset, @ConstantNodeParameter LocationIdentity locationIdentity, @ConstantNodeParameter JavaKind wordKind)786 private static native KlassPointer loadKlassFromObjectIntrinsic(Object object, long offset, @ConstantNodeParameter LocationIdentity locationIdentity, @ConstantNodeParameter JavaKind wordKind); 787 788 @NodeIntrinsic(value = LoadHubNode.class) loadHubIntrinsic(Object object)789 public static native KlassPointer loadHubIntrinsic(Object object); 790 791 @Fold log2WordSize()792 public static int log2WordSize() { 793 return CodeUtil.log2(wordSize()); 794 } 795 796 public static final LocationIdentity CLASS_STATE_LOCATION = NamedLocationIdentity.mutable("ClassState"); 797 798 @Fold instanceKlassInitStateOffset(@njectedParameter GraalHotSpotVMConfig config)799 public static int instanceKlassInitStateOffset(@InjectedParameter GraalHotSpotVMConfig config) { 800 return config.instanceKlassInitStateOffset; 801 } 802 803 @Fold instanceKlassStateFullyInitialized(@njectedParameter GraalHotSpotVMConfig config)804 public static int instanceKlassStateFullyInitialized(@InjectedParameter GraalHotSpotVMConfig config) { 805 return config.instanceKlassStateFullyInitialized; 806 } 807 808 /** 809 * 810 * @param hub the hub of an InstanceKlass 811 * @return true is the InstanceKlass represented by hub is fully initialized 812 */ isInstanceKlassFullyInitialized(KlassPointer hub)813 public static boolean isInstanceKlassFullyInitialized(KlassPointer hub) { 814 return readInstanceKlassState(hub) == instanceKlassStateFullyInitialized(INJECTED_VMCONFIG); 815 } 816 readInstanceKlassState(KlassPointer hub)817 private static byte readInstanceKlassState(KlassPointer hub) { 818 return hub.readByte(instanceKlassInitStateOffset(INJECTED_VMCONFIG), CLASS_STATE_LOCATION); 819 } 820 821 public static final LocationIdentity KLASS_MODIFIER_FLAGS_LOCATION = NamedLocationIdentity.immutable("Klass::_modifier_flags"); 822 823 @Fold klassModifierFlagsOffset(@njectedParameter GraalHotSpotVMConfig config)824 public static int klassModifierFlagsOffset(@InjectedParameter GraalHotSpotVMConfig config) { 825 return config.klassModifierFlagsOffset; 826 } 827 828 public static final LocationIdentity CLASS_KLASS_LOCATION = new HotSpotOptimizingLocationIdentity("Class._klass") { 829 @Override 830 public ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool) { 831 return foldIndirection(read, object, CLASS_MIRROR_LOCATION); 832 } 833 }; 834 835 @Fold klassOffset(@njectedParameter GraalHotSpotVMConfig config)836 public static int klassOffset(@InjectedParameter GraalHotSpotVMConfig config) { 837 return config.klassOffset; 838 } 839 840 public static final LocationIdentity CLASS_ARRAY_KLASS_LOCATION = new HotSpotOptimizingLocationIdentity("Class._array_klass") { 841 @Override 842 public ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool) { 843 return foldIndirection(read, object, ARRAY_KLASS_COMPONENT_MIRROR); 844 } 845 }; 846 847 @Fold arrayKlassOffset(@njectedParameter GraalHotSpotVMConfig config)848 public static int arrayKlassOffset(@InjectedParameter GraalHotSpotVMConfig config) { 849 return config.arrayKlassOffset; 850 } 851 852 public static final LocationIdentity CLASS_MIRROR_LOCATION = NamedLocationIdentity.immutable("Klass::_java_mirror"); 853 854 public static final LocationIdentity CLASS_MIRROR_HANDLE_LOCATION = NamedLocationIdentity.immutable("Klass::_java_mirror handle"); 855 856 public static final LocationIdentity HEAP_TOP_LOCATION = NamedLocationIdentity.mutable("HeapTop"); 857 858 @Fold heapTopAddress(@njectedParameter GraalHotSpotVMConfig config)859 public static long heapTopAddress(@InjectedParameter GraalHotSpotVMConfig config) { 860 return config.heapTopAddress; 861 } 862 863 public static final LocationIdentity HEAP_END_LOCATION = NamedLocationIdentity.mutable("HeapEnd"); 864 865 @Fold heapEndAddress(@njectedParameter GraalHotSpotVMConfig config)866 public static long heapEndAddress(@InjectedParameter GraalHotSpotVMConfig config) { 867 return config.heapEndAddress; 868 } 869 870 @Fold tlabIntArrayMarkWord(@njectedParameter GraalHotSpotVMConfig config)871 public static long tlabIntArrayMarkWord(@InjectedParameter GraalHotSpotVMConfig config) { 872 return config.tlabIntArrayMarkWord(); 873 } 874 875 @Fold inlineContiguousAllocationSupported(@njectedParameter GraalHotSpotVMConfig config)876 public static boolean inlineContiguousAllocationSupported(@InjectedParameter GraalHotSpotVMConfig config) { 877 return config.inlineContiguousAllocationSupported; 878 } 879 880 @Fold tlabAlignmentReserveInHeapWords(@njectedParameter GraalHotSpotVMConfig config)881 public static int tlabAlignmentReserveInHeapWords(@InjectedParameter GraalHotSpotVMConfig config) { 882 return config.tlabAlignmentReserve; 883 } 884 885 public static final LocationIdentity TLAB_SIZE_LOCATION = NamedLocationIdentity.mutable("TlabSize"); 886 887 @Fold threadTlabSizeOffset(@njectedParameter GraalHotSpotVMConfig config)888 public static int threadTlabSizeOffset(@InjectedParameter GraalHotSpotVMConfig config) { 889 return config.threadTlabSizeOffset(); 890 } 891 892 public static final LocationIdentity TLAB_THREAD_ALLOCATED_BYTES_LOCATION = NamedLocationIdentity.mutable("TlabThreadAllocatedBytes"); 893 894 @Fold threadAllocatedBytesOffset(@njectedParameter GraalHotSpotVMConfig config)895 public static int threadAllocatedBytesOffset(@InjectedParameter GraalHotSpotVMConfig config) { 896 return config.threadAllocatedBytesOffset; 897 } 898 899 public static final LocationIdentity TLAB_REFILL_WASTE_LIMIT_LOCATION = NamedLocationIdentity.mutable("RefillWasteLimit"); 900 901 @Fold tlabRefillWasteLimitOffset(@njectedParameter GraalHotSpotVMConfig config)902 public static int tlabRefillWasteLimitOffset(@InjectedParameter GraalHotSpotVMConfig config) { 903 return config.tlabRefillWasteLimitOffset(); 904 } 905 906 public static final LocationIdentity TLAB_NOF_REFILLS_LOCATION = NamedLocationIdentity.mutable("TlabNOfRefills"); 907 908 @Fold tlabNumberOfRefillsOffset(@njectedParameter GraalHotSpotVMConfig config)909 public static int tlabNumberOfRefillsOffset(@InjectedParameter GraalHotSpotVMConfig config) { 910 return config.tlabNumberOfRefillsOffset(); 911 } 912 913 public static final LocationIdentity TLAB_FAST_REFILL_WASTE_LOCATION = NamedLocationIdentity.mutable("TlabFastRefillWaste"); 914 915 @Fold tlabFastRefillWasteOffset(@njectedParameter GraalHotSpotVMConfig config)916 public static int tlabFastRefillWasteOffset(@InjectedParameter GraalHotSpotVMConfig config) { 917 return config.tlabFastRefillWasteOffset(); 918 } 919 920 public static final LocationIdentity TLAB_SLOW_ALLOCATIONS_LOCATION = NamedLocationIdentity.mutable("TlabSlowAllocations"); 921 922 @Fold tlabSlowAllocationsOffset(@njectedParameter GraalHotSpotVMConfig config)923 public static int tlabSlowAllocationsOffset(@InjectedParameter GraalHotSpotVMConfig config) { 924 return config.tlabSlowAllocationsOffset(); 925 } 926 927 @Fold tlabRefillWasteIncrement(@njectedParameter GraalHotSpotVMConfig config)928 public static int tlabRefillWasteIncrement(@InjectedParameter GraalHotSpotVMConfig config) { 929 return config.tlabRefillWasteIncrement; 930 } 931 932 @Fold tlabStats(@njectedParameter GraalHotSpotVMConfig config)933 public static boolean tlabStats(@InjectedParameter GraalHotSpotVMConfig config) { 934 return config.tlabStats; 935 } 936 937 @Fold layoutHelperHeaderSizeShift(@njectedParameter GraalHotSpotVMConfig config)938 public static int layoutHelperHeaderSizeShift(@InjectedParameter GraalHotSpotVMConfig config) { 939 return config.layoutHelperHeaderSizeShift; 940 } 941 942 @Fold layoutHelperHeaderSizeMask(@njectedParameter GraalHotSpotVMConfig config)943 public static int layoutHelperHeaderSizeMask(@InjectedParameter GraalHotSpotVMConfig config) { 944 return config.layoutHelperHeaderSizeMask; 945 } 946 947 @Fold layoutHelperLog2ElementSizeShift(@njectedParameter GraalHotSpotVMConfig config)948 public static int layoutHelperLog2ElementSizeShift(@InjectedParameter GraalHotSpotVMConfig config) { 949 return config.layoutHelperLog2ElementSizeShift; 950 } 951 952 @Fold layoutHelperLog2ElementSizeMask(@njectedParameter GraalHotSpotVMConfig config)953 public static int layoutHelperLog2ElementSizeMask(@InjectedParameter GraalHotSpotVMConfig config) { 954 return config.layoutHelperLog2ElementSizeMask; 955 } 956 957 @Fold layoutHelperElementTypeShift(@njectedParameter GraalHotSpotVMConfig config)958 public static int layoutHelperElementTypeShift(@InjectedParameter GraalHotSpotVMConfig config) { 959 return config.layoutHelperElementTypeShift; 960 } 961 962 @Fold layoutHelperElementTypeMask(@njectedParameter GraalHotSpotVMConfig config)963 public static int layoutHelperElementTypeMask(@InjectedParameter GraalHotSpotVMConfig config) { 964 return config.layoutHelperElementTypeMask; 965 } 966 967 @Fold layoutHelperElementTypePrimitiveInPlace(@njectedParameter GraalHotSpotVMConfig config)968 public static int layoutHelperElementTypePrimitiveInPlace(@InjectedParameter GraalHotSpotVMConfig config) { 969 return config.layoutHelperElementTypePrimitiveInPlace(); 970 } 971 972 @NodeIntrinsic(ForeignCallNode.class) identityHashCode(@onstantNodeParameter ForeignCallDescriptor descriptor, Object object)973 public static native int identityHashCode(@ConstantNodeParameter ForeignCallDescriptor descriptor, Object object); 974 975 @Fold verifiedEntryPointOffset(@njectedParameter GraalHotSpotVMConfig config)976 public static int verifiedEntryPointOffset(@InjectedParameter GraalHotSpotVMConfig config) { 977 return config.nmethodEntryOffset; 978 } 979 980 @Fold gcTotalCollectionsAddress(@njectedParameter GraalHotSpotVMConfig config)981 public static long gcTotalCollectionsAddress(@InjectedParameter GraalHotSpotVMConfig config) { 982 return config.gcTotalCollectionsAddress(); 983 } 984 985 @Fold referentOffset()986 public static long referentOffset() { 987 try { 988 return UNSAFE.objectFieldOffset(java.lang.ref.Reference.class.getDeclaredField("referent")); 989 } catch (Exception e) { 990 throw new GraalError(e); 991 } 992 } 993 994 public static final LocationIdentity OBJ_ARRAY_KLASS_ELEMENT_KLASS_LOCATION = new HotSpotOptimizingLocationIdentity("ObjArrayKlass::_element_klass") { 995 @Override 996 public ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool) { 997 ValueNode javaObject = findReadHub(object); 998 if (javaObject != null) { 999 ResolvedJavaType type = StampTool.typeOrNull(javaObject); 1000 if (type != null && type.isArray()) { 1001 ResolvedJavaType element = type.getComponentType(); 1002 if (element != null && !element.isPrimitive() && !element.getElementalType().isInterface()) { 1003 Assumptions assumptions = object.graph().getAssumptions(); 1004 AssumptionResult<ResolvedJavaType> leafType = element.findLeafConcreteSubtype(); 1005 if (leafType != null && leafType.canRecordTo(assumptions)) { 1006 leafType.recordTo(assumptions); 1007 return ConstantNode.forConstant(read.stamp(NodeView.DEFAULT), tool.getConstantReflection().asObjectHub(leafType.getResult()), tool.getMetaAccess()); 1008 } 1009 } 1010 } 1011 } 1012 return read; 1013 } 1014 }; 1015 1016 @Fold arrayClassElementOffset(@njectedParameter GraalHotSpotVMConfig config)1017 public static int arrayClassElementOffset(@InjectedParameter GraalHotSpotVMConfig config) { 1018 return config.arrayClassElementOffset; 1019 } 1020 1021 public static final LocationIdentity PRIMARY_SUPERS_LOCATION = NamedLocationIdentity.immutable("PrimarySupers"); 1022 1023 public static final LocationIdentity METASPACE_ARRAY_LENGTH_LOCATION = NamedLocationIdentity.immutable("MetaspaceArrayLength"); 1024 1025 public static final LocationIdentity SECONDARY_SUPERS_ELEMENT_LOCATION = NamedLocationIdentity.immutable("SecondarySupersElement"); 1026 1027 @Fold useFastTLABRefill(@njectedParameter GraalHotSpotVMConfig config)1028 public static boolean useFastTLABRefill(@InjectedParameter GraalHotSpotVMConfig config) { 1029 return config.useFastTLABRefill; 1030 } 1031 } 1032