Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[browser][wasm] Implement JavaScript managed object reference counting #37417

Merged
merged 145 commits into from
Jun 12, 2020
Merged

[browser][wasm] Implement JavaScript managed object reference counting #37417

merged 145 commits into from
Jun 12, 2020

Conversation

kjpou1
Copy link
Contributor

@kjpou1 kjpou1 commented Jun 4, 2020

Wrap the javascript handle in a SafeHandleZeroOrMinusOneIsInvalid implementation.

  • AnyRef

    • Modify AnyRef to be abstract and deriving from SafeHandleZeroOrMinusOneIsInvalid
    • Add extra parameter for ownsHandle
    • The GCHandle.Alloc creates a normal allocation or a weak allocation depending on the ownsHandle value passed.
      • true - GCHandleType.Weak
      • false - GCHandleType.Normal
  • JSObject

    • Implements ReleaseHandle that is overridden from AnyRef
    • This removes the Dispose and Finalizers definitions from the objects. This will be taken care of by AnyRef which derives from SafeHandleZeroOrMinusOneIsInvalid
    • Add extra parameter for ownsHandle
  • Runtime

    • The _boundObjects dictionary that tracks all the objects that have been bound from JavaScript objects to managed code is now a WeakReference.
    • Implement methods for obtaining a handle, adding a reference to a handle and releasing a handle. These are called from the javascript binding_support lib.
    • Refactored the releasing a JSObject.
      • Involved multiple calls to the bindings and managed code.
      • Streamlined to only call the bindings code once to free handles.

Add support for marshaling the AnyRef SafeHandle.

  • When calling into the bindings from managed code the JSObject reference handle is incremented.
  • After execution of the call the JSObject reference is decremented.
  • Special processing for the GlobalObject where the object is set with ownsHandle = false so that it is not released.
  • Release reference counts on javascript exceptions.

Support freeing delegates marshaled to the bindings.

Every delegate that was passed to the bindings code was kept forever causing leaks.

  • Delegates are now not kept alive when GC'd.

  • Delegates using lambda expressions forced the developer to explicitly free the delegate.

    • If a local is captured (used) by a lambda it becomes heap memory as we translate them into fields on an object.
    • A delegate that used lambda expressions was never collected and never released the heap so it could be collected.
    • This was a cause of memory leaks forcing the developer to explicitly call FreeObject (foreachAction);
  • If a delegate is collected and the javascript code calls that delegate function an exception is thrown instead of inexplicably crashing with null exception error.

    • throw new Error("The delegate target that is being invoked is no longer available. Please check if it has been prematurely GC'd.");
    • Uncaught Error: The delegate target that is being invoked is no longer available. Please check if it has been prematurely GC'd.

kjpou1 and others added 30 commits April 28, 2020 12:15
- This still needs to have the code implement nullable
…http-interop

# Conflicts:
#	src/libraries/System.Net.Http/src/System.Net.Http.csproj
- Throws `PlatformNotSupportedException` for properties and methods of the HttpMessageHandler abstract implementation.
- For all of these vars, please replace them with the actual type, except when the type is obvious from a new or explicit cast on the right-hand side.
Co-Authored-By: Marek Safar <marek.safar@gmail.com>
…reference-counting

# Conflicts:
#	src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/AnyRef.cs
#	src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs
@kjpou1 kjpou1 requested a review from jkotas June 10, 2020 07:35
@kjpou1 kjpou1 requested a review from marek-safar June 10, 2020 12:45
}
else
{
Console.WriteLine($"\tSafeHandleReleaseByHandle: did not find active target {jsId} / target: {reference.Target}");
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are these not asserts?

@kjpou1 kjpou1 merged commit 208bce9 into dotnet:master Jun 12, 2020
@kjpou1 kjpou1 deleted the wasm-reference-counting branch June 16, 2020 04:56
@ghost ghost locked as resolved and limited conversation to collaborators Dec 8, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants