-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Support macOS ARM64 (Apple silicon) without JIT #6869
Conversation
bd5aac7
to
8733d46
Compare
9db2135
to
8adf180
Compare
8adf180
to
9d2bc10
Compare
This may be just about there for
|
Found and enabled working arm CI (Cirrus CI) - will need additional configurations, currently it's just testing a no-jit Test build. Everything is looking promising. The Jit still needs some work - the calling convention is different so the function prologue and epilogue code is not usable nor is the code for generating a Call. Hopefully total diff to fix this will only be ~200 lines but it's complex stuff. |
I don't know whether this has come up before, but to run jitted code on a non-Windows target the JIT will also need to generate whatever exception info the ABI requires, i.e., the equivalent of pdata + xdata. |
I'd seen in the source tree that I'd need to look at this but haven't given it much thought yet - I have been (perhaps naively) hoping that it will not be too hard to figure out once I have the basic functionality of the jit working - the relevant logic is there for apple/linux on amd64 which I hope to be able to model off of. |
6396881
to
5ab9610
Compare
FYI for anyone following this, considering the size/scale of this I'm going to try and clean it up, sort out the license and style issues (and possibly get it to work on linux arm64 too which should be a small step) then land it without JIT support for now, I intent to continue to work on the JIT as a follow up. |
bb4a158
to
b86980e
Compare
- Some material brought in from PAL at github.com/dotnet/ - Various manual changes to fit with existing codebase - Updated licensing in edited files, latest PAL is copyright .dotNet - Updated copyright check scripts to check pal/ files for new text
- Memory page size on apple arm64 is 16kb - This change caused ushort overflows - minor edits to orders of operations to fix - New assembler file for arm64_SAVE_REGISTERS
b86980e
to
d5ed057
Compare
@ppenzin I have had some difficulty getting a functional arm64 linux vm going so leaving this as just macOS arm64 support for now - also as discussed, leaving the JIT for the time being. Allowing for linux support and Jit support as future work I think this is ready. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PAL LGTM
Edit: oops, I thought I was just going through PAL change, hold on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trying new tactic of reviewing commits one by one.
PAL and Memory LGTM overall, but have some questions about the Memory commit.
@@ -62,7 +63,11 @@ class AutoSystemInfo : public SYSTEM_INFO | |||
#ifdef _WIN32 | |||
static HMODULE GetCRTHandle(); | |||
#endif | |||
#if defined(__APPLE__) && defined(_M_ARM64) | |||
static DWORD const PageSize = 16384; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: are there any consequences to hardcoding the page size? I think base class should contain the page size (this might be out of scope of this review).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was staying consistent with how it was before, it may not be ideal but it's not a change.
@@ -294,7 +295,11 @@ BOOL Heap<TAlloc, TPreReservedAlloc>::ProtectAllocationWithExecuteReadWrite(Allo | |||
} | |||
else | |||
{ | |||
#if defined(__APPLE__) && defined(_M_ARM64) | |||
protectFlags = PAGE_READWRITE; // PAGE_EXECUTE_READWRITE banned on Apple Silicon |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Side note: this would be trouble for JIT in the future
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was worried about it but I'm not sure if it will be a problem, I was able to get some run time produced code to run by setting a page to READWRITE, writing it and then switching to EXECUTE_READ before execution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, that's great, and it is actually a safer way to do this. Write+execute permissions provide an easier entry for JOP/ROP exploits (not that EXECUTE_READ is completely bulletproof, but it slows potential attacks somewhat).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should explore using that on other platforms as well.
@@ -62,7 +63,11 @@ class AutoSystemInfo : public SYSTEM_INFO | |||
#ifdef _WIN32 | |||
static HMODULE GetCRTHandle(); | |||
#endif | |||
#if defined(__APPLE__) && defined(_M_ARM64) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Apple" + "ARM64" can mean both iPhone and Arm-based Mac, I wonder if it is necessary to distinguish the two (I don't think we are trying to support iPhone).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good point, some of my #ifdefs may not be the most consistent, I don't think the codebase as a whole will run on an iPhone at the moment but I haven't tried.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIK M1/M2 are essentially just souped up A-series processors and ARM macOS can even run iOS apps natively so there's probably no need to distinguish.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect it won't run for one reason or the other, but this is probably low priority at the moment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Runtime commit looks good. Very impressive actually!
@@ -2818,6 +2819,8 @@ namespace TTD | |||
TTDAssert(wcscmp(_u("x64"), archString.Contents) == 0, "Mismatch in arch between record and replay!!!"); | |||
#elif defined(_M_ARM) | |||
TTDAssert(wcscmp(_u("arm64"), archString.Contents) == 0, "Mismatch in arch between record and replay!!!"); | |||
#elif defined(_M_ARM64) | |||
TTDAssert(wcscmp(_u("arm64"), archString.Contents) == 0, "Mismatch in arch between record and replay!!!"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curious why _M_ARM and _M_ARM64 both test for "arm64"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The M_ARM path may be wrong but I don't have testing set up for ARM or a device to check it on, so was nervous about changing it - it's a very old line of code and before microsoft stopped supporting CC it used to pass arm tests on windows, implying perhaps that both sides of the condition were being set incorrectly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a comment to look at it later?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do (let me know when you've finished reviewing and I'll address all points together if that's ok)
@@ -24,6 +25,9 @@ void mac_fde_wrapper(const char *dataStart, mac_fde_reg_op reg_op); | |||
#define __REGISTER_FRAME(addr) __register_frame(addr) | |||
#define __DEREGISTER_FRAME(addr) __deregister_frame(addr) | |||
#endif // __APPLE__ | |||
#elif defined(_M_ARM64) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add a comment what #if
this corresponds to, would be easier to follow.
test/CMakeLists.txt
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huge thanks for doing this!
One more suggestion, but overall looks good. |
- Update entry point call for Apple arm64 function calling convention - New Assembler routines for function calls
- Enables dynamic interpretor thunks on Apple Silicon - Remainder of the JIT will compile with these edits but not yet work
- small changes e.g. alternatives for windows intrinsics - build file updates
- update DateTimeFormat.js which required ICU_Version<72 - update ICU path for native tests (different on Apple Silicon) - use find_package for Python
- Build and test Debug, Test and Release Builds - Cirrus CI supports Apple Silicon - Not intended to replace Azure for other builds due to usage limits
<!--TODO Investigate and re-enable this test on ARM64 macOS--> | ||
<tags>exclude_mac</tags> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test began failing in the online apple silicon CI but not offline - Number.toString on a double was outputting a slightly different answer to the baseline. Ok to merge anyway and investigate later? @ppenzin
I believe this was due to an update to the VM image used by Cirrus CI as I'd not made any relevant change to the source and the test fail doesn't occur offline.
NOTE, double to string conversion is implementation defined and has long been a point where CC was out of line with other implementations, so I don't think this really counts as a bug - though it would be nice to work out why it's different on a particularly version of macOS (in the online CI)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have #149 filed for this issue in general, maybe add a comment there so that we don't forget. I think it is OK to merge in current state.
This is a working port of ChakraCore for Apple Silicon, though jit support requires further work and will be left for a follow up PR.
Work done:
ref: #6860
@ppenzin