-
Couldn't load subscription status.
- Fork 5.2k
Reuse x86 GC and unwinding code in NativeAOT #99109
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
Merged
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
21acdcd
Verbatim code extraction from eetwain.cpp into gc_unwind_x86.inl
filipnavara d10ff51
Reuse x86 GC and unwinding code in NativeAOT
filipnavara 0c94dc1
PR feedback
filipnavara 15543ed
Remove extra EXTERNs from asm code
filipnavara ab0b9f2
Fix rebase
filipnavara aeef9dd
Fix passing code offset for unwinding
filipnavara cf35f92
Remove assert
filipnavara File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,138 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| #ifndef _UNWIND_X86_H | ||
| #define _UNWIND_X86_H | ||
|
|
||
| // This file is shared between CoreCLR and NativeAOT. Some of the differences are handled | ||
| // with the FEATURE_NATIVEAOT and FEATURE_EH_FUNCLETS defines. There are three main methods | ||
| // that are used by both runtimes - DecodeGCHdrInfo, UnwindStackFrameX86, and EnumGcRefsX86. | ||
| // | ||
| // The IN_EH_FUNCLETS and IN_EH_FUNCLETS_COMMA macros are used to specify some parameters | ||
| // for the above methods that are specific for a certain runtime or configuration. | ||
| #ifdef FEATURE_EH_FUNCLETS | ||
| #define IN_EH_FUNCLETS(a) a | ||
| #define IN_EH_FUNCLETS_COMMA(a) a, | ||
| #else | ||
| #define IN_EH_FUNCLETS(a) | ||
| #define IN_EH_FUNCLETS_COMMA(a) | ||
| #endif | ||
|
|
||
| enum regNum | ||
| { | ||
| REGI_EAX, REGI_ECX, REGI_EDX, REGI_EBX, | ||
| REGI_ESP, REGI_EBP, REGI_ESI, REGI_EDI, | ||
| REGI_COUNT, | ||
| REGI_NA = REGI_COUNT | ||
| }; | ||
|
|
||
| /***************************************************************************** | ||
| Register masks | ||
| */ | ||
|
|
||
| enum RegMask | ||
| { | ||
| RM_EAX = 0x01, | ||
| RM_ECX = 0x02, | ||
| RM_EDX = 0x04, | ||
| RM_EBX = 0x08, | ||
| RM_ESP = 0x10, | ||
| RM_EBP = 0x20, | ||
| RM_ESI = 0x40, | ||
| RM_EDI = 0x80, | ||
|
|
||
| RM_NONE = 0x00, | ||
| RM_ALL = (RM_EAX|RM_ECX|RM_EDX|RM_EBX|RM_ESP|RM_EBP|RM_ESI|RM_EDI), | ||
| RM_CALLEE_SAVED = (RM_EBP|RM_EBX|RM_ESI|RM_EDI), | ||
| RM_CALLEE_TRASHED = (RM_ALL & ~RM_CALLEE_SAVED), | ||
| }; | ||
|
|
||
| /***************************************************************************** | ||
| * | ||
| * Helper to extract basic info from a method info block. | ||
| */ | ||
|
|
||
| struct hdrInfo | ||
| { | ||
| unsigned int methodSize; // native code bytes | ||
| unsigned int argSize; // in bytes | ||
| unsigned int stackSize; // including callee saved registers | ||
| unsigned int rawStkSize; // excluding callee saved registers | ||
| ReturnKind returnKind; // The ReturnKind for this method. | ||
|
|
||
| unsigned int prologSize; | ||
|
|
||
| // Size of the epilogs in the method. | ||
| // For methods which use CEE_JMP, some epilogs may end with a "ret" instruction | ||
| // and some may end with a "jmp". The epilogSize reported should be for the | ||
| // epilog with the smallest size. | ||
| unsigned int epilogSize; | ||
|
|
||
| unsigned char epilogCnt; | ||
| bool epilogEnd; // is the epilog at the end of the method | ||
|
|
||
| bool ebpFrame; // locals and arguments addressed relative to EBP | ||
| bool doubleAlign; // is the stack double-aligned? locals addressed relative to ESP, and arguments relative to EBP | ||
| bool interruptible; // intr. at all times (excluding prolog/epilog), not just call sites | ||
|
|
||
| bool handlers; // has callable handlers | ||
| bool localloc; // uses localloc | ||
| bool editNcontinue; // has been compiled in EnC mode | ||
| bool varargs; // is this a varargs routine | ||
| bool profCallbacks; // does the method have Enter-Leave callbacks | ||
| bool genericsContext;// has a reported generic context parameter | ||
| bool genericsContextIsMethodDesc;// reported generic context parameter is methoddesc | ||
| bool isSpeculativeStackWalk; // is the stackwalk seeded by an untrusted source (e.g., sampling profiler)? | ||
|
|
||
| // These always includes EBP for EBP-frames and double-aligned-frames | ||
| RegMask savedRegMask:8; // which callee-saved regs are saved on stack | ||
|
|
||
| // Count of the callee-saved registers, excluding the frame pointer. | ||
| // This does not include EBP for EBP-frames and double-aligned-frames. | ||
| unsigned int savedRegsCountExclFP; | ||
|
|
||
| unsigned int untrackedCnt; | ||
| unsigned int varPtrTableSize; | ||
| unsigned int argTabOffset; // INVALID_ARGTAB_OFFSET if argtab must be reached by stepping through ptr tables | ||
| unsigned int gsCookieOffset; // INVALID_GS_COOKIE_OFFSET if there is no GuardStack cookie | ||
|
|
||
| unsigned int syncStartOffset; // start/end code offset of the protected region in synchronized methods. | ||
| unsigned int syncEndOffset; // INVALID_SYNC_OFFSET if there not synchronized method | ||
| unsigned int syncEpilogStart; // The start of the epilog. Synchronized methods are guaranteed to have no more than one epilog. | ||
| unsigned int revPInvokeOffset; // INVALID_REV_PINVOKE_OFFSET if there is no Reverse PInvoke frame | ||
|
|
||
| enum { NOT_IN_PROLOG = -1, NOT_IN_EPILOG = -1 }; | ||
|
|
||
| int prologOffs; // NOT_IN_PROLOG if not in prolog | ||
| int epilogOffs; // NOT_IN_EPILOG if not in epilog. It is never 0 | ||
|
|
||
| // | ||
| // Results passed back from scanArgRegTable | ||
| // | ||
| regNum thisPtrResult; // register holding "this" | ||
| RegMask regMaskResult; // registers currently holding GC ptrs | ||
| RegMask iregMaskResult; // iptr qualifier for regMaskResult | ||
| unsigned argHnumResult; | ||
| PTR_CBYTE argTabResult; // Table of encoded offsets of pending ptr args | ||
| unsigned argTabBytes; // Number of bytes in argTabResult[] | ||
|
|
||
| // These next two are now large structs (i.e 132 bytes each) | ||
|
|
||
| ptrArgTP argMaskResult; // pending arguments mask | ||
| ptrArgTP iargMaskResult; // iptr qualifier for argMaskResult | ||
| }; | ||
|
|
||
| bool UnwindStackFrameX86(PREGDISPLAY pContext, | ||
| PTR_CBYTE methodStart, | ||
| DWORD curOffs, | ||
| hdrInfo * info, | ||
| PTR_CBYTE table, | ||
| IN_EH_FUNCLETS_COMMA(PTR_CBYTE funcletStart) | ||
| IN_EH_FUNCLETS_COMMA(bool isFunclet) | ||
| bool updateAllRegs); | ||
|
|
||
| size_t DecodeGCHdrInfo(GCInfoToken gcInfoToken, | ||
| unsigned curOffset, | ||
| hdrInfo * infoPtr); | ||
|
|
||
| #endif // _UNWIND_X86_H |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back 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.
This likely should be changed back and
bitvector.cppneeds to be added to NativeAOT/win-x86 build.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.
BitVector does not seem to be used anywhere else. What is the advantage of using the BITVECTOR wrapper? Can we delete bitvector.h/bitvector.cpp and turn the handful of methods into internal helpers used by x86 GC info decoding only?
Uh oh!
There was an error while loading. Please reload this page.
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.
It is used for
ptrArgTPwhich is in turn used in the x86 GC info decoder. I suppose it may be needed for methods with > 64 arguments. For the sake of simplicity I opted to go with!USE_BITVECTORfor the bring up but I suppose theBitVectoris necessary for correctness.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.
Oh, if you mean to merge it with the rest of the extracted code, I guess that would make sense. I'd prefer to do it separately to keep it reviewable.
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.
Yes, I would move it together (and maybe renamed it too). It is not a general purpose bitvector. Also, delete the non-BitVector path.
It is fine to do it in a follow up PR.