<div dir="ltr"><div dir="ltr"><div class="gmail_default" style="font-size:small"><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Apr 18, 2022 at 3:05 AM Marcel Taeumel <<a href="mailto:marcel.taeumel@hpi.de">marcel.taeumel@hpi.de</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div><div id="gmail-m_257425249764720969__MailbirdStyleContent" style="font-size:10pt;font-family:Arial;color:rgb(0,0,0);text-align:left" dir="ltr">
Hi <span style="font-family:Arial,Helvetica,sans-serif;font-size:13px">Michał --</span><div><br></div><div>> <span style="font-family:Arial,Helvetica,sans-serif;font-size:13px">Or should I not worry about that it will perform full GC (thus Image freeze) more frequently?</span></div><div><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px"><br></span></div><div><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px">If you pin too many objects, you will annoy the compactor. This cannot be "fixed" in a full GC as far as I know. Be sure to unpin those objects in time. Only pin objects if you have to.</span></div></div></div></blockquote><div><br></div><div class="gmail_default" style="font-size:small">That said, the memory manager does try to pin objects in a single segment, so it shouldn't get too annoyed :-).</div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small">However, ideally the marshalling logic in the FFI plugin would do the pinning and unpinning for you, automatically. The issues here are specification and backwards compatibility. The current marshalling semantics derive from the old "V3" VM's memory manager which didn't support pinning. Andreas (its author) explicitly forbade passing an external pointer to an object on the heap. With pinning support I think we would like to relax this restriction, but how far? For example, it could be that one is only allowed to pass a pointer into the heap if that pointer is to an already pinned object, which might provide more safety than allowing passing a pointer to any byte-like object. There is also an important aliasing issue; C strings need to be null-terminated, and the size of the null marker depends on string encoding. Currently the FFI plugin copies string parameters, assumes they're 8 bit, and null terminates the copies. This is only appropriate in some circumstances. In others we'd like to include the null marker in the actual object itself, pin and pass a pointer to that object. But how do we specify these strategies?</div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small">One approach is to extend the current plugin, and experience shows that this is likely the only way to make measurable progress. Another way is to move the marshalling boundary so that more can be done at the image level, simplifying the plugin and moving these policy issues up to the image level where we can implement these various policies more effectively and flexibly. But experience shows that aiming at the ambitious "right solution" is simply a way of grinding to a complete halt (given that we have so little resource).</div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small">But do know that at least Marcel and myself are interested in enhancing the FFI significantly.</div><div class="gmail_default" style="font-size:small"><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div><div id="gmail-m_257425249764720969__MailbirdStyleContent" style="font-size:10pt;font-family:Arial;color:rgb(0,0,0);text-align:left" dir="ltr"><div><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px"><br></span></div><div><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px">Best,</span></div><div><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px">Marcel</span></div><div></div><blockquote type="cite" style="border-left-style:solid;border-width:1px;margin-top:20px;margin-left:0px;padding-left:10px">
<p style="color:rgb(170,170,170);margin-top:10px">Am 17.04.2022 14:07:22 schrieb Michał Olszewski <<a href="mailto:m.olszewski@nexat.pl" target="_blank">m.olszewski@nexat.pl</a>>:</p><div style="font-family:Arial,Helvetica,sans-serif">
<p>Hi,</p>
<p>Thanks for the answers. I'd like to ask one more question, out of
curiosity. <br>
</p>
<p>Does allocating (and pinning them) a large (possibly very large)
instances of RawBitsArray (Float64, ByteArray etc. for storing,
say, textures) puts significant pressure on GC during garbage
collection? Or should I not worry about that it will perform full
GC (thus Image freeze) more frequently?<br>
</p>
<p>Michał<br>
</p>
<div>W dniu 06.04.2022 o 08:31, Marcel
Taeumel pisze:<br>
</div>
<blockquote type="cite">
<div id="gmail-m_257425249764720969__MailbirdStyleContent" style="font-size:10pt;font-family:Arial;color:rgb(0,0,0);text-align:left" dir="ltr"> Hi <span style="font-family:Arial,Helvetica,sans-serif;font-size:13px">Michał --</span>
<div><br>
</div>
<div>> <span style="font-family:Arial,Helvetica,sans-serif;font-size:13px">Have you considered simplifying
FFI interface, where callout (the primitive) would only
handle raw bytes (along with argument sizes), without type
checking?</span></div>
<div><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px"><br>
</span></div>
<div><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px">An approach without type
checking would be the Alien FFI. </span><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px">Here is Alien: </span><a href="http://www.squeaksource.com/Alien" style="font-size:10pt" target="_blank"><span style="font-size:10pt;font-family:Arial,Helvetica,sans-serif">http://www.squeaksource.com/Alien</span></a><span style="font-family:Arial,Helvetica,sans-serif"> </span><span style="font-size:10pt">The required IA32ABI plugin is also
part of the OpenSmalltalk VM.</span></div>
<div><br>
</div>
<div><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px">Squeak FFI wants to make FFI
programming more robust and better integrated into the
object-oriented world with its tools. Besides these
particular inconveniences you just experienced, the goal is
to make that FFI interface with ExternalType very simple and
straightforward. And robust. :-)</span><br>
</div>
<div><br>
</div>
<div>> <span style="font-family:Arial,Helvetica,sans-serif;font-size:13px">Maybe some support for
auto-pinning objects that are passed to FFI?</span></div>
<div><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px"><br>
</span></div>
<div><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px">Maybe there already is around
FFI callbacks. Not sure.</span></div>
<div><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px"><br>
</span></div>
<div><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px">> </span><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px">It's not like sending #pin is a big deal.</span></div>
<div><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px"><br>
</span></div>
<div><span style="font-family:Arial,Helvetica,sans-serif"><span style="font-size:13px">It sure is. It takes time. If you,
for example, want to program a graphics back-end through
FFI you need all the performance you can get. And too much
pinning might annoy the GC compaction phase. :-)</span></span></div>
<div><br>
</div>
<div>Best,</div>
<div>Marcel</div>
<blockquote type="cite" style="border-left-style:solid;border-width:1px;margin-top:20px;margin-left:0px;padding-left:10px;min-width:500px">
<p style="color:rgb(170,170,170);margin-top:10px">Am 05.04.2022
18:50:59 schrieb Michał Olszewski
<a href="mailto:m.olszewski@nexat.pl" target="_blank"><m.olszewski@nexat.pl></a>:</p>
<div style="font-family:Arial,Helvetica,sans-serif">
<p>Hi,</p>
<p> </p>
<blockquote type="cite" style="min-width:500px"><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px">The type model for pointer
types with arity > 1 is still rudimentary. You can
always go the unsafe way to code against 'void*'. In
your case, the type 'char*[]' gives you an array type
with a 'char*' content type. Not sure whether type
coercing will work during the FFI call. You can also use
the 'string[]' type for that matter. Again, if you get a
type check error on the call, you might have to resort
to 'void*' instead and pass on that ExternalAddress your
have at hand.</span></blockquote>
Yes, I did it, sorta. I allocated external bytes, copied the
string to them (along with null terminator), put the
handle's bytes into intptr_t type (a := ExternalType
intptr_t allocate. a at: 1 put: h getHandle asInteger), then
passed that one to the call. <br>
<p>But I thought I could get away with only using
in-squeak-memory objects (i.e. no external memory
allocations since it's a bit of a pain to handle them
across the methods).</p>
<p><br>
</p>
<p>I have a suggestion, it may not matter much, after all
you're much more familiar with Squeak internals (and far
more experienced in programming overall). <br>
</p>
<p>Have you considered simplifying FFI interface, where
callout (the primitive) would only handle raw bytes (along
with argument sizes), without type checking? Type checking
& marshalling would then be moved to the Image side,
along with some "extras" for example retrieving memory
address of a RawBitsArray instance. This could, for
example, ease implementing n-dim pointers, since all the
neccessary info is easily accessible & no more type
juggling.</p>
<p>Again, just some random stupid thought, please don't take
it seriously :D. <br>
</p>
<p> </p>
<blockquote type="cite" style="min-width:500px"><span style="font-family:Arial,Helvetica,sans-serif"><span style="font-size:13px">You have to do it manually if
you really need to pass on object memory to a call and
that callee holds on to the address after the return.
No need to pin objects that are just read during the
call. That is, for example, fill your RawBitsArray and
pass it into the function as is. I think. Just check
via #isPinned. Watch out for segfaults after GC. Might
indicate that you do have to pin that object. :-D</span></span></blockquote>
OK, I pin them all anyway, just in case:). Maybe some
support for auto-pinning objects that are passed to FFI?
It's not like sending #pin is a big deal. Just really easy
to forget to insert 10th time the same method call (and this
time it would actually be the one that is mandatory...).<br>
<p>Michał<br>
</p>
<div>W dniu 2022-04-05 o 11:54,
Marcel Taeumel pisze:<br>
</div>
<blockquote type="cite" style="min-width:500px">
<div id="gmail-m_257425249764720969__MailbirdStyleContent" style="font-size:10pt;font-family:Arial;color:rgb(0,0,0);text-align:left" dir="ltr"> Hi <span style="font-family:Arial,Helvetica,sans-serif;font-size:13px">Michał --</span>
<div><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px"><br>
</span></div>
<div><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px">> </span><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px">As in the title, what's
the way to pass single string to External</span></div>
<span style="font-family:Arial,Helvetica,sans-serif;font-size:13px">> Function that expects
array of strings (char**)?</span>
<div><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px"><br>
</span></div>
<div><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px">The type model for
pointer types with arity > 1 is still
rudimentary. You can always go the unsafe way to
code against 'void*'. In your case, the type
'char*[]' gives you an array type with a 'char*'
content type. Not sure whether type coercing will
work during the FFI call. You can also use the
'string[]' type for that matter. Again, if you get a
type check error on the call, you might have to
resort to 'void*' instead and pass on that
ExternalAddress your have at hand.</span></div>
<div><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px"><br>
</span></div>
<div><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px">(ExternalType typeNamed:
'char*[]') explore.</span><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px"><br>
</span></div>
<div><span style="font-family:Arial,Helvetica,sans-serif"><span style="font-size:13px">(ExternalType
typeNamed: 'string[]') explore.</span></span><br>
</div>
<div><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px"><br>
</span></div>
<div><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px">> </span><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px">I assume the new FFI
interface will be released along with Squeak 6.0? :)</span></div>
<div><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px"><br>
</span></div>
<div><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px">Well, I will make a tag
so that everybody knows what to load in Squeak 6.0.
Yet, active development will continue after that
release against Trunk (e.g. 6.1alpha).</span></div>
<div><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px"><br>
</span></div>
<div><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px">> </span><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px">are objects passed to
FFI (the ones allocated</span></div>
<span style="font-family:Arial,Helvetica,sans-serif;font-size:13px">> on the Squeak heap)
auto-pinned or do I need pin them manually?</span>
<div><span style="font-family:Arial,Helvetica,sans-serif;font-size:13px"><br>
</span></div>
<div><span style="font-family:Arial,Helvetica,sans-serif"><span style="font-size:13px">You have
to do it manually if you really need to pass on
object memory to a call and that callee holds on
to the address after the return. No need to pin
objects that are just read during the call. That
is, for example, fill your RawBitsArray and pass
it into the function as is. I think. Just check
via #isPinned. Watch out for segfaults after GC.
Might indicate that you do have to pin that
object. :-D</span></span></div>
<div><span style="font-family:Arial,Helvetica,sans-serif"><span style="font-size:13px"><br>
</span></span></div>
<div><span style="font-family:Arial,Helvetica,sans-serif"><span style="font-size:13px">Best,<br>
Marcel</span></span></div>
<blockquote type="cite" style="border-left-style:solid;border-width:1px;margin-top:20px;margin-left:0px;padding-left:10px;min-width:500px">
<p style="color:rgb(170,170,170);margin-top:10px">Am
02.04.2022 03:34:38 schrieb Michał Olszewski <a href="mailto:m.olszewski@nexat.pl" target="_blank"><m.olszewski@nexat.pl></a>:</p>
<div style="font-family:Arial,Helvetica,sans-serif">Hello,<br>
<br>
As in the title, what's the way to pass single
string to External <br>
Function that expects array of strings (char**)? I
know that the way to <br>
do that in plain C would be something like this:
&myString but I have <br>
not idea how to manipulate Squeak objects such that
I can pass their <br>
addresses manually to FFI. I guess I have to somehow
wrap stuff into <br>
ExternalData but how?<br>
<br>
The image used is: Squeak 6.0 alpha 21520.<br>
<br>
I assume the new FFI interface will be released
along with Squeak 6.0? :)<br>
<br>
At last, quick question: are objects passed to FFI
(the ones allocated <br>
on the Squeak heap) auto-pinned or do I need pin
them manually?<br>
<br>
Michał<br>
<br>
<br>
</div>
</blockquote>
</div>
<br>
<fieldset></fieldset>
</blockquote>
</div>
</blockquote>
</div>
<br>
<fieldset></fieldset>
<pre></pre>
</blockquote>
</div></blockquote>
</div></div><br>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div></div>