-
Notifications
You must be signed in to change notification settings - 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
Conversation
| #ifndef FEATURE_NATIVEAOT | ||
| #define USE_BITVECTOR 1 | ||
| #endif |
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.cpp needs 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?
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 ptrArgTP which 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_BITVECTOR for the bring up but I suppose the BitVector is 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.
72f41d8 to
6ca5310
Compare
|
....and, just as expected, I must have messed up something while cleaning this up and I broke win-x86 CoreCLR. Switching back to draft until I figure out what was it. |
|
@filipnavara I am OOF, I will review it in detail on Monday. |
Extracts x86 unwinding code and EnumGCRefs from eetwain.h/cpp into gc_unwind_x86.h/inl files. The bulk of the code remains unchanged with the methods UnwindStackFrameX86 and EnumGcRefsX86 extracted from the original EECodeManager methods. CoffNativeCodeManager includes all the x86 GC decoders and includes gc_unwind_x86.inl for TARGET_X86. Missing methods are implemented in terms of UnwindStackFrameX86, EnumGcRefsX86, and DecodeGCHdrInfo. Funclet calling assembly helpers are fixed up to follow the same pattern as on other platform.
9993252 to
15543ed
Compare
| call RhpCallFunclet | ||
|
|
||
| ALTERNATE_ENTRY RhpCallCatchFunclet2 | ||
| CALL_FUNCLET Catch |
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.
Does pushing the ebp that the macro does in the middle of a function work well with the debugger stack unwinding from the actual funclet / the code inside of this macro after the ebp is pushed?
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.
That's good question and I will try.
That said, the hack with custom object file that ProjectN used doesn't really transfer well and requires custom code all over the place. Since the thread hijacking works differently from ProjectN I don't expect this to hit the same issues. The NativeAOT unwinder used for exception handling, GC refs, and hijacking, can work with the ebp on the stack.
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 suppose I can reserve one more stack slot through FUNCLET_CALL_PROLOGUE and use that instead of push / pop. Would that make sense?
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 it is ok as is, so if you verify that stepping through that code keeps debugger showing correct stack trace, we can keep it as is.
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.
Stack trace before the push ebp:
[0x0] Exceptions!RhpCallCatchFunclet+0x44 0xd7f888 0x7b1b4b
[0x1] Exceptions!_ehinfo_System.Activator__CreateInstance<System___Canon> 0xd7f88c 0x56e5f4
[0x2] Exceptions!System.Runtime.EH__DispatchEx+0x5e4 0xd7f8a4 0x56def9
[0x3] Exceptions!System.Runtime.EH__RhThrowHwEx+0x149 0xd7f9b0 0x34428a
[0x4] Exceptions!RhpThrowHwEx2 0xd7f9e8 0x4ba181
[0x5] Exceptions!Exceptions_BringUpTest__TestGenericExceptions+0x21 0xd7faf0 0x56b87a
[0x6] Exceptions!System.Runtime.GCSettings__get_IsServerGC+0xa 0xd7fafc 0x0
Stack trace after the mov ebp, eax:
[0x0] Exceptions!RhpCallCatchFunclet+0x47 0xd7f884 0x4ba181
[0x1] Exceptions!Exceptions_BringUpTest__TestGenericExceptions+0x21 0xd7faf0 0x4b98fb
[0x2] Exceptions!Exceptions_BringUpTest__Main+0xbb 0xd7fb0c 0x6256c8
[0x3] Exceptions!Exceptions__Module___MainMethodWrapper+0x8 0xd7fc40 0x62572e
[0x4] Exceptions!Exceptions__Module___StartupCodeMain+0x5e 0xd7fc48 0x343cbb
[0x5] Exceptions!wmain+0x2b 0xd7fc68 0x414bd3
[0x6] Exceptions!invoke_main+0x33 0xd7fc7c 0x414aa7
[0x7] Exceptions!__scrt_common_main_seh+0x157 0xd7fc9c 0x41494d
[0x8] Exceptions!__scrt_common_main+0xd 0xd7fcf8 0x414c38
[0x9] Exceptions!wmainCRTStartup+0x8 0xd7fd00 0x75775d49
[0xa] KERNEL32!BaseThreadInitThunk+0x19 0xd7fd08 0x76f0bb1b
[0xb] ntdll!__RtlUserThreadStart+0x2b 0xd7fd18 0x76f0baa1
[0xc] ntdll!_RtlUserThreadStart+0x1b 0xd7fd70 0x0
So, it is broken, but it is actually broken in the first part of the code.
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 would be interesting to investigate why the stack trace is broken before the push, but that's clearly unrelated to this PR.
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 think I know how to fix it. I'll look at it once I flush the current patch queue.
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.
LGTM, thank you!
Extracts x86 unwinding code and
EnumGCRefsfromeetwain.h/cppintogc_unwind_x86.h/inlfiles. The bulk of the code remains unchanged with the methodsUnwindStackFrameX86andEnumGcRefsX86extracted from the originalEECodeManagermethods.CoffNativeCodeManagerincludes all the x86 GC decoders and includesgc_unwind_x86.inlfor TARGET_X86. Missing methods are implemented in terms ofUnwindStackFrameX86,EnumGcRefsX86, andDecodeGCHdrInfo.Funclet calling assembly helpers are fixed up to follow the same pattern as on other platform.
For the purpose of the PR review the first commit moves the code from eetwain.cpp into gc_unwind_x86.inl verbatim. It doesn't compile. The second commit is the real viewable diff where the changes are actually visible without the move.