Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
8ce637c
thenable and datetime cleanup
pavelsavara Aug 9, 2021
d8326dd
removed ownsHandle for readability, removed AnyRef from hierarchy, re…
pavelsavara Aug 9, 2021
4b96785
rename _csOwnedObjects
pavelsavara Aug 9, 2021
0a4c611
rename _csOwnedObjects
pavelsavara Aug 9, 2021
99b05bb
redirect to Inflight counter
pavelsavara Aug 9, 2021
0d218f9
renames
pavelsavara Aug 9, 2021
151a059
rename and move
pavelsavara Aug 9, 2021
0f3d6d0
rename
pavelsavara Aug 9, 2021
dca5d5e
New+BindCoreObject -> CreateCsOwnedObject single call
pavelsavara Aug 9, 2021
4783438
remove refcount frames
pavelsavara Aug 9, 2021
c2fd18e
differentiate gcHandles
pavelsavara Aug 9, 2021
d30c4a8
get rid of weak GCHandle
pavelsavara Aug 9, 2021
53e2eb9
feedback
pavelsavara Aug 10, 2021
36e864a
added MappedType enum
pavelsavara Aug 10, 2021
e0b3b53
naming consistency
pavelsavara Aug 10, 2021
7c743b1
feedback
pavelsavara Aug 10, 2021
efcd1a9
rename _cs_owned_objects_by_js_handle
pavelsavara Aug 10, 2021
a9212b7
split and rename files
pavelsavara Aug 10, 2021
4f24a9d
shouldAddInflight to more methods
pavelsavara Aug 10, 2021
c5f22be
improved in-flight references
pavelsavara Aug 10, 2021
7d23f76
assert for JSObject not disposed
pavelsavara Aug 10, 2021
cce3ccc
introduce in-flight assert
pavelsavara Aug 10, 2021
e29416a
move should_add_in_flight arg to fisrt position, so that we could bin…
pavelsavara Aug 10, 2021
e4dd539
doc
pavelsavara Aug 10, 2021
3897513
cleanup
pavelsavara Aug 10, 2021
d7345bc
doc
pavelsavara Aug 10, 2021
6ee696a
implement fallback for missing support of FInalizationRegistry/WeakRe…
pavelsavara Aug 16, 2021
92b9a3b
feedback
pavelsavara Aug 16, 2021
685d2a5
no polyfill feedback
pavelsavara Aug 16, 2021
a6f7eda
feedback
pavelsavara Aug 16, 2021
4a388ed
name consistency feedback
pavelsavara Aug 16, 2021
f5cede0
use symbols for helper fields
pavelsavara Aug 16, 2021
b8ad165
feedback
pavelsavara Aug 16, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
get rid of weak GCHandle
  • Loading branch information
pavelsavara committed Aug 16, 2021
commit d30c4a87292fcca390f849c11795f38cdc67b35a
14 changes: 1 addition & 13 deletions src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading.Tasks;

using JSObject = System.Runtime.InteropServices.JavaScript.JSObject;
using JSException = System.Runtime.InteropServices.JavaScript.JSException;
Expand Down Expand Up @@ -36,7 +32,7 @@ internal static partial class Runtime
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern object ReleaseCsOwnedObject(int jsHandle);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern object CreateCsOwnedObject(int gcHandle, string className, object[] parms, out int exceptionalResult);
internal static extern object CreateCsOwnedObject(string className, object[] parms, out int exceptionalResult);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern object TypedArrayToArray(int jsHandle, out int exceptionalResult);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
Expand Down Expand Up @@ -73,14 +69,6 @@ public static string InvokeJS(string str)
return res as System.Runtime.InteropServices.JavaScript.Function;
}

internal static IntPtr CreateCsOwnedObject(int gcHandle, string typeName, params object[] parms)
{
object res = CreateCsOwnedObject(gcHandle, typeName, parms, out int exception);
if (exception != 0)
throw new JSException((string)res);
return (IntPtr)(int)res;
}

public static object GetGlobalObject(string? str = null)
{
int exception;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,38 +11,30 @@ public partial class JSObject : SafeHandleMinusOneIsInvalid
{
private GCHandle? InFlight;
private int InFlightCounter;
private GCHandle WeakRefHandle;
public int JSHandle => (int)handle;
internal int GCHandleValue => (int)(IntPtr)WeakRefHandle;
public bool IsDisposed { get; private set; }

public JSObject() : base(true)
{
// this is weak C# reference to the JSObject, it has same lifetime as the JSObject
WeakRefHandle = GCHandle.Alloc(this, GCHandleType.Weak);
InFlight = null;
InFlightCounter = 0;

var jsHandle = Interop.Runtime.CreateCsOwnedObject(GCHandleValue, nameof(Object));
var jsHandle = Runtime.CreateCsOwnedObject(this, nameof(Object));
SetHandle(jsHandle);
}

protected JSObject(string typeName, object[] _params) : base(true)
{
// this is weak C# reference to the JSObject, it has same lifetime as the JSObject
WeakRefHandle = GCHandle.Alloc(this, GCHandleType.Weak);
InFlight = null;
InFlightCounter = 0;

var jsHandle = Interop.Runtime.CreateCsOwnedObject(GCHandleValue, typeName, _params);
var jsHandle = Runtime.CreateCsOwnedObject(this, typeName, _params);
SetHandle(jsHandle);
}

internal JSObject(IntPtr jsHandle) : base(true)
{
SetHandle(jsHandle);
// this is weak C# reference to the JSObject, it has same lifetime as the JSObject
WeakRefHandle = GCHandle.Alloc(this, GCHandleType.Weak);
InFlight = null;
InFlightCounter = 0;
}
Expand Down Expand Up @@ -82,7 +74,6 @@ protected override bool ReleaseHandle()
Runtime.ReleaseCsOwnedObject(this);
SetHandleAsInvalid();
IsDisposed = true;
WeakRefHandle.Free();
return true;
}

Expand All @@ -92,7 +83,7 @@ protected override bool ReleaseHandle()

public override string ToString()
{
return $"(js-obj js '{GCHandleValue}')";
return $"(js-obj js '{JSHandle}')";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ public void SetObjectProperty(string name, object value, bool createIfNotExists
{
object setPropResult = Interop.Runtime.SetObjectProperty(JSHandle, name, value, createIfNotExists, hasOwnProperty, out int exception);
if (exception != 0)
throw new JSException($"Error setting {name} on (js-obj js '{JSHandle}' .NET '{GCHandleValue})");
throw new JSException($"Error setting {name} on (js-obj js '{JSHandle}')");
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Threading.Tasks;
Expand Down Expand Up @@ -44,44 +43,42 @@ public static void DumpAotProfileData(ref byte buf, int len, string extraArg)
Interop.Runtime.DumpAotProfileData(ref buf, len, extraArg);
}

public static int CsOwnedObjectGetJsHandle(JSObject target, bool addRef)
public static int GetCsOwnedObjectJsHandle(JSObject target, int shouldAddInflight)
{
if (addRef)
if (shouldAddInflight != 0)
{
target.AddInFlight();
}
return target.JSHandle;
}

public static void ReleaseCsOwnedObjectByHandle(int jsHandle)
internal static bool ReleaseCsOwnedObject(JSObject objToRelease)
{
lock (_csOwnedObjects)
{
if (_csOwnedObjects.TryGetValue(jsHandle, out WeakReference<JSObject>? reference))
{
reference.TryGetTarget(out JSObject? target);
Debug.Assert(target != null, $"\tSafeHandleReleaseByHandle: did not find active target {jsHandle}");

target.ReleaseInFlight();
}
else
{
Debug.Fail($"\tSafeHandleReleaseByHandle: did not find reference for {jsHandle}");
}
_csOwnedObjects.Remove(objToRelease.JSHandle);
Interop.Runtime.ReleaseCsOwnedObject(objToRelease.JSHandle);
}
return true;
}

internal static bool ReleaseCsOwnedObject(JSObject objToRelease)
internal static IntPtr CreateCsOwnedObject(JSObject proxy, string typeName, params object[] parms)
{
object res = Interop.Runtime.CreateCsOwnedObject(typeName, parms, out int exception);
if (exception != 0)
throw new JSException((string)res);

var jsHandle = (int)res;

lock (_csOwnedObjects)
{
Interop.Runtime.ReleaseCsOwnedObject(objToRelease.JSHandle);
_csOwnedObjects.Remove(objToRelease.JSHandle);
_csOwnedObjects[jsHandle] = new WeakReference<JSObject>(proxy, trackResurrection: true);
}
return true;

return (IntPtr)jsHandle;
}

public static int CreateCSOwnedObject(int jsHandle, int mappedType)
public static JSObject CreateCSOwnedObject(int jsHandle, int mappedType)
{
JSObject? target = null;

Expand All @@ -98,30 +95,31 @@ public static int CreateCSOwnedObject(int jsHandle, int mappedType)

target.AddInFlight();

return target.GCHandleValue;
return target;
}

public static int TryGetCsOwnedObjectJsHandle(object rawObj)
{
JSObject? jsObject = rawObj as JSObject;
return jsObject?.JSHandle ?? -1;
}

public static object GetJSOwnedObjectByGcHandle(int gcHandle)
{
GCHandle h = (GCHandle)(IntPtr)gcHandle;
return h.Target!;
return jsObject?.JSHandle ?? 0;
}

public static JSObject? GetCSOwnedObjectByGcHandle(int gcHandle, int shouldAddInflight)
public static JSObject? GetCSOwnedObjectByJsHandle(int jsHandle, int shouldAddInflight)
{
GCHandle h = (GCHandle)(IntPtr)gcHandle;
var jso = (JSObject?)h.Target;
if (shouldAddInflight != 0 && jso != null)
lock (_csOwnedObjects)
{
jso.AddInFlight();
if (_csOwnedObjects.TryGetValue(jsHandle, out WeakReference<JSObject>? reference))
{
reference.TryGetTarget(out JSObject? jso);
if (shouldAddInflight != 0 && jso != null)
{
jso.AddInFlight();
}
return jso;
}
}
return jso;
return null;

}

private static JSObject BindJSType(IntPtr jsHandle, int coreType) =>
Expand Down Expand Up @@ -175,6 +173,12 @@ public static object GetTaskSourceTask(int tcsGCHandle)
return tcs.Task;
}

public static object GetJSOwnedObjectByGcHandle(int gcHandle)
{
GCHandle h = (GCHandle)(IntPtr)gcHandle;
return h.Target!;
}

// A JSOwnedObject is a managed object with its lifetime controlled by javascript.
// The managed side maintains a strong reference to the object, while the JS side
// maintains a weak reference and notifies the managed side if the JS wrapper object
Expand All @@ -201,7 +205,7 @@ public static int GetJSOwnedObjectGCHandle(object o)

// The JS layer invokes this method when the JS wrapper for a JS owned object
// has been collected by the JS garbage collector
public static void ReleaseJSOwnedObjectByHandle(int gcHandle)
public static void ReleaseJSOwnedObjectByGcHandle(int gcHandle)
{
GCHandle handle = (GCHandle)(IntPtr)gcHandle;
lock (JSOwnedObjectLock)
Expand Down
Loading