Re: [fpc-devel] Freeze of fixes for 3.2.4 by 9th June

2024-06-08 Thread Benito van der Zander via fpc-devel

Hi,

i made two patches to fix my Android app crashing:

https://gitlab.com/freepascal.org/fpc/source/-/merge_requests/235

https://gitlab.com/freepascal.org/fpc/source/-/issues/39985


I do not believe it is possible to build a stable Android 64-bit library 
with current fixes


Cheers,
Benito

On 02.06.24 22:28, Florian Klämpfl via fpc-devel wrote:

To get finally forward with the 3.2.4 release, fixes will be frozen by 9th 
June, so if there are some last second cherry picks needed, now it’s time to 
speak up :)
___
fpc-devel maillist  -fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] creating call nodes for managed operators

2023-07-25 Thread Benito van der Zander via fpc-devel

Hi

i have found the problem


views.inc(4318,17) Error: Wrong number of parameters specified for call to 
"$copy"



that is not what it says

It has nothing to do with the parameters. FPC generates this message if 
no matching callable function is not found for any reason


In this case because "copy" was not public in the record. I can set a 
flag [cnf_ignore_visibility] in the compiler






Bye,
Benito
On 23.07.23 16:35, Hairy Pixels via fpc-devel wrote:



On Jul 23, 2023, at 7:13 AM, Benito van der Zander via 
fpc-devel  wrote:

with my patch, "copy" can be inlined!
initialize and finalize some times, too.

Amazing!


There are two places that call them. compiler/nld.pas and compiler/ngenutil.pas 
where it creates the call nodes. There my patch turns them into ordinary 
function calls, which can be inlined like any other function call.

This is the "old way" you describe. Why did they do it like this instead of 
normal function calls which could be inlined? I suspect one of the compiler devs needs to 
explain this because there may be a reason.


Then there is compiler/hlcgobj.pas, which calls initialize/finalize for local 
or temporary variables. That appears to happen after the inlining is done.  
Perhaps it needs to do the inlining first to know which variables are there, 
and afterwards it could not change them anymore.

So the inlining caused extra init/finalize calls? That's not good for sure. 
There's already a problem with an extra copy operator being called on temporary 
memory which can make or break the feature entirely depending on your usage.

Regards,
Ryan Joseph

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


Re: [fpc-devel] creating call nodes for managed operators

2023-07-23 Thread Benito van der Zander via fpc-devel

Hi,

main fails to cycle compile rtl-console/fv-package due to a 
TEnhancedVideoCell record.

fixes does not have a TEnhancedVideoCell record, so it cannot fail there.

But if I copy TEnhancedVideoCell into a new project file, I can compile 
it with the patched fixes, too



What is the performance improvement here


I did not benchmark it.

I tested my test cases after dozen of unrelated changes. I started with 
COM interfaces for reference counting. There the run time was like 80 
seconds. Then I changed it to managed records. Now it is around 30 seconds.



and why was it done the old way?


what old way?



Another question I had about them is why they can't be inlined.



with my patch, "copy" can be inlined!

initialize and finalize some times, too.

There are two places that call them. compiler/nld.pas and 
compiler/ngenutil.pas where it creates the call nodes. There my patch 
turns them into ordinary function calls, which can be inlined like any 
other function call.
Then there is compiler/hlcgobj.pas, which calls initialize/finalize for 
local or temporary variables. That appears to happen after the inlining 
is done.  Perhaps it needs to do the inlining first to know which 
variables are there, and afterwards it could not change them anymore.




Bye,
Benito
On 22.07.23 15:47, Hairy Pixels via fpc-devel wrote:

Nice work, I have no answer for you though. :)

What is the performance improvement here and why was it done the old way?

Another question I had about them is why they can't be inlined. Does anyone 
have the answer for that? Not being able to be inlined is the biggest 
performance problem I suspect, followed by the copy operator which gets called 
redundantly on assignment to temporary memory.


On Jul 22, 2023, at 7:07 AM, Benito van der Zander via 
fpc-devel  wrote:

Hallo,


i made a patch for faster management 
operators:https://gitlab.com/benibela/fpc-source/-/commit/1aa0866112c97dd0c7ed7f3a4b1c7ab6420cb942



And it has been working fine on fixes3_2, but when I tried to apply it on main, 
I get an error message:

views.inc(4318,17) Error: Wrong number of parameters specified for call to 
"$copy"
video.inc(180,35) Error: Found declaration: operator copy(constref 
TEnhancedVideoCell;var TEnhancedVideoCell); Static;

I have been creating two paranodes for the call like that:

if is_rtti_managed_type(left.resultdef) and 
is_record(left.resultdef)
and (mop_copy in 
trecordsymtable(left.resultdef.getsymtable(gs_record)).managementoperators) then
  begin
hsym := 
tprocsym(left.resultdef.getsymtable(gs_record).Find('copy'));
hp := ccallparanode.create(left, ccallparanode.create(right, 
nil));
result := ccallnode.create(hp,hsym,hsym.owner,nil,[],nil);

should it be done differently?


 
Viele Grüße,

Benito

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

Regards,
Ryan Joseph

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


[fpc-devel] creating call nodes for managed operators

2023-07-22 Thread Benito van der Zander via fpc-devel

Hallo,


i made a patch for faster management operators: 
https://gitlab.com/benibela/fpc-source/-/commit/1aa0866112c97dd0c7ed7f3a4b1c7ab6420cb942




And it has been working fine on fixes3_2, but when I tried to apply it 
on main, I get an error message:


views.inc(4318,17) Error: Wrong number of parameters specified for call 
to "$copy"
video.inc(180,35) Error: Found declaration: operator copy(constref 
TEnhancedVideoCell;var TEnhancedVideoCell); Static;


I have been creating two paranodes for the call like that:

   if is_rtti_managed_type(left.resultdef) and 
is_record(left.resultdef)
   and (mop_copy in 
trecordsymtable(left.resultdef.getsymtable(gs_record)).managementoperators) 
then

 begin
   hsym := 
tprocsym(left.resultdef.getsymtable(gs_record).Find('copy'));
   hp := ccallparanode.create(left, 
ccallparanode.create(right, nil));

   result := ccallnode.create(hp,hsym,hsym.owner,nil,[],nil);

should it be done differently?




Viele Grüße,

Benito

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


Re: [fpc-devel] Sorting tests

2022-11-29 Thread Benito van der Zander via fpc-devel

Hi,
and the FPC implementation is actually documented to not be stable in 
the code:



{
QuickSort

Average performance: O(n log n)
Worst performance: O(n*n)
Extra memory use: O(log n) on the stack
Stable: no
Additional notes: Uses the middle element asthe pivot. This makes it work
well also on already sorted sequences, which can occur
often in practice. As expected from QuickSort, it works
best on random sequencesand is usually the fastest
algorithm to sort them. It is, however, possible for a
malicious user to craft special sequences, which trigger
its worst O(n*n)case. They can also occur in practice,
although they are veryunlikely. If this is not an
acceptable risk (e.g.for high risk applications,
security-conscious applications or applications with hard
real-time requirements),another sorting algorithm must
be used.
}

and one can see that it is indeed not stable, if you sort ['a','b','A']  
case-insensitively, it becomes ['A', 'a','b']




If you want a stable sort, you need to use things like merge sort instead.


I wanted a stable sort and implemented merge sort, and it was far too 
slow to be usable.


Now I use the sortbase quicksort, but sort an array of pointers to the 
actual array, so the compare function can compare the indices for equal 
elements.



Cheers,
Benito
On 29.11.22 14:41, J. Gareth Moreton via fpc-devel wrote:


Quicksort is not inherently stable because of what happens if a value 
is equal to the pivot - more specifically, which of the identical 
values is selected as the pivot - for example, if you try to sort a 
list of identical values, they will inevitably change order because 
each stage will move all of the values to one side of the pivot (and 
also cause quicksort to degenerate into O(n²)).  If you want a stable 
sort, you need to use things like merge sort instead.


Kit

On 29/11/2022 13:25, Sven Barth via fpc-devel wrote:
Ondrej Pokorny via fpc-devel  schrieb 
am Di., 29. Nov. 2022, 11:39:


Am 29.11.2022 um 11:08 schrieb Sven Barth via fpc-devel:

J. Gareth Moreton via fpc-devel 
schrieb am Di., 29. Nov. 2022, 10:09:

Surely that's a bug in the comparison functions that should
be fixed and
not something that can be blamed on introsort.  If a
comparison function
is faulty, then pretty nuch any sorting algorithm can be
considered to
have unpredictable behaviour.


This *can* be blamed on IntroSort, because Stability (order of
equal elements is kept) is an attribute of sorting algorithms
and IntroSort is *not* considered stable while QuickSort *can*
be stable depending on the implementation and ours *is*.


If for two elements [a, b] the comparison function returns
aFor such a comparison function the issue is indeed in the comparison 
function, but Nikolay also mentioned "ais the case for equal elements.


Regards,
Sven


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


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


Re: [fpc-devel] Thoughts: Make FillChar etc. an intrinsic for specialised performance potential

2022-04-16 Thread Benito van der Zander via fpc-devel

Hi,

FillChar is on most platforms an assembly function and FPC *never* 
inlines assembly functions. 


even without inlining, rep stosb is faster than FillChar:

 {$asmmode intel}
procedure repfillchar(var buffer; len: sizeuint; c: byte);
begin
  asm
    mov al, c
    mov rdi, buffer
    mov rcx, len
    rep stosb
  end;
end;


1GB:
fillchar: 364 ms
repfillchar 321 ms

4GB:
fillchar: 1382 ms
repfillchar:1217 ms

Bye,
Benito
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Thoughts: Make FillChar etc. an intrinsic for specialised performance potential

2022-04-16 Thread Benito van der Zander via fpc-devel

Hi,

it could always inline it.

For small sizes do that mov and for large sizes do rep stosb on x86. It 
is very fast nowadays. Faster than FillChar on my Intel laptop. (except 
for mid sizes like 128 bytes)



Bye,
Benito
On 16.04.22 01:26, J. Gareth Moreton via fpc-devel wrote:

Hi everyone,

This is something that sprung to mind when thinking about code speed 
and the like, and one thing that cropped up is the initialisation of 
large variables such as arrays or records.  A common means of doing 
this is, say:


FillChar(MyVar, SizeOf(MyVar), 0);

To keep things as general-purpose as possible, this usually results in 
a function call that decides the best course of action, and for very 
large blocks of data whose size may not be deterministic (e.g. a file 
buffer), this is the best approach - the overhead is relatively small 
and it quickly uses fast block-move instructions.


However, for small-to-mid-sized variables of known size, this can lead 
to some inefficiencies, first by not taking into account that the size 
of the variable is known, but also because the initialisation value is 
zero, more often that not, and the variable is probably aligned on the 
stack (so the checks to make sure a pointer is aligned are unnecessary).


I did a proof of concept on x86_64-win64 with the following record:

type
  TTestRecord = record
    Field1: Byte;
    Field2, Field3, Field4: Integer;
  end;

SizeOf(TTestRecord) is 16 and all the fields are on 4-byte 
boundaries.  Nothing particularly special.


I then declared a variable of this time and filled the fields with 
random values, and then ran two different methods to clear their 
memory.  To get a good speed average, I ran each method 1,000,000,000 
times in a for-loop.  The first method was:


FillChar(TestRecord, SizeOf(TestRecord), 0);

The second method was inline assembly language (which I've called 'the 
intrinsic'):


asm
  PXOR   XMM0, XMM0
  MOVDQU [RIP+TestRecord], XMM0
end;2

It's not perfect because the presence of inline assembly prevents the 
use of register variables (although TestRecord is always on the stack 
regardless), but the performance hit is barely noticeable in this 
case, and if the assembly language were inserted by the compiler, the 
register variable problem won't arise.


These are my results:

 FillChar time: 2.398 ns

Field1 = 0
Field2 = 0
Field3 = 0
Field4 = 0

Intrinsic time: 1.336 ns

Field1 = 0
Field2 = 0
Field3 = 0
Field4 = 0

Sure, it's on the order of nanoseconds, but the intrinsic is almost 
twice as fast.


In terms of size - FillChar call = 20 bytes:

488d0d22080200   lea 0x20822(%rip),%rcx    # 0x100022010
4531c0   xor    %r8d,%r8d
ba1000   mov    $0x10,%edx
e8150a   callq  0x12210 



The intrinsic = 12 bytes:

660fefc0 pxor %xmm0,%xmm0
f30f7f05bd050200 movdqu %xmm0,0x205bd(%rip)    # 0x100022010

For a 32-byte record instead, an extra 8-byte MOVDQU instruction would 
be required, so the 2 would be equal size, but with the bonus that the 
intrinsic doesn't have a function call and will probably help 
optimisation in the rest of the procedure by freeing up the registers 
used to pass parameters (%rcx, %rdx and %r8 in this case; although the 
intrinsic will require an MM register in this x86_64 example, they 
tend to not be used as often).  Also, the peephole optimizer can 
remove redundant PXOR XMM0, XMM0 calls, which will help as well if 
there are multiple FillChar calls.


I'm not proposing a total rewrite, and I would say that in the default 
case, it should just fall back to the in-built System functions, but 
the relevant compiler nodes could be overridden on specific platforms 
to generate smaller, more optimised code when the sizes and values are 
known at compile time.


Now, in this example, it is still faster to simply set the fields 
manually one-by-one (clocks in at around 1.2 ns), possibly due to the 
unaligned write (MOVDQU) and internal SSE state switching adding some 
overhead, but there's nothing to stop the compiler from inserting code 
in place of the FillChar call to do just that if it thinks it's the 
fastest method.  Then again, one has to be a little bit careful 
because FillChar and the intrinsic will also set the filler bytes 
between Field1 and Field2 to 0, whereas manually assigning 0 to the 
fields won't (so they aren't strictly equivalent and might only be 
allowed if there are no filler bytes or when compiling under -O4, but 
the latter may still be dangerous when typecasting is concerned), and 
extra care would have to be taken when unions are concerned (sorry, 
'union' that's a C term - what's the official Pascal term again?).


Actual Pascal calls to FillChar would not change in any way and so 
theoretically it won't break existing code.  The only drawback is that 
the intrinsic and the internal System functions would have to be named 
the same so constructs such as "FuncPtr := @FillChar;" 

Re: [fpc-devel] The "magic div" algorithm

2021-11-16 Thread Benito van der Zander via fpc-devel

Hi,

in my big decimal unit, I need to divide by 10 all the time, 
e.g. 
https://github.com/benibela/bigdecimalmath/blob/master/bigdecimalmath.pas#L1324-L1325


would the magic div help there much?

Bye,
Benito
On 09.11.21 22:12, J. Gareth Moreton via fpc-devel wrote:


This one for Marģers specifically,

You'll be pleased to know that your insight has been partially 
implemented!


https://gitlab.com/freepascal.org/fpc/source/-/merge_requests/51

This only expands 32-bit divisions to 64-bit, since the smaller sizes 
requires more work at the node level, but is certainly possible and 
will happily continue to experiment with seeing if it can be 
implemented.  This was fun to do!


The test "bench/bdiv.pp" (also "tests/test/cg/tmoddiv6.pp" which just 
includes the given file) is my benchmark test for division and modulus 
operations if anyone wants to see if they can make the fundamental 
routine faster on any platform.


Gareth aka. Kit

On 24/08/2021 20:14, Marģers . via fpc-devel wrote:

I came up with even shorter variant of div
example
function teDWordDivBy7_v4( divided : dword):dword; assembler; 
nostackframe;

asm
 mov ecx,divided
 mov rax,2635249153693862181
 mul rcx
 mov eax,edx
end;

current version for comparison

function teDWordDivBy7_v0( divided : dword):dword; assembler; 
nostackframe;

asm
 mov ecx,divided
 mov eax,613566757
 mul ecx
 add edx,ecx
 rcr edx,1
 shr edx,2
 mov eax,edx
end;




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


 
	Virus-free. www.avast.com 
 



<#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>

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


Re: [fpc-devel] Merging identical procedure proposals

2021-10-16 Thread Benito van der Zander via fpc-devel

Hi,

 that is a great idea

It especially useful for generics, where each specialization can create 
a huge amount of identical methods


Best,
Benito
On 13.10.21 19:33, J. Gareth Moreton via fpc-devel wrote:

Hi everyone,

So one optimisation that has cropped up a couple of times is finding 
ways to merge subroutines that, while containing different source 
code, compile into the exact same assembly language.  For example, 
TStream.WriteData has implementations for numerous input types, and 
the compilation of "function TStream.WriteData(const Buffer: 
WideChar): NativeInt;", "function TStream.WriteData(const Buffer: 
Int16): NativeInt;", "function TStream.WriteData(const Buffer: 
UInt16): NativeInt;" all produce the following:


    leaq    -40(%rsp),%rsp
.seh_stackalloc 40
.seh_endprologue
    movq    %rcx,%rax
    movw    %dx,32(%rsp)
    leaq    32(%rsp),%rdx
    movl    $2,%r8d
    movq    (%rax),%rax
    call    *264(%rax)
    movslq    %eax,%rax
    nop
    leaq    40(%rsp),%rsp
    ret
.seh_endproc

As you can imagine, having the compiler only keep one copy of the code 
and redirect all relevant calls to it will reduce code size 
significantly for no speed penalty.


One thought I had was to keep a "code hash" for each subroutine that's 
computed via digesting the assembly language, although I'm not quite 
sure how it should handle labels.  If two hashes are identical, the 
procedures are checked more closely to determine if they are actually 
identical and it wasn't just a collision.


I figure this would be a whole-program optimization though due to 
inter-unit calls and comparisons and the like.


Gareth aka. Kit


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


Re: [fpc-devel] Defer keyword

2021-05-07 Thread Benito van der Zander via fpc-devel

Hi,




Don't forget that the record/management operator approach will again 
blow up binary size; for every variable declared like this you risk 
creating a new type.


the classic Delphi way was to use an interface for freeing. It only 
requires one type and nothing blows up.


type
  TDefer = class(TInterfacedObject)
    toDefer: TObject;
    constructor Create(anobject: tobject);
    destructor destroy; override;
  end;

constructor TDefer.Create(anobject: tobject);
begin
  toDefer := anobject;
end;

destructor TDefer.destroy;
begin
  toDefer.free;
  inherited destroy;
end;

function deferedFree(obj: TObject): IUnknown;
begin
  result := TDefer.Create(obj);
end;

Then it can be used as:

procedure test;
var
  sl: TStringList;
begin
  sl := TStringList.Create;
  deferedFree(sl);
  writeln(sl.count);
end;


Unfortunately it fails in FreePascal because the interface is released 
too soon.





At worst, one could use a temporary variable in Delphi:

procedure test;
var
  sl: TStringList;
begin
  sl := TStringList.Create;
  var temp := deferedFree(sl);
  writeln(sl.count);
end;


The introduction of generics and their abundant use in Delphi has 
noticably slowed down the compiler and increased binary sizes. To my 
dismay, compile times of 20 seconds up to 2 minutes have become not 
uncommon in Delphi. Something almmost unthinkable in D7 days. 


With these generics they copied all the problems of C++. One of the 
worst ways of doing that


It would have been better to implement them like dynamic arrays. The 
generic code gets RTTI, the specialization does not generate any code, 
and just avoids explicit casting.



Cheers,
Benito
On 07.05.21 11:08, Michael Van Canneyt via fpc-devel wrote:



On Fri, 7 May 2021, Sven Barth via fpc-devel wrote:



I thought it was agreed at the time that this was the most viable way
forward ?



As far as I remember there wasn't really any agreement.


Can be, I was not sure... I remember this path was investigated.


IIRC there was also the proposal that this could be done automatically
using
a keyword:

var
   SomeClass : TSomeClass; dispose;

The compiler can internally create the management record with a single
default
field and the needed management operator, so the user does not need
to create all that.



I'm not aboard with such a keyword. The compiler should provide the
necessary language mechanisms (default field, operator hoisting) and 
then

there should be a default implementation as part of the RTL. There is no
need to hide this behind a keyword, attribute or whatever.


There is:

Using a keyword, the compiler could also optimize things by simply 
initializing and freeing the instance if the usage of the object in 
the procedure allows it; it would allow to skip the record and 
operators and whatnot.


I'm not proposing to abolish the record approach, just an additional 
automatism that will use it, but allows to skip it for simple enough 
cases which are

probably the largest use-case.

Don't forget that the record/management operator approach will again 
blow up binary size; for every variable declared like this you risk 
creating a new type.


The introduction of generics and their abundant use in Delphi has 
noticably slowed down the compiler and increased binary sizes. To my 
dismay, compile times of 20 seconds up to 2 minutes have become not 
uncommon in Delphi. Something almmost unthinkable in D7 days.


If that can be avoided by use of a keyword for 90% of use cases, I 
think it is worth thinking about it and not dismissing it offhand.


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


Re: [fpc-devel] Generic class comparison operators

2021-04-21 Thread Benito van der Zander via fpc-devel

Hi,

 what about overloading operators for OBJECTs?

They do not conflict with any default operators.

I expected this to work, but it did not compile:


  type generic TXQHashset = object //(specialize 
TXQBaseHashmap)...

    class operator =(const a, b: TXQHashset): boolean;
  end;


Cheers,
Benito
On 17.04.21 22:12, Jonas Maebe via fpc-devel wrote:

On 2021-04-17 22:02, Ryan Joseph via fpc-devel wrote:

Since I'm working on generics right now can we finally, at the very
least, allow class operators for comparison operators? This is
literally the only way for a generic class to override the = operator
(along with some others) so there's no reason not to allow this. I
understand the objection to :=, + etc.. where it returns a copy of a
class instance and people could in theory do memory unsafe things,
with comparison operators there is no possibility for this. I already
made a patch for "advanced records" which is in limbo but It's trivial
to adapt this for classes and put restrictions on the type of
operator.


The issue with allowing it for classes (generic or not) is that the 
the = operator already has a meaning for them (pointer equality). I 
think in general we don't allow overloading operators that have a 
built-in meaning.


It would work very well either, because if you'd pass such a class 
instance as a TObject parameter and that called routine performs a 
comparison, then suddenly the comparison would happen again based on 
pointer equality rather than with this custom operator. This means 
that e.g. any non-generic container class that uses comparisons (for 
sorting or for detecting duplicates) would fail to work, or at least 
work differently than generic container classes. That's something you 
don't want at all in a programming language, as it means you 
constantly have to keep in mind how something you call was implemented 
to know how it will behave (the called routine may even have your 
class type as parameter type, but then call something else that uses 
TObject).



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


Re: [fpc-devel] Feature request/discussion - SetLengthNoInit

2020-09-16 Thread Benito van der Zander via fpc-devel


Hi,



I'm against adding support for this. Dynamic arrays have guaranteed 
behavior. If users find that this behavior is not appropriate for 
their use case then they should not use them (or as you already 
suggested, preallocate them).


well, setlength does not always initialize the array

That is why the new fpc versions always show a "might be 
uninitialized"-warning, when setlength is called without setting the 
array to nil first


Bye,
Benito

On 15.09.2020 11:11, Sven Barth via fpc-devel wrote:
J. Gareth Moreton via fpc-devel > schrieb am Mo., 14. Sep. 
2020, 19:00:


With all this in mind, would there be support for an intrinsic
such as
"SetLengthNoInit" or "SetLengthNoClear" or some similar name that has
all the benefits of SetLength (especially the reference counting) but
doesn't initialise new elements to zero? If I'm learning one
thing, Free
Pascal is finding a niche in some scientific applications, and
speed can
be essential sometimes.


I'm against adding support for this. Dynamic arrays have guaranteed 
behavior. If users find that this behavior is not appropriate for 
their use case then they should not use them (or as you already 
suggested, preallocate them).


Regards,
Sven



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


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


Re: [fpc-devel] Merge request for 3.2 fixes

2020-07-25 Thread Benito van der Zander


and: https://bugs.freepascal.org/view.php?id=36603 a regression when 
passing empty strings to regexpr


perhaps its follow-up: https://bugs.freepascal.org/view.php?id=36701





On 25.07.20 16:26, Martin wrote:
Could the fix for issue https://bugs.freepascal.org/view.php?id=36017 
be merged to fixes branch please?


Unfortunately I missed that it wasn't merged before the release (I had 
it commented out in my tests, so I could see if anything else would 
break).

But it would be nice to have it for 3.2.2.

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


Re: [fpc-devel] Binary size discrepancy with -a

2020-07-18 Thread Benito van der Zander

Hi J. Gareth,

I once added -a to debug my Android app, and then it did not start 
anymore on some devices...




Bye,
Benito
On 19.07.20 05:09, J. Gareth Moreton wrote:

Hi everyone,

I've noticed something a bit weird with the Free Pascal Compiler when 
you use the the -a option to dump the compiled assembly files... the 
resultant binaries are sometimes smaller.  I recently tried it with 
Lazarus under x86_64-win64 (using "make distclean all install" with 
FPCOPT):


(-O4 -OoCONSTPROP)
241,010,289 bytes - lazarus.exe

(-a -O4 -OoCONSTPROP)
235,655,062 bytes - lazarus.exe

Anyone else noticed this? Logically, shoudn't the EXE files be 
completely identical?


Gareth aka. Kit


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


Re: [fpc-devel] Fwd: Re: An optimization suggestion for FPC

2020-06-28 Thread Benito van der Zander

Hi J. Gareth,

that is a really important optimization.

Especially with new record management operators. I am going to wrap 
almost all my variables in records, so they will be automatically 
initialized.


I have suggested it in the bug tracker, but it was closed, because they 
say the bug tracker is not for suggestions: 
https://bugs.freepascal.org/view.php?id=34915


Bye,
Benito
On 28.06.20 12:31, J. Gareth Moreton wrote:


So someone reached out to me directly again asking for an FPC 
optimisation.  Now I want to see if this is possible to optimise and 
won't break something or be annoying specific.


Gareth aka. Kit

 Forwarded Message 
Subject:Re: An optimization suggestion for FPC
Date:   Sun, 28 Jun 2020 11:30:09 +0100
From:   J. Gareth Moreton 
To: Okoba 



Heh, I'm honoured you came to me directly.  I'll see if I can work 
anything out.  A lot of it is down to where the record is stored.  If 
it's on the stack, an optimisation shouldn't be difficult, but if it's 
on the heap somewhere, then it will be a bit more difficult.  Do you 
have your C++ example, and which C++ compiler did you use?


Gareth aka. Kit

On 28/06/2020 11:06, Okoba wrote:

Hi,
It seems you are interested in optimizing FPC and I have a trouble 
with it and wanted to check it with you if I may.
I like to have a way to pass the record variable and inc it without 
losing speed. I wrote a sample and ran it with FPC trunk in Win64 and 
the times are commented. I should say the times for Delphi for the 
same target is the same. And tried a C++ version and all the times 
are almost the same and near 250.
I tried many ways including absolute, pointer, custom asm functions, 
custom functions with const and var params and the are almost always 
slower than the first loop.
So is there anyway to have a custom Inc function that get he record 
variable and inc it without losing speed in compare to the system inc?


Regards.



program Project1;

uses
  SysUtils;

type
  TTest = record
    P: int64;
  end;

  procedure Test;
  var
    V: TTest;
    P: int64;
    T: UInt64;
    i, C: integer;
  begin
    C := 1000 * 1000 * 1000;

    T := GetTickCount64;
    P := 1;
    for i := 1 to C do
  Inc(P);
    WriteLn(GetTickCount64 - T); //266

    T := GetTickCount64;
    V.P := 1;
    for i := 1 to C do
  Inc(V.P);
    WriteLn(GetTickCount64 - T); //1400

    T := GetTickCount64;
    V.P := 1;
    P := V.P;
    for i := 1 to C do
  Inc(P);
    P := V.P;
    WriteLn(GetTickCount64 - T);  //250
  end;

begin
  Test;
  ReadLn;
end.



 
	Virus-free. www.avast.com 
 



<#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>

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


Re: [fpc-devel] New feature announcement: constant parameters for generics

2020-04-28 Thread Benito van der Zander

Hi,




Also assume you have a record and a hashmap that stores them. Now you 
add a string to the record which turns it into a managed one and 
suddenly your code will no longer work, probably resulting in subtle 
bugs or memory leaks. That's /not/ what should happen for merely 
adding a string. It's already bad enough that this happens with the 
Pascal style I/O we don't need to have this with base container types.


For calling Free we have explicit classes. But the difference between 
managed types vs. not-managed types is subtle and can change - as 
mentioned above - by merely adding a field.


That is why FreePascal should merge non-managed generic classes that 
have the same size when it can.


But as long as FreePascal does not do it, the user needs to do the 
merging manually, with all the resulting problems. And constants 
generics can be used to store the size


Best,
Benito
On 27.04.20 07:46, Sven Barth wrote:

Am 26.04.2020 um 23:42 schrieb Benito van der Zander:

Hi Sven,



It's not that simple. In principle you're right that the compiler 
could try to merge more implementations, but this does not depend on 
the declaration of the generic, but the use of the parameter types.


I mostly use generics for containers, especially hashmaps. They only 
stores the values and never calls specific methods on them




Well, nice and well for /you/ then, but there are many more uses for 
generics. And as a compiler developer I /must/ think about these cases 
as well.





Not to mention that your TBaseHashMap would not work with managed 
types...


That would need be handled separately. There are probably also people 
who want a container that calls .free on TObject descendants.


The user should not need to care about that, especially for general 
base classes.


Also assume you have a record and a hashmap that stores them. Now you 
add a string to the record which turns it into a managed one and 
suddenly your code will no longer work, probably resulting in subtle 
bugs or memory leaks. That's /not/ what should happen for merely 
adding a string. It's already bad enough that this happens with the 
Pascal style I/O we don't need to have this with base container types.


For calling Free we have explicit classes. But the difference between 
managed types vs. not-managed types is subtle and can change - as 
mentioned above - by merely adding a field.


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


Re: [fpc-devel] New feature announcement: constant parameters for generics

2020-04-26 Thread Benito van der Zander

Hi Sven,



It's not that simple. In principle you're right that the compiler 
could try to merge more implementations, but this does not depend on 
the declaration of the generic, but the use of the parameter types.


I mostly use generics for containers, especially hashmaps. They only 
stores the values and never calls specific methods on them





Not to mention that your TBaseHashMap would not work with managed types...


That would need be handled separately. There are probably also people 
who want a container that calls .free on TObject descendants.



Best,
Benito
On 26.04.20 14:18, Sven Barth wrote:

Am 26.04.2020 um 14:01 schrieb Benito van der Zander:

Hi,

perhaps it could be used to merge specializations (if fpc cannot do 
that on its own):


Like when you have a hashmap THashMap, and need three 
specializations:


THashMap

THashMap

THashMap

It is basically three times the same hashmap, but if fpc does not 
detect that, it might generate three times the same assembly code, 
which waste a lot of space.



But with constants it can be merged to TBaseHashMapinteger> and then you only have one map in the assembly code, and 
three wrappers to remove the casting:


THashMap = TBaseHashMap = 
TBaseHashMap


THashMap = TBaseHashMap = 
TBaseHashMap


THashMap = TBaseHashMap = 
TBaseHashMap




It's not that simple. In principle you're right that the compiler 
could try to merge more implementations, but this does not depend on 
the declaration of the generic, but the use of the parameter types.


Take the following example:

=== code begin ===

{$mode objfpc}

type
  generic TTest = class
    procedure DoSomething;
  end;

  TMyClass1 = class
 procedure Foobar;
  end;

  TMyClass2 = class
    procedure Foobar; virtual;
  end;

procedure TTest.DoSomething;
var
  o: T;
begin
  o.Foobar;
end;

procedure TMyClass1.Foobar;
begin
  Writeln('TMyClass1.Foobar');
end;

procedure TMyClass2.Foobar;
begin
  Writeln('TMyClass2.Foobar');
end;

type
  TTestMyClass1 = specialize TTest;
  TTestMyClass2 = specialize TTest;

begin
end.

=== code end ===

In case of TMyClass1 this will result in a static call to 
TMyClass1.Foobar, however in case of TMyClass2 this will result in an 
indirect call through the VMT.


The type information needs to be correct as well, even more so once we 
have support for Extended RTTI where one can enumerate non-published 
fields, properties and methods in addition to published.


Not to mention that your TBaseHashMap would not work with managed types...

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


Re: [fpc-devel] New feature announcement: constant parameters for generics

2020-04-26 Thread Benito van der Zander

Hi,

perhaps it could be used to merge specializations (if fpc cannot do that 
on its own):


Like when you have a hashmap THashMap, and need three 
specializations:


THashMap

THashMap

THashMap

It is basically three times the same hashmap, but if fpc does not detect 
that, it might generate three times the same assembly code, which waste 
a lot of space.



But with constants it can be merged to TBaseHashMapinteger> and then you only have one map in the assembly code, and three 
wrappers to remove the casting:


THashMap = TBaseHashMap = 
TBaseHashMap


THashMap = TBaseHashMap = 
TBaseHashMap


THashMap = TBaseHashMap = 
TBaseHashMap




Cheers,
Benito
On 26.04.20 11:48, Sven Barth via fpc-devel wrote:

Am 26.04.2020 um 09:38 schrieb Michael Van Canneyt:



On Sun, 26 Apr 2020, Ryan Joseph via fpc-devel wrote:




On Apr 26, 2020, at 5:13 AM, Sven Barth via fpc-devel 
 wrote:


The Free Pascal team is happy to announce the addition of a new 
language feature: constant parameters for generics.


Excellent! Thanks for getting this merged. It was a long battle but 
it's finally over. ;)


As the original author, can you say something about the intended use 
of this feature ?


Sven gave some examples, and they show how it works, but from his 
examples I don't see the point

of this feature.


Jeppe had provided a potential usecase on the core mailing list in 
October '18. His example is not useable as-is, but to give you an idea:


=== code begin ===

program tgpio;

{$mode objfpc}
{$modeswitch advancedrecords}

type
 generic TSomeMicroGPIO = record
 private
   procedure SetPin(aIndex: SizeInt; aEnable: Boolean); inline;
   function GetPin(aIndex: SizeInt): Boolean; inline;
 public
   property Pin[Index: SizeInt]: Boolean read GetPin write SetPin;
 end;

procedure TSomeMicroGPIO.SetPin(aIndex: SizeInt; aEnable: Boolean);
begin
  if aEnable then
    PLongWord(Base)[2] := PLongWord(Base)[2] or (1 shl aIndex)
  else
    PLongWord(Base)[2] := PLongWord(Base)[2] and not (1 shl aIndex);
end;

function TSomeMicroGPIO.GetPin(aIndex: SizeInt): Boolean;
begin
  Result := (PLongWord(Base)[2] and (1 shl aIndex)) <> 0
end;

var
  GPIOA: specialize TSomeMicroGPIO<$8000F000>;
  GPIOB: specialize TSomeMicroGPIO<$8000F100>;
  GPIOC: specialize TSomeMicroGPIO<$8000F200>;

begin
  GPIOA.Pin[2] := True;
end.

=== code end ===

As the compiler can inline all this, the writing of maintainable, 
hardware agnostic frameworks for embedded controllers becomes easier.


In general I agree with you that the use of constants as generic 
parameters is less wide. But there cases where one might want them.


A further example could be to determine the size of a hash table: 
Determining that at compile time instead of runtime might allow for 
better code. At the same time the user of that code would still be 
able to influence it.


In the bug report there was a further example by Akira1364. At its 
core it's about static arrays again, but it shows what can be done 
with this:


=== code begin ===

program ConstMatrixExampleObjFPC;

{$mode ObjFPC}
{$modeswitch AdvancedRecords}

type
  String3 = String[3];

  generic TRawMatrix = array[0..N-1] of 
array[0..N-1] of T;


  generic TMatrix = record
  private type
ArrayType = specialize TRawMatrix;
  private
Data: ArrayType;
  public
class operator :=(constref Arr: ArrayType): TMatrix; inline;
procedure Display;
  end;

  class operator TMatrix.:=(constref Arr: ArrayType): TMatrix;
  begin
Result.Data := Arr;
  end;

  procedure TMatrix.Display;
  var I, J: SizeInt;
  begin
WriteLn('[');
for I := 0 to N - 1 do begin
  Write(' [');
  for J := 0 to N - 2 do
Write(Data[I, J], ', ');
  Write(Data[I, N - 1]);
  Writeln('] ');
end;
Write(']');
  end;

const RawMat: specialize TRawMatrix = (
  ('AAA', 'BBB', 'CCC', 'DDD'),
  ('EEE', 'FFF', 'GGG', 'HHH'),
  ('III', 'JJJ', 'KKK', 'LLL'),
  ('MMM', 'NNN', 'OOO', 'PPP')
);

var Mat: specialize TMatrix;

begin
  Mat := RawMat;
  Mat.Display();
end.

=== code end ===

I'm sure the future will show more potential examples. Or one could 
look at C++ examples that allow constants as well.


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


Re: [fpc-devel] FPC now supports Windows 33-bit

2020-04-23 Thread Benito van der Zander

Hi,

if someone needs even more bits: I once made a 65-bit integer type



Cheers,
Benito
On 23.04.20 07:27, Sven Barth via fpc-devel wrote:

Am 22.04.2020 um 22:21 schrieb Bart via fpc-devel:

Hi,

Please don't feel offended, but this typo just made me smile:
(And a smile is what we need in these harsh times)

Revision 44996
"Moved the common interface part of the win33 and win64 System units
to the syswinh.inc include file."

Lol... I've fixed the message text.

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


Re: [fpc-devel] Progress on reviewing x86_64 optimizer overhaul and node semantic pass

2019-10-27 Thread Benito van der Zander

Hi,

I use TortoiseHg and then a Mercurial to Git converter...

Unfortunately the linux distributions do not want to maintain it and 
most ship with an outdated TortoiseHg in their package management


Best,
Benito

On 27.10.19 17:48, Florian Klämpfl wrote:

Am 27.10.19 um 15:32 schrieb Martok:
cover one single topic. Today, using e.g. TortoiseGit on Windows 
(sorry,

on Linux there is no tool which comes close) such patches can be
re-arranged without too much hazzle.


Just plain ol' git-gui can also do it. SmartGit is cross-platform and 
also
pretty nice. 


I use SmartGit on linux, but neither SmartGit nor git-gui come close 
to TortoiseGit for me.



I guess the main difference is whether one prefers side-by-side
diffs or udiffs.


In particular partial commits as well as conflict resolution work much 
better with TortoiseGit for me.





By the way, many people seem to use git on the client side... I 
remember there

were talks about moving the main repo to git. What happened to that?


Boring job nobody wants to do?
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Some thoughts on multi-line string support, and a possible syntax that I think is perfectly clean and Pascal-ish.

2019-07-05 Thread Benito van der Zander

Hi,

Am 04.07.19 um 19:51 schrieb Marco van de Voort:




If $ifdef was a single char token, maybe. And for a trivial feature, 
not a core one, like conditional compiling.




So the compiler will correctly give an error.


... but not at or near the place where the mistake is made. 


Some languages uses multiple chars to mark start and end to solve that.  
E.g. in XQuery there are strings with 3-char markers: |``[   ... |||]``||


Bye,
Benito

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


Re: [fpc-devel] atomic reads and writes, was: "Maybe Gareth can be convinced to spend his energy on this ... "

2019-07-02 Thread Benito van der Zander

Hi,

Am 28.06.19 um 11:24 schrieb George Bakhtadze:
If FPC somehow guarantees that a global field (even only of simple 
types) can be atomically read and written from any thread for ANY 
platform that is a very strong guarantee and worth mention in 
documentation.


 btw, how would you do that if it is in not guaranteed? especially on arm

Are there functions to do only an atomic reads and writes? (besides 
functions like interlockedincrement that do both, a read and write, 
together)


Best,
Benito
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] "Maybe Gareth can be convinced to spend his energy on this ... "

2019-06-27 Thread Benito van der Zander

Hi Gareth,

there are more optimizations to look at

An user could write custom string enumerators to replace such 
assignments in loops and try to manually solve that issue.



But then

https://bugs.freepascal.org/view.php?id=34915

the enumerators are stored in memory rather than registers, so it is 
always slower than a normal loop



Or since you like case; a case of strings should use a hashmap or 
something rather than doing one by one comparisons


Cheers,
Benito

Am 27.06.19 um 09:27 schrieb J. Gareth Moreton:

https://bugs.freepascal.org/view.php?id=35775

I'm both honoured and amused!  Thank you.

Gareth aka. Kit


---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

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


Re: [fpc-devel] Object upgrades (new)

2019-06-16 Thread Benito van der Zander

Hi',



I don't see a need to add management operators to objects. Objects 
have constructors and destructors, so they don't need Initialize and 
Finalize operators



One need would be to automatically call the destructor

It could make the code much simpler, especially when it also replaces 
try..finally, and prevent memory leaks




Just leave the poor, old objects alone.


Objects are much more useful than classes or records

Bye,
Benito

Am 15.06.19 um 18:50 schrieb Sven Barth via fpc-devel:

Am 15.06.2019 um 17:17 schrieb Ryan Joseph:
{ I think the old thread “Object upgrades” got broken during the 
server move so I’ll try to start a new thread and see if this gets 
posted }


Another question. I’m not sure it’s possible but I did try to add 
management operators to objects and found that if a initialize 
operator was declared in a unit which was precompiled and then 
inherited from an object in another unit which declared another 
initialize operators, the initialize operator would be called twice.


The issue is that the operator is compiled into some other code which 
always gets called when the object is used as a var type. Is there 
any work around to that? The options I’m aware of are:


1) don’t allow management operators in objects (that would be very 
unfortunate indeed).
2) don’t allow subclasses to redeclare a management operator (that 
seems ok since the operator can call a virtual method from the base 
class).
3) allow overriding of operators. I don’t think that would be make 
sense or perhaps even possible.
I don't see a need to add management operators to objects. Objects 
have constructors and destructors, so they don't need Initialize and 
Finalize operators and they have a defined assignment operation. Just 
leave the poor, old objects alone.


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


Re: [fpc-devel] Standard generic classes

2019-06-08 Thread Benito van der Zander


An object based container library would also be helpful.

With classes stored on the heap you always need additional memory 
access. Just one, but that is already bad in performance critical loops




Best, Benito

Am 06.06.19 um 18:23 schrieb George Bakhtadze:
It would be also great if there was an official set of interfaces (not 
necessarily in interface type form but API description) describing all 
these generic containers and algorithms.
Thus, all implementations which follow these interfaces are 
interchangeable.

I believe this is even more important than 4-th or 5-th implementation.
---
Best regards, George
06.06.2019, 17:58, "Ben Grasset" :

On Wed, Jun 5, 2019 at 11:11 AM Sven Barth via fpc-devel
mailto:fpc-devel@lists.freepascal.org>> wrote:

You could try to adjust the FGL unit to use the pluggable
sorting system introduced here:

https://svn.freepascal.org/cgi-bin/viewvc.cgi?view=revision=41167

Wouldn't that system itself need to be generic and not just use
void pointers first? Or is that part of what you meant?
IMO something FGL would benefit from also is the removal of the
probably-not-the-best-design inheritance from non-generic TFPSList
to everything else, which prevents inlining in a large number of
places (the compiler notes indicating such are visible basically
any time you use anything from FGL.)
,

___
fpc-devel maillist - fpc-devel@lists.freepascal.org

http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


___
fpc-devel maillist  -fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] "Blank slate" next version of FPC

2019-02-22 Thread Benito van der Zander

Hi,

The trick with enumerators is to never make them classes, and use 
advanced records instead, I've found. This way you avoid the heap 
allocation and the implicit try/finally. Also make sure you inline the 
MoveNext and GetCurrent!


that's what I do.


But the generated assembly is still worse than an old for loop, because 
it keeps all the fields of the record in memory.


for example

>   for I in TSlice.TakeWhile(Arr, Test) do J := I;

generates something like this

00401290 488b45f0 mov -0x10(%rbp),%rax
00401294 488b00   mov    (%rax),%rax
00401297 488905b22a0300   mov %rax,0x32ab2(%rip)    
# 0x433d50 

project1.lpr:75   J := I;
0040129E 488905bb2a0300   mov %rax,0x32abb(%rip)    
# 0x433d60 
project1.lpr:74   for I in 
TSlice.TakeWhile(Arr, Test) do

004012A5 488345f008   addq   $0x8,-0x10(%rbp)
project1.lpr:69   begin
004012AA 488b45e8 mov    -0x18(%rbp),%rax
project1.lpr:74   for I in 
TSlice.TakeWhile(Arr, Test) do

004012AE 483b45f0 cmp    -0x10(%rbp),%rax
004012B2 720a jb 0x4012be 
004012B4 483b45e0 cmp    -0x20(%rbp),%rax
004012B8 7404 je 0x4012be 
004012BA b001 mov    $0x1,%al
004012BC eb02 jmp    0x4012c0 
004012BE 30c0 xor    %al,%al
004012C0 84c0 test   %al,%al
004012C2 75cc jne    0x401290 

Nearly every line is accessing some memory, when it could keep 
everything in a few registers. amd64 has 16 registers, but fpc seems to 
only know three when records are involved




Cheers,
Benito

Am 22.02.19 um 16:51 schrieb Ben Grasset:
On Fri, Feb 22, 2019 at 1:07 AM Paul van Helden > wrote:


 How do you make a (for in) enumerator with a record? I don't use
them for exactly this reason, and they did seem to be another
useful language feature that turned out to be poorly implemented
by Embarcadero. (Haven't checked with FPC).


Here's an example (for FPC) that demonstrates it by implementing the 
"take-while" pattern:


program TakeWhileExample;

{$mode Delphi}{$H+}{$J-}
{$modeswitch NestedProcVars}
{$ImplicitExceptions Off}
{$PointerMath On}

type
  TSlice = record
  public type
    PT = ^T;
    ArrayType = array of T;
  private
    FFirst, FLast, FCurrent: PT;
    function GetCurrent: T; inline;
  public
    function GetEnumerator: TSlice; inline;
    function MoveNext: Boolean; inline;
    class function TakeWhile(const A: ArrayType; function F(const Val: 
T): Boolean): TSlice; static; inline;

    property Current: T read GetCurrent;
  end;

  TTestFunc = function(const Val: T): Boolean;

  function TSlice.GetCurrent: T;
  begin
    Result := FCurrent^;
  end;

  function TSlice.GetEnumerator: TSlice;
  begin
    Result := Self;
    with Result do FCurrent := FFirst - 1;
  end;

  function TSlice.MoveNext: Boolean;
  begin
    Inc(FCurrent);
    Exit((FCurrent <= FLast) and (FFirst <> FLast));
  end;

  function Test(const Val: SizeUInt): Boolean; inline;
  begin
    Exit((Val < 5000));
  end;

  class function TSlice.TakeWhile(const A: ArrayType; function 
F(const Val: T): Boolean): TSlice;

  var
    I: SizeUInt;
    X: TTestFunc absolute F;
    //FPC generates slightly better code for the "absolute" way, not 
sure why...

  begin
    with Result do begin
      FFirst := @A[0];
      FLast := @A[0];
      for I := 0 to High(A) do
        case X(A[I]) of
          True: Inc(FLast);
          False: Exit();
        end;
    end;
  end;

var
  I, J: SizeUInt;
  Arr: TSlice.ArrayType;

begin
  SetLength(Arr, 1);
  for I := 0 to  do Arr[I] := I;
  I := 0;
  J := 0;
  for I in TSlice.TakeWhile(Arr, Test) do J := I;
  WriteLn(J);
end.

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] "Blank slate" next version of FPC

2019-02-16 Thread Benito van der Zander

Hi,

there is NewPascal with improved memory safety/smart pointers: 
http://newpascal.org/



but we try as much as possible to break old code. 



I have noticed that. All my code has been broken by the codepage aware 
strings and TEncoding




and FPC's goal to remain Delphi-compatible.


So are inline variables coming soon? 
http://blog.marcocantu.com/blog/2018-october-inline-variables-delphi.html




Works fine, and I don't think my productivity is in any way enhanced 
by all the new features.

Maybe enumerators save some typing.


The new features also generate too often weird assembly, and then you 
have to benchmark is the old code faster or the new one, and then it can 
turn out the enumerators are slower than an old school loop , or the 
case of strings is slower than a hashmap, and then the new features need 
to be avoided.


Best,
Benito

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] ref count types / threadsave question

2019-01-03 Thread Benito van der Zander

Hi Fpc Developers',

Nobody is talking about the string content. 



But when they are stored together, that is the same. You can't get one 
without the other.



When core A creates a string to pass to core B, core A writes three 
things: ref count 1, the string content and the incremented ref count 2.


If core B could see stale data after the second write (with ref count 
1), it could also see stale data after the first write (without 
content). Nothing changes on core B between the writes.





It's only about the reference count right now and that one *can* 
differ between cores if that isn't correctly handled (even if the 
string content stays the same). 


Sure one core can read 2 after the other core wrote 1.

I do not see how a core can read 1 after a 2 was written.

Cheers,
Benito

Am 03.01.19 um 14:23 schrieb Sven Barth via fpc-devel:
Am Do., 3. Jan. 2019, 13:25 hat Benito van der Zander 
mailto:ben...@benibela.de>> geschrieben:


Hi,




The issue I was talking about is the fact that atomic operations
do function as global memory synchronisation operations across
all cores (at least not on all architectures). If core 1
atomatically increases refcount to two and you "then" load the
same refcount normally (without an atomic read-modify-exchange
oepration) on another core, this other core may still see the old
value. 


Is that really so?

The ref count is stored in the same memory block as the string itself.

If core 2 could not see the new ref count, it could not see what
is in the string and thus not use the string for anything .


Nobody is talking about the string content. It's only about the 
reference count right now and that one *can* differ between cores if 
that isn't correctly handled (even if the string content stays the same).


Regards,
Sven


___
fpc-devel maillist  -fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] ref count types / threadsave question

2019-01-03 Thread Benito van der Zander

Hi,




The issue I was talking about is the fact that atomic operations do 
function as global memory synchronisation operations across all cores 
(at least not on all architectures). If core 1 atomatically increases 
refcount to two and you "then" load the same refcount normally 
(without an atomic read-modify-exchange oepration) on another core, 
this other core may still see the old value. 



Is that really so?

The ref count is stored in the same memory block as the string itself.

If core 2 could not see the new ref count, it could not see what is in 
the string and thus not use the string for anything .


Bye,
Benito

Am 02.01.19 um 21:52 schrieb Jonas Maebe:

On 02/01/19 21:46, Martin Frb wrote:

On 02/01/2019 21:22, Benito van der Zander wrote:

Hi,

but if another core can do anything to the string, the refcount 
should already be 2, one for this core and one for the other core, 
should it not?

No:

// global var
var
   Foo: String;

// main thread
Foo := getsomestring_with_refcount_1();
TMyThread.Create(false); // not suspended / start

Foo := ''; // de-ref

//TMyThread.Execute
LocalFoo := Foo; // copy from the global var


This is a different issue. Managed types are indeed only threadsafe as 
long as there is no race condition that could cause their refcount to 
become zero at some point.


The issue I was talking about is the fact that atomic operations do 
function as global memory synchronisation operations across all cores 
(at least not on all architectures). If core 1 atomatically increases 
refcount to two and you "then" load the same refcount normally 
(without an atomic read-modify-exchange oepration) on another core, 
this other core may still see the old value.


The reason "then" is between quotes is because there is no forced 
ordering between these two operations (since there is no 
synchronisation/memory barrier linking the the two), which is also the 
basis of the problem.


See e.g. 
https://homes.cs.washington.edu/~bornholt/post/memory-models.html for 
more information.



Jonas
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] ref count types / threadsave question

2019-01-02 Thread Benito van der Zander

Hi,

but if another core can do anything to the string, the refcount should 
already be 2, one for this core and one for the other core, should it not?


UniqueString has such a test:

Function fpc_ansistr_Unique(Var S : Pointer): Pointer; [Public,Alias : 
'FPC_ANSISTR_UNIQUE']; compilerproc; inline;

{
  Make sure reference count of S is 1,
  using copy-on-write semantics.
}
begin
  pointer(result) := pointer(s);
  If Pointer(S)=Nil then
    exit;
  if PAnsiRec(Pointer(S)-AnsiFirstOff)^.Ref<>1 then
    result:=fpc_truely_ansistr_unique(s);
end;



Bye,
Benito

Am 02.01.19 um 20:14 schrieb Jonas Maebe:

On 02/01/19 20:08, Martin wrote:
If a local string var has a refcount of 1, then it can not be 
accessed by any other thread. Therefore it needs no lock for 
decreasing the ref.


You would need a full memory barrier before checking whether the 
reference count is one, otherwise it could have been increased to two 
by another thread on another core quite a while ago without that 
change being already visible on the current core. This would probably 
slow down things much more than any potential gain from not performing 
the atomic decrement.



Jonas
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] [Patch/RFC] Warnings for (in/over)complete case statements

2019-01-02 Thread Benito van der Zander



Wait - why does that code not raise a 5033 "Function Result does not seem to be
set"? Add a second property "Property MyOtherString : String Index 2 Read
GetString;", and now its provably wrong. No warning. This seems wrong,
considering what we just talked about on fpc-pascal.



Because there is no SetLength call in the function?


Am 02.01.19 um 17:41 schrieb Martok:

Am 02.01.2019 um 11:19 schrieb Michael Van Canneyt:


Consider the following:

Type
TMyClass = class
Private
  function GetString(AIndex: Integer): string;
Published
  Property MyString : String Index 1 Read GetString;
end;

function TMyClass.GetString(AIndex: Integer): string;

begin
case AIndex of
 1 : Result:=GenerateSomestringvalue;
end;
end;

I don't think there should be errors or warnings.

Good example.

Although... you *could* call GetString from some other class member function,
and at that point Result would be undefined. I don't think the compiler can
prove that?
Wait - why does that code not raise a 5033 "Function Result does not seem to be
set"? Add a second property "Property MyOtherString : String Index 2 Read
GetString;", and now its provably wrong. No warning. This seems wrong,
considering what we just talked about on fpc-pascal.


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Where to set proper alignment default of const strings?

2018-11-28 Thread Benito van der Zander

Hi Michael,

there was a discussion in this issue 
https://bugs.freepascal.org/view.php?id=33323



Cheers,
Benito

Am 28.11.18 um 19:51 schrieb Michael Ring:


The more I dig the more I ask myself if not the rtl routine is to 
blame for the issue in the first place because it only takes alignment 
of the destination into account when doing it's job.


Aligncount is calculated base on destination (which is RAM), for this 
reason the last line always crashes because psrc can be unaligned.


I most likely completely misunderstand the meaning of 
FPC_REQUIRES_PROPER_ALIGNMENT but usually ram can be written byte 
aligned but flash has often limitations on read access so alignment 
should look for psrc as this can come from flash.


Unless of course FPC_REQUIRES_PROPER_ALIGNMENT is  primarily meant for 
speed improovement only, then it would make sense to look at pdest to 
try to optimize write performance by having as much aligned access as 
possible.I only found an old discussion in lazarus list from 2011 on 
this topic, where it looks like structs were manually aligned in 
lazarus, but I did not look too deep into the patches.


procedure Move(const source;var dest;count:SizeInt);[public, alias: 
'FPC_MOVE']; from generic.inc line77:


    begin
  { Align on native pointer size }
--> *aligncount:=(PtrUInt(pdest) and (sizeof(PtrUInt)-1));*
  dec(count,aligncount);
  pend:=psrc+aligncount;
  while psrc  pptruint(pend):=pptruint(psrc)+(sizeuint(count) div 
sizeof(ptruint));

  while psrc
Hi,

I am debugging an issue that I see on mipsel embedded target (and 
perhaps also on arm-embedded for corteX-m0, I had crashes in the same 
rtl routine a while ago)


because RAM is small on embedded devices I use:

{$WRITEABLECONST OFF}

which means that const are read from flash and not from ram.

problem is now that const strings are sometimes not 32-bit aligned 
and this causes an unaligned access exception on pic32mx because date 
from flash must be read 32-bit aligned.


I thought that I had seen the correct place to configure this 
alignment in the past but my google/grep foo is weak at the moment, I 
cannot find something in the fpc sourcecode that rings a bell.


{$CODEALIGN CONSTMIN=4}

also does not work, I recompiled and in my case the const is still 
improperly alligned.



Thanks in advance,


Michael



___
fpc-devel maillist  - fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


[fpc-devel] sizeof member in class procedure

2018-08-14 Thread Benito van der Zander

Hi,

why is sizeof on object/class fields sometimes allowed and sometimes not?

type TTest = object
  f: integer;
  class procedure test;
end;

class procedure TTest.test;
begin
  writeln(sizeof(f)); // does not compile
  writeln(sizeof(TTest.f));  // compiles
end;

---

type TTest = class
  f: integer;
  class procedure test;
end;

class procedure TTest.test;
begin
  writeln(sizeof(f)); // does not compile
  writeln(sizeof(TTest.f));  // does not compile
end;

surely that should all be equal to sizeof(integer)

Bye,

Benito


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Loop unrolling question

2018-08-04 Thread Benito van der Zander

Hi,

case of strings could also use some optimization

does it still call fpc_ansistr_compare_equal ?

fpc could hash the strings, or build a trie, even testing the length 
first would help



Cheers,
Benito



Am 03.08.2018 um 21:57 schrieb J. Gareth Moreton:

  Hi everyone,

  So I'm pondering about attempting to implement the binary search system I
devised for case blocks.  To find the correct case label, you need to
iterate a search loop a fixed maximum of ceil(log2(n)) times, where n is
the number of individual case values (excluding "else").  Given that this
is quite a low number and I managed to get the loop itself down to just 8
instructions (not including the comparison and conditional jump at the
end), this could be unwrapped for low values of ceil(log2(n))... possibly
up to 7 or 8, I'd say.  However, if an exact match is found early, how
serious is the penalty of having a conditional jump forward on each
unrolled iteration for x86-64, whether it's taken or not? (This would be
the equivalent of a Break command)

  Gareth aka. Kit
  



___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] FPProfiler

2018-02-19 Thread Benito van der Zander

Hi,


In theory a call to _mcount could be replaced with a
compilerproc, which you could then override in the RTL, allowing a way to
add support for various profilers.


If it became fully overridable,  you could put a callback between any 
branch/line/function and create instrumentalization not just for profilers.


A single tracing system for gprof, gcov, american fuzzy lop, etc. ...


Best,
Benito



Am 19.02.2018 um 12:01 schrieb Karoly Balogh (Charlie/SGR):

Hi,

On Mon, 19 Feb 2018, Sven Barth via fpc-devel wrote:


It's not the same scenario as heaptrc is entirely working in the RTL
without any compiler extension (aside from the -gh parameter). Profiling
code however would require extensions to the compiler whereby it would
also need to handle exceptions correctly and such things.

Yes, but it's still worth thinking about how to generalize the current GNU
Profiler support we have, which is messy at places, and of course entirely
depends on GNU Profiler. But it's still mostly about generating a call to
_mcount in various ways, taking the stackframe of various platform ABI
into account. In theory a call to _mcount could be replaced with a
compilerproc, which you could then override in the RTL, allowing a way to
add support for various profilers.

I'm sure it would allow moving out some of the complexity from the
compiler to the RTL, and make things more flexible in the end.

(And GNU profiler's _mcount itself also depends on GCC/GLibc
implementation details per platform.)

Charlie
___
fpc-devel maillist  -fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] End of support for Win XP?

2018-01-31 Thread Benito van der Zander

Hi,

XP is still important


yesterday I had a dream about some kind of ebook reader with multiple 
pages, like 7 displays in a row on a foldable sheet, each for one page. 
(and something about a washing machine) At first the displays looked 
like Android, but when you took it apart, you noticed there was no 
software on the display devices, and underneath each display device 
there was a second device looking kind of like the mobile emitter in 
Voyager which was doing all the processing and which was actually 
running Windows XP


Best,
Benito



Am 31.01.2018 um 13:44 schrieb Bart:

On Tue, Jan 30, 2018 at 10:40 PM, Florian Klämpfl
 wrote:


Probably yes, at least with the release of 3.2.0. After all, Win XP is almost 
for 4 years out of
support. But if somebody decides to stick with Win XP, he can stick also with 
FPC 3.0.x, it will not
stop working.


Just out of curiosity: is thei library loaded dynamically or statically?
I expect Lazarus will want to continue support for XP for some time,
if possible also with the 3.2.x version of fpc as compiler back-end.

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


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] First pas2js public release

2017-12-18 Thread Benito van der Zander


Hi,


Of course not. First of all 10 is ridiculously small and second
the above example is probably optimized by the engine.
For example under V8 with 1 iterations you get 1.1s and 1.9s.


It is not so small or optimized with Firefox.

It took around 100ms

With 1000, it gives 5479ms and 4814ms, i.e. the array is faster here

With 1 the script does not complete, before Firefox ask "do you 
want to stop the too slow script"



Like what?
What pointer code do you want to port?



I have not looked at any specific.

But recently I have started to change everything to pointers.

For example when you have an array and want a subrange without the first 
element of the array, you can either copy almost everything in a new 
array, or just use a pointer to the second element.


Or in my XQuery interpreter I used interfaces to get ref counting, but 
at many places the ref counting was too slow, so I replaced it with 
pointers to interfaces.


E.g. when iterating over an array of interfaces with an enumerator. for 
x in thearray do, the array keeps the ref count >= 1, so x is much more 
efficient as pointer to an interface.





Isn't that a contradiction to "port all existing"?


Not with full program static analysis

Or people could mark the values they need as pointers in other units (by 
adding an unused public function just accessing it as pointer)


Best,
Benito



On 18.12.2017 17:19, Mattias Gaertner wrote:

On Mon, 18 Dec 2017 14:55:53 +0100
Benito van der Zander<ben...@benibela.de>  wrote:


[...]

That would be quite a slow down.

Is it?

I saw no speed difference between

var x = 1;
for (var i=0;i<10;i++) x++;

and

var x = [1];
for (var i=0;i<10;i++) x[0]++;

in Firefox.

Of course not. First of all 10 is ridiculously small and second
the above example is probably optimized by the engine.
For example under V8 with 1 iterations you get 1.1s and 1.9s.

Test with some more real world code.


Perhaps more memory usage

Pretty sure more memory usage.

  

Isn't speed the main idea of using pointers?

It would be to port all existing pascal code

Like what?
What pointer code do you want to port?



Also what if var and @var are in different units?

Either it needs full program static analysis, or pointers are only
allowed to something that was used with a pointer in its unit

Isn't that a contradiction to "port all existing"?



You may want to take a look at asm.js, which has a working
model for emulating pointers in JavaScript. It would be possible to add
a pas2js target for that. But then again there is webassembly
as well and it seems to have better support.

That model looks like quite a slow down

The js engines have some optimizations for that model.

Mattias
___
fpc-devel maillist  -fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] First pas2js public release

2017-12-18 Thread Benito van der Zander


Hi,


It seems you want to emulate pointer of integer.


Of all primitive types

In the JavaScript example there was no more integer typing.



That would be quite a slow down.


Is it?

I saw no speed difference between

var x = 1;
for (var i=0;i<10;i++) x++;

and

var x = [1];
for (var i=0;i<10;i++) x[0]++;

in Firefox. Perhaps more memory usage


Isn't speed the main idea of using pointers?


It would be to port all existing pascal code



Also what if var and @var are in different units?


Either it needs full program static analysis, or pointers are only 
allowed to something that was used with a pointer in its unit


Local pointers (like var arguments) could always be changed to an array 
when the address is taken, and copied back at the end of scope.




And what about pointer of pointer?


It becomes an array of arrays with the same construction



You may want to take a look at asm.js, which has a working
model for emulating pointers in JavaScript. It would be possible to add
a pas2js target for that. But then again there is webassembly
as well and it seems to have better support.



That model looks like quite a slow down

Cheers,
Benito



On 17.12.2017 22:24, Mattias Gaertner wrote:

On Sun, 17 Dec 2017 21:43:45 +0100
Benito van der Zander <ben...@benibela.de> wrote:


Hi,


Naturally, any memory pointer operation is not possible in Javascript.
Code that relies on this will not work.


it would be great, if pointers were added.

There are pointers already. For example references to class and
arrays.
It seems you want to emulate pointer of integer.

  

One trick would be to wrap every variable that is accessed by a pointer
in an array (or object).

That would be quite a slow down.
Isn't speed the main idea of using pointers?

Also what if var and @var are in different units?
And what about pointer of pointer?

You may want to take a look at asm.js, which has a working
model for emulating pointers in JavaScript. It would be possible to add
a pas2js target for that. But then again there is webassembly
as well and it seems to have better support.

Mattias

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] First pas2js public release

2017-12-17 Thread Benito van der Zander

Hi,



Naturally, any memory pointer operation is not possible in Javascript. 
Code that relies on this will not work.



it would be great, if pointers were added.


One trick would be to wrap every variable that is accessed by a pointer 
in an array (or object).  The array can then be used as reference.


For example:

var a: integer;
  b: pinteger;

begin

 a := 10;
 b := @a;
 b^ := 11;
 writeln(a);
 writeln(b^);

end;

becomes

 var a,b
 a = [10]
 b = a
 b[0] = 11;
 alert(a[0])
 alert(b[0])


For pointer arithmetic or pointers inside array elements, it would need 
an additional index:


For example:

var a: integer = 10;
    ar: array[0..1] of integer = (1,2);
    b: pinteger;

begin
 b := @a;
 b^ := 11;
 b := @ar[1]
 b^ := 12;
 dec(b);
 b^ := 13;
end;

becomes

 var a,b,bi,ar
 a = [10]
 ar = [1,2]
 b = a; bi = 0
 b[bi] = 11;
 b = ar; bi = 1
 b[bi] = 12;
 bi--;
 b[bi] = 13;

It does not cover pointers of mixed sizes (e.g. getting a pbyte of an 
integer, or converting double to int64), but the most common things 
should work. pchars should probably get special treatment, too. When it 
is not modified, there is no need to wrap a string in an array, but just 
keep a string reference plus index. Perhaps there need to be two type of 
pchars, readonly and writeable. Only writeable need wrapping.


And then there needs to be some kind of static analysis that only wraps 
those variables/fields in arrays whose address is actually taken anywhere.



Best,
Benito



Am 16.12.2017 um 17:36 schrieb Michael Van Canneyt:


Hello fellow Pascal enthousiasts,

It is with great pleasure that I can finally announce the first publicly
available version of pas2js. A "beta" version, version 0.8.39.
The endpoint (for the time being) of nearly 10 years of (slow) 
development.


pas2js is a Object Pascal to Javascript transpiler. It compiles Object
pascal, and emits Javascript. The javascript is usable in the browser, 
and

in Node.js.

It is open source, and part of FPC/Lazarus. This makes Free Pascal a 
full-stack development environment for Web Development:
You can use it to program the server and the browser alike, all from 
within

the environment you love so much :)

What does pas2js include ?
--

* On the language level:

It supports basically Delphi 7 syntax, interfaces excepted.
Naturally, any memory pointer operation is not possible in Javascript. 
Code that relies on this will not work.


This is just the first version, we of course want to add the same 
language features that exist in Delphi and FPC today.


* On the runtime level:

Beside the compiler itself, there is a basic Object Pascal RTL, and 
several units from the FPC Packages are also available:


system
sysutils
Math
strutils
rtlconst
classes
contnrs
DB (yes, TDataset)
fpcunit testsuite
custapp
restconnection
js (javascript system objects)
web (browser provided objects)
libjquery (jquery is available too)
nodejs (basic node runtime environment)
typeinfo
objpas
browserconsole (support for writeln)
dateutils
browserapp
nodejsapp

* Debugging:

Obviously, the browser debugger can be used to debug the Javascript.
But there is more: the compiler can emit a source map, and this means 
that

if the browser finds the source file, it will display the original source
file instead of the javascript. You can debug Object pascal in the 
browser.


* Demoes ?

The package has several demoes, including FPReport, TDataset, JQuery and
Bootstrap.

* Documentation  ?

As befits an open source project, docs are lagging behind :/

But a WIKI page has been started, it will be expanded as time permits:

http://wiki.freepascal.org/pas2js

* Sources ?

The pas2js compiler sources and RTL sources have been checked in in 
FPC's subversion repository. The page describes where to find it in SVN.


* Binaries ?

A snapshot is available:
http://www.freepascal.org/~michael/pas2js/pas2js-demo-0.8.39.zip

* Reporting bugs ?

The FPC bugtracker has now a 'pas2js' project, it can be used to report
bugs.

* Can you help ?

Yes, of course. There is still a lot of work to be done. Feel free to 
contact me or Mattias Gaertner with questions.


What about Lazarus ?


Lazarus "understands" the extensions to object pascal (for importing 
Javascript

classes) that were borrowed from the JVM version of the compiler, so the
code completion will continue to work.

Using the pre-compiler command, CTRL-F9 just works. On error, you will be
shown the error location etc.

Further and deeped integration of pas2js into lazarus is expected. In 
the first place, IDE integration. Later on, a real widget set for the 
browser can (and hopefully will) be created.


But that is not all !
-

In the very near future, a major Delphi component vendor will announce a
complete package for RAD web development in the Delphi IDE. The 
expectation is 

[fpc-devel] Quickly recompiling fpc

2017-12-09 Thread Benito van der Zander

Hi,

how do you recompile fpc after making a small change in the compiler, 
like enabling the debugmsg define in x86/aoptx86.pas?


make buildbase says nothing was changed, and make clean; make buildbase 
recompiles not just the compiler, but also the rtl, which is a waste of 
time.


Bye,

Benito


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] trunk broken

2017-09-02 Thread Benito van der Zander

Hi,

 trunk is always broken, is it not?

Perhaps that is why it is called trunk. After all a trunk is an 
incomplete tree. Just a little bit more than a completely broken tree 
(stump)



Best,
Benito



Am 02.09.2017 um 19:03 schrieb Sven Barth via fpc-devel:


Am 02.09.2017 17:06 schrieb "Karoly Balogh (Charlie/SGR)" 
>:

>
> Hi,
>
> On Sat, 2 Sep 2017, Marco van de Voort wrote:
>
> > The expansion of texpropcode in r37108 (Mattias) breaks fppasjs 
because it

> > defines an array with texpropcode as range.
> >
> > This prohibits building of trunk.
>
> Sven fixed it already in r37109.
>
> (The quick-response advantage of receiving build notifications from
> Marcus' Jenkins... ;)

Indeed :)

Regards,
Sven



___
fpc-devel maillist  -fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Optimizing unused return values of inline functions

2017-08-23 Thread Benito van der Zander

Hi,


Isn't rax needed for the call to Free?



I think self stays in rdi

Perhaps we need a new calling convention that keeps self in rax. Or the 
return value in rdi


Cheers,
Benito



Am 21.08.2017 um 15:45 schrieb Stefan Glienke:

Isn't rax needed for the call to Free?
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Optimizing unused return values of inline functions

2017-08-23 Thread Benito van der Zander

Hi,,


  SomeProc(Builder
.Build('1')
.Build('2')
.Build('3').Value);






That's exactly what I wanted to use it for


And since a string builder is such a low level construct, mostly used 
for performance improvements, it needs to be fast without additional 
instructions




Best,
Benito



Am 22.08.2017 um 14:42 schrieb Kazantsev Alexey via fpc-devel:

On Tue, 22 Aug 2017 13:15:24 +0200 (CEST)
Michael Van Canneyt  wrote:


Call me old-fashioned, but I much prefer

With StdIO::stdOutPrinter() do
  begin
  out("Helllo World ");
  out(42);
  out("");
  hex();
  out(42);
  line();
  end;

I see no point or gain in the "fluent" code.

  SomeProc(Builder
.Build('1')
.Build('2')
.Build('3').Value);



___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Optimizing unused return values of inline functions

2017-08-21 Thread Benito van der Zander

Hi,

This pattern is not inherently efficient. Why should it be ? 



It is not efficient, because of the pointless instruction!



Bye,
Benito



Am 21.08.2017 um 08:39 schrieb Michael Van Canneyt:



On Sun, 20 Aug 2017, Benito van der Zander wrote:


Hi,

why does fpc not remove the calculation of the return value of inline 
functions, when the return value is unused?


For example

type TUtility = class
 function doSomething: TUtility; inline;
end;


It is a popular pattern to add result := self; to _every_ method (or 
result := @self in objects/records), so it can be chained as 
dosomething().dosomething().dosomething(),.
but one cannot use it with fpc efficiently, when it inserts too many 
unnecessary instructions


A strange statement.

This pattern is not inherently efficient. Why should it be ?

It's just something that boiled over from other languages and some people
see it as a nifty way of writing code.

Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


[fpc-devel] Optimizing unused return values of inline functions

2017-08-20 Thread Benito van der Zander

Hi,

why does fpc not remove the calculation of the return value of inline 
functions, when the return value is unused?


For example

type TUtility = class
  function doSomething: TUtility; inline;
end;

function TUtility.dosomething: TUtility;
begin
   writeln();
   result := self;
end;

adds a movrax,rdi in the caller function, even if rax is then never 
used.


{
26  begin
   0x004001c0 <+0>: push   rbx

27ut := TUtility.Create;
   0x004001c1 <+1>: movabs rsi,0x1
   0x004001cb <+11>:lea rdi,[rip+0x2b2fde]# 
0x6b31b0 
   0x004001d2 <+18>:call   0x411b60 


   0x004001d7 <+23>:movrbx,rax

28ut.dosomething;
   0x004001da <+26>:call   0x41bf20 
   0x004001df <+31>:movrdi,rax
   0x004001e2 <+34>:call   0x41c100 
   0x004001e7 <+39>:call   0x416170 
   0x004001ec <+44>:movrdi,rbx
   0x004001ef <+47>:movrax,rdi 
//<--- here


29ut.free;
   0x004001f2 <+50>:call   0x411cd0 



30  end;
   0x004001f7 <+55>:poprbx
   0x004001f8 <+56>:ret
}


It is a popular pattern to add result := self; to _every_ method (or 
result := @self in objects/records), so it can be chained as 
dosomething().dosomething().dosomething(),.
but one cannot use it with fpc efficiently, when it inserts too many 
unnecessary instructions




Best,

Benito


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Request for an interim release of the 3.0 branch

2017-04-28 Thread Benito van der Zander

Hi,

r35545, too ? (http://bugs.freepascal.org/view.php?id=31135)



Bye,
Benito



On 04/26/2017 03:17 PM, Marco van de Voort wrote:

In our previous episode, Bart said:

The issue is fixed by merging  r33007, 33008, 33561 and 34384 (unit exeinfo).
Probably r35886 should be merged as well.

These revs ( but not 35886) are merged in the fixes branch a few days back
when I saw the bugreport about the issue, please test.


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel