private static unsafe RuntimeFunction *FunctionTableHandler(ulong controlPc, IntPtr context) { int offset = (int)((long)controlPc - context.ToInt64()); if (!JitCache.TryFind(offset, out JitCacheEntry funcEntry)) { // Not found. return(null); } var unwindInfo = funcEntry.UnwindInfo; int codeIndex = 0; int spOffset = unwindInfo.FixedAllocSize; foreach (var entry in unwindInfo.PushEntries) { if (entry.Type == RegisterType.Vector) { spOffset -= 16; } } for (int index = unwindInfo.PushEntries.Length - 1; index >= 0; index--) { var entry = unwindInfo.PushEntries[index]; if (entry.Type == RegisterType.Vector) { ushort uwop = PackUwop(UnwindOperation.SaveXmm128, entry.StreamEndOffset, entry.Index); _unwindInfo->UnwindCodes[codeIndex++] = uwop; _unwindInfo->UnwindCodes[codeIndex++] = (ushort)spOffset; spOffset += 16; } } _unwindInfo->UnwindCodes[0] = PackUwop(UnwindOperation.AllocLarge, unwindInfo.PrologueSize, 1); _unwindInfo->UnwindCodes[1] = (ushort)(unwindInfo.FixedAllocSize >> 0); _unwindInfo->UnwindCodes[2] = (ushort)(unwindInfo.FixedAllocSize >> 16); codeIndex += 3; for (int index = unwindInfo.PushEntries.Length - 1; index >= 0; index--) { var entry = unwindInfo.PushEntries[index]; if (entry.Type == RegisterType.Integer) { ushort uwop = PackUwop(UnwindOperation.PushNonvol, entry.StreamEndOffset, entry.Index); _unwindInfo->UnwindCodes[codeIndex++] = uwop; } } _unwindInfo->VersionAndFlags = 1; _unwindInfo->SizeOfProlog = (byte)unwindInfo.PrologueSize; _unwindInfo->CountOfUnwindCodes = (byte)codeIndex; _unwindInfo->FrameRegister = 0; _runtimeFunction->BeginAddress = (uint)funcEntry.Offset; _runtimeFunction->EndAddress = (uint)(funcEntry.Offset + funcEntry.Size); _runtimeFunction->UnwindData = (uint)_sizeOfRuntimeFunction; return(_runtimeFunction); }
private static unsafe RuntimeFunction *FunctionTableHandler(ulong controlPc, IntPtr context) { int offset = (int)((long)controlPc - context.ToInt64()); if (!JitCache.TryFind(offset, out JitCacheEntry funcEntry)) { return(null); // Not found. } var unwindInfo = funcEntry.UnwindInfo; int codeIndex = 0; for (int index = unwindInfo.PushEntries.Length - 1; index >= 0; index--) { var entry = unwindInfo.PushEntries[index]; switch (entry.PseudoOp) { case UnwindPseudoOp.SaveXmm128: { int stackOffset = entry.StackOffsetOrAllocSize; Debug.Assert(stackOffset % 16 == 0); if (stackOffset <= 0xFFFF0) { _unwindInfo->UnwindCodes[codeIndex++] = PackUnwindOp(UnwindOperation.SaveXmm128, entry.PrologOffset, entry.RegIndex); _unwindInfo->UnwindCodes[codeIndex++] = (ushort)(stackOffset / 16); } else { _unwindInfo->UnwindCodes[codeIndex++] = PackUnwindOp(UnwindOperation.SaveXmm128Far, entry.PrologOffset, entry.RegIndex); _unwindInfo->UnwindCodes[codeIndex++] = (ushort)(stackOffset >> 0); _unwindInfo->UnwindCodes[codeIndex++] = (ushort)(stackOffset >> 16); } break; } case UnwindPseudoOp.AllocStack: { int allocSize = entry.StackOffsetOrAllocSize; Debug.Assert(allocSize % 8 == 0); if (allocSize <= 128) { _unwindInfo->UnwindCodes[codeIndex++] = PackUnwindOp(UnwindOperation.AllocSmall, entry.PrologOffset, (allocSize / 8) - 1); } else if (allocSize <= 0x7FFF8) { _unwindInfo->UnwindCodes[codeIndex++] = PackUnwindOp(UnwindOperation.AllocLarge, entry.PrologOffset, 0); _unwindInfo->UnwindCodes[codeIndex++] = (ushort)(allocSize / 8); } else { _unwindInfo->UnwindCodes[codeIndex++] = PackUnwindOp(UnwindOperation.AllocLarge, entry.PrologOffset, 1); _unwindInfo->UnwindCodes[codeIndex++] = (ushort)(allocSize >> 0); _unwindInfo->UnwindCodes[codeIndex++] = (ushort)(allocSize >> 16); } break; } case UnwindPseudoOp.PushReg: { _unwindInfo->UnwindCodes[codeIndex++] = PackUnwindOp(UnwindOperation.PushNonvol, entry.PrologOffset, entry.RegIndex); break; } default: throw new NotImplementedException($"({nameof(entry.PseudoOp)} = {entry.PseudoOp})"); } } Debug.Assert(codeIndex <= MaxUnwindCodesArraySize); _unwindInfo->VersionAndFlags = 1; // Flags: The function has no handler. _unwindInfo->SizeOfProlog = (byte)unwindInfo.PrologSize; _unwindInfo->CountOfUnwindCodes = (byte)codeIndex; _unwindInfo->FrameRegister = 0; _runtimeFunction->BeginAddress = (uint)funcEntry.Offset; _runtimeFunction->EndAddress = (uint)(funcEntry.Offset + funcEntry.Size); _runtimeFunction->UnwindData = (uint)_sizeOfRuntimeFunction; return(_runtimeFunction); }