@@ -40,7 +40,7 @@ protected override void OnMarked(NodeFactory factory)
4040 public int [ ] CalculateFuncletOffsets ( NodeFactory factory )
4141 {
4242 int coldCodeUnwindInfoCount = 0 ;
43- if ( _methodNode . GetColdCodeNode ( ) != null )
43+ if ( _methodNode . ColdCodeNode != null )
4444 {
4545 coldCodeUnwindInfoCount = _methodNode . ColdFrameInfos . Length ;
4646 }
@@ -68,7 +68,7 @@ public int[] CalculateFuncletOffsets(NodeFactory factory)
6868 }
6969 }
7070
71- if ( _methodNode . GetColdCodeNode ( ) != null )
71+ if ( _methodNode . ColdCodeNode != null )
7272 {
7373 // TODO: Take a look at deduplicatedResult
7474 for ( int frameInfoIndex = 0 ; frameInfoIndex < _methodNode . ColdFrameInfos . Length ; frameInfoIndex ++ )
@@ -156,104 +156,68 @@ private IEnumerable<GCInfoComponent> EncodeDataCore(NodeFactory factory)
156156 {
157157 TargetArchitecture targetArch = factory . Target . Architecture ;
158158
159- for ( int frameInfoIndex = 0 ; frameInfoIndex < _methodNode . FrameInfos . Length ; frameInfoIndex ++ )
159+ int numHotFrameInfos = _methodNode . FrameInfos . Length ;
160+ int numFrameInfos = numHotFrameInfos ;
161+ if ( _methodNode . ColdCodeNode != null )
160162 {
161- byte [ ] unwindInfo = _methodNode . FrameInfos [ frameInfoIndex ] . BlobData ;
162-
163- if ( targetArch == TargetArchitecture . X64 )
164- {
165- // On Amd64, patch the first byte of the unwind info by setting the flags to EHANDLER | UHANDLER
166- // as that's what CoreCLR does (zapcode.cpp, ZapUnwindData::Save).
167- const byte UNW_FLAG_EHANDLER = 1 ;
168- const byte UNW_FLAG_UHANDLER = 2 ;
169- const byte FlagsShift = 3 ;
163+ numFrameInfos += _methodNode . ColdFrameInfos . Length ;
164+ }
170165
171- unwindInfo [ 0 ] |= ( byte ) ( ( UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER ) << FlagsShift ) ;
172- }
173- else if ( ( targetArch == TargetArchitecture . ARM ) || ( targetArch == TargetArchitecture . ARM64 ) || ( targetArch == TargetArchitecture . LoongArch64 ) )
166+ const byte UNW_FLAG_EHANDLER = 1 ;
167+ const byte UNW_FLAG_UHANDLER = 2 ;
168+ const byte UNW_FLAG_CHAININFO = 4 ;
169+ const byte FlagsShift = 3 ;
170+
171+ for ( int frameInfoIndex = 0 ; frameInfoIndex < numFrameInfos ; frameInfoIndex ++ )
172+ {
173+ FrameInfo frameInfo = ( frameInfoIndex >= numHotFrameInfos ) ?
174+ _methodNode . ColdFrameInfos [ frameInfoIndex - numHotFrameInfos ] :
175+ _methodNode . FrameInfos [ frameInfoIndex ] ;
176+ byte [ ] unwindInfo = frameInfo . BlobData ;
177+ if ( unwindInfo == null )
174178 {
175- // Set the 'X' bit to indicate that there is a personality routine associated with this method
176- unwindInfo [ 2 ] |= 1 << 4 ;
179+ // Chain unwind info
180+ byte [ ] header = new byte [ 4 ] ;
181+ int i = 0 ;
182+ header [ i ++ ] = 1 + ( UNW_FLAG_CHAININFO << FlagsShift ) ; // Version = 1, UNW_FLAG_CHAININFO
183+ header [ i ++ ] = 0 ; // SizeOfProlog = 0
184+ header [ i ++ ] = 0 ; // CountOfCode = 0
185+ header [ i ++ ] = _methodNode . FrameInfos [ 0 ] . BlobData [ 3 ] ; // Copying frame and frame offset from main function
186+ yield return new GCInfoComponent ( header ) ;
187+ yield return new GCInfoComponent ( _methodNode , 0 ) ;
188+ yield return new GCInfoComponent ( _methodNode , _methodNode . Size ) ;
189+ // TODO: Is this correct?
190+ yield return new GCInfoComponent ( factory . RuntimeFunctionsGCInfo . StartSymbol , this . OffsetFromBeginningOfArray ) ;
177191 }
178-
179- yield return new GCInfoComponent ( unwindInfo ) ;
180-
181- if ( targetArch != TargetArchitecture . X86 )
192+ else
182193 {
183- bool isFilterFunclet = ( _methodNode . FrameInfos [ frameInfoIndex ] . Flags & FrameInfoFlags . Filter ) != 0 ;
184- ISymbolNode personalityRoutine = ( isFilterFunclet ? factory . FilterFuncletPersonalityRoutine : factory . PersonalityRoutine ) ;
185- int codeDelta = 0 ;
186- if ( targetArch == TargetArchitecture . ARM )
194+ if ( targetArch == TargetArchitecture . X64 )
187195 {
188- // THUMB_CODE
189- codeDelta = 1 ;
196+ // On Amd64, patch the first byte of the unwind info by setting the flags to EHANDLER | UHANDLER
197+ // as that's what CoreCLR does (zapcode.cpp, ZapUnwindData::Save).
198+ unwindInfo [ 0 ] |= ( byte ) ( ( UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER ) << FlagsShift ) ;
190199 }
191- yield return new GCInfoComponent ( personalityRoutine , codeDelta ) ;
192- }
193-
194- if ( frameInfoIndex == 0 && _methodNode . GCInfo != null )
195- {
196- yield return new GCInfoComponent ( _methodNode . GCInfo ) ;
197- }
198- }
199- #if READYTORUN
200- if ( _methodNode . GetColdCodeNode ( ) != null )
201- {
202- for ( int frameInfoIndex = 0 ; frameInfoIndex < _methodNode . ColdFrameInfos . Length ; frameInfoIndex ++ )
203- {
204- byte [ ] unwindInfo = _methodNode . ColdFrameInfos [ frameInfoIndex ] . BlobData ;
205-
206- if ( unwindInfo == null )
200+ else if ( ( targetArch == TargetArchitecture . ARM ) || ( targetArch == TargetArchitecture . ARM64 ) || ( targetArch == TargetArchitecture . LoongArch64 ) )
207201 {
208- // Chain unwind info
209- byte [ ] header = new byte [ 4 ] ;
210- int i = 0 ;
211- header [ i ++ ] = 1 + ( 4 << 3 ) ; // Version = 1, UNW_FLAG_CHAININFO
212- header [ i ++ ] = 0 ; // SizeOfProlog = 0
213- header [ i ++ ] = 0 ; // CountOfCode = 0
214- header [ i ++ ] = _methodNode . FrameInfos [ 0 ] . BlobData [ 3 ] ; // Copying frame and frame offset from main function
215- yield return new GCInfoComponent ( header ) ;
216- yield return new GCInfoComponent ( _methodNode , 0 ) ;
217- yield return new GCInfoComponent ( _methodNode , _methodNode . Size ) ;
218- // TODO: Is this correct?
219- yield return new GCInfoComponent ( factory . RuntimeFunctionsGCInfo . StartSymbol , this . OffsetFromBeginningOfArray ) ;
202+ // Set the 'X' bit to indicate that there is a personality routine associated with this method
203+ unwindInfo [ 2 ] |= 1 << 4 ;
220204 }
221- else
222- {
223- if ( targetArch == TargetArchitecture . X64 )
224- {
225- // On Amd64, patch the first byte of the unwind info by setting the flags to EHANDLER | UHANDLER
226- // as that's what CoreCLR does (zapcode.cpp, ZapUnwindData::Save).
227- const byte UNW_FLAG_EHANDLER = 1 ;
228- const byte UNW_FLAG_UHANDLER = 2 ;
229- const byte FlagsShift = 3 ;
230205
231- unwindInfo [ 0 ] |= ( byte ) ( ( UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER ) << FlagsShift ) ;
232- }
233- else if ( ( targetArch == TargetArchitecture . ARM ) || ( targetArch == TargetArchitecture . ARM64 ) )
234- {
235- // Set the 'X' bit to indicate that there is a personality routine associated with this method
236- unwindInfo [ 2 ] |= 1 << 4 ;
237- }
206+ yield return new GCInfoComponent ( unwindInfo ) ;
238207
239- yield return new GCInfoComponent ( unwindInfo ) ;
208+ if ( targetArch != TargetArchitecture . X86 )
209+ {
210+ bool isFilterFunclet = ( frameInfo . Flags & FrameInfoFlags . Filter ) != 0 ;
211+ ISymbolNode personalityRoutine = ( isFilterFunclet ? factory . FilterFuncletPersonalityRoutine : factory . PersonalityRoutine ) ;
212+ yield return new GCInfoComponent ( personalityRoutine , factory . Target . CodeDelta ) ;
213+ }
240214
241- if ( targetArch != TargetArchitecture . X86 )
242- {
243- bool isFilterFunclet = ( _methodNode . ColdFrameInfos [ frameInfoIndex ] . Flags & FrameInfoFlags . Filter ) != 0 ;
244- ISymbolNode personalityRoutine = ( isFilterFunclet ? factory . FilterFuncletPersonalityRoutine : factory . PersonalityRoutine ) ;
245- int codeDelta = 0 ;
246- if ( targetArch == TargetArchitecture . ARM )
247- {
248- // THUMB_CODE
249- codeDelta = 1 ;
250- }
251- yield return new GCInfoComponent ( personalityRoutine , codeDelta ) ;
252- }
215+ if ( frameInfoIndex == 0 && _methodNode . GCInfo != null )
216+ {
217+ yield return new GCInfoComponent ( _methodNode . GCInfo ) ;
253218 }
254219 }
255220 }
256- #endif
257221 }
258222
259223 class MethodGCInfoNodeDeduplicatingComparer : IEqualityComparer < MethodGCInfoNode >
0 commit comments