52 import static org.graalvm.compiler.hotspot.HotSpotBackend.NEW_INSTANCE_OR_NULL;
53 import static org.graalvm.compiler.hotspot.HotSpotBackend.NEW_MULTI_ARRAY;
54 import static org.graalvm.compiler.hotspot.HotSpotBackend.NEW_MULTI_ARRAY_OR_NULL;
55 import static org.graalvm.compiler.hotspot.HotSpotBackend.RESOLVE_DYNAMIC_INVOKE;
56 import static org.graalvm.compiler.hotspot.HotSpotBackend.RESOLVE_KLASS_BY_SYMBOL;
57 import static org.graalvm.compiler.hotspot.HotSpotBackend.RESOLVE_METHOD_BY_SYMBOL_AND_LOAD_COUNTERS;
58 import static org.graalvm.compiler.hotspot.HotSpotBackend.RESOLVE_STRING_BY_SYMBOL;
59 import static org.graalvm.compiler.hotspot.HotSpotBackend.SHA2_IMPL_COMPRESS;
60 import static org.graalvm.compiler.hotspot.HotSpotBackend.SHA2_IMPL_COMPRESS_MB;
61 import static org.graalvm.compiler.hotspot.HotSpotBackend.SHA5_IMPL_COMPRESS;
62 import static org.graalvm.compiler.hotspot.HotSpotBackend.SHA5_IMPL_COMPRESS_MB;
63 import static org.graalvm.compiler.hotspot.HotSpotBackend.SHA_IMPL_COMPRESS;
64 import static org.graalvm.compiler.hotspot.HotSpotBackend.SHA_IMPL_COMPRESS_MB;
65 import static org.graalvm.compiler.hotspot.HotSpotBackend.SQUARE_TO_LEN;
66 import static org.graalvm.compiler.hotspot.HotSpotBackend.UNWIND_EXCEPTION_TO_CALLER;
67 import static org.graalvm.compiler.hotspot.HotSpotBackend.VECTORIZED_MISMATCHED;
68 import static org.graalvm.compiler.hotspot.HotSpotBackend.VM_ERROR;
69 import static org.graalvm.compiler.hotspot.HotSpotBackend.WRONG_METHOD_HANDLER;
70 import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Reexecutability.NOT_REEXECUTABLE;
71 import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Reexecutability.REEXECUTABLE;
72 import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.RegisterEffect.DESTROYS_REGISTERS;
73 import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.RegisterEffect.PRESERVES_REGISTERS;
74 import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.LEAF;
75 import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.LEAF_NO_VZERO;
76 import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.SAFEPOINT;
77 import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.STACK_INSPECTABLE_LEAF;
78 import static org.graalvm.compiler.hotspot.HotSpotHostBackend.DEOPTIMIZATION_HANDLER;
79 import static org.graalvm.compiler.hotspot.HotSpotHostBackend.ENABLE_STACK_RESERVED_ZONE;
80 import static org.graalvm.compiler.hotspot.HotSpotHostBackend.THROW_DELAYED_STACKOVERFLOW_ERROR;
81 import static org.graalvm.compiler.hotspot.HotSpotHostBackend.UNCOMMON_TRAP_HANDLER;
82 import static org.graalvm.compiler.hotspot.replacements.AssertionSnippets.ASSERTION_VM_MESSAGE_C;
83 import static org.graalvm.compiler.hotspot.replacements.HotSpotG1WriteBarrierSnippets.G1WBPOSTCALL;
84 import static org.graalvm.compiler.hotspot.replacements.HotSpotG1WriteBarrierSnippets.G1WBPRECALL;
85 import static org.graalvm.compiler.hotspot.replacements.HotSpotG1WriteBarrierSnippets.VALIDATE_OBJECT;
86 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.MARK_WORD_LOCATION;
87 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.TLAB_END_LOCATION;
88 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.TLAB_TOP_LOCATION;
89 import static org.graalvm.compiler.hotspot.replacements.Log.LOG_OBJECT;
90 import static org.graalvm.compiler.hotspot.replacements.Log.LOG_PRIMITIVE;
91 import static org.graalvm.compiler.hotspot.replacements.Log.LOG_PRINTF;
92 import static org.graalvm.compiler.hotspot.replacements.MonitorSnippets.MONITORENTER;
93 import static org.graalvm.compiler.hotspot.replacements.MonitorSnippets.MONITOREXIT;
199 ForeignCallDescriptor desc = descMap.get(routine);
200 if (desc == null) {
201 desc = buildDescriptor(kind, aligned, disjoint, uninit, killAny, routine);
202 descMap.put(routine, desc);
203 }
204 if (uninit) {
205 assert kind == JavaKind.Object;
206 uninitObjectArraycopyDescriptors[aligned ? 1 : 0][disjoint ? 1 : 0] = desc;
207 } else if (killAny) {
208 arraycopyDescriptorsKillAny[aligned ? 1 : 0][disjoint ? 1 : 0].put(kind, desc);
209 } else {
210 arraycopyDescriptors[aligned ? 1 : 0][disjoint ? 1 : 0].put(kind, desc);
211 }
212 }
213
214 private ForeignCallDescriptor buildDescriptor(JavaKind kind, boolean aligned, boolean disjoint, boolean uninit, boolean killAny, long routine) {
215 assert !uninit || kind == JavaKind.Object;
216 String name = kind + (aligned ? "Aligned" : "") + (disjoint ? "Disjoint" : "") + (uninit ? "Uninit" : "") + "Arraycopy" + (killAny ? "KillAny" : "");
217 ForeignCallDescriptor desc = new ForeignCallDescriptor(name, void.class, Word.class, Word.class, Word.class);
218 LocationIdentity killed = killAny ? LocationIdentity.any() : NamedLocationIdentity.getArrayLocation(kind);
219 registerForeignCall(desc, routine, NativeCall, DESTROYS_REGISTERS, LEAF_NO_VZERO, NOT_REEXECUTABLE, killed);
220 return desc;
221 }
222
223 private void registerCheckcastArraycopyDescriptor(boolean uninit, long routine) {
224 String name = "Object" + (uninit ? "Uninit" : "") + "CheckcastArraycopy";
225 // Input:
226 // c_rarg0 - source array address
227 // c_rarg1 - destination array address
228 // c_rarg2 - element count, treated as ssize_t, can be zero
229 // c_rarg3 - size_t ckoff (super_check_offset)
230 // c_rarg4 - oop ckval (super_klass)
231 // return: 0 = success, n = number of copied elements xor'd with -1.
232 ForeignCallDescriptor desc = new ForeignCallDescriptor(name, int.class, Word.class, Word.class, Word.class, Word.class, Word.class);
233 LocationIdentity killed = NamedLocationIdentity.any();
234 registerForeignCall(desc, routine, NativeCall, DESTROYS_REGISTERS, LEAF_NO_VZERO, NOT_REEXECUTABLE, killed);
235 checkcastArraycopyDescriptors[uninit ? 1 : 0] = desc;
236 }
237
238 private void registerArrayCopy(JavaKind kind,
239 long routine,
240 long alignedRoutine,
241 long disjointRoutine,
242 long alignedDisjointRoutine) {
243 registerArrayCopy(kind, routine, alignedRoutine, disjointRoutine, alignedDisjointRoutine, false);
244 }
245
246 private void registerArrayCopy(JavaKind kind,
247 long routine,
248 long alignedRoutine,
249 long disjointRoutine,
250 long alignedDisjointRoutine,
251 boolean uninit) {
252 /*
253 * Sometimes the same function is used for multiple cases so share them when that's the case
254 * but only within the same Kind. For instance short and char are the same copy routines but
255 * they kill different memory so they still have to be distinct.
256 */
257 EconomicMap<Long, ForeignCallDescriptor> descMap = EconomicMap.create();
258 registerArraycopyDescriptor(descMap, kind, false, false, uninit, false, routine);
259 registerArraycopyDescriptor(descMap, kind, true, false, uninit, false, alignedRoutine);
260 registerArraycopyDescriptor(descMap, kind, false, true, uninit, false, disjointRoutine);
261 registerArraycopyDescriptor(descMap, kind, true, true, uninit, false, alignedDisjointRoutine);
262
263 if (!uninit) {
264 EconomicMap<Long, ForeignCallDescriptor> killAnyDescMap = EconomicMap.create();
265 registerArraycopyDescriptor(killAnyDescMap, kind, false, false, uninit, true, routine);
266 registerArraycopyDescriptor(killAnyDescMap, kind, true, false, uninit, true, alignedRoutine);
267 registerArraycopyDescriptor(killAnyDescMap, kind, false, true, uninit, true, disjointRoutine);
268 registerArraycopyDescriptor(killAnyDescMap, kind, true, true, uninit, true, alignedDisjointRoutine);
269 }
270 }
271
272 public void initialize(HotSpotProviders providers, OptionValues options) {
273 GraalHotSpotVMConfig c = runtime.getVMConfig();
274 registerForeignCall(DEOPTIMIZATION_HANDLER, c.handleDeoptStub, NativeCall, PRESERVES_REGISTERS, LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS);
275 registerForeignCall(UNCOMMON_TRAP_HANDLER, c.uncommonTrapStub, NativeCall, PRESERVES_REGISTERS, LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS);
276 registerForeignCall(IC_MISS_HANDLER, c.inlineCacheMissStub, NativeCall, PRESERVES_REGISTERS, LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS);
277
278 if (c.enableStackReservedZoneAddress != 0) {
279 assert c.throwDelayedStackOverflowErrorEntry != 0 : "both must exist";
280 registerForeignCall(ENABLE_STACK_RESERVED_ZONE, c.enableStackReservedZoneAddress, NativeCall, DESTROYS_REGISTERS, LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS);
281 registerForeignCall(THROW_DELAYED_STACKOVERFLOW_ERROR, c.throwDelayedStackOverflowErrorEntry, NativeCall, DESTROYS_REGISTERS, LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS);
282 }
283
284 registerForeignCall(JAVA_TIME_MILLIS, c.javaTimeMillisAddress, NativeCall, DESTROYS_REGISTERS, LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS);
285 registerForeignCall(JAVA_TIME_NANOS, c.javaTimeNanosAddress, NativeCall, DESTROYS_REGISTERS, LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS);
286
287 registerMathStubs(c, providers, options);
288
289 registerForeignCall(ARITHMETIC_FREM, c.fremAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
290 registerForeignCall(ARITHMETIC_DREM, c.dremAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
291
292 registerForeignCall(LOAD_AND_CLEAR_EXCEPTION, c.loadAndClearExceptionAddress, NativeCall, DESTROYS_REGISTERS, LEAF_NO_VZERO, NOT_REEXECUTABLE, any());
293
294 registerForeignCall(EXCEPTION_HANDLER_FOR_PC, c.exceptionHandlerForPcAddress, NativeCall, DESTROYS_REGISTERS, SAFEPOINT, REEXECUTABLE, any());
295 registerForeignCall(EXCEPTION_HANDLER_FOR_RETURN_ADDRESS, c.exceptionHandlerForReturnAddressAddress, NativeCall, DESTROYS_REGISTERS, SAFEPOINT, REEXECUTABLE, any());
296
297 CreateExceptionStub.registerForeignCalls(c, this);
298
299 /*
300 * This message call is registered twice, where the second one must only be used for calls
301 * that do not return, i.e., that exit the VM.
302 */
303 registerForeignCall(VM_MESSAGE_C, c.vmMessageAddress, NativeCall, DESTROYS_REGISTERS, SAFEPOINT, REEXECUTABLE, NO_LOCATIONS);
304 registerForeignCall(ASSERTION_VM_MESSAGE_C, c.vmMessageAddress, NativeCall, PRESERVES_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
305
306 linkForeignCall(options, providers, NEW_INSTANCE, c.newInstanceAddress, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, TLAB_TOP_LOCATION, TLAB_END_LOCATION);
307 linkForeignCall(options, providers, NEW_ARRAY, c.newArrayAddress, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, TLAB_TOP_LOCATION, TLAB_END_LOCATION);
308 linkForeignCall(options, providers, NEW_MULTI_ARRAY, c.newMultiArrayAddress, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, TLAB_TOP_LOCATION, TLAB_END_LOCATION);
309 linkForeignCall(options, providers, DYNAMIC_NEW_INSTANCE, c.dynamicNewInstanceAddress, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE);
310
311 if (c.areNullAllocationStubsAvailable()) {
312 linkForeignCall(options, providers, NEW_INSTANCE_OR_NULL, c.newInstanceOrNullAddress, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, TLAB_TOP_LOCATION, TLAB_END_LOCATION);
313 linkForeignCall(options, providers, NEW_ARRAY_OR_NULL, c.newArrayOrNullAddress, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, TLAB_TOP_LOCATION, TLAB_END_LOCATION);
314 linkForeignCall(options, providers, NEW_MULTI_ARRAY_OR_NULL, c.newMultiArrayOrNullAddress, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, TLAB_TOP_LOCATION, TLAB_END_LOCATION);
315 linkForeignCall(options, providers, DYNAMIC_NEW_INSTANCE_OR_NULL, c.dynamicNewInstanceOrNullAddress, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE);
316 }
317
318 link(new ExceptionHandlerStub(options, providers, foreignCalls.get(EXCEPTION_HANDLER)));
319 link(new UnwindExceptionToCallerStub(options, providers, registerStubCall(UNWIND_EXCEPTION_TO_CALLER, SAFEPOINT, NOT_REEXECUTABLE, any())));
320 link(new VerifyOopStub(options, providers, registerStubCall(VERIFY_OOP, LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS)));
321
322 EnumMap<BytecodeExceptionKind, ForeignCallDescriptor> exceptionRuntimeCalls = DefaultHotSpotLoweringProvider.RuntimeCalls.runtimeCalls;
323 link(new ArrayStoreExceptionStub(options, providers, registerStubCall(exceptionRuntimeCalls.get(BytecodeExceptionKind.ARRAY_STORE), SAFEPOINT, REEXECUTABLE, any())));
324 link(new ClassCastExceptionStub(options, providers, registerStubCall(exceptionRuntimeCalls.get(BytecodeExceptionKind.CLASS_CAST), SAFEPOINT, REEXECUTABLE, any())));
325 link(new NullPointerExceptionStub(options, providers, registerStubCall(exceptionRuntimeCalls.get(BytecodeExceptionKind.NULL_POINTER), SAFEPOINT, REEXECUTABLE, any())));
326 link(new OutOfBoundsExceptionStub(options, providers, registerStubCall(exceptionRuntimeCalls.get(BytecodeExceptionKind.OUT_OF_BOUNDS), SAFEPOINT, REEXECUTABLE, any())));
327 link(new DivisionByZeroExceptionStub(options, providers, registerStubCall(exceptionRuntimeCalls.get(BytecodeExceptionKind.DIVISION_BY_ZERO), SAFEPOINT, REEXECUTABLE, any())));
328 link(new IntegerExactOverflowExceptionStub(options, providers, registerStubCall(exceptionRuntimeCalls.get(BytecodeExceptionKind.INTEGER_EXACT_OVERFLOW), SAFEPOINT, REEXECUTABLE, any())));
329 link(new LongExactOverflowExceptionStub(options, providers, registerStubCall(exceptionRuntimeCalls.get(BytecodeExceptionKind.LONG_EXACT_OVERFLOW), SAFEPOINT, REEXECUTABLE, any())));
330
331 linkForeignCall(options, providers, IDENTITY_HASHCODE, c.identityHashCodeAddress, PREPEND_THREAD, SAFEPOINT, NOT_REEXECUTABLE, MARK_WORD_LOCATION);
332 linkForeignCall(options, providers, REGISTER_FINALIZER, c.registerFinalizerAddress, PREPEND_THREAD, SAFEPOINT, NOT_REEXECUTABLE, any());
333 linkForeignCall(options, providers, MONITORENTER, c.monitorenterAddress, PREPEND_THREAD, SAFEPOINT, NOT_REEXECUTABLE, any());
334 linkForeignCall(options, providers, MONITOREXIT, c.monitorexitAddress, PREPEND_THREAD, STACK_INSPECTABLE_LEAF, NOT_REEXECUTABLE, any());
335 linkForeignCall(options, providers, NOTIFY, c.notifyAddress, PREPEND_THREAD, SAFEPOINT, NOT_REEXECUTABLE, any());
336 linkForeignCall(options, providers, NOTIFY_ALL, c.notifyAllAddress, PREPEND_THREAD, SAFEPOINT, NOT_REEXECUTABLE, any());
337 linkForeignCall(options, providers, LOG_PRINTF, c.logPrintfAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
338 linkForeignCall(options, providers, LOG_OBJECT, c.logObjectAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
339 linkForeignCall(options, providers, LOG_PRIMITIVE, c.logPrimitiveAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
340 linkForeignCall(options, providers, VM_ERROR, c.vmErrorAddress, PREPEND_THREAD, LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS);
341 linkForeignCall(options, providers, OSR_MIGRATION_END, c.osrMigrationEndAddress, DONT_PREPEND_THREAD, LEAF_NO_VZERO, NOT_REEXECUTABLE, NO_LOCATIONS);
342 linkForeignCall(options, providers, G1WBPRECALL, c.writeBarrierPreAddress, PREPEND_THREAD, LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS);
343 linkForeignCall(options, providers, G1WBPOSTCALL, c.writeBarrierPostAddress, PREPEND_THREAD, LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS);
344 linkForeignCall(options, providers, VALIDATE_OBJECT, c.validateObject, PREPEND_THREAD, LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS);
345
346 if (GeneratePIC.getValue(options)) {
347 registerForeignCall(WRONG_METHOD_HANDLER, c.handleWrongMethodStub, NativeCall, PRESERVES_REGISTERS, LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS);
348 CompilerRuntimeHotSpotVMConfig cr = new CompilerRuntimeHotSpotVMConfig(HotSpotJVMCIRuntime.runtime().getConfigStore());
349 linkForeignCall(options, providers, RESOLVE_STRING_BY_SYMBOL, cr.resolveStringBySymbol, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, TLAB_TOP_LOCATION, TLAB_END_LOCATION);
350 linkForeignCall(options, providers, RESOLVE_DYNAMIC_INVOKE, cr.resolveDynamicInvoke, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, any());
351 linkForeignCall(options, providers, RESOLVE_KLASS_BY_SYMBOL, cr.resolveKlassBySymbol, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, any());
352 linkForeignCall(options, providers, RESOLVE_METHOD_BY_SYMBOL_AND_LOAD_COUNTERS, cr.resolveMethodBySymbolAndLoadCounters, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, NO_LOCATIONS);
353 linkForeignCall(options, providers, INITIALIZE_KLASS_BY_SYMBOL, cr.initializeKlassBySymbol, PREPEND_THREAD, SAFEPOINT, NOT_REEXECUTABLE, any());
354 linkForeignCall(options, providers, INVOCATION_EVENT, cr.invocationEvent, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, NO_LOCATIONS);
355 linkForeignCall(options, providers, BACKEDGE_EVENT, cr.backedgeEvent, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, NO_LOCATIONS);
356 }
357
358 linkForeignCall(options, providers, TEST_DEOPTIMIZE_CALL_INT, c.testDeoptimizeCallInt, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, any());
359
360 registerArrayCopy(JavaKind.Byte, c.jbyteArraycopy, c.jbyteAlignedArraycopy, c.jbyteDisjointArraycopy, c.jbyteAlignedDisjointArraycopy);
361 registerArrayCopy(JavaKind.Boolean, c.jbyteArraycopy, c.jbyteAlignedArraycopy, c.jbyteDisjointArraycopy, c.jbyteAlignedDisjointArraycopy);
362 registerArrayCopy(JavaKind.Char, c.jshortArraycopy, c.jshortAlignedArraycopy, c.jshortDisjointArraycopy, c.jshortAlignedDisjointArraycopy);
363 registerArrayCopy(JavaKind.Short, c.jshortArraycopy, c.jshortAlignedArraycopy, c.jshortDisjointArraycopy, c.jshortAlignedDisjointArraycopy);
364 registerArrayCopy(JavaKind.Int, c.jintArraycopy, c.jintAlignedArraycopy, c.jintDisjointArraycopy, c.jintAlignedDisjointArraycopy);
365 registerArrayCopy(JavaKind.Float, c.jintArraycopy, c.jintAlignedArraycopy, c.jintDisjointArraycopy, c.jintAlignedDisjointArraycopy);
366 registerArrayCopy(JavaKind.Long, c.jlongArraycopy, c.jlongAlignedArraycopy, c.jlongDisjointArraycopy, c.jlongAlignedDisjointArraycopy);
367 registerArrayCopy(JavaKind.Double, c.jlongArraycopy, c.jlongAlignedArraycopy, c.jlongDisjointArraycopy, c.jlongAlignedDisjointArraycopy);
368 registerArrayCopy(JavaKind.Object, c.oopArraycopy, c.oopAlignedArraycopy, c.oopDisjointArraycopy, c.oopAlignedDisjointArraycopy);
369 registerArrayCopy(JavaKind.Object, c.oopArraycopyUninit, c.oopAlignedArraycopyUninit, c.oopDisjointArraycopyUninit, c.oopAlignedDisjointArraycopyUninit, true);
370
371 registerCheckcastArraycopyDescriptor(true, c.checkcastArraycopyUninit);
372 registerCheckcastArraycopyDescriptor(false, c.checkcastArraycopy);
373
374 registerForeignCall(GENERIC_ARRAYCOPY, c.genericArraycopy, NativeCall, DESTROYS_REGISTERS, LEAF_NO_VZERO, NOT_REEXECUTABLE, NamedLocationIdentity.any());
375 registerForeignCall(UNSAFE_ARRAYCOPY, c.unsafeArraycopy, NativeCall, DESTROYS_REGISTERS, LEAF_NO_VZERO, NOT_REEXECUTABLE, NamedLocationIdentity.any());
376
377 if (c.useMultiplyToLenIntrinsic()) {
378 registerForeignCall(MULTIPLY_TO_LEN, c.multiplyToLen, NativeCall, DESTROYS_REGISTERS, LEAF_NO_VZERO, NOT_REEXECUTABLE,
379 NamedLocationIdentity.getArrayLocation(JavaKind.Int));
380 }
381
382 if (c.useSHA1Intrinsics()) {
383 registerForeignCall(SHA_IMPL_COMPRESS, c.sha1ImplCompress, NativeCall, DESTROYS_REGISTERS, LEAF, NOT_REEXECUTABLE, NamedLocationIdentity.any());
384 registerForeignCall(SHA_IMPL_COMPRESS_MB, c.sha1ImplCompressMultiBlock, NativeCall, DESTROYS_REGISTERS, LEAF, NOT_REEXECUTABLE, NamedLocationIdentity.any());
385 }
386 if (c.useSHA256Intrinsics()) {
387 registerForeignCall(SHA2_IMPL_COMPRESS, c.sha256ImplCompress, NativeCall, DESTROYS_REGISTERS, LEAF, NOT_REEXECUTABLE, NamedLocationIdentity.any());
388 registerForeignCall(SHA2_IMPL_COMPRESS_MB, c.sha256ImplCompressMultiBlock, NativeCall, DESTROYS_REGISTERS, LEAF, NOT_REEXECUTABLE, NamedLocationIdentity.any());
389 }
390 if (c.useSHA512Intrinsics()) {
391 registerForeignCall(SHA5_IMPL_COMPRESS, c.sha512ImplCompress, NativeCall, DESTROYS_REGISTERS, LEAF, NOT_REEXECUTABLE, NamedLocationIdentity.any());
392 registerForeignCall(SHA5_IMPL_COMPRESS_MB, c.sha512ImplCompressMultiBlock, NativeCall, DESTROYS_REGISTERS, LEAF, NOT_REEXECUTABLE, NamedLocationIdentity.any());
393 }
394 if (c.useGHASHIntrinsics()) {
395 registerForeignCall(GHASH_PROCESS_BLOCKS, c.ghashProcessBlocks, NativeCall, DESTROYS_REGISTERS, LEAF, NOT_REEXECUTABLE, NamedLocationIdentity.any());
396 }
397 if (c.useBase64Intrinsics()) {
398 registerForeignCall(BASE64_ENCODE_BLOCK, c.base64EncodeBlock, NativeCall, DESTROYS_REGISTERS, LEAF, NOT_REEXECUTABLE, NamedLocationIdentity.any());
399 }
400 if (c.useMulAddIntrinsic()) {
401 registerForeignCall(MUL_ADD, c.mulAdd, NativeCall, DESTROYS_REGISTERS, LEAF_NO_VZERO, NOT_REEXECUTABLE, NamedLocationIdentity.getArrayLocation(JavaKind.Int));
402 }
403 if (c.useMontgomeryMultiplyIntrinsic()) {
404 registerForeignCall(MONTGOMERY_MULTIPLY, c.montgomeryMultiply, NativeCall, DESTROYS_REGISTERS, LEAF_NO_VZERO, NOT_REEXECUTABLE,
405 NamedLocationIdentity.getArrayLocation(JavaKind.Int));
406 }
407 if (c.useMontgomerySquareIntrinsic()) {
408 registerForeignCall(MONTGOMERY_SQUARE, c.montgomerySquare, NativeCall, DESTROYS_REGISTERS, LEAF_NO_VZERO, NOT_REEXECUTABLE,
409 NamedLocationIdentity.getArrayLocation(JavaKind.Int));
410 }
411 if (c.useSquareToLenIntrinsic()) {
412 registerForeignCall(SQUARE_TO_LEN, c.squareToLen, NativeCall, DESTROYS_REGISTERS, LEAF_NO_VZERO, NOT_REEXECUTABLE, NamedLocationIdentity.getArrayLocation(JavaKind.Int));
413 }
414
415 if (c.useAESIntrinsics) {
416 /*
417 * When the java.ext.dirs property is modified then the crypto classes might not be
418 * found. If that's the case we ignore the ClassNotFoundException and continue since we
419 * cannot replace a non-existing method anyway.
420 */
421 try {
422 // These stubs do callee saving
423 registerForeignCall(ENCRYPT_BLOCK, c.aescryptEncryptBlockStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE,
424 NamedLocationIdentity.getArrayLocation(JavaKind.Byte));
425 registerForeignCall(DECRYPT_BLOCK, c.aescryptDecryptBlockStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE,
426 NamedLocationIdentity.getArrayLocation(JavaKind.Byte));
427 registerForeignCall(DECRYPT_BLOCK_WITH_ORIGINAL_KEY, c.aescryptDecryptBlockStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE,
428 NamedLocationIdentity.getArrayLocation(JavaKind.Byte));
429 } catch (GraalError e) {
430 if (!(e.getCause() instanceof ClassNotFoundException)) {
431 throw e;
432 }
433 }
434 try {
435 // These stubs do callee saving
436 registerForeignCall(ENCRYPT, c.cipherBlockChainingEncryptAESCryptStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE,
437 NamedLocationIdentity.getArrayLocation(JavaKind.Byte));
438 registerForeignCall(DECRYPT, c.cipherBlockChainingDecryptAESCryptStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE,
439 NamedLocationIdentity.getArrayLocation(JavaKind.Byte));
440 registerForeignCall(DECRYPT_WITH_ORIGINAL_KEY, c.cipherBlockChainingDecryptAESCryptStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE,
441 NamedLocationIdentity.getArrayLocation(JavaKind.Byte));
442 } catch (GraalError e) {
443 if (!(e.getCause() instanceof ClassNotFoundException)) {
444 throw e;
445 }
446 }
447 }
448
449 if (c.useAESCTRIntrinsics) {
450 assert (c.counterModeAESCrypt != 0L);
451 registerForeignCall(COUNTERMODE_IMPL_CRYPT, c.counterModeAESCrypt, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE,
452 NamedLocationIdentity.any());
453 }
454
455 if (c.useVectorizedMismatchIntrinsic) {
456 assert (c.vectorizedMismatch != 0L);
457 registerForeignCall(VECTORIZED_MISMATCHED, c.vectorizedMismatch, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE,
458 NamedLocationIdentity.any());
459
460 }
461 }
462
463 public HotSpotForeignCallLinkage getForeignCall(ForeignCallDescriptor descriptor) {
464 assert foreignCalls != null : descriptor;
465 return foreignCalls.get(descriptor);
466 }
467
468 @SuppressWarnings("unused")
469 protected void registerMathStubs(GraalHotSpotVMConfig hotSpotVMConfig, HotSpotProviders providers, OptionValues options) {
470 registerForeignCall(SIN.foreignCallDescriptor, hotSpotVMConfig.arithmeticSinAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
471 registerForeignCall(COS.foreignCallDescriptor, hotSpotVMConfig.arithmeticCosAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
472 registerForeignCall(TAN.foreignCallDescriptor, hotSpotVMConfig.arithmeticTanAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
473 registerForeignCall(EXP.foreignCallDescriptor, hotSpotVMConfig.arithmeticExpAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
474 registerForeignCall(LOG.foreignCallDescriptor, hotSpotVMConfig.arithmeticLogAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
475 registerForeignCall(LOG10.foreignCallDescriptor, hotSpotVMConfig.arithmeticLog10Address, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
476 registerForeignCall(POW.foreignCallDescriptor, hotSpotVMConfig.arithmeticPowAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
477 }
478 }
|
52 import static org.graalvm.compiler.hotspot.HotSpotBackend.NEW_INSTANCE_OR_NULL;
53 import static org.graalvm.compiler.hotspot.HotSpotBackend.NEW_MULTI_ARRAY;
54 import static org.graalvm.compiler.hotspot.HotSpotBackend.NEW_MULTI_ARRAY_OR_NULL;
55 import static org.graalvm.compiler.hotspot.HotSpotBackend.RESOLVE_DYNAMIC_INVOKE;
56 import static org.graalvm.compiler.hotspot.HotSpotBackend.RESOLVE_KLASS_BY_SYMBOL;
57 import static org.graalvm.compiler.hotspot.HotSpotBackend.RESOLVE_METHOD_BY_SYMBOL_AND_LOAD_COUNTERS;
58 import static org.graalvm.compiler.hotspot.HotSpotBackend.RESOLVE_STRING_BY_SYMBOL;
59 import static org.graalvm.compiler.hotspot.HotSpotBackend.SHA2_IMPL_COMPRESS;
60 import static org.graalvm.compiler.hotspot.HotSpotBackend.SHA2_IMPL_COMPRESS_MB;
61 import static org.graalvm.compiler.hotspot.HotSpotBackend.SHA5_IMPL_COMPRESS;
62 import static org.graalvm.compiler.hotspot.HotSpotBackend.SHA5_IMPL_COMPRESS_MB;
63 import static org.graalvm.compiler.hotspot.HotSpotBackend.SHA_IMPL_COMPRESS;
64 import static org.graalvm.compiler.hotspot.HotSpotBackend.SHA_IMPL_COMPRESS_MB;
65 import static org.graalvm.compiler.hotspot.HotSpotBackend.SQUARE_TO_LEN;
66 import static org.graalvm.compiler.hotspot.HotSpotBackend.UNWIND_EXCEPTION_TO_CALLER;
67 import static org.graalvm.compiler.hotspot.HotSpotBackend.VECTORIZED_MISMATCHED;
68 import static org.graalvm.compiler.hotspot.HotSpotBackend.VM_ERROR;
69 import static org.graalvm.compiler.hotspot.HotSpotBackend.WRONG_METHOD_HANDLER;
70 import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Reexecutability.NOT_REEXECUTABLE;
71 import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Reexecutability.REEXECUTABLE;
72 import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.RegisterEffect.DESTROYS_ALL_CALLER_SAVE_REGISTERS;
73 import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.LEAF;
74 import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.LEAF_NO_VZERO;
75 import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.SAFEPOINT;
76 import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.STACK_INSPECTABLE_LEAF;
77 import static org.graalvm.compiler.hotspot.HotSpotHostBackend.DEOPTIMIZATION_HANDLER;
78 import static org.graalvm.compiler.hotspot.HotSpotHostBackend.ENABLE_STACK_RESERVED_ZONE;
79 import static org.graalvm.compiler.hotspot.HotSpotHostBackend.THROW_DELAYED_STACKOVERFLOW_ERROR;
80 import static org.graalvm.compiler.hotspot.HotSpotHostBackend.UNCOMMON_TRAP_HANDLER;
81 import static org.graalvm.compiler.hotspot.replacements.AssertionSnippets.ASSERTION_VM_MESSAGE_C;
82 import static org.graalvm.compiler.hotspot.replacements.HotSpotG1WriteBarrierSnippets.G1WBPOSTCALL;
83 import static org.graalvm.compiler.hotspot.replacements.HotSpotG1WriteBarrierSnippets.G1WBPRECALL;
84 import static org.graalvm.compiler.hotspot.replacements.HotSpotG1WriteBarrierSnippets.VALIDATE_OBJECT;
85 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.MARK_WORD_LOCATION;
86 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.TLAB_END_LOCATION;
87 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.TLAB_TOP_LOCATION;
88 import static org.graalvm.compiler.hotspot.replacements.Log.LOG_OBJECT;
89 import static org.graalvm.compiler.hotspot.replacements.Log.LOG_PRIMITIVE;
90 import static org.graalvm.compiler.hotspot.replacements.Log.LOG_PRINTF;
91 import static org.graalvm.compiler.hotspot.replacements.MonitorSnippets.MONITORENTER;
92 import static org.graalvm.compiler.hotspot.replacements.MonitorSnippets.MONITOREXIT;
198 ForeignCallDescriptor desc = descMap.get(routine);
199 if (desc == null) {
200 desc = buildDescriptor(kind, aligned, disjoint, uninit, killAny, routine);
201 descMap.put(routine, desc);
202 }
203 if (uninit) {
204 assert kind == JavaKind.Object;
205 uninitObjectArraycopyDescriptors[aligned ? 1 : 0][disjoint ? 1 : 0] = desc;
206 } else if (killAny) {
207 arraycopyDescriptorsKillAny[aligned ? 1 : 0][disjoint ? 1 : 0].put(kind, desc);
208 } else {
209 arraycopyDescriptors[aligned ? 1 : 0][disjoint ? 1 : 0].put(kind, desc);
210 }
211 }
212
213 private ForeignCallDescriptor buildDescriptor(JavaKind kind, boolean aligned, boolean disjoint, boolean uninit, boolean killAny, long routine) {
214 assert !uninit || kind == JavaKind.Object;
215 String name = kind + (aligned ? "Aligned" : "") + (disjoint ? "Disjoint" : "") + (uninit ? "Uninit" : "") + "Arraycopy" + (killAny ? "KillAny" : "");
216 ForeignCallDescriptor desc = new ForeignCallDescriptor(name, void.class, Word.class, Word.class, Word.class);
217 LocationIdentity killed = killAny ? LocationIdentity.any() : NamedLocationIdentity.getArrayLocation(kind);
218 registerForeignCall(desc, routine, NativeCall, LEAF_NO_VZERO, NOT_REEXECUTABLE, killed);
219 return desc;
220 }
221
222 private void registerCheckcastArraycopyDescriptor(boolean uninit, long routine) {
223 String name = "Object" + (uninit ? "Uninit" : "") + "CheckcastArraycopy";
224 // Input:
225 // c_rarg0 - source array address
226 // c_rarg1 - destination array address
227 // c_rarg2 - element count, treated as ssize_t, can be zero
228 // c_rarg3 - size_t ckoff (super_check_offset)
229 // c_rarg4 - oop ckval (super_klass)
230 // return: 0 = success, n = number of copied elements xor'd with -1.
231 ForeignCallDescriptor desc = new ForeignCallDescriptor(name, int.class, Word.class, Word.class, Word.class, Word.class, Word.class);
232 LocationIdentity killed = NamedLocationIdentity.any();
233 registerForeignCall(desc, routine, NativeCall, LEAF_NO_VZERO, NOT_REEXECUTABLE, killed);
234 checkcastArraycopyDescriptors[uninit ? 1 : 0] = desc;
235 }
236
237 private void registerArrayCopy(JavaKind kind,
238 long routine,
239 long alignedRoutine,
240 long disjointRoutine,
241 long alignedDisjointRoutine) {
242 registerArrayCopy(kind, routine, alignedRoutine, disjointRoutine, alignedDisjointRoutine, false);
243 }
244
245 private void registerArrayCopy(JavaKind kind,
246 long routine,
247 long alignedRoutine,
248 long disjointRoutine,
249 long alignedDisjointRoutine,
250 boolean uninit) {
251 /*
252 * Sometimes the same function is used for multiple cases so share them when that's the case
253 * but only within the same Kind. For instance short and char are the same copy routines but
254 * they kill different memory so they still have to be distinct.
255 */
256 EconomicMap<Long, ForeignCallDescriptor> descMap = EconomicMap.create();
257 registerArraycopyDescriptor(descMap, kind, false, false, uninit, false, routine);
258 registerArraycopyDescriptor(descMap, kind, true, false, uninit, false, alignedRoutine);
259 registerArraycopyDescriptor(descMap, kind, false, true, uninit, false, disjointRoutine);
260 registerArraycopyDescriptor(descMap, kind, true, true, uninit, false, alignedDisjointRoutine);
261
262 if (!uninit) {
263 EconomicMap<Long, ForeignCallDescriptor> killAnyDescMap = EconomicMap.create();
264 registerArraycopyDescriptor(killAnyDescMap, kind, false, false, uninit, true, routine);
265 registerArraycopyDescriptor(killAnyDescMap, kind, true, false, uninit, true, alignedRoutine);
266 registerArraycopyDescriptor(killAnyDescMap, kind, false, true, uninit, true, disjointRoutine);
267 registerArraycopyDescriptor(killAnyDescMap, kind, true, true, uninit, true, alignedDisjointRoutine);
268 }
269 }
270
271 public void initialize(HotSpotProviders providers, OptionValues options) {
272 GraalHotSpotVMConfig c = runtime.getVMConfig();
273 registerForeignCall(DEOPTIMIZATION_HANDLER, c.handleDeoptStub, NativeCall, LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS);
274 registerForeignCall(UNCOMMON_TRAP_HANDLER, c.uncommonTrapStub, NativeCall, LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS);
275 registerForeignCall(IC_MISS_HANDLER, c.inlineCacheMissStub, NativeCall, LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS);
276
277 if (c.enableStackReservedZoneAddress != 0) {
278 assert c.throwDelayedStackOverflowErrorEntry != 0 : "both must exist";
279 registerForeignCall(ENABLE_STACK_RESERVED_ZONE, c.enableStackReservedZoneAddress, NativeCall, LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS);
280 registerForeignCall(THROW_DELAYED_STACKOVERFLOW_ERROR, c.throwDelayedStackOverflowErrorEntry, NativeCall, LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS);
281 }
282
283 registerForeignCall(JAVA_TIME_MILLIS, c.javaTimeMillisAddress, NativeCall, LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS);
284 registerForeignCall(JAVA_TIME_NANOS, c.javaTimeNanosAddress, NativeCall, LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS);
285
286 registerMathStubs(c, providers, options);
287
288 registerForeignCall(ARITHMETIC_FREM, c.fremAddress, NativeCall, LEAF, REEXECUTABLE, NO_LOCATIONS);
289 registerForeignCall(ARITHMETIC_DREM, c.dremAddress, NativeCall, LEAF, REEXECUTABLE, NO_LOCATIONS);
290
291 registerForeignCall(LOAD_AND_CLEAR_EXCEPTION, c.loadAndClearExceptionAddress, NativeCall, LEAF_NO_VZERO, NOT_REEXECUTABLE, any());
292
293 registerForeignCall(EXCEPTION_HANDLER_FOR_PC, c.exceptionHandlerForPcAddress, NativeCall, SAFEPOINT, REEXECUTABLE, any());
294 registerForeignCall(EXCEPTION_HANDLER_FOR_RETURN_ADDRESS, c.exceptionHandlerForReturnAddressAddress, NativeCall, SAFEPOINT, REEXECUTABLE, any());
295
296 CreateExceptionStub.registerForeignCalls(c, this);
297
298 /*
299 * This message call is registered twice, where the second one must only be used for calls
300 * that do not return, i.e., that exit the VM.
301 */
302 registerForeignCall(VM_MESSAGE_C, c.vmMessageAddress, NativeCall, SAFEPOINT, REEXECUTABLE, NO_LOCATIONS);
303 registerForeignCall(ASSERTION_VM_MESSAGE_C, c.vmMessageAddress, NativeCall, LEAF, REEXECUTABLE, NO_LOCATIONS);
304
305 linkForeignCall(options, providers, NEW_INSTANCE, c.newInstanceAddress, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, TLAB_TOP_LOCATION, TLAB_END_LOCATION);
306 linkForeignCall(options, providers, NEW_ARRAY, c.newArrayAddress, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, TLAB_TOP_LOCATION, TLAB_END_LOCATION);
307 linkForeignCall(options, providers, NEW_MULTI_ARRAY, c.newMultiArrayAddress, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, TLAB_TOP_LOCATION, TLAB_END_LOCATION);
308 linkForeignCall(options, providers, DYNAMIC_NEW_INSTANCE, c.dynamicNewInstanceAddress, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE);
309
310 if (c.areNullAllocationStubsAvailable()) {
311 linkForeignCall(options, providers, NEW_INSTANCE_OR_NULL, c.newInstanceOrNullAddress, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, TLAB_TOP_LOCATION, TLAB_END_LOCATION);
312 linkForeignCall(options, providers, NEW_ARRAY_OR_NULL, c.newArrayOrNullAddress, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, TLAB_TOP_LOCATION, TLAB_END_LOCATION);
313 linkForeignCall(options, providers, NEW_MULTI_ARRAY_OR_NULL, c.newMultiArrayOrNullAddress, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, TLAB_TOP_LOCATION, TLAB_END_LOCATION);
314 linkForeignCall(options, providers, DYNAMIC_NEW_INSTANCE_OR_NULL, c.dynamicNewInstanceOrNullAddress, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE);
315 }
316
317 link(new ExceptionHandlerStub(options, providers, foreignCalls.get(EXCEPTION_HANDLER)));
318 link(new UnwindExceptionToCallerStub(options, providers,
319 registerStubCall(UNWIND_EXCEPTION_TO_CALLER, SAFEPOINT, NOT_REEXECUTABLE, DESTROYS_ALL_CALLER_SAVE_REGISTERS, any())));
320 link(new VerifyOopStub(options, providers, registerStubCall(VERIFY_OOP, LEAF_NO_VZERO, REEXECUTABLE, DESTROYS_ALL_CALLER_SAVE_REGISTERS, NO_LOCATIONS)));
321
322 EnumMap<BytecodeExceptionKind, ForeignCallDescriptor> exceptionRuntimeCalls = DefaultHotSpotLoweringProvider.RuntimeCalls.runtimeCalls;
323 link(new ArrayStoreExceptionStub(options, providers,
324 registerStubCall(exceptionRuntimeCalls.get(BytecodeExceptionKind.ARRAY_STORE), SAFEPOINT, NOT_REEXECUTABLE, DESTROYS_ALL_CALLER_SAVE_REGISTERS, any())));
325 link(new ClassCastExceptionStub(options, providers,
326 registerStubCall(exceptionRuntimeCalls.get(BytecodeExceptionKind.CLASS_CAST), SAFEPOINT, NOT_REEXECUTABLE, DESTROYS_ALL_CALLER_SAVE_REGISTERS, any())));
327 link(new NullPointerExceptionStub(options, providers,
328 registerStubCall(exceptionRuntimeCalls.get(BytecodeExceptionKind.NULL_POINTER), SAFEPOINT, NOT_REEXECUTABLE, DESTROYS_ALL_CALLER_SAVE_REGISTERS, any())));
329 link(new OutOfBoundsExceptionStub(options, providers,
330 registerStubCall(exceptionRuntimeCalls.get(BytecodeExceptionKind.OUT_OF_BOUNDS), SAFEPOINT, NOT_REEXECUTABLE, DESTROYS_ALL_CALLER_SAVE_REGISTERS, any())));
331 link(new DivisionByZeroExceptionStub(options, providers,
332 registerStubCall(exceptionRuntimeCalls.get(BytecodeExceptionKind.DIVISION_BY_ZERO), SAFEPOINT, NOT_REEXECUTABLE, DESTROYS_ALL_CALLER_SAVE_REGISTERS, any())));
333 link(new IntegerExactOverflowExceptionStub(options, providers,
334 registerStubCall(exceptionRuntimeCalls.get(BytecodeExceptionKind.INTEGER_EXACT_OVERFLOW), SAFEPOINT, NOT_REEXECUTABLE, DESTROYS_ALL_CALLER_SAVE_REGISTERS, any())));
335 link(new LongExactOverflowExceptionStub(options, providers,
336 registerStubCall(exceptionRuntimeCalls.get(BytecodeExceptionKind.LONG_EXACT_OVERFLOW), SAFEPOINT, NOT_REEXECUTABLE, DESTROYS_ALL_CALLER_SAVE_REGISTERS, any())));
337
338 linkForeignCall(options, providers, IDENTITY_HASHCODE, c.identityHashCodeAddress, PREPEND_THREAD, SAFEPOINT, NOT_REEXECUTABLE, MARK_WORD_LOCATION);
339 linkForeignCall(options, providers, REGISTER_FINALIZER, c.registerFinalizerAddress, PREPEND_THREAD, SAFEPOINT, NOT_REEXECUTABLE, any());
340 linkForeignCall(options, providers, MONITORENTER, c.monitorenterAddress, PREPEND_THREAD, SAFEPOINT, NOT_REEXECUTABLE, any());
341 linkForeignCall(options, providers, MONITOREXIT, c.monitorexitAddress, PREPEND_THREAD, STACK_INSPECTABLE_LEAF, NOT_REEXECUTABLE, any());
342 linkForeignCall(options, providers, NOTIFY, c.notifyAddress, PREPEND_THREAD, SAFEPOINT, NOT_REEXECUTABLE, any());
343 linkForeignCall(options, providers, NOTIFY_ALL, c.notifyAllAddress, PREPEND_THREAD, SAFEPOINT, NOT_REEXECUTABLE, any());
344 linkForeignCall(options, providers, LOG_PRINTF, c.logPrintfAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
345 linkForeignCall(options, providers, LOG_OBJECT, c.logObjectAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
346 linkForeignCall(options, providers, LOG_PRIMITIVE, c.logPrimitiveAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
347 linkForeignCall(options, providers, VM_ERROR, c.vmErrorAddress, PREPEND_THREAD, LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS);
348 linkForeignCall(options, providers, OSR_MIGRATION_END, c.osrMigrationEndAddress, DONT_PREPEND_THREAD, LEAF_NO_VZERO, NOT_REEXECUTABLE, NO_LOCATIONS);
349 linkForeignCall(options, providers, G1WBPRECALL, c.writeBarrierPreAddress, PREPEND_THREAD, LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS);
350 linkForeignCall(options, providers, G1WBPOSTCALL, c.writeBarrierPostAddress, PREPEND_THREAD, LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS);
351 linkForeignCall(options, providers, VALIDATE_OBJECT, c.validateObject, PREPEND_THREAD, LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS);
352
353 if (GeneratePIC.getValue(options)) {
354 registerForeignCall(WRONG_METHOD_HANDLER, c.handleWrongMethodStub, NativeCall, LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS);
355 CompilerRuntimeHotSpotVMConfig cr = new CompilerRuntimeHotSpotVMConfig(HotSpotJVMCIRuntime.runtime().getConfigStore());
356 linkForeignCall(options, providers, RESOLVE_STRING_BY_SYMBOL, cr.resolveStringBySymbol, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, TLAB_TOP_LOCATION, TLAB_END_LOCATION);
357 linkForeignCall(options, providers, RESOLVE_DYNAMIC_INVOKE, cr.resolveDynamicInvoke, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, any());
358 linkForeignCall(options, providers, RESOLVE_KLASS_BY_SYMBOL, cr.resolveKlassBySymbol, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, any());
359 linkForeignCall(options, providers, RESOLVE_METHOD_BY_SYMBOL_AND_LOAD_COUNTERS, cr.resolveMethodBySymbolAndLoadCounters, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, NO_LOCATIONS);
360 linkForeignCall(options, providers, INITIALIZE_KLASS_BY_SYMBOL, cr.initializeKlassBySymbol, PREPEND_THREAD, SAFEPOINT, NOT_REEXECUTABLE, any());
361 linkForeignCall(options, providers, INVOCATION_EVENT, cr.invocationEvent, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, NO_LOCATIONS);
362 linkForeignCall(options, providers, BACKEDGE_EVENT, cr.backedgeEvent, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, NO_LOCATIONS);
363 }
364
365 linkForeignCall(options, providers, TEST_DEOPTIMIZE_CALL_INT, c.testDeoptimizeCallInt, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, any());
366
367 registerArrayCopy(JavaKind.Byte, c.jbyteArraycopy, c.jbyteAlignedArraycopy, c.jbyteDisjointArraycopy, c.jbyteAlignedDisjointArraycopy);
368 registerArrayCopy(JavaKind.Boolean, c.jbyteArraycopy, c.jbyteAlignedArraycopy, c.jbyteDisjointArraycopy, c.jbyteAlignedDisjointArraycopy);
369 registerArrayCopy(JavaKind.Char, c.jshortArraycopy, c.jshortAlignedArraycopy, c.jshortDisjointArraycopy, c.jshortAlignedDisjointArraycopy);
370 registerArrayCopy(JavaKind.Short, c.jshortArraycopy, c.jshortAlignedArraycopy, c.jshortDisjointArraycopy, c.jshortAlignedDisjointArraycopy);
371 registerArrayCopy(JavaKind.Int, c.jintArraycopy, c.jintAlignedArraycopy, c.jintDisjointArraycopy, c.jintAlignedDisjointArraycopy);
372 registerArrayCopy(JavaKind.Float, c.jintArraycopy, c.jintAlignedArraycopy, c.jintDisjointArraycopy, c.jintAlignedDisjointArraycopy);
373 registerArrayCopy(JavaKind.Long, c.jlongArraycopy, c.jlongAlignedArraycopy, c.jlongDisjointArraycopy, c.jlongAlignedDisjointArraycopy);
374 registerArrayCopy(JavaKind.Double, c.jlongArraycopy, c.jlongAlignedArraycopy, c.jlongDisjointArraycopy, c.jlongAlignedDisjointArraycopy);
375 registerArrayCopy(JavaKind.Object, c.oopArraycopy, c.oopAlignedArraycopy, c.oopDisjointArraycopy, c.oopAlignedDisjointArraycopy);
376 registerArrayCopy(JavaKind.Object, c.oopArraycopyUninit, c.oopAlignedArraycopyUninit, c.oopDisjointArraycopyUninit, c.oopAlignedDisjointArraycopyUninit, true);
377
378 registerCheckcastArraycopyDescriptor(true, c.checkcastArraycopyUninit);
379 registerCheckcastArraycopyDescriptor(false, c.checkcastArraycopy);
380
381 registerForeignCall(GENERIC_ARRAYCOPY, c.genericArraycopy, NativeCall, LEAF_NO_VZERO, NOT_REEXECUTABLE, NamedLocationIdentity.any());
382 registerForeignCall(UNSAFE_ARRAYCOPY, c.unsafeArraycopy, NativeCall, LEAF_NO_VZERO, NOT_REEXECUTABLE, NamedLocationIdentity.any());
383
384 if (c.useMultiplyToLenIntrinsic()) {
385 registerForeignCall(MULTIPLY_TO_LEN, c.multiplyToLen, NativeCall, LEAF_NO_VZERO, NOT_REEXECUTABLE,
386 NamedLocationIdentity.getArrayLocation(JavaKind.Int));
387 }
388
389 if (c.useSHA1Intrinsics()) {
390 registerForeignCall(SHA_IMPL_COMPRESS, c.sha1ImplCompress, NativeCall, LEAF, NOT_REEXECUTABLE, NamedLocationIdentity.any());
391 registerForeignCall(SHA_IMPL_COMPRESS_MB, c.sha1ImplCompressMultiBlock, NativeCall, LEAF, NOT_REEXECUTABLE, NamedLocationIdentity.any());
392 }
393 if (c.useSHA256Intrinsics()) {
394 registerForeignCall(SHA2_IMPL_COMPRESS, c.sha256ImplCompress, NativeCall, LEAF, NOT_REEXECUTABLE, NamedLocationIdentity.any());
395 registerForeignCall(SHA2_IMPL_COMPRESS_MB, c.sha256ImplCompressMultiBlock, NativeCall, LEAF, NOT_REEXECUTABLE, NamedLocationIdentity.any());
396 }
397 if (c.useSHA512Intrinsics()) {
398 registerForeignCall(SHA5_IMPL_COMPRESS, c.sha512ImplCompress, NativeCall, LEAF, NOT_REEXECUTABLE, NamedLocationIdentity.any());
399 registerForeignCall(SHA5_IMPL_COMPRESS_MB, c.sha512ImplCompressMultiBlock, NativeCall, LEAF, NOT_REEXECUTABLE, NamedLocationIdentity.any());
400 }
401 if (c.useGHASHIntrinsics()) {
402 registerForeignCall(GHASH_PROCESS_BLOCKS, c.ghashProcessBlocks, NativeCall, LEAF, NOT_REEXECUTABLE, NamedLocationIdentity.any());
403 }
404 if (c.useBase64Intrinsics()) {
405 registerForeignCall(BASE64_ENCODE_BLOCK, c.base64EncodeBlock, NativeCall, LEAF, NOT_REEXECUTABLE, NamedLocationIdentity.any());
406 }
407 if (c.useMulAddIntrinsic()) {
408 registerForeignCall(MUL_ADD, c.mulAdd, NativeCall, LEAF_NO_VZERO, NOT_REEXECUTABLE, NamedLocationIdentity.getArrayLocation(JavaKind.Int));
409 }
410 if (c.useMontgomeryMultiplyIntrinsic()) {
411 registerForeignCall(MONTGOMERY_MULTIPLY, c.montgomeryMultiply, NativeCall, LEAF_NO_VZERO, NOT_REEXECUTABLE,
412 NamedLocationIdentity.getArrayLocation(JavaKind.Int));
413 }
414 if (c.useMontgomerySquareIntrinsic()) {
415 registerForeignCall(MONTGOMERY_SQUARE, c.montgomerySquare, NativeCall, LEAF_NO_VZERO, NOT_REEXECUTABLE,
416 NamedLocationIdentity.getArrayLocation(JavaKind.Int));
417 }
418 if (c.useSquareToLenIntrinsic()) {
419 registerForeignCall(SQUARE_TO_LEN, c.squareToLen, NativeCall, LEAF_NO_VZERO, NOT_REEXECUTABLE, NamedLocationIdentity.getArrayLocation(JavaKind.Int));
420 }
421
422 if (c.useAESIntrinsics) {
423 /*
424 * When the java.ext.dirs property is modified then the crypto classes might not be
425 * found. If that's the case we ignore the ClassNotFoundException and continue since we
426 * cannot replace a non-existing method anyway.
427 */
428 try {
429 // These stubs do callee saving
430 registerForeignCall(ENCRYPT_BLOCK, c.aescryptEncryptBlockStub, NativeCall, LEAF, NOT_REEXECUTABLE,
431 NamedLocationIdentity.getArrayLocation(JavaKind.Byte));
432 registerForeignCall(DECRYPT_BLOCK, c.aescryptDecryptBlockStub, NativeCall, LEAF, NOT_REEXECUTABLE,
433 NamedLocationIdentity.getArrayLocation(JavaKind.Byte));
434 registerForeignCall(DECRYPT_BLOCK_WITH_ORIGINAL_KEY, c.aescryptDecryptBlockStub, NativeCall, LEAF, NOT_REEXECUTABLE,
435 NamedLocationIdentity.getArrayLocation(JavaKind.Byte));
436 } catch (GraalError e) {
437 if (!(e.getCause() instanceof ClassNotFoundException)) {
438 throw e;
439 }
440 }
441 try {
442 // These stubs do callee saving
443 registerForeignCall(ENCRYPT, c.cipherBlockChainingEncryptAESCryptStub, NativeCall, LEAF, NOT_REEXECUTABLE,
444 NamedLocationIdentity.getArrayLocation(JavaKind.Byte));
445 registerForeignCall(DECRYPT, c.cipherBlockChainingDecryptAESCryptStub, NativeCall, LEAF, NOT_REEXECUTABLE,
446 NamedLocationIdentity.getArrayLocation(JavaKind.Byte));
447 registerForeignCall(DECRYPT_WITH_ORIGINAL_KEY, c.cipherBlockChainingDecryptAESCryptStub, NativeCall, LEAF, NOT_REEXECUTABLE,
448 NamedLocationIdentity.getArrayLocation(JavaKind.Byte));
449 } catch (GraalError e) {
450 if (!(e.getCause() instanceof ClassNotFoundException)) {
451 throw e;
452 }
453 }
454 }
455
456 if (c.useAESCTRIntrinsics) {
457 assert (c.counterModeAESCrypt != 0L);
458 registerForeignCall(COUNTERMODE_IMPL_CRYPT, c.counterModeAESCrypt, NativeCall, LEAF, NOT_REEXECUTABLE,
459 NamedLocationIdentity.any());
460 }
461
462 if (c.useVectorizedMismatchIntrinsic) {
463 assert (c.vectorizedMismatch != 0L);
464 registerForeignCall(VECTORIZED_MISMATCHED, c.vectorizedMismatch, NativeCall, LEAF, NOT_REEXECUTABLE,
465 NamedLocationIdentity.any());
466
467 }
468 }
469
470 public HotSpotForeignCallLinkage getForeignCall(ForeignCallDescriptor descriptor) {
471 assert foreignCalls != null : descriptor;
472 return foreignCalls.get(descriptor);
473 }
474
475 @SuppressWarnings("unused")
476 protected void registerMathStubs(GraalHotSpotVMConfig hotSpotVMConfig, HotSpotProviders providers, OptionValues options) {
477 registerForeignCall(SIN.foreignCallDescriptor, hotSpotVMConfig.arithmeticSinAddress, NativeCall, LEAF, REEXECUTABLE, NO_LOCATIONS);
478 registerForeignCall(COS.foreignCallDescriptor, hotSpotVMConfig.arithmeticCosAddress, NativeCall, LEAF, REEXECUTABLE, NO_LOCATIONS);
479 registerForeignCall(TAN.foreignCallDescriptor, hotSpotVMConfig.arithmeticTanAddress, NativeCall, LEAF, REEXECUTABLE, NO_LOCATIONS);
480 registerForeignCall(EXP.foreignCallDescriptor, hotSpotVMConfig.arithmeticExpAddress, NativeCall, LEAF, REEXECUTABLE, NO_LOCATIONS);
481 registerForeignCall(LOG.foreignCallDescriptor, hotSpotVMConfig.arithmeticLogAddress, NativeCall, LEAF, REEXECUTABLE, NO_LOCATIONS);
482 registerForeignCall(LOG10.foreignCallDescriptor, hotSpotVMConfig.arithmeticLog10Address, NativeCall, LEAF, REEXECUTABLE, NO_LOCATIONS);
483 registerForeignCall(POW.foreignCallDescriptor, hotSpotVMConfig.arithmeticPowAddress, NativeCall, LEAF, REEXECUTABLE, NO_LOCATIONS);
484 }
485 }
|