Re: [fpc-pascal] Question about System.Move()

2021-01-11 Thread Benito van der Zander via fpc-pascal

Hi,

perhaps a  safe, generic function for this copying could be added to the 
RTL. Like:


Procedure ManagedMove(const source: T;var dest: T;count: SizeInt);


a) For non-managed types it would be the same as Move(source, dest, 
count*sizeof(T))


b) For reference counted types (like strings or interfaces or records of 
them), it would do:


1. finalize dest
2. normal Move
3. clear source, with fillchar

(for ranges where source and dest overlap, it should skip 1 and 3 for 
the overlapping elements. Like when you shift some elements in an arrays 
by two elements to the left, it only has to finalize the two overridden 
elements before the shifted elements, and clear the last two shifted 
elements. There is only one way to do that keeps the reference counts valid)


c) For user-defined managed, not reference counted types, it would just do

  for i := 0 to count - 1 do dest[i] := source[i]

Because you really want to use Move for strings, it can be vastly faster 
than updating the refcounts. But it might not work with user-defined 
types, like someone could build a managed type that cannot be moved. E.g.:


 type TA = record
  class operator Initialize(var a: TA);
  procedure dosomething;
end;

var globalPointer: ^TA;
class operator TA.Initialize(var a: TA);
begin
  globalPointer := @a;
end;
procedure TA.dosomething;
begin
  assert(globalPointer = @self)
end;




And when you use IsManagedType, it does not distinguish standard strings 
with such weird managed types.


And perhaps there could be a special attribute to mark which kind of 
moving is needed, e.g..


  type [moveable] TA = record
  type [referencecounted] TA = record
  type [nonmoveable] TA = record

Bye,
Benito
On 09.01.21 16:28, Bart via fpc-pascal wrote:

Hi,

This may be a silly question.
I use System.Move() to move items in a dynamic array, like
   Move(FData[0], FData[OldEnd], FStart*SizeOf(T));
Where T is the type of the elements in the array.
This seems to work as expected.

I have some questions though:

1. Does this depend on the alignment of the array?
2. Is it OK if the elements of the array are (or contain) managed types?
3. Are there caveats if T is a specialization of a generic type definition?

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] PTCGraph Causing 217

2021-01-11 Thread James Richters via fpc-pascal
I've made a sample program that demonstrates the problem, it's at:
gist.github.com/Zaaphod/936901eb5f31df5044d2bd36a7cf6c91

When I was testing it, I found out that the problem shows up also with
PTCCRT.Keypressed,

Procedure to re-produce bug in Putimage
1. Run program in Windows
2. Do something that activates Windows User Account Control like open an
administrator command prompt
3. Program crashes with exitcode 217 EAccessViolation: Access violation on
line 108 which is doing Putimage, even if you answer NO to user account
control

Procedure to re-produce bug in Keypressed
1. UnComment //Until ptccrt.Keypressed;   Comment out //Until
ptccrt.Keypressed;
2. Run Program in Windows
3. Do something that activates Windows User Account Control like open an
administrator command prompt
4. Program crashes with exitcode 217 EAccessViolation: Access violation on
line 114 which is doing Keypresed (sometimes the error is on putimage)

Other things that cause it:
Unplug monitor and plug it back in
Change Display settings
Putting computer to sleep
Unknown reasons. system just idle

James

>Can you provide an example program and exact steps to reproduce this bug?
>Nikolay

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Question about System.Move()

2021-01-11 Thread Sven Barth via fpc-pascal
Benito van der Zander via fpc-pascal 
schrieb am Mo., 11. Jan. 2021, 15:26:

> Hi,
>
> perhaps a  safe, generic function for this copying could be added to the
> RTL. Like:
>
> Procedure ManagedMove(const source: T;var dest: T;count: SizeInt);
>

In principle a good idea. However this is one of those cases where you'd
definitely need to use constref instead of const.

And when you use IsManagedType, it does not distinguish standard strings
> with such weird managed types.
>

You can additionally use GetTypeKind as well. Unlike TypeInfo it directly
returns the TTypeKind (which for this case is enough) and is considered
constant.

And perhaps there could be a special attribute to mark which kind of moving
> is needed, e.g..
>   type [moveable] TA = record
>   type [referencecounted] TA = record
>   type [nonmoveable] TA = record
>

No, thank you.

Regards,
Sven
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Question about System.Move()

2021-01-11 Thread Bart via fpc-pascal
On Sun, Jan 10, 2021 at 12:09 PM Sven Barth via fpc-pascal
 wrote:

> If after the Move only one of the two references is reachable anymore
> (because e.g. some internal count variable "ends" the array before that
> element) then you don't need to care about increasing the reference
> count, cause there is only one reference after all (in that case you
> must *not* use an assignment to clear the value, but e.g. FillChar,
> cause the reference count must not be touched). Only if you'd really
> duplicate the element you'd need to take care of that.
>

OK, thanks for that.
I'll have to get my head around all the caveats.

Why did I ask in the first place?
Because I was doing some work on TDeque implementation (fixing a
simple range check error in TDeque.IncreaseCapacity).
Inside that procedure simple loop approach is used and I thought I
could maybe improve that, because when we increase capacity by less
than a factor 2, you cannot simply move data in one go and speed
difference (with moving data > 256 MB) might be significant.

I then contemplated all the above issues (I don't want to break
current implementation), but as far as I understand things TDeque
cannot be safely used with managed types as it is now. There is more
code that would need to finalize elements (PopBack, PopFront, Insert,
Clear) and certainly it does not support Objects (classes).
Which is fine, as long as you know it.

We could try to extend it, but now we have Generics.Collections etc:
do we already have a better generic Deque (double ended queue)
implementation somewhere?




-- 
Bart
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal