From 86047aaed9a2cdc998ad2076bc5db85d0e9ebf9b Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Sun, 27 Dec 2020 20:26:29 +0300 Subject: [PATCH] Intrinsify Object.MemberwiseClone() (#46243) --- .../System.Private.CoreLib/src/System/Object.CoreCLR.cs | 1 + src/coreclr/jit/gentree.cpp | 3 ++- src/coreclr/jit/importer.cpp | 7 +++++++ src/coreclr/jit/namedintrinsiclist.h | 1 + 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Object.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Object.CoreCLR.cs index 76251e3239db4..a390ec6c03bc8 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Object.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Object.CoreCLR.cs @@ -16,6 +16,7 @@ public partial class Object // object. This is always a shallow copy of the instance. The method is protected // so that other object may only call this method on themselves. It is intended to // support the ICloneable interface. + [Intrinsic] protected unsafe object MemberwiseClone() { object clone = RuntimeHelpers.AllocateUninitializedClone(this); diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 5b9a88c1d6a89..d65a21f7784a0 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -17759,7 +17759,8 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b GenTreeCall* call = tree->AsCall(); if (call->gtFlags & CORINFO_FLG_JIT_INTRINSIC) { - if (lookupNamedIntrinsic(call->gtCallMethHnd) == NI_System_Array_Clone) + NamedIntrinsic ni = lookupNamedIntrinsic(call->gtCallMethHnd); + if ((ni == NI_System_Array_Clone) || (ni == NI_System_Object_MemberwiseClone)) { objClass = gtGetClassHandle(call->gtCallThisArg->GetNode(), pIsExact, pIsNonNull); break; diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index aa75207070bd3..cf114a6d034c5 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -4816,6 +4816,13 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) result = NI_System_Array_Clone; } } + else if (strcmp(className, "Object") == 0) + { + if (strcmp(methodName, "MemberwiseClone") == 0) + { + result = NI_System_Object_MemberwiseClone; + } + } else if (strcmp(className, "Type") == 0) { if (strcmp(methodName, "get_IsValueType") == 0) diff --git a/src/coreclr/jit/namedintrinsiclist.h b/src/coreclr/jit/namedintrinsiclist.h index c223307eebe9f..e595838d097c9 100644 --- a/src/coreclr/jit/namedintrinsiclist.h +++ b/src/coreclr/jit/namedintrinsiclist.h @@ -44,6 +44,7 @@ enum NamedIntrinsic : unsigned short NI_System_Type_IsAssignableFrom, NI_System_Type_IsAssignableTo, NI_System_Array_Clone, + NI_System_Object_MemberwiseClone, // These are used by HWIntrinsics but are defined more generally // to allow dead code optimization and handle the recursion case