Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Wrighton <davidwr@microsoft.com>2021-06-11 03:43:26 +0300
committerGitHub <noreply@github.com>2021-06-11 03:43:26 +0300
commitd07f9111c57fab97aa135bebb2687471a8bfc5bf (patch)
treeb6d42fb3e6f570e7966be934cbe72c90368ac65d /src/coreclr/inc
parente4751aee57c1089cf5aba40256a0d7b5461f691c (diff)
Enable devirtualization in more scenarios on crossgen2 (#53567)
Address deficiencies in current devirtualization infrastructure - Remove the responsibility of creating a CORINFO_RESOLVED_TOKEN structure from the JIT and make it a responsibility of the VM side of the jit interface. - This enables the component (crossgen2) which has deeper understanding of the requirements here to correctly handle scenarios that would otherwise require expressing crossgen2 specific details across the jit interface. - Add a new set of fixups (`READYTORUN_FIXUP_Check_VirtualFunctionOverride` and `READYTORUN_FIXUP_Verify_VirtualFunctionOverride`) these are used to validate that the behavior of the runtime and crossgen2 compiler is equivalent for a virtual resolution event - `READYTORUN_FIXUP_Check_VirtualFunctionOverride` will ensure that the virtual resolution decision is the same at crossgen2 time and runtime, and if the decision differs, any generated code affected by the decision will not be used. - `READYTORUN_FIXUP_Verify_VirtualFunctionOverride` will perform the same checks as `READYTORUN_FIXUP_Check_VirtualFunctionOverride`, but if it fails the check, the process will be terminated with a fail-fast. It is intended for use under the `--verify-type-and-field-layout` stress mode. - Currently only the `READYTORUN_FIXUP_Verify_VirtualFunctionOverride` is actually generated, and it is only generated when using the `--verify-type-and-field-layout` switch to crossgen2. Future work will identify if there are scenarios where we need to generate the `READYTORUN_FIXUP_Check_VirtualFunctionOverride` flag. One area of possible concern is around covariant returns, another is around handling of type equivalence. - In order to express the fixup signature for the VirtualFunctionOverride fixups, a new flag has been added to `ReadyToRunMethodSigFlags`. `READYTORUN_METHOD_SIG_UpdateContext` will allow the method signature to internally specify the assembly which is associated with the method token, instead of relying on the ambient context. - R2RDump and the ReadyToRun format documentation have been updated with the details of the new fixups/flags. - Update the rules for handling unboxing stubs - See #51918 for details. This adds a new test, as well as proper handling for unboxing stubs to match the JIT behavior - Also revert #52605, which avoided the problem by simply disabling devirtualization in the presence of structs - Adjust the rules for when it is legal to devirtualize and maintain version resiliency - The VersionsWithCode and VersionsWithType rules are unnecessarily restrictive. - Instead Validate that the metadata is safely checkable, and rely on the canInline logic to ensure that no IL that can't be handled is inlined. - This also involved adding a check that the chain of types from the implementation type to the declaration method table type is within the version bubble. - And changing the `VersionsWithType` check on the implementation type, to a new `VersionsWithTypeReference` check which can be used to validate that the type can be referred to, in combination with using `VersionsWithType` on the type definition. - By adjusting the way that the declMethod is referred to, it becomes possible to use the declMethod without checking the full method is `VersionsWithCode`, and it just needs a relationship to version matching code. - In `resolveVirtualMethod` generate the `CORINFO_RESOLVED_TOKEN` structures for the jit - In particular we are now able to resolve to methods where the decl method is the resolution result but is not within the version bubble itself. This can happen if we can prove that the decl method is the only method which can possibly implement a virtual. - Add support for devirtualization reasons to crossgen2 - Port all devirtualization abort conditions to crossgen2 from runtime that were not already present - Fix devirtualization from a canonical virtual method when the actual implementation is more exact - Fix variant interface override scenario where there is an interface that requires implementation of the variant interface as well as the variant interface itself.
Diffstat (limited to 'src/coreclr/inc')
-rw-r--r--src/coreclr/inc/corcompile.h4
-rw-r--r--src/coreclr/inc/corinfo.h35
-rw-r--r--src/coreclr/inc/jiteeversionguid.h10
-rw-r--r--src/coreclr/inc/readytorun.h12
4 files changed, 43 insertions, 18 deletions
diff --git a/src/coreclr/inc/corcompile.h b/src/coreclr/inc/corcompile.h
index 2fb5d6fabc7..283124c15b9 100644
--- a/src/coreclr/inc/corcompile.h
+++ b/src/coreclr/inc/corcompile.h
@@ -702,6 +702,9 @@ enum CORCOMPILE_FIXUP_BLOB_KIND
ENCODE_VERIFY_FIELD_OFFSET, /* Used for the R2R compiler can generate a check against the real field offset used at runtime */
ENCODE_VERIFY_TYPE_LAYOUT, /* Used for the R2R compiler can generate a check against the real type layout used at runtime */
+ ENCODE_CHECK_VIRTUAL_FUNCTION_OVERRIDE, /* Generate a runtime check to ensure that virtual function resolution has equivalent behavior at runtime as at compile time. If not equivalent, code will not be used */
+ ENCODE_VERIFY_VIRTUAL_FUNCTION_OVERRIDE, /* Generate a runtime check to ensure that virtual function resolution has equivalent behavior at runtime as at compile time. If not equivalent, generate runtime failure. */
+
ENCODE_MODULE_HANDLE = 0x50, /* Module token */
ENCODE_STATIC_FIELD_ADDRESS, /* For accessing a static field */
ENCODE_MODULE_ID_FOR_STATICS, /* For accessing static fields */
@@ -724,6 +727,7 @@ enum EncodeMethodSigFlags
ENCODE_METHOD_SIG_MemberRefToken = 0x10,
ENCODE_METHOD_SIG_Constrained = 0x20,
ENCODE_METHOD_SIG_OwnerType = 0x40,
+ ENCODE_METHOD_SIG_UpdateContext = 0x80,
};
enum EncodeFieldSigFlags
diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h
index c2fde45f84f..abf5527d001 100644
--- a/src/coreclr/inc/corinfo.h
+++ b/src/coreclr/inc/corinfo.h
@@ -1604,18 +1604,24 @@ struct CORINFO_CALL_INFO
enum CORINFO_DEVIRTUALIZATION_DETAIL
{
- CORINFO_DEVIRTUALIZATION_UNKNOWN, // no details available
- CORINFO_DEVIRTUALIZATION_SUCCESS, // devirtualization was successful
- CORINFO_DEVIRTUALIZATION_FAILED_CANON, // object class was canonical
- CORINFO_DEVIRTUALIZATION_FAILED_COM, // object class was com
- CORINFO_DEVIRTUALIZATION_FAILED_CAST, // object class could not be cast to interface class
- CORINFO_DEVIRTUALIZATION_FAILED_LOOKUP, // interface method could not be found
- CORINFO_DEVIRTUALIZATION_FAILED_DIM, // interface method was default interface method
- CORINFO_DEVIRTUALIZATION_FAILED_SUBCLASS, // object not subclass of base class
- CORINFO_DEVIRTUALIZATION_FAILED_SLOT, // virtual method installed via explicit override
- CORINFO_DEVIRTUALIZATION_FAILED_BUBBLE, // devirtualization crossed version bubble
- CORINFO_DEVIRTUALIZATION_MULTIPLE_IMPL, // object has multiple implementations of interface class
- CORINFO_DEVIRTUALIZATION_COUNT, // sentinel for maximum value
+ CORINFO_DEVIRTUALIZATION_UNKNOWN, // no details available
+ CORINFO_DEVIRTUALIZATION_SUCCESS, // devirtualization was successful
+ CORINFO_DEVIRTUALIZATION_FAILED_CANON, // object class was canonical
+ CORINFO_DEVIRTUALIZATION_FAILED_COM, // object class was com
+ CORINFO_DEVIRTUALIZATION_FAILED_CAST, // object class could not be cast to interface class
+ CORINFO_DEVIRTUALIZATION_FAILED_LOOKUP, // interface method could not be found
+ CORINFO_DEVIRTUALIZATION_FAILED_DIM, // interface method was default interface method
+ CORINFO_DEVIRTUALIZATION_FAILED_SUBCLASS, // object not subclass of base class
+ CORINFO_DEVIRTUALIZATION_FAILED_SLOT, // virtual method installed via explicit override
+ CORINFO_DEVIRTUALIZATION_FAILED_BUBBLE, // devirtualization crossed version bubble
+ CORINFO_DEVIRTUALIZATION_MULTIPLE_IMPL, // object has multiple implementations of interface class
+ CORINFO_DEVIRTUALIZATION_FAILED_BUBBLE_CLASS_DECL, // decl method is defined on class and decl method not in version bubble, and decl method not in closest to version bubble
+ CORINFO_DEVIRTUALIZATION_FAILED_BUBBLE_INTERFACE_DECL, // decl method is defined on interface and not in version bubble, and implementation type not entirely defined in bubble
+ CORINFO_DEVIRTUALIZATION_FAILED_BUBBLE_IMPL, // object class not defined within version bubble
+ CORINFO_DEVIRTUALIZATION_FAILED_BUBBLE_IMPL_NOT_REFERENCEABLE, // object class cannot be referenced from R2R code due to missing tokens
+ CORINFO_DEVIRTUALIZATION_FAILED_DUPLICATE_INTERFACE, // crossgen2 virtual method algorithm and runtime algorithm differ in the presence of duplicate interface implementations
+ CORINFO_DEVIRTUALIZATION_FAILED_DECL_NOT_REPRESENTABLE, // Decl method cannot be represented in R2R image
+ CORINFO_DEVIRTUALIZATION_COUNT, // sentinel for maximum value
};
struct CORINFO_DEVIRTUALIZATION_INFO
@@ -1626,6 +1632,7 @@ struct CORINFO_DEVIRTUALIZATION_INFO
CORINFO_METHOD_HANDLE virtualMethod;
CORINFO_CLASS_HANDLE objClass;
CORINFO_CONTEXT_HANDLE context;
+ CORINFO_RESOLVED_TOKEN *pResolvedTokenVirtualMethod;
//
// [Out] results of resolveVirtualMethod.
@@ -1634,11 +1641,15 @@ struct CORINFO_DEVIRTUALIZATION_INFO
// - requiresInstMethodTableArg is set to TRUE if the devirtualized method requires a type handle arg.
// - exactContext is set to wrapped CORINFO_CLASS_HANDLE of devirt'ed method table.
// - details on the computation done by the jit host
+ // - If pResolvedTokenDevirtualizedMethod is not set to NULL and targetting an R2R image
+ // use it as the parameter to getCallInfo
//
CORINFO_METHOD_HANDLE devirtualizedMethod;
bool requiresInstMethodTableArg;
CORINFO_CONTEXT_HANDLE exactContext;
CORINFO_DEVIRTUALIZATION_DETAIL detail;
+ CORINFO_RESOLVED_TOKEN resolvedTokenDevirtualizedMethod;
+ CORINFO_RESOLVED_TOKEN resolvedTokenDevirtualizedUnboxedMethod;
};
//----------------------------------------------------------------------------
diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h
index 25746b45992..225c73008bb 100644
--- a/src/coreclr/inc/jiteeversionguid.h
+++ b/src/coreclr/inc/jiteeversionguid.h
@@ -43,11 +43,11 @@ typedef const GUID *LPCGUID;
#define GUID_DEFINED
#endif // !GUID_DEFINED
-constexpr GUID JITEEVersionIdentifier = { /* 1052f490-cad7-4610-99bb-6f2bd91a1d19 */
- 0x1052f490,
- 0xcad7,
- 0x4610,
- {0x99, 0xbb, 0x6f, 0x2b, 0xd9, 0x1a, 0x1d, 0x19}
+constexpr GUID JITEEVersionIdentifier = { /* de9a9a0e-c66a-4d97-a268-92a31f99d919 */
+ 0xde9a9a0e,
+ 0xc66a,
+ 0x4d97,
+ {0xa2, 0x68, 0x92, 0xa3, 0x1f, 0x99, 0xd9, 0x19}
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/coreclr/inc/readytorun.h b/src/coreclr/inc/readytorun.h
index f35d80c37d1..7d43b403894 100644
--- a/src/coreclr/inc/readytorun.h
+++ b/src/coreclr/inc/readytorun.h
@@ -16,7 +16,7 @@
// Keep these in sync with src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs
#define READYTORUN_MAJOR_VERSION 0x0005
-#define READYTORUN_MINOR_VERSION 0x0003
+#define READYTORUN_MINOR_VERSION 0x0004
#define MINIMUM_READYTORUN_MAJOR_VERSION 0x003
@@ -134,6 +134,7 @@ enum ReadyToRunMethodSigFlags
READYTORUN_METHOD_SIG_MemberRefToken = 0x10,
READYTORUN_METHOD_SIG_Constrained = 0x20,
READYTORUN_METHOD_SIG_OwnerType = 0x40,
+ READYTORUN_METHOD_SIG_UpdateContext = 0x80,
};
enum ReadyToRunFieldSigFlags
@@ -152,6 +153,12 @@ enum ReadyToRunTypeLayoutFlags
READYTORUN_LAYOUT_GCLayout_Empty = 0x10,
};
+enum ReadyToRunVirtualFunctionOverrideFlags
+{
+ READYTORUN_VIRTUAL_OVERRIDE_None = 0x00,
+ READYTORUN_VIRTUAL_OVERRIDE_VirtualFunctionOverriden = 0x01,
+};
+
//
// Constants for fixup signature encoding
//
@@ -211,6 +218,9 @@ enum ReadyToRunFixupKind
READYTORUN_FIXUP_Verify_FieldOffset = 0x31, /* Generate a runtime check to ensure that the field offset matches between compile and runtime. Unlike Check_FieldOffset, this will generate a runtime failure instead of silently dropping the method */
READYTORUN_FIXUP_Verify_TypeLayout = 0x32, /* Generate a runtime check to ensure that the type layout (size, alignment, HFA, reference map) matches between compile and runtime. Unlike Check_TypeLayout, this will generate a runtime failure instead of silently dropping the method */
+
+ READYTORUN_FIXUP_Check_VirtualFunctionOverride = 0x33, /* Generate a runtime check to ensure that virtual function resolution has equivalent behavior at runtime as at compile time. If not equivalent, code will not be used */
+ READYTORUN_FIXUP_Verify_VirtualFunctionOverride = 0x34, /* Generate a runtime check to ensure that virtual function resolution has equivalent behavior at runtime as at compile time. If not equivalent, generate runtime failure. */
};
//