|
1 | 1 | /* |
2 | | - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. |
| 2 | + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. |
3 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | 4 | * |
5 | 5 | * This code is free software; you can redistribute it and/or modify it |
|
58 | 58 | import jdk.graal.compiler.hotspot.meta.HotSpotProviders; |
59 | 59 | import jdk.graal.compiler.hotspot.stubs.Stub; |
60 | 60 | import jdk.graal.compiler.lir.LIR; |
| 61 | +import jdk.graal.compiler.lir.SyncPort; |
61 | 62 | import jdk.graal.compiler.lir.amd64.AMD64Call; |
62 | 63 | import jdk.graal.compiler.lir.amd64.AMD64FrameMap; |
63 | 64 | import jdk.graal.compiler.lir.asm.CompilationResultBuilder; |
@@ -459,20 +460,49 @@ public void emitCodeSuffix(CompilationResultBuilder crb, AMD64MacroAssembler asm |
459 | 460 | crb.recordImplicitException(pendingImplicitException.codeOffset, pos, pendingImplicitException.state); |
460 | 461 | } |
461 | 462 | } |
462 | | - trampolineCall(crb, asm, foreignCalls.lookupForeignCall(EXCEPTION_HANDLER), HotSpotMarkId.EXCEPTION_HANDLER_ENTRY); |
463 | | - trampolineCall(crb, asm, foreignCalls.lookupForeignCall(DEOPT_BLOB_UNPACK), HotSpotMarkId.DEOPT_HANDLER_ENTRY); |
| 463 | + emitExceptionHandler(crb, asm, foreignCalls.lookupForeignCall(EXCEPTION_HANDLER), HotSpotMarkId.EXCEPTION_HANDLER_ENTRY); |
| 464 | + emitDeoptHandler(crb, asm, foreignCalls.lookupForeignCall(DEOPT_BLOB_UNPACK), HotSpotMarkId.DEOPT_HANDLER_ENTRY); |
464 | 465 | if (config.supportsMethodHandleDeoptimizationEntry() && crb.needsMHDeoptHandler()) { |
465 | | - trampolineCall(crb, asm, foreignCalls.lookupForeignCall(DEOPT_BLOB_UNPACK), HotSpotMarkId.DEOPT_MH_HANDLER_ENTRY); |
| 466 | + emitDeoptHandler(crb, asm, foreignCalls.lookupForeignCall(DEOPT_BLOB_UNPACK), HotSpotMarkId.DEOPT_MH_HANDLER_ENTRY); |
466 | 467 | } |
467 | 468 | } |
468 | 469 | } |
469 | 470 |
|
470 | | - private static void trampolineCall(CompilationResultBuilder crb, AMD64MacroAssembler asm, ForeignCallLinkage callTarget, HotSpotMarkId exceptionHandlerEntry) { |
| 471 | + private static void emitExceptionHandler(CompilationResultBuilder crb, AMD64MacroAssembler asm, ForeignCallLinkage callTarget, HotSpotMarkId exceptionHandlerEntry) { |
471 | 472 | crb.recordMark(AMD64Call.directCall(crb, asm, callTarget, null, false, null), exceptionHandlerEntry); |
472 | 473 | // Ensure the return location is a unique pc and that control flow doesn't return here |
473 | 474 | asm.halt(); |
474 | 475 | } |
475 | 476 |
|
| 477 | + // @formatter:off |
| 478 | + @SyncPort(from = "https://github.com/openjdk/jdk/blob/74a2c831a2af55c66317ca8aead53fde2a2a6900/src/hotspot/cpu/x86/x86.ad#L1261-L1288", |
| 479 | + sha1 = "1326c5aa33296807cd6fb271150c3fcc0bfb9388") |
| 480 | + // @formatter:on |
| 481 | + private static void emitDeoptHandler(CompilationResultBuilder crb, AMD64MacroAssembler asm, ForeignCallLinkage callTarget, HotSpotMarkId deoptHandlerEntry) { |
| 482 | + /* Line comments preserved from JDK code. */ |
| 483 | + crb.recordMark(asm.position(), deoptHandlerEntry); |
| 484 | + int position = asm.position(); |
| 485 | + Label next = new Label(); |
| 486 | + // push a "the_pc" on the stack without destroying any registers |
| 487 | + // as they all may be live. |
| 488 | + |
| 489 | + // push address of "next" |
| 490 | + asm.call(next); |
| 491 | + asm.bind(next); |
| 492 | + // adjust it so it matches "the_pc" |
| 493 | + asm.subq(new AMD64Address(rsp, 0), asm.position() - position); |
| 494 | + |
| 495 | + int jmpSize = 1 + 4; // 1 byte opcode + 4 bytes displacement |
| 496 | + crb.recordDirectCall(asm.position(), asm.position() + jmpSize, callTarget, null); |
| 497 | + asm.rawJmpNoJCCErratumMitigation(); |
| 498 | + |
| 499 | + /* |
| 500 | + * Ensure that control flow doesn't return here. The synthetic return location PC is the |
| 501 | + * address of the call instruction above. |
| 502 | + */ |
| 503 | + asm.halt(); |
| 504 | + } |
| 505 | + |
476 | 506 | @Override |
477 | 507 | public RegisterAllocationConfig newRegisterAllocationConfig(RegisterConfig registerConfig, String[] allocationRestrictedTo, Object stub) { |
478 | 508 | RegisterConfig registerConfigNonNull = registerConfig == null ? getCodeCache().getRegisterConfig() : registerConfig; |
|
0 commit comments