helper for corert
authorSergey Andreenko <seandree@microsoft.com>
Mon, 17 Oct 2016 19:52:12 +0000 (12:52 -0700)
committerSergey Andreenko <seandree@microsoft.com>
Mon, 17 Oct 2016 21:14:11 +0000 (14:14 -0700)
Helper to get ready to run, shared, generic, static base.

src/inc/corinfo.h
src/inc/jithelpers.h
src/jit/compiler.h
src/jit/compiler.hpp
src/jit/importer.cpp
src/jit/utils.cpp
src/jit/valuenum.cpp
src/jit/valuenumfuncs.h

index 6e41d8e..35e855b 100644 (file)
@@ -642,6 +642,7 @@ enum CorInfoHelpFunc
 #if COR_JIT_EE_VERSION > 460
     CORINFO_HELP_READYTORUN_GENERIC_HANDLE,
     CORINFO_HELP_READYTORUN_DELEGATE_CTOR,
+    CORINFO_HELP_READYTORUN_GENERIC_STATIC_BASE,
 #else
     #define CORINFO_HELP_READYTORUN_DELEGATE_CTOR CORINFO_HELP_EE_PRESTUB
 #endif // COR_JIT_EE_VERSION
@@ -1706,6 +1707,7 @@ enum CORINFO_FIELD_ACCESSOR
     CORINFO_FIELD_STATIC_GENERICS_STATIC_HELPER, // static field access using the "generic static" helper (argument is MethodTable *)
     CORINFO_FIELD_STATIC_ADDR_HELPER,       // static field accessed using address-of helper (argument is FieldDesc *)
     CORINFO_FIELD_STATIC_TLS,               // unmanaged TLS access
+    CORINFO_FIELD_STATIC_READYTORUN_HELPER, // static field access using a runtime lookup helper
 
     CORINFO_FIELD_INTRINSIC_ZERO,           // intrinsic zero (IntPtr.Zero, UIntPtr.Zero)
     CORINFO_FIELD_INTRINSIC_EMPTY_STRING,   // intrinsic emptry string (String.Empty)
index 8a71992..f84db91 100644 (file)
     JITHELPER(CORINFO_HELP_VIRTUAL_FUNC_PTR,    JIT_VirtualFunctionPointer, CORINFO_HELP_SIG_4_STACK)
     //JITHELPER(CORINFO_HELP_VIRTUAL_FUNC_PTR_LOG,JIT_VirtualFunctionPointerLogging)
 
-    JITHELPER(CORINFO_HELP_READYTORUN_NEW,                NULL,   CORINFO_HELP_SIG_NO_ALIGN_STUB)
-    JITHELPER(CORINFO_HELP_READYTORUN_NEWARR_1,           NULL,   CORINFO_HELP_SIG_NO_ALIGN_STUB)
-    JITHELPER(CORINFO_HELP_READYTORUN_ISINSTANCEOF,       NULL,   CORINFO_HELP_SIG_NO_ALIGN_STUB)
-    JITHELPER(CORINFO_HELP_READYTORUN_CHKCAST,            NULL,   CORINFO_HELP_SIG_NO_ALIGN_STUB)
-    JITHELPER(CORINFO_HELP_READYTORUN_STATIC_BASE,        NULL,   CORINFO_HELP_SIG_NO_ALIGN_STUB)
-    JITHELPER(CORINFO_HELP_READYTORUN_VIRTUAL_FUNC_PTR,   NULL,   CORINFO_HELP_SIG_NO_ALIGN_STUB)
+    JITHELPER(CORINFO_HELP_READYTORUN_NEW,                 NULL,   CORINFO_HELP_SIG_NO_ALIGN_STUB)
+    JITHELPER(CORINFO_HELP_READYTORUN_NEWARR_1,            NULL,   CORINFO_HELP_SIG_NO_ALIGN_STUB)
+    JITHELPER(CORINFO_HELP_READYTORUN_ISINSTANCEOF,        NULL,   CORINFO_HELP_SIG_NO_ALIGN_STUB)
+    JITHELPER(CORINFO_HELP_READYTORUN_CHKCAST,             NULL,   CORINFO_HELP_SIG_NO_ALIGN_STUB)
+    JITHELPER(CORINFO_HELP_READYTORUN_STATIC_BASE,         NULL,   CORINFO_HELP_SIG_NO_ALIGN_STUB)
+    JITHELPER(CORINFO_HELP_READYTORUN_VIRTUAL_FUNC_PTR,    NULL,   CORINFO_HELP_SIG_NO_ALIGN_STUB)
 #if COR_JIT_EE_VERSION > 460
-    JITHELPER(CORINFO_HELP_READYTORUN_GENERIC_HANDLE,     NULL,   CORINFO_HELP_SIG_NO_ALIGN_STUB)
-    JITHELPER(CORINFO_HELP_READYTORUN_DELEGATE_CTOR,      NULL,   CORINFO_HELP_SIG_NO_ALIGN_STUB)
+    JITHELPER(CORINFO_HELP_READYTORUN_GENERIC_HANDLE,      NULL,   CORINFO_HELP_SIG_NO_ALIGN_STUB)
+    JITHELPER(CORINFO_HELP_READYTORUN_DELEGATE_CTOR,       NULL,   CORINFO_HELP_SIG_NO_ALIGN_STUB)
+    JITHELPER(CORINFO_HELP_READYTORUN_GENERIC_STATIC_BASE, NULL,   CORINFO_HELP_SIG_NO_ALIGN_STUB)
 #endif // COR_JIT_EE_VERSION
 
     JITHELPER(CORINFO_HELP_EE_PRESTUB,          ThePreStub,                 CORINFO_HELP_SIG_NO_ALIGN_STUB)
index 5687e9a..eb3d714 100644 (file)
@@ -2914,6 +2914,8 @@ public:
                                unsigned                flags,
                                void*                   compileTimeHandle);
 
+    GenTreePtr getRuntimeContextTree(CORINFO_LOOKUP* pLookup);
+
     GenTreePtr impRuntimeLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedToken,
                                       CORINFO_LOOKUP*         pLookup,
                                       void*                   compileTimeHandle);
index c53bf4c..fcc3315 100644 (file)
@@ -3927,7 +3927,7 @@ inline bool Compiler::IsSharedStaticHelper(GenTreePtr tree)
         helper == CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_DYNAMICCLASS ||
         helper == CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_DYNAMICCLASS ||
 #ifdef FEATURE_READYTORUN_COMPILER
-        helper == CORINFO_HELP_READYTORUN_STATIC_BASE ||
+        helper == CORINFO_HELP_READYTORUN_STATIC_BASE || helper == CORINFO_HELP_READYTORUN_GENERIC_STATIC_BASE ||
 #endif
         helper == CORINFO_HELP_CLASSINIT_SHARED_DYNAMICCLASS;
 #if 0
index 53e856c..e78b460 100644 (file)
@@ -1856,6 +1856,35 @@ GenTreePtr Compiler::impMethodPointer(CORINFO_RESOLVED_TOKEN* pResolvedToken, CO
     return op1;
 }
 
+GenTreePtr Compiler::getRuntimeContextTree(CORINFO_LOOKUP* pLookup)
+{
+    GenTreePtr                  ctxTree = nullptr;
+    CORINFO_RUNTIME_LOOKUP_KIND kind    = pLookup->lookupKind.runtimeLookupKind;
+
+    // Collectible types requires that for shared generic code, if we use the generic context parameter
+    // that we report it. (This is a conservative approach, we could detect some cases particularly when the
+    // context parameter is this that we don't need the eager reporting logic.)
+    lvaGenericsContextUsed = true;
+
+    if (kind == CORINFO_LOOKUP_THISOBJ)
+    {
+        // this Object
+        ctxTree = gtNewLclvNode(info.compThisArg, TYP_REF);
+
+        // Vtable pointer of this object
+        ctxTree = gtNewOperNode(GT_IND, TYP_I_IMPL, ctxTree);
+        ctxTree->gtFlags |= GTF_EXCEPT; // Null-pointer exception
+        ctxTree->gtFlags |= GTF_IND_INVARIANT;
+    }
+    else
+    {
+        assert(kind == CORINFO_LOOKUP_METHODPARAM || kind == CORINFO_LOOKUP_CLASSPARAM);
+
+        ctxTree = gtNewLclvNode(info.compTypeCtxtArg, TYP_I_IMPL); // Exact method descriptor as passed in as last arg
+    }
+    return ctxTree;
+}
+
 /*****************************************************************************/
 /* Import a dictionary lookup to access a handle in code shared between
    generic instantiations.
@@ -1878,36 +1907,12 @@ GenTreePtr Compiler::impRuntimeLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedTok
                                             CORINFO_LOOKUP*         pLookup,
                                             void*                   compileTimeHandle)
 {
-    CORINFO_RUNTIME_LOOKUP_KIND kind           = pLookup->lookupKind.runtimeLookupKind;
-    CORINFO_RUNTIME_LOOKUP*     pRuntimeLookup = &pLookup->runtimeLookup;
 
     // This method can only be called from the importer instance of the Compiler.
     // In other word, it cannot be called by the instance of the Compiler for the inlinee.
     assert(!compIsForInlining());
 
-    GenTreePtr ctxTree;
-
-    // Collectible types requires that for shared generic code, if we use the generic context parameter
-    // that we report it. (This is a conservative approach, we could detect some cases particularly when the
-    // context parameter is this that we don't need the eager reporting logic.)
-    lvaGenericsContextUsed = true;
-
-    if (kind == CORINFO_LOOKUP_THISOBJ)
-    {
-        // this Object
-        ctxTree = gtNewLclvNode(info.compThisArg, TYP_REF);
-
-        // Vtable pointer of this object
-        ctxTree = gtNewOperNode(GT_IND, TYP_I_IMPL, ctxTree);
-        ctxTree->gtFlags |= GTF_EXCEPT; // Null-pointer exception
-        ctxTree->gtFlags |= GTF_IND_INVARIANT;
-    }
-    else
-    {
-        assert(kind == CORINFO_LOOKUP_METHODPARAM || kind == CORINFO_LOOKUP_CLASSPARAM);
-
-        ctxTree = gtNewLclvNode(info.compTypeCtxtArg, TYP_I_IMPL); // Exact method descriptor as passed in as last arg
-    }
+    GenTreePtr ctxTree = getRuntimeContextTree(pLookup);
 
 #ifdef FEATURE_READYTORUN_COMPILER
     if (opts.IsReadyToRun())
@@ -1917,6 +1922,7 @@ GenTreePtr Compiler::impRuntimeLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedTok
     }
 #endif
 
+    CORINFO_RUNTIME_LOOKUP* pRuntimeLookup = &pLookup->runtimeLookup;
     // It's available only via the run-time helper function
     if (pRuntimeLookup->indirections == CORINFO_USEHELPER)
     {
@@ -5727,10 +5733,10 @@ GenTreePtr Compiler::impImportStaticFieldAccess(CORINFO_RESOLVED_TOKEN* pResolve
             FieldSeqNode* fs = GetFieldSeqStore()->CreateSingleton(pResolvedToken->hField);
             op1              = gtNewOperNode(GT_ADD, type, op1,
                                 new (this, GT_CNS_INT) GenTreeIntCon(TYP_I_IMPL, pFieldInfo->offset, fs));
+            break;
         }
-        break;
-
         case CORINFO_FIELD_STATIC_SHARED_STATIC_HELPER:
+        {
 #ifdef FEATURE_READYTORUN_COMPILER
             if (opts.IsReadyToRun())
             {
@@ -5757,8 +5763,26 @@ GenTreePtr Compiler::impImportStaticFieldAccess(CORINFO_RESOLVED_TOKEN* pResolve
                                     new (this, GT_CNS_INT) GenTreeIntCon(TYP_INT, pFieldInfo->offset, fs));
             }
             break;
+        }
+        case CORINFO_FIELD_STATIC_READYTORUN_HELPER:
+        {
+            noway_assert(opts.IsReadyToRun());
+            CORINFO_GENERICHANDLE_RESULT embedInfo;
+            info.compCompHnd->embedGenericHandle(pResolvedToken, FALSE, &embedInfo);
+            assert(embedInfo.lookup.lookupKind.needsRuntimeLookup);
 
+            GenTreePtr ctxTree = getRuntimeContextTree(&embedInfo.lookup);
+
+            var_types type = TYP_BYREF;
+            op1            = impReadyToRunHelperToTree(pResolvedToken, pFieldInfo->helper, type, gtNewArgList(ctxTree),
+                                            &embedInfo.lookup.lookupKind);
+            FieldSeqNode* fs = GetFieldSeqStore()->CreateSingleton(pResolvedToken->hField);
+            op1              = gtNewOperNode(GT_ADD, type, op1,
+                                new (this, GT_CNS_INT) GenTreeIntCon(TYP_I_IMPL, pFieldInfo->offset, fs));
+            break;
+        }
         default:
+        {
             if (!(access & CORINFO_ACCESS_ADDRESS))
             {
                 // In future, it may be better to just create the right tree here instead of folding it later.
@@ -5815,6 +5839,7 @@ GenTreePtr Compiler::impImportStaticFieldAccess(CORINFO_RESOLVED_TOKEN* pResolve
                 }
             }
             break;
+        }
     }
 
     if (pFieldInfo->fieldFlags & CORINFO_FLG_FIELD_STATIC_IN_HEAP)
@@ -12922,6 +12947,7 @@ void Compiler::impImportBlockCode(BasicBlock* block)
                     case CORINFO_FIELD_STATIC_RVA_ADDRESS:
                     case CORINFO_FIELD_STATIC_SHARED_STATIC_HELPER:
                     case CORINFO_FIELD_STATIC_GENERICS_STATIC_HELPER:
+                    case CORINFO_FIELD_STATIC_READYTORUN_HELPER:
                         op1 = impImportStaticFieldAccess(&resolvedToken, (CORINFO_ACCESS_FLAGS)aflags, &fieldInfo,
                                                          lclTyp);
                         break;
@@ -13184,6 +13210,7 @@ void Compiler::impImportBlockCode(BasicBlock* block)
                     case CORINFO_FIELD_STATIC_RVA_ADDRESS:
                     case CORINFO_FIELD_STATIC_SHARED_STATIC_HELPER:
                     case CORINFO_FIELD_STATIC_GENERICS_STATIC_HELPER:
+                    case CORINFO_FIELD_STATIC_READYTORUN_HELPER:
                         op1 = impImportStaticFieldAccess(&resolvedToken, (CORINFO_ACCESS_FLAGS)aflags, &fieldInfo,
                                                          lclTyp);
                         break;
index 1970313..1820625 100644 (file)
@@ -1417,6 +1417,7 @@ void HelperCallProperties::init()
             case CORINFO_HELP_GETGENERICS_GCSTATIC_BASE:
             case CORINFO_HELP_GETGENERICS_NONGCSTATIC_BASE:
             case CORINFO_HELP_READYTORUN_STATIC_BASE:
+            case CORINFO_HELP_READYTORUN_GENERIC_STATIC_BASE:
 
                 // These may invoke static class constructors
                 // These can throw InvalidProgram exception if the class can not be constructed
index 82b9278..b5eeae2 100644 (file)
@@ -7159,6 +7159,9 @@ VNFunc Compiler::fgValueNumberHelperMethVNFunc(CorInfoHelpFunc helpFunc)
         case CORINFO_HELP_READYTORUN_STATIC_BASE:
             vnf = VNF_ReadyToRunStaticBase;
             break;
+        case CORINFO_HELP_READYTORUN_GENERIC_STATIC_BASE:
+            vnf = VNF_ReadyToRunGenericStaticBase;
+            break;
         case CORINFO_HELP_GETSHARED_GCSTATIC_BASE_DYNAMICCLASS:
             vnf = VNF_GetsharedGcstaticBaseDynamicclass;
             break;
index 064a337..4729fc6 100644 (file)
@@ -99,6 +99,7 @@ ValueNumFuncDef(GetsharedNongcstaticBase, 2, false, true, true)
 ValueNumFuncDef(GetsharedGcstaticBaseNoctor, 1, false, true, true)
 ValueNumFuncDef(GetsharedNongcstaticBaseNoctor, 1, false, true, true)
 ValueNumFuncDef(ReadyToRunStaticBase, 1, false, true, true)
+ValueNumFuncDef(ReadyToRunGenericStaticBase, 1, false, true, true)
 ValueNumFuncDef(GetsharedGcstaticBaseDynamicclass, 2, false, true, true)
 ValueNumFuncDef(GetsharedNongcstaticBaseDynamicclass, 2, false, true, true)
 ValueNumFuncDef(GetgenericsGcthreadstaticBase, 1, false, true, true)