<div dir="ltr">Your simplified code would not be thread safe. A thread swap after the first instruction of<br> <br> mov (%rdi), %rax<br> <br>could potentially cause a problem. RAX (A) contains the pointer to the string descriptor, which includes the pointer to the actual string data and the reference count.<br><br>Should "A" have a reference count of 1, and it is assigned a new value on another thread, its reference count will decrease to zero and the string and its descriptor are both freed. The value of "A" will be set to nil. <br><br>RAX will not have been updated, so after<br><br> mov %rax, (%rsi)<br> <br>"B" will be pointing to an invalid location. Its content is now dependent on memory reallocation. <br><br>In this situation, changing "B" after the return from stringSwap procedure might again cause the string to be freed (assuming the memory was not reallocated), causing a double free error.<br><div><br></div><div>Use of the internal procedures to increment the string reference count of both strings before your code and then decrementing the reference counts afterwards would probably work.</div><div><br></div><div>The same probably applies to other reference count objects.</div><div><br></div><div>Derek</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Jan 28, 2021 at 11:35 AM Benito van der Zander via fpc-pascal <<a href="mailto:fpc-pascal@lists.freepascal.org">fpc-pascal@lists.freepascal.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div>
<div id="gmail-m_3515440808062385958smartTemplate4-template">Hi,<br>
<br>
<p> </p>
<blockquote type="cite">
<div><br>
</div>
<div>
<blockquote type="cite"> Procedure ManagedMove<T>(const
source: T;var dest: T;count: SizeInt);</blockquote>
</div>
<br>
<div dir="auto">In principle a good idea. However this is one of
those cases where you'd definitely need to use constref
instead of const.</div>
</blockquote>
<p><br>
</p>
<p>Or var, since the source might be cleared<br>
</p>
<p>
</p><blockquote type="cite">
<div dir="auto">
<div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div>
<div>
<p>And perhaps there could be a special attribute to
mark which kind of moving is needed, e.g..<br>
</p>
type [moveable] TA = record<br>
<div>
<div> </div>
</div>
type [referencecounted] TA = record</div>
<div> type [nonmoveable] TA = record<br>
</div>
</div>
</blockquote>
</div>
</div>
<div dir="auto"><br>
</div>
<div dir="auto">No, thank you.</div>
<div dir="auto"><br>
</div>
</blockquote>
<p></p>
<p>But it could help a lot with optimizations. For moveable types
it could omit calling an assignment function and just do a
memory copy; and for refcounted tyes it could that when the
number of references does not change. <br>
</p>
<p><br>
</p>
<p><br>
</p>
<p>Like a simple swap function:</p>
<p>procedure stringSwap(var a, b: string);<br>
var t: string;<br>
begin<br>
t := a;<br>
a := b;<br>
b := t;<br>
end;<br>
</p>
<p>A smart compiler could detect that it is a refcounted type and
the number of references stays the same, and thus optimize it
into:</p>
<p> mov (%rdi),%rax<br>
mov (%rsi),%rdx<br>
mov %rdx,(%rdi)<br>
mov %rax,(%rsi)<br>
retq <br>
<br>
</p>
<p>But FPC turns it into:</p>
<p> begin<br>
push %rbx<br>
push %r12<br>
lea -0x68(%rsp),%rsp<br>
mov %rdi,%rbx<br>
mov %rsi,%r12<br>
movq $0x0,(%rsp)<br>
lea 0x8(%rsp),%rdx<br>
lea 0x20(%rsp),%rsi<br>
mov $0x1,%edi<br>
callq 0x4324c0 <fpc_pushexceptaddr><br>
mov %rax,%rdi<br>
callq 0x41fba0 <fpc_setjmp><br>
movslq %eax,%rdx<br>
mov %rdx,0x60(%rsp)<br>
test %eax,%eax<br>
jne 0x469191 <STRINGSWAP+97><br>
t := a;<br>
mov (%rbx),%rsi<br>
mov %rsp,%rdi<br>
callq 0x428d00 <fpc_ansistr_assign><br>
a := b;<br>
mov (%r12),%rsi<br>
mov %rbx,%rdi<br>
callq 0x428d00 <fpc_ansistr_assign><br>
b := t;<br>
mov (%rsp),%rsi<br>
mov %r12,%rdi<br>
callq 0x428d00 <fpc_ansistr_assign><br>
callq 0x432830 <fpc_popaddrstack><br>
end;<br>
mov %rsp,%rdi<br>
callq 0x428ca0 <fpc_ansistr_decr_ref><br>
mov 0x60(%rsp),%rax<br>
test %rax,%rax<br>
je 0x4691b8 <STRINGSWAP+136><br>
callq 0x4329e0 <fpc_reraise><br>
movq $0x0,0x60(%rsp)<br>
jmp 0x469191 <STRINGSWAP+97><br>
lea 0x68(%rsp),%rsp<br>
pop %r12<br>
pop %rbx<br>
retq <br>
<br>
</p>
<p><br>
</p>
<blockquote type="cite"><br>
Then you want to simply use ismanagedtype and move(). Moving
the move() to a separate generic procedure will only lead to
many instantiations of what is basically a move() procedure. <br>
</blockquote>
</div>
<div><br>
</div>
<div>The goal is to reduce instantiations. <br>
</div>
<div>If there are n generic (collection) classes, C1, C2, .., Cn,
and k types used in the collections, T1, T2, .. Tk, there are n*k
collection class instantiation C1<T1>, C1<T2>, ..
C1<Tk>, C2<T1>, ... Cn<Tk></div>
<div>If each collection class does its own
Finalize-Loop/Move/Fillchar there are also n*k of these move
implementations. So like 3*n*k calls.<br>
</div>
<div>When any collection can call the same ManagedMove, there should
only be k ManagedMove instantiations and n*k calls to ManagedMove,
which is only one call. So it is k + n*k calls, which is around a
third of 3*n*k<br>
</div>
<div> <br>
Bye,<br>
Benito </div>
<div>On 11.01.21 18:51, Sven Barth via
fpc-pascal wrote:<br>
</div>
<blockquote type="cite">
<div dir="auto">
<div>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">Benito van der Zander via
fpc-pascal <<a href="mailto:fpc-pascal@lists.freepascal.org" target="_blank">fpc-pascal@lists.freepascal.org</a>>
schrieb am Mo., 11. Jan. 2021, 15:26:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div>
<div id="gmail-m_3515440808062385958m_926231055581021927smartTemplate4-template">Hi,</div>
<div><br>
</div>
<div>perhaps a safe, generic function for this copying
could be added to the RTL. Like:<br>
</div>
<div><br>
</div>
<div> Procedure ManagedMove<T>(const source: T;var
dest: T;count: SizeInt);</div>
</div>
</blockquote>
</div>
</div>
<div dir="auto"><br>
</div>
<div dir="auto">In principle a good idea. However this is one of
those cases where you'd definitely need to use constref
instead of const.</div>
<div dir="auto"><br>
</div>
<div dir="auto">
<div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div>
<div>And when you use IsManagedType, it does not
distinguish standard strings with such weird managed
types.<br>
</div>
</div>
</blockquote>
</div>
</div>
<div dir="auto"><br>
</div>
<div dir="auto">You can additionally use GetTypeKind as well.
Unlike TypeInfo it directly returns the TTypeKind (which for
this case is enough) and is considered constant. </div>
<div dir="auto"><br>
</div>
<div dir="auto">
<div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div>
<div>
<p>And perhaps there could be a special attribute to
mark which kind of moving is needed, e.g..<br>
</p>
type [moveable] TA = record<br>
<div>
<div> </div>
</div>
type [referencecounted] TA = record</div>
<div> type [nonmoveable] TA = record<br>
</div>
</div>
</blockquote>
</div>
</div>
<div dir="auto"><br>
</div>
<div dir="auto">No, thank you.</div>
<div dir="auto"><br>
</div>
<div dir="auto">Regards, </div>
<div dir="auto">Sven </div>
</div>
<br>
<fieldset></fieldset>
<pre>_______________________________________________
fpc-pascal maillist - <a href="mailto:fpc-pascal@lists.freepascal.org" target="_blank">fpc-pascal@lists.freepascal.org</a>
<a href="https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal" target="_blank">https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal</a>
</pre>
</blockquote>
</div>
_______________________________________________<br>
fpc-pascal maillist - <a href="mailto:fpc-pascal@lists.freepascal.org" target="_blank">fpc-pascal@lists.freepascal.org</a><br>
<a href="https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal" rel="noreferrer" target="_blank">https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal</a><br>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature">Derek Edson</div>