ReadyToRun bugfixes
authorJan Kotas <jkotas@microsoft.com>
Wed, 20 May 2015 23:05:59 +0000 (16:05 -0700)
committerJan Kotas <jkotas@microsoft.com>
Wed, 20 May 2015 23:05:59 +0000 (16:05 -0700)
Fix bugs found by desktop tests

[tfs-changeset: 1474260]

src/tools/crossgen/crossgen.cpp
src/vm/compile.cpp
src/vm/jitinterface.cpp
src/vm/zapsig.cpp
src/zap/zapinfo.cpp
src/zap/zapmetadata.cpp

index 3bf729f..6f180a1 100644 (file)
@@ -120,7 +120,9 @@ void PrintUsageHelper()
        W("    /nologo              - Prevents displaying the logo\n")
        W("    @response.rsp        - Process command line arguments from specified\n")
        W("                           response file\n")
+#ifdef FEATURE_CORECLR
        W("    /partialtrust        - Assembly will be run in a partial trust domain.\n")
+#endif
        W("    /in <file>           - Specifies input filename (optional)\n")
 #ifdef MDIL
        W("    /out <file>          - Specifies output filename (optional with native images,\n")
@@ -523,6 +525,7 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv)
         {
             dwFlags |= NGENWORKER_FLAGS_MISSINGDEPENDENCIESOK;
         }
+#ifdef FEATURE_CORECLR
         else if (MatchParameter(*argv, W("PartialTrust")))
         {
             // Clear the /fulltrust flag
@@ -537,6 +540,7 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv)
             // We dont explicitly set the flag here again so that if "/PartialTrust" is specified, then it will successfully override the default
             // fulltrust behaviour.
         }
+#endif
 #ifdef FEATURE_LEGACYNETCF
         else if (MatchParameter(*argv, W("PreWP8App")))
         {
index d77a285..3cbe518 100644 (file)
@@ -534,7 +534,8 @@ HRESULT CEECompileInfo::LoadAssemblyByPath(
 #endif
 
 #if defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
-            pDomain->ToCompilationDomain()->ComputeAssemblyHardBindList(pAssemblyHolder->GetPersistentMDImport());
+            if (!IsReadyToRunCompilation())
+                pDomain->ToCompilationDomain()->ComputeAssemblyHardBindList(pAssemblyHolder->GetPersistentMDImport());
 #endif
 
 #ifdef MDIL
@@ -1042,6 +1043,14 @@ HRESULT CEECompileInfo::SetCompilationTarget(CORINFO_ASSEMBLY_HANDLE     assembl
         }
     }
 
+#ifdef FEATURE_READYTORUN_COMPILER
+    if (IsReadyToRunCompilation() && !pModule->IsILOnly())
+    {
+        GetSvcLogger()->Printf(LogLevel_Error, W("Error: /readytorun not supported for mixed mode assemblies\n"));
+        return E_FAIL;
+    }
+#endif
+
     return S_OK;
 }
 
index ee25456..cd720ba 100644 (file)
@@ -5446,7 +5446,8 @@ void CEEInfo::getCallInfo(
     // Delegate targets are always treated as direct calls here. (It would be nice to clean it up...).
     if (flags & CORINFO_CALLINFO_LDFTN)
     {
-        TypeEquivalenceFixupSpecificationHelper(m_pOverride, pTargetMD);
+        if (m_pOverride != NULL)
+            TypeEquivalenceFixupSpecificationHelper(m_pOverride, pTargetMD);
         directCall = true;
     }
     else
@@ -6446,7 +6447,7 @@ CorInfoHelpFunc CEEInfo::getCastingHelper(CORINFO_RESOLVED_TOKEN * pResolvedToke
 
     bool fClassMustBeRestored;
     result = getCastingHelperStatic(TypeHandle(pResolvedToken->hClass), fThrowing, &fClassMustBeRestored);
-    if (fClassMustBeRestored)
+    if (fClassMustBeRestored && m_pOverride != NULL)
         m_pOverride->classMustBeLoadedBeforeCodeIsRun(pResolvedToken->hClass);
 
     EE_TO_JIT_TRANSITION();
@@ -6581,7 +6582,7 @@ CorInfoHelpFunc CEEInfo::getUnBoxHelper(CORINFO_CLASS_HANDLE clsHnd)
 {
     LIMITED_METHOD_CONTRACT;
 
-    if (!isVerifyOnly())
+    if (m_pOverride != NULL)
         m_pOverride->classMustBeLoadedBeforeCodeIsRun(clsHnd);
 
     TypeHandle VMClsHnd(clsHnd);
index 77be8d8..15a4ffa 100644 (file)
@@ -970,7 +970,15 @@ MethodDesc *ZapSig::DecodeMethod(Module *pReferencingModule,
             MemberLoader::ThrowMissingMethodException(constrainedType.GetMethodTable(), NULL, NULL, NULL, 0, NULL);
         }
 
-        pMethod = directMethod;
+        // Strip the instantiating stub if the signature did not ask for one
+        if (directMethod->IsInstantiatingStub() && !isInstantiatingStub)
+        {
+            pMethod = directMethod->GetWrappedMethodDesc();
+        }
+        else
+        {
+            pMethod = directMethod;
+        }
     }
 
     return pMethod;
index 1c53511..151ac02 100644 (file)
@@ -2644,7 +2644,8 @@ void ZapInfo::getFunctionEntryPoint(
 {
     if (IsReadyToRunCompilation())
     {
-        _ASSERTE(!"getFunctionEntryPoint");
+        // READYTORUN: FUTURE: JIT still calls this for tail. and jmp instructions
+        m_zapper->Warning(W("ReadyToRun: Method entrypoint cannot be encoded\n"));
         ThrowHR(E_NOTIMPL);
     }
 
@@ -4052,7 +4053,17 @@ CorInfoIsAccessAllowedResult ZapInfo::canAccessClass( CORINFO_RESOLVED_TOKEN * p
                                                       CORINFO_METHOD_HANDLE   callerHandle,
                                                       CORINFO_HELPER_DESC    *throwHelper)
 {
-    return m_pEEJitInfo->canAccessClass(pResolvedToken, callerHandle, throwHelper);
+    CorInfoIsAccessAllowedResult ret = m_pEEJitInfo->canAccessClass(pResolvedToken, callerHandle, throwHelper);
+
+#ifdef FEATURE_READYTORUN_COMPILER
+    if (ret != CORINFO_ACCESS_ALLOWED)
+    {
+        m_zapper->Warning(W("ReadyToRun: Runtime access checks not supported\n"));
+        ThrowHR(E_NOTIMPL);
+    }
+#endif
+
+    return ret;
 }
 
 
index 95d3129..b8801d8 100644 (file)
@@ -665,6 +665,27 @@ ZapRVADataNode * ZapILMetaData::GetRVAField(void * pData)
     return pRVADataNode;
 }
 
+struct RVAField
+{
+    PVOID pData;
+    DWORD cbSize;
+    DWORD cbAlignment;
+};
+
+// Used by qsort
+int __cdecl RVAFieldCmp(const void * a_, const void * b_)
+{
+    RVAField * a = (RVAField *)a_;
+    RVAField * b = (RVAField *)b_;
+
+    if (a->pData != b->pData)
+    {
+        return (a->pData > b->pData) ? 1 : -1;
+    }
+
+    return 0;
+}
+
 void ZapILMetaData::CopyRVAFields()
 {
     IMDInternalImport * pMDImport = m_pImage->m_pMDImport;
@@ -672,26 +693,37 @@ void ZapILMetaData::CopyRVAFields()
     HENUMInternalHolder hEnum(pMDImport);
     hEnum.EnumAllInit(mdtFieldDef);
 
+    SArray<RVAField> fields;
+
     mdFieldDef fd;
     while (pMDImport->EnumNext(&hEnum, &fd))
     {
         DWORD dwRVA = 0;
         if (pMDImport->GetFieldRVA(fd, &dwRVA) == S_OK)
         {
-            PVOID pData = NULL;
-            DWORD cbSize = 0;
-            DWORD cbAlignment = 0;
+            RVAField field;
+            m_pImage->m_pPreloader->GetRVAFieldData(fd, &field.pData, &field.cbSize, &field.cbAlignment);
+            fields.Append(field);
+        }
+    }
 
-            m_pImage->m_pPreloader->GetRVAFieldData(fd, &pData, &cbSize, &cbAlignment);
+    if (fields.GetCount() == 0)
+        return;
 
-            ZapRVADataNode * pRVADataNode = GetRVAField(pData);
+    // Managed C++ binaries depend on the order of RVA fields
+    qsort(&fields[0], fields.GetCount(), sizeof(RVAField), RVAFieldCmp);
 
-            // Handle overlapping fields by reusing blobs based on the address, and just updating size and alignment.
-            pRVADataNode->UpdateSizeAndAlignment(cbSize, cbAlignment);
+    for (COUNT_T i = 0; i < fields.GetCount(); i++)
+    {
+        RVAField field = fields[i];
 
-            if (!pRVADataNode->IsPlaced())
-                m_pImage->m_pReadOnlyDataSection->Place(pRVADataNode);
-        }
+        ZapRVADataNode * pRVADataNode = GetRVAField(field.pData);
+
+        // Handle overlapping fields by reusing blobs based on the address, and just updating size and alignment.
+        pRVADataNode->UpdateSizeAndAlignment(field.cbSize, field.cbAlignment);
+
+        if (!pRVADataNode->IsPlaced())
+             m_pImage->m_pReadOnlyDataSection->Place(pRVADataNode);
     }
 }