summaryrefslogtreecommitdiff
path: root/src/vm/zapsig.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/zapsig.h')
-rw-r--r--src/vm/zapsig.h213
1 files changed, 213 insertions, 0 deletions
diff --git a/src/vm/zapsig.h b/src/vm/zapsig.h
new file mode 100644
index 0000000000..258e821aa8
--- /dev/null
+++ b/src/vm/zapsig.h
@@ -0,0 +1,213 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+// ---------------------------------------------------------------------------
+// zapsig.h
+// ---------------------------------------------------------------------------
+//
+// This module contains helper functions used to encode and manipulate
+// signatures for the zapper (ngen).
+//
+
+// ---------------------------------------------------------------------------
+
+
+#ifndef ZAPSIG_H
+#define ZAPSIG_H
+
+#include "common.h"
+
+//define function pointer type: EncodeModuleCallback
+//
+typedef DWORD (*EncodeModuleCallback)(void* pModuleContext, Module *pReferencedModule);
+enum {
+ // return value when EncodeModule fails
+ ENCODE_MODULE_FAILED = 0xffffffff,
+};
+
+//define function pointer type: TokenDefinitionCallback
+//
+typedef void (*TokenDefinitionCallback)(void* pModuleContext, Module *pReferencedModule, DWORD index, mdToken* refToken);
+
+class ZapSig
+{
+public:
+ enum ExternalTokens
+ {
+ IllegalValue,
+ NormalTokens,
+ IbcTokens
+ };
+
+ struct Context
+ {
+ Module * pInfoModule; // The tokens in this ZapSig are expressed relative to context.pInfoModule
+ void * pModuleContext; // This is a code:Module* when we are resolving Ngen fixups or doing an Ibc Profiling run
+ // and is a code:ZapImportTable* when we are running ngen
+ ExternalTokens externalTokens; // When we see a ELEMENT_TYPE_MODULE_ZAPSIG this tells us what type of token follows.
+
+ Module * GetZapSigModule() const { return (Module*) pModuleContext; }
+
+ Context(
+ Module* _pInfoModule,
+ void* _pModuleContext, ExternalTokens _externalTokens)
+ : pInfoModule(_pInfoModule),
+ pModuleContext(_pModuleContext),
+ externalTokens(_externalTokens)
+ { LIMITED_METHOD_CONTRACT; _ASSERTE(externalTokens != IllegalValue); }
+
+ Context(
+ Module* _pInfoModule,
+ Module* _pZapSigModule)
+ : pInfoModule(_pInfoModule),
+ pModuleContext((void*) _pZapSigModule),
+ externalTokens(NormalTokens)
+ { }
+ };
+
+public:
+
+ ZapSig(
+ Module * _pInfoModule,
+ void * _pModuleContext,
+ ExternalTokens _externalTokens,
+ EncodeModuleCallback _pfnEncodeModule,
+ TokenDefinitionCallback _pfnTokenDefinition)
+
+ : context(_pInfoModule, _pModuleContext, _externalTokens),
+ pfnEncodeModule(_pfnEncodeModule),
+ pfnTokenDefinition(_pfnTokenDefinition)
+ {}
+
+#ifdef FEATURE_PREJIT
+
+ // Instance methods
+
+ // Create a signature for a typeHandle
+ // It can be decoded using MetaSig::GetTypeHandleThrowing
+ // The tokens are espressed relative to this->pInfoModule
+ // When (handle.GetModule() != this->pInfoModule), we escape
+ // the signature with ELEMENT_TYPE_MODULE_ZAPSIG <id-num>
+ // followed by a <token> to encode a temporary change of module
+ // For Ibc Signatures the <token> is one of the ibc defined tokens
+ // For Ngen Fixup signatures the <token> is for the external module
+ //
+ BOOL GetSignatureForTypeHandle(TypeHandle typeHandle,
+ SigBuilder * pSigBuilder);
+
+ // Static methods
+
+ // Compare a type handle with a signature whose tokens are resolved with respect to pModule
+ // pZapSigContext is used to resolve ELEMENT_TYPE_MODULE_ZAPSIG encodings
+ static BOOL CompareSignatureToTypeHandle(PCCOR_SIGNATURE pSig,
+ Module* pModule,
+ TypeHandle handle,
+ const ZapSig::Context * pZapSigContext);
+
+ // Compare a type handle with a tagged pointer. Ensure that the common path is inlined into the caller.
+ static FORCEINLINE BOOL CompareTaggedPointerToTypeHandle(Module * pModule, TADDR addr, TypeHandle handle)
+ {
+ WRAPPER_NO_CONTRACT;
+ if (handle.AsTAddr() == addr)
+ return TRUE;
+ if (!CORCOMPILE_IS_POINTER_TAGGED(addr))
+ return FALSE;
+ return CompareFixupToTypeHandle(pModule, addr, handle);
+ }
+
+ static BOOL CompareFixupToTypeHandle(Module * pModule, TADDR fixup, TypeHandle handle);
+
+ static BOOL CompareTypeHandleFieldToTypeHandle(TypeHandle *pTypeHnd, TypeHandle typeHnd2);
+
+private:
+ BOOL GetSignatureForTypeDesc(TypeDesc * desc, SigBuilder * pSigBuilder);
+
+ // Returns element type when the typeHandle can be encoded using
+ // using a single CorElementType value
+ // This includes using ELEMENT_TYPE_CANON_ZAPSIG for the System.__Canon type
+ //
+ static CorElementType TryEncodeUsingShortcut(/* in */ MethodTable * pMT);
+
+#endif // FEATURE_PREJIT
+
+private:
+
+ ZapSig::Context context;
+
+ EncodeModuleCallback pfnEncodeModule; // Function Pointer to the EncodeModuleHelper
+ TokenDefinitionCallback pfnTokenDefinition; // Function Pointer to the DefineTokenHelper
+
+public:
+ //--------------------------------------------------------------------
+ // Static helper encode/decode helper methods
+
+ static Module *DecodeModuleFromIndexes(Module *fromModule,
+ DWORD assemblyIndex,
+ DWORD moduleIndex);
+
+ static Module *DecodeModuleFromIndexesIfLoaded(Module *fromModule,
+ DWORD assemblyIndex,
+ DWORD moduleIndex);
+
+ // referencingModule is the module that references the type.
+ // 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 FieldDesc *DecodeField(
+ Module *pReferencingModule,
+ Module *pInfoModule,
+ PCCOR_SIGNATURE pBuffer,
+ SigTypeContext *pContext,
+ TypeHandle *ppTH = NULL);
+
+ static BOOL EncodeMethod(
+ MethodDesc *pMethod,
+ Module *pInfoModule,
+ SigBuilder *pSigBuilder,
+ LPVOID pReferencingModule,
+ ENCODEMODULE_CALLBACK pfnEncodeModule,
+ DEFINETOKEN_CALLBACK pfnDefineToken,
+ CORINFO_RESOLVED_TOKEN *pResolvedToken = NULL,
+ CORINFO_RESOLVED_TOKEN *pConstrainedResolvedToken = NULL,
+ BOOL fEncodeUsingResolvedTokenSpecStreams = FALSE);
+
+ static void EncodeField(
+ FieldDesc *pField,
+ Module *pInfoModule,
+ SigBuilder *pSigBuilder,
+ LPVOID pReferencingModule,
+ ENCODEMODULE_CALLBACK pfnEncodeModule,
+ CORINFO_RESOLVED_TOKEN *pResolvedToken = NULL,
+ BOOL fEncodeUsingResolvedTokenSpecStreams = FALSE);
+
+};
+
+#endif // ZAPGSIG_H