Skip to content

Conversation

@ericwj
Copy link
Collaborator

@ericwj ericwj commented Jul 23, 2022

PR Details

Migrate away from IL weaving and take the first steps to improve memory management.

The mode of operation has generally been not to rewrite to safe code immediately.

Description

  • Fixed a buffer overrun in ParameterCollection.CopyTo<T>.
  • Identified a bug affecting the copy operation in ParameterCollection.UpdateLayout caused by parameters changing type and size after being initialized. Modified the copy operation to right-size them for every element in the collection, pending fixing of the bug causing the types to differ.
  • Replaces uses of methods that are IL weaved with their C# equivalents. Rewrites Utilities marking most methods in it as obsolete, remove Interop.
    • In particular using Unsafe.CopyBlockUnaligned instead of Utilities.CopyMemory.
  • Reviewed most uses of fixed
    • To verify that code around it throws instead of dereferencing null if the array being fixed is null or empty.
    • To elide checks on array.Length if the null result of fixed is intended when the array is null or empty.
  • Add Debug.Assert in some places to verify correctness of CopyBlock and similar operations.
  • Review all implementations of System.IO.Stream:
    • Add synchronous overloads for Read and Write that take Span<byte> as argument.
    • Fix the exception behavior to match the documentation of System.IO.Stream; no longer throw InvalidOperationException or EndOfStreamException, but use NotSupportedException and IOException.
    • Obsolete and remove NativeStream and NativeMemoryStream from the inheritance graph of Strides Stream types.
      • Obsolete related types such as NativeStreamWrapper.
      • SerializationStream.NativeStream is of type Stream, no longer NativeStream and is obsoleted in favor of the new property UnderlyingStream.
      • Use UnmanagedMemoryStream to replace all usage of NativeMemoryStream in Stride.
      • BlobStream now inherits from UnmanagedMemoryStream instead of from NativeMemoryStream.
    • Polyfill the virtual methods in NativeStream with extension methods. These are obsolete themselves since they are inefficient.
  • Obsolete BinarySerialization on grounds that it is inefficent and a very minor benefit to Stride users.
  • Added handle types to the P/Invoke declarations of Navigation.
  • Many methods dealing with primitives and e.g. image data have had their type constraints changed from struct to unmanaged.
  • Minor improvements in performance such as vector-enabled SequenceEqual over CompareMemory, correctness, code style and use of new language features in particular nint and nuint over IntPtr.

Related Issue

#1461

Motivation and Context

See issue for the motivation for starting this PR. Issues with buffer overruns which have surfaced are hard to fix without tracking of owned memory throughout the code. Hence the scope of this PR is broadened to include basic memory management.

Types of changes

  • Docs change / refactoring / dependency upgrade
  • Bug fix (non-breaking change which fixes an issue) Access violations have been reported and there are hidden buffer overruns which may or may not be separate of those.
  • New feature (non-breaking change which adds functionality) The changes in types and inheritance hierarchy are binary breaking changs, but will be source-compatible.
  • Breaking change (fix or feature that would cause existing functionality to change)
    • Public API affected by the described changes have been marked obsolete and will now generate warnings.

Did not make it into this PR

  • Many formal declarations using nint, IntPtr, void* or other unmanaged pointers will be obsoleted in favor or overloads that consistently carry length information, such as Memory<T> and Span<T>.
  • Use of arrays in signatures, fields and implementations may be (further) discouraged and obsoleted.

Checklist

  • This work in progress has completed.
  • My change requires a change to the documentation.
    • Documentation comments have been modified and added.
  • I have added tests to cover my changes.
  • All new and existing tests passed. All tests succeed, except the following. 3 test projects fail to run due to test infrastructure failures. 1 test project fails all tests due to expecting packages for samples in $env:USERPROFILE\.nuget\packages which don't exist.

@ericwj ericwj changed the title Migrate IL weaving 10-CoreRuntime and Stride Migrate IL weaving Step 2 Jul 24, 2022
@xen2
Copy link
Member

xen2 commented Jul 29, 2022

Great change! (that I meant to do for a long time to remove yet another AssemblyProcessor dependency but never got around to do)

One important point though:
I was thinking, shouldn't we directly use the underlying Unsafe methods rather than writing yet another wrapper on it?

It would make the code more direct, standard & easy to understand, esp. for people familiar with recent high-perf C# (no need to check how our low-level Utilities/CoreUtilities map to yet another low-level Unsafe call).

That's what I initially had in mind when I saw all the new recently Unsafe equivalent to our Utilities class.

@ericwj
Copy link
Collaborator Author

ericwj commented Jul 29, 2022

I was thinking, shouldn't we directly use the underlying Unsafe methods rather than writing yet another wrapper on it?

Ideally yes but there are AV's, this is perhaps a halfway measure to have some checks (right now also but sometimes). Since Stride usually works, can also leave it for now and come back to the AV's later getting rid of AllocHGlobal and using a better, verifyable allocation strategy.

@ericwj
Copy link
Collaborator Author

ericwj commented Jul 29, 2022

I had Span<T>.CopyTo in a fair few cases. But testing it the first time it was clear it wasn't going to work.

@ericwj
Copy link
Collaborator Author

ericwj commented Jul 29, 2022

Checked it twice, don't see anything wrong - most changes are mundane. Yet I can't start GameStudio anymore - when it sais Loading scene opening Starbreach there is an AV.

@ericwj ericwj requested review from manio143 and xen2 July 29, 2022 23:11
@ericwj ericwj changed the title Migrate IL weaving Step 2 Improve memory management, embrace modern .NET Jul 29, 2022
@ericwj
Copy link
Collaborator Author

ericwj commented Jul 29, 2022

I have updated the title and the description to reflect the current plan as discussed with @xen2.

@manio143 would you review please as I go?

Copy link
Member

@manio143 manio143 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looked through the first half of this PR (incl Stride.Graphics) - looks good overall

@manio143
Copy link
Member

Please note that Vulkan builds are failing - VS by default only builds for D3D11 and you may need to modify sources\targets\Stride.props and set <StrideDefaultGraphicsApi>Vulkan</StrideDefaultGraphicsApi> on line 21 to have VS build Vulkan config for you.

ericwj added 8 commits August 3, 2022 01:07
Remove Read/Write(nint, int), also from SerializationStream.
Polyfill with extension methods. Source compatible; binary breaking.
Proper exceptions in new methods; fix messages in others.
Remove manually copied documentation comments in favor of `<inheritdoc/>`.
… buffer.

Fixes pre-existing buffer overrun and those introduced by assuming trailing alignment padding.
ericwj added 2 commits August 4, 2022 18:20
To account for differences in type/size of equally named parameters.
@ericwj
Copy link
Collaborator Author

ericwj commented Aug 5, 2022

Documented the changes in this PR in the description, since the intent is to merge and continue in a future PR.

@ericwj ericwj changed the title [WIP] Improve memory management, embrace modern .NET Improve memory management, embrace modern .NET Aug 7, 2022
@xen2
Copy link
Member

xen2 commented Aug 7, 2022

I didn't have the time to go through every single change yet, but from what I saw so far it's a great PR!
It simplifies a lot of code and put it much more in line with recent C#! (esp. unsafe and lot of custom workaround we had)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants