<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<p>Hi,<br>
Having the ability to select different calling conventions (or,
more accurately, completely different ABIs) is a powerful trick.
It comes in especially handy in cases that I'd call foreign^2 -
that is, when you want to talk to some native function that adopts
calling conventions that are not first-class on that particular
system. I view x86 on x64 and x64 on arm64 as largely similar in
spirit.</p>
<p>That is in contrast, IMHO with the situation we had with x86 -
where multiple competing calling conventions often existed within
the same system (sometimes with the intent of providing better
performances in certain contexts). Windows x86 supports six (!!)
calling conventions [1]. By contrast, on Windows x64 there's only
two (__vectorcall is apparently still around, although I don't
know how widely used). Other platforms followed a similar
evolution.</p>
<p>The cross-architecture-compatibility use case you mention is an
emerging important one, so we will keep an eye in this space for
sure.</p>
<p>Maurizio</p>
<p>[1] -
<a class="moz-txt-link-freetext" href="https://learn.microsoft.com/en-us/cpp/cpp/argument-passing-and-naming-conventions?view=msvc-170">https://learn.microsoft.com/en-us/cpp/cpp/argument-passing-and-naming-conventions?view=msvc-170</a></p>
<div class="moz-cite-prefix">On 11/10/2024 01:48, Владимир Козелков
wrote:<br>
</div>
<blockquote type="cite" cite="mid:CAGF0iuR7G_Hvh5AGk0RUeQyoQZgBHRQBcFz8-Wp2TD5YSBGBYg@mail.gmail.com">
<p dir="ltr">I think the main use of alternative linkers is to
reflect the existing ability of systems to run binaries from
other platforms. </p>
<p dir="ltr">In my example, it was possible to use old binaries
for 32-bin systems on 64-bit systems. But platforms are not
limited to this. You were wrong when you said about the unified
calling convention on new architectures - just look at the
ARM64EC calling convention - it allows an application to have
both aarch64 and x86_64 binaries in the process!</p>
<p dir="ltr">Also... I'm confused by the existence of Wine on
Linux - it provides a platform for running binaries of the same
architecture, but of a different operating system (Windows).
Unfortunately, I don't know if it has the ability to have a
process with mixed binaries and how this relates to Java, but
this is also an interesting example. </p>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">пт, 11 окт. 2024 г., 4:04
Maurizio Cimadamore <<a href="mailto:maurizio.cimadamore@oracle.com" moz-do-not-send="true" class="moz-txt-link-freetext">maurizio.cimadamore@oracle.com</a>>:<br>
</div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
as you noticed, while the Linker javadoc alludes at the fact
that there <br>
might be other calling conventions supported in the future, at
the <br>
moment there's no API to expose this. What we had in mind the
last time <br>
we discussed this was not too dissimilar to what you propose
here - <br>
basically just keep calling convention open, by using strings,
and then <br>
allow the "nativeLinker" factory to accept a calling
convention string.<br>
<br>
Another possibility would be to use linker options - e.g. have
a <br>
CallingConvention linker option that can be passed to <br>
downcallHandle/upcallStub. This would allow to keep a single
linker, but <br>
to support downcalls with different calling conventions. Both
approaches <br>
are equally expressive, at least in terms of allowing to call
functions <br>
using different argument shuffling. That said, on some
platforms, like <br>
PowerPC support for instance different kind of endianness. So
perhaps it <br>
would be good to have a way to ask for the "big endian"
Linker, whose <br>
canonical layouts will be... big endian. That is, a Linker is
about <br>
functions as much as it is about the definition of fundamental
data <br>
types. So, perhaps when adding support for different Linker
"flavors" it <br>
would be good to keep this in mind.<br>
<br>
The reason we left this out in 22 was that we wanted to learn
more use <br>
cases where this was useful. For instance, while it's true
that x86 <br>
supported several calling conventions, modern systems seems to
have <br>
evolved a bit, so that each major platform tend to gravitate
towards one <br>
main set of calling convention, typically specified in that
platform's <br>
ABI (e.g. SysV for Linux). It seems to me that even in your
case, the <br>
main driver for selecting an alternate calling convention is
x86 really. <br>
So I'm still not 100% sure that this is something worth
pursuing. I <br>
would feel more at ease if we had more cases where this was
useful.<br>
<br>
Cheers<br>
Maurizio<br>
<br>
<br>
On 10/10/2024 20:14, Владимир Козелков wrote:<br>
> Greetings,<br>
><br>
> The documentation for the Linker.nativeLinker() method
says: "It is <br>
> not currently possible to obtain a linker for a different
combination <br>
> of OS and processor."<br>
><br>
> This is indeed true for hotspot, but what if another
implementation <br>
> could provide the ability to create a linker for a
different calling <br>
> convention? Even if the implementation wanted to do this,
it would <br>
> fail because the API does not provide any points through
which this <br>
> could be done.<br>
><br>
> As an example - android allows us to use binaries for arm
in aarch64 <br>
> and for x86 in x86_64 with JNI. In the current
implementation, I have <br>
> to filter the output of SymbolLookup.loaderLookup() so
that the user <br>
> does not get symbols with a different calling convention,
although the <br>
> platform really allows to use them.<br>
><br>
> Additionally, I would like to note that the x86 and
x86_64 platforms <br>
> have several "native" calling conventions, such as cdecl
(which is <br>
> actually used now), fastcall, vectorcall, etc. Even if a
hotspot does <br>
> not allow these calling conventions, it would be useful
to have at <br>
> least the potential to implement them.<br>
><br>
> I can suggest a not very good and naive method for
solving the problem <br>
> - it is inspired by target-triple from LLVM:<br>
><br>
> interface Linker ... {<br>
> static List<String> supportedConventions()
{return ... ;}<br>
> static String defaultConvention() {return ... ;}<br>
> static boolean isSupportedConvention(String
convention) {return ... ;}<br>
> static Linker linkerForConvention(String convention)
{return ... ;}<br>
> static Linker nativeLinker() {<br>
> return linkerForConvention(defaultConvention());<br>
> }<br>
> }<br>
><br>
> For android aarch64 defaultConvention() will return
something like <br>
> "aarch64-android-cdecl"<br>
><br>
> Thanks for reading<br>
</blockquote>
</div>
</blockquote>
</body>
</html>