summaryrefslogtreecommitdiff
path: root/src/ToolBox
diff options
context:
space:
mode:
authorAndy Ayers <andya@microsoft.com>2017-10-23 17:46:41 -0700
committerAndy Ayers <andya@microsoft.com>2017-10-30 14:36:24 -0700
commit215ee89756e612bcdd7e9bd61ea500eacaf4973f (patch)
tree1ba04645996fd4c04db80c1975a1fbd3ef791568 /src/ToolBox
parent274c961fa23d3dcd38cbb5736dcbf7b908d0cf99 (diff)
downloadcoreclr-215ee89756e612bcdd7e9bd61ea500eacaf4973f.tar.gz
coreclr-215ee89756e612bcdd7e9bd61ea500eacaf4973f.tar.bz2
coreclr-215ee89756e612bcdd7e9bd61ea500eacaf4973f.zip
JIT: optimize calls on boxed objects
For calls with boxed this objects, invoke the unboxed entry point if available and modify the box to copy the original value or struct to a local. Pass the address of this local as the first argument to the unboxed entry point. Defer for cases where the unboxed entry point requires an extra type parameter. This may enable subsequent inlining of the method, and if the method has other boxed parameters, may enable undoing those boxes as well. The jit is not yet as proficient at eliminating the struct copies, but they are present with or without this change, and some may even be required when the methods mutate the fields of `this`. Closes #14213.
Diffstat (limited to 'src/ToolBox')
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h5
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/lwmlist.h1
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp49
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/methodcontext.h10
-rw-r--r--src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp15
-rw-r--r--src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp7
-rw-r--r--src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp6
-rw-r--r--src/ToolBox/superpmi/superpmi/icorjitinfo.cpp9
8 files changed, 101 insertions, 1 deletions
diff --git a/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h b/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h
index 64a9619e9f..5c6dc4fc04 100644
--- a/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h
+++ b/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h
@@ -121,6 +121,11 @@ CORINFO_METHOD_HANDLE resolveVirtualMethod(CORINFO_METHOD_HANDLE virtualMethod,
CORINFO_CLASS_HANDLE implementingClass,
CORINFO_CONTEXT_HANDLE ownerType);
+// Get the unboxed entry point for a method, if possible.
+CORINFO_METHOD_HANDLE getUnboxedEntry(
+ CORINFO_METHOD_HANDLE ftn,
+ bool* requiresInstMethodTableArg /* OUT */);
+
// Given T, return the type of the default EqualityComparer<T>.
// Returns null if the type can't be determined exactly.
CORINFO_CLASS_HANDLE getDefaultEqualityComparerClass(CORINFO_CLASS_HANDLE elemType);
diff --git a/src/ToolBox/superpmi/superpmi-shared/lwmlist.h b/src/ToolBox/superpmi/superpmi-shared/lwmlist.h
index b2f69af782..b0cb7ad3c8 100644
--- a/src/ToolBox/superpmi/superpmi-shared/lwmlist.h
+++ b/src/ToolBox/superpmi/superpmi-shared/lwmlist.h
@@ -124,6 +124,7 @@ LWM(GetThreadTLSIndex, DWORD, DLD)
LWM(GetTokenTypeAsHandle, GetTokenTypeAsHandleValue, DWORDLONG)
LWM(GetTypeForBox, DWORDLONG, DWORDLONG)
LWM(GetTypeForPrimitiveValueClass, DWORDLONG, DWORD)
+LWM(GetUnboxedEntry, DWORDLONG, DLD);
LWM(GetUnBoxHelper, DWORDLONG, DWORD)
LWM(GetUnmanagedCallConv, DWORDLONG, DWORD)
LWM(GetVarArgsHandle, GetVarArgsHandleValue, DLDL)
diff --git a/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
index 0ee17c9104..3326a49937 100644
--- a/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
+++ b/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
@@ -3018,6 +3018,55 @@ CORINFO_METHOD_HANDLE MethodContext::repResolveVirtualMethod(CORINFO_METHOD_HAND
return (CORINFO_METHOD_HANDLE)result;
}
+void MethodContext::recGetUnboxedEntry(CORINFO_METHOD_HANDLE ftn,
+ bool *requiresInstMethodTableArg,
+ CORINFO_METHOD_HANDLE result)
+{
+ if (GetUnboxedEntry == nullptr)
+ {
+ GetUnboxedEntry = new LightWeightMap<DWORDLONG, DLD>();
+ }
+
+ DWORDLONG key = (DWORDLONG) ftn;
+ DLD value;
+ value.A = (DWORDLONG) result;
+ if (requiresInstMethodTableArg != nullptr)
+ {
+ value.B = (DWORD) *requiresInstMethodTableArg ? 1 : 0;
+ }
+ else
+ {
+ value.B = 0;
+ }
+ GetUnboxedEntry->Add(key, value);
+ DEBUG_REC(dmpGetUnboxedEntry(key, value));
+}
+
+void MethodContext::dmpGetUnboxedEntry(DWORDLONG key, DLD value)
+{
+ printf("GetUnboxedEntry ftn-%016llX, result-%016llX, requires-inst-%u",
+ key, value.A, value.B);
+}
+
+CORINFO_METHOD_HANDLE MethodContext::repGetUnboxedEntry(CORINFO_METHOD_HANDLE ftn,
+ bool* requiresInstMethodTableArg)
+{
+ DWORDLONG key = (DWORDLONG)ftn;
+
+ AssertCodeMsg(GetUnboxedEntry != nullptr, EXCEPTIONCODE_MC, "No GetUnboxedEntry map for %016llX", key);
+ AssertCodeMsg(GetUnboxedEntry->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX", key);
+ DLD result = GetUnboxedEntry->Get(key);
+
+ DEBUG_REP(dmpGetUnboxedEntry(key, result));
+
+ if (requiresInstMethodTableArg != nullptr)
+ {
+ *requiresInstMethodTableArg = (result.B == 1);
+ }
+
+ return (CORINFO_METHOD_HANDLE)(result.A);
+}
+
void MethodContext::recGetDefaultEqualityComparerClass(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE result)
{
if (GetDefaultEqualityComparerClass == nullptr)
diff --git a/src/ToolBox/superpmi/superpmi-shared/methodcontext.h b/src/ToolBox/superpmi/superpmi-shared/methodcontext.h
index ce62aa188d..450831d114 100644
--- a/src/ToolBox/superpmi/superpmi-shared/methodcontext.h
+++ b/src/ToolBox/superpmi/superpmi-shared/methodcontext.h
@@ -877,6 +877,13 @@ public:
CORINFO_CLASS_HANDLE implClass,
CORINFO_CONTEXT_HANDLE ownerType);
+ void recGetUnboxedEntry(CORINFO_METHOD_HANDLE ftn,
+ bool* requiresInstMethodTableArg,
+ CORINFO_METHOD_HANDLE result);
+ void dmpGetUnboxedEntry(DWORDLONG key, DLD value);
+ CORINFO_METHOD_HANDLE repGetUnboxedEntry(CORINFO_METHOD_HANDLE ftn,
+ bool* requiresInstMethodTableArg);
+
void recGetDefaultEqualityComparerClass(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE result);
void dmpGetDefaultEqualityComparerClass(DWORDLONG key, DWORDLONG value);
CORINFO_CLASS_HANDLE repGetDefaultEqualityComparerClass(CORINFO_CLASS_HANDLE cls);
@@ -1269,7 +1276,7 @@ private:
};
// ********************* Please keep this up-to-date to ease adding more ***************
-// Highest packet number: 164
+// Highest packet number: 165
// *************************************************************************************
enum mcPackets
{
@@ -1384,6 +1391,7 @@ enum mcPackets
Packet_GetTokenTypeAsHandle = 89,
Packet_GetTypeForBox = 90,
Packet_GetTypeForPrimitiveValueClass = 91,
+ Packet_GetUnboxedEntry = 165, // Added 10/26/17
Packet_GetUnBoxHelper = 92,
Packet_GetReadyToRunHelper = 150, // Added 10/10/2014
Packet_GetReadyToRunDelegateCtorHelper = 157, // Added 3/30/2016
diff --git a/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp
index 1c7c0cbd9f..3477baca77 100644
--- a/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp
+++ b/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp
@@ -242,6 +242,21 @@ CORINFO_METHOD_HANDLE interceptor_ICJI::resolveVirtualMethod(CORINFO_METHOD_HAND
return result;
}
+// Get the unboxed entry point for a method, if possible.
+CORINFO_METHOD_HANDLE interceptor_ICJI::getUnboxedEntry(CORINFO_METHOD_HANDLE ftn, bool* requiresInstMethodTableArg)
+{
+ mc->cr->AddCall("getUnboxedEntry");
+ bool localRequiresInstMethodTableArg = false;
+ CORINFO_METHOD_HANDLE result =
+ original_ICorJitInfo->getUnboxedEntry(ftn, &localRequiresInstMethodTableArg);
+ mc->recGetUnboxedEntry(ftn, &localRequiresInstMethodTableArg, result);
+ if (requiresInstMethodTableArg != nullptr)
+ {
+ *requiresInstMethodTableArg = localRequiresInstMethodTableArg;
+ }
+ return result;
+}
+
// Given T, return the type of the default EqualityComparer<T>.
// Returns null if the type can't be determined exactly.
CORINFO_CLASS_HANDLE interceptor_ICJI::getDefaultEqualityComparerClass(CORINFO_CLASS_HANDLE cls)
diff --git a/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp
index 1e7ee24d50..a9e5761c34 100644
--- a/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp
+++ b/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp
@@ -163,6 +163,13 @@ CORINFO_METHOD_HANDLE interceptor_ICJI::resolveVirtualMethod(CORINFO_METHOD_HAND
return original_ICorJitInfo->resolveVirtualMethod(virtualMethod, implementingClass, ownerType);
}
+// Get the unboxed entry point for a method, if possible.
+CORINFO_METHOD_HANDLE interceptor_ICJI::getUnboxedEntry(CORINFO_METHOD_HANDLE ftn, bool* requiresInstMethodTableArg)
+{
+ mcs->AddCall("getUnboxedEntry");
+ return original_ICorJitInfo->getUnboxedEntry(ftn, requiresInstMethodTableArg);
+}
+
// Given T, return the type of the default EqualityComparer<T>.
// Returns null if the type can't be determined exactly.
CORINFO_CLASS_HANDLE interceptor_ICJI::getDefaultEqualityComparerClass(CORINFO_CLASS_HANDLE cls)
diff --git a/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp
index bf3d6483d3..d7ca029fae 100644
--- a/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp
+++ b/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp
@@ -141,6 +141,12 @@ void interceptor_ICJI::getMethodVTableOffset(CORINFO_METHOD_HANDLE method,
original_ICorJitInfo->getMethodVTableOffset(method, offsetOfIndirection, offsetAfterIndirection, isRelative);
}
+// Get the unboxed entry point for a method, if possible.
+CORINFO_METHOD_HANDLE interceptor_ICJI::getUnboxedEntry(CORINFO_METHOD_HANDLE ftn, bool* requiresInstMethodTableArg)
+{
+ return original_ICorJitInfo->getUnboxedEntry(ftn, requiresInstMethodTableArg);
+}
+
// Find the virtual method in implementingClass that overrides virtualMethod.
// Return null if devirtualization is not possible.
CORINFO_METHOD_HANDLE interceptor_ICJI::resolveVirtualMethod(CORINFO_METHOD_HANDLE virtualMethod,
diff --git a/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp
index c53c77942a..e8f86cedbd 100644
--- a/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp
+++ b/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp
@@ -185,6 +185,15 @@ CORINFO_METHOD_HANDLE MyICJI::resolveVirtualMethod(CORINFO_METHOD_HANDLE virtua
return result;
}
+// Get the unboxed entry point for a method, if possible.
+CORINFO_METHOD_HANDLE MyICJI::getUnboxedEntry(CORINFO_METHOD_HANDLE ftn, bool* requiresInstMethodTableArg)
+{
+ jitInstance->mc->cr->AddCall("getUnboxedEntry");
+ CORINFO_METHOD_HANDLE result =
+ jitInstance->mc->repGetUnboxedEntry(ftn, requiresInstMethodTableArg);
+ return result;
+}
+
// Given T, return the type of the default EqualityComparer<T>.
// Returns null if the type can't be determined exactly.
CORINFO_CLASS_HANDLE MyICJI::getDefaultEqualityComparerClass(CORINFO_CLASS_HANDLE cls)