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

[mono] Remove some of the restrictions on constrained calls from #59182

Merged
merged 2 commits into from
Sep 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,6 @@ public class SuffixNamingPolicy : JsonNamingPolicy
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/58204", TestPlatforms.iOS | TestPlatforms.tvOS)]
public static void RoundtripAllDictionaryConverters()
{
const string Expected = @"{""1"":1}";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ public void DeserializeBoolean_EmptyString()
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/58204", TestPlatforms.iOS | TestPlatforms.tvOS)]
public void IncompleteContainers()
{
JsonException e = Assert.Throws<JsonException>(() => JsonSerializer.Deserialize<IList<object>>("[1,"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,6 @@ public static void PropertyCacheWithMinInputsLast()

[Theory]
[MemberData(nameof(WriteSuccessCases))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/58204", TestPlatforms.iOS | TestPlatforms.tvOS)]
public static async Task MultipleTypes(ITestClass testObj)
{
Type type = testObj.GetType();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

namespace System.Text.Json.Serialization.Tests
{
[ActiveIssue("https://github.com/dotnet/runtime/issues/58204", TestPlatforms.iOS | TestPlatforms.tvOS)]
public sealed partial class CollectionTestsDynamic : CollectionTests
{
public CollectionTestsDynamic() : base(JsonSerializerWrapperForString.StringSerializer, JsonSerializerWrapperForStream.AsyncStreamSerializer) { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ namespace System.Text.Json.Serialization.Tests
public static partial class NullableTests
{
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/58204", TestPlatforms.iOS | TestPlatforms.tvOS)]
public static void DictionaryWithNullableValue()
{
Dictionary<string, float?> dictWithFloatValue = new Dictionary<string, float?> { { "key", 42.0f } };
Expand Down Expand Up @@ -171,7 +170,6 @@ public class SimpleClassWithDictionariesWithNullableValues
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/58204", TestPlatforms.iOS | TestPlatforms.tvOS)]
public static void ClassWithDictionariesWithNullableValues()
{
string json =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,6 @@ public class Class_With_ListsOfBoxedNonNumbers

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/49936", TestPlatforms.Android)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/58204", TestPlatforms.iOS | TestPlatforms.tvOS)]
public static void Number_AsCollectionElement_RoundTrip()
{
RunAsCollectionElementTest(JsonNumberTestData.Bytes);
Expand Down Expand Up @@ -604,7 +603,6 @@ private static void AssertDictionaryElements_StringValues(string serialized)
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/39674", typeof(PlatformDetection), nameof(PlatformDetection.IsMonoInterpreter))]
[SkipOnCoreClr("https://github.com/dotnet/runtime/issues/45464", RuntimeConfiguration.Checked)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/58204", TestPlatforms.iOS | TestPlatforms.tvOS)]
public static void DictionariesRoundTrip()
{
RunAllDictionariessRoundTripTest(JsonNumberTestData.ULongs);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,6 @@ private ConcreteDerivedClassWithNoPublicDefaultCtor(string error)
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/58204", TestPlatforms.iOS | TestPlatforms.tvOS)]
public static void ReadClassWithStringToPrimitiveDictionary()
{
TestClassWithStringToPrimitiveDictionary obj = JsonSerializer.Deserialize<TestClassWithStringToPrimitiveDictionary>(TestClassWithStringToPrimitiveDictionary.s_data);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ public static void VerifyTypeFail()

[Theory]
[MemberData(nameof(WriteSuccessCases))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/58204", TestPlatforms.iOS | TestPlatforms.tvOS)]
public static void Write(ITestClass testObj)
{
var options = new JsonSerializerOptions { IncludeFields = true };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,6 @@ public static void ReadSimpleStruct()
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/58204", TestPlatforms.iOS | TestPlatforms.tvOS)]
public static void ReadClasses()
{
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1240,7 +1240,6 @@ public static void ReferenceObjectBeforePreservedObject()

[Theory]
[MemberData(nameof(ReadSuccessCases))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/58204", TestPlatforms.iOS | TestPlatforms.tvOS)]
public static void ReadTestClassesWithExtensionOption(Type classType, byte[] data)
{
var options = new JsonSerializerOptions { IncludeFields = true, ReferenceHandler = ReferenceHandler.Preserve };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ public static void ParseNullTypeFail()

[Theory]
[MemberData(nameof(ReadSuccessCases))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/58204", TestPlatforms.iOS | TestPlatforms.tvOS)]
public static void Read(Type classType, byte[] data)
{
var options = new JsonSerializerOptions { IncludeFields = true };
Expand All @@ -28,7 +27,6 @@ public static void Read(Type classType, byte[] data)

[Theory]
[MemberData(nameof(ReadSuccessCases))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/58204", TestPlatforms.iOS | TestPlatforms.tvOS)]
public static void ReadFromStream(Type classType, byte[] data)
{
MemoryStream stream = new MemoryStream(data);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ public partial class StreamTests
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/35927", typeof(PlatformDetection), nameof(PlatformDetection.IsMonoInterpreter))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/35927", TestPlatforms.Browser)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/58204", TestPlatforms.iOS | TestPlatforms.tvOS)]
public async Task HandleCollectionsAsync()
{
await RunTestAsync<string>();
Expand Down
24 changes: 14 additions & 10 deletions src/mono/mono/mini/gshared.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1472,15 +1472,16 @@ public static int test_0_nullable_unbox () {

interface IConstrained {
void foo ();
void foo_ref_arg (string s);
void foo_ref_arg (string s, string s2);
}

interface IConstrained<T3> {
void foo_gsharedvt_arg (T3 s);
void foo_gsharedvt_arg (T3 s, T3 s2);
T3 foo_gsharedvt_ret (T3 s);
}

static object constrained_res;
static object constrained_res2;

struct ConsStruct : IConstrained {
public int i;
Expand All @@ -1489,8 +1490,8 @@ public void foo () {
constrained_res = i;
}

public void foo_ref_arg (string s) {
constrained_res = s == "A" ? 42 : 0;
public void foo_ref_arg (string s, string s2) {
constrained_res = (s == "A" && s2 == "B") ? 42 : 0;
}
}

Expand All @@ -1501,14 +1502,15 @@ public void foo () {
constrained_res = i;
}

public void foo_ref_arg (string s) {
constrained_res = s == "A" ? 43 : 0;
public void foo_ref_arg (string s, string s2) {
constrained_res = (s == "A" && s2 == "B") ? 43 : 0;
}
}

struct ConsStruct<T> : IConstrained<T> {
public void foo_gsharedvt_arg (T s) {
public void foo_gsharedvt_arg (T s, T s2) {
constrained_res = s;
constrained_res2 = s2;
}

public T foo_gsharedvt_ret (T s) {
Expand All @@ -1521,7 +1523,7 @@ public void foo () {
throw new Exception ();
}

public void foo_ref_arg (string s) {
public void foo_ref_arg (string s, string s2) {
}
}

Expand All @@ -1541,12 +1543,12 @@ public void constrained_void_iface_call<T, T2>(T t, T2 t2) where T2 : IConstrain

[MethodImplAttribute (MethodImplOptions.NoInlining)]
public void constrained_void_iface_call_ref_arg<T, T2>(T t, T2 t2) where T2 : IConstrained {
t2.foo_ref_arg ("A");
t2.foo_ref_arg ("A", "B");
}

[MethodImplAttribute (MethodImplOptions.NoInlining)]
public void constrained_void_iface_call_gsharedvt_arg<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T> {
t2.foo_gsharedvt_arg (t);
t2.foo_gsharedvt_arg (t, t);
}

[MethodImplAttribute (MethodImplOptions.NoInlining)]
Expand Down Expand Up @@ -1616,6 +1618,8 @@ public static int test_0_constrained_void_iface_call_gsharedvt_arg () {
c.constrained_void_iface_call_gsharedvt_arg<string, ConsStruct<string>, int> ("A", s2, 55);
if (!(constrained_res is string) || ((string)constrained_res) != "A")
return 2;
if (!(constrained_res2 is string) || ((string)constrained_res2) != "A")
return 3;

return 0;
}
Expand Down
13 changes: 10 additions & 3 deletions src/mono/mono/mini/jit-icalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -1396,7 +1396,7 @@ constrained_gsharedvt_call_setup (gpointer mp, MonoMethod *cmethod, MonoClass *k
* the arguments to the method in the format used by mono_runtime_invoke_checked ().
*/
MonoObject*
mono_gsharedvt_constrained_call (gpointer mp, MonoMethod *cmethod, MonoClass *klass, gboolean deref_arg, gpointer *args)
mono_gsharedvt_constrained_call (gpointer mp, MonoMethod *cmethod, MonoClass *klass, guint8 *deref_args, gpointer *args)
{
ERROR_DECL (error);
MonoObject *o;
Expand Down Expand Up @@ -1424,8 +1424,15 @@ mono_gsharedvt_constrained_call (gpointer mp, MonoMethod *cmethod, MonoClass *kl

if (!m)
return NULL;
if (args && deref_arg) {
new_args [0] = *(gpointer*)args [0];
if (deref_args) {
/* Have to deref gsharedvt ref arguments since the runtime invoke expects it */
MonoMethodSignature *fsig = mono_method_signature_internal (m);
g_assert (fsig->param_count < 16);
memcpy (new_args, args, fsig->param_count * sizeof (gpointer));
for (int i = 0; i < fsig->param_count; ++i) {
if (deref_args [i])
new_args [i] = *(gpointer*)new_args [i];
}
args = new_args;
}
if (m->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
Expand Down
2 changes: 1 addition & 1 deletion src/mono/mono/mini/jit-icalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ ICALL_EXPORT
void
ves_icall_mono_delegate_ctor_interp (MonoObject *this_obj, MonoObject *target, gpointer addr);

ICALL_EXPORT MonoObject* mono_gsharedvt_constrained_call (gpointer mp, MonoMethod *cmethod, MonoClass *klass, gboolean deref_arg, gpointer *args);
ICALL_EXPORT MonoObject* mono_gsharedvt_constrained_call (gpointer mp, MonoMethod *cmethod, MonoClass *klass, guint8 *deref_args, gpointer *args);

ICALL_EXPORT void mono_gsharedvt_value_copy (gpointer dest, gpointer src, MonoClass *klass);

Expand Down
52 changes: 32 additions & 20 deletions src/mono/mono/mini/method-to-ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -3676,13 +3676,10 @@ handle_constrained_gsharedvt_call (MonoCompile *cfg, MonoMethod *cmethod, MonoMe
if (fsig->param_count == 0 || (!fsig->hasthis && fsig->param_count == 1)) {
supported = TRUE;
} else {
/* Allow scalar parameters and a gsharedvt first parameter */
supported = MONO_TYPE_IS_PRIMITIVE (fsig->params [0]) || MONO_TYPE_IS_REFERENCE (fsig->params [0]) || fsig->params [0]->byref || mini_is_gsharedvt_type (fsig->params [0]);
if (supported) {
for (int i = 1; i < fsig->param_count; ++i) {
if (!(fsig->params [i]->byref || MONO_TYPE_IS_PRIMITIVE (fsig->params [i]) || MONO_TYPE_IS_REFERENCE (fsig->params [i]) || MONO_TYPE_ISSTRUCT (fsig->params [i])))
supported = FALSE;
}
supported = TRUE;
for (int i = 0; i < fsig->param_count; ++i) {
if (!(fsig->params [i]->byref || MONO_TYPE_IS_PRIMITIVE (fsig->params [i]) || MONO_TYPE_IS_REFERENCE (fsig->params [i]) || MONO_TYPE_ISSTRUCT (fsig->params [i]) || mini_is_gsharedvt_type (fsig->params [i])))
supported = FALSE;
}
}
}
Expand All @@ -3703,29 +3700,44 @@ handle_constrained_gsharedvt_call (MonoCompile *cfg, MonoMethod *cmethod, MonoMe

/* !fsig->hasthis is for the wrapper for the Object.GetType () icall */
if (fsig->hasthis && fsig->param_count) {
/* Call mono_gsharedvt_constrained_call (gpointer mp, MonoMethod *cmethod, MonoClass *klass, gboolean deref_arg, gpointer *args) */
/* Call mono_gsharedvt_constrained_call (gpointer mp, MonoMethod *cmethod, MonoClass *klass, gboolean *deref_args, gpointer *args) */
gboolean has_gsharedvt = FALSE;
for (int i = 0; i < fsig->param_count; ++i) {
if (mini_is_gsharedvt_type (fsig->params [i]))
has_gsharedvt = TRUE;
}
/* Pass an array of bools which signal whenever the corresponding argument is a gsharedvt ref type */
if (has_gsharedvt) {
MONO_INST_NEW (cfg, ins, OP_LOCALLOC_IMM);
ins->dreg = alloc_preg (cfg);
ins->inst_imm = fsig->param_count;
MONO_ADD_INS (cfg->cbb, ins);
args [3] = ins;
} else {
EMIT_NEW_PCONST (cfg, args [3], 0);
}
/* Pass the arguments using a localloc-ed array using the format expected by runtime_invoke () */
MONO_INST_NEW (cfg, ins, OP_LOCALLOC_IMM);
ins->dreg = alloc_preg (cfg);
ins->inst_imm = fsig->param_count * sizeof (target_mgreg_t);
MONO_ADD_INS (cfg->cbb, ins);
args [4] = ins;

/* Only the first argument is allowed to be gsharedvt */
/* args [3] = deref_arg */
if (mini_is_gsharedvt_type (fsig->params [0])) {
int deref_arg_reg;
ins = mini_emit_get_gsharedvt_info_klass (cfg, mono_class_from_mono_type_internal (fsig->params [0]), MONO_RGCTX_INFO_CLASS_BOX_TYPE);
deref_arg_reg = alloc_preg (cfg);
/* deref_arg = BOX_TYPE != MONO_GSHAREDVT_BOX_TYPE_VTYPE */
EMIT_NEW_BIALU_IMM (cfg, args [3], OP_ISUB_IMM, deref_arg_reg, ins->dreg, 1);
} else {
EMIT_NEW_ICONST (cfg, args [3], 0);
}

for (int i = 0; i < fsig->param_count; ++i) {
int addr_reg;

if (mini_is_gsharedvt_type (fsig->params [i])) {
MonoInst *is_deref;
int deref_arg_reg;
ins = mini_emit_get_gsharedvt_info_klass (cfg, mono_class_from_mono_type_internal (fsig->params [i]), MONO_RGCTX_INFO_CLASS_BOX_TYPE);
deref_arg_reg = alloc_preg (cfg);
/* deref_arg = BOX_TYPE != MONO_GSHAREDVT_BOX_TYPE_VTYPE */
EMIT_NEW_BIALU_IMM (cfg, is_deref, OP_ISUB_IMM, deref_arg_reg, ins->dreg, 1);
MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI1_MEMBASE_REG, args [3]->dreg, i, is_deref->dreg);
} else if (has_gsharedvt) {
MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STOREI1_MEMBASE_IMM, args [3]->dreg, i, 0);
}

if (mini_is_gsharedvt_type (fsig->params [i]) || MONO_TYPE_IS_PRIMITIVE (fsig->params [i]) || MONO_TYPE_ISSTRUCT (fsig->params [i])) {
EMIT_NEW_VARLOADA_VREG (cfg, ins, sp [i + 1]->dreg, fsig->params [i]);
addr_reg = ins->dreg;
Expand Down