예제 #1
0
        private unsafe ThunksHeap(IntPtr commonStubAddress)
        {
            _commonStubAddress = commonStubAddress;

            _allocatedBlocks = new AllocatedBlock();

            InternalCalls.RhpAcquireThunkPoolLock();

            IntPtr thunkStubsBlock = ThunkBlocks.GetNewThunksBlock();

            InternalCalls.RhpReleaseThunkPoolLock();

            if (thunkStubsBlock != IntPtr.Zero)
            {
                IntPtr thunkDataBlock = InternalCalls.RhpGetThunkDataBlockAddress(thunkStubsBlock);

                // Address of the first thunk data cell should be at the begining of the thunks data block (page-aligned)
                Debug.Assert(((nuint)(nint)thunkDataBlock % Constants.PageSize) == 0);

                // Update the last pointer value in the thunks data section with the value of the common stub address
                *(IntPtr *)(thunkDataBlock + (int)(Constants.PageSize - IntPtr.Size)) = commonStubAddress;
                Debug.Assert(*(IntPtr *)(thunkDataBlock + (int)(Constants.PageSize - IntPtr.Size)) == commonStubAddress);

                // Set the head and end of the linked list
                _nextAvailableThunkPtr = thunkDataBlock;
                _lastThunkPtr          = _nextAvailableThunkPtr + Constants.ThunkDataSize * (Constants.NumThunksPerBlock - 1);

                _allocatedBlocks._blockBaseAddress = thunkStubsBlock;
            }
        }
예제 #2
0
        private unsafe ThunksHeap(IntPtr commonStubAddress)
        {
            _commonStubAddress = commonStubAddress;

            _allocatedBlocks = new AllocatedBlock();

            InternalCalls.RhpAcquireThunkPoolLock();

            IntPtr thunksBlock = ThunkBlocks.GetNewThunksBlock();

            InternalCalls.RhpReleaseThunkPoolLock();

            if (thunksBlock != IntPtr.Zero)
            {
                // Update the last pointer value in the thunks data section with the value of the common stub address
                *((IntPtr *)(thunksBlock + (int)(Constants.PageSize * 2 - IntPtr.Size))) = commonStubAddress;
                Debug.Assert(*((IntPtr *)(thunksBlock + (int)(Constants.PageSize * 2 - IntPtr.Size))) != IntPtr.Zero);

                // Set the head and end of the linked list
                _nextAvailableThunkPtr = thunksBlock + (int)Constants.PageSize;
                _lastThunkPtr          = _nextAvailableThunkPtr + 2 * IntPtr.Size * (InternalCalls.RhpGetNumThunksPerBlock() - 1);

                _allocatedBlocks._blockBaseAddress = thunksBlock;
            }
        }
예제 #3
0
        // TODO: Feature
        // public static ThunksHeap DestroyThunksHeap(ThunksHeap heapToDestroy)
        // {
        // }

        //
        // Note: Expected to be called under lock
        //
        private unsafe bool ExpandHeap()
        {
            AllocatedBlock newBlockInfo;

            try
            {
                newBlockInfo = new AllocatedBlock();
            }
            catch (Exception)
            {
                return(false);
            }

            IntPtr thunkStubsBlock = ThunkBlocks.GetNewThunksBlock();

            if (thunkStubsBlock != IntPtr.Zero)
            {
                IntPtr thunkDataBlock = InternalCalls.RhpGetThunkDataBlockAddress(thunkStubsBlock);

                // Address of the first thunk data cell should be at the begining of the thunks data block (page-aligned)
                Debug.Assert(((nuint)(nint)thunkDataBlock % Constants.PageSize) == 0);

                // Update the last pointer value in the thunks data section with the value of the common stub address
                *(IntPtr *)(thunkDataBlock + (int)(Constants.PageSize - IntPtr.Size)) = _commonStubAddress;
                Debug.Assert(*(IntPtr *)(thunkDataBlock + (int)(Constants.PageSize - IntPtr.Size)) == _commonStubAddress);

                // Link the last entry in the old list to the first entry in the new list
                *((IntPtr *)_lastThunkPtr) = thunkDataBlock;

                // Update the pointer to the last entry in the list
                _lastThunkPtr = *((IntPtr *)_lastThunkPtr) + Constants.ThunkDataSize * (Constants.NumThunksPerBlock - 1);

                newBlockInfo._blockBaseAddress = thunkStubsBlock;
                newBlockInfo._nextBlock        = _allocatedBlocks;

                _allocatedBlocks = newBlockInfo;

                return(true);
            }

            return(false);
        }
예제 #4
0
        // TODO: Feature
        // public static ThunksHeap DestroyThunksHeap(ThunksHeap heapToDestroy)
        // {
        // }

        //
        // Note: Expected to be called under lock
        //
        private unsafe bool ExpandHeap()
        {
            AllocatedBlock newBlockInfo;

            try
            {
                newBlockInfo = new AllocatedBlock();
            }
            catch
            {
                return(false);
            }

            IntPtr newBlockAddress = ThunkBlocks.GetNewThunksBlock();

            if (newBlockAddress != IntPtr.Zero)
            {
                // Update the last pointer value in the thunks data section with the value of the common stub address
                *((IntPtr *)(newBlockAddress + (int)(Constants.PageSize * 2 - IntPtr.Size))) = _commonStubAddress;
                Debug.Assert(*((IntPtr *)(newBlockAddress + (int)(Constants.PageSize * 2 - IntPtr.Size))) != IntPtr.Zero);

                // Link the last entry in the old list to the first entry in the new list
                *((IntPtr *)_lastThunkPtr) = newBlockAddress + (int)Constants.PageSize;

                // Update the pointer to the last entry in the list
                _lastThunkPtr = newBlockAddress + (int)Constants.PageSize + 2 * IntPtr.Size * (InternalCalls.RhpGetNumThunksPerBlock() - 1);

                newBlockInfo._blockBaseAddress = newBlockAddress;
                newBlockInfo._nextBlock        = _allocatedBlocks;

                _allocatedBlocks = newBlockInfo;

                return(true);
            }

            return(false);
        }