<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hi @ll,<div class=""><br class=""></div><div class="">over the past year we gained more experience with the patchpoint/stackmap/statepoint intrinsics and it exposed limitations in the stackmap format.</div><div class="">The following proposal includes feedback and request from several interested parties and I would like to hear your feedback.</div><div class=""><br class=""></div><div class="">Missing correlation between functions and stackmap records:</div><div class="">Originally the client had to keep track of the ID to know which stackmap record belongs to which function, but this would stop working once functions are inlined.</div><div class="">The new format fixes that by adding a direct reference from the function to the stackmap records.</div><div class=""><br class=""></div><div class="">Call Size and Function Size:</div><div class="">These are additional information that are of interest and have been added to the format.</div><div class="">@Swaroop: Could you please provide a little more detailed explanation on the "Call Size" field and what exactly is there recorded. Is it just the call instruction</div><div class="">or also the materialization code for the address? For what is this used for?</div><div class=""><br class=""></div><div class="">Flat format:</div><div class="">We think moving to a flat form will make parsing easier, because every record has a fixed size and offsets can be calculated easily. The plan is to also</div><div class="">provide parsers for both stackmap versions (there is already one for the first format in tree) and a corresponding C-API to make it easier for clients to</div><div class="">adopt the new format. There is no plan to drop the original format and we will continue to support both formats. I will ask for feedback on the C API in a</div><div class="">separate RFC. </div><div class=""><br class=""></div><div class="">Another benefit we hope to achieve from this format is to optimize for size by uniquing entries - but that is independent optimization and not required.</div><div class=""><br class=""></div><div class="">More detailed frame record:</div><div class="">Clients require more information about the function frame, such as spilled registers, etc. The frame base register i.e. might change when dynamic stack</div><div class="">realignment is performed on X86.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">If there is anything missing please let me know.</div><div class=""><br class=""></div><div class="">Thanks</div><div class=""><br class=""></div><div class="">Cheers,</div><div class="">Juergen</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><div class=""><font face="Courier New" class="">Header v2 {<br class="">  uint8  : Stack Map Version (2)<br class="">  uint8  : Reserved [3] (0)<br class="">  uint32 : Constants Offset (bytes)<br class="">  uint32 : Frame Records Offset (bytes)<br class="">  uint32 : Frame Registers Offset (bytes)<br class="">  uint32 : StackMap Records Offset (bytes)<br class="">  uint32 : Locations Offset (bytes)<br class="">  uint32 : LiveOuts Offset (bytes)</font></div><div class=""><font face="Courier New" class="">}<br class=""><br class="">align to 8 bytes<br class="">Constants[] {<br class="">  uint64 : LargeConstant<br class="">}<br class=""><br class="">align to 8 bytes<br class="">FrameRecord[] {<br class="">  uint64 : Function Address<br class="">  uint32 : Function Size<br class="">  uint32 : Stack Size<br class="">  uint16 : Flags {<br class="">    bool : HasFrame<br class="">    bool : HasVariableSizeAlloca<br class="">    bool : HasStackRealignment<br class="">    bool : HasLiveOutInfo<br class="">    bool : Reserved [12]<br class="">  }<br class="">  uint16 : Frame Base Register Dwarf RegNum<br class="">  uint16 : Num Frame Registers<br class="">  uint16 : Frame Register Index<br class="">  uint16 : Num StackMap Records<br class="">  uint16 : StackMap Record Index</font></div><div class=""><font face="Courier New" class="">}<br class=""><br class="">align to 4 bytes<br class="">FrameRegister[] {<br class="">  uint16 : Dwarf RegNum<br class="">  int16  : Offset<br class="">  uint8  : Size in Bytes<br class="">  uint8  : Flags {<br class="">    bool : IsSpilled<br class="">    bool : Reserved [7]<br class="">  }<br class="">}<br class=""><br class="">align to 8 bytes<br class="">StackMapRecord[] {<br class="">  uint64 : PatchPoint ID<br class="">  uint32 : Instruction Offset<br class="">  uint8  : Call size (bytes)<br class="">  uint8  : Flags {<br class="">    bool : HasLiveOutInfo<br class="">    bool : Reserved [7]<br class="">  }<br class="">  uint16 : Num Locations<br class="">  uint16 : Location Index<br class="">  uint16 : Num LiveOuts<br class="">  uint16 : LiveOut Index<br class="">}</font></div><div class=""><span style="font-family: 'Courier New';" class=""><br class=""></span></div><div class=""><span style="font-family: 'Courier New';" class="">align to 4 bytes</span></div><div class=""><font face="Courier New" class="">Location[] {<br class="">  uint8  : Register | Direct | Indirect | Constant | ConstantIndex<br class="">  uint8  : Reserved (location flags)<br class="">  uint16 : Dwarf RegNum<br class="">  int32  : Offset or SmallConstant<br class="">}<br class=""><br class="">align to 2 bytes<br class="">LiveOuts[] {<br class="">  uint16 : Dwarf RegNum<br class="">  uint8  : Reserved<br class="">  uint8  : Size in Bytes<br class="">}</font></div><div class=""><br class=""></div></div></body></html>