<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:Wingdings;
        panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        font-size:10.0pt;
        font-family:"Calibri",sans-serif;}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
        {mso-style-priority:34;
        margin-top:0cm;
        margin-right:0cm;
        margin-bottom:0cm;
        margin-left:36.0pt;
        font-size:10.0pt;
        font-family:"Calibri",sans-serif;}
span.EmailStyle18
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;
        mso-ligatures:none;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
        {page:WordSection1;}
/* List Definitions */
@list l0
        {mso-list-id:729118117;
        mso-list-type:hybrid;
        mso-list-template-ids:-1687657514 -1604008954 134807555 134807557 134807553 134807555 134807557 134807553 134807555 134807557;}
@list l0:level1
        {mso-level-number-format:bullet;
        mso-level-text:-;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:"Calibri",sans-serif;
        mso-fareast-font-family:Calibri;}
@list l0:level2
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:"Courier New";}
@list l0:level3
        {mso-level-number-format:bullet;
        mso-level-text:\F0A7 ;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Wingdings;}
@list l0:level4
        {mso-level-number-format:bullet;
        mso-level-text:\F0B7 ;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Symbol;}
@list l0:level5
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:"Courier New";}
@list l0:level6
        {mso-level-number-format:bullet;
        mso-level-text:\F0A7 ;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Wingdings;}
@list l0:level7
        {mso-level-number-format:bullet;
        mso-level-text:\F0B7 ;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Symbol;}
@list l0:level8
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:"Courier New";}
@list l0:level9
        {mso-level-number-format:bullet;
        mso-level-text:\F0A7 ;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Wingdings;}
@list l1
        {mso-list-id:1528063041;
        mso-list-type:hybrid;
        mso-list-template-ids:-359499878 224281732 134807555 134807557 134807553 134807555 134807557 134807553 134807555 134807557;}
@list l1:level1
        {mso-level-number-format:bullet;
        mso-level-text:-;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:"Calibri",sans-serif;
        mso-fareast-font-family:Calibri;}
@list l1:level2
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:"Courier New";}
@list l1:level3
        {mso-level-number-format:bullet;
        mso-level-text:\F0A7 ;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Wingdings;}
@list l1:level4
        {mso-level-number-format:bullet;
        mso-level-text:\F0B7 ;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Symbol;}
@list l1:level5
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:"Courier New";}
@list l1:level6
        {mso-level-number-format:bullet;
        mso-level-text:\F0A7 ;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Wingdings;}
@list l1:level7
        {mso-level-number-format:bullet;
        mso-level-text:\F0B7 ;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Symbol;}
@list l1:level8
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:"Courier New";}
@list l1:level9
        {mso-level-number-format:bullet;
        mso-level-text:\F0A7 ;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Wingdings;}
@list l2
        {mso-list-id:1797480419;
        mso-list-type:hybrid;
        mso-list-template-ids:983445158 134807567 134807577 134807579 134807567 134807577 134807579 134807567 134807577 134807579;}
@list l2:level1
        {mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;}
@list l2:level2
        {mso-level-number-format:alpha-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;}
@list l2:level3
        {mso-level-number-format:roman-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:right;
        text-indent:-9.0pt;}
@list l2:level4
        {mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;}
@list l2:level5
        {mso-level-number-format:alpha-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;}
@list l2:level6
        {mso-level-number-format:roman-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:right;
        text-indent:-9.0pt;}
@list l2:level7
        {mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;}
@list l2:level8
        {mso-level-number-format:alpha-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;}
@list l2:level9
        {mso-level-number-format:roman-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:right;
        text-indent:-9.0pt;}
ol
        {margin-bottom:0cm;}
ul
        {margin-bottom:0cm;}
--></style>
</head>
<body lang="en-CZ" link="#0563C1" vlink="#954F72" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">I like the idea. It makes sense to simplify handling of custom attributes for some common situations.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">As the proposal adds a method to AtributeMapper identifying “brittle” attributes, it still implies existence of custom attribute mapper for each custom attribute.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">Current attributes can be split into following categories :<o:p></o:p></span></p>
<ol style="margin-top:0cm" start="1" type="1">
<li class="MsoListParagraph" style="margin-left:0cm;mso-list:l2 level1 lfo1"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">Self-contained attributes (no dependency on CP nor Code offsets). Such attributes can be safely transformed in
 any situation and their payload is just copy/pasted.<o:p></o:p></span></li><li class="MsoListParagraph" style="margin-left:0cm;mso-list:l2 level1 lfo1"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">Attributes with references to constant pool. Such attributes can be safely transformed when the CP is shared,
 however require custom handling (cloning of CP entries) during write into a class with new CP.<o:p></o:p></span></li><li class="MsoListParagraph" style="margin-left:0cm;mso-list:l2 level1 lfo1"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">Attributes with references to bytecode offsets (Code attributes). Payload of such attributes can be safely copy/pasted
 only when the Code is untouched. Otherwise they require custom translation into labeled model during read and back to offsets during write. These attribute most probably also use constant pool.</span><span style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p></o:p></span></li></ol>
<p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">I would suggest an alternative proposal to provide various custom attribute mapper factories, mainly to simplify handling of category #1 and #2 of custom attributes.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">That solution would not require to add any indication methods to the mappers nor global switches. Each custom mapper (composed by user) will respond to the actual situation
 accordingly.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">For category #1 there might be a single factory getting attribute name and returning attribute mapper.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">For category #2 there might be more options:<o:p></o:p></span></p>
<ul style="margin-top:0cm" type="disc">
<li class="MsoListParagraph" style="margin-left:0cm;mso-list:l0 level1 lfo3"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">A factory producing mapper which throws on write when CP is not shared<o:p></o:p></span></li><li class="MsoListParagraph" style="margin-left:0cm;mso-list:l0 level1 lfo3"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">Or a factory producing mapper simplifying CP entries clone and re-mapping on write when CP is not shared (it
 might be implemented even the way the user function identify offsets of CP indexes inside the payload and mapper does all the job with CP entries re-mapping).
<o:p></o:p></span></li></ul>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">For category #3 we may also provide some mapper factories, as we will better know specific use cases.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">Thanks,
<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">Adam<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<div id="mail-editor-reference-message-container">
<div>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal" style="margin-bottom:12.0pt"><b><span style="font-size:12.0pt;color:black">From:
</span></b><span style="font-size:12.0pt;color:black">classfile-api-dev <classfile-api-dev-retn@openjdk.org> on behalf of Brian Goetz <brian.goetz@oracle.com><br>
<b>Date: </b>Thursday, 27 July 2023 23:02<br>
<b>To: </b>classfile-api-dev@openjdk.org <classfile-api-dev@openjdk.org><br>
<b>Subject: </b>Attribute safety<o:p></o:p></span></p>
</div>
<p class="MsoNormal" style="margin-bottom:12.0pt"><span style="font-size:13.5pt;font-family:"Courier New"">We currently divide attributes into two buckets: those for which an attribute mapper exists, and those for which one doesn't.  The latter are represented
 with `UnknownAttribute`.  There is also an Option to determine whether unknown attributes should be discarded when reading or writing a classfile.  The main reason to be cautious about unknown attributes is that we cannot guarantee their integrity during transformation
 if there are any other changes to the classfile, because we don't know what their raw contents represent. 
<br>
<br>
The library leans heavily on constant pool sharing to optimize transformation.  The default behavior when transforming a classfile is to keep the original constant pool as the initial part of the new constant pool.  If constant pool sharing is enabled in this
 way, attributes that contain only pure data and/or constant pool offsets can be bulk-copied during transformation rather than parsing and regenerating them. 
<br>
<br>
Most of the known attributes meet this criteria -- that they contain only pure data and/or constant pool offsets.  However, there are a cluster of attributes that are more problematic: the type annotation attributes.  These may contain offsets into the bytecode
 table, exception table, list of type variables, bounds of type variables, and many other structures that may be perturbed during transformation.  This leaves us with some bad choices:<br>
<br>
 - Try to track if anything the attribute indexes into has been changed.  (The cost and benefit here are out of balance by multiple orders of magnitude here.)<br>
 - Copy the attribute and hope it is good enough.  Much of the fine structure of RVTA and friends are not actually used at runtime, so this may be OK. 
<br>
 - Drop the attribute during transformation and hope that's OK.  <br>
<br>
(There are also middle grounds, such as trying to detect whether the entity with the attribute (method, field, etc) has been modified.  This is lighter-weight that trying to track if the attribute has been invalidated, but this is already a significant task.) 
<br>
<br>
I haven't been happy with any of the options, but I have a proposal for incrementally improving it:<br>
<br>
 - Add a method to AttributeMapper for to indicate whether or not the attribute contains only pure data and/or constant pool offsets.  (Almost all the attributes defined in JVMS meet this restriction; only the type annotation attributes do not.)  For purposes
 of this mail, call the ones that do not the "brittle" attributes.  <br>
<br>
 - Add an option to determine what to do with brittle attributes under transformation: drop them, retain them, fail. 
<br>
<br>
This way, nonstandard brittle attributes can be marked as such as well, and get the same treatment as the known brittle attributes. 
<br>
<br>
</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
</div>
</div>
</div>
</body>
</html>