@@ -2477,7 +2477,10 @@ void Lowering::InsertPInvokeMethodProlog()
2477
2477
2478
2478
if (comp->opts .ShouldUsePInvokeHelpers ())
2479
2479
{
2480
- // Initialize the P/Invoke frame by calling CORINFO_HELP_INIT_PINVOKE_FRAME
2480
+ // Initialize the P/Invoke frame by calling CORINFO_HELP_INIT_PINVOKE_FRAME:
2481
+ //
2482
+ // OpaqueFrame opaqueFrame;
2483
+ // CORINFO_HELP_INIT_PINVOKE_FRAME(&opaqueFrame);
2481
2484
2482
2485
GenTree* frameAddr = new (comp, GT_LCL_VAR_ADDR)
2483
2486
GenTreeLclVar (GT_LCL_VAR_ADDR, TYP_BYREF, comp->lvaInlinedPInvokeFrameVar , BAD_IL_OFFSET);
@@ -2845,6 +2848,55 @@ GenTree* Lowering::LowerNonvirtPinvokeCall(GenTreeCall* call)
2845
2848
// ------------------------------------------------------
2846
2849
// Non-virtual/Indirect calls: PInvoke calls.
2847
2850
2851
+ // PInvoke lowering varies depending on the flags passed in by the EE. By default,
2852
+ // GC transitions are generated inline; if CORJIT_FLG2_USE_PINVOKE_HELPERS is specified,
2853
+ // GC transitions are instead performed using helper calls. Examples of each case are given
2854
+ // below. Note that the data structure that is used to store information about a call frame
2855
+ // containing any P/Invoke calls is initialized in the method prolog (see
2856
+ // InsertPInvokeMethod{Prolog,Epilog} for details).
2857
+ //
2858
+ // Inline transitions:
2859
+ // InlinedCallFrame inlinedCallFrame;
2860
+ //
2861
+ // ...
2862
+ //
2863
+ // // Set up frame information
2864
+ // inlinedCallFrame.callTarget = methodHandle;
2865
+ // inlinedCallFrame.callSiteTracker = SP; (x86 only)
2866
+ // inlinedCallFrame.callSiteReturnAddress = &label; (the address of the instruction immediately following the call)
2867
+ // thread->m_pFrame = &inlinedCallFrame; (non-IL-stub only)
2868
+ //
2869
+ // // Switch the thread's GC mode to preemptive mode
2870
+ // thread->m_fPreemptiveGCDisabled = 0;
2871
+ //
2872
+ // // Call the unmanged method
2873
+ // target();
2874
+ //
2875
+ // // Switch the thread's GC mode back to cooperative mode
2876
+ // thread->m_fPreemptiveGCDisabled = 1;
2877
+ //
2878
+ // // Rendezvous with a running collection if necessary
2879
+ // if (g_TrapReturningThreads)
2880
+ // RareDisablePreemptiveGC();
2881
+ //
2882
+ // Transistions using helpers:
2883
+ //
2884
+ // OpaqueFrame opaqueFrame;
2885
+ //
2886
+ // ...
2887
+ //
2888
+ // // Call the JIT_PINVOKE_BEGIN helper
2889
+ // JIT_PINVOKE_BEGIN(&opaqueFrame);
2890
+ //
2891
+ // // Call the unmanaged method
2892
+ // target();
2893
+ //
2894
+ // // Call the JIT_PINVOKE_END helper
2895
+ // JIT_PINVOKE_END(&opaqueFrame);
2896
+ //
2897
+ // Note that the JIT_PINVOKE_{BEGIN.END} helpers currently use the default calling convention for the target platform.
2898
+ // They may be changed in the near future s.t. they preserve all register values.
2899
+
2848
2900
GenTree* result = nullptr ;
2849
2901
void * addr = nullptr ;
2850
2902
0 commit comments