Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add arm64 support for EnC #69679

Merged
merged 4 commits into from
May 23, 2022
Merged

Add arm64 support for EnC #69679

merged 4 commits into from
May 23, 2022

Conversation

jakobbotsch
Copy link
Member

@jakobbotsch jakobbotsch commented May 23, 2022

This adds support for EnC on arm64. A couple of notes on the
implementation compared to x64:

  • On x64 we get the fixed stack size from unwind info. However, for the
    frames we set up on arm64 for EnC it is not possible to extract the
    frame size from there because their prologs generally look like

    stp fp, lr, [sp,#-16]!
    mov fp, sp
    sub sp, sp, # 144

    with unwind codes like the following:

    set_fp; mov fp, sp

    save_fplr_x # 1 (0x01); stp fp, lr, [sp, #-16]!

    As can be seen, it is not possible to get the fixed stack size from
    unwind info in this case. Instead we pass it through the GC info that
    already has a section for EnC data.

  • On arm64 the JIT is required to place the PSPSym at the same offset
    from caller-SP for both the main function and for funclets. Due to
    this we try to allocate the PSPSym as early as possible in the main
    function and we must take some care in funclets. However, this
    conflicts with the EnC frame header that the JIT uses to place values
    that must be preserved on EnC transitions. This is currently
    callee-saved registers and the MonitorAcquired boolean.

    Before this change we were allocating PSPSym above (before) the
    monitor acquired boolean, but we now have to allocate MonitorAcquired
    first, particularly because the size of the preserved header cannot
    change on EnC transitions, while the PSPSym can disappear or appear.
    This changes frame allocation slightly for synchronized functions.

This adds support for EnC on arm64. A couple of notes on the
implementation compared to x64:
- On x64 we get the fixed stack size from unwind info. However, for the
  frames we set up on arm64 for EnC it is not possible to extract the
  frame size from there because their prologs generally look like

  stp fp, lr, [sp,#-16]!
  mov fp, sp
  sub sp, sp, dotnet#144

  with unwind codes like the following:

  set_fp; mov fp, sp

  save_fplr_x #1 (0x01); tp fp, lr, [sp, #-16]!

  As can be seen, it is not possible to get the fixed stack size from
  unwind info in this case. Instead we pass it through the GC info that
  already has a section for EnC data.

- On arm64 the JIT is required to place the PSPSym at the same offset
  from caller-SP for both the main function and for funclets. Due to
  this we try to allocate the PSPSym as early as possible in the main
  function and we must take some care in funclets.  However, this
  conflicts with the EnC frame header that the JIT uses to place values
  that must be preserved on EnC transitions. This is currently
  callee-saved registers and the MonitorAcquired boolean.

  Before this change we were allocating PSPSym above (before) the
  monitor acquired boolean, but we now have to allocate MonitorAcquired
  first, particularly because the size of the preserved header cannot
  change on EnC transitions, while the PSPSym can disappear or appear.
  This changes frame allocation slightly for synchronized functions.
@ghost ghost assigned jakobbotsch May 23, 2022
@dotnet-issue-labeler dotnet-issue-labeler bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label May 23, 2022
@ghost
Copy link

ghost commented May 23, 2022

Tagging subscribers to this area: @JulieLeeMSFT
See info in area-owners.md if you want to be subscribed.

Issue Details

This adds support for EnC on arm64. A couple of notes on the
implementation compared to x64:

  • On x64 we get the fixed stack size from unwind info. However, for the
    frames we set up on arm64 for EnC it is not possible to extract the
    frame size from there because their prologs generally look like

    stp fp, lr, [sp,#-16]!
    mov fp, sp
    sub sp, sp, # 144

    with unwind codes like the following:

    set_fp; mov fp, sp

    save_fplr_x # 1 (0x01); tp fp, lr, [sp, #-16]!

    As can be seen, it is not possible to get the fixed stack size from
    unwind info in this case. Instead we pass it through the GC info that
    already has a section for EnC data.

  • On arm64 the JIT is required to place the PSPSym at the same offset
    from caller-SP for both the main function and for funclets. Due to
    this we try to allocate the PSPSym as early as possible in the main
    function and we must take some care in funclets. However, this
    conflicts with the EnC frame header that the JIT uses to place values
    that must be preserved on EnC transitions. This is currently
    callee-saved registers and the MonitorAcquired boolean.

    Before this change we were allocating PSPSym above (before) the
    monitor acquired boolean, but we now have to allocate MonitorAcquired
    first, particularly because the size of the preserved header cannot
    change on EnC transitions, while the PSPSym can disappear or appear.
    This changes frame allocation slightly for synchronized functions.

Author: jakobbotsch
Assignees: jakobbotsch
Labels:

area-CodeGen-coreclr

Milestone: -


CORDbgSetInstruction((CORDB_ADDRESS_TYPE *)patchBypass, 0xd503201f); //Add Nop in buffer
SetReg(context, RegNum, finalAddr);
return patchBypass;
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am including a bugfix to the stepper. On arm64 we would not handle adr/adrp correctly which causes issues when running diagnostics tests.

Copy link
Member

@AndyAyersMS AndyAyersMS left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to update the R2R version because of the gc info change? I suppose we don't as this new format is only there with ENC, which we won't see in R2R.

src/coreclr/vm/encee.cpp Outdated Show resolved Hide resolved
@jakobbotsch
Copy link
Member Author

Do we need to update the R2R version because of the gc info change? I suppose we don't as this new format is only there with ENC, which we won't see in R2R.

Right, I checked with @davidwrighton and he was under the same belief.

@jakobbotsch
Copy link
Member Author

Looks like there is an OSR + synchronized assert I'll need to sort out.

OSR methods reuse the bool created by the tier 0 frame so we should not
allocate space for it.
Copy link
Member

@tommcdon tommcdon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@jakobbotsch jakobbotsch merged commit 8ca9916 into dotnet:main May 23, 2022
@jakobbotsch jakobbotsch deleted the arm64-enc branch May 23, 2022 22:14
@ghost ghost locked as resolved and limited conversation to collaborators Jun 23, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants