Re: [Question] Could the max code size check be optional?

"Manuel Carrasco" (via asm Mailing List) <[email protected]> Fri, 26 Mar 2021 12:01:15 +0000
Newsgroups gmane.comp.java.objectweb.asm
Message-ID <CA+_2aJ-Gf=8uwrEo+CUfFcop5ErkzBR3h_nmx0YO3b0po+vuSw@mail.gmail.com>
This is a multi-part message in MIME format...

------------=_1616760110-29191-12
Content-Type: multipart/alternative; boundary="000000000000a3a31c05be6f4a79"

--000000000000a3a31c05be6f4a79
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Thanks a lot for your help! All your input were very helpful.

Cheers,
Manuel.


El jue, 18 mar 2021 a las 17:31, <[email protected]> escribi=C3=B3:

> Hi,
>
>
> https://asm.ow2.io/javadoc/org/objectweb/asm/tree/analysis/Analyzer.html#=
analyzeAndComputeMaxs(java.lang.String,org.objectweb.asm.tree.MethodNode)
> can be used to compute the max stack and locals, as well as the stack
> map frames. However, it is much slower than using ClassWriter.
>
> You can also use
> https://asm.ow2.io/javadoc/org/objectweb/asm/commons/CodeSizeEvaluator.ht=
ml
> to estimate the bytecode size of a method. So you can know if your
> method is too big without using ClassWriter and checking whether you get
> an exception because the code size is too large.
>
> Eric
>
> >> In the sense, that the frame computation and max local/stack is
> > coupled to it. Currently, those features can't be used without a
> > MethodWriter (please correct me otherwise!).
> >
> > I would say they are more a utility added onto the MethodWriter in
> > case you don't update the maxLocals and maxStack yourself.
> >
> >> Would it be better that those analyses/transformations are available
> > and required to be executed before actually calling the MethodWriter?
> > In this way, the MethodWriter just writes the legal and valid method
> > structure of the class file. In addition, in case you need to compute
> > the max stack/local and frames for a method node you can use that
> > functionality without calling a MethodWriter.
> >
> > I think it would certainly be useful to have it available before
> > calling the MethodWriter (though not a requirement, calculating it
> > within the MethodWriter would be faster than first passing it through
> > a separate calculator).
> >
> > It would be duplicating the functionality of the MethodWriter, however
> > I don't think that is much of a problem, as the actual stack and local
> > size calculation performed in MethodWriter is a very small part of the
> > large code existing for frame generation. Removing it from the
> > MethodWriter would not have much purpose - the code that performs all
> > the calculations for the stack and local size calculations would still
> > need to remain to support the frame calculations.
> >
> >> In the current design, is it possible to calculate these things
> > without calling the MethodWriter? I'm assuming it is not possible.
> >
> > It is possible, you would just have to write it yourself - or it could
> > perhaps be included in asm-commons. A similar thing already exists
> > (AnalyzerAdapter) but I think it only works with bytecode that has
> > updated stackframes - I assume if you are not updating the maxLocals
> > and maxStack you are also not updating frames.
> >
> > x4e
> >
> > =E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90 Origina=
l Message =E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90
> >
> > On Wednesday, March 17th, 2021 at 13:45, Manuel Carrasco
> > <[email protected]> wrote:
> >
> >> Thanks for your answer!
> >>
> >>> In my opinion the MethodWriter should be designed to fit one
> >>> purpose - writing the (legal and valid) method structure of the
> >>> classfile.
> >>
> >> Yes, I do agree, but I think the MethodWriter is not actually doing
> >> that. In the sense, that the frame computation and max local/stack
> >> is coupled to it. Currently, those features can't be used without a
> >> MethodWriter (please correct me otherwise!). Would it be better that
> >> those analyses/transformations are available and required to be
> >> executed before actually calling the MethodWriter? In this way, the
> >> MethodWriter just writes the legal and valid method structure of the
> >> class file. In addition, in case you need to compute the max
> >> stack/local and frames for a method node you can use that
> >> functionality without calling a MethodWriter.
> >>
> >>> Perhaps a better way to do this would be to write a custom method
> >>> visitor that is able to calculate this for you?
> >>
> >> That can work but the problem that I see is that we would duplicate
> >> the functionality that is already in the MethodWriter.
> >>
> >> In the current design, is it possible to calculate these things
> >> without calling the MethodWriter? I'm assuming it is not possible.
> >>
> >> Thanks again!
> >>
> >> Cheers,
> >>
> >> Manuel.
> >>
> >> El mi=C3=A9, 17 mar 2021 a las 12:25, x4e_x4e (<[email protected]=
>)
> >> escribi=C3=B3:
> >>
> >> Hi Manuel,
> >>
> >> In my opinion the MethodWriter should be designed to fit one purpose
> >> - writing the (legal and valid) method structure of the classfile.
> >> It would seem strange for it to also be used as a way of calculating
> >> the max stack/locals in a method for the user. Especially because
> >> the intended output of the methodvisitor would be not just illegal
> >> but physically invalid, and no longer conform to the classfile=E2=80=
=99s
> >> structure from the specification (not just the verifier/formatting
> >> rules).
> >>
> >> Perhaps a better way to do this would be to write a custom method
> >> visitor that is able to calculate this for you?
> >>
> >> x4e
> >>
> >> =E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90 Origin=
al Message =E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90
> >>
> >> On Wednesday, March 17th, 2021 at 11:09, Manuel Carrasco
> >> <[email protected]> wrote:
> >>
> >> Hi,
> >>
> >> How are you?
> >>
> >> I noticed that the MethodWriter currently
> >> (184aaa9f0ec4c233872087a3c4d2d96a3c204ac6) throws an exception when
> >> the method size exceeds the maximum allowed by the JVM [1]. The
> >> intent is clear to me, the library wants to emit Java bytecode that
> >> is legal in terms of the specification. My question is, could we
> >> make this check optional and true by default?
> >>
> >> In case that you want to perform an optimization to shrink your
> >> code, you may require to have the max stack and local as well as the
> >> stack map frames available. So, you execute the ClassWriter to
> >> compute them, but it will crash as soon the MethodWriter verifies
> >> the maximum code size.
> >>
> >> The current implementation is limiting user optimizations on their
> >> code in case it has already exceeded the maximum limit. At least, it
> >> is not allowing them to compute the max stack and local as well as
> >> the map stack frames.
> >>
> >> I tested commenting the check and emitting the code. It didn't
> >> crash, and I could optimize it, so it can be executed by the JVM.
> >>
> >> Considering all this, I'd like to know if you consider reasonable to
> >> make the max code size check optional. Perhaps, I'm missing some
> >> other technical reason that could make this impossible.
> >>
> >> Thanks in advance!
> >>
> >> Cheers,
> >>
> >> Manuel.
> >
> >
> >
> > Links:
> > ------
> > [1]
> >
> https://gitlab.ow2.org/asm/asm/-/blob/master/asm/src/main/java/org/object=
web/asm/MethodWriter.java#L2086
>

--000000000000a3a31c05be6f4a79
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Thanks a lot for your help! All your input were very =
helpful.</div><div><br></div><div>Cheers,<br></div><div>Manuel.<br></div><d=
iv><br></div></div><br><div class=3D"gmail_quote"><div dir=3D"ltr" class=3D=
"gmail_attr">El jue, 18 mar 2021 a las 17:31, &lt;<a href=3D"mailto:ebrunet=
[email protected]">[email protected]</a>&gt; escribi=C3=B3:<br></div><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px soli=
d rgb(204,204,204);padding-left:1ex">Hi,<br>
<br>
<a href=3D"https://asm.ow2.io/javadoc/org/objectweb/asm/tree/analysis/Analy=
zer.html#analyzeAndComputeMaxs(java.lang.String,org.objectweb.asm.tree.Meth=
odNode)" rel=3D"noreferrer" target=3D"_blank">https://asm.ow2.io/javadoc/or=
g/objectweb/asm/tree/analysis/Analyzer.html#analyzeAndComputeMaxs(java.lang=
.String,org.objectweb.asm.tree.MethodNode)</a> <br>
can be used to compute the max stack and locals, as well as the stack <br>
map frames. However, it is much slower than using ClassWriter.<br>
<br>
You can also use <br>
<a href=3D"https://asm.ow2.io/javadoc/org/objectweb/asm/commons/CodeSizeEva=
luator.html" rel=3D"noreferrer" target=3D"_blank">https://asm.ow2.io/javado=
c/org/objectweb/asm/commons/CodeSizeEvaluator.html</a> <br>
to estimate the bytecode size of a method. So you can know if your <br>
method is too big without using ClassWriter and checking whether you get <b=
r>
an exception because the code size is too large.<br>
<br>
Eric<br>
<br>
&gt;&gt; In the sense, that the frame computation and max local/stack is<br>
&gt; coupled to it. Currently, those features can&#39;t be used without a<b=
r>
&gt; MethodWriter (please correct me otherwise!).<br>
&gt; <br>
&gt; I would say they are more a utility added onto the MethodWriter in<br>
&gt; case you don&#39;t update the maxLocals and maxStack yourself.<br>
&gt; <br>
&gt;&gt; Would it be better that those analyses/transformations are availab=
le<br>
&gt; and required to be executed before actually calling the MethodWriter?<=
br>
&gt; In this way, the MethodWriter just writes the legal and valid method<b=
r>
&gt; structure of the class file. In addition, in case you need to compute<=
br>
&gt; the max stack/local and frames for a method node you can use that<br>
&gt; functionality without calling a MethodWriter.<br>
&gt; <br>
&gt; I think it would certainly be useful to have it available before<br>
&gt; calling the MethodWriter (though not a requirement, calculating it<br>
&gt; within the MethodWriter would be faster than first passing it through<=
br>
&gt; a separate calculator).<br>
&gt; <br>
&gt; It would be duplicating the functionality of the MethodWriter, however=
<br>
&gt; I don&#39;t think that is much of a problem, as the actual stack and l=
ocal<br>
&gt; size calculation performed in MethodWriter is a very small part of the=
<br>
&gt; large code existing for frame generation. Removing it from the<br>
&gt; MethodWriter would not have much purpose - the code that performs all<=
br>
&gt; the calculations for the stack and local size calculations would still=
<br>
&gt; need to remain to support the frame calculations.<br>
&gt; <br>
&gt;&gt; In the current design, is it possible to calculate these things<br>
&gt; without calling the MethodWriter? I&#39;m assuming it is not possible.=
<br>
&gt; <br>
&gt; It is possible, you would just have to write it yourself - or it could=
<br>
&gt; perhaps be included in asm-commons. A similar thing already exists<br>
&gt; (AnalyzerAdapter) but I think it only works with bytecode that has<br>
&gt; updated stackframes - I assume if you are not updating the maxLocals<b=
r>
&gt; and maxStack you are also not updating frames.<br>
&gt; <br>
&gt; x4e<br>
&gt; <br>
&gt; =E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90 Origin=
al Message =E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90<=
br>
&gt; <br>
&gt; On Wednesday, March 17th, 2021 at 13:45, Manuel Carrasco<br>
&gt; &lt;<a href=3D"mailto:[email protected]" target=3D"_blank">mgca=
[email protected]</a>&gt; wrote:<br>
&gt; <br>
&gt;&gt; Thanks for your answer!<br>
&gt;&gt; <br>
&gt;&gt;&gt; In my opinion the MethodWriter should be designed to fit one<b=
r>
&gt;&gt;&gt; purpose - writing the (legal and valid) method structure of th=
e<br>
&gt;&gt;&gt; classfile.<br>
&gt;&gt; <br>
&gt;&gt; Yes, I do agree, but I think the MethodWriter is not actually doin=
g<br>
&gt;&gt; that. In the sense, that the frame computation and max local/stack=
<br>
&gt;&gt; is coupled to it. Currently, those features can&#39;t be used with=
out a<br>
&gt;&gt; MethodWriter (please correct me otherwise!). Would it be better th=
at<br>
&gt;&gt; those analyses/transformations are available and required to be<br>
&gt;&gt; executed before actually calling the MethodWriter? In this way, th=
e<br>
&gt;&gt; MethodWriter just writes the legal and valid method structure of t=
he<br>
&gt;&gt; class file. In addition, in case you need to compute the max<br>
&gt;&gt; stack/local and frames for a method node you can use that<br>
&gt;&gt; functionality without calling a MethodWriter.<br>
&gt;&gt; <br>
&gt;&gt;&gt; Perhaps a better way to do this would be to write a custom met=
hod<br>
&gt;&gt;&gt; visitor that is able to calculate this for you?<br>
&gt;&gt; <br>
&gt;&gt; That can work but the problem that I see is that we would duplicat=
e<br>
&gt;&gt; the functionality that is already in the MethodWriter.<br>
&gt;&gt; <br>
&gt;&gt; In the current design, is it possible to calculate these things<br>
&gt;&gt; without calling the MethodWriter? I&#39;m assuming it is not possi=
ble.<br>
&gt;&gt; <br>
&gt;&gt; Thanks again!<br>
&gt;&gt; <br>
&gt;&gt; Cheers,<br>
&gt;&gt; <br>
&gt;&gt; Manuel.<br>
&gt;&gt; <br>
&gt;&gt; El mi=C3=A9, 17 mar 2021 a las 12:25, x4e_x4e (&lt;<a href=3D"mail=
to:[email protected]" target=3D"_blank">[email protected]</a>&gt;=
)<br>
&gt;&gt; escribi=C3=B3:<br>
&gt;&gt; <br>
&gt;&gt; Hi Manuel,<br>
&gt;&gt; <br>
&gt;&gt; In my opinion the MethodWriter should be designed to fit one purpo=
se<br>
&gt;&gt; - writing the (legal and valid) method structure of the classfile.=
<br>
&gt;&gt; It would seem strange for it to also be used as a way of calculati=
ng<br>
&gt;&gt; the max stack/locals in a method for the user. Especially because<=
br>
&gt;&gt; the intended output of the methodvisitor would be not just illegal=
<br>
&gt;&gt; but physically invalid, and no longer conform to the classfile=E2=
=80=99s<br>
&gt;&gt; structure from the specification (not just the verifier/formatting=
<br>
&gt;&gt; rules).<br>
&gt;&gt; <br>
&gt;&gt; Perhaps a better way to do this would be to write a custom method<=
br>
&gt;&gt; visitor that is able to calculate this for you?<br>
&gt;&gt; <br>
&gt;&gt; x4e<br>
&gt;&gt; <br>
&gt;&gt; =E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90 Or=
iginal Message =E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=
=90<br>
&gt;&gt; <br>
&gt;&gt; On Wednesday, March 17th, 2021 at 11:09, Manuel Carrasco<br>
&gt;&gt; &lt;<a href=3D"mailto:[email protected]" target=3D"_blank">[email protected]</=
a>&gt; wrote:<br>
&gt;&gt; <br>
&gt;&gt; Hi,<br>
&gt;&gt; <br>
&gt;&gt; How are you?<br>
&gt;&gt; <br>
&gt;&gt; I noticed that the MethodWriter currently<br>
&gt;&gt; (184aaa9f0ec4c233872087a3c4d2d96a3c204ac6) throws an exception whe=
n<br>
&gt;&gt; the method size exceeds the maximum allowed by the JVM [1]. The<br>
&gt;&gt; intent is clear to me, the library wants to emit Java bytecode tha=
t<br>
&gt;&gt; is legal in terms of the specification. My question is, could we<b=
r>
&gt;&gt; make this check optional and true by default?<br>
&gt;&gt; <br>
&gt;&gt; In case that you want to perform an optimization to shrink your<br>
&gt;&gt; code, you may require to have the max stack and local as well as t=
he<br>
&gt;&gt; stack map frames available. So, you execute the ClassWriter to<br>
&gt;&gt; compute them, but it will crash as soon the MethodWriter verifies<=
br>
&gt;&gt; the maximum code size.<br>
&gt;&gt; <br>
&gt;&gt; The current implementation is limiting user optimizations on their=
<br>
&gt;&gt; code in case it has already exceeded the maximum limit. At least, =
it<br>
&gt;&gt; is not allowing them to compute the max stack and local as well as=
<br>
&gt;&gt; the map stack frames.<br>
&gt;&gt; <br>
&gt;&gt; I tested commenting the check and emitting the code. It didn&#39;t=
<br>
&gt;&gt; crash, and I could optimize it, so it can be executed by the JVM.<=
br>
&gt;&gt; <br>
&gt;&gt; Considering all this, I&#39;d like to know if you consider reasona=
ble to<br>
&gt;&gt; make the max code size check optional. Perhaps, I&#39;m missing so=
me<br>
&gt;&gt; other technical reason that could make this impossible.<br>
&gt;&gt; <br>
&gt;&gt; Thanks in advance!<br>
&gt;&gt; <br>
&gt;&gt; Cheers,<br>
&gt;&gt; <br>
&gt;&gt; Manuel.<br>
&gt; <br>
&gt; <br>
&gt; <br>
&gt; Links:<br>
&gt; ------<br>
&gt; [1]<br>
&gt; <a href=3D"https://gitlab.ow2.org/asm/asm/-/blob/master/asm/src/main/j=
ava/org/objectweb/asm/MethodWriter.java#L2086" rel=3D"noreferrer" target=3D=
"_blank">https://gitlab.ow2.org/asm/asm/-/blob/master/asm/src/main/java/org=
/objectweb/asm/MethodWriter.java#L2086</a><br>
</blockquote></div>

--000000000000a3a31c05be6f4a79--

------------=_1616760110-29191-12
Content-Type: text/plain; charset="UTF-8"
Content-Disposition: inline
Content-Transfer-Encoding: 8bit


-- 
You receive this message as a subscriber of the [email protected] mailing list.
To unsubscribe: mailto:[email protected]
For general help: mailto:[email protected]?subject=help
OW2 mailing lists service home page: http://www.ow2.org/wws

------------=_1616760110-29191-12--