Re: [fpc-devel] Const optimization is a serious bug

2011-07-08 Thread Daniël Mantione



Op Thu, 7 Jul 2011, schreef Chad Berchek:

The problem comes down to the specs though, or rather the lack thereof. As I 
have searched the web and read some docs at Embarcadero, things have only 
become more ambiguous.


You are looking in the wrong places. Both Turbo Pascal and Delphi came 
with a language guide that describe the desired behaviour in deep detail.


Daniël___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug (What nexy)

2011-07-08 Thread Martin

On 08/07/2011 11:05, Jonas Maebe wrote:

On 08 Jul 2011, at 05:51, Chad Berchek wrote:
I'm more interested now in a solution. The solutions I've seen so far 
have potential, but in my opinion most of them seem like they are 
more complex, would be more overhead, and produce worse performance 
than just getting rid of the const optimization.


The main proposals I've seen were
a) treat const string parameters the same as value parameters (i.e., 
get rid of the current const behaviour)
b) the same as a), combined with a very conservative heuristic to 
apply the optimization in case there can be no side effects. I.e., in 
case there is not a single function call and not a single indirect 
write (var parameter, pointer, global variable, dynamic array, ...) to 
any string or anything that might be somehow aliased to a string 
passed as parameter to the current routine
c) keep the current behaviour, but add functionality to the compiler 
to help debug problems that can occur as a result of problems that can 
occur as a result of this behaviour



Actually I think you can describe that as 3 independent proposals:

1) Add a compiler switch or directive to disable constbehaviour for 
ref counted types (e.g. simply ignore const for 
string/dyn-array/interface params; Actually downgrade, still prevent 
assignment to local var)
2) Add automatic optimization of dropping ref-count and exception frame, 
if the compiler can prove it to be save (e.g.  no calls to any other 
code...). This can happen completely independent of either the present 
or meaning of const.

3) Add safety checks (similar to range checks)

1)
The only thing I can see, is that future optimization, added to 
const-param (of all types, e.g also records, etc) can introduce 
problems, when the value of the const param is indirectly changed, and 
that may lead to further requests of what const should or should not do. 
It may be needed to draw a line, and point out that const will always 
have some dangers. (Apparently with such a ignore-it-fix not any more 
for ansistrings (copy on write), but still for dyn arrays (also ref 
counted)).
Anyway if the extend off that switch is well defined, it may be worth 
having. IMHO better as compiler directive, that would allow to put it 
into the code, and make sure behaviour is stabel (rather than behaviour 
might change, if a compiler switch is used)


2)
Depends, on someone writing and contributing it. Mostly unrelated to the 
discussion.


3)
Might not only help to fix issues, but might also create awareness.

However, looking at the generated assembly, I can't believe there 
isn't a more efficient way to handle the implicit try-finally. It 
feels to me like that is where the problem is. There is a lot of code 
and several function calls that go into implementing that implicit 
'finally' block. There's got to be some way to decrement the refcount 
even when there are exceptions but without so much overhead. It would 
require changes to the exception handling mechanism though. Here my 
knowledge runs out.


The main problem here is that FPC's exception handling is based on 
setjump/longjump. This technique has a relatively high overhead for 
try, but low overhead when an exception actually occurs (of course, 
since exceptions are supposed to happen only exceptionally, that's not 
a really good selling point). The main reason we use it is because 
it's easy to implement.




For implicit exception (so long as there purpose is only to decrease 
ref-counts (and free the data if 0 reached), there is another solution.


If an exception frame already exists (even if on a higher stackframe), 
and the compiler can detect that it does exist:
then instead of creating an exception frame for the current stackframe, 
all the variables that need refcount decrement, can be added to a list. 
This list can be processed by the exception handler, before any other 
code executes. The draw back is, that memory needs to be allocated for 
this list.



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


Re: [fpc-devel] Const optimization is a serious bug

2011-07-08 Thread Sven Barth

Am 08.07.2011 12:05, schrieb Jonas Maebe:

However, looking at the generated assembly, I can't believe there
isn't a more efficient way to handle the implicit try-finally. It
feels to me like that is where the problem is. There is a lot of code
and several function calls that go into implementing that implicit
'finally' block. There's got to be some way to decrement the refcount
even when there are exceptions but without so much overhead. It would
require changes to the exception handling mechanism though. Here my
knowledge runs out.


The main problem here is that FPC's exception handling is based on
setjump/longjump. This technique has a relatively high overhead for
try, but low overhead when an exception actually occurs (of course,
since exceptions are supposed to happen only exceptionally, that's not a
really good selling point). The main reason we use it is because it's
easy to implement.

A better approach would be to use SEH-based exception handling (which
has no overhead at all for try, and a high overhead in case an
exception occurs), but that woud require
a) support for generating EH frames for all platforms (it's currently
only supported for a number of i386 and x86-64 platforms)
b) support for parsing EH frames on all platforms and performing
exception handling based on that

This is definitely something we want, but nobody has found the time yet
to implement it.


Around a year ago I've experimented with using SEH on Windows (I have 
not reached a working state back then). It's on my list to revive this 
again, but before that I want to have Delphi compatible generics and 
extended RTTI with attributes working :D


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


Re: [fpc-devel] Const optimization is a serious bug (What nexy)

2011-07-08 Thread Hans-Peter Diettrich

Martin schrieb:

c) keep the current behaviour, but add functionality to the compiler 
to help debug problems that can occur as a result of problems that can 
occur as a result of this behaviour


Concrete: add means to ignore const with managed types.

Further debugging aids as far as feasable. Do we want to make FPC an 
outstanding compiler, WRT bug hunting? IMO *not* a realistic goal.




Actually I think you can describe that as 3 independent proposals:

1) Add a compiler switch or directive to disable constbehaviour for 
ref counted types (e.g. simply ignore const for 
string/dyn-array/interface params; Actually downgrade, still prevent 
assignment to local var)


+1

2) Add automatic optimization of dropping ref-count and exception frame, 
if the compiler can prove it to be save (e.g.  no calls to any other 
code...). This can happen completely independent of either the present 
or meaning of const.


~ [people will point at you if it doesn't work perfectly :-]


3) Add safety checks (similar to range checks)


As a debug feature only, on demand (debugging memory manager?)


Most people don't have problems with const, according debug features are 
*not* an urgent requirement.


I only agree that a *quick workaround* (global ignore const option) is 
highly desireable (a *must*) for the rare (but real) cases where it can 
make runtime errors disappear.


Extended debug features are not so important, because code with such 
problems typically suffers from *general* problems, which suggest a 
change of the personal coding style. A compiler can prevent an user from 
shooting himself into one foot, at best, but not prevent him from 
shooting himself into other limbs :-]





3)
Might not only help to fix issues, but might also create awareness.


This may apply to newbies, but IMO will be ignored by people which 
*believe* that they are superior coders, maybe from practice in other 
languages. A collection of suggested design patters (resource 
protection, object ownership...) would be nice - in detail for pointing 
people with coding style problems to. We could add to that collection 
all demo code, that forces unexpected exceptions, together with a safe 
version of the same code, that eliminates the demonstrated problem.




If an exception frame already exists (even if on a higher stackframe), 
and the compiler can detect that it does exist:
then instead of creating an exception frame for the current stackframe, 
all the variables that need refcount decrement, can be added to a list. 
This list can be processed by the exception handler, before any other 
code executes. The draw back is, that memory needs to be allocated for 
this list.


IMO this is what the compiler already does, or should do - an implicit 
try-finally block with a list of variables to be finalized on exit of a 
subroutine (used also in stack unwinding after an exception). One should 
not confuse try-except (*handling* exceptions) and try-finally 
(guaranteed *cleanup*).


DoDi

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


Re: [fpc-devel] Const optimization is a serious bug

2011-07-08 Thread Den Jean
On Friday 08 July 2011 12:05:02 Jonas Maebe wrote:
 The main problem here is that FPC's exception handling is based on  
 setjump/longjump. This technique has a relatively high overhead for  
 try, but low overhead when an exception actually occurs (of course,  
 since exceptions are supposed to happen only exceptionally, that's not  
 a really good selling point). The main reason we use it is because  
 it's easy to implement.
 
 A better approach would be to use SEH-based exception handling (which  
 has no overhead at all for try, and a high overhead in case an  
 exception occurs), but that woud require
I strongly prefer the current situation where the occurrence of 
exceptions does not incur an important extra overhead compared to
the nominal situation.

In the type of applications I write (Air Traffic Control Radar Screens,
Electronic Strips and System Interfaces) it is considered good practice 
to catch exceptions in every procedure because it is a must that 
the applications always survive and continue to provide the remaining,
not affected services.(graceful degradation principle)

I do not want any discussions whether catching exceptions is good or not.
If someone thinks otherwise, I do not care at all, do not bother me or 
this mailing list. 

However what is imperative is that when many exceptions occur, there should 
not be a mayor performance penalty. One of the reasons I use languages such 
Pascal and Ada for this type of applications, is that they are very fast, 
(though I also have foreseen code to shutdown services with too many problems 
in a given time frame). So I beg you to leave exceptions as is (please :-)). 

kind regards,

Den Jean
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


[fpc-devel] Sparc v9

2011-07-08 Thread Ludo Brands
membar and stbar are instructions available as of sparc v9. To get fpc
running on a sparc v9 I have commented out
def_system_macro('FPC_HAS_MEMBAR'); in compiler/options.pas. Is there a
command line option that does the same? 

Ludo

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


Re: [fpc-devel] Sparc v9

2011-07-08 Thread Vincent Snijders
2011/7/8 Ludo Brands ludo.bra...@free.fr:
 membar and stbar are instructions available as of sparc v9. To get fpc
 running on a sparc v9 I have commented out
 def_system_macro('FPC_HAS_MEMBAR'); in compiler/options.pas. Is there a
 command line option that does the same?

maybe -uFPC_HAS_MEMBAR.

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


RE : [fpc-devel] Sparc v9

2011-07-08 Thread Ludo Brands
 
 maybe -uFPC_HAS_MEMBAR.
 

Mmm. Didn't expect that a command line undefine would override a define in
the code. I'll give it a try. 

Thanks, Ludo

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


Re: [fpc-devel] Sparc v9

2011-07-08 Thread Mark Morgan Lloyd

Ludo Brands wrote:

membar and stbar are instructions available as of sparc v9. To get fpc
running on a sparc v9 I have commented out
def_system_macro('FPC_HAS_MEMBAR'); in compiler/options.pas. Is there a
command line option that does the same? 


I wonder whether this would be worth considering on a per-OS basis? 
Working from memory, when I last looked I think that Linux initialised 
the processor to a mode where it didn't reorder memory accesses so (if 
my recollection of the documentation is correct) didn't require membars, 
in which case an RTL startup check for an unexpected mode should suffice.


--
Mark Morgan Lloyd
markMLl .AT. telemetry.co .DOT. uk

[Opinions above are the author's, not those of his employers or colleagues]
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Sparc v9

2011-07-08 Thread Mark Morgan Lloyd

Ludo Brands wrote:

membar and stbar are instructions available as of sparc v9. To get fpc
running on a sparc v9


For completeness and playing Devil's Advocate, I do have to ask whether 
pre-v9 (i.e. pre-UltraSPARC) systems are relevant any more.


I've got one remaining Sun4m system (SPARCstation 20) here which will 
just about run Linux 2.4, not sure it will handle anything later. I've 
also got several Sun4d which I've managed to get running SMP 2.4 but not 
2.6. Both of those will also run Solaris 8 but I don't think later.


I've got a Sun4c (SPARCstation IPC) which I can't get to run a realistic 
(=2.4) version of Linux, and won't run later than Solaris 7.


I must admit that I'm very attached to the Sun4d, because it performs 
spectacularly and is a Xerox PARC design. But I'd certainly not expect 
it to run an off-the-shelf FPC.


The remaining question is whether there's any mileage in supporting the 
Gaisler Research LEON processor, which I believe is a v8.


--
Mark Morgan Lloyd
markMLl .AT. telemetry.co .DOT. uk

[Opinions above are the author's, not those of his employers or colleagues]
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-08 Thread Martin

On 09/07/2011 00:09, Max Vlasov wrote:

The answer is indirect referencing. it's a workaround that probably
will solve the problem, but I must admit that I don't know what is the
exact performance price. The compiler when it detects const s:
ansistring could switch to passing not the actual address of the
string, but the address of the variable that holds it. In other words
passing PString instead of string. In this case no reference counting
or exception frame is probably created and at the same time, if the
used string is reallocated occasionally because of a side change, the
code will not fail because it will just automatically use the new
modified address.



function CRCConstString(constref Str: string): integer;

does what you describe

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


Re: [fpc-devel] Const optimization is a serious bug

2011-07-08 Thread Max Vlasov
On Sat, Jul 9, 2011 at 3:14 AM, Martin f...@mfriebe.de wrote:
 On 09/07/2011 00:09, Max Vlasov wrote:

 The answer is indirect referencing. it's a workaround that probably
 will solve the problem, but I must admit that I don't know what is the
 exact performance price. The compiler when it detects const s:
 ansistring could switch to passing not the actual address of the
 string, but the address of the variable that holds it. In other words
 passing PString instead of string. In this case no reference counting
 or exception frame is probably created and at the same time, if the
 used string is reallocated occasionally because of a side change, the
 code will not fail because it will just automatically use the new
 modified address.


 function CRCConstString(constref Str: string): integer;

 does what you describe


Hmm, it's interesting.. Some observations:
- constref is implemented in 2.5.1, right? Unfortunately I can not
test it right now in 2.4.2, it refuses to recognize it, but I I want
to test it.
- In LCL it used only with interfaces and TGuid's, no strings or other
structures
- there are not much information about constrefs in Lazarus, several
posts, the largest part of them is yours, Martin :) so you're probably
one of the few who really understand it  :)

If constref is what you said , some quick fix for those who's scary
of the current const behavior could  be iintroducing a setting in fpc
that forces all const to be constrefs.

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


Re: [fpc-devel] Const optimization is a serious bug

2011-07-08 Thread Martin

On 09/07/2011 00:59, Max Vlasov wrote:

On Sat, Jul 9, 2011 at 3:14 AM, Martinf...@mfriebe.de  wrote:

function CRCConstString(constref Str: string): integer;
does what you describ

Hmm, it's interesting.. Some observations:
- constref is implemented in 2.5.1, right? Unfortunately I can not
test it right now in 2.4.2, it refuses to recognize it, but I I want
to test it.
- In LCL it used only with interfaces and TGuid's, no strings or other
structures
- there are not much information about constrefs in Lazarus, several
posts, the largest part of them is yours, Martin :) so you're probably
one of the few who really understand it  :)
Well the LCL can't use it, if it's trunk only (except if IFDEFed). The 
LCL should compile with release fpc...


See: 
http://wiki.lazarus.freepascal.org/FPC_New_Features_Trunk#Constref_parameter_modifier


- See difference to normal const is  that it must be passed by 
reference.


- Note (same as const) it is described as: This modifier means that the 
compiler can assume that the parameter is constant
The assume means that the requirement for constant-ness goes above 
that what the compiler can enforce (that is: the compiler can enforce 
only the local var; but constant implies the value by any means of access)


With what the compiler does today (afaik) none-constantness would not 
cause any harm (yet). Unless you count it as harm (and you should) that 
future FPC may (= is allowed to) compile your code (without any 
warning or hint) into an exe that behaves different.


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


Re: [fpc-devel] Const optimization is a serious bug

2011-07-08 Thread Chad Berchek

Martin wrote:

- See difference to normal const is  that it must be passed by
reference.


I had not read about it before, but I think constref is a huge step in 
the right direction. It eliminates my fundamental grief with the current 
implementation.


Specifically, the way const is now defined (or not...) is disturbing 
because it leaves out important details. In C++, you can pass by value 
or reference, or by pointer which is a value but is used to make 
references. But what's important is you _always_ know what it's going to 
do. If you pass something by reference and modify that instance via 
another reference, they're all going to change, because they are the 
same instance. And if you pass by value, it's the opposite. The point 
is, though, you always know what it's going to be.


Imagine if we took C++ and redefined the pass by reference syntax as 
the compiler might pass by value or reference, depending what it feels 
like. Result? Boom. Tons of carefully written code would suddenly break.


It is OK for implementation details to be unspecified. That is how they 
should be--but only if they are in fact implementation details. If they 
affect the *meaning* of the program, they have to be defined as part of 
the language. That's what bothers me. The behavior of const is something 
that does affect the behavior of the program, but it is undefined. 
/Usually/ when you pass a record as const it will by by reference, but 
maybe not. Ditto for other types.


All the problems we've seen with const used in various contexts with 
different data types--AnsiString, ShortString, records, etc.--are the 
result of one fundamental problem, which is the language design. Const 
is not clearly defined. All problems mentioned stem from this.


If we *knew* that const meant it would be by reference, then that 
immediately eliminates the confusion in the case of ShortString and 
records; modifying one instance through several references affects them 
all, as expected. What the programmer says happens; there can be no 
bug, except in the programmer's own knowledge.


This precision of language is closely tied with the testing approach 
several people have mentioned. The testing approach is that you run 
the program with the const optimization on, and, if it works, great, and 
if not, turn the optimization off.


I greatly disagree with this approach. Testing is very important, 
certainly. But you can only ever test a tiny fraction of real world 
scenarios. Ultimately you are much better off if you can mentally verify 
that the program is unconditionally *correct*. That is why I cannot 
accept the ambiguous const feature, because it is impossible to 
theoretically prove that the program is correct, which is something I 
try to do as much as possible.


I applaud the notion of constref. I think it should be used everywhere 
as long as Delphi compatibility is not required.


The difference is slight. In many (but not all--and that's the key) 
cases using const or constref would result in the same assembly, if my 
understanding is correct. What's really important is that it allows the 
programmer to reason logically about a piece of code without mysteries 
popping up.

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


Re: [fpc-devel] Const optimization is a serious bug

2011-07-08 Thread Martin

On 09/07/2011 02:14, Chad Berchek wrote:
Specifically, the way const is now defined (or not...) is disturbing 
because it leaves out important details. In C++, you can pass by value 
or reference, or by pointer which is a value but is used to make 
references. But what's important is you _always_ know what it's going 
to do. If you pass something by reference and modify that instance via 
another reference, they're all going to change, because they are the 
same instance. And if you pass by value, it's the opposite. The point 
is, though, you always know what it's going to be.


Imagine if we took C++ and redefined the pass by reference syntax as 
the compiler might pass by value or reference, depending what it 
feels like. Result? Boom. Tons of carefully written code would 
suddenly break.



...
If we *knew* that const meant it would be by reference, then that 
immediately eliminates the confusion in the case of ShortString and 
records; modifying one instance through several references affects 
them all, as expected. What the programmer says happens; there can be 
no bug, except in the programmer's own knowledge.




We do know:
http://www.freepascal.org/docs-html/ref/refsu58.html#x135-14500011.4.4
A constant argument is passed by reference if its size is larger than 
a pointer. It is passed by value if the size is equal or is less then 
the size of a native pointer.


Of course if you want to rely on this, you must ensure the size of your 
type does ot change (a records definition can be chnaged, and that would 
have consequences for const param). But then, if you rely on it, but 
some compiler $IF and $FAIL in the code, to ensure it only compiles if 
your assumptions are met.


Personally I thing this page would be a good place to document the 
properties of const param with regards to ref-counted types...



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