Skip to content

Commit

Permalink
WASM Bindings optimizations and fixes (#41808)
Browse files Browse the repository at this point in the history
* Fix MarshalTypedArrayByte and re-enable it. Re-enable TestFunctionApply

* Re-enable MarshalTypedArray

* Detect when the managed wrapper for a JS object has been collected and create a new one

* Remove debugging code

* Maintain a small pool of temporary root instances to minimize GC pressure. Improve benchmark

* Don't use release_roots in call_method due to varargs overhead

* Various call_method optimizations

* Checkpoint: Don't rely on finally block for teardown in call path, because it has a performance cost

* Checkpoint: Unboxing fast path for primitives

* Checkpoint: Fix unboxing fast path

* Update bindings to use bound static methods instead of call_method in various places

* Address PR feedback

* Revert sample and add separate proj for benchmark

* Fix benchmark

* Revert test change

* Fix passing mono object ptrs to bound functions
Fix passing strings across the boundary
Fix JS strings being truncated at the first null when passed to mono

* Implement unboxing for chars
Slightly optimize the unboxing slow path

* Don't allocate a root buffer for arguments if nothing needs to be rooted. Reuse scratch native buffer across calls unless re-entrant to avoid per-invoke malloc

* Fix whitespace damage from merge

* Tweaks to try and prevent boxing/gc

* Fix typo

* Add some tests

* Fix test failures

* Add more error handling and diagnostic messages
Fix a couple broken tests

* Repair merge damage

* Remove bindings benchmark

* Use TypedArray.fill 3-argument version to zero memory

* Checkpoint: Introduce format strings

* Fix interpolated strings

* Test refactoring

* Checkpoint: Add more test coverage for bindings and interop

* Checkpoint: Enum marshaling works

* Improve test coverage

* Checkpoint: Unify unboxing of primitive types

* Checkpoint: Unify unboxing of primitive types

* Checkpoint: Restore fn to satisfy runtime-test.js

* Checkpoint: Unify boxing for primitives

* Remove now-unused box methods

* Don't store names for null method IDs

* Fix indentation damage

* Add test

* Satisfy CI

* Accept weaker promises

Co-authored-by: Larry Ewing <[email protected]>
  • Loading branch information
kg and lewing authored Nov 11, 2020
1 parent a593f58 commit 85cb1df
Show file tree
Hide file tree
Showing 9 changed files with 1,355 additions and 388 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,16 @@ private static int BindJSObject(int jsId, bool ownsHandle, int mappedType)
WeakReference? reference;
lock (_boundObjects)
{
if (!_boundObjects.TryGetValue(jsId, out reference))
if (_boundObjects.TryGetValue(jsId, out reference))
{
if ((reference.Target == null) || ((reference.Target as JSObject)?.IsDisposed == true))
{
_boundObjects.Remove(jsId);
reference = null;
}
}

if (reference == null)
{
IntPtr jsIntPtr = (IntPtr)jsId;
reference = new WeakReference(mappedType > 0 ? BindJSType(jsIntPtr, ownsHandle, mappedType) : new JSObject(jsIntPtr, ownsHandle), true);
Expand Down Expand Up @@ -229,21 +238,6 @@ private static int GetJSObjectId(object rawObj)
js.GetWrappedObject() ?? h.Target : h.Target;
}

private static object BoxInt(int i)
{
return i;
}

private static object BoxDouble(double d)
{
return d;
}

private static object BoxBool(int b)
{
return b == 0 ? false : true;
}

private static bool IsSimpleArray(object a)
{
return a is System.Array arr && arr.Rank == 1 && arr.GetLowerBound(0) == 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ private static object InvokeMarshalObj()
return _marshalledObject;
}

private static object InvokeReturnMarshalObj()
{
return _marshalledObject;
}

internal static int _valOne, _valTwo;
private static void ManipulateObject(JSObject obj)
{
Expand Down Expand Up @@ -316,20 +321,26 @@ private static void CreateFunctionSum()
internal static int _sumValue = 0;
private static void CallFunctionSum()
{
if (_sumFunction == null)
throw new Exception("_sumFunction is null");
_sumValue = (int)_sumFunction.Call(null, 3, 5);
}

private static Function _mathMinFunction;
private static void CreateFunctionApply()
{
var math = (JSObject)Runtime.GetGlobalObject("Math");
if (math == null)
throw new Exception("Runtime.GetGlobalObject(Math) returned null");
_mathMinFunction = (Function)math.GetObjectProperty("min");

}

internal static int _minValue = 0;
private static void CallFunctionApply()
{
if (_mathMinFunction == null)
throw new Exception("_mathMinFunction is null");
_minValue = (int)_mathMinFunction.Apply(null, new object[] { 5, 6, 2, 3, 7 });
}

Expand All @@ -345,5 +356,32 @@ public static void SetBlobAsUri(Uri blobUri)
_blobURI = blobUri;
}

internal static uint _uintValue;
private static void InvokeUInt(uint value)
{
_uintValue = value;
}

internal static TestEnum _enumValue;
private static void SetEnumValue(TestEnum value)
{
_enumValue = value;
}
private static TestEnum GetEnumValue()
{
return _enumValue;
}

private static UInt64 GetUInt64()
{
return UInt64.MaxValue;
}
}

public enum TestEnum : uint {
FirstValue = 1,
Zero = 0,
Five = 5,
BigValue = 0xFFFFFFFEu
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,13 @@ public static void FunctionSum()
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/40112")]
public static void FunctionMath()
{
JSObject math = (JSObject)Runtime.GetGlobalObject("Math");
Assert.NotNull(math);
Assert.True(math != null, "math != null");

Function mathMax = (Function)math.GetObjectProperty("max");
Assert.NotNull(mathMax);
Assert.True(mathMax != null, "math.max != null");

var maxValue = (int)mathMax.Apply(null, new object[] { 5, 6, 2, 3, 7 });
Assert.Equal(7, maxValue);
Expand All @@ -108,7 +107,7 @@ public static void FunctionMath()
Assert.Equal(7, maxValue);

Function mathMin = (Function)((JSObject)Runtime.GetGlobalObject("Math")).GetObjectProperty("min");
Assert.NotNull(mathMin);
Assert.True(mathMin != null, "math.min != null");

var minValue = (int)mathMin.Apply(null, new object[] { 5, 6, 2, 3, 7 });
Assert.Equal(2, minValue);
Expand Down
Loading

0 comments on commit 85cb1df

Please sign in to comment.