When we call ICastable.IsInstanceOfInterface, we treat RuntimeTypeHandle as a OBJECTREF, which is incorrect as-per x86 calling convention since RuntimeTypehandle is a struct that contains a RuntimeType ref field and needs to be passed in stack. Our VM simple call helpers CALL_MANAGED_METHOD doesn't handle this correctly (it does the simple thing that always assume all the arguments are passed in register first). I'm fixing this by using a static method that takes RuntimeType instead of RuntimeTypeHandle, then convert it to RuntimeTypehandle.
Also switch to use PREPARE_NONVIRTUAL_CALLSITE(METHODID) as per Jan's suggestion.
ICastable test is now enabled in x86 for both JITs.
<Member Name="IsInstanceOfInterface(System.RuntimeTypeHandle,System.Exception@)" /> <!-- EE -->
<Member Name="GetImplType(System.RuntimeTypeHandle)" /> <!-- EE -->
</Type>
+ <Type Name="System.Runtime.CompilerServices.ICastableHelpers">
+ <Member Name="IsInstanceOfInterface(System.Runtime.CompilerServices.ICastable,System.RuntimeType,System.Exception@)" /> <!-- EE -->
+ <Member Name="GetImplType(System.Runtime.CompilerServices.ICastable,System.RuntimeType)" /> <!-- EE -->
+ </Type>
<Type Name="System.Runtime.CompilerServices.IsExplicitlyDereferenced"> <!-- for MC++ -->
</Type>
<Type Name="System.Runtime.CompilerServices.IsImplicitlyDereferenced"> <!-- for MC++ -->
<Member Name="IsInstanceOfInterface(System.RuntimeTypeHandle,System.Exception@)" /> <!-- EE -->
<Member Name="GetImplType(System.RuntimeTypeHandle)" /> <!-- EE -->
</Type>
+ <Type Name="System.Runtime.CompilerServices.ICastableHelpers">
+ <Member Name="IsInstanceOfInterface(System.Runtime.CompilerServices.ICastable,System.RuntimeType, System.Exception@)" /> <!-- EE -->
+ <Member Name="GetImplType(System.Runtime.CompilerServices.ICastable,System.RuntimeType)" /> <!-- EE -->
+ </Type>
<Type Name="System.Runtime.CompilerServices.IsExplicitlyDereferenced"> <!-- for MC++ -->
</Type>
<Type Name="System.Runtime.CompilerServices.IsImplicitlyDereferenced"> <!-- for MC++ -->
// IsInstanceOfInterface.
RuntimeTypeHandle GetImplType(RuntimeTypeHandle interfaceType);
}
+
+ /// <summary>
+ /// Helpers that allows VM to call into ICastable methods without having to deal with RuntimeTypeHandle.
+ /// RuntimeTypeHandle is a struct and is always passed in stack in x86, which our VM call helpers don't
+ /// particularly like.
+ /// </summary>
+ class ICastableHelpers
+ {
+ internal static bool IsInstanceOfInterface(ICastable castable, RuntimeType type, out Exception castError)
+ {
+ return castable.IsInstanceOfInterface(new RuntimeTypeHandle(type), out castError);
+ }
+
+ internal static RuntimeType GetImplType(ICastable castable, RuntimeType interfaceType)
+ {
+ return castable.GetImplType(new RuntimeTypeHandle(interfaceType)).GetRuntimeType();
+ }
+ }
}
// to a given type.
else if (toTypeHnd.IsInterface() && fromTypeHnd.GetMethodTable()->IsICastable())
{
- // Make actuall call to obj.IsInstanceOfInterface(interfaceTypeObj, out exception)
+ // Make actuall call to ICastableHelpers.IsInstanceOfInterface(obj, interfaceTypeObj, out exception)
OBJECTREF exception = NULL;
GCPROTECT_BEGIN(exception);
- MethodTable *pFromTypeMT = fromTypeHnd.GetMethodTable();
- MethodDesc *pIsInstanceOfMD = pFromTypeMT->GetMethodDescForInterfaceMethod(MscorlibBinder::GetMethod(METHOD__ICASTABLE__ISINSTANCEOF)); //GC triggers
- OBJECTREF managedType = toTypeHnd.GetManagedClassObject(); //GC triggers
+
+ PREPARE_NONVIRTUAL_CALLSITE(METHOD__ICASTABLEHELPERS__ISINSTANCEOF);
- PREPARE_NONVIRTUAL_CALLSITE_USING_METHODDESC(pIsInstanceOfMD);
+ OBJECTREF managedType = toTypeHnd.GetManagedClassObject(); //GC triggers
DECLARE_ARGHOLDER_ARRAY(args, 3);
args[ARGNUM_0] = OBJECTREF_TO_ARGHOLDER(obj);
DEFINE_METASIG_T(SM(RefCleanupWorkList_RetVoid, r(C(CLEANUP_WORK_LIST)), v))
DEFINE_METASIG_T(SM(RefCleanupWorkList_SafeHandle_RetIntPtr, r(C(CLEANUP_WORK_LIST)) C(SAFE_HANDLE), I))
-DEFINE_METASIG_T(IM(RuntimeTypeHandle_RefException_RetBool, g(RT_TYPE_HANDLE) r(C(EXCEPTION)), F))
-DEFINE_METASIG_T(IM(RuntimeTypeHandle_RetRuntimeTypeHandle, g(RT_TYPE_HANDLE), g(RT_TYPE_HANDLE)))
+DEFINE_METASIG_T(SM(ICastable_RtType_RefException_RetBool, C(ICASTABLE) C(CLASS) r(C(EXCEPTION)), F))
+DEFINE_METASIG_T(SM(ICastable_RtType_RetRtType, C(ICASTABLE) C(CLASS), C(CLASS)))
DEFINE_METASIG_T(IM(ArrByte_Int_Int_AsyncCallback_Object_RetIAsyncResult, a(b) i i C(ASYNCCALLBACK) j, C(IASYNCRESULT)))
DEFINE_METASIG_T(IM(IAsyncResult_RetInt, C(IASYNCRESULT), i))
{
GCStress<cfg_any>::MaybeTrigger();
- // Make call to obj.GetImplType(interfaceTypeObj)
- MethodDesc *pGetImplTypeMD = pServerMT->GetMethodDescForInterfaceMethod(MscorlibBinder::GetMethod(METHOD__ICASTABLE__GETIMPLTYPE));
- OBJECTREF ownerManagedType = ownerType.GetManagedClassObject(); //GC triggers
+ // Make call to ICastableHelpers.GetImplType(obj, interfaceTypeObj)
+ PREPARE_NONVIRTUAL_CALLSITE(METHOD__ICASTABLEHELPERS__GETIMPLTYPE);
- PREPARE_NONVIRTUAL_CALLSITE_USING_METHODDESC(pGetImplTypeMD);
+ OBJECTREF ownerManagedType = ownerType.GetManagedClassObject(); //GC triggers
DECLARE_ARGHOLDER_ARRAY(args, 2);
args[ARGNUM_0] = OBJECTREF_TO_ARGHOLDER(*pServer);
#ifdef FEATURE_ICASTABLE
DEFINE_CLASS(ICASTABLE, CompilerServices, ICastable)
-DEFINE_METHOD(ICASTABLE, ISINSTANCEOF, IsInstanceOfInterface, IM_RuntimeTypeHandle_RefException_RetBool)
-DEFINE_METHOD(ICASTABLE, GETIMPLTYPE, GetImplType, IM_RuntimeTypeHandle_RetRuntimeTypeHandle)
+
+DEFINE_CLASS(ICASTABLEHELPERS, CompilerServices, ICastableHelpers)
+DEFINE_METHOD(ICASTABLEHELPERS, ISINSTANCEOF, IsInstanceOfInterface, SM_ICastable_RtType_RefException_RetBool)
+DEFINE_METHOD(ICASTABLEHELPERS, GETIMPLTYPE, GetImplType, SM_ICastable_RtType_RetRtType)
+
#endif // FEATURE_ICASTABLE
DEFINE_CLASS(CUTF8MARSHALER, StubHelpers, UTF8Marshaler)
// It allows objects that implement ICastable to mimic behavior of other types.
MethodTable * pTokenMT = GetTypeFromToken(token);
- // Make call to obj.GetImplType(interfaceTypeObj)
- MethodDesc *pGetImplTypeMD = pMT->GetMethodDescForInterfaceMethod(MscorlibBinder::GetMethod(METHOD__ICASTABLE__GETIMPLTYPE));
- OBJECTREF tokenManagedType = pTokenMT->GetManagedClassObject(); //GC triggers
-
- PREPARE_NONVIRTUAL_CALLSITE_USING_METHODDESC(pGetImplTypeMD);
+ // Make call to ICastableHelpers.GetImplType(this, interfaceTypeObj)
+ PREPARE_NONVIRTUAL_CALLSITE(METHOD__ICASTABLEHELPERS__GETIMPLTYPE);
+ OBJECTREF tokenManagedType = pTokenMT->GetManagedClassObject(); //GC triggers
+
DECLARE_ARGHOLDER_ARRAY(args, 2);
args[ARGNUM_0] = OBJECTREF_TO_ARGHOLDER(*protectedObj);
args[ARGNUM_1] = OBJECTREF_TO_ARGHOLDER(tokenManagedType);
<ExcludeList Include="$(XunitTestBinBase)\GC\LargeMemory\API\gc\suppressfinalize\suppressfinalize.cmd">
<Issue>3392</Issue>
</ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)\Interop\ICastable\Castable\Castable.cmd">
- <Issue>needs triage</Issue>
- </ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)\JIT\Methodical\divrem\div\u8div_cs_do\u8div_cs_do.cmd">
<Issue>needs triage</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)\Interop\MarshalAPI\Copy\CopySingleArray\CopySingleArray.cmd" >
<Issue>4179</Issue>
</ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)\Interop\ICastable\Castable\Castable.cmd" >
- <Issue>4179</Issue>
- </ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)\Interop\MarshalAPI\OffsetOf\OffsetOf\OffsetOf.cmd" >
<Issue>4179</Issue>
</ExcludeList>
<Project DefaultTargets = "GetListOfTestCmds"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >
<ItemGroup Condition="'$(XunitTestBinBase)' != ''">
- <ExcludeList Include="$(XunitTestBinBase)\Interop\ICastable\Castable\Castable.cmd" >
- <Issue> Assert failure(PID 4872 [0x00001308], Thread: 13744 [0x35b0]): Consistency check failed: AV in clr at this callstack:</Issue>
- </ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)\JIT\opt\Inline\regression\mismatch64\mismatch64\mismatch64.cmd" >
<Issue>'Arg type mismatch: Wanted long (size 8), Got struct (size 4) for call at IL offset 0x16'</Issue>
</ExcludeList>
<Issue>needs triage</Issue>
</ExcludeList>
</ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
<ExcludeList Include="$(XunitTestBinBase)\JIT\Directed\rvastatics\rvastatic1\rvastatic1.cmd">
<Issue>needs triage</Issue>
</ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)\Interop\ICastable\Castable\Castable.cmd">
- <Issue>needs triage</Issue>
- </ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)\JIT\Methodical\Boxing\xlang\_odbgsin_il_cs\_odbgsin_il_cs.cmd">
<Issue>needs triage</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)\JIT\Methodical\tailcall\_il_dbgtest_implicit\_il_dbgtest_implicit.cmd">
<Issue>needs triage</Issue>
</ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)\Interop\ICastable\Castable\Castable.cmd Timed Out">
- <Issue>needs triage</Issue>
- </ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)\JIT\Directed\rvastatics\rvastatic3\rvastatic3.cmd">
<Issue>needs triage</Issue>
</ExcludeList>