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.
5 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
10 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
11 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
20 #error "This should be included only for x86"
21 #endif // _TARGET_X86_
23 #if defined(_TARGET_UNIX_)
24 int Compiler::mapRegNumToDwarfReg(regNumber reg)
26 int dwarfReg = DWARF_REG_ILLEGAL;
32 #endif // _TARGET_UNIX_
34 void Compiler::unwindBegProlog()
38 void Compiler::unwindEndProlog()
42 void Compiler::unwindBegEpilog()
46 void Compiler::unwindEndEpilog()
50 void Compiler::unwindPush(regNumber reg)
54 void Compiler::unwindAllocStack(unsigned size)
58 void Compiler::unwindSetFrameReg(regNumber reg, unsigned offset)
62 void Compiler::unwindSaveReg(regNumber reg, unsigned offset)
66 //------------------------------------------------------------------------
67 // Compiler::unwindReserve: Ask the VM to reserve space for the unwind information
68 // for the function and all its funclets. Called once, just before asking the VM
69 // for memory and emitting the generated code. Calls unwindReserveFunc() to handle
70 // the main function and each of the funclets, in turn.
72 void Compiler::unwindReserve()
74 #if FEATURE_EH_FUNCLETS
75 assert(!compGeneratingProlog);
76 assert(!compGeneratingEpilog);
78 assert(compFuncInfoCount > 0);
79 for (unsigned funcIdx = 0; funcIdx < compFuncInfoCount; funcIdx++)
81 unwindReserveFunc(funGetFunc(funcIdx));
86 //------------------------------------------------------------------------
87 // Compiler::unwindEmit: Report all the unwind information to the VM.
90 // pHotCode - Pointer to the beginning of the memory with the function and funclet hot code.
91 // pColdCode - Pointer to the beginning of the memory with the function and funclet cold code.
93 void Compiler::unwindEmit(void* pHotCode, void* pColdCode)
95 #if FEATURE_EH_FUNCLETS
96 assert(!compGeneratingProlog);
97 assert(!compGeneratingEpilog);
99 assert(compFuncInfoCount > 0);
100 for (unsigned funcIdx = 0; funcIdx < compFuncInfoCount; funcIdx++)
102 unwindEmitFunc(funGetFunc(funcIdx), pHotCode, pColdCode);
104 #endif // FEATURE_EH_FUNCLETS
107 #if FEATURE_EH_FUNCLETS
108 //------------------------------------------------------------------------
109 // Compiler::unwindReserveFunc: Reserve the unwind information from the VM for a
110 // given main function or funclet.
113 // func - The main function or funclet to reserve unwind info for.
115 void Compiler::unwindReserveFunc(FuncInfoDsc* func)
117 unwindReserveFuncHelper(func, true);
119 if (fgFirstColdBlock != nullptr)
121 unwindReserveFuncHelper(func, false);
125 //------------------------------------------------------------------------
126 // Compiler::unwindReserveFuncHelper: Reserve the unwind information from the VM for a
127 // given main function or funclet, for either the hot or the cold section.
130 // func - The main function or funclet to reserve unwind info for.
131 // isHotCode - 'true' to reserve the hot section, 'false' to reserve the cold section.
133 void Compiler::unwindReserveFuncHelper(FuncInfoDsc* func, bool isHotCode)
135 BOOL isFunclet = (func->funKind != FUNC_ROOT);
136 BOOL isColdCode = isHotCode ? FALSE : TRUE;
138 eeReserveUnwindInfo(isFunclet, isColdCode, sizeof(UNWIND_INFO));
141 //------------------------------------------------------------------------
142 // Compiler::unwindEmitFunc: Report the unwind information to the VM for a
143 // given main function or funclet. Reports the hot section, then the cold
144 // section if necessary.
147 // func - The main function or funclet to reserve unwind info for.
148 // pHotCode - Pointer to the beginning of the memory with the function and funclet hot code.
149 // pColdCode - Pointer to the beginning of the memory with the function and funclet cold code.
151 void Compiler::unwindEmitFunc(FuncInfoDsc* func, void* pHotCode, void* pColdCode)
153 // Verify that the JIT enum is in sync with the JIT-EE interface enum
154 static_assert_no_msg(FUNC_ROOT == (FuncKind)CORJIT_FUNC_ROOT);
155 static_assert_no_msg(FUNC_HANDLER == (FuncKind)CORJIT_FUNC_HANDLER);
156 static_assert_no_msg(FUNC_FILTER == (FuncKind)CORJIT_FUNC_FILTER);
158 unwindEmitFuncHelper(func, pHotCode, pColdCode, true);
160 if (pColdCode != nullptr)
162 unwindEmitFuncHelper(func, pHotCode, pColdCode, false);
166 //------------------------------------------------------------------------
167 // Compiler::unwindEmitFuncHelper: Report the unwind information to the VM for a
168 // given main function or funclet, for either the hot or cold section.
171 // func - The main function or funclet to reserve unwind info for.
172 // pHotCode - Pointer to the beginning of the memory with the function and funclet hot code.
173 // pColdCode - Pointer to the beginning of the memory with the function and funclet cold code.
174 // Ignored if 'isHotCode' is true.
175 // isHotCode - 'true' to report the hot section, 'false' to report the cold section.
177 void Compiler::unwindEmitFuncHelper(FuncInfoDsc* func, void* pHotCode, void* pColdCode, bool isHotCode)
179 UNATIVE_OFFSET startOffset;
180 UNATIVE_OFFSET endOffset;
184 emitLocation* startLoc;
185 emitLocation* endLoc;
187 unwindGetFuncLocations(func, true, &startLoc, &endLoc);
189 if (startLoc == nullptr)
195 startOffset = startLoc->CodeOffset(genEmitter);
198 if (endLoc == nullptr)
200 endOffset = info.compNativeCodeSize;
204 endOffset = endLoc->CodeOffset(genEmitter);
209 emitLocation* coldStartLoc;
210 emitLocation* coldEndLoc;
212 assert(fgFirstColdBlock != nullptr);
213 assert(func->funKind == FUNC_ROOT); // No splitting of funclets.
215 unwindGetFuncLocations(func, false, &coldStartLoc, &coldEndLoc);
217 if (coldStartLoc == nullptr)
223 startOffset = coldStartLoc->CodeOffset(genEmitter);
226 if (coldEndLoc == nullptr)
228 endOffset = info.compNativeCodeSize;
232 endOffset = coldEndLoc->CodeOffset(genEmitter);
236 // Adjust for cold or hot code:
237 // 1. The VM doesn't want the cold code pointer unless this is cold code.
238 // 2. The startOffset and endOffset need to be from the base of the hot section for hot code
239 // and from the base of the cold section for cold code
243 assert(endOffset <= info.compTotalHotCodeSize);
248 assert(startOffset >= info.compTotalHotCodeSize);
249 startOffset -= info.compTotalHotCodeSize;
250 endOffset -= info.compTotalHotCodeSize;
253 UNWIND_INFO unwindInfo;
255 unwindInfo.FunctionLength = (ULONG)(endOffset - startOffset);
257 eeAllocUnwindInfo((BYTE*)pHotCode, (BYTE*)pColdCode, startOffset, endOffset, sizeof(UNWIND_INFO),
258 (BYTE*)&unwindInfo, (CorJitFuncKind)func->funKind);
260 #endif // FEATURE_EH_FUNCLETS