/// <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));
                }
            }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        private static PInvokeDelegateThunk AllocateThunk(Delegate del)
        {
            if (s_thunkPoolHeap == null)
            {
                // TODO: Free s_thunkPoolHeap if the thread lose the race
                Interlocked.CompareExchange(
                    ref s_thunkPoolHeap,
                    RuntimeAugments.CreateThunksHeap(RuntimeImports.GetInteropCommonStubAddress()),
                    null
                    );
                Debug.Assert(s_thunkPoolHeap != null);
            }

            var delegateThunk = new PInvokeDelegateThunk(del);

            McgPInvokeDelegateData pinvokeDelegateData;

            if (!RuntimeAugments.InteropCallbacks.TryGetMarshallerDataForDelegate(del.GetTypeHandle(), out pinvokeDelegateData))
            {
                Environment.FailFast("Couldn't find marshalling stubs for delegate.");
            }

            //
            //  For open static delegates set target to ReverseOpenStaticDelegateStub which calls the static function pointer directly
            //
            IntPtr pTarget = del.GetRawFunctionPointerForOpenStaticDelegate() == IntPtr.Zero ? pinvokeDelegateData.ReverseStub : pinvokeDelegateData.ReverseOpenStaticDelegateStub;

            RuntimeAugments.SetThunkData(s_thunkPoolHeap, delegateThunk.Thunk, delegateThunk.ContextData, pTarget);

            return(delegateThunk);
        }
Ejemplo n.º 4
0
            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);
            }
Ejemplo n.º 5
0
        private static PInvokeDelegateThunk AllocateThunk(Delegate del)
        {
            if (s_thunkPoolHeap == null)
            {
                // TODO: Free s_thunkPoolHeap if the thread lose the race
                Interlocked.CompareExchange(
                    ref s_thunkPoolHeap,
                    RuntimeAugments.CreateThunksHeap(RuntimeImports.GetInteropCommonStubAddress()),
                    null
                    );
                Debug.Assert(s_thunkPoolHeap != null);
            }

            var delegateThunk = new PInvokeDelegateThunk(del);

            //
            //  For open static delegates set target to ReverseOpenStaticDelegateStub which calls the static function pointer directly
            //
            bool openStaticDelegate = del.GetRawFunctionPointerForOpenStaticDelegate() != IntPtr.Zero;

            IntPtr pTarget = RuntimeInteropData.GetDelegateMarshallingStub(del.GetTypeHandle(), openStaticDelegate);

            Debug.Assert(pTarget != IntPtr.Zero);

            RuntimeAugments.SetThunkData(s_thunkPoolHeap, delegateThunk.Thunk, delegateThunk.ContextData, pTarget);

            return(delegateThunk);
        }
Ejemplo n.º 6
0
        private static IntPtr AllocateThunk(Delegate del)
        {
            //TODO: cache del->thunk here

            if (s_thunkPoolHeap == null)
            {
                s_thunkPoolHeap = RuntimeAugments.CreateThunksHeap(RuntimeImports.GetInteropCommonStubAddress());
                Debug.Assert(s_thunkPoolHeap != null);
            }

            IntPtr pThunk = RuntimeAugments.AllocateThunk(s_thunkPoolHeap);

            Debug.Assert(pThunk != IntPtr.Zero);

            if (pThunk == IntPtr.Zero)
            {
                // We've either run out of memory, or failed to allocate a new thunk due to some other bug. Now we should fail fast
                Environment.FailFast("Insufficient number of thunks.");
                return(IntPtr.Zero);
            }
            else
            {
                McgPInvokeDelegateData pinvokeDelegateData;
                if (!RuntimeAugments.InteropCallbacks.TryGetMarshallerDataForDelegate(del.GetTypeHandle(), out pinvokeDelegateData))
                {
                    Environment.FailFast("Couldn't find marshalling stubs for delegate.");
                }
                IntPtr pContext;
                unsafe
                {
                    //
                    // Allocate unmanaged memory for GCHandle of delegate and function pointer of open static delegate
                    // We will store this pointer on the context slot of thunk data
                    //
                    pContext = (IntPtr)CoTaskMemAllocAndZeroMemory((System.IntPtr)(2 * (IntPtr.Size)));
                    ThunkContextData *thunkData = (ThunkContextData *)pContext;

                    (*thunkData).Handle      = GCHandle.Alloc(del, GCHandleType.Weak);
                    (*thunkData).FunctionPtr = del.GetRawFunctionPointerForOpenStaticDelegate();
                }

                //
                //  For open static delegates set target to ReverseOpenStaticDelegateStub which calls the static function pointer directly
                //
                IntPtr pTarget = del.GetRawFunctionPointerForOpenStaticDelegate() == IntPtr.Zero ? pinvokeDelegateData.ReverseStub : pinvokeDelegateData.ReverseOpenStaticDelegateStub;

                RuntimeAugments.SetThunkData(s_thunkPoolHeap, pThunk, pContext, pTarget);

                return(pThunk);
            }
        }
Ejemplo n.º 7
0
        private static IntPtr GetOrAllocateThunk(Delegate del)
        {
            ConditionalWeakTable <Delegate, PInvokeDelegateThunk> pinvokeDelegates = GetPInvokeDelegates();

            PInvokeDelegateThunk delegateThunk;

            // if the delegate already exists in the table return the allocated thunk for it
            if (pinvokeDelegates.TryGetValue(del, out delegateThunk))
            {
                return(delegateThunk.Thunk);
            }

            if (s_thunkPoolHeap == null)
            {
                s_thunkPoolHeap = RuntimeAugments.CreateThunksHeap(RuntimeImports.GetInteropCommonStubAddress());
                Debug.Assert(s_thunkPoolHeap != null);
            }


            delegateThunk = new PInvokeDelegateThunk(del);


            McgPInvokeDelegateData pinvokeDelegateData;

            if (!RuntimeAugments.InteropCallbacks.TryGetMarshallerDataForDelegate(del.GetTypeHandle(), out pinvokeDelegateData))
            {
                Environment.FailFast("Couldn't find marshalling stubs for delegate.");
            }

            //
            //  For open static delegates set target to ReverseOpenStaticDelegateStub which calls the static function pointer directly
            //
            IntPtr pTarget = del.GetRawFunctionPointerForOpenStaticDelegate() == IntPtr.Zero ? pinvokeDelegateData.ReverseStub : pinvokeDelegateData.ReverseOpenStaticDelegateStub;


            RuntimeAugments.SetThunkData(s_thunkPoolHeap, delegateThunk.Thunk, delegateThunk.ContextData, pTarget);

            // Add the delegate to the dictionary if it doesn't already exists
            delegateThunk = pinvokeDelegates.GetOrAdd(del, delegateThunk);

            return(delegateThunk.Thunk);
        }
Ejemplo n.º 8
0
        private static IntPtr CreateDynamicThunk(int slotIndex)
        {
            if (s_lazyVtableThunksPoolHeap == null)
            {
                s_lazyVtableThunksPoolHeap = RuntimeAugments.CreateThunksHeap(VTableResolver_GetCommonCallingStub());
                Debug.Assert(s_lazyVtableThunksPoolHeap != null);
            }

            IntPtr thunk = RuntimeAugments.AllocateThunk(s_lazyVtableThunksPoolHeap);

            if (thunk == IntPtr.Zero)
            {
                Environment.FailFast("Not enough thunks for calling convention converter");
            }

            int eetypeVtableOffset = SlotIndexToEETypeVTableOffset(slotIndex);

            RuntimeAugments.SetThunkData(s_lazyVtableThunksPoolHeap, thunk, new IntPtr(eetypeVtableOffset), thunk);

            return(thunk);
        }