/// <summary> /// Create a new value from a key. Must be threadsafe. Value may or may not be added /// to collection. Return value must not be null. /// </summary> protected override unsafe MethodEntrypointPtr CreateValueFromKey(MethodEntrypointLookup key) { lock (this) { IntPtr thunk = IntPtr.Zero; if (s_thunkPoolHeap == null) { s_thunkPoolHeap = RuntimeAugments.CreateThunksHeap(s_entryPointStub); MethodEntrypointPtr.SetThunkPool(s_thunkPoolHeap); Debug.Assert(s_thunkPoolHeap != null); } thunk = RuntimeAugments.AllocateThunk(s_thunkPoolHeap); Debug.Assert(thunk != IntPtr.Zero); MethodEntrypointData *methodEntrypointData = (MethodEntrypointData *)MemoryHelpers.AllocateMemory(sizeof(MethodEntrypointData)); *methodEntrypointData = new MethodEntrypointData(key.MethodHandle, thunk); RuntimeAugments.SetThunkData(s_thunkPoolHeap, thunk, IntPtr.Zero, new IntPtr(methodEntrypointData)); SerializedDebugData.RegisterTailCallThunk(thunk); return(new MethodEntrypointPtr(methodEntrypointData)); } }
private static IntPtr GetThunkThatDereferencesThisPointerAndTailCallsTarget(IntPtr target) { IntPtr result = IntPtr.Zero; lock (s_deferenceAndCallThunks) { if (!s_deferenceAndCallThunks.TryGetValue(target, out result)) { if (s_DerefThisAndCall_ThunkPoolHeap == null) { s_DerefThisAndCall_ThunkPoolHeap = RuntimeAugments.CreateThunksHeap(s_constrainedCallSupport_DerefThisAndCall_CommonCallingStub); Debug.Assert(s_DerefThisAndCall_ThunkPoolHeap != null); } IntPtr thunk = RuntimeAugments.AllocateThunk(s_DerefThisAndCall_ThunkPoolHeap); Debug.Assert(thunk != IntPtr.Zero); RuntimeAugments.SetThunkData(s_DerefThisAndCall_ThunkPoolHeap, thunk, target, IntPtr.Zero); result = thunk; s_deferenceAndCallThunks.Add(target, result); } SerializedDebugData.RegisterTailCallThunk(result); } return(result); }
public static unsafe IntPtr GetDirectConstrainedCallPtr(RuntimeTypeHandle constraintType, RuntimeTypeHandle constrainedMethodType, int constrainedMethodSlot) { if (s_DirectConstrainedCall_ThunkPoolHeap == null) { lock (s_DirectConstrainedCall_ThunkPoolHeapLock) { if (s_DirectConstrainedCall_ThunkPoolHeap == null) { s_DirectConstrainedCall_ThunkPoolHeap = RuntimeAugments.CreateThunksHeap(s_constrainedCallSupport_DirectConstrainedCall_CommonCallingStub); Debug.Assert(s_DirectConstrainedCall_ThunkPoolHeap != null); } } } IntPtr thunk = RuntimeAugments.AllocateThunk(s_DirectConstrainedCall_ThunkPoolHeap); Debug.Assert(thunk != IntPtr.Zero); IntPtr constrainedCallDesc = Get(constraintType, constrainedMethodType, constrainedMethodSlot, true); RuntimeAugments.SetThunkData(s_DirectConstrainedCall_ThunkPoolHeap, thunk, constrainedCallDesc, s_resolveDirectConstrainedCallFuncPtr); SerializedDebugData.RegisterTailCallThunk(thunk); return(thunk); }
/// <summary> /// Register a new runtime-allocated code thunk in the diagnostic stream. /// </summary> /// <param name="thunkAddress">Address of thunk to register</param> public override void RegisterThunk(IntPtr thunkAddress) { SerializedDebugData.RegisterTailCallThunk(thunkAddress); }