JITDUMP("fgMorphTailCall (before):\n");
DISPTREE(call);
+ // The runtime requires that we perform a null check on the `this` argument before
+ // tail calling to a virtual dispatch stub. This requirement is a consequence of limitations
+ // in the runtime's ability to map an AV to a NullReferenceException if
+ // the AV occurs in a dispatch stub that has unmanaged caller.
+ if (call->IsVirtualStub())
+ {
+ call->gtFlags |= GTF_CALL_NULLCHECK;
+ }
+
#if defined(_TARGET_ARM_)
// For the helper-assisted tail calls, we need to push all the arguments
// into a single list, and then add a few extra at the beginning
}
#endif // _TARGET_X86_
-#if defined(_TARGET_X86_)
- // When targeting x86, the runtime requires that we perforrm a null check on the `this` argument before tail
- // calling to a virtual dispatch stub. This requirement is a consequence of limitations in the runtime's
- // ability to map an AV to a NullReferenceException if the AV occurs in a dispatch stub.
- if (call->NeedsNullCheck() || call->IsVirtualStub())
-#else
if (call->NeedsNullCheck())
-#endif // defined(_TARGET_X86_)
{
// clone "this" if "this" has no side effects.
if ((thisPtr == nullptr) && !(objp->gtFlags & GTF_SIDE_EFFECT))
call->gtCallMoreFlags |= GTF_CALL_M_VARARGS | GTF_CALL_M_TAILCALL | GTF_CALL_M_TAILCALL_VIA_HELPER;
call->gtFlags &= ~GTF_CALL_POP_ARGS;
-#endif // _TARGET_*
+#elif defined(_TARGET_ARM64_)
+ NYI_ARM64("Tail calls via stub are unsupported on this platform.");
+#endif // _TARGET_ARM64_
+
+ // The function is responsible for doing explicit null check when it is necessary.
+ assert(!call->NeedsNullCheck());
JITDUMP("fgMorphTailCall (after):\n");
DISPTREE(call);
// NYI - TAILCALL_RECURSIVE/TAILCALL_HELPER.
// So, bail out if we can't make fast tail call.
szFailReason = "Non-qualified fast tail call";
+
+ if (call->IsTailPrefixedCall())
+ {
+ NYI_ARM64("Arm64 does not support tail calls via helpers.");
+ }
}
#endif
#endif // LEGACY_BACKEND
WorkingDir=JIT\jit64\mcc\interop\mcc_i06
Expected=0
MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NATIVE_INTEROP
+Categories=EXPECTED_FAIL;6675;EXCLUDED;NATIVE_INTEROP
HostStyle=0
[mcc_i07.cmd_5191]
WorkingDir=JIT\jit64\mcc\interop\mcc_i16
Expected=0
MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS
+Categories=EXPECTED_FAIL;6675;EXCLUDED
HostStyle=0
[mcc_i17.cmd_5199]
WorkingDir=JIT\jit64\mcc\interop\mcc_i36
Expected=0
MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS
+Categories=EXPECTED_FAIL;6675;EXCLUDED
HostStyle=0
[mcc_i37.cmd_5207]
WorkingDir=JIT\jit64\mcc\interop\mcc_i56
Expected=0
MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS
+Categories=EXPECTED_FAIL;6675;EXCLUDED
HostStyle=0
[mcc_i57.cmd_5215]
WorkingDir=JIT\jit64\mcc\interop\mcc_i66
Expected=0
MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS
+Categories=EXPECTED_FAIL;6675;EXCLUDED
HostStyle=0
[mcc_i67.cmd_5223]
WorkingDir=JIT\jit64\mcc\interop\mcc_i76
Expected=0
MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS
+Categories=EXPECTED_FAIL;6675;EXCLUDED
HostStyle=0
[mcc_i77.cmd_5231]
WorkingDir=JIT\jit64\mcc\interop\mcc_i86
Expected=0
MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NATIVE_INTEROP
+Categories=EXPECTED_FAIL;6675;EXCLUDED;NATIVE_INTEROP
HostStyle=0
[mcc_i87.cmd_5239]
WorkingDir=JIT\Methodical\Invoke\25params\25param2c_il_d
Expected=0
MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS
+Categories=EXPECTED_FAIL;6675;EXCLUDED
HostStyle=0
[25param2c_il_r.cmd_7167]
WorkingDir=JIT\Methodical\Invoke\25params\25param2c_il_r
Expected=0
MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;Pri1
+Categories=EXPECTED_FAIL;6675;EXCLUDED;Pri1
HostStyle=0
[25param3a_cs_d.cmd_7168]
WorkingDir=CoreMangLib\system\span\SlowTailCallArgs
Expected=0
MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;Pri1;NEW
+Categories=EXPECTED_FAIL;6675;EXCLUDED;Pri1
HostStyle=0
[GitHub_13057.cmd_11966]
WorkingDir=JIT\Regression\JitBlue\GitHub_17585\GitHub_17585
Expected=0
MaxAllowedDurationSeconds=600
-Categories=EXPECTED_FAIL;17585;EXCLUDED
+Categories=EXPECTED_FAIL;6675;EXCLUDED
HostStyle=0