<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<div class="markdown-here-wrapper" data-md-url="" style="">
<p style="margin: 0px 0px 1.2em !important;">On 02/02/2023 13:15,
<a class="moz-txt-link-abbreviated" href="mailto:radek@smogura.eu">radek@smogura.eu</a> wrote:</p>
<blockquote style="margin: 1.2em 0px;border-left: 4px solid
rgb(221, 221, 221); padding: 0px 1em; color: rgb(119, 119, 119);
quotes: none;">
<p style="margin: 0px 0px 1.2em !important;">Hi Maurizio,</p>
<p style="margin: 0px 0px 1.2em !important;">Thank you for
sharing this. I agree that there’s a tension between<br>
Scope and Arena, and for i.e. passing Arena to
FileChannel::map look<br>
bit like we pass too big object there.</p>
<p style="margin: 0px 0px 1.2em !important;">I just thought
(sorry if it was proposed somewhere else), to<br>
introduce supporting object Scopable (can’t imagine better
name on<br>
short notice). So something which can have a scope (own -
freshly<br>
generated or shared in some way).</p>
<p style="margin: 0px 0px 1.2em !important;">The Scopable would
have single method scope(), and for simplicity<br>
Scope could be Scopable returning “this”.</p>
<p style="margin: 0px 0px 1.2em !important;">If MemorySegment
should be Scopable - I don’t know - as there’s next<br>
issue of allocating segments which are dependent in some way
and<br>
deallocation should be executed in order.</p>
</blockquote>
<p style="margin: 0px 0px 1.2em !important;">Hi Rado,<br>
Thanks for the comments. Having a common interface for all
things with a scope accessor is possible, and something we have
considered to bring Arena and SegmentScope under the same
umbrella.</p>
<p style="margin: 0px 0px 1.2em !important;">The main problem
though, is where do you put the “allocate” method. It is
unfortunate that, in the Java 20 API, there are <em>three</em>
ways to allocate a native segment:</p>
<pre style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">MemorySegment.allocateNative(100, arena.scope()) // 1
arena.allocate(100) // 2
SegmentAllocator.nativeAllocator(arena.scope()).allocate(100); // 3
</code></pre>
<p style="margin: 0px 0px 1.2em !important;">This seems overkill,
and adding an interface on top of Arena and SegmentScope doesn’t
help much. Well, Scopeable might also extend SegmentAllocator,
so you can do:</p>
<pre style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">SegmentScope.auto().allocate(100)
</code></pre>
<p style="margin: 0px 0px 1.2em !important;">But now this creates
an issue: if a scope is an allocator, then an Arena provides <em>two</em>
allocators: the allocator in its “allocate” method, and the
“fallback” allocator, available accessing the arena’s scope.</p>
<p style="margin: 0px 0px 1.2em !important;">This seemed overly
confusing.</p>
<p style="margin: 0px 0px 1.2em !important;">There’s also another
aspect in this: what we call SegmentScope.auto() really does act
as an arena (as the document explains) - just one that cannot be
closed explicitly. So having too much splitting in the API seems
to create unnecessary asymmetries and non-orthogonality.</p>
<p style="margin: 0px 0px 1.2em !important;">Once you embrace the
fact that Arena is your unit of allocation for native segments,
everything becomes easier. In the API proposed in the document
there is now only <em>one</em> way to allocate a native
segment, namely Arena::allocate.</p>
<p style="margin: 0px 0px 1.2em !important;">P.S.</p>
<p style="margin: 0px 0px 1.2em !important;">Related to this, we
also considered adding a Scopeable/Scoped interface (implemented
by MemorySegment) instead of a separate “Scope” interface. While
initially appealing, as:</p>
<pre style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">segment.isAlive()
</code></pre>
<p style="margin: 0px 0px 1.2em !important;">Seems better than:</p>
<pre style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">segment.scope().isAlive()
</code></pre>
<p style="margin: 0px 0px 1.2em !important;">That approach starts
running out of gas when you consider things like “how do you
compare the lifetime of two Scoped/Scopeable” ? You can’t use
“equals” (as equals on MemorySegment means something else) - so
you end up with something like this:</p>
<pre style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">segment.isLifetimeEquals(....)
</code></pre>
<p style="margin: 0px 0px 1.2em !important;">or, if we also
consider lifetime containment:</p>
<pre style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">segment.isLifetimeContainedBy(....)
</code></pre>
<p style="margin: 0px 0px 1.2em !important;">Both of which seems
less direct than:</p>
<pre style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">segment.scope().equals(...)
</code></pre>
<p style="margin: 0px 0px 1.2em !important;">or</p>
<pre style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">segment.scope().containedBy(...)
</code></pre>
<p style="margin: 0px 0px 1.2em !important;">On top of that, since
now Arena does not have a scope, but <em>is</em> a scope, we
need to make arena an abstract class, which somewhat limits
extension options for clients.</p>
<p style="margin: 0px 0px 1.2em !important;">So we have concluded
that keeping a small scope interface off to the side
(MemorySegment.Scope) represented the most pragmatic compromise.</p>
<p style="margin: 0px 0px 1.2em !important;">Maurizio</p>
<blockquote style="margin: 1.2em 0px;border-left: 4px solid
rgb(221, 221, 221); padding: 0px 1em; color: rgb(119, 119, 119);
quotes: none;">
<p style="margin: 0px 0px 1.2em !important;">Kind regards,
Radosław Smogura</p>
<blockquote style="margin: 1.2em 0px;border-left: 4px solid
rgb(221, 221, 221); padding: 0px 1em; color: rgb(119, 119,
119); quotes: none;">
<p style="margin: 0px 0px 1.2em !important;">On 31 Jan 2023,
at 19:46, Maurizio Cimadamore</p>
<p style="margin: 0px 0px 1.2em !important;"><a href="http://mailto:maurizio.cimadamore@oracle.com">maurizio.cimadamore@oracle.com</a>
wrote:</p>
<p style="margin: 0px 0px 1.2em !important;">Hi, as discussed
here [1], it is not clear as to whether Java 20<br>
iteration of the Foreign Function & Memory API (FFM API)
has yet<br>
reached bottom, especially when it comes to managing the
lifetime<br>
of the regions of memory backing memory segments. After
collecting<br>
some rounds of internal and external feedback, it was clear
that<br>
while the Java 20 API has all the functionalities we require
for<br>
writing efficient and robust native interop code, some of
the<br>
concepts in the API were made a bit harder to grok, as users
had to<br>
choose between two toplevel abstractions, namely <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">SegmentScope</code>
and<br>
<code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">Arena</code>.
This choice is made even more difficult, as some of the<br>
functionalities (e.g. allocation) is duplicated in both API
points.<br>
As a result, we have been busy exploring different ways to
restack<br>
the FFM API in search of something more approachable.</p>
<p style="margin: 0px 0px 1.2em !important;">The results of
our findings are described in this document:</p>
<p style="margin: 0px 0px 1.2em !important;"><a href="http://cr.openjdk.java.net/~mcimadamore/panama/scoped_arenas.html" class="moz-txt-link-freetext">http://cr.openjdk.java.net/~mcimadamore/panama/scoped_arenas.html</a></p>
<p style="margin: 0px 0px 1.2em !important;">Here, we propose
a possible simplification of the FFM API, where we<br>
make <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">Arena</code>
the true star of the show, which results in the<br>
following changes:</p>
<ul style="margin: 1.2em 0px;padding-left: 2em;">
<li style="margin: 0.5em 0px;">factories such as <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">SegmentScope::auto</code>
are now moved to <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">Arena</code>;
</li>
<li style="margin: 0.5em 0px;">all segment-producing methods
(such as <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">FileChannel::map</code>)
now<br>
accept an <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">Arena</code>
parameter; <em> static factories such as<br>
<code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">MemorySegment::allocateNative</code>
have been dropped; </em> scopes are<br>
made less prominent, and moved to a nested class<br>
(<code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">MemorySegment.Scope</code>).</li>
</ul>
<p style="margin: 0px 0px 1.2em !important;">This gives us a
remarkably simple API, which brings together the<br>
best aspects of the Java 19 and Java 20 FFM API iterations.
On the<br>
one hand, <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">Arena</code>
is now the most important abstraction that users<br>
of the FFM API have to deal with (in a way, <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">Arena</code>
is the new<br>
<code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">MemorySession</code>);
at the same time, we still have a way to model<br>
the lifetime of an <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">Arena</code>
(and all the segments allocated by it)<br>
using a <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">MemorySegment.Scope</code>
- which is desirable both in terms of<br>
debugging (e.g. inspecting whether two segments/arenas have
the<br>
same lifetime) and, more importantly, in terms of allowing
the<br>
definition of custom arenas via simple delegation (as in
Java 20).</p>
<p style="margin: 0px 0px 1.2em !important;">As always,
feedback is welcome. While this proposal does not<br>
significantly alter the expressiveness of the FFM API, the
proposed<br>
API comes with some limitations. For instance, since all
allocation<br>
routines are now <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">Arena</code>-centric
(see above), it is no longer<br>
possible to allocate a new segment if a corresponding arena
is not<br>
available (we call this co-allocation). As explained in the<br>
document, while it would be possible to add back the missing<br>
co-allocation functionality, extensive analysis of the code
using<br>
the FFM API has shown co-allocation to be <em>extremely</em>
rare (**) -<br>
and of dubious value. For these reasons, we would like to
aim for a<br>
more principled approach which avoids co-allocation
altogether, and<br>
allows for more encapsulation of the capabilities associated
with<br>
an <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">Arena</code>
object.</p>
<p style="margin: 0px 0px 1.2em !important;">Maurizio</p>
<p style="margin: 0px 0px 1.2em !important;">(**) We have only
found <em>one</em> usage [2] in over 10K Java files and<br>
more than 11M LoC analyzed. Moreover, this usage is only
present in<br>
the Java 19 branch of the project, and removed in the “main”
branch<br>
(which tracks the Java 20 FFM API). We suspect that this use
of<br>
co-allocation has been made irrelevant after the unification
of<br>
<code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">MemoryAddress</code>
and <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">MemorySegment</code>.</p>
<p style="margin: 0px 0px 1.2em !important;">[1] -<br>
<a href="https://mail.openjdk.org/pipermail/panama-dev/2022-December/018182.html" class="moz-txt-link-freetext">https://mail.openjdk.org/pipermail/panama-dev/2022-December/018182.html</a></p>
<p style="margin: 0px 0px 1.2em !important;">[2] - <a href="https://urldefense.com/v3/__https://github.com/boulder-on/JPassport/blob/Java_19/jpassport/src/main/java/jpassport/Utils.java*L418__;Iw!!ACWV5N9M2RV99hQ!N83lUkxsLt0-52DJ28iFtyghkVYTBrkIqpba_S_rHp-LgkOjS11XHE2aNR0-4t77U_S3UqP_HU-K1tufeLRhfQs$" class="moz-txt-link-freetext">https://urldefense.com/v3/__https://github.com/boulder-on/JPassport/blob/Java_19/jpassport/src/main/java/jpassport/Utils.java*L418__;Iw!!ACWV5N9M2RV99hQ!N83lUkxsLt0-52DJ28iFtyghkVYTBrkIqpba_S_rHp-LgkOjS11XHE2aNR0-4t77U_S3UqP_HU-K1tufeLRhfQs$</a>
</p>
</blockquote>
</blockquote>
<div title="MDH:PGJyPk9uIDAyLzAyLzIwMjMgMTM6MTUsIHJhZGVrQHNtb2d1cmEuZXUgd3JvdGU6PGJyPjxzcGFuIHN0eWxlPSJ3aGl0ZS1zcGFjZTogcHJlLXdyYXA7IGRpc3BsYXk6IGJsb2NrOyB3aWR0aDogOTh2
dzsiPiZndDsgSGkgTWF1cml6aW8sPGJyPiZndDsgPGJyPiZndDsgVGhhbmsgeW91IGZvciBzaGFy
aW5nIHRoaXMuIEkgYWdyZWUgdGhhdCB0aGVyZeKAmXMgYSB0ZW5zaW9uIGJldHdlZW48YnI+Jmd0
OyBTY29wZSBhbmQgQXJlbmEsIGFuZCBmb3IgaS5lLiBwYXNzaW5nIEFyZW5hIHRvIEZpbGVDaGFu
bmVsOjptYXAgbG9vazxicj4mZ3Q7IGJpdCBsaWtlIHdlIHBhc3MgdG9vIGJpZyBvYmplY3QgdGhl
cmUuPGJyPiZndDsgPGJyPiZndDsgSSBqdXN0IHRob3VnaHQgKHNvcnJ5IGlmIGl0IHdhcyBwcm9w
b3NlZCBzb21ld2hlcmUgZWxzZSksIHRvPGJyPiZndDsgaW50cm9kdWNlIHN1cHBvcnRpbmcgb2Jq
ZWN0IFNjb3BhYmxlIChjYW7igJl0IGltYWdpbmUgYmV0dGVyIG5hbWUgb248YnI+Jmd0OyBzaG9y
dCBub3RpY2UpLiBTbyBzb21ldGhpbmcgd2hpY2ggY2FuIGhhdmUgYSBzY29wZSAob3duIC0gZnJl
c2hseTxicj4mZ3Q7IGdlbmVyYXRlZCBvciBzaGFyZWQgaW4gc29tZSB3YXkpLjxicj4mZ3Q7IDxi
cj4mZ3Q7IFRoZSBTY29wYWJsZSB3b3VsZCBoYXZlIHNpbmdsZSBtZXRob2Qgc2NvcGUoKSwgYW5k
IGZvciBzaW1wbGljaXR5PGJyPiZndDsgU2NvcGUgY291bGQgYmUgU2NvcGFibGUgcmV0dXJuaW5n
IOKAnHRoaXMiLjxicj4mZ3Q7IDxicj4mZ3Q7IElmIE1lbW9yeVNlZ21lbnQgc2hvdWxkIGJlIFNj
b3BhYmxlIC0gSSBkb27igJl0IGtub3cgLSBhcyB0aGVyZeKAmXMgbmV4dDxicj4mZ3Q7IGlzc3Vl
IG9mIGFsbG9jYXRpbmcgc2VnbWVudHMgd2hpY2ggYXJlIGRlcGVuZGVudCBpbiBzb21lIHdheSBh
bmQ8YnI+Jmd0OyBkZWFsbG9jYXRpb24gc2hvdWxkIGJlIGV4ZWN1dGVkIGluIG9yZGVyLjxicj48
L3NwYW4+PGJyPkhpIFJhZG8sPGJyPlRoYW5rcyBmb3IgdGhlIGNvbW1lbnRzLiBIYXZpbmcgYSBj
b21tb24gaW50ZXJmYWNlIGZvciBhbGwgdGhpbmdzIHdpdGggYSBzY29wZSBhY2Nlc3NvciBpcyBw
b3NzaWJsZSwgYW5kIHNvbWV0aGluZyB3ZSBoYXZlIGNvbnNpZGVyZWQgdG8gYnJpbmcgQXJlbmEg
YW5kIFNlZ21lbnRTY29wZSB1bmRlciB0aGUgc2FtZSB1bWJyZWxsYS48YnI+PGJyPlRoZSBtYWlu
IHByb2JsZW0gdGhvdWdoLCBpcyB3aGVyZSBkbyB5b3UgcHV0IHRoZSAiYWxsb2NhdGUiIG1ldGhv
ZC4gSXQgaXMgdW5mb3J0dW5hdGUgdGhhdCwgaW4gdGhlIEphdmEgMjAgQVBJLCB0aGVyZSBhcmUg
X3RocmVlXyB3YXlzIHRvIGFsbG9jYXRlIGEgbmF0aXZlIHNlZ21lbnQ6PGJyPjxicj5gYGA8YnI+
TWVtb3J5U2VnbWVudC5hbGxvY2F0ZU5hdGl2ZSgxMDAsIGFyZW5hLnNjb3BlKCkpIC8vIDE8YnI+
PGJyPmFyZW5hLmFsbG9jYXRlKDEwMCkgLy8gMjxicj48YnI+U2VnbWVudEFsbG9jYXRvci5uYXRp
dmVBbGxvY2F0b3IoYXJlbmEuc2NvcGUoKSkuYWxsb2NhdGUoMTAwKTsgLy8gMzxicj5gYGA8YnI+
PGJyPlRoaXMgc2VlbXMgb3ZlcmtpbGwsIGFuZCBhZGRpbmcgYW4gaW50ZXJmYWNlIG9uIHRvcCBv
ZiBBcmVuYSBhbmQgU2VnbWVudFNjb3BlIGRvZXNuJ3QgaGVscCBtdWNoLiBXZWxsLCBTY29wZWFi
bGUgbWlnaHQgYWxzbyBleHRlbmQgU2VnbWVudEFsbG9jYXRvciwgc28geW91IGNhbiBkbzo8YnI+
PGJyPmBgYDxicj5TZWdtZW50U2NvcGUuYXV0bygpLmFsbG9jYXRlKDEwMCk8YnI+YGBgPGJyPjxi
cj5CdXQgbm93IHRoaXMgY3JlYXRlcyBhbiBpc3N1ZTogaWYgYSBzY29wZSBpcyBhbiBhbGxvY2F0
b3IsIHRoZW4gYW4gQXJlbmEgcHJvdmlkZXMgX3R3b18gYWxsb2NhdG9yczogdGhlIGFsbG9jYXRv
ciBpbiBpdHMgImFsbG9jYXRlIiBtZXRob2QsIGFuZCB0aGUgImZhbGxiYWNrIiBhbGxvY2F0b3Is
IGF2YWlsYWJsZSBhY2Nlc3NpbmcgdGhlIGFyZW5hJ3Mgc2NvcGUuPGJyPjxicj5UaGlzIHNlZW1l
ZCBvdmVybHkgY29uZnVzaW5nLjxicj48YnI+VGhlcmUncyBhbHNvIGFub3RoZXIgYXNwZWN0IGlu
IHRoaXM6IHdoYXQgd2UgY2FsbCBTZWdtZW50U2NvcGUuYXV0bygpIHJlYWxseSBkb2VzIGFjdCBh
cyBhbiBhcmVuYSAoYXMgdGhlIGRvY3VtZW50IGV4cGxhaW5zKSAtIGp1c3Qgb25lIHRoYXQgY2Fu
bm90IGJlIGNsb3NlZCBleHBsaWNpdGx5LiBTbyBoYXZpbmcgdG9vIG11Y2ggc3BsaXR0aW5nIGlu
IHRoZSBBUEkgc2VlbXMgdG8gY3JlYXRlIHVubmVjZXNzYXJ5IGFzeW1tZXRyaWVzIGFuZCBub24t
b3J0aG9nb25hbGl0eS48YnI+PGJyPk9uY2UgeW91IGVtYnJhY2UgdGhlIGZhY3QgdGhhdCBBcmVu
YSBpcyB5b3VyIHVuaXQgb2YgYWxsb2NhdGlvbiBmb3IgbmF0aXZlIHNlZ21lbnRzLCBldmVyeXRo
aW5nIGJlY29tZXMgZWFzaWVyLiBJbiB0aGUgQVBJIHByb3Bvc2VkIGluIHRoZSBkb2N1bWVudCB0
aGVyZSBpcyBub3cgb25seSBfb25lXyB3YXkgdG8gYWxsb2NhdGUgYSBuYXRpdmUgc2VnbWVudCwg
bmFtZWx5IEFyZW5hOjphbGxvY2F0ZS48YnI+PGJyPlAuUy48YnI+PGJyPlJlbGF0ZWQgdG8gdGhp
cywgd2UgYWxzbyBjb25zaWRlcmVkIGFkZGluZyBhIFNjb3BlYWJsZS9TY29wZWQgaW50ZXJmYWNl
IChpbXBsZW1lbnRlZCBieSBNZW1vcnlTZWdtZW50KSBpbnN0ZWFkIG9mIGEgc2VwYXJhdGUgIlNj
b3BlIiBpbnRlcmZhY2UuIFdoaWxlIGluaXRpYWxseSBhcHBlYWxpbmcsIGFzOjxicj48YnI+YGBg
PGJyPnNlZ21lbnQuaXNBbGl2ZSgpPGJyPmBgYDxicj48YnI+U2VlbXMgYmV0dGVyIHRoYW46PGJy
Pjxicj5gYGA8YnI+c2VnbWVudC5zY29wZSgpLmlzQWxpdmUoKTxicj5gYGA8YnI+PGJyPlRoYXQg
YXBwcm9hY2ggc3RhcnRzIHJ1bm5pbmcgb3V0IG9mIGdhcyB3aGVuIHlvdSBjb25zaWRlciB0aGlu
Z3MgbGlrZSAiaG93IGRvIHlvdSBjb21wYXJlIHRoZSBsaWZldGltZSBvZiB0d28gU2NvcGVkL1Nj
b3BlYWJsZSIgPyBZb3UgY2FuJ3QgdXNlICJlcXVhbHMiIChhcyBlcXVhbHMgb24gTWVtb3J5U2Vn
bWVudCBtZWFucyBzb21ldGhpbmcgZWxzZSkgLSBzbyB5b3UgZW5kIHVwIHdpdGggc29tZXRoaW5n
IGxpa2UgdGhpczo8YnI+PGJyPmBgYDxicj5zZWdtZW50LmlzTGlmZXRpbWVFcXVhbHMoLi4uLik8
YnI+YGBgPGJyPjxicj5vciwgaWYgd2UgYWxzbyBjb25zaWRlciBsaWZldGltZSBjb250YWlubWVu
dDo8YnI+PGJyPmBgYDxicj5zZWdtZW50LmlzTGlmZXRpbWVDb250YWluZWRCeSguLi4uKTxicj5g
YGA8YnI+PGJyPkJvdGggb2Ygd2hpY2ggc2VlbXMgbGVzcyBkaXJlY3QgdGhhbjo8YnI+PGJyPmBg
YDxicj5zZWdtZW50LnNjb3BlKCkuZXF1YWxzKC4uLik8YnI+YGBgPGJyPjxicj5vcjxicj48YnI+
YGBgPGJyPnNlZ21lbnQuc2NvcGUoKS5jb250YWluZWRCeSguLi4pPGJyPmBgYDxicj48YnI+T24g
dG9wIG9mIHRoYXQsIHNpbmNlIG5vdyBBcmVuYSBkb2VzIG5vdCBoYXZlIGEgc2NvcGUsIGJ1dCBf
aXNfIGEgc2NvcGUsIHdlIG5lZWQgdG8gbWFrZSBhcmVuYSBhbiBhYnN0cmFjdCBjbGFzcywgd2hp
Y2ggc29tZXdoYXQgbGltaXRzIGV4dGVuc2lvbiBvcHRpb25zIGZvciBjbGllbnRzLjxicj48YnI+
U28gd2UgaGF2ZSBjb25jbHVkZWQgdGhhdCBrZWVwaW5nIGEgc21hbGwgc2NvcGUgaW50ZXJmYWNl
IG9mZiB0byB0aGUgc2lkZSAoTWVtb3J5U2VnbWVudC5TY29wZSkgcmVwcmVzZW50ZWQgdGhlIG1v
c3QgcHJhZ21hdGljIGNvbXByb21pc2UuPGJyPjxicj5NYXVyaXppbzxicj48YnI+PGJyPjxzcGFu
IHN0eWxlPSJ3aGl0ZS1zcGFjZTogcHJlLXdyYXA7IGRpc3BsYXk6IGJsb2NrOyB3aWR0aDogOTh2
dzsiPiZndDsgS2luZCByZWdhcmRzLCBSYWRvc8WCYXcgU21vZ3VyYTxicj4mZ3Q7IDxicj4mZ3Q7
Jmd0OyBPbiAzMSBKYW4gMjAyMywgYXQgMTk6NDYsIE1hdXJpemlvIENpbWFkYW1vcmU8YnI+Jmd0
OyZndDsgJmx0O21hdXJpemlvLmNpbWFkYW1vcmVAb3JhY2xlLmNvbSZndDsgd3JvdGU6PGJyPiZn
dDsmZ3Q7IDxicj4mZ3Q7Jmd0OyBIaSwgYXMgZGlzY3Vzc2VkIGhlcmUgWzFdLCBpdCBpcyBub3Qg
Y2xlYXIgYXMgdG8gd2hldGhlciBKYXZhIDIwPGJyPiZndDsmZ3Q7IGl0ZXJhdGlvbiBvZiB0aGUg
Rm9yZWlnbiBGdW5jdGlvbiAmYW1wOyBNZW1vcnkgQVBJIChGRk0gQVBJKSBoYXMgeWV0PGJyPiZn
dDsmZ3Q7IHJlYWNoZWQgYm90dG9tLCBlc3BlY2lhbGx5IHdoZW4gaXQgY29tZXMgdG8gbWFuYWdp
bmcgdGhlIGxpZmV0aW1lPGJyPiZndDsmZ3Q7IG9mIHRoZSByZWdpb25zIG9mIG1lbW9yeSBiYWNr
aW5nIG1lbW9yeSBzZWdtZW50cy4gQWZ0ZXIgY29sbGVjdGluZzxicj4mZ3Q7Jmd0OyBzb21lIHJv
dW5kcyBvZiBpbnRlcm5hbCBhbmQgZXh0ZXJuYWwgZmVlZGJhY2ssIGl0IHdhcyBjbGVhciB0aGF0
PGJyPiZndDsmZ3Q7IHdoaWxlIHRoZSBKYXZhIDIwIEFQSSBoYXMgYWxsIHRoZSBmdW5jdGlvbmFs
aXRpZXMgd2UgcmVxdWlyZSBmb3I8YnI+Jmd0OyZndDsgd3JpdGluZyBlZmZpY2llbnQgYW5kIHJv
YnVzdCBuYXRpdmUgaW50ZXJvcCBjb2RlLCBzb21lIG9mIHRoZTxicj4mZ3Q7Jmd0OyBjb25jZXB0
cyBpbiB0aGUgQVBJIHdlcmUgbWFkZSBhIGJpdCBoYXJkZXIgdG8gZ3JvaywgYXMgdXNlcnMgaGFk
IHRvPGJyPiZndDsmZ3Q7IGNob29zZSBiZXR3ZWVuIHR3byB0b3BsZXZlbCBhYnN0cmFjdGlvbnMs
IG5hbWVseSBgU2VnbWVudFNjb3BlYCBhbmQ8YnI+Jmd0OyZndDsgYEFyZW5hYC4gVGhpcyBjaG9p
Y2UgaXMgbWFkZSBldmVuIG1vcmUgZGlmZmljdWx0LCBhcyBzb21lIG9mIHRoZTxicj4mZ3Q7Jmd0
OyBmdW5jdGlvbmFsaXRpZXMgKGUuZy4gYWxsb2NhdGlvbikgaXMgZHVwbGljYXRlZCBpbiBib3Ro
IEFQSSBwb2ludHMuPGJyPiZndDsmZ3Q7IEFzIGEgcmVzdWx0LCB3ZSBoYXZlIGJlZW4gYnVzeSBl
eHBsb3JpbmcgZGlmZmVyZW50IHdheXMgdG8gcmVzdGFjazxicj4mZ3Q7Jmd0OyB0aGUgRkZNIEFQ
SSBpbiBzZWFyY2ggb2Ygc29tZXRoaW5nIG1vcmUgYXBwcm9hY2hhYmxlLjxicj4mZ3Q7Jmd0OyA8
YnI+Jmd0OyZndDsgVGhlIHJlc3VsdHMgb2Ygb3VyIGZpbmRpbmdzIGFyZSBkZXNjcmliZWQgaW4g
dGhpcyBkb2N1bWVudDo8YnI+Jmd0OyZndDsgPGJyPiZndDsmZ3Q7IGh0dHA6Ly9jci5vcGVuamRr
LmphdmEubmV0L35tY2ltYWRhbW9yZS9wYW5hbWEvc2NvcGVkX2FyZW5hcy5odG1sPGJyPiZndDsm
Z3Q7IDxicj4mZ3Q7Jmd0OyBIZXJlLCB3ZSBwcm9wb3NlIGEgcG9zc2libGUgc2ltcGxpZmljYXRp
b24gb2YgdGhlIEZGTSBBUEksIHdoZXJlIHdlPGJyPiZndDsmZ3Q7IG1ha2UgYEFyZW5hYCB0aGUg
dHJ1ZSBzdGFyIG9mIHRoZSBzaG93LCB3aGljaCByZXN1bHRzIGluIHRoZTxicj4mZ3Q7Jmd0OyBm
b2xsb3dpbmcgY2hhbmdlczo8YnI+Jmd0OyZndDsgPGJyPiZndDsmZ3Q7ICogZmFjdG9yaWVzIHN1
Y2ggYXMgYFNlZ21lbnRTY29wZTo6YXV0b2AgYXJlIG5vdyBtb3ZlZCB0byBgQXJlbmFgOyA8YnI+
Jmd0OyZndDsgKiBhbGwgc2VnbWVudC1wcm9kdWNpbmcgbWV0aG9kcyAoc3VjaCBhcyBgRmlsZUNo
YW5uZWw6Om1hcGApIG5vdzxicj4mZ3Q7Jmd0OyBhY2NlcHQgYW4gYEFyZW5hYCBwYXJhbWV0ZXI7
ICogc3RhdGljIGZhY3RvcmllcyBzdWNoIGFzPGJyPiZndDsmZ3Q7IGBNZW1vcnlTZWdtZW50Ojph
bGxvY2F0ZU5hdGl2ZWAgaGF2ZSBiZWVuIGRyb3BwZWQ7ICogc2NvcGVzIGFyZTxicj4mZ3Q7Jmd0
OyBtYWRlIGxlc3MgcHJvbWluZW50LCBhbmQgbW92ZWQgdG8gYSBuZXN0ZWQgY2xhc3M8YnI+Jmd0
OyZndDsgKGBNZW1vcnlTZWdtZW50LlNjb3BlYCkuPGJyPiZndDsmZ3Q7IDxicj4mZ3Q7Jmd0OyBU
aGlzIGdpdmVzIHVzIGEgcmVtYXJrYWJseSBzaW1wbGUgQVBJLCB3aGljaCBicmluZ3MgdG9nZXRo
ZXIgdGhlPGJyPiZndDsmZ3Q7IGJlc3QgYXNwZWN0cyBvZiB0aGUgSmF2YSAxOSBhbmQgSmF2YSAy
MCBGRk0gQVBJIGl0ZXJhdGlvbnMuIE9uIHRoZTxicj4mZ3Q7Jmd0OyBvbmUgaGFuZCwgYEFyZW5h
YCBpcyBub3cgdGhlIG1vc3QgaW1wb3J0YW50IGFic3RyYWN0aW9uIHRoYXQgdXNlcnM8YnI+Jmd0
OyZndDsgb2YgdGhlIEZGTSBBUEkgaGF2ZSB0byBkZWFsIHdpdGggKGluIGEgd2F5LCBgQXJlbmFg
IGlzIHRoZSBuZXc8YnI+Jmd0OyZndDsgYE1lbW9yeVNlc3Npb25gKTsgYXQgdGhlIHNhbWUgdGlt
ZSwgd2Ugc3RpbGwgaGF2ZSBhIHdheSB0byBtb2RlbDxicj4mZ3Q7Jmd0OyB0aGUgbGlmZXRpbWUg
b2YgYW4gYEFyZW5hYCAoYW5kIGFsbCB0aGUgc2VnbWVudHMgYWxsb2NhdGVkIGJ5IGl0KTxicj4m
Z3Q7Jmd0OyB1c2luZyBhIGBNZW1vcnlTZWdtZW50LlNjb3BlYCAtIHdoaWNoIGlzIGRlc2lyYWJs
ZSBib3RoIGluIHRlcm1zIG9mPGJyPiZndDsmZ3Q7IGRlYnVnZ2luZyAoZS5nLiBpbnNwZWN0aW5n
IHdoZXRoZXIgdHdvIHNlZ21lbnRzL2FyZW5hcyBoYXZlIHRoZTxicj4mZ3Q7Jmd0OyBzYW1lIGxp
ZmV0aW1lKSBhbmQsIG1vcmUgaW1wb3J0YW50bHksIGluIHRlcm1zIG9mIGFsbG93aW5nIHRoZTxi
cj4mZ3Q7Jmd0OyBkZWZpbml0aW9uIG9mIGN1c3RvbSBhcmVuYXMgdmlhIHNpbXBsZSBkZWxlZ2F0
aW9uIChhcyBpbiBKYXZhIDIwKS48YnI+Jmd0OyZndDsgPGJyPiZndDsmZ3Q7IEFzIGFsd2F5cywg
ZmVlZGJhY2sgaXMgd2VsY29tZS4gV2hpbGUgdGhpcyBwcm9wb3NhbCBkb2VzIG5vdDxicj4mZ3Q7
Jmd0OyBzaWduaWZpY2FudGx5IGFsdGVyIHRoZSBleHByZXNzaXZlbmVzcyBvZiB0aGUgRkZNIEFQ
SSwgdGhlIHByb3Bvc2VkPGJyPiZndDsmZ3Q7IEFQSSBjb21lcyB3aXRoIHNvbWUgbGltaXRhdGlv
bnMuIEZvciBpbnN0YW5jZSwgc2luY2UgYWxsIGFsbG9jYXRpb248YnI+Jmd0OyZndDsgcm91dGlu
ZXMgYXJlIG5vdyBgQXJlbmFgLWNlbnRyaWMgKHNlZSBhYm92ZSksIGl0IGlzIG5vIGxvbmdlcjxi
cj4mZ3Q7Jmd0OyBwb3NzaWJsZSB0byBhbGxvY2F0ZSBhIG5ldyBzZWdtZW50IGlmIGEgY29ycmVz
cG9uZGluZyBhcmVuYSBpcyBub3Q8YnI+Jmd0OyZndDsgYXZhaWxhYmxlICh3ZSBjYWxsIHRoaXMg
Y28tYWxsb2NhdGlvbikuIEFzIGV4cGxhaW5lZCBpbiB0aGU8YnI+Jmd0OyZndDsgZG9jdW1lbnQs
IHdoaWxlIGl0IHdvdWxkIGJlIHBvc3NpYmxlIHRvIGFkZCBiYWNrIHRoZSBtaXNzaW5nPGJyPiZn
dDsmZ3Q7IGNvLWFsbG9jYXRpb24gZnVuY3Rpb25hbGl0eSwgZXh0ZW5zaXZlIGFuYWx5c2lzIG9m
IHRoZSBjb2RlIHVzaW5nPGJyPiZndDsmZ3Q7IHRoZSBGRk0gQVBJIGhhcyBzaG93biBjby1hbGxv
Y2F0aW9uIHRvIGJlIF9leHRyZW1lbHlfIHJhcmUgKCoqKSAtPGJyPiZndDsmZ3Q7IGFuZCBvZiBk
dWJpb3VzIHZhbHVlLiBGb3IgdGhlc2UgcmVhc29ucywgd2Ugd291bGQgbGlrZSB0byBhaW0gZm9y
IGE8YnI+Jmd0OyZndDsgbW9yZSBwcmluY2lwbGVkIGFwcHJvYWNoIHdoaWNoIGF2b2lkcyBjby1h
bGxvY2F0aW9uIGFsdG9nZXRoZXIsIGFuZDxicj4mZ3Q7Jmd0OyBhbGxvd3MgZm9yIG1vcmUgZW5j
YXBzdWxhdGlvbiBvZiB0aGUgY2FwYWJpbGl0aWVzIGFzc29jaWF0ZWQgd2l0aDxicj4mZ3Q7Jmd0
OyBhbiBgQXJlbmFgIG9iamVjdC48YnI+Jmd0OyZndDsgPGJyPiZndDsmZ3Q7IE1hdXJpemlvPGJy
PiZndDsmZ3Q7IDxicj4mZ3Q7Jmd0OyAoKiopIFdlIGhhdmUgb25seSBmb3VuZCBfb25lXyB1c2Fn
ZSBbMl0gaW4gb3ZlciAxMEsgSmF2YSBmaWxlcyBhbmQ8YnI+Jmd0OyZndDsgbW9yZSB0aGFuIDEx
TSBMb0MgYW5hbHl6ZWQuIE1vcmVvdmVyLCB0aGlzIHVzYWdlIGlzIG9ubHkgcHJlc2VudCBpbjxi
cj4mZ3Q7Jmd0OyB0aGUgSmF2YSAxOSBicmFuY2ggb2YgdGhlIHByb2plY3QsIGFuZCByZW1vdmVk
IGluIHRoZSAibWFpbiIgYnJhbmNoPGJyPiZndDsmZ3Q7ICh3aGljaCB0cmFja3MgdGhlIEphdmEg
MjAgRkZNIEFQSSkuIFdlIHN1c3BlY3QgdGhhdCB0aGlzIHVzZSBvZjxicj4mZ3Q7Jmd0OyBjby1h
bGxvY2F0aW9uIGhhcyBiZWVuIG1hZGUgaXJyZWxldmFudCBhZnRlciB0aGUgdW5pZmljYXRpb24g
b2Y8YnI+Jmd0OyZndDsgYE1lbW9yeUFkZHJlc3NgIGFuZCBgTWVtb3J5U2VnbWVudGAuPGJyPiZn
dDsmZ3Q7IDxicj4mZ3Q7Jmd0OyBbMV0gLTxicj4mZ3Q7Jmd0OyBodHRwczovL21haWwub3Blbmpk
ay5vcmcvcGlwZXJtYWlsL3BhbmFtYS1kZXYvMjAyMi1EZWNlbWJlci8wMTgxODIuaHRtbDxicj4m
Z3Q7Jmd0Ozxicj4mZ3Q7Jmd0OyA8YnI+PC9zcGFuPlsyXSAtIGh0dHBzOi8vdXJsZGVmZW5zZS5j
b20vdjMvX19odHRwczovL2dpdGh1Yi5jb20vYm91bGRlci1vbi9KUGFzc3BvcnQvYmxvYi9KYXZh
XzE5L2pwYXNzcG9ydC9zcmMvbWFpbi9qYXZhL2pwYXNzcG9ydC9VdGlscy5qYXZhKkw0MThfXztJ
dyEhQUNXVjVOOU0yUlY5OWhRIU44M2xVa3hzTHQwLTUyREoyOGlGdHlnaGtWWVRCcmtJcXBiYV9T
X3JIcC1MZ2tPalMxMVhIRTJhTlIwLTR0NzdVX1MzVXFQX0hVLUsxdHVmZUxSaGZRcyQgPGJyPjxz
cGFuIHN0eWxlPSJ3aGl0ZS1zcGFjZTogcHJlLXdyYXA7IGRpc3BsYXk6IGJsb2NrOyB3aWR0aDog
OTh2dzsiPiZndDsmZ3Q7IDxicj4mZ3Q7Jmd0OyA8YnI+Jmd0OyZndDsgPGJyPiZndDsmZ3Q7IDxi
cj4mZ3Q7Jmd0OyA8YnI+Jmd0OyZndDsgPGJyPjwvc3Bhbj48YnI+" style="height:0;width:0;max-height:0;max-width:0;overflow:hidden;font-size:0em;padding:0;margin:0;"></div>
</div>
</body>
</html>