diff options
author | Fadi Hanna <fadim@microsoft.com> | 2016-08-03 18:00:49 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-08-03 18:00:49 -0700 |
commit | 693fff99049bc7d63459b2c444237ca532036b47 (patch) | |
tree | b6c9b7fdc517276f1480f6a9deb23c506ffc8fdd /src/vm | |
parent | d18ddfda61efdfe4521d2dce816fa01021bf26a8 (diff) | |
download | coreclr-693fff99049bc7d63459b2c444237ca532036b47.tar.gz coreclr-693fff99049bc7d63459b2c444237ca532036b47.tar.bz2 coreclr-693fff99049bc7d63459b2c444237ca532036b47.zip |
Adding Support for FieldDescSlot generic dictionary entries for R2R generic code. (#6200)
This enables generic code with ldtoken instructions for fields on generic types to be compiled into R2R.
This change makes newer versions of the runtime compatible with older version R2R images,
but not vice-versa. Therefore, the major version is increased to 2 with this change.
This change adds more encodings to a R2R image without changing the format of any previously encoded
entity, and is backwards compatible.
Diffstat (limited to 'src/vm')
-rw-r--r-- | src/vm/codeman.cpp | 14 | ||||
-rw-r--r-- | src/vm/compile.cpp | 6 | ||||
-rw-r--r-- | src/vm/compile.h | 7 | ||||
-rw-r--r-- | src/vm/genericdict.cpp | 52 | ||||
-rw-r--r-- | src/vm/jitinterface.cpp | 7 | ||||
-rw-r--r-- | src/vm/zapsig.cpp | 48 | ||||
-rw-r--r-- | src/vm/zapsig.h | 62 |
7 files changed, 120 insertions, 76 deletions
diff --git a/src/vm/codeman.cpp b/src/vm/codeman.cpp index 8e1800d24f..9ce6bb2a20 100644 --- a/src/vm/codeman.cpp +++ b/src/vm/codeman.cpp @@ -6412,18 +6412,12 @@ UINT32 ReadyToRunJitManager::JitTokenToGCInfoVersion(const METHODTOKEN& MethodTo { CONTRACTL{ NOTHROW; - GC_NOTRIGGER; - HOST_NOCALLS; - SUPPORTS_DAC; + GC_NOTRIGGER; + HOST_NOCALLS; + SUPPORTS_DAC; } CONTRACTL_END; - READYTORUN_HEADER * header = JitTokenToReadyToRunInfo(MethodToken)->GetImage()->GetReadyToRunHeader(); - UINT32 gcInfoVersion = header->MajorVersion; - - // Currently there's only one version of GCInfo. - _ASSERTE(gcInfoVersion == GCINFO_VERSION); - - return gcInfoVersion; + return GCINFO_VERSION; } PTR_RUNTIME_FUNCTION ReadyToRunJitManager::JitTokenToRuntimeFunction(const METHODTOKEN& MethodToken) diff --git a/src/vm/compile.cpp b/src/vm/compile.cpp index 7a3507eed6..b381b3f074 100644 --- a/src/vm/compile.cpp +++ b/src/vm/compile.cpp @@ -2368,7 +2368,8 @@ void CEECompileInfo::EncodeField( SigBuilder * pSigBuilder, LPVOID encodeContext, ENCODEMODULE_CALLBACK pfnEncodeModule, - CORINFO_RESOLVED_TOKEN * pResolvedToken) + CORINFO_RESOLVED_TOKEN * pResolvedToken, + BOOL fEncodeUsingResolvedTokenSpecStreams) { STANDARD_VM_CONTRACT; @@ -2379,7 +2380,8 @@ void CEECompileInfo::EncodeField( pSigBuilder, encodeContext, pfnEncodeModule, - pResolvedToken); + pResolvedToken, + fEncodeUsingResolvedTokenSpecStreams); COOPERATIVE_TRANSITION_END(); } diff --git a/src/vm/compile.h b/src/vm/compile.h index c7a2d06ce9..19bbac3228 100644 --- a/src/vm/compile.h +++ b/src/vm/compile.h @@ -281,8 +281,8 @@ class CEECompileInfo : public ICorCompileInfo SigBuilder *pSigBuilder, LPVOID encodeContext, ENCODEMODULE_CALLBACK pfnEncodeModule, - CORINFO_RESOLVED_TOKEN * pResolvedToken, - CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken, + CORINFO_RESOLVED_TOKEN *pResolvedToken, + CORINFO_RESOLVED_TOKEN *pConstrainedResolvedToken, BOOL fEncodeUsingResolvedTokenSpecStreams); virtual mdToken TryEncodeMethodAsToken(CORINFO_METHOD_HANDLE handle, @@ -296,7 +296,8 @@ class CEECompileInfo : public ICorCompileInfo SigBuilder *pSigBuilder, LPVOID encodeContext, ENCODEMODULE_CALLBACK pfnEncodeModule, - CORINFO_RESOLVED_TOKEN * pResolvedToken); + CORINFO_RESOLVED_TOKEN *pResolvedToken, + BOOL fEncodeUsingResolvedTokenSpecStreams); // Encode generic dictionary signature virtual void EncodeGenericSignature( diff --git a/src/vm/genericdict.cpp b/src/vm/genericdict.cpp index 70a4b8a627..4aca9e140b 100644 --- a/src/vm/genericdict.cpp +++ b/src/vm/genericdict.cpp @@ -690,6 +690,7 @@ Dictionary::PopulateEntry( switch (signatureKind) { case ENCODE_TYPE_HANDLE: kind = TypeHandleSlot; break; + case ENCODE_FIELD_HANDLE: kind = FieldDescSlot; break; case ENCODE_METHOD_HANDLE: kind = MethodDescSlot; break; case ENCODE_METHOD_ENTRY: kind = MethodEntrySlot; break; case ENCODE_VIRTUAL_ENTRY: kind = DispatchStubAddrSlot; break; @@ -1124,30 +1125,43 @@ Dictionary::PopulateEntry( case FieldDescSlot: { - TypeHandle th = ptr.GetTypeHandleThrowing( - pLookupModule, - &typeContext, - (nonExpansive ? ClassLoader::DontLoadTypes : ClassLoader::LoadTypes), - CLASS_LOADED, - FALSE, - NULL, - pZapSigContext); - if (th.IsNull()) + TypeHandle ownerType; + + if (isReadyToRunModule) { - _ASSERTE(nonExpansive); - return NULL; + FieldDesc* pField = ZapSig::DecodeField((Module*)pZapSigContext->pModuleContext, pZapSigContext->pInfoModule, ptr.GetPtr(), &typeContext, &ownerType); + _ASSERTE(!ownerType.IsNull()); + + if (!IsCompilationProcess()) + ownerType.AsMethodTable()->EnsureInstanceActive(); + + result = (CORINFO_GENERIC_HANDLE)pField; } - IfFailThrow(ptr.SkipExactlyOne()); + else + { + ownerType = ptr.GetTypeHandleThrowing( + pLookupModule, + &typeContext, + (nonExpansive ? ClassLoader::DontLoadTypes : ClassLoader::LoadTypes), + CLASS_LOADED, + FALSE, + NULL, + pZapSigContext); + if (ownerType.IsNull()) + { + _ASSERTE(nonExpansive); + return NULL; + } + IfFailThrow(ptr.SkipExactlyOne()); - DWORD fieldIndex; - IfFailThrow(ptr.GetData(&fieldIndex)); + DWORD fieldIndex; + IfFailThrow(ptr.GetData(&fieldIndex)); - if (!IsCompilationProcess()) - { - th.AsMethodTable()->EnsureInstanceActive(); - } + if (!IsCompilationProcess()) + ownerType.AsMethodTable()->EnsureInstanceActive(); - result = (CORINFO_GENERIC_HANDLE)th.AsMethodTable()->GetFieldDescByIndex(fieldIndex); + result = (CORINFO_GENERIC_HANDLE)ownerType.AsMethodTable()->GetFieldDescByIndex(fieldIndex); + } break; } diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp index b72eaf3826..59172fe220 100644 --- a/src/vm/jitinterface.cpp +++ b/src/vm/jitinterface.cpp @@ -3137,10 +3137,8 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr switch (entryKind) { case TypeHandleSlot: - { pResultLookup->lookupKind.runtimeLookupFlags = READYTORUN_FIXUP_TypeHandle; break; - } case MethodDescSlot: case MethodEntrySlot: @@ -3161,8 +3159,11 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr break; } - case DeclaringTypeHandleSlot: case FieldDescSlot: + pResultLookup->lookupKind.runtimeLookupFlags = READYTORUN_FIXUP_FieldHandle; + break; + + case DeclaringTypeHandleSlot: case ConstrainedMethodEntrySlot: ThrowHR(E_NOTIMPL); diff --git a/src/vm/zapsig.cpp b/src/vm/zapsig.cpp index 93b34db31e..c619610f42 100644 --- a/src/vm/zapsig.cpp +++ b/src/vm/zapsig.cpp @@ -836,7 +836,7 @@ MethodDesc *ZapSig::DecodeMethod(Module *pReferencingModule, Module *pInfoModule, PCCOR_SIGNATURE pBuffer, SigTypeContext *pContext, - TypeHandle * ppTH, /*=NULL*/ + TypeHandle *ppTH, /*=NULL*/ PCCOR_SIGNATURE *ppOwnerTypeSpecWithVars, /*=NULL*/ PCCOR_SIGNATURE *ppMethodSpecWithVars /*=NULL*/) { @@ -1013,7 +1013,20 @@ MethodDesc *ZapSig::DecodeMethod(Module *pReferencingModule, FieldDesc * ZapSig::DecodeField(Module *pReferencingModule, Module *pInfoModule, PCCOR_SIGNATURE pBuffer, - TypeHandle * ppTH /*=NULL*/) + TypeHandle *ppTH /*=NULL*/) +{ + STANDARD_VM_CONTRACT; + + SigTypeContext typeContext; // empty context is OK: encoding should not contain type variables. + + return DecodeField(pReferencingModule, pInfoModule, pBuffer, &typeContext, ppTH); +} + +FieldDesc * ZapSig::DecodeField(Module *pReferencingModule, + Module *pInfoModule, + PCCOR_SIGNATURE pBuffer, + SigTypeContext *pContext, + TypeHandle *ppTH /*=NULL*/) { CONTRACTL { @@ -1037,10 +1050,8 @@ FieldDesc * ZapSig::DecodeField(Module *pReferencingModule, ZapSig::Context zapSigContext(pInfoModule, pReferencingModule); ZapSig::Context * pZapSigContext = &zapSigContext; - SigTypeContext typeContext; // empty context is OK: encoding should not contain type variables. - pOwnerMT = sig.GetTypeHandleThrowing(pInfoModule, - &typeContext, + pContext, ClassLoader::LoadTypes, CLASS_LOADED, FALSE, @@ -1371,7 +1382,8 @@ void ZapSig::EncodeField( SigBuilder *pSigBuilder, LPVOID pEncodeModuleContext, ENCODEMODULE_CALLBACK pfnEncodeModule, - CORINFO_RESOLVED_TOKEN * pResolvedToken) + CORINFO_RESOLVED_TOKEN *pResolvedToken, + BOOL fEncodeUsingResolvedTokenSpecStreams) { CONTRACTL { @@ -1452,15 +1464,23 @@ void ZapSig::EncodeField( if (fieldFlags & ENCODE_FIELD_SIG_OwnerType) { - ZapSig zapSig(pInfoModule, pEncodeModuleContext, ZapSig::NormalTokens, - (EncodeModuleCallback) pfnEncodeModule, NULL); + if (fEncodeUsingResolvedTokenSpecStreams && pResolvedToken != NULL && pResolvedToken->pTypeSpec != NULL) + { + _ASSERTE(pResolvedToken->cbTypeSpec > 0); + pSigBuilder->AppendBlob((PVOID)pResolvedToken->pTypeSpec, pResolvedToken->cbTypeSpec); + } + else + { + ZapSig zapSig(pInfoModule, pEncodeModuleContext, ZapSig::NormalTokens, + (EncodeModuleCallback)pfnEncodeModule, NULL); - // - // Write class - // - BOOL fSuccess; - fSuccess = zapSig.GetSignatureForTypeHandle(pMT, pSigBuilder); - _ASSERTE(fSuccess); + // + // Write class + // + BOOL fSuccess; + fSuccess = zapSig.GetSignatureForTypeHandle(pMT, pSigBuilder); + _ASSERTE(fSuccess); + } } if ((fieldFlags & ENCODE_FIELD_SIG_IndexInsteadOfToken) == 0) diff --git a/src/vm/zapsig.h b/src/vm/zapsig.h index ef837ad2d2..258e821aa8 100644 --- a/src/vm/zapsig.h +++ b/src/vm/zapsig.h @@ -154,28 +154,39 @@ public: // fromModule is the module in which the type is defined. // pBuffer contains the signature encoding for the type. // level is the class load level (see classloadlevel.h) to which the type should be loaded - static TypeHandle DecodeType(Module *referencingModule, - Module *fromModule, - PCCOR_SIGNATURE pBuffer, - ClassLoadLevel level = CLASS_LOADED); - - static MethodDesc *DecodeMethod(Module *referencingModule, - Module *fromModule, - PCCOR_SIGNATURE pBuffer, - TypeHandle * ppTH = NULL); - - static MethodDesc *DecodeMethod(Module *referencingModule, - Module *fromModule, - PCCOR_SIGNATURE pBuffer, - SigTypeContext *pContext, - TypeHandle * ppTH = NULL, - PCCOR_SIGNATURE *ppOwnerTypeSpecWithVars = NULL, - PCCOR_SIGNATURE *ppMethodSpecWithVars = NULL); - - static FieldDesc *DecodeField(Module *referencingModule, - Module *fromModule, - PCCOR_SIGNATURE pBuffer, - TypeHandle * ppTH = NULL); + static TypeHandle DecodeType( + Module *referencingModule, + Module *fromModule, + PCCOR_SIGNATURE pBuffer, + ClassLoadLevel level = CLASS_LOADED); + + static MethodDesc *DecodeMethod( + Module *referencingModule, + Module *fromModule, + PCCOR_SIGNATURE pBuffer, + TypeHandle *ppTH = NULL); + + static MethodDesc *DecodeMethod( + Module *referencingModule, + Module *fromModule, + PCCOR_SIGNATURE pBuffer, + SigTypeContext *pContext, + TypeHandle *ppTH = NULL, + PCCOR_SIGNATURE *ppOwnerTypeSpecWithVars = NULL, + PCCOR_SIGNATURE *ppMethodSpecWithVars = NULL); + + static FieldDesc *DecodeField( + Module *referencingModule, + Module *fromModule, + PCCOR_SIGNATURE pBuffer, + TypeHandle *ppTH = NULL); + + static FieldDesc *DecodeField( + Module *pReferencingModule, + Module *pInfoModule, + PCCOR_SIGNATURE pBuffer, + SigTypeContext *pContext, + TypeHandle *ppTH = NULL); static BOOL EncodeMethod( MethodDesc *pMethod, @@ -184,8 +195,8 @@ public: LPVOID pReferencingModule, ENCODEMODULE_CALLBACK pfnEncodeModule, DEFINETOKEN_CALLBACK pfnDefineToken, - CORINFO_RESOLVED_TOKEN * pResolvedToken = NULL, - CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken = NULL, + CORINFO_RESOLVED_TOKEN *pResolvedToken = NULL, + CORINFO_RESOLVED_TOKEN *pConstrainedResolvedToken = NULL, BOOL fEncodeUsingResolvedTokenSpecStreams = FALSE); static void EncodeField( @@ -194,7 +205,8 @@ public: SigBuilder *pSigBuilder, LPVOID pReferencingModule, ENCODEMODULE_CALLBACK pfnEncodeModule, - CORINFO_RESOLVED_TOKEN * pResolvedToken = NULL); + CORINFO_RESOLVED_TOKEN *pResolvedToken = NULL, + BOOL fEncodeUsingResolvedTokenSpecStreams = FALSE); }; |