Merge pull request #6685 from RussKeldorph/test-native-log
[platform/upstream/coreclr.git] / src / vm / ilstubresolver.cpp
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 // 
5 // File: ILStubResolver.cpp
6 // 
7
8 //
9
10
11 #include "common.h"
12
13 #include "field.h"
14
15 // returns pointer to IL code
16 BYTE* ILStubResolver::GetCodeInfo(unsigned* pCodeSize, unsigned* pStackSize, CorInfoOptions* pOptions, unsigned* pEHSize)
17 {
18     CONTRACT(BYTE*)
19     {
20         STANDARD_VM_CHECK;
21         PRECONDITION(CheckPointer(pCodeSize));
22         PRECONDITION(CheckPointer(pStackSize));
23         PRECONDITION(CheckPointer(pOptions));
24         PRECONDITION(CheckPointer(pEHSize));
25         PRECONDITION(CheckPointer(m_pCompileTimeState));
26         POSTCONDITION(CheckPointer(RETVAL));
27     }
28     CONTRACT_END;
29
30 #ifndef DACCESS_COMPILE
31     CORINFO_METHOD_INFO methodInfo;    
32     getMethodInfoILMethodHeaderHelper(&m_pCompileTimeState->m_ILHeader, &methodInfo);
33
34     *pCodeSize = methodInfo.ILCodeSize;
35     *pStackSize = methodInfo.maxStack;
36     *pOptions = methodInfo.options;
37     *pEHSize = methodInfo.EHcount;
38     
39     RETURN methodInfo.ILCode;
40 #else // DACCESS_COMPILE
41     DacNotImpl();
42     RETURN NULL;
43 #endif // DACCESS_COMPILE
44 }
45
46 // static
47 LPCUTF8 ILStubResolver::GetStubClassName(MethodDesc* pMD)
48 {
49     CONTRACTL
50     {
51         MODE_ANY;
52         GC_NOTRIGGER;
53         NOTHROW;
54         SUPPORTS_DAC;
55         PRECONDITION(pMD->IsILStub());
56     }
57     CONTRACTL_END;
58
59     if (pMD->GetDomain()->IsSharedDomain())
60     {
61         return "DomainNeutralILStubClass";
62     }
63     else
64     {
65         return "DomainBoundILStubClass";
66     }
67 }
68
69 LPCUTF8 ILStubResolver::GetStubMethodName()
70 {
71     CONTRACTL
72     {
73         MODE_ANY;
74         GC_NOTRIGGER;
75         NOTHROW;
76     }
77     CONTRACTL_END;
78
79     switch (m_type)
80     {
81         case CLRToNativeInteropStub: return "IL_STUB_PInvoke";
82         case CLRToCOMInteropStub:    return "IL_STUB_CLRtoCOM";
83         case CLRToWinRTInteropStub:  return "IL_STUB_CLRtoWinRT";
84         case NativeToCLRInteropStub: return "IL_STUB_ReversePInvoke";
85         case COMToCLRInteropStub:    return "IL_STUB_COMtoCLR";
86         case WinRTToCLRInteropStub:  return "IL_STUB_WinRTtoCLR";
87 #ifdef FEATURE_ARRAYSTUB_AS_IL
88         case ArrayOpStub:            return "IL_STUB_Array";
89 #endif
90 #ifdef FEATURE_STUBS_AS_IL
91         case MulticastDelegateStub:  return "IL_STUB_MulticastDelegate_Invoke";
92         case UnboxingILStub:         return "IL_STUB_UnboxingStub";
93         case InstantiatingStub:      return "IL_STUB_InstantiatingStub";
94         case SecureDelegateStub:     return "IL_STUB_SecureDelegate_Invoke";
95 #endif
96         default:
97             UNREACHABLE_MSG("Unknown stub type");
98     }
99 }
100
101 void ILStubResolver::GetJitContext(SecurityControlFlags* pSecurityControlFlags,
102                                    TypeHandle* pTypeOwner)
103 {
104     CONTRACTL
105     {
106         STANDARD_VM_CHECK;
107         PRECONDITION(CheckPointer(pSecurityControlFlags));
108         PRECONDITION(CheckPointer(pTypeOwner));
109     }
110     CONTRACTL_END;
111
112     *pSecurityControlFlags = DynamicResolver::SkipVisibilityChecks;
113     *pTypeOwner = TypeHandle();
114 }
115
116 ChunkAllocator* ILStubResolver::GetJitMetaHeap()
117 {
118     LIMITED_METHOD_CONTRACT;
119     _ASSERTE(FALSE);
120     return NULL;
121 }
122
123 SigPointer 
124 ILStubResolver::GetLocalSig()
125 {
126     STANDARD_VM_CONTRACT;
127
128     return SigPointer(
129         m_pCompileTimeState->m_ILHeader.LocalVarSig, 
130         m_pCompileTimeState->m_ILHeader.cbLocalVarSig);
131 }
132
133 OBJECTHANDLE ILStubResolver::ConstructStringLiteral(mdToken token)
134 {
135     STANDARD_VM_CONTRACT;
136     _ASSERTE(FALSE);
137     return NULL;
138 }
139
140 BOOL ILStubResolver::IsValidStringRef(mdToken metaTok)
141 {
142     STANDARD_VM_CONTRACT;
143     _ASSERTE(FALSE);
144     return FALSE;
145 }
146
147 void ILStubResolver::ResolveToken(mdToken token, TypeHandle * pTH, MethodDesc ** ppMD, FieldDesc ** ppFD)
148 {        
149     STANDARD_VM_CONTRACT;
150
151     *pTH = NULL;
152     *ppMD = NULL;
153     *ppFD = NULL;
154
155     switch (TypeFromToken(token))
156     {
157     case mdtMethodDef:
158         {
159             MethodDesc* pMD = m_pCompileTimeState->m_tokenLookupMap.LookupMethodDef(token);
160             _ASSERTE(pMD);
161             *ppMD = pMD;
162             *pTH = TypeHandle(pMD->GetMethodTable());
163         }
164         break;
165
166     case mdtTypeDef:
167         {
168             TypeHandle typeHnd = m_pCompileTimeState->m_tokenLookupMap.LookupTypeDef(token);
169             _ASSERTE(!typeHnd.IsNull());
170             *pTH = typeHnd;
171         }
172         break;
173
174     case mdtFieldDef:
175         {
176             FieldDesc* pFD = m_pCompileTimeState->m_tokenLookupMap.LookupFieldDef(token);
177             _ASSERTE(pFD);
178             *ppFD = pFD;
179             *pTH = TypeHandle(pFD->GetEnclosingMethodTable());
180         }
181         break;
182
183     default:
184         UNREACHABLE_MSG("unexpected metadata token type");
185     }
186 }
187
188 //---------------------------------------------------------------------------------------
189 // 
190 SigPointer 
191 ILStubResolver::ResolveSignature(
192     mdToken token)
193 {
194     STANDARD_VM_CONTRACT;
195     CONSISTENCY_CHECK_MSG(token == TOKEN_ILSTUB_TARGET_SIG, "IL stubs do not support any other signature tokens!");
196
197     return m_pCompileTimeState->m_StubTargetMethodSig;
198 }
199
200 //---------------------------------------------------------------------------------------
201 // 
202 SigPointer 
203 ILStubResolver::ResolveSignatureForVarArg(
204     mdToken token)
205 {
206     STANDARD_VM_CONTRACT;
207     _ASSERTE(FALSE);
208     return SigPointer();
209 }
210
211 //---------------------------------------------------------------------------------------
212 // 
213 void ILStubResolver::GetEHInfo(unsigned EHnumber, CORINFO_EH_CLAUSE* clause)
214 {
215     CONTRACTL
216     {
217         STANDARD_VM_CHECK;
218         PRECONDITION(CheckPointer(m_pCompileTimeState));
219         PRECONDITION(CheckPointer(m_pCompileTimeState->m_ILHeader.EH));
220         PRECONDITION(EHnumber < m_pCompileTimeState->m_ILHeader.EH->EHCount());
221     }
222     CONTRACTL_END;
223    
224     COR_ILMETHOD_SECT_EH_CLAUSE_FAT ehClause;
225     const COR_ILMETHOD_SECT_EH_CLAUSE_FAT* ehInfo;
226     ehInfo = (COR_ILMETHOD_SECT_EH_CLAUSE_FAT*)m_pCompileTimeState->m_ILHeader.EH->EHClause(EHnumber, &ehClause);
227     clause->Flags = (CORINFO_EH_CLAUSE_FLAGS)ehInfo->GetFlags();
228     clause->TryOffset = ehInfo->GetTryOffset();
229     clause->TryLength = ehInfo->GetTryLength();
230     clause->HandlerOffset = ehInfo->GetHandlerOffset();
231     clause->HandlerLength = ehInfo->GetHandlerLength();
232     clause->ClassToken = ehInfo->GetClassToken();
233     clause->FilterOffset = ehInfo->GetFilterOffset();
234 }
235
236 bool ILStubResolver::IsNativeToCLRInteropStub()
237 {
238     return (m_type == NativeToCLRInteropStub);
239 }
240
241 void ILStubResolver::SetStubType(ILStubType stubType)
242 {
243     LIMITED_METHOD_CONTRACT;
244     m_type = stubType;
245 }
246
247 void ILStubResolver::SetStubMethodDesc(MethodDesc* pStubMD)
248 {
249     LIMITED_METHOD_CONTRACT;
250     m_pStubMD = PTR_MethodDesc(pStubMD);
251 }
252
253 void ILStubResolver::SetStubTargetMethodDesc(MethodDesc* pStubTargetMD)
254 {
255     LIMITED_METHOD_CONTRACT;
256     m_pStubTargetMD = PTR_MethodDesc(pStubTargetMD);
257 }
258
259
260 //---------------------------------------------------------------------------------------
261 // 
262 void 
263 ILStubResolver::SetStubTargetMethodSig(
264     PCCOR_SIGNATURE pStubTargetMethodSig, 
265     DWORD           cbStubTargetSigLength)
266 {
267     CONTRACTL
268     {
269         STANDARD_VM_CHECK;
270         PRECONDITION(CheckPointer(m_pCompileTimeState));
271     }
272     CONTRACTL_END;
273
274     NewHolder<BYTE> pNewSig = new BYTE[cbStubTargetSigLength];
275     
276     memcpyNoGCRefs((void *)pNewSig, pStubTargetMethodSig, cbStubTargetSigLength);
277     
278     m_pCompileTimeState->m_StubTargetMethodSig = SigPointer(pNewSig, cbStubTargetSigLength);
279     pNewSig.SuppressRelease();
280 }
281
282 //---------------------------------------------------------------------------------------
283 // 
284 MethodDesc * 
285 ILStubResolver::GetStubTargetMethodDesc()
286 {
287     LIMITED_METHOD_CONTRACT;
288     return m_pStubTargetMD;
289 }
290
291 MethodDesc* ILStubResolver::GetStubMethodDesc()
292 {
293     LIMITED_METHOD_CONTRACT;
294     return m_pStubMD;
295 }
296
297 ILStubResolver::ILStubResolver() : 
298     m_pCompileTimeState(dac_cast<PTR_CompileTimeState>(ILNotYetGenerated)),
299     m_pStubMD(dac_cast<PTR_MethodDesc>(nullptr)),
300     m_pStubTargetMD(dac_cast<PTR_MethodDesc>(nullptr)),
301     m_type(Unassigned),
302     m_dwJitFlags(0)
303 {
304     LIMITED_METHOD_CONTRACT;
305     
306 }
307
308 //---------------------------------------------------------------------------------------
309 // 
310 COR_ILMETHOD_DECODER * 
311 ILStubResolver::AllocGeneratedIL(
312     size_t cbCode, 
313     DWORD  cbLocalSig, 
314     UINT   maxStack)
315 {
316     STANDARD_VM_CONTRACT;
317
318 #if !defined(DACCESS_COMPILE)
319     _ASSERTE(0 != cbCode);
320
321     NewHolder<BYTE>             pNewILCodeBuffer        = NULL;
322     NewHolder<BYTE>             pNewLocalSig            = NULL;
323     NewHolder<CompileTimeState> pNewCompileTimeState    = NULL;
324
325     pNewCompileTimeState = (CompileTimeState *)new BYTE[sizeof(CompileTimeState)];
326     memset(pNewCompileTimeState, 0, sizeof(CompileTimeState));
327
328     pNewILCodeBuffer = new BYTE[cbCode];
329
330     if (0 != cbLocalSig)
331     {
332         pNewLocalSig = new BYTE[cbLocalSig];
333     }
334
335     COR_ILMETHOD_DECODER* pILHeader = &pNewCompileTimeState->m_ILHeader;    
336
337     pILHeader->Flags         = 0;
338     pILHeader->CodeSize      = (DWORD)cbCode;
339     pILHeader->MaxStack      = maxStack;
340     pILHeader->EH            = 0;
341     pILHeader->Sect          = 0;
342     pILHeader->Code          = pNewILCodeBuffer;
343     pILHeader->LocalVarSig   = pNewLocalSig;
344     pILHeader->cbLocalVarSig = cbLocalSig;
345
346 #ifdef _DEBUG
347     LPVOID pPrevCompileTimeState =
348 #endif // _DEBUG
349     FastInterlockExchangePointer(&m_pCompileTimeState, pNewCompileTimeState.GetValue());
350     CONSISTENCY_CHECK(ILNotYetGenerated == (UINT_PTR)pPrevCompileTimeState);
351
352     pNewLocalSig.SuppressRelease();
353     pNewILCodeBuffer.SuppressRelease();
354     pNewCompileTimeState.SuppressRelease();
355
356     return pILHeader;
357
358 #else  // DACCESS_COMPILE
359     DacNotImpl();
360     return NULL;
361
362 #endif // DACCESS_COMPILE
363 } // ILStubResolver::AllocGeneratedIL
364
365 //---------------------------------------------------------------------------------------
366 // 
367 COR_ILMETHOD_DECODER* ILStubResolver::GetILHeader()
368 {
369     CONTRACTL
370     {
371         MODE_ANY;
372         THROWS;
373         GC_NOTRIGGER;
374         PRECONDITION(CheckPointer(m_pCompileTimeState));
375     }
376     CONTRACTL_END;
377
378     return &m_pCompileTimeState->m_ILHeader;
379 }
380
381 COR_ILMETHOD_SECT_EH* ILStubResolver::AllocEHSect(size_t nClauses)
382 {
383     STANDARD_VM_CONTRACT;
384
385     if (nClauses >= 1)
386     {
387         size_t cbSize = sizeof(COR_ILMETHOD_SECT_EH)
388                         - sizeof(IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT)
389                         + (nClauses * sizeof(IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT));
390         m_pCompileTimeState->m_pEHSect = (COR_ILMETHOD_SECT_EH*) new BYTE[cbSize];
391         CONSISTENCY_CHECK(NULL == m_pCompileTimeState->m_ILHeader.EH);
392         m_pCompileTimeState->m_ILHeader.EH = m_pCompileTimeState->m_pEHSect;
393         return m_pCompileTimeState->m_pEHSect;
394     }
395     else
396     {
397         return NULL;
398     }
399 }
400
401
402 void ILStubResolver::FreeCompileTimeState()
403 {
404     CONTRACTL
405     {
406         NOTHROW;
407         GC_NOTRIGGER;
408         MODE_ANY;
409     }
410     CONTRACTL_END;
411
412     if ((ILNotYetGenerated == dac_cast<TADDR>(m_pCompileTimeState)) || 
413         (ILGeneratedAndFreed == dac_cast<TADDR>(m_pCompileTimeState)))
414     {
415         return;
416     }
417
418     ClearCompileTimeState(ILGeneratedAndFreed);
419 }
420
421 //---------------------------------------------------------------------------------------
422 // 
423 void 
424 ILStubResolver::ClearCompileTimeState(CompileTimeStatePtrSpecialValues newState)
425 {
426     CONTRACTL
427     {
428         NOTHROW;
429         GC_NOTRIGGER;
430         MODE_ANY;
431     }
432     CONTRACTL_END;
433
434     //
435     // See allocations in AllocGeneratedIL and SetStubTargetMethodSig
436     //
437     
438     COR_ILMETHOD_DECODER * pILHeader = &m_pCompileTimeState->m_ILHeader;    
439
440     CONSISTENCY_CHECK(NULL != pILHeader->Code);
441     delete[] pILHeader->Code;
442
443     if (NULL != pILHeader->LocalVarSig)
444     {
445         delete[] pILHeader->LocalVarSig;
446     }
447
448     if (!m_pCompileTimeState->m_StubTargetMethodSig.IsNull())
449     {
450         delete[] m_pCompileTimeState->m_StubTargetMethodSig.GetPtr();
451     }
452
453     if (NULL != m_pCompileTimeState->m_pEHSect)
454     {
455         delete[] m_pCompileTimeState->m_pEHSect;
456     }
457
458     delete m_pCompileTimeState;
459
460     FastInterlockExchangePointer(&m_pCompileTimeState, dac_cast<PTR_CompileTimeState>((TADDR)newState));
461 } // ILStubResolver::ClearCompileTimeState
462
463 //---------------------------------------------------------------------------------------
464 // 
465 void 
466 ILStubResolver::SetTokenLookupMap(
467     TokenLookupMap * pMap)
468 {
469     CONTRACTL
470     {
471         STANDARD_VM_CHECK;
472         PRECONDITION(CheckPointer(m_pCompileTimeState));
473     }
474     CONTRACTL_END;
475
476     // run copy ctor
477     new (&m_pCompileTimeState->m_tokenLookupMap) TokenLookupMap(pMap);
478 }
479
480 bool ILStubResolver::IsCompiled()
481 {
482     LIMITED_METHOD_CONTRACT;
483     return (dac_cast<TADDR>(m_pCompileTimeState) == ILGeneratedAndFreed);
484 }
485
486 bool ILStubResolver::IsILGenerated()
487 {
488     return (dac_cast<TADDR>(m_pCompileTimeState) != ILNotYetGenerated);
489 }
490
491 void ILStubResolver::SetJitFlags(DWORD dwFlags)
492 {
493     LIMITED_METHOD_CONTRACT;
494     m_dwJitFlags = dwFlags;
495 }
496
497 DWORD ILStubResolver::GetJitFlags()
498 {
499     LIMITED_METHOD_CONTRACT;
500     return m_dwJitFlags;
501 }
502
503 // static
504 void ILStubResolver::StubGenFailed(ILStubResolver* pResolver)
505 {
506     CONTRACTL
507     {
508         NOTHROW;
509         GC_NOTRIGGER;
510         MODE_ANY;
511     }
512     CONTRACTL_END;
513
514     if ((ILNotYetGenerated == dac_cast<TADDR>(pResolver->m_pCompileTimeState)) || 
515         (ILGeneratedAndFreed == dac_cast<TADDR>(pResolver->m_pCompileTimeState)))
516     {
517         return;
518     }
519
520     pResolver->ClearCompileTimeState(ILNotYetGenerated);
521 }