Add support for RVA fields to crossgen/R2R (dotnet/coreclr#21463)
authorJan Kotas <jkotas@microsoft.com>
Mon, 10 Dec 2018 15:52:15 +0000 (07:52 -0800)
committerGitHub <noreply@github.com>
Mon, 10 Dec 2018 15:52:15 +0000 (07:52 -0800)
* Add support for RVA fields to crossgen/R2R

RVA fields are became more common with pre-inititialized ReadOnlySpan<byte>. Fix crossgen to deal with them for R2R.

* Fix tests, map new JIT helper for R2R

Commit migrated from https://github.com/dotnet/coreclr/commit/32d8dfb65f2403c1cb628495ee944a9f35a0eb3a

src/coreclr/src/vm/jitinterface.cpp
src/coreclr/src/zap/zapinfo.cpp
src/coreclr/tests/src/readytorun/tests/main.cs

index 63b407c..7fcdd62 100644 (file)
@@ -13964,11 +13964,35 @@ InfoAccessType CEEInfo::emptyStringLiteral(void ** ppValue)
 void* CEEInfo::getFieldAddress(CORINFO_FIELD_HANDLE fieldHnd,
                                   void **ppIndirection)
 {
-    LIMITED_METHOD_CONTRACT;
-    _ASSERTE(isVerifyOnly());
+    CONTRACTL{
+        SO_TOLERANT;
+        THROWS;
+        GC_TRIGGERS;
+        MODE_PREEMPTIVE;
+    } CONTRACTL_END;
+
+    void *result = NULL;
+
     if (ppIndirection != NULL)
         *ppIndirection = NULL;
-    return (void *)0x10;
+
+    // Do not bother with initialization if we are only verifying the method.
+    if (isVerifyOnly())
+    {
+        return (void *)0x10;
+    }
+
+    JIT_TO_EE_TRANSITION();
+
+    FieldDesc* field = (FieldDesc*)fieldHnd;
+
+    _ASSERTE(field->IsRVA());
+
+    result = field->GetStaticAddressHandle(NULL);
+
+    EE_TO_JIT_TRANSITION();
+
+    return result;
 }
 
 CORINFO_CLASS_HANDLE CEEInfo::getStaticFieldCurrentClass(CORINFO_FIELD_HANDLE fieldHnd,
index 7c0200b..a37531c 100644 (file)
@@ -1715,6 +1715,9 @@ ReadyToRunHelper MapReadyToRunHelper(CorInfoHelpFunc func, bool * pfOptimizeForS
     case corInfoHelpFunc: flags return readyToRunHelper;
 #include "readytorunhelpers.h"
 
+    case CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE:
+        return READYTORUN_HELPER_GetRuntimeTypeHandle;
+
     case CORINFO_HELP_STRCNS_CURRENT_MODULE:
         *pfOptimizeForSize = true;
         return READYTORUN_HELPER_GetString;
@@ -2319,6 +2322,13 @@ unsigned ZapInfo::getClassDomainID (CORINFO_CLASS_HANDLE cls, void **ppIndirecti
 
 void * ZapInfo::getFieldAddress(CORINFO_FIELD_HANDLE field, void **ppIndirection)
 {
+    if (IsReadyToRunCompilation())
+    {
+        void * pAddress = m_pEEJitInfo->getFieldAddress(field, ppIndirection);
+
+        return m_pImage->m_pILMetaData->GetRVAField(pAddress);
+    }
+
     _ASSERTE(ppIndirection != NULL);
 
     CORINFO_CLASS_HANDLE hClass = m_pEEJitInfo->getFieldClass(field);
@@ -3005,8 +3015,15 @@ void ZapInfo::getFieldInfo (CORINFO_RESOLVED_TOKEN * pResolvedToken,
                }
             break;
 
-        case CORINFO_FIELD_STATIC_ADDRESS:           // field at given address
         case CORINFO_FIELD_STATIC_RVA_ADDRESS:       // RVA field at given address
+            if (m_pEEJitInfo->getClassModule(pResolvedToken->hClass) != m_pImage->m_hModule)
+            {
+                m_zapper->Warning(W("ReadyToRun: Cross-module RVA static fields not supported\n"));
+                ThrowHR(E_NOTIMPL);
+            }
+            break;
+
+        case CORINFO_FIELD_STATIC_ADDRESS:           // field at given address
         case CORINFO_FIELD_STATIC_ADDR_HELPER:       // static field accessed using address-of helper (argument is FieldDesc *)
         case CORINFO_FIELD_STATIC_TLS:
             m_zapper->Warning(W("ReadyToRun: Rare kinds of static fields not supported\n"));
index 783c1fd..67a2965 100644 (file)
@@ -415,6 +415,13 @@ class Program
         }
     }
 
+    static void RVAFieldTest()
+    {
+        ReadOnlySpan<byte> value = new byte[] { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
+        for (byte i = 0; i < value.Length; i++)
+            Assert.AreEqual(value[i], (byte)(9 - i));
+    }
+
     static void RunAllTests()
     {
         TestVirtualMethodCalls();
@@ -467,6 +474,8 @@ class Program
         TestOpenClosedDelegate();
         
         GenericLdtokenFieldsTest();
+
+        RVAFieldTest();
     }
 
     static int Main()